Subversion Repositories Kolibri OS

Rev

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