Rev 3725 | Rev 5565 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3725 | Rev 5201 | ||
---|---|---|---|
Line 3... | Line 3... | ||
3 | ;; Copyright (C) KolibriOS team 2007-2012. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2007-2012. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 7... | Line 7... | ||
7 | 7 | ||
Line 8... | Line 8... | ||
8 | $Revision: 3725 $ |
8 | $Revision: 5201 $ |
9 | 9 | ||
Line 10... | Line 10... | ||
10 | ; Virtual-8086 mode manager |
10 | ; Virtual-8086 mode manager |
Line 11... | Line 11... | ||
11 | ; diamond, 2007, 2008 |
11 | ; diamond, 2007, 2008 |
12 | 12 | ||
13 | DEBUG_SHOW_IO = 0 |
- | |
14 | - | ||
15 | struct V86_machine |
13 | DEBUG_SHOW_IO = 0 |
16 | ; page directory |
14 | |
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 |
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, eax, 4096 ;FIXME |
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, (OS_BASE shr 20) + sys_pgdir |
- | |
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!) |
|
111 | ; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!) |
102 | ; physical address = 0xC0000 |
- | 103 | ||
112 | ; physical address = 0xC0000 |
104 | mov eax, 0xC0000+PG_UW |
113 | ; linear address = 0x800C0000 |
105 | mov edi, page_tabs+0xC0*4 |
114 | mov ecx, 0xC0 |
106 | mov ecx, 64 |
115 | @@: |
107 | @@: |
116 | mov edx, ecx |
108 | stosd |
117 | shl edx, 12 |
- | |
- | 109 | add eax, edx |
|
118 | push edx |
110 | loop @b |
119 | or edx, 111b |
111 | |
120 | mov [eax+ecx*4], edx |
112 | mov eax, sys_proc |
121 | pop edx |
113 | push ebx |
122 | add edx, OS_BASE |
114 | call set_cr3 |
- | 115 | pop ebx |
|
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 |
- | |
150 | v86_get_lin_addr: |
144 | ; destroys: nothing |
- | 145 | v86_get_lin_addr: |
|
151 | push ecx edx |
146 | push ecx edx |
152 | mov ecx, eax |
147 | mov ecx, eax |
- | 148 | shr ecx, 12 |
|
153 | mov edx, [esi+V86_machine.pages] |
149 | mov edx, [page_tabs+ecx*4] |
154 | shr ecx, 12 |
150 | and eax, 0xFFF |
Line -... | Line 151... | ||
- | 151 | and edx, 0xFFFFF000 |
|
155 | and eax, 0xFFF |
152 | or eax, edx |
156 | add eax, [edx+ecx*4] ; atomic operation, no mutex needed |
153 | pop edx ecx |
157 | pop edx ecx |
154 | ret |
158 | ret |
155 | |
159 | 156 | ;not used |
|
160 | ; Sets linear address for V86-page |
157 | ; Sets linear address for V86-page |
161 | ; in: eax=linear address (must be page-aligned) |
158 | ; in: eax=linear address (must be page-aligned) |
162 | ; ecx=V86 page (NOT address!) |
159 | ; ecx=V86 page (NOT address!) |
163 | ; esi=handle |
160 | ; esi=handle |
164 | ; out: nothing |
161 | ; out: nothing |
165 | ; destroys: nothing |
162 | ; destroys: nothing |
166 | v86_set_page: |
163 | ;v86_set_page: |
167 | push eax ebx |
164 | ; push eax ebx |
168 | mov ebx, [esi+V86_machine.pagedir] |
165 | ; mov ebx, [esi+V86_machine.pagedir] |
169 | mov [ebx+ecx*4+0x1800], eax |
166 | ; mov [ebx+ecx*4+0x1800], eax |
Line 170... | Line 167... | ||
170 | call get_pg_addr |
167 | ; call get_pg_addr |
171 | or al, 111b |
168 | ; or al, 111b |
172 | mov [ebx+ecx*4+0x1000], eax |
169 | ; mov [ebx+ecx*4+0x1000], eax |
173 | pop ebx eax |
170 | ; pop ebx eax |
Line 212... | Line 209... | ||
212 | init_sys_v86: |
209 | init_sys_v86: |
213 | call v86_create |
210 | call v86_create |
214 | mov [sys_v86_machine], eax |
211 | mov [sys_v86_machine], eax |
215 | test eax, eax |
212 | test eax, eax |
216 | jz .ret |
213 | 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 |
214 | 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 |
215 | if ~DEBUG_SHOW_IO |
233 | ; allow access to all ports |
216 | ; allow access to all ports |
234 | mov ecx, [esi+V86_machine.iopm] |
217 | mov ecx, [esi+V86_machine.iopm] |
235 | xor eax, eax |
218 | xor eax, eax |
236 | mov edi, ecx |
219 | mov edi, ecx |
Line 270... | Line 253... | ||
270 | ; eax = 1 - exception has occured, cl contains code |
253 | ; eax = 1 - exception has occured, cl contains code |
271 | ; eax = 2 - access to disabled i/o port, ecx contains port address |
254 | ; eax = 2 - access to disabled i/o port, ecx contains port address |
272 | ; eax = 3 - IRQ is already hooked by another VM |
255 | ; eax = 3 - IRQ is already hooked by another VM |
273 | ; destroys: nothing |
256 | ; destroys: nothing |
274 | v86_start: |
257 | v86_start: |
- | 258 | ||
275 | pushad |
259 | pushad |
Line 276... | Line 260... | ||
276 | 260 | ||
Line 277... | Line 261... | ||
277 | cli |
261 | cli |
- | 262 | ||
- | 263 | mov ecx, [current_slot] |
|
- | 264 | ||
278 | 265 | push dword [ecx+APPDATA.io_map] |
|
- | 266 | push dword [ecx+APPDATA.io_map+4] |
|
- | 267 | push [ecx+APPDATA.process] |
|
279 | mov ecx, [CURRENT_TASK] |
268 | push [ecx+APPDATA.saved_esp0] |
Line 280... | Line 269... | ||
280 | shl ecx, 8 |
269 | mov [ecx+APPDATA.saved_esp0], esp |
281 | add ecx, SLOT_BASE |
270 | mov [tss._esp0], esp |
282 | 271 | ||
283 | mov eax, [esi+V86_machine.iopm] |
- | |
284 | call get_pg_addr |
- | |
285 | inc eax |
272 | mov eax, [esi+V86_machine.iopm] |
286 | push dword [ecx+APPDATA.io_map] |
273 | call get_pg_addr |
- | 274 | inc eax |
|
- | 275 | mov dword [ecx+APPDATA.io_map], eax |
|
287 | push dword [ecx+APPDATA.io_map+4] |
276 | mov dword [page_tabs + (tss._io_map_0 shr 10)], eax |
- | 277 | ||
- | 278 | mov eax, [esi+V86_machine.iopm] |
|
288 | mov dword [ecx+APPDATA.io_map], eax |
279 | add eax, 0x1000 |
289 | mov dword [page_tabs + (tss._io_map_0 shr 10)], eax |
280 | call get_pg_addr |
Line 290... | Line -... | ||
290 | add eax, 0x1000 |
- | |
291 | mov dword [ecx+APPDATA.io_map+4], eax |
281 | inc eax |
292 | mov dword [page_tabs + (tss._io_map_1 shr 10)], eax |
282 | mov dword [ecx+APPDATA.io_map+4], eax |
293 | 283 | mov dword [page_tabs + (tss._io_map_1 shr 10)], eax |
|
294 | push [ecx+APPDATA.dir_table] |
- | |
295 | push [ecx+APPDATA.saved_esp0] |
284 | |
296 | mov [ecx+APPDATA.saved_esp0], esp |
- | |
297 | mov [tss._esp0], esp |
- | |
298 | 285 | mov eax, [esi+V86_machine.process] |
|
Line 299... | Line -... | ||
299 | mov eax, [esi+V86_machine.pagedir] |
- | |
300 | call get_pg_addr |
- | |
301 | mov [ecx+APPDATA.dir_table], eax |
286 | mov [ecx+APPDATA.process], eax |
302 | mov cr3, eax |
287 | mov [current_process], eax |
303 | 288 | mov eax, [eax+PROC.pdt_0_phys] |
|
304 | ; mov [irq_tab+5*4], my05 |
289 | mov cr3, eax |
Line 780... | Line 765... | ||
780 | mov ecx, sizeof.v86_regs/4 |
765 | mov ecx, sizeof.v86_regs/4 |
781 | rep movsd |
766 | rep movsd |
782 | mov esp, esi |
767 | mov esp, esi |
Line 783... | Line 768... | ||
783 | 768 | ||
784 | cli |
769 | cli |
785 | mov ecx, [CURRENT_TASK] |
- | |
786 | shl ecx, 8 |
770 | mov ecx, [current_slot] |
- | 771 | pop eax |
|
787 | pop eax |
772 | |
788 | mov [SLOT_BASE+ecx+APPDATA.saved_esp0], eax |
773 | mov [ecx+APPDATA.saved_esp0], eax |
789 | mov [tss._esp0], eax |
774 | mov [tss._esp0], eax |
790 | pop eax |
775 | pop eax |
- | 776 | mov [ecx+APPDATA.process], eax |
|
791 | mov [SLOT_BASE+ecx+APPDATA.dir_table], eax |
777 | mov [current_process], eax |
792 | pop ebx |
778 | pop ebx |
793 | mov dword [SLOT_BASE+ecx+APPDATA.io_map+4], ebx |
779 | mov dword [ecx+APPDATA.io_map+4], ebx |
794 | mov dword [page_tabs + (tss._io_map_1 shr 10)], ebx |
780 | mov dword [page_tabs + (tss._io_map_1 shr 10)], ebx |
795 | pop ebx |
781 | pop ebx |
796 | mov dword [SLOT_BASE+ecx+APPDATA.io_map], ebx |
782 | mov dword [ecx+APPDATA.io_map], ebx |
- | 783 | mov dword [page_tabs + (tss._io_map_0 shr 10)], ebx |
|
797 | mov dword [page_tabs + (tss._io_map_0 shr 10)], ebx |
784 | mov eax, [eax+PROC.pdt_0_phys] |
798 | mov cr3, eax |
785 | mov cr3, eax |
Line 799... | Line 786... | ||
799 | sti |
786 | sti |
800 | 787 | ||
Line 841... | Line 828... | ||
841 | cld |
828 | cld |
842 | mov edi, ebp |
829 | mov edi, ebp |
843 | pop eax |
830 | pop eax |
844 | v86_irq2: |
831 | v86_irq2: |
845 | mov esi, [v86_irqhooks+edi*8] ; get VM handle |
832 | mov esi, [v86_irqhooks+edi*8] ; get VM handle |
846 | mov eax, [esi+V86_machine.pagedir] |
833 | mov eax, [esi+V86_machine.process] |
847 | call get_pg_addr |
- | |
848 | mov ecx, [CURRENT_TASK] |
834 | mov ecx, [CURRENT_TASK] |
849 | shl ecx, 8 |
835 | shl ecx, 8 |
850 | cmp [SLOT_BASE+ecx+APPDATA.dir_table], eax |
836 | cmp [SLOT_BASE+ecx+APPDATA.process], eax |
851 | jnz .notcurrent |
837 | jnz .notcurrent |
852 | lea eax, [edi+8] |
838 | lea eax, [edi+8] |
853 | cmp al, 10h |
839 | cmp al, 10h |
854 | mov ah, 1 |
840 | mov ah, 1 |
855 | jb @f |
841 | jb @f |
Line 858... | Line 844... | ||
858 | jmp v86_exc_c.simulate_int |
844 | jmp v86_exc_c.simulate_int |
859 | .notcurrent: |
845 | .notcurrent: |
860 | mov ebx, SLOT_BASE + 0x100 |
846 | mov ebx, SLOT_BASE + 0x100 |
861 | mov ecx, [TASK_COUNT] |
847 | mov ecx, [TASK_COUNT] |
862 | .scan: |
848 | .scan: |
863 | cmp [ebx+APPDATA.dir_table], eax |
849 | cmp [ebx+APPDATA.process], eax |
864 | jnz .cont |
850 | jnz .cont |
865 | push ecx |
851 | push ecx |
866 | mov ecx, [ebx+APPDATA.saved_esp0] |
852 | mov ecx, [ebx+APPDATA.saved_esp0] |
867 | cmp word [ecx-sizeof.v86_regs+v86_regs.esp], 6 |
853 | cmp word [ecx-sizeof.v86_regs+v86_regs.esp], 6 |
868 | jb .cont2 |
854 | jb .cont2 |
Line 893... | Line 879... | ||
893 | mov ecx, edi |
879 | mov ecx, edi |
894 | call irq_eoi |
880 | call irq_eoi |
895 | popad |
881 | popad |
896 | iretd |
882 | iretd |
897 | .found: |
883 | .found: |
- | 884 | mov eax, [eax+PROC.pdt_0_phys] |
|
898 | mov cr3, eax |
885 | mov cr3, eax |
899 | mov esi, [ebx+APPDATA.saved_esp0] |
886 | mov esi, [ebx+APPDATA.saved_esp0] |
900 | sub word [esi-sizeof.v86_regs+v86_regs.esp], 6 |
887 | sub word [esi-sizeof.v86_regs+v86_regs.esp], 6 |
901 | mov ecx, [esi-sizeof.v86_regs+v86_regs.eip] |
888 | mov ecx, [esi-sizeof.v86_regs+v86_regs.eip] |
902 | mov word [edx], cx |
889 | mov word [edx], cx |