Subversion Repositories Kolibri OS

Rev

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