forked from KolibriOS/kolibrios
kernel: kolibri-process merged into trunk. This is my little gift to myself for my birthday.
git-svn-id: svn://kolibrios.org@5130 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
@@ -14,9 +14,7 @@ DEBUG_SHOW_IO = 0
|
||||
|
||||
struct V86_machine
|
||||
; page directory
|
||||
pagedir dd ?
|
||||
; translation table: V86 address -> flat linear address
|
||||
pages dd ?
|
||||
process dd ?
|
||||
; mutex to protect all data from writing by multiple threads at one time
|
||||
mutex dd ?
|
||||
; i/o permission map
|
||||
@@ -38,91 +36,87 @@ v86_create:
|
||||
and dword [eax+V86_machine.mutex], 0
|
||||
; allocate tables
|
||||
mov ebx, eax
|
||||
; We allocate 4 pages.
|
||||
; First is main page directory for V86 mode.
|
||||
; Second page:
|
||||
; first half (0x800 bytes) is page table for addresses 0 - 0x100000,
|
||||
; second half is for V86-to-linear translation.
|
||||
; Third and fourth are for I/O permission map.
|
||||
push 8000h ; blocks less than 8 pages are discontinuous
|
||||
|
||||
stdcall create_process, 4096, OS_BASE, 4096
|
||||
test eax, eax
|
||||
jz .fail2
|
||||
|
||||
mov [eax+PROC.mem_used], 4096
|
||||
mov [ebx+V86_machine.process], eax
|
||||
|
||||
push 2000h
|
||||
call kernel_alloc
|
||||
test eax, eax
|
||||
jz .fail2
|
||||
mov [ebx+V86_machine.pagedir], eax
|
||||
push edi eax
|
||||
mov edi, eax
|
||||
add eax, 1800h
|
||||
mov [ebx+V86_machine.pages], eax
|
||||
|
||||
mov [ebx+V86_machine.iopm], eax
|
||||
|
||||
|
||||
; initialize tables
|
||||
mov ecx, 2000h/4
|
||||
xor eax, eax
|
||||
rep stosd
|
||||
mov [ebx+V86_machine.iopm], edi
|
||||
dec eax
|
||||
mov ecx, 2000h/4
|
||||
rep stosd
|
||||
pop eax
|
||||
; page directory: first entry is page table...
|
||||
push edi
|
||||
mov edi, eax
|
||||
add eax, 1000h
|
||||
push eax
|
||||
call get_pg_addr
|
||||
or al, PG_UW
|
||||
stosd
|
||||
; ...and also copy system page tables
|
||||
; thx to Serge, system is located at high addresses
|
||||
add edi, (OS_BASE shr 20) - 4
|
||||
push esi
|
||||
mov esi, (OS_BASE shr 20) + sys_pgdir
|
||||
mov ecx, 0x80000000 shr 22
|
||||
rep movsd
|
||||
mov eax, -1
|
||||
mov ecx, 2000h/4
|
||||
rep stosd
|
||||
|
||||
mov eax, [ebx+V86_machine.process]
|
||||
mov eax, [eax+PROC.pdt_0_phys]
|
||||
|
||||
pushfd
|
||||
cli
|
||||
mov cr3, eax
|
||||
|
||||
mov eax, [ebx+V86_machine.pagedir] ;root dir also is
|
||||
call get_pg_addr ;used as page table
|
||||
or al, PG_SW
|
||||
mov [edi-4096+(page_tabs shr 20)], eax
|
||||
|
||||
pop esi
|
||||
; now V86 specific: initialize known addresses in first Mb
|
||||
pop eax
|
||||
|
||||
; first page - BIOS data (shared between all machines!)
|
||||
; physical address = 0
|
||||
; linear address = OS_BASE
|
||||
mov dword [eax], 111b
|
||||
mov dword [eax+800h], OS_BASE
|
||||
; page before 0xA0000 - Extended BIOS Data Area (shared between all machines!)
|
||||
; physical address = 0x9C000
|
||||
; linear address = 0x8009C000
|
||||
; (I have seen one computer with EBDA segment = 0x9D80,
|
||||
; all other computers use less memory)
|
||||
mov ecx, 4
|
||||
mov edx, 0x9C000
|
||||
push eax
|
||||
lea edi, [eax+0x9C*4]
|
||||
|
||||
mov eax, PG_UW
|
||||
mov [page_tabs], eax
|
||||
invlpg [eax]
|
||||
|
||||
mov byte [0x500], 0xCD
|
||||
mov byte [0x501], 0x13
|
||||
mov byte [0x502], 0xF4
|
||||
mov byte [0x503], 0xCD
|
||||
mov byte [0x504], 0x10
|
||||
mov byte [0x505], 0xF4
|
||||
|
||||
mov eax, 0x99000+PG_UW
|
||||
mov edi, page_tabs+0x99*4
|
||||
mov edx, 0x1000
|
||||
mov ecx, 7
|
||||
@@:
|
||||
lea eax, [edx + OS_BASE]
|
||||
mov [edi+800h], eax
|
||||
lea eax, [edx + 111b]
|
||||
stosd
|
||||
add edx, 0x1000
|
||||
add eax, edx
|
||||
loop @b
|
||||
pop eax
|
||||
pop edi
|
||||
|
||||
; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!)
|
||||
; physical address = 0xC0000
|
||||
; linear address = 0x800C0000
|
||||
mov ecx, 0xC0
|
||||
|
||||
mov eax, 0xC0000+PG_UW
|
||||
mov edi, page_tabs+0xC0*4
|
||||
mov ecx, 64
|
||||
@@:
|
||||
mov edx, ecx
|
||||
shl edx, 12
|
||||
push edx
|
||||
or edx, 111b
|
||||
mov [eax+ecx*4], edx
|
||||
pop edx
|
||||
add edx, OS_BASE
|
||||
mov [eax+ecx*4+0x800], edx
|
||||
inc cl
|
||||
jnz @b
|
||||
stosd
|
||||
add eax, edx
|
||||
loop @b
|
||||
|
||||
mov eax, sys_proc
|
||||
push ebx
|
||||
call set_cr3
|
||||
pop ebx
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
|
||||
mov eax, ebx
|
||||
ret
|
||||
.fail2:
|
||||
@@ -132,15 +126,16 @@ v86_create:
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
;not used
|
||||
; Destroy V86 machine
|
||||
; in: eax = handle
|
||||
; out: nothing
|
||||
; destroys: eax, ebx, ecx, edx (due to free)
|
||||
v86_destroy:
|
||||
push eax
|
||||
stdcall kernel_free, [eax+V86_machine.pagedir]
|
||||
pop eax
|
||||
jmp free
|
||||
;v86_destroy:
|
||||
; push eax
|
||||
; stdcall kernel_free, [eax+V86_machine.pagedir]
|
||||
; pop eax
|
||||
; jmp free
|
||||
|
||||
; Translate V86-address to linear address
|
||||
; in: eax=V86 address
|
||||
@@ -150,28 +145,30 @@ v86_destroy:
|
||||
v86_get_lin_addr:
|
||||
push ecx edx
|
||||
mov ecx, eax
|
||||
mov edx, [esi+V86_machine.pages]
|
||||
shr ecx, 12
|
||||
mov edx, [page_tabs+ecx*4]
|
||||
and eax, 0xFFF
|
||||
add eax, [edx+ecx*4] ; atomic operation, no mutex needed
|
||||
and edx, 0xFFFFF000
|
||||
or eax, edx
|
||||
pop edx ecx
|
||||
ret
|
||||
|
||||
;not used
|
||||
; Sets linear address for V86-page
|
||||
; in: eax=linear address (must be page-aligned)
|
||||
; ecx=V86 page (NOT address!)
|
||||
; esi=handle
|
||||
; out: nothing
|
||||
; destroys: nothing
|
||||
v86_set_page:
|
||||
push eax ebx
|
||||
mov ebx, [esi+V86_machine.pagedir]
|
||||
mov [ebx+ecx*4+0x1800], eax
|
||||
call get_pg_addr
|
||||
or al, 111b
|
||||
mov [ebx+ecx*4+0x1000], eax
|
||||
pop ebx eax
|
||||
ret
|
||||
;v86_set_page:
|
||||
; push eax ebx
|
||||
; mov ebx, [esi+V86_machine.pagedir]
|
||||
; mov [ebx+ecx*4+0x1800], eax
|
||||
; call get_pg_addr
|
||||
; or al, 111b
|
||||
; mov [ebx+ecx*4+0x1000], eax
|
||||
; pop ebx eax
|
||||
; ret
|
||||
|
||||
; Allocate memory in V86 machine
|
||||
; in: eax=size (in bytes)
|
||||
@@ -214,21 +211,7 @@ init_sys_v86:
|
||||
mov [sys_v86_machine], eax
|
||||
test eax, eax
|
||||
jz .ret
|
||||
mov byte [OS_BASE + 0x500], 0xCD
|
||||
mov byte [OS_BASE + 0x501], 0x13
|
||||
mov byte [OS_BASE + 0x502], 0xF4
|
||||
mov byte [OS_BASE + 0x503], 0xCD
|
||||
mov byte [OS_BASE + 0x504], 0x10
|
||||
mov byte [OS_BASE + 0x505], 0xF4
|
||||
mov esi, eax
|
||||
mov ebx, [eax+V86_machine.pagedir]
|
||||
; one page for stack, two pages for results (0x2000 bytes = 16 sectors)
|
||||
mov dword [ebx+0x99*4+0x1000], 0x99000 or 111b
|
||||
mov dword [ebx+0x99*4+0x1800], OS_BASE + 0x99000
|
||||
mov dword [ebx+0x9A*4+0x1000], 0x9A000 or 111b
|
||||
mov dword [ebx+0x9A*4+0x1800], OS_BASE + 0x9A000
|
||||
mov dword [ebx+0x9B*4+0x1000], 0x9B000 or 111b
|
||||
mov dword [ebx+0x9B*4+0x1800], OS_BASE + 0x9B000
|
||||
if ~DEBUG_SHOW_IO
|
||||
; allow access to all ports
|
||||
mov ecx, [esi+V86_machine.iopm]
|
||||
@@ -272,36 +255,38 @@ ends
|
||||
; eax = 3 - IRQ is already hooked by another VM
|
||||
; destroys: nothing
|
||||
v86_start:
|
||||
|
||||
pushad
|
||||
|
||||
cli
|
||||
|
||||
mov ecx, [CURRENT_TASK]
|
||||
shl ecx, 8
|
||||
add ecx, SLOT_BASE
|
||||
mov ecx, [current_slot]
|
||||
|
||||
mov eax, [esi+V86_machine.iopm]
|
||||
call get_pg_addr
|
||||
inc eax
|
||||
push dword [ecx+APPDATA.io_map]
|
||||
push dword [ecx+APPDATA.io_map+4]
|
||||
mov dword [ecx+APPDATA.io_map], eax
|
||||
mov dword [page_tabs + (tss._io_map_0 shr 10)], eax
|
||||
add eax, 0x1000
|
||||
mov dword [ecx+APPDATA.io_map+4], eax
|
||||
mov dword [page_tabs + (tss._io_map_1 shr 10)], eax
|
||||
|
||||
push [ecx+APPDATA.dir_table]
|
||||
push [ecx+APPDATA.process]
|
||||
push [ecx+APPDATA.saved_esp0]
|
||||
mov [ecx+APPDATA.saved_esp0], esp
|
||||
mov [tss._esp0], esp
|
||||
|
||||
mov eax, [esi+V86_machine.pagedir]
|
||||
mov eax, [esi+V86_machine.iopm]
|
||||
call get_pg_addr
|
||||
mov [ecx+APPDATA.dir_table], eax
|
||||
mov cr3, eax
|
||||
inc eax
|
||||
mov dword [ecx+APPDATA.io_map], eax
|
||||
mov dword [page_tabs + (tss._io_map_0 shr 10)], eax
|
||||
|
||||
; mov [irq_tab+5*4], my05
|
||||
mov eax, [esi+V86_machine.iopm]
|
||||
add eax, 0x1000
|
||||
call get_pg_addr
|
||||
inc eax
|
||||
mov dword [ecx+APPDATA.io_map+4], eax
|
||||
mov dword [page_tabs + (tss._io_map_1 shr 10)], eax
|
||||
|
||||
mov eax, [esi+V86_machine.process]
|
||||
mov [ecx+APPDATA.process], eax
|
||||
mov [current_process], eax
|
||||
mov eax, [eax+PROC.pdt_0_phys]
|
||||
mov cr3, eax
|
||||
|
||||
; We do not enable interrupts, because V86 IRQ redirector assumes that
|
||||
; machine is running
|
||||
@@ -782,19 +767,21 @@ end if
|
||||
mov esp, esi
|
||||
|
||||
cli
|
||||
mov ecx, [CURRENT_TASK]
|
||||
shl ecx, 8
|
||||
mov ecx, [current_slot]
|
||||
pop eax
|
||||
mov [SLOT_BASE+ecx+APPDATA.saved_esp0], eax
|
||||
|
||||
mov [ecx+APPDATA.saved_esp0], eax
|
||||
mov [tss._esp0], eax
|
||||
pop eax
|
||||
mov [SLOT_BASE+ecx+APPDATA.dir_table], eax
|
||||
mov [ecx+APPDATA.process], eax
|
||||
mov [current_process], eax
|
||||
pop ebx
|
||||
mov dword [SLOT_BASE+ecx+APPDATA.io_map+4], ebx
|
||||
mov dword [ecx+APPDATA.io_map+4], ebx
|
||||
mov dword [page_tabs + (tss._io_map_1 shr 10)], ebx
|
||||
pop ebx
|
||||
mov dword [SLOT_BASE+ecx+APPDATA.io_map], ebx
|
||||
mov dword [ecx+APPDATA.io_map], ebx
|
||||
mov dword [page_tabs + (tss._io_map_0 shr 10)], ebx
|
||||
mov eax, [eax+PROC.pdt_0_phys]
|
||||
mov cr3, eax
|
||||
sti
|
||||
|
||||
@@ -843,11 +830,10 @@ v86_irq:
|
||||
pop eax
|
||||
v86_irq2:
|
||||
mov esi, [v86_irqhooks+edi*8] ; get VM handle
|
||||
mov eax, [esi+V86_machine.pagedir]
|
||||
call get_pg_addr
|
||||
mov eax, [esi+V86_machine.process]
|
||||
mov ecx, [CURRENT_TASK]
|
||||
shl ecx, 8
|
||||
cmp [SLOT_BASE+ecx+APPDATA.dir_table], eax
|
||||
cmp [SLOT_BASE+ecx+APPDATA.process], eax
|
||||
jnz .notcurrent
|
||||
lea eax, [edi+8]
|
||||
cmp al, 10h
|
||||
@@ -860,7 +846,7 @@ v86_irq2:
|
||||
mov ebx, SLOT_BASE + 0x100
|
||||
mov ecx, [TASK_COUNT]
|
||||
.scan:
|
||||
cmp [ebx+APPDATA.dir_table], eax
|
||||
cmp [ebx+APPDATA.process], eax
|
||||
jnz .cont
|
||||
push ecx
|
||||
mov ecx, [ebx+APPDATA.saved_esp0]
|
||||
@@ -895,6 +881,7 @@ v86_irq2:
|
||||
popad
|
||||
iretd
|
||||
.found:
|
||||
mov eax, [eax+PROC.pdt_0_phys]
|
||||
mov cr3, eax
|
||||
mov esi, [ebx+APPDATA.saved_esp0]
|
||||
sub word [esi-sizeof.v86_regs+v86_regs.esp], 6
|
||||
|
Reference in New Issue
Block a user