kolibrios/kernel/trunk/core/memory.inc
Jurgen 5eb750c289 1. Edit procedure check exception 12 (overflow stack)
2. Edit func 68,24
3. Add proc "control exception"
4. Add subfuncs func 51 (GetPriorityThread, SetPriorityThread,GetCurrentThreadId)
5. Add info in ReferenceFunc(rus)

git-svn-id: svn://kolibrios.org@10002 a494cfbc-eb01-0410-851d-a64ba20cac60
2024-03-23 19:19:24 +00:00

1450 lines
34 KiB
PHP

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2022. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
align 4
proc alloc_page
pushfd
cli
push ebx
cmp [pg_data.pages_free], 1
jle .out_of_memory
mov ebx, [page_start]
mov ecx, [page_end]
.l1:
bsf eax, [ebx];
jnz .found
add ebx, 4
cmp ebx, ecx
jb .l1
pop ebx
popfd
xor eax, eax
ret
.found:
dec [pg_data.pages_free]
jz .out_of_memory
btr [ebx], eax
mov [page_start], ebx
sub ebx, sys_pgmap
lea eax, [eax+ebx*8]
shl eax, 12
; dec [pg_data.pages_free]
pop ebx
popfd
ret
.out_of_memory:
mov [pg_data.pages_free], 1
xor eax, eax
pop ebx
popfd
ret
endp
align 4
proc alloc_pages stdcall, count:dword
pushfd
push ebx
push edi
cli
mov eax, [count]
add eax, 7
shr eax, 3
mov [count], eax
mov ebx, [pg_data.pages_free]
sub ebx, 9
js .out_of_memory
shr ebx, 3
cmp eax, ebx
jg .out_of_memory
mov ecx, [page_start]
mov ebx, [page_end]
.find:
mov edx, [count]
mov edi, ecx
.match:
cmp byte [ecx], 0xFF
jne .next
dec edx
jz .ok
inc ecx
cmp ecx, ebx
jb .match
.out_of_memory:
.fail:
xor eax, eax
pop edi
pop ebx
popfd
ret
.next:
inc ecx
cmp ecx, ebx
jb .find
pop edi
pop ebx
popfd
xor eax, eax
ret
.ok:
sub ecx, edi
inc ecx
push esi
mov esi, edi
xor eax, eax
rep stosb
sub esi, sys_pgmap
shl esi, 3+12
mov eax, esi
mov ebx, [count]
shl ebx, 3
sub [pg_data.pages_free], ebx
pop esi
pop edi
pop ebx
popfd
ret
endp
align 4
;proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
map_page:
push ebx
mov eax, [esp+12] ; phis_addr
or eax, [esp+16] ; flags
and eax, [pte_valid_mask]
mov ebx, [esp+8] ; lin_addr
shr ebx, 12
mov [page_tabs + ebx*4], eax
mov eax, [esp+8] ; lin_addr
pop ebx
invlpg [eax]
ret 12
align 4
map_space: ;not implemented
ret
align 4
proc free_page
;arg: eax page address
pushfd
cli
shr eax, 12 ;page index
bts dword [sys_pgmap], eax ;that's all!
cmc
adc [pg_data.pages_free], 0
shr eax, 3
and eax, not 3 ;dword offset from page_map
add eax, sys_pgmap
cmp [page_start], eax
ja @f
popfd
ret
@@:
mov [page_start], eax
popfd
ret
endp
align 4
proc map_io_mem stdcall, base:dword, size:dword, flags:dword
push ebx
push edi
mov eax, [size]
add eax, [base]
add eax, PAGE_SIZE-1
and eax, -PAGE_SIZE
mov ecx, [base]
and ecx, -PAGE_SIZE
sub eax, ecx
mov [size], eax
stdcall alloc_kernel_space, eax
test eax, eax
jz .fail
push eax
mov edi, PAGE_SIZE
mov ebx, eax
mov ecx, [size]
mov edx, [base]
shr eax, 12
shr ecx, 12
or edx, [flags]
and edx, [pte_valid_mask]
@@:
mov [page_tabs + eax*4], edx
invlpg [ebx]
inc eax
add ebx, edi
add edx, edi
loop @B
pop eax
mov edx, [base]
and edx, PAGE_SIZE-1
add eax, edx
.fail:
pop edi
pop ebx
ret
endp
; param
; eax= page base + page flags
; ebx= linear address
; ecx= count
align 4
commit_pages:
test ecx, ecx
jz .fail
push edi
push eax
push ecx
mov ecx, pg_data.mutex
call mutex_lock
pop ecx
pop eax
and eax, [pte_valid_mask ]
mov edi, ebx
shr edi, 12
lea edi, [page_tabs + edi*4]
@@:
stosd
invlpg [ebx]
add eax, PAGE_SIZE
add ebx, PAGE_SIZE
loop @B
pop edi
mov ecx, pg_data.mutex
call mutex_unlock
.fail:
ret
; param
; eax= base
; ecx= count
align 4
release_pages:
push ebp
push esi
push edi
push ebx
mov esi, eax
mov edi, eax
shr esi, 12
lea esi, [page_tabs + esi*4]
push ecx
mov ecx, pg_data.mutex
call mutex_lock
pop ecx
mov ebp, [pg_data.pages_free]
mov ebx, [page_start]
mov edx, sys_pgmap
@@:
xor eax, eax
xchg eax, [esi]
invlpg [edi]
test eax, 1
jz .next
shr eax, 12
bts [edx], eax
cmc
adc ebp, 0
shr eax, 3
and eax, -4
add eax, edx
cmp eax, ebx
jae .next
mov ebx, eax
.next:
add edi, PAGE_SIZE
add esi, 4
loop @B
mov [pg_data.pages_free], ebp
mov ecx, pg_data.mutex
call mutex_unlock
pop ebx
pop edi
pop esi
pop ebp
ret
; param
; eax= base
; ecx= count
align 4
unmap_pages:
push edi
mov edi, eax
mov edx, eax
shr edi, 10
add edi, page_tabs
xor eax, eax
@@:
stosd
invlpg [edx]
add edx, PAGE_SIZE
loop @b
pop edi
ret
align 4
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
push ebx
mov ebx, [lin_addr]
shr ebx, 22
mov eax, [phis_addr]
and eax, -PAGE_SIZE
or eax, PG_UWR
mov dword [master_tab + ebx*4], eax
mov eax, [lin_addr]
shr eax, 10
add eax, page_tabs
invlpg [eax]
pop ebx
ret
endp
uglobal
sb16_buffer_allocated db 0
endg
; Allocates [.size] bytes so that the target memory block
; is inside one 64K page for 24-bit DMA controller,
; that is, somewhere between 00xx0000h and 00xxFFFFh.
proc alloc_dma24
; Implementation note.
; The only user of that function is SB16 driver,
; so just return a statically allocated buffer.
virtual at esp
dd ? ; return address
.size dd ?
end virtual
cmp [sb16_buffer_allocated], 0
jnz .fail
inc [sb16_buffer_allocated]
mov eax, SB16Buffer
ret 4
.fail:
xor eax, eax
ret 4
endp
; Allocates a physical page for master page table
; that duplicates first Mb of OS_BASE at address 0;
; used for starting APs and for shutting down,
; where it is important to execute code in trivial-mapped pages.
; Returns eax = allocated physical page.
proc create_trampoline_pgmap
; The only non-trivial moment:
; we need a linear address to fill information,
; but we don't need it outside of this function,
; so we're returning physical address.
; Therefore, allocate memory with kernel_alloc,
; this will allocate physical page and a linear address somewhere,
; and deallocate only linear address with free_kernel_space.
stdcall kernel_alloc, PAGE_SIZE
mov edi, eax
mov esi, master_tab
mov ecx, PAGE_SIZE/4
rep movsd
mov ecx, [master_tab + (OS_BASE shr 20)]
mov [eax], ecx
mov edi, eax
call get_pg_addr
push eax
stdcall free_kernel_space, edi
pop eax
ret
endp
align 4
proc new_mem_resize stdcall, new_size:dword
push ebx
push esi
push edi
mov edx, [current_slot]
mov ebx, [edx + APPDATA.process]
cmp [ebx + PROC.heap_base], 0
jne .exit
mov edi, [new_size]
add edi, PAGE_SIZE-1
and edi, -PAGE_SIZE
mov [new_size], edi
mov esi, [ebx + PROC.mem_used]
add esi, PAGE_SIZE-1
and esi, -PAGE_SIZE
cmp edi, esi
ja .expand
je .exit
mov ebx, edi
shr edi, 12
shr esi, 12
mov ecx, pg_data.mutex
call mutex_lock
@@:
mov eax, [app_page_tabs + edi*4]
test eax, 1
jz .next
mov dword [app_page_tabs + edi*4], 0
invlpg [ebx]
call free_page
.next:
inc edi
add ebx, PAGE_SIZE
cmp edi, esi
jb @B
mov ecx, pg_data.mutex
call mutex_unlock
.update_size:
mov edx, [current_slot]
mov ebx, [new_size]
mov edx, [edx + APPDATA.process]
mov [edx + PROC.mem_used], ebx
.exit:
pop edi
pop esi
pop ebx
xor eax, eax
ret
.expand:
mov ecx, pg_data.mutex
call mutex_lock
xchg esi, edi
push esi ;new size
push edi ;old size
add edi, 0x3FFFFF
and edi, not(0x3FFFFF)
add esi, 0x3FFFFF
and esi, not(0x3FFFFF)
cmp edi, esi
jae .grow
@@:
call alloc_page
test eax, eax
jz .exit_fail
stdcall map_page_table, edi, eax
push edi
shr edi, 10
add edi, page_tabs
mov ecx, 1024
xor eax, eax
cld
rep stosd
pop edi
add edi, 0x00400000
cmp edi, esi
jb @B
.grow:
pop edi ;old size
pop ecx ;new size
shr edi, 10
shr ecx, 10
sub ecx, edi
shr ecx, 2 ;pages count
mov eax, 2
add edi, app_page_tabs
rep stosd
mov ecx, pg_data.mutex
call mutex_unlock
jmp .update_size
.exit_fail:
mov ecx, pg_data.mutex
call mutex_unlock
add esp, 8
pop edi
pop esi
pop ebx
xor eax, eax
inc eax
ret
endp
; param
; eax= linear address
;
; retval
; eax= physical page address
align 4
get_pg_addr:
sub eax, OS_BASE
cmp eax, 0x400000
jb @f
shr eax, 12
mov eax, [page_tabs + (eax+(OS_BASE shr 12))*4]
@@:
and eax, -PAGE_SIZE
ret
align 4
; Now it is called from core/sys32::exc_c (see stack frame there)
proc page_fault_handler
.err_addr equ ebp-4
push ebx ;save exception number (#PF)
mov ebp, esp
mov ebx, cr2
push ebx ;that is locals: .err_addr = cr2
inc [pg_data.pages_faults]
mov eax, [pf_err_code]
cmp ebx, OS_BASE ;ebx == .err_addr
jb .user_space ;page in application memory
cmp ebx, page_tabs
jb .kernel_space ;page in kernel memory
cmp ebx, kernel_tabs
jb .alloc;.app_tabs ;page tables of application ;
;simply create one
.core_tabs:
.fail: ;simply return to caller
mov esp, ebp
pop ebx ;restore exception number (#PF)
ret
.user_space:
test eax, PG_READ
jnz .err_access ;Page presents
;Access error ?
shr ebx, 12
mov ecx, ebx
shr ecx, 10
mov edx, [master_tab + ecx*4]
test edx, PG_READ
jz .fail ;page table is not created
;incorrect address in program
mov eax, [page_tabs + ebx*4]
test eax, 2
jz .fail ;address is not reserved for usage. Error
.alloc:
call alloc_page
test eax, eax
jz .fail
stdcall map_page, [.err_addr], eax, PG_UWR
mov edi, [.err_addr]
and edi, -PAGE_SIZE
mov ecx, 1024
xor eax, eax
;cld ;caller is duty for this
rep stosd
.exit: ;iret with repeat fault instruction
add esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller
restore_ring3_context
iretd
.err_access:
; access denied? this may be a result of copy-on-write protection for DLL
; check list of HDLLs
and ebx, -PAGE_SIZE
mov eax, [current_process]
mov eax, [eax + PROC.dlls_list_ptr]
test eax, eax
jz .fail
mov esi, [eax + HDLL.fd]
.scan_hdll:
cmp esi, eax
jz .fail
mov edx, ebx
sub edx, [esi + HDLL.base]
cmp edx, [esi + HDLL.size]
jb .fault_in_hdll
.scan_hdll.next:
mov esi, [esi + HDLL.fd]
jmp .scan_hdll
.fault_in_hdll:
; allocate new page, map it as rw and copy data
call alloc_page
test eax, eax
jz .fail
stdcall map_page, ebx, eax, PG_UWR
mov edi, ebx
mov ecx, 1024
sub ebx, [esi + HDLL.base]
mov esi, [esi + HDLL.parent]
mov esi, [esi + DLLDESCR.data]
add esi, ebx
rep movsd
jmp .exit
.kernel_space:
test eax, PG_READ
jz .fail ;page does not present
test eax, 12 ;U/S (+below)
jnz .fail ;application requested kernel memory
;test eax, 8
;jnz .fail ;the reserved bit is set in page tables. Added in P4/Xeon
;an attempt to write to a protected kernel page
cmp ebx, tss._io_map_0
jb .fail
cmp ebx, tss._io_map_0+8192
jae .fail
; io permission map
; copy-on-write protection
call alloc_page
test eax, eax
jz .fail
push eax
stdcall map_page, [.err_addr], eax, dword PG_SWR
pop eax
mov edi, [.err_addr]
and edi, -PAGE_SIZE
lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
mov ebx, esi
shr ebx, 12
mov edx, [current_slot]
or eax, PG_SWR
mov [edx + APPDATA.io_map + ebx*4], eax
add esi, [default_io_map]
mov ecx, PAGE_SIZE/4
;cld ;caller is duty for this
rep movsd
jmp .exit
endp
; returns number of mapped bytes
proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\
ofs:dword,buf_size:dword,req_access:dword
locals
count dd ?
process dd ?
endl
mov [count], 0
cmp [buf_size], 0
jz .exit
mov eax, [slot]
shl eax, BSF sizeof.APPDATA
mov eax, [SLOT_BASE + eax + APPDATA.process]
test eax, eax
jz .exit
mov [process], eax
mov ebx, [ofs]
shr ebx, 22
mov eax, [eax + PROC.pdt_0 + ebx*4] ;get page table
mov esi, [ipc_ptab]
and eax, -PAGE_SIZE
jz .exit
stdcall map_page, esi, eax, PG_SWR
@@:
mov edi, [lin_addr]
and edi, -PAGE_SIZE
mov ecx, [buf_size]
add ecx, PAGE_SIZE-1
shr ecx, 12
inc ecx ; ???????????
mov edx, [ofs]
shr edx, 12
and edx, 0x3FF
.map:
stdcall safe_map_page, [slot], [req_access], [ofs]
jnc .exit
add [count], PAGE_SIZE
add [ofs], PAGE_SIZE
dec ecx
jz .exit
add edi, PAGE_SIZE
inc edx
cmp edx, 1024
jnz .map
inc ebx
mov eax, [process]
mov eax, [eax + PROC.pdt_0 + ebx*4]
and eax, -PAGE_SIZE
jz .exit
stdcall map_page, esi, eax, PG_SWR
xor edx, edx
jmp .map
.exit:
mov eax, [count]
ret
endp
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
ofs:dword,buf_size:dword,req_access:dword
locals
count dd ?
process dd ?
endl
mov [count], 0
cmp [buf_size], 0
jz .exit
mov eax, [slot]
shl eax, BSF sizeof.APPDATA
mov eax, [SLOT_BASE + eax + APPDATA.process]
test eax, eax
jz .exit
mov [process], eax
mov ebx, [ofs]
shr ebx, 22
mov eax, [eax + PROC.pdt_0 + ebx*4] ;get page table
mov esi, [proc_mem_tab]
and eax, -PAGE_SIZE
jz .exit
stdcall map_page, esi, eax, PG_SWR
@@:
mov edi, [lin_addr]
and edi, -PAGE_SIZE
mov ecx, [buf_size]
add ecx, PAGE_SIZE-1
shr ecx, 12
inc ecx ; ???????????
mov edx, [ofs]
shr edx, 12
and edx, 0x3FF
.map:
stdcall safe_map_page, [slot], [req_access], [ofs]
jnc .exit
add [count], PAGE_SIZE
add [ofs], PAGE_SIZE
dec ecx
jz .exit
add edi, PAGE_SIZE
inc edx
cmp edx, 1024
jnz .map
inc ebx
mov eax, [process]
mov eax, [eax + PROC.pdt_0 + ebx*4]
and eax, -PAGE_SIZE
jz .exit
stdcall map_page, esi, eax, PG_SWR
xor edx, edx
jmp .map
.exit:
mov eax, [count]
ret
endp
; in: esi+edx*4 = pointer to page table entry
; in: [slot], [req_access], [ofs] on the stack
; in: edi = linear address to map
; out: CF cleared <=> failed
; destroys: only eax
proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
mov eax, [esi + edx*4]
test al, PG_READ
jz .not_present
test al, PG_WRITE
jz .resolve_readonly
; normal case: writable page, just map with requested access
.map:
stdcall map_page, edi, eax, [req_access]
stc
.fail:
ret
.not_present:
; check for alloc-on-demand page
test al, 2
jz .fail
; allocate new page, save it to source page table
push ecx
call alloc_page
pop ecx
test eax, eax
jz .fail
or al, PG_UWR
mov [esi + edx*4], eax
jmp .map
.resolve_readonly:
; readonly page, probably copy-on-write
; check: readonly request of readonly page is ok
test [req_access], PG_WRITE
jz .map
; find control structure for this page
pushf
cli
cld
push ebx ecx
mov eax, [slot]
shl eax, BSF sizeof.APPDATA
mov eax, [SLOT_BASE + eax + APPDATA.process]
mov eax, [eax + PROC.dlls_list_ptr]
test eax, eax
jz .no_hdll
mov ecx, [eax + HDLL.fd]
.scan_hdll:
cmp ecx, eax
jz .no_hdll
mov ebx, [ofs]
and ebx, -PAGE_SIZE
sub ebx, [ecx + HDLL.base]
cmp ebx, [ecx + HDLL.size]
jb .hdll_found
mov ecx, [ecx + HDLL.fd]
jmp .scan_hdll
.no_hdll:
pop ecx ebx
popf
clc
ret
.hdll_found:
; allocate page, save it in page table, map it, copy contents from base
mov eax, [ecx + HDLL.parent]
add ebx, [eax + DLLDESCR.data]
call alloc_page
test eax, eax
jz .no_hdll
or al, PG_UWR
mov [esi + edx*4], eax
stdcall map_page, edi, eax, [req_access]
push esi edi
mov esi, ebx
mov ecx, PAGE_SIZE/4
rep movsd
pop edi esi
pop ecx ebx
popf
stc
ret
endp
sys_IPC:
;input:
; ebx=1 - set ipc buffer area
; ecx=address of buffer
; edx=size of buffer
; eax=2 - send message
; ebx=PID
; ecx=address of message
; edx=size of message
dec ebx
jnz @f
mov eax, [current_slot]
pushf
cli
mov [eax + APPDATA.ipc_start], ecx ;set fields in extended information area
mov [eax + APPDATA.ipc_size], edx
add edx, ecx
add edx, PAGE_SIZE-1
and edx, -PAGE_SIZE
.touch:
mov eax, [ecx]
add ecx, PAGE_SIZE
cmp ecx, edx
jb .touch
popf
mov [esp + SYSCALL_STACK.eax], ebx ;ebx=0
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;2
@@:
dec ebx
jnz @f
stdcall sys_ipc_send, ecx, edx, esi
mov [esp + SYSCALL_STACK.eax], eax
ret
@@:
or eax, -1
mov [esp + SYSCALL_STACK.eax], eax
ret
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
locals
dst_slot dd ?
dst_offset dd ?
buf_size dd ?
used_buf dd ?
endl
pushf
cli
mov eax, [PID]
call pid_to_slot
test eax, eax
jz .no_pid
mov [dst_slot], eax
shl eax, BSF sizeof.APPDATA
mov edi, [SLOT_BASE + eax + APPDATA.ipc_start] ;is ipc area defined?
test edi, edi
jz .no_ipc_area
mov ebx, edi
and ebx, 0xFFF
mov [dst_offset], ebx
mov esi, [SLOT_BASE + eax + APPDATA.ipc_size]
mov [buf_size], esi
mov ecx, [ipc_tmp]
cmp esi, 0x40000-0x1000; size of [ipc_tmp] minus one page
jbe @f
push esi edi
add esi, 0x1000
stdcall alloc_kernel_space, esi
mov ecx, eax
pop edi esi
@@:
mov [used_buf], ecx
stdcall map_mem_ipc, ecx, [dst_slot], \
edi, esi, PG_SWR
mov edi, [dst_offset]
add edi, [used_buf]
cmp dword [edi], 0
jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now
mov edx, dword [edi+4]
lea ebx, [edx+8]
add ebx, [msg_size]
cmp ebx, [buf_size]
ja .buffer_overflow ;esi<0 - not enough memory in buffer
mov dword [edi+4], ebx
mov eax, [current_slot]
mov eax, [eax + APPDATA.tid] ;eax - our PID
add edi, edx
mov [edi], eax
mov ecx, [msg_size]
mov [edi+4], ecx
add edi, 8
mov esi, [msg_addr]
; add esi, std_application_base_address
cld
rep movsb
mov ebx, [ipc_tmp]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [page_tabs + ebx*4], eax
invlpg [edx]
mov ebx, [ipc_pdir]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [page_tabs + ebx*4], eax
invlpg [edx]
mov ebx, [ipc_ptab]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [page_tabs + ebx*4], eax
invlpg [edx]
mov eax, [dst_slot]
shl eax, BSF sizeof.APPDATA
or [SLOT_BASE + eax + APPDATA.occurred_events], EVENT_IPC
push 0
jmp .ret
.no_pid:
popf
mov eax, 4
ret
.no_ipc_area:
popf
xor eax, eax
inc eax
ret
.ipc_blocked:
push 2
jmp .ret
.buffer_overflow:
push 3
.ret:
mov eax, [used_buf]
cmp eax, [ipc_tmp]
je @f
stdcall free_kernel_space, eax
@@:
pop eax
popf
ret
endp
align 4
sysfn_meminfo:
cmp ecx, OS_BASE
jae .fail
mov eax, [pg_data.pages_count]
mov [ecx], eax
shl eax, 12
mov [esp + SYSCALL_STACK.eax], eax
mov eax, [pg_data.pages_free]
mov [ecx + 4], eax
mov eax, [pg_data.pages_faults]
mov [ecx + 8], eax
mov eax, [heap_size]
mov [ecx + 12], eax
mov eax, [heap_free]
mov [ecx + 16], eax
mov eax, [heap_blocks]
mov [ecx + 20], eax
mov eax, [free_blocks]
mov [ecx + 24], eax
ret
.fail:
or dword [esp + SYSCALL_STACK.eax], -1
ret
align 4
f68:
cmp ebx, 4
jbe sys_sheduler
cmp ebx, 11
jb undefined_syscall
cmp ebx, 31
ja undefined_syscall
xor eax, eax
jmp dword [f68call + ebx*4-11*4]
.11:
call init_heap
mov [esp + SYSCALL_STACK.eax], eax
ret
.12:
stdcall user_alloc, ecx
mov [esp + SYSCALL_STACK.eax], eax
ret
.13:
stdcall user_free, ecx
mov [esp + SYSCALL_STACK.eax], eax
ret
.14:
cmp ecx, OS_BASE
jae .fail
mov edi, ecx
call get_event_ex
mov [esp + SYSCALL_STACK.eax], eax
ret
.16:
test ecx, ecx
jz .fail
cmp ecx, OS_BASE
jae .fail
stdcall get_service, ecx
mov [esp + SYSCALL_STACK.eax], eax
ret
.17:
call srv_handlerEx ;ecx
mov [esp + SYSCALL_STACK.eax], eax
ret
.18:
mov eax, edx
.19:
stdcall is_string_userspace, ecx
jnz .fail
stdcall load_library, ecx, eax
mov [esp + SYSCALL_STACK.eax], eax
ret
.20:
mov eax, edx
mov ebx, ecx
call user_realloc ;in: eax = pointer, ebx = new size
mov [esp + SYSCALL_STACK.eax], eax
ret
.21:
cmp ecx, OS_BASE
jae .fail
cmp edx, OS_BASE
jae .fail
stdcall load_pe_driver, ecx, edx
mov [esp + SYSCALL_STACK.eax], eax
ret
.22:
cmp ecx, OS_BASE
jae .fail
stdcall shmem_open, ecx, edx, esi
mov [esp + SYSCALL_STACK.edx], edx
mov [esp + SYSCALL_STACK.eax], eax
ret
.23:
cmp ecx, OS_BASE
jae .fail
stdcall shmem_close, ecx
mov [esp + SYSCALL_STACK.eax], eax
ret
.24:
mov eax, [current_slot]
xchg ecx, [eax + APPDATA.exc_handler]
xchg edx, [eax + APPDATA.except_mask]
xchg esi, [eax + APPDATA.exc_reserve_stack]
mov [esp + SYSCALL_STACK.ebx], edx
mov [esp + SYSCALL_STACK.eax], ecx
ret
.25:
cmp ecx, 32
jae .fail
mov eax, [current_slot]
btr [eax + APPDATA.except_mask], ecx
setc byte[esp + SYSCALL_STACK.eax]
jecxz @f
bts [eax + APPDATA.except_mask], ecx
@@:
ret
.26:
stdcall user_unmap, ecx, edx, esi
mov [esp + SYSCALL_STACK.eax], eax
ret
.27:
cmp ecx, OS_BASE
jae .fail
stdcall load_file_umode, ecx
mov [esp + SYSCALL_STACK.edx], edx
mov [esp + SYSCALL_STACK.eax], eax
ret
.28:
cmp ecx, OS_BASE
jae .fail
push ecx edx
stdcall kernel_alloc, maxPathLength
mov edi, eax
pop eax esi
push edi
call getFullPath
pop ebp
test eax, eax
jz @f
stdcall load_file_umode, ebp
mov [esp + SYSCALL_STACK.edx], edx
@@:
mov [esp + SYSCALL_STACK.eax], eax
stdcall kernel_free, ebp
ret
.29:
stdcall user_ring, ecx
mov [esp + SYSCALL_STACK.eax], eax
ret
; unload driver
.30: ; ecx = handl driver edx = cmdline
mov eax, -1
cmp edx, OS_BASE
jae .fail
cmp ecx, OS_BASE
jbe .fail
cmp [ecx+SRV.magic], ' SRV'
jne .fail
cmp [ecx+SRV.size], sizeof.SRV
jne .fail
mov eax, [ecx + SRV.entry]
test eax, eax
jz .fail
push ecx ;save handl
push edx ;cmdline
push DRV_EXIT
call eax ;the result is not checked
lea esp, [esp+8]
push ecx
mov ebx, [ecx + SRV.base]
mov eax, -2 ;error free RAM
test ebx, ebx
jz .fail
stdcall kernel_free, ebx ;del driver
mov eax, [ecx + SRV.fd]
mov edx, [ecx + SRV.bk]
mov [edx + SRV.fd], eax
mov [eax + SRV.bk], edx
stdcall free, ecx
;dec [count_services]
mov [esp + SYSCALL_STACK.eax], eax
ret
.31: ; get list service
test ecx, ecx
jz .fail ; get count
dec ecx
jnz @f ;1 - get pointer first and last structure
mov ebx, [srv.fd]
mov ecx, [srv.bk]
mov [esp + SYSCALL_STACK.ebx], ebx ;fd
mov [esp + SYSCALL_STACK.ecx], ecx ;bk
mov [esp + SYSCALL_STACK.eax], 0
ret
@@:
dec ecx
jnz .fail ; 2 - get info for SRV structure
mov eax, -1
cmp edx, OS_BASE ; edx = pointer on structure
jbe .fail
stdcall is_region_userspace, edi, 40 ;16+4*6=40 <-max size buffer
jnz .fail ; edi = pointer on buffer
cmp [edx + SRV.magic], ' SRV'
jne .fail
cmp [edx + SRV.size], sizeof.SRV
jne .fail
mov esi, edx
movsd ; name service 16 byte
movsd
movsd
movsd
lea esi, [edx+SRV.fd]
movsd ; SRV.fd
movsd ; SRV.bk
movsd ; SRV.base
movsd ; SRV.entry
movsd ; SRV.srv_proc
;movsd ; SRV.srv_proc_ex
xor eax, eax
.fail:
mov [esp + SYSCALL_STACK.eax], eax
ret
align 4
f68call: ; keep this table closer to main code
dd f68.11 ; init_heap
dd f68.12 ; user_alloc
dd f68.13 ; user_free
dd f68.14 ; get_event_ex
dd f68.fail ; moved to f68.24
dd f68.16 ; get_service
dd f68.17 ; call_service
dd f68.18 ; loadLibUnicode
dd f68.19 ; load_dll
dd f68.20 ; user_realloc
dd f68.21 ; load_driver
dd f68.22 ; shmem_open
dd f68.23 ; shmem_close
dd f68.24 ; set exception handler
dd f68.25 ; unmask exception
dd f68.26 ; user_unmap
dd f68.27 ; load_file_umode
dd f68.28 ; loadFileUnicode
dd f68.29 ; user_ring
dd f68.30 ; unload_driver
dd f68.31 ; get_driver_info
align 4
proc load_pe_driver stdcall, file:dword, cmdline:dword
push esi
stdcall load_PE, [file]
test eax, eax
jz .fail
mov esi, eax
push ebx ; base addres driver
push [cmdline]
push DRV_ENTRY
call eax
pop ecx
pop ecx
pop ebx
test eax, eax
jz .fail_init
mov [eax + SRV.base], ebx
mov [eax + SRV.entry], esi
pop esi
ret
.fail_init:
stdcall kernel_free, ebx ;clear memory driver
.fail:
xor eax, eax
pop esi
ret
endp
align 4
proc create_ring_buffer stdcall, size:dword, flags:dword
locals
buf_ptr dd ?
endl
mov eax, [size]
test eax, eax
jz .fail
add eax, eax
stdcall alloc_kernel_space, eax
test eax, eax
jz .fail
push ebx
mov [buf_ptr], eax
mov ebx, [size]
shr ebx, 12
push ebx
stdcall alloc_pages, ebx
pop ecx
test eax, eax
jz .mm_fail
push edi
or eax, [flags]
mov edi, [buf_ptr]
mov ebx, [buf_ptr]
mov edx, ecx
shl edx, 2
shr edi, 10
@@:
mov [page_tabs + edi], eax
mov [page_tabs + edi + edx], eax
invlpg [ebx]
invlpg [ebx+0x10000]
add eax, 0x1000
add ebx, 0x1000
add edi, 4
dec ecx
jnz @B
mov eax, [buf_ptr]
pop edi
pop ebx
ret
.mm_fail:
stdcall free_kernel_space, [buf_ptr]
xor eax, eax
pop ebx
.fail:
ret
endp
align 4
proc print_mem
mov edi, BOOT.memmap_blocks
mov ecx, [edi-4]
test ecx, ecx
jz .done
@@:
mov eax, [edi]
mov edx, [edi+4]
add eax, [edi+8]
adc edx, [edi+12]
DEBUGF 1, "K : E820 %x%x - %x%x type %d\n", \
[edi+4], [edi],\
edx, eax, [edi+16]
add edi, 20
dec ecx
jnz @b
.done:
ret
endp