Rev 4923 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4923 | Rev 4993 | ||
---|---|---|---|
Line 12... | Line 12... | ||
12 | 12 | ||
Line 13... | Line 13... | ||
13 | DEBUG_SHOW_IO = 0 |
13 | DEBUG_SHOW_IO = 0 |
14 | 14 | ||
15 | struct V86_machine |
- | |
16 | ; page directory |
- | |
17 | pagedir dd ? |
15 | struct V86_machine |
18 | ; translation table: V86 address -> flat linear address |
16 | ; page directory |
19 | pages dd ? |
17 | process dd ? |
20 | ; mutex to protect all data from writing by multiple threads at one time |
18 | ; mutex to protect all data from writing by multiple threads at one time |
21 | mutex dd ? |
19 | mutex dd ? |
22 | ; i/o permission map |
20 | ; i/o permission map |
Line 36... | Line 34... | ||
36 | jz .fail |
34 | jz .fail |
37 | ; initialize mutex |
35 | ; initialize mutex |
38 | and dword [eax+V86_machine.mutex], 0 |
36 | and dword [eax+V86_machine.mutex], 0 |
39 | ; allocate tables |
37 | ; allocate tables |
40 | mov ebx, eax |
38 | mov ebx, eax |
- | 39 | ||
41 | ; We allocate 4 pages. |
40 | stdcall create_process, 4096, OS_BASE, 4096 |
42 | ; First is main page directory for V86 mode. |
41 | test eax, eax |
43 | ; Second page: |
42 | jz .fail2 |
- | 43 | ||
44 | ; first half (0x800 bytes) is page table for addresses 0 - 0x100000, |
44 | mov [eax+PROC.mem_used], 4096 |
45 | ; second half is for V86-to-linear translation. |
45 | mov [ebx+V86_machine.process], eax |
- | 46 | ||
46 | ; Third and fourth are for I/O permission map. |
47 | push 2000h |
47 | push 8000h ; blocks less than 8 pages are discontinuous |
- | |
48 | call kernel_alloc |
48 | call kernel_alloc |
49 | test eax, eax |
49 | test eax, eax |
50 | jz .fail2 |
50 | jz .fail2 |
51 | mov [ebx+V86_machine.pagedir], eax |
- | |
52 | push edi eax |
- | |
53 | mov edi, eax |
- | |
54 | add eax, 1800h |
- | |
- | 51 | ||
55 | mov [ebx+V86_machine.pages], eax |
52 | mov [ebx+V86_machine.iopm], eax |
- | 53 | ||
- | 54 | ||
56 | ; initialize tables |
55 | ; initialize tables |
57 | mov ecx, 2000h/4 |
56 | push edi |
58 | xor eax, eax |
57 | mov edi, eax |
59 | rep stosd |
- | |
60 | mov [ebx+V86_machine.iopm], edi |
- | |
61 | dec eax |
58 | mov eax, -1 |
62 | mov ecx, 2000h/4 |
59 | mov ecx, 2000h/4 |
63 | rep stosd |
60 | rep stosd |
64 | pop eax |
- | |
65 | ; page directory: first entry is page table... |
- | |
66 | mov edi, eax |
- | |
67 | add eax, 1000h |
- | |
68 | push eax |
- | |
69 | call get_pg_addr |
- | |
70 | or al, PG_UW |
- | |
71 | stosd |
- | |
72 | ; ...and also copy system page tables |
- | |
73 | ; thx to Serge, system is located at high addresses |
- | |
74 | add edi, (OS_BASE shr 20) - 4 |
- | |
75 | push esi |
- | |
76 | mov esi, sys_proc+PROC.pdt_0+(OS_BASE shr 20) |
- | |
77 | mov ecx, 0x80000000 shr 22 |
- | |
78 | rep movsd |
- | |
Line 79... | Line 61... | ||
79 | 61 | ||
80 | mov eax, [ebx+V86_machine.pagedir] ;root dir also is |
62 | mov eax, [ebx+V86_machine.process] |
- | 63 | mov eax, [eax+PROC.pdt_0_phys] |
|
81 | call get_pg_addr ;used as page table |
64 | |
- | 65 | pushfd |
|
82 | or al, PG_SW |
66 | cli |
- | 67 | mov cr3, eax |
|
Line 83... | Line -... | ||
83 | mov [edi-4096+(page_tabs shr 20)], eax |
- | |
84 | 68 | ||
85 | pop esi |
- | |
- | 69 | ||
86 | ; now V86 specific: initialize known addresses in first Mb |
70 | ; now V86 specific: initialize known addresses in first Mb |
87 | pop eax |
71 | |
88 | ; first page - BIOS data (shared between all machines!) |
72 | ; first page - BIOS data (shared between all machines!) |
89 | ; physical address = 0 |
- | |
90 | ; linear address = OS_BASE |
- | |
91 | mov dword [eax], 111b |
73 | ; physical address = 0 |
92 | mov dword [eax+800h], OS_BASE |
74 | ; linear address = OS_BASE |
93 | ; page before 0xA0000 - Extended BIOS Data Area (shared between all machines!) |
75 | ; page before 0xA0000 - Extended BIOS Data Area (shared between all machines!) |
94 | ; physical address = 0x9C000 |
76 | ; physical address = 0x9C000 |
95 | ; linear address = 0x8009C000 |
77 | ; linear address = 0x8009C000 |
- | 78 | ; (I have seen one computer with EBDA segment = 0x9D80, |
|
96 | ; (I have seen one computer with EBDA segment = 0x9D80, |
79 | ; all other computers use less memory) |
97 | ; all other computers use less memory) |
80 | |
98 | mov ecx, 4 |
81 | mov eax, PG_UW |
- | 82 | mov [page_tabs], eax |
|
- | 83 | invlpg [eax] |
|
- | 84 | ||
- | 85 | mov byte [0x500], 0xCD |
|
- | 86 | mov byte [0x501], 0x13 |
|
- | 87 | mov byte [0x502], 0xF4 |
|
- | 88 | mov byte [0x503], 0xCD |
|
- | 89 | mov byte [0x504], 0x10 |
|
- | 90 | mov byte [0x505], 0xF4 |
|
99 | mov edx, 0x9C000 |
91 | |
- | 92 | mov eax, 0x99000+PG_UW |
|
- | 93 | mov edi, page_tabs+0x99*4 |
|
100 | push eax |
94 | mov edx, 0x1000 |
101 | lea edi, [eax+0x9C*4] |
- | |
102 | @@: |
- | |
103 | lea eax, [edx + OS_BASE] |
- | |
104 | mov [edi+800h], eax |
95 | mov ecx, 7 |
105 | lea eax, [edx + 111b] |
96 | @@: |
106 | stosd |
97 | stosd |
107 | add edx, 0x1000 |
- | |
108 | loop @b |
- | |
- | 98 | add eax, edx |
|
109 | pop eax |
99 | loop @b |
110 | pop edi |
100 | |
- | 101 | ; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!) |
|
- | 102 | ; physical address = 0xC0000 |
|
- | 103 | ||
111 | ; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!) |
104 | mov eax, 0xC0000+PG_UW |
112 | ; physical address = 0xC0000 |
105 | mov edi, page_tabs+0xC0*4 |
113 | ; linear address = 0x800C0000 |
106 | mov edx, 0x1000 |
114 | mov ecx, 0xC0 |
- | |
115 | @@: |
- | |
116 | mov edx, ecx |
107 | mov ecx, 64 |
117 | shl edx, 12 |
108 | @@: |
118 | push edx |
- | |
119 | or edx, 111b |
109 | stosd |
- | 110 | add eax, edx |
|
120 | mov [eax+ecx*4], edx |
111 | loop @b |
- | 112 | ||
121 | pop edx |
113 | mov eax, sys_proc-OS_BASE+PROC.pdt_0 |
122 | add edx, OS_BASE |
114 | |
- | 115 | mov cr3, eax |
|
123 | mov [eax+ecx*4+0x800], edx |
116 | popfd |
- | 117 | ||
124 | inc cl |
118 | pop edi |
125 | jnz @b |
119 | |
126 | mov eax, ebx |
120 | mov eax, ebx |
127 | ret |
121 | ret |
128 | .fail2: |
122 | .fail2: |
129 | mov eax, ebx |
123 | mov eax, ebx |
130 | call free |
124 | call free |
131 | .fail: |
125 | .fail: |
Line -... | Line 126... | ||
- | 126 | xor eax, eax |
|
132 | xor eax, eax |
127 | ret |
133 | ret |
128 | |
134 | 129 | ;not used |
|
135 | ; Destroy V86 machine |
130 | ; Destroy V86 machine |
136 | ; in: eax = handle |
131 | ; in: eax = handle |
137 | ; out: nothing |
132 | ; out: nothing |
138 | ; destroys: eax, ebx, ecx, edx (due to free) |
133 | ; destroys: eax, ebx, ecx, edx (due to free) |
139 | v86_destroy: |
134 | ;v86_destroy: |
140 | push eax |
135 | ; push eax |
Line 141... | Line 136... | ||
141 | stdcall kernel_free, [eax+V86_machine.pagedir] |
136 | ; stdcall kernel_free, [eax+V86_machine.pagedir] |
142 | pop eax |
137 | ; pop eax |
143 | jmp free |
138 | ; jmp free |
144 | 139 | ||
145 | ; Translate V86-address to linear address |
140 | ; Translate V86-address to linear address |
146 | ; in: eax=V86 address |
141 | ; in: eax=V86 address |
147 | ; esi=handle |
142 | ; esi=handle |
148 | ; out: eax=linear address |
143 | ; out: eax=linear address |
149 | ; destroys: nothing |
144 | ; destroys: nothing |
150 | v86_get_lin_addr: |
145 | v86_get_lin_addr: |
151 | push ecx edx |
146 | push ecx edx |
152 | mov ecx, eax |
147 | mov ecx, eax |
153 | mov edx, [esi+V86_machine.pages] |
148 | mov edx, page_tabs |
154 | shr ecx, 12 |
149 | shr ecx, 12 |
Line -... | Line 150... | ||
- | 150 | and eax, 0xFFF |
|
155 | and eax, 0xFFF |
151 | add eax, [edx+ecx*4] ; atomic operation, no mutex needed |
156 | add eax, [edx+ecx*4] ; atomic operation, no mutex needed |
152 | pop edx ecx |
157 | pop edx ecx |
153 | ret |
158 | ret |
154 | |
159 | 155 | ;not used |
|
160 | ; Sets linear address for V86-page |
156 | ; Sets linear address for V86-page |
161 | ; in: eax=linear address (must be page-aligned) |
157 | ; in: eax=linear address (must be page-aligned) |
162 | ; ecx=V86 page (NOT address!) |
158 | ; ecx=V86 page (NOT address!) |
163 | ; esi=handle |
159 | ; esi=handle |
164 | ; out: nothing |
160 | ; out: nothing |
165 | ; destroys: nothing |
161 | ; destroys: nothing |
166 | v86_set_page: |
162 | ;v86_set_page: |
167 | push eax ebx |
163 | ; push eax ebx |
168 | mov ebx, [esi+V86_machine.pagedir] |
164 | ; mov ebx, [esi+V86_machine.pagedir] |
169 | mov [ebx+ecx*4+0x1800], eax |
165 | ; mov [ebx+ecx*4+0x1800], eax |
Line 170... | Line 166... | ||
170 | call get_pg_addr |
166 | ; call get_pg_addr |
171 | or al, 111b |
167 | ; or al, 111b |
172 | mov [ebx+ecx*4+0x1000], eax |
168 | ; mov [ebx+ecx*4+0x1000], eax |
173 | pop ebx eax |
169 | ; pop ebx eax |
Line 212... | Line 208... | ||
212 | init_sys_v86: |
208 | init_sys_v86: |
213 | call v86_create |
209 | call v86_create |
214 | mov [sys_v86_machine], eax |
210 | mov [sys_v86_machine], eax |
215 | test eax, eax |
211 | test eax, eax |
216 | jz .ret |
212 | jz .ret |
217 | mov byte [OS_BASE + 0x500], 0xCD |
- | |
218 | mov byte [OS_BASE + 0x501], 0x13 |
- | |
219 | mov byte [OS_BASE + 0x502], 0xF4 |
- | |
220 | mov byte [OS_BASE + 0x503], 0xCD |
- | |
221 | mov byte [OS_BASE + 0x504], 0x10 |
- | |
222 | mov byte [OS_BASE + 0x505], 0xF4 |
- | |
223 | mov esi, eax |
213 | mov esi, eax |
224 | mov ebx, [eax+V86_machine.pagedir] |
- | |
225 | ; one page for stack, two pages for results (0x2000 bytes = 16 sectors) |
- | |
226 | mov dword [ebx+0x99*4+0x1000], 0x99000 or 111b |
- | |
227 | mov dword [ebx+0x99*4+0x1800], OS_BASE + 0x99000 |
- | |
228 | mov dword [ebx+0x9A*4+0x1000], 0x9A000 or 111b |
- | |
229 | mov dword [ebx+0x9A*4+0x1800], OS_BASE + 0x9A000 |
- | |
230 | mov dword [ebx+0x9B*4+0x1000], 0x9B000 or 111b |
- | |
231 | mov dword [ebx+0x9B*4+0x1800], OS_BASE + 0x9B000 |
- | |
232 | if ~DEBUG_SHOW_IO |
214 | if ~DEBUG_SHOW_IO |
233 | ; allow access to all ports |
215 | ; allow access to all ports |
234 | mov ecx, [esi+V86_machine.iopm] |
216 | mov ecx, [esi+V86_machine.iopm] |
235 | xor eax, eax |
217 | xor eax, eax |
236 | mov edi, ecx |
218 | mov edi, ecx |
Line 270... | Line 252... | ||
270 | ; eax = 1 - exception has occured, cl contains code |
252 | ; eax = 1 - exception has occured, cl contains code |
271 | ; eax = 2 - access to disabled i/o port, ecx contains port address |
253 | ; eax = 2 - access to disabled i/o port, ecx contains port address |
272 | ; eax = 3 - IRQ is already hooked by another VM |
254 | ; eax = 3 - IRQ is already hooked by another VM |
273 | ; destroys: nothing |
255 | ; destroys: nothing |
274 | v86_start: |
256 | v86_start: |
- | 257 | ||
- | 258 | xchg bx, bx |
|
- | 259 | ||
275 | pushad |
260 | pushad |
Line 276... | Line 261... | ||
276 | 261 | ||
Line 277... | Line 262... | ||
277 | cli |
262 | cli |
Line 294... | Line 279... | ||
294 | push [ecx+APPDATA.process] |
279 | push [ecx+APPDATA.process] |
295 | push [ecx+APPDATA.saved_esp0] |
280 | push [ecx+APPDATA.saved_esp0] |
296 | mov [ecx+APPDATA.saved_esp0], esp |
281 | mov [ecx+APPDATA.saved_esp0], esp |
297 | mov [tss._esp0], esp |
282 | mov [tss._esp0], esp |
Line 298... | Line 283... | ||
298 | 283 | ||
299 | mov eax, [esi+V86_machine.pagedir] |
- | |
300 | call get_pg_addr |
284 | mov eax, [esi+V86_machine.process] |
301 | mov [ecx+APPDATA.process], eax |
285 | mov [ecx+APPDATA.process], eax |
302 | ; mov cr3, eax |
- | |
303 | 286 | mov eax, [eax+PROC.pdt_0_phys] |
|
Line 304... | Line 287... | ||
304 | ; mov [irq_tab+5*4], my05 |
287 | mov cr3, eax |
305 | 288 | ||
306 | ; We do not enable interrupts, because V86 IRQ redirector assumes that |
289 | ; We do not enable interrupts, because V86 IRQ redirector assumes that |
307 | ; machine is running |
290 | ; machine is running |
Line 793... | Line 776... | ||
793 | mov dword [SLOT_BASE+ecx+APPDATA.io_map+4], ebx |
776 | mov dword [SLOT_BASE+ecx+APPDATA.io_map+4], ebx |
794 | mov dword [page_tabs + (tss._io_map_1 shr 10)], ebx |
777 | mov dword [page_tabs + (tss._io_map_1 shr 10)], ebx |
795 | pop ebx |
778 | pop ebx |
796 | mov dword [SLOT_BASE+ecx+APPDATA.io_map], ebx |
779 | mov dword [SLOT_BASE+ecx+APPDATA.io_map], ebx |
797 | mov dword [page_tabs + (tss._io_map_0 shr 10)], ebx |
780 | mov dword [page_tabs + (tss._io_map_0 shr 10)], ebx |
- | 781 | mov eax, [eax+PROC.pdt_0_phys] |
|
798 | mov cr3, eax |
782 | mov cr3, eax |
799 | sti |
783 | sti |
Line 800... | Line 784... | ||
800 | 784 | ||
801 | popad |
785 | popad |
Line 841... | Line 825... | ||
841 | cld |
825 | cld |
842 | mov edi, ebp |
826 | mov edi, ebp |
843 | pop eax |
827 | pop eax |
844 | v86_irq2: |
828 | v86_irq2: |
845 | mov esi, [v86_irqhooks+edi*8] ; get VM handle |
829 | mov esi, [v86_irqhooks+edi*8] ; get VM handle |
846 | mov eax, [esi+V86_machine.pagedir] |
830 | mov eax, [esi+V86_machine.process] |
847 | call get_pg_addr |
- | |
848 | mov ecx, [CURRENT_TASK] |
831 | mov ecx, [CURRENT_TASK] |
849 | shl ecx, 8 |
832 | shl ecx, 8 |
850 | cmp [SLOT_BASE+ecx+APPDATA.process], eax |
833 | cmp [SLOT_BASE+ecx+APPDATA.process], eax |
851 | jnz .notcurrent |
834 | jnz .notcurrent |
852 | lea eax, [edi+8] |
835 | lea eax, [edi+8] |
Line 893... | Line 876... | ||
893 | mov ecx, edi |
876 | mov ecx, edi |
894 | call irq_eoi |
877 | call irq_eoi |
895 | popad |
878 | popad |
896 | iretd |
879 | iretd |
897 | .found: |
880 | .found: |
- | 881 | mov eax, [eax+PROC.pdt_0_phys] |
|
898 | mov cr3, eax |
882 | mov cr3, eax |
899 | mov esi, [ebx+APPDATA.saved_esp0] |
883 | mov esi, [ebx+APPDATA.saved_esp0] |
900 | sub word [esi-sizeof.v86_regs+v86_regs.esp], 6 |
884 | sub word [esi-sizeof.v86_regs+v86_regs.esp], 6 |
901 | mov ecx, [esi-sizeof.v86_regs+v86_regs.eip] |
885 | mov ecx, [esi-sizeof.v86_regs+v86_regs.eip] |
902 | mov word [edx], cx |
886 | mov word [edx], cx |