Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 203 → Rev 204

/kernel/tags/kolibri0.6.3.0/core/memory.inc
0,0 → 1,1328
 
tmp_page_tab equ 0x01000000
 
align 4
proc mem_test
mov eax, cr0
or eax, (CR0_CD+CR0_NW);disable caching
mov cr0, eax
wbinvd ;invalidate cache
 
xor edi, edi
mov ebx, 'TEST'
@@:
add edi, 0x400000
xchg ebx, dword [edi]
cmp dword [edi], 'TEST'
xchg ebx, dword [edi]
je @b
 
and eax, not (CR0_CD+CR0_NW)
mov cr0, eax
mov eax, edi
ret
endp
 
align 4
proc init_memEx
xor eax, eax
mov edi, sys_pgdir
mov ecx, 2048
rep stosd
 
bt [cpu_caps], CAPS_PSE
jnc .no_PSE
 
mov ebx, cr4
or ebx, CR4_PSE
mov eax, PG_LARGE+PG_SW
bt [cpu_caps], CAPS_PGE
jnc @F
or eax, PG_GLOBAL
or ebx, CR4_PGE
 
@@:
mov cr4, ebx
 
mov dword [sys_pgdir], eax
add eax, 0x00400000
mov dword [sys_pgdir+4], eax
add eax, 0x00400000
mov dword [sys_pgdir+8], eax
add eax, 0x00400000
mov dword [sys_pgdir+12], eax
 
mov dword [sys_pgdir+0x600], sys_pgdir+PG_SW
 
mov ecx, [pg_data.kernel_tables]
sub ecx, 4
mov eax, tmp_page_tab+PG_SW
mov edi, sys_pgdir+16
 
jmp .map_kernel_tabs
.no_PSE:
mov eax, PG_SW
mov esi, tmp_page_tab
mov ecx, 4096/4 ;0x0 - 0x00FFFFFF
.map_low:
mov [esi], eax
add eax, 0x1000
mov [esi+4], eax
add eax, 0x1000
mov [esi+8], eax
add eax, 0x1000
mov [esi+12], eax
add eax, 0x1000
add esi, 16
dec ecx
jnz .map_low ;ÿäðî
 
mov ecx, [pg_data.kernel_tables]
mov eax, tmp_page_tab+PG_SW
mov edi, sys_pgdir
 
.map_kernel_tabs:
 
mov [edi], eax
add eax, 0x1000
add edi, 4
dec ecx
jnz .map_kernel_tabs
 
mov edi, tmp_page_tab
bt [cpu_caps], CAPS_PSE
jc @F
add edi, 4096*4 ;skip low kernel memory
@@:
mov ecx, [pg_data.kernel_tables]
sub ecx, 4
shl ecx, 10
xor eax, eax
cld
rep stosd
 
mov dword [sys_pgdir+0x600], sys_pgdir+PG_SW
 
ret
endp
 
align 4
proc init_page_map
mov edi, sys_pgmap
mov ecx, 512/4
xor eax,eax
cld
rep stosd
 
not eax
mov ecx, [pg_data.pagemap_size]
sub ecx, 512
shr ecx, 2
rep stosd
 
mov edi, sys_pgmap+512
mov edx, [pg_data.pages_count]
mov ecx, [pg_data.kernel_tables]
bt [cpu_caps], CAPS_PSE
jnc @f
sub ecx, 4
@@:
sub edx, 4096
sub edx, ecx
mov [pg_data.pages_free], edx
 
xor eax, eax
mov ebx, ecx
shr ecx, 5
rep stosd
 
not eax
mov ecx, ebx
and ecx, 31
shl eax, cl
stosd
 
mov [page_start], sys_pgmap+512
mov ebx, sys_pgmap
add ebx, [pg_data.pagemap_size]
mov [page_end], ebx
 
mov [pg_data.pg_mutex], 0
 
ret
endp
 
align 4
proc alloc_page
 
pushfd
cli
mov ebx, [page_start]
mov ecx, [page_end]
.l1:
bsf eax,[ebx];
jnz .found
add ebx,4
cmp ebx, ecx
jb .l1
popfd
xor eax,eax
ret
.found:
btr [ebx], eax
mov [page_start],ebx
sub ebx, sys_pgmap
shl ebx, 3
add eax,ebx
shl eax, 12
dec [pg_data.pages_free]
popfd
ret
endp
 
align 4
proc alloc_pages stdcall, count:dword
pushfd
cli
mov eax, [count]
add eax, 7
shr eax, 3
mov [count], eax
cmp eax, [pg_data.pages_free]
ja .fail
 
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
.fail: xor eax, eax
popfd
ret
.next:
inc ecx
cmp ecx, ebx
jb .find
popfd
xor eax, eax
ret
.ok:
sub ecx, edi
inc ecx
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
popfd
ret
endp
 
align 4
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
mov eax, [phis_addr]
and eax, not 0xFFF
or eax, [flags]
mov ebx, [lin_addr]
shr ebx, 12
mov [pages_tab+ebx*4], eax
mov eax, [lin_addr]
invlpg [eax]
ret
endp
 
align 4
proc free_page
;arg: eax page address
pushfd
cli
inc [pg_data.pages_free]
shr eax, 12 ;page index
mov ebx, sys_pgmap
bts [ebx], eax ;that's all!
shr eax, 3
and eax, not 3 ;dword offset from page_map
add eax, ebx
cmp [page_start], eax
ja @f
popfd
ret
@@:
mov [page_start], eax
popfd
ret
endp
 
align 4
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
mov ebx, [lin_addr]
shr ebx, 22
mov eax, [phis_addr]
and eax, not 0xFFF
or eax, PG_UW ;+PG_NOCACHE
mov dword [current_pgdir+ebx*4], eax
mov eax, [lin_addr]
shr eax, 10
add eax, pages_tab
invlpg [eax]
ret
endp
 
align 4
proc init_LFB
 
cmp dword [LFBAddress], -1
jne @f
 
mov [0x2f0000+0x901c],byte 2
stdcall kernel_alloc, 0x280000
mov [LFBAddress], eax
 
ret
@@:
test [SCR_MODE],word 0100000000000000b
jz @f
call map_LFB
@@:
ret
endp
 
align 4
proc map_LFB
locals
pg_count dd ?
endl
 
mov edi, [LFBSize]
mov esi, [LFBAddress]
shr edi, 12
mov [pg_count], edi
shr edi, 10
 
bt [cpu_caps], CAPS_PSE
jnc .map_page_tables
mov ebx, esi
or esi, PG_LARGE+PG_UW
shr ebx, 20
mov ecx, ebx
@@:
mov [sys_pgdir+ebx], esi
add ebx, 4
add esi, 0x00400000
dec edi
jnz @B
 
or dword [sys_pgdir+ecx], PG_GLOBAL
mov eax, cr3 ;flush TLB
mov cr3, eax
ret
 
.map_page_tables:
 
@@:
call alloc_page
stdcall map_page_table, esi, eax
add esi, 0x00400000
dec edi
jnz @B
 
mov eax, [LFBAddress]
mov esi, eax
shr esi, 10
add esi, pages_tab
or eax, PG_UW
mov ecx, [pg_count]
shr ecx, 2
.map:
mov [esi], eax
add eax, 0x1000
mov [esi+4], eax
add eax, 0x1000
mov [esi+8], eax
add eax, 0x1000
mov [esi+12], eax
add eax, 0x1000
add esi, 16
sub ecx, 1
jnz .map
 
mov eax, cr3 ;flush TLB
mov cr3, eax
 
ret
endp
 
align 4
proc new_mem_resize stdcall, new_size:dword
 
stdcall wait_mutex, pg_data.pg_mutex
 
mov edi, [new_size]
add edi,4095
and edi,not 4095
mov [new_size], edi
 
mov edx,[CURRENT_TASK]
shl edx,8
cmp [PROC_BASE+APPDATA.heap_base+edx],0
jne .exit
 
mov esi, [PROC_BASE+APPDATA.mem_size+edx]
add esi, 4095
and esi, not 4095
 
cmp edi, esi
jae .expand
 
shr edi, 12
shr esi, 12
@@:
mov eax, [pages_tab+0x00181000+edi*4]
test eax, 1
jz .next
mov dword [pages_tab+0x00181000+edi*4], 2
mov ebx, edi
shl ebx, 12
invlpg [ebx+std_application_base_address]
call free_page
 
.next: add edi, 1
cmp edi, esi
jb @B
 
.update_size:
 
mov ebx, [new_size]
mov [PROC_BASE+0x8c+edx],ebx
 
;search threads and update
;application memory size infomation
mov ecx,[PROC_BASE+0xb8+edx]
mov eax,2
 
.search_threads:
;eax = current slot
;ebx = new memory size
;ecx = page directory
cmp eax,[TASK_COUNT]
jg .search_threads_end
mov edx,eax
shl edx,5
cmp word [CURRENT_TASK+edx+0xa],9 ;if slot empty?
jz .search_threads_next
shl edx,3
cmp [PROC_BASE+edx+0xb8],ecx ;if it is our thread?
jnz .search_threads_next
mov [PROC_BASE+edx+0x8c],ebx ;update memory size
.search_threads_next:
inc eax
jmp .search_threads
.search_threads_end:
xor eax, eax
dec [pg_data.pg_mutex]
ret
 
.expand:
add edi, new_app_base
add esi, new_app_base
 
push esi
push edi
 
add edi, 0x3FFFFF
and edi, not(0x3FFFFF)
add esi, 0x3FFFFF
and esi, not(0x3FFFFF)
 
cmp esi, edi
jae .grow
 
xchg esi, edi
 
@@:
call alloc_page
test eax, eax
jz .exit
 
stdcall map_page_table, edi, eax
 
push edi
shr edi, 10
add edi, pages_tab
mov ecx, 1024
xor eax, eax
cld
rep stosd
pop edi
 
add edi, 0x00400000
cmp edi, esi
jb @B
.grow:
pop edi
pop esi
@@:
call alloc_page
test eax, eax
jz .exit
stdcall map_page,esi,eax,dword PG_UW
 
push edi
mov edi, esi
xor eax, eax
mov ecx, 1024
cld
rep stosd
pop edi
 
add esi, 0x1000
cmp esi, edi
jna @B
 
jmp .update_size
.exit:
xor eax, eax
inc eax
dec [pg_data.pg_mutex]
ret
endp
 
align 4
proc get_pg_addr stdcall, lin_addr:dword
mov ebx, [lin_addr]
shr ebx, 12
mov eax, [pages_tab+ebx*4]
and eax, 0xFFFFF000
ret
endp
 
align 4
proc page_fault_handler
pushad
 
mov ebp, esp
mov eax, cr2
push eax
push ds
push es
 
mov ax, 0x10
mov ds, ax
mov es, ax
 
inc [pg_data.pages_faults]
 
mov ebx, [ebp-4]
 
cmp ebx, 0xe0000000
jae .lfb_addr
 
cmp ebx, 0x60400000
jae .user_space
 
cmp ebx, master_tab+0x1000
jae .alloc
 
cmp ebx, 0x60000000
jae .tab_space
 
jmp .kernel_space
 
.user_space:
shr ebx, 12
mov ecx, ebx
shr ecx, 10
mov edx, [master_tab+ecx*4]
test edx, 1
jz .fail
 
mov eax, [pages_tab+ebx*4]
test eax, 2
jz .fail
.alloc:
call alloc_page
and eax, eax
jz .exit
 
stdcall map_page,[ebp-4],eax,dword PG_UW
 
mov edi, [ebp-4]
and edi, 0xFFFFF000
mov ecx, 1024
xor eax, eax
cld
rep stosd
.exit:
pop es
pop ds
mov esp, ebp
popad
add esp, 4
iretd
.fail:
pop es
pop ds
mov esp, ebp
popad
add esp, 4
 
save_ring3_context ;debugger support
 
mov bl, 14
jmp exc_c
iretd
 
.kernel_space:
; shr ebx, 12
; mov eax, [pages_tab+ebx*4]
; shr ebx, 10
; mov eax, [master_tab+ebx*4]
jmp .exit
.old_addr:
; shr ebx, 12
; mov eax, [pages_tab+ebx*4]
; shr ebx, 10
; mov eax, [master_tab+ebx*4]
jmp .exit
.lfb_addr:
; shr ebx, 22
; ;mov ecx, [sys_page_dir]
; mov eax, [master_tab+ebx*4]
jmp .exit
.tab_space:
; shr ebx, 12
; mov eax, [pages_tab+ebx*4]
; shr ebx, 10
; ;mov ecx, [sys_page_dir]
; mov eax, [master_tab+ebx*4]
jmp .exit
endp
 
align 4
proc map_mem stdcall, lin_addr:dword,pdir:dword,\
ofs:dword,buf_size:dword
mov eax, [buf_size]
test eax, eax
jz .exit
 
mov eax, [pdir]
and eax, 0xFFFFF000
 
stdcall map_page,[ipc_pdir],eax,dword PG_UW
mov ebx, [ofs]
shr ebx, 22
mov esi, [ipc_pdir]
mov edi, [ipc_ptab]
mov eax, [esi+ebx*4]
and eax, 0xFFFFF000
test eax, eax
jz .exit
stdcall map_page,edi,eax,dword PG_UW
; inc ebx
; add edi, 0x1000
; mov eax, [esi+ebx*4]
; test eax, eax
; jz @f
; and eax, 0xFFFFF000
; stdcall map_page, edi, eax
 
@@: mov edi, [lin_addr]
and edi, 0xFFFFF000
mov ecx, [buf_size]
add ecx, 4095
shr ecx, 12
inc ecx
 
mov edx, [ofs]
shr edx, 12
and edx, 0x3FF
mov esi, [ipc_ptab]
 
.map: mov eax, [esi+edx*4]
and eax, 0xFFFFF000
test eax, eax
jz .exit
stdcall map_page,edi,eax,dword PG_UW
add edi, 0x1000
inc edx
dec ecx
jnz .map
 
.exit:
ret
endp
 
align 4
proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
ofs:dword,buf_size:dword
mov eax, [buf_size]
test eax, eax
jz .exit
 
mov eax, [pdir]
and eax, 0xFFFFF000
 
stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
mov ebx, [ofs]
shr ebx, 22
mov esi, [proc_mem_pdir]
mov edi, [proc_mem_tab]
mov eax, [esi+ebx*4]
and eax, 0xFFFFF000
test eax, eax
jz .exit
stdcall map_page,edi,eax,dword PG_UW
 
@@: mov edi, [lin_addr]
and edi, 0xFFFFF000
mov ecx, [buf_size]
add ecx, 4095
shr ecx, 12
inc ecx
 
mov edx, [ofs]
shr edx, 12
and edx, 0x3FF
mov esi, [proc_mem_tab]
 
.map: mov eax, [esi+edx*4]
; and eax, 0xFFFFF000
; test eax, eax
; jz .exit
stdcall map_page,edi,eax,dword PG_UW
add edi, 0x1000
inc edx
dec ecx
jnz .map
.exit:
ret
endp
 
 
 
 
sys_IPC:
;input:
; eax=1 - set ipc buffer area
; ebx=address of buffer
; ecx=size of buffer
; eax=2 - send message
; ebx=PID
; ecx=address of message
; edx=size of message
 
cmp eax,1
jne @f
call set_ipc_buff
mov [esp+36], eax
ret
@@:
cmp eax, 2
jne @f
stdcall sys_ipc_send, ebx, ecx, edx
mov [esp+36], eax
ret
@@:
xor eax, eax
not eax
mov [esp+36], eax
ret
 
align 4
proc set_ipc_buff
 
mov eax,[CURRENT_TASK]
shl eax,8
add eax, PROC_BASE
pushf
cli
mov [eax+0xA0],ebx ;set fields in extended information area
mov [eax+0xA4],ecx
 
add ebx, new_app_base
add ecx, ebx
add ecx, 4095
and ecx, not 4095
 
.touch: mov eax, [ebx]
add ebx, 0x1000
cmp ebx, ecx
jna .touch
 
popf
xor eax, eax
ret
endp
 
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
locals
dst_slot dd ?
dst_offset dd ?
buf_size dd ?
endl
 
pushf
cli
 
mov eax, [PID]
call pid_to_slot
test eax,eax
jz .no_pid
 
mov [dst_slot], eax
shl eax,8
mov edi,[eax+PROC_BASE+0xa0] ;is ipc area defined?
test edi,edi
jz .no_ipc_area
 
mov ebx, edi
add edi, new_app_base
and ebx, 0xFFF
mov [dst_offset], ebx
 
mov esi, [eax+PROC_BASE+0xa4]
mov [buf_size], esi
 
stdcall map_mem, [ipc_tmp], [PROC_BASE+eax+0xB8],\
edi, esi
 
mov edi, [dst_offset]
add edi, [ipc_tmp]
cmp dword [edi], 0
jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now
mov ebx, dword [edi+4]
mov edx, ebx
add ebx, 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,[TASK_BASE]
mov eax, [eax+0x04] ;eax - our PID
mov edi, [dst_offset]
add edi, [ipc_tmp]
add edi, edx
mov [edi], eax
mov ecx, [msg_size]
 
mov [edi+4], ecx
add edi, 8
mov esi, [msg_addr]
add esi, new_app_base
cld
rep movsb
 
mov ebx, [ipc_tmp]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [pages_tab+ebx*4], eax
invlpg [edx]
 
mov ebx, [ipc_pdir]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [pages_tab+ebx*4], eax
invlpg [edx]
 
mov ebx, [ipc_ptab]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [pages_tab+ebx*4], eax
invlpg [edx]
 
mov eax, [dst_slot]
shl eax, 8
or [eax+PROC_BASE+0xA8],dword 0x40
cmp dword [check_idle_semaphore],20
jge .ipc_no_cis
 
mov dword [check_idle_semaphore],5
.ipc_no_cis:
popf
xor eax, eax
ret
.no_pid:
popf
mov eax, 4
ret
.no_ipc_area:
popf
xor eax, eax
inc eax
ret
.ipc_blocked:
popf
mov eax, 2
ret
.buffer_overflow:
popf
mov eax, 3
ret
endp
 
align 4
sysfn_meminfo:
 
add ebx, new_app_base
cmp ebx, new_app_base
jb .fail
 
mov eax, [pg_data.pages_count]
mov [ebx], eax
shl eax, 12
mov [esp+36], eax
mov ecx, [pg_data.pages_free]
mov [ebx+4], ecx
mov edx, [pg_data.pages_faults]
mov [ebx+8], edx
mov esi, [heap_size]
mov [ebx+12], esi
mov edi, [heap_free]
mov [ebx+16], edi
mov eax, [heap_blocks]
mov [ebx+20], eax
mov ecx, [free_blocks]
mov [ebx+24], ecx
ret
.fail:
mov dword [esp+36], -1
ret
 
align 4
new_services:
 
cmp eax,4
jle sys_sheduler
 
cmp eax, 11
jb .fail
ja @f
 
call init_heap
mov [esp+36], eax
ret
@@:
cmp eax, 12
ja @f
 
stdcall user_alloc, ebx
mov [esp+36], eax
ret
@@:
cmp eax, 13
ja @f
add ebx, new_app_base
stdcall user_free, ebx
mov [esp+36], eax
ret
@@:
cmp eax, 14
ja @f
add ebx,new_app_base
cmp ebx, new_app_base
jb .fail
stdcall get_notify, ebx
ret
@@:
cmp eax, 15
ja @f
mov ecx, [CURRENT_TASK]
shl ecx, 8
mov eax, [ecx+PROC_BASE+APPDATA.fpu_handler]
mov [ecx+PROC_BASE+APPDATA.fpu_handler], ebx
mov [esp+36], eax
ret
@@:
cmp eax, 16
ja @f
 
test ebx, ebx
jz .fail
add ebx, new_app_base
cmp ebx, new_app_base
jb .fail
stdcall get_service, ebx
mov [esp+36], eax
ret
@@:
cmp eax, 17
ja @f
stdcall srv_handlerEx, ebx
mov [esp+36], eax
ret
@@:
cmp eax, 18
ja @f
mov ecx, [CURRENT_TASK]
shl ecx, 8
mov eax, [ecx+PROC_BASE+APPDATA.sse_handler]
mov [ecx+PROC_BASE+APPDATA.sse_handler], ebx
mov [esp+36], eax
ret
@@:
cmp eax, 19
ja @f
add ebx, new_app_base
cmp ebx, new_app_base
jb .fail
stdcall load_library, ebx
mov [esp+36], eax
ret
@@:
.fail:
xor eax, eax
mov [esp+36], eax
ret
 
align 4
proc strncmp stdcall, str1:dword, str2:dword, count:dword
 
mov ecx,[count]
jecxz .end
 
mov ebx,ecx
 
mov edi,[str1]
mov esi,edi
xor eax,eax
repne scasb
neg ecx ; cx = count - strlen
add ecx,ebx ; strlen + count - strlen
 
.okay:
mov edi,esi
mov esi,[str2]
repe cmpsb
mov al,[esi-1]
xor ecx,ecx
 
cmp al,[edi-1]
ja .str2_big
je .end
 
.str1_big:
sub ecx,2
 
.str2_big:
not ecx
.end:
mov eax,ecx
ret
endp
 
align 4
proc fpu_save
clts
mov ebx, [fpu_owner]
shl ebx, 8
mov eax, [ebx+PROC_BASE+0x10]
mov ebx, [CURRENT_TASK]
mov [fpu_owner], ebx
 
bt [cpu_caps], CAPS_FXSR
jnc .no_SSE
 
fxsave [eax]
fninit ;re-init fpu
ret
.no_SSE:
fnsave [eax]
ret
endp
 
align 4
proc fpu_restore
mov ebx, [CURRENT_TASK]
shl ebx, 8
mov eax, [ebx+PROC_BASE+0x10]
bt [cpu_caps], CAPS_FXSR
jnc .no_SSE
 
fxrstor [eax]
ret
.no_SSE:
fnclex ;fix possible problems
frstor [eax]
ret
endp
 
align 4
proc test_cpu
locals
cpu_type dd ?
cpu_id dd ?
cpu_Intel dd ?
cpu_AMD dd ?
endl
 
mov [cpu_type], 0
 
pushfd
pop eax
mov ecx, eax
xor eax, 0x40000
push eax
popfd
pushfd
pop eax
xor eax, ecx
mov [cpu_type], CPU_386
jz .end_cpu
push ecx
popfd
 
mov [cpu_type], CPU_486
mov eax, ecx
xor eax, 0x200000
push eax
popfd
pushfd
pop eax
xor eax, ecx
je .end_cpu
mov [cpu_id], 1
 
xor eax, eax
cpuid
mov [cpu_vendor], ebx
mov [cpu_vendor+4], edx
mov [cpu_vendor+8], ecx
cmp ebx, dword [intel_str]
jne .check_AMD
cmp edx, dword [intel_str+4]
jne .check_AMD
cmp ecx, dword [intel_str+8]
jne .check_AMD
mov [cpu_Intel], 1
cmp eax, 1
jl .end_cpuid
mov eax, 1
cpuid
mov [cpu_sign], eax
mov [cpu_info], ebx
mov [cpu_caps], edx
mov [cpu_caps+4],ecx
 
shr eax, 8
and eax, 0x0f
mov [cpu_type], eax
ret
 
.end_cpuid:
mov eax, [cpu_type]
ret
 
.check_AMD:
cmp ebx, dword [AMD_str]
jne .end_cpu
cmp edx, dword [AMD_str+4]
jne .end_cpu
cmp ecx, dword [AMD_str+8]
jne .end_cpu
mov [cpu_AMD], 1
cmp eax, 1
jl .end_cpuid
mov eax, 1
cpuid
mov [cpu_sign], eax
mov [cpu_info], ebx
mov [cpu_caps], edx
mov [cpu_caps+4],ecx
shr eax, 8
and eax, 0x0f
mov [cpu_type], eax
.end_cpu:
mov eax, [cpu_type]
ret
endp
 
MEM_WB equ 6 ;write-back memory
MEM_WC equ 1 ;write combined memory
MEM_UC equ 0 ;uncached memory
 
align 4
proc init_mtrr
 
cmp [0x2f0000+0x901c],byte 2
je .exit
 
mov eax, cr0
or eax, 0x60000000 ;disable caching
mov cr0, eax
wbinvd ;invalidate cache
 
mov ecx, 0x2FF
rdmsr ;
push eax
 
xor edx, edx
xor eax, eax
mov ecx, 0x2FF
wrmsr ;disable all MTRR
 
stdcall set_mtrr, dword 0,dword 0,[MEM_AMOUNT],MEM_WB
stdcall set_mtrr, dword 1,[LFBAddress],[LFBSize],MEM_WC
xor edx, edx
xor eax, eax
mov ecx, 0x204
mov ebx, 6
@@:
wrmsr ;disable unused MTRR
inc ecx
wrmsr
inc ecx
dec ebx
jnz @b
 
wbinvd ;again invalidate
 
pop eax
or eax, 0x800 ;set default memtype to UC
and al, 0xF0
mov ecx, 0x2FF
wrmsr ;and enable MTRR
 
mov eax, cr0
and eax, not 0x60000000
mov cr0, eax ; enable caching
.exit:
ret
endp
 
align 4
proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword
 
xor edx, edx
mov eax, [base]
or eax, [mem_type]
mov ecx, [reg]
lea ecx, [0x200+ecx*2]
wrmsr
 
mov ebx, [size]
dec ebx
mov eax, 0xFFFFFFFF
mov edx, 0x0000000F
sub eax, ebx
sbb edx, 0
or eax, 0x800
inc ecx
wrmsr
ret
endp
 
align 4
proc stall stdcall, delay:dword
push ecx
push edx
push ebx
push eax
 
mov eax, [delay]
mul [stall_mcs]
mov ebx, eax ;low
mov ecx, edx ;high
rdtsc
add ebx, eax
adc ecx,edx
@@:
rdtsc
sub eax, ebx
sbb edx, ecx
jb @B
 
pop eax
pop ebx
pop edx
pop ecx
ret
endp
 
iglobal
align 4
intel_str db "GenuineIntel",0
AMD_str db "AuthenticAMD",0
endg
 
uglobal
align 16
irq_tab rd 16
 
 
MEM_FreeSpace rd 1
 
ipc_tmp rd 1
ipc_pdir rd 1
ipc_ptab rd 1
 
proc_mem_map rd 1
proc_mem_pdir rd 1
proc_mem_tab rd 1
 
tmp_task_pdir rd 1
tmp_task_ptab rd 1
tmp_task_data rd 1
 
; current_pdir rd 1
 
fpu_data rd 1
fdd_buff rd 1
 
stall_mcs rd 1
;;CPUID information
 
cpu_vendor rd 3
cpu_sign rd 1
cpu_info rd 1
 
endg
 
uglobal
align 16
dll_tab rb 32*32
srv_tab rb 32*32
dll_map rd 1
srv_map rd 1
 
mem_used_list rd 1
mem_block_list rd 64
mem_block_map rb 512
mem_block_arr rd 1
mem_block_start rd 1
mem_block_end rd 1
mem_block_mask rd 2
heap_size rd 1
heap_free rd 1
heap_blocks rd 1
free_blocks rd 1
 
page_start rd 1
page_end rd 1
sys_page_map rd 1
; app_load rd 1
endg
 
 
; push eax
; push edx
; mov edx, 0x400 ;bocsh
; mov al,0xff ;bocsh
; out dx, al ;bocsh
; pop edx
; pop eax
 
/kernel/tags/kolibri0.6.3.0/core/sys32.inc
0,0 → 1,995
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; MenuetOS process management, protected ring3 ;;
;; ;;
;; Distributed under GPL. See file COPYING for details. ;;
;; Copyright 2003 Ville Turjanmaa ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
idtreg:
dw 8*0x41-1
dd idts+8
;label idts at 0xB100-8
 
 
uglobal
tss_sceleton:
l.back dw 0,0
l.esp0 dd 0
l.ss0 dw 0,0
l.esp1 dd 0
l.ss1 dw 0,0
l.esp2 dd 0
l.ss2 dw 0,0
l.cr3 dd 0
l.eip dd 0
l.eflags dd 0
l.eax dd 0
l.ecx dd 0
l.edx dd 0
l.ebx dd 0
l.esp dd 0
l.ebp dd 0
l.esi dd 0
l.edi dd 0
l.es dw 0,0
l.cs dw 0,0
l.ss dw 0,0
l.ds dw 0,0
l.fs dw 0,0
l.gs dw 0,0
l.ldt dw 0,0
l.trap dw 0
l.io dw 0
endg
 
 
build_process_gdt_tss_pointer:
 
mov ecx,tss_data
mov edi,0
setgdtl2:
mov [edi+gdts+ tss0 +0], word tss_step
mov [edi+gdts+ tss0 +2], cx
mov eax,ecx
shr eax,16
mov [edi+gdts+ tss0 +4], al
mov [edi+gdts+ tss0 +7], ah
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
add ecx,tss_step
add edi,8
cmp edi,8*(max_processes+5)
jbe setgdtl2
 
ret
 
 
build_interrupt_table:
 
mov edi, idts+8
mov esi, sys_int
mov ecx, 0x40
@@:
mov eax, [esi]
mov [edi], ax ; lower part of offset
mov [edi+2], word os_code ; segment selector
shr eax, 16
mov [edi+4], word 10001110b shl 8 ; interrupt descriptor
mov [edi+6], ax
add esi, 4
add edi, 8
dec ecx
jnz @b
 
;mov edi,8*0x40+idts+8
mov [edi + 0], word (i40 and ((1 shl 16)-1))
mov [edi + 2], word os_code
mov [edi + 4], word 11101110b*256
mov [edi + 6], word (i40 shr 16)
 
ret
 
iglobal
sys_int:
dd e0,debug_exc,e2,e3
dd e4,e5,e6,e7
dd e8,e9,e10,e11
dd e12,e13,page_fault_handler,e15
 
dd except_16, e17,e18, except_19
times 12 dd unknown_interrupt
 
dd irq0 , irq_serv.irq_1, p_irq2 ,irq_serv.irq_3
dd p_irq4 ,irq_serv.irq_5,p_irq6,irq_serv.irq_7
dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10
dd irq_serv.irq_11,p_irq12,irqD ,p_irq14,p_irq15
 
times 16 dd unknown_interrupt
 
dd i40
endg
 
macro save_ring3_context
{
push ds es
pushad
}
macro restore_ring3_context
{
popad
pop es ds
}
 
; simply return control to interrupted process
unknown_interrupt:
iret
 
macro exc_wo_code [num]
{
forward
e#num :
save_ring3_context
mov bl, num
jmp exc_c
}
 
macro exc_w_code [num]
{
forward
e#num :
add esp, 4
save_ring3_context
mov bl, num
jmp exc_c
}
 
exc_wo_code 0, 1, 2, 3, 4, 5, 6, 9, 15, 18
exc_w_code 8, 10, 11, 12, 13, 14, 17
 
exc_c:
mov ax, os_data
mov ds, ax
mov es, ax
 
; test if debugging
cli
mov eax, [0x3000]
shl eax, 8
mov eax, [0x80000+eax+APPDATA.debugger_slot]
test eax, eax
jnz .debug
sti
; not debuggee => say error and terminate
add esp, 28h
movzx eax, bl
mov [error_interrupt], eax
call show_error_parameters
 
mov edx, [0x3010]
mov [edx + TASKDATA.state], byte 4
 
jmp change_task
 
.debug:
; we are debugged process, notify debugger and suspend ourself
; eax=debugger PID
cld
movzx ecx, bl
push ecx
mov ecx, [0x3010]
push dword [ecx+TASKDATA.pid] ; PID of current process
push 12
pop ecx
push 1 ; 1=exception
call debugger_notify
pop ecx
pop ecx
pop ecx
mov edx, [0x3010]
mov byte [edx+TASKDATA.state], 1 ; suspended
call change_task
restore_ring3_context
iretd
 
;;;;;;;;;;;;;;;;;;;;;;;
;; FPU ERROR HANDLER ;;
;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
e7:
save_ring3_context
clts
mov ax, os_data
mov ds, ax
mov es, ax
 
mov ebx, [fpu_owner]
cmp ebx, [CURRENT_TASK]
je .exit
 
shl ebx, 8
mov eax, [ebx+PROC_BASE+APPDATA.fpu_state]
bt [cpu_caps], CAPS_FXSR
jnc .no_SSE
 
fxsave [eax]
mov ebx, [CURRENT_TASK]
mov [fpu_owner], ebx
shl ebx, 8
cmp dword [ebx+PROC_BASE+APPDATA.fpu_init], 0
je .init
mov eax, [ebx+PROC_BASE+APPDATA.fpu_state]
fxrstor [eax]
restore_ring3_context
iret
 
.no_SSE:
fnsave [eax]
mov ebx, [CURRENT_TASK]
mov [fpu_owner], ebx
shl ebx, 8
cmp dword [ebx+PROC_BASE+APPDATA.fpu_init], 0
je .ready
 
mov eax, [ebx+PROC_BASE+APPDATA.fpu_state]
frstor [eax]
restore_ring3_context
iret
.init:
fninit ;­ ¬ ­¥ ­ã¦­ë ­¥¬ áª¨à®¢ ­­ë¥ ¨áª«î祭¨ï
.ready:
mov dword [ebx+PROC_BASE+APPDATA.fpu_init], 1
.exit:
restore_ring3_context
iret
 
iglobal
fpu_owner dd 1
endg
 
 
writehex:
pusha
 
mov edi, [write_error_to]
mov esi, 8
@@:
mov ecx, eax
and ecx, 0xf
 
mov cl,[ecx+hexletters]
mov [edi],cl
dec edi
 
shr eax,4
dec esi
jnz @b
 
popa
ret
 
iglobal
hexletters db '0123456789ABCDEF'
 
error_interrupt dd -1
 
process_error db 'K : Process - forced terminate INT: 00000000',13,10,0
process_pid db 'K : Process - forced terminate PID: 00000000',13,10,0
process_eip db 'K : Process - forced terminate EIP: 00000000',13,10,0
system_error db 'K : Kernel error',13,10,0
endg
 
uglobal
write_error_to dd 0x0
endg
 
show_error_parameters:
 
mov [write_error_to],process_pid+43
mov eax,[0x3000]
shl eax, 5
mov eax,[0x3000+TASKDATA.pid+eax]
call writehex
 
mov [write_error_to],process_error+43
mov eax,[error_interrupt]
call writehex
 
cmp dword [esp+4+4], os_code ; CS
jnz @f
mov esi,system_error
call sys_msg_board_str
@@:
mov eax, [esp+4] ; EIP
 
mov [write_error_to],process_eip+43
call writehex
 
mov esi,process_error
call sys_msg_board_str
 
mov esi,process_pid
call sys_msg_board_str
 
mov esi,process_eip
call sys_msg_board_str
 
ret
 
 
 
; irq1 -> hid/keyboard.inc
 
 
macro irqh [num]
{
forward
p_irq#num :
save_ring3_context
mov edi, num
jmp irq_c
}
 
irqh 2,5,7,8,9,10,11
 
irq_c:
mov ax, os_data
mov ds, ax
mov es, ax
call irqhandler
restore_ring3_context
iret
 
p_irq6:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
call fdc_irq
call ready_for_next_irq
restore_ring3_context
iret
 
p_irq3:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
cmp [com2_mouse_detected],0
je old_irq3_handler
call check_mouse_data_com2
jmp p_irq3_1
old_irq3_handler:
mov edi,3
call irqhandler
p_irq3_1:
restore_ring3_context
iret
 
p_irq4:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
cmp [com1_mouse_detected],0
je old_irq4_handler
call check_mouse_data_com1
jmp p_irq4_1
old_irq4_handler:
mov edi,4
call irqhandler
p_irq4_1:
restore_ring3_context
iret
 
p_irq12:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
call check_mouse_data_ps2
restore_ring3_context
iret
 
p_irq14:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
call [irq14_func]
call ready_for_next_irq_1
restore_ring3_context
iret
p_irq15:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
call [irq15_func]
call ready_for_next_irq_1
restore_ring3_context
iret
 
ready_for_next_irq:
mov [check_idle_semaphore],5
mov al, 0x20
out 0x20, al
ret
 
ready_for_next_irq_1:
mov [check_idle_semaphore],5
mov al, 0x20
out 0xa0,al
out 0x20, al
ret
 
irqD:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
 
mov dx,0xf0
mov al,0
out dx,al
 
mov dx,0xa0
mov al,0x20
out dx,al
mov dx,0x20
out dx,al
 
restore_ring3_context
 
iret
 
 
irqhandler:
 
push edi
 
mov esi,edi ; 1
shl esi,6 ; 1
add esi,irq00read ; 1
shl edi,12 ; 1
add edi,0x2E0000
mov ecx,16
 
mov [check_idle_semaphore],5
 
irqnewread:
dec ecx
js irqover
 
mov dx,[esi] ; 2+
 
cmp dx,0 ; 1
jz irqover
cmp [esi+3],byte 1 ; 2 ; byte read
jne noirqbyte ; 4-11
 
in al,dx
 
mov edx,[edi]
cmp edx,4000
je irqfull
mov ebx,edi
add ebx,0x10
add ebx,edx
mov [ebx],al
inc edx
mov [edi],edx
 
add esi,4
jmp irqnewread
 
noirqbyte:
 
 
cmp [esi+3],byte 2 ; word read
jne noirqword
 
in ax,dx
 
mov edx,[edi]
cmp edx,4000
je irqfull
mov ebx,edi
add ebx,0x10
add ebx,edx
mov [ebx],ax
add edx,2
mov [edi],edx
add esi,4
jmp irqnewread
 
noirqword:
irqfull:
irqover:
 
mov al,0x20 ; ready for next irq
out 0x20,al
 
pop ebx
cmp ebx,7
jbe noa0
out 0xa0,al
noa0:
 
ret
 
 
 
set_application_table_status:
push eax
 
mov eax,[0x3000]
shl eax, 5
add eax,0x3000+TASKDATA.pid
mov eax,[eax]
 
mov [application_table_status],eax
 
pop eax
 
ret
 
 
clear_application_table_status:
push eax
 
mov eax,[0x3000]
shl eax, 5
add eax,0x3000+TASKDATA.pid
mov eax,[eax]
 
cmp eax,[application_table_status]
jne apptsl1
mov [application_table_status],0
apptsl1:
 
pop eax
 
ret
 
 
 
sys_resize_app_memory:
; eax = 1 - resize
; ebx = new amount of memory
 
cmp eax,1
jne .no_application_mem_resize
 
stdcall new_mem_resize, ebx
mov [esp+36], eax
ret
 
.no_application_mem_resize:
ret
 
 
 
get_app_params:
 
push eax
 
cmp [0x90000+6],word '00'
jne no_00_header
 
mov eax,[0x90000+12]
mov [app_start],eax
mov eax,[0x90000+16]
mov [app_i_end],eax
mov eax,[0x90000+20]
mov [app_mem],eax
; \begin{diamond}[20.08.2006]
; sanity check (functions 19,58 load app_i_end bytes and that must
; fit in allocated memory to prevent kernel faults)
cmp eax,[app_i_end]
jb no_01_header
; \end{diamond}[20.08.2006]
shr eax,1
sub eax,0x10
mov [app_esp],eax
mov eax,[0x90000+24]
mov [app_i_param],eax
mov [app_i_icon],dword 0
 
pop eax
clc
ret
 
no_00_header:
 
 
cmp [0x90000+6],word '01'
jne no_01_header
 
mov eax,[0x90000+12]
mov [app_start],eax
mov eax,[0x90000+16]
mov [app_i_end],eax
mov eax,[0x90000+20]
mov [app_mem],eax
; \begin{diamond}[20.08.2006]
cmp eax,[app_i_end]
jb no_01_header
; \end{diamond}[20.08.2006]
mov eax,[0x90000+24]
mov [app_esp],eax
mov eax,[0x90000+28]
mov [app_i_param],eax
mov eax,[0x90000+32]
mov [app_i_icon],eax
 
pop eax
clc
ret
 
no_01_header:
 
pop eax
stc
ret
 
 
uglobal
new_process_place dd 0x0
app_start dd 0x0
app_i_end dd 0x0
app_mem dd 0x0
app_esp dd 0x0
app_i_param dd 0x0
app_i_icon dd 0x0
; app_mem_pos dd 0x0
appl_path dd 0x0
appl_path_size dd 0x0
endg
 
 
sys_threads:
 
; eax=1 create thread
;
; ebx=thread start
; ecx=thread stack value
;
; on return : eax = pid
jmp new_sys_threads
 
iglobal
process_terminating db 'K : Process - terminating',13,10,0
process_terminated db 'K : Process - done',13,10,0
endg
 
 
terminate: ; terminate application
push esi
mov esi,process_terminating
call sys_msg_board_str
pop esi
 
@@:
cli
cmp [application_table_status],0
je term9
sti
call change_task
jmp @b
term9:
 
call set_application_table_status
 
mov eax,esi
 
pushad
shl eax,8
mov eax,[PROC_BASE+eax+0xB8]
stdcall destroy_app_space, eax
popad
 
cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1
jne fpu_ok_1
 
mov [fpu_owner],1
mov eax, [256+PROC_BASE+0x10]
bt [cpu_caps], CAPS_FXSR
jnc .no_SSE
fxrstor [eax]
jmp fpu_ok_1
.no_SSE:
fnclex
frstor [eax]
fpu_ok_1:
 
mov [0xf400],byte 0 ; empty keyboard buffer
mov [0xf500],byte 0 ; empty button buffer
 
 
; remove defined hotkeys
mov eax, hotkey_list
.loop:
cmp [eax+8], esi
jnz .cont
mov ecx, [eax]
jecxz @f
push dword [eax+12]
pop dword [ecx+12]
@@:
mov ecx, [eax+12]
push dword [eax]
pop dword [ecx]
xor ecx, ecx
mov [eax], ecx
mov [eax+4], ecx
mov [eax+8], ecx
mov [eax+12], ecx
.cont:
add eax, 16
cmp eax, hotkey_list+256*16
jb .loop
; remove hotkeys in buffer
mov eax, hotkey_buffer
.loop2:
cmp [eax], esi
jnz .cont2
and dword [eax+4], 0
and dword [eax], 0
.cont2:
add eax, 8
cmp eax, hotkey_buffer+120*8
jb .loop2
 
mov ecx,esi ; remove buttons
bnewba2:
mov edi,[0xfe88]
mov eax,edi
cld
movzx ebx,word [edi]
inc bx
bnewba:
dec bx
jz bnmba
add eax,0x10
cmp cx,[eax]
jnz bnewba
pusha
mov ecx,ebx
inc ecx
shl ecx,4
mov ebx,eax
add eax,0x10
call memmove
dec dword [edi]
popa
jmp bnewba2
bnmba:
 
pusha ; save window coordinates for window restoring
cld
shl esi,5
add esi,window_data
mov eax,[esi+WDATA.box.left]
mov [dlx],eax
add eax,[esi+WDATA.box.width]
mov [dlxe],eax
mov eax,[esi+WDATA.box.top]
mov [dly],eax
add eax,[esi+WDATA.box.height]
mov [dlye],eax
 
xor eax, eax
mov [esi+WDATA.box.left],eax
mov [esi+WDATA.box.width],eax
mov [esi+WDATA.box.top],eax
mov [esi+WDATA.box.height],eax
mov [esi+WDATA.cl_workarea],eax
mov [esi+WDATA.cl_titlebar],eax
mov [esi+WDATA.cl_frames],eax
mov dword [esi+WDATA.reserved],eax ; clear all flags: wstate, redraw, wdrawn
lea edi, [esi-window_data+draw_data]
mov ecx,32/4
rep stosd
popa
 
; debuggee test
pushad
mov edi, esi
shl edi, 5
mov eax, [0x80000+edi*8+APPDATA.debugger_slot]
test eax, eax
jz .nodebug
push 8
pop ecx
push dword [0x3000+edi+TASKDATA.pid] ; PID
push 2
call debugger_notify
pop ecx
pop ecx
.nodebug:
popad
 
pusha ; at 0x80000+
mov edi,esi
shl edi,8
add edi,0x80000
mov ecx,256/4
xor eax, eax
rep stosd
popa
 
pusha ; name to spaces
mov edi,esi
shl edi,8
add edi,0x80000+APPDATA.app_name
mov ecx,11
mov eax,' '
rep stosb
popa
 
 
; activate window
movzx eax, word [0xC000 + esi*2]
cmp eax, [0x3004]
jne .dont_activate
pushad
.check_next_window:
dec eax
cmp eax, 1
jbe .nothing_to_activate
lea esi, [0xc400+eax*2]
movzx edi, word [esi] ; edi = process
shl edi, 5
cmp [0x3000 + edi + TASKDATA.state], byte 9 ; skip dead slots
je .check_next_window
add edi, window_data
; \begin{diamond}[19.09.2006]
; skip minimized windows
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .check_next_window
; \end{diamond}
call waredraw
.nothing_to_activate:
popad
.dont_activate:
 
push esi ; remove hd1 & cd & flp reservation
shl esi, 5
mov esi, [esi+0x3000+TASKDATA.pid]
cmp [hd1_status], esi
jnz @f
mov [hd1_status], 0
@@:
cmp [cd_status], esi
jnz @f
mov [cd_status], 0
@@:
cmp [flp_status], esi
jnz @f
mov [flp_status], 0
@@:
pop esi
 
pusha ; remove all irq reservations
mov eax,esi
shl eax, 5
mov eax,[eax+0x3000+TASKDATA.pid]
mov edi,irq_owner
mov ecx,16
newirqfree:
scasd
jne nofreeirq
mov [edi-4],dword 0
nofreeirq:
loop newirqfree
popa
 
 
pusha ; remove all port reservations
mov edx,esi
shl edx, 5
add edx,0x3000
mov edx,[edx+TASKDATA.pid]
 
rmpr0:
 
mov esi,[0x2d0000]
 
cmp esi,0
je rmpr9
 
rmpr3:
 
mov edi,esi
shl edi,4
add edi,0x2d0000
 
cmp edx,[edi]
je rmpr4
 
dec esi
jnz rmpr3
 
jmp rmpr9
 
rmpr4:
 
mov ecx,256
sub ecx,esi
shl ecx,4
 
mov esi,edi
add esi,16
cld
rep movsb
 
dec dword [0x2d0000]
 
jmp rmpr0
 
rmpr9:
 
popa
mov edi,esi ; do not run this process slot
shl edi, 5
mov [edi+0x3000 + TASKDATA.state],byte 9
; debugger test - terminate all debuggees
mov eax, 2
mov ecx, 0x80000+2*0x100+APPDATA.debugger_slot
.xd0:
cmp eax, [0x3004]
ja .xd1
cmp dword [ecx], esi
jnz @f
and dword [ecx], 0
pushad
xchg eax, ebx
mov eax, 2
call sys_system
popad
@@:
inc eax
add ecx, 0x100
jmp .xd0
.xd1:
; call systest
sti ; .. and life goes on
 
mov eax, [dlx]
mov ebx, [dly]
mov ecx, [dlxe]
mov edx, [dlye]
call calculatescreen
xor eax, eax
xor esi, esi
call redrawscreen
 
mov [0xfff4],byte 0 ; no mouse background
mov [0xfff5],byte 0 ; draw mouse
 
mov [application_table_status],0
mov esi,process_terminated
call sys_msg_board_str
 
ret
 
iglobal
boot_sched_1 db 'Building gdt tss pointer',0
boot_sched_2 db 'Building IDT table',0
endg
 
 
build_scheduler:
 
mov esi,boot_sched_1
call boot_log
call build_process_gdt_tss_pointer
 
mov esi,boot_sched_2
call boot_log
call build_interrupt_table
 
ret
 
/kernel/tags/kolibri0.6.3.0/core/dll.inc
0,0 → 1,935
;
; This file is part of the Infinity sound AC97 driver.
; (C) copyright Serge 2006
; email: infinity_sound@mail.ru
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
 
align 4
proc attach_int_handler stdcall, irq:dword, handler:dword
 
mov ebx, [irq] ;irq num
test ebx, ebx
jz .err
mov eax, [handler]
test eax, eax
jz .err
mov [irq_tab+ebx*4], eax
stdcall enable_irq, [irq]
ret
.err:
xor eax, eax
ret
endp
 
align 4
proc detach_int_handler
 
ret
endp
 
align 4
proc enable_irq stdcall, irq_line:dword
mov ebx, [irq_line]
mov edx, 0x21
cmp ebx, 8
jb @F
mov edx, 0xA1
sub ebx,8
@@:
in al,dx
btr eax, ebx
out dx, al
ret
endp
 
align 16
;; proc irq_serv
 
irq_serv:
 
.irq_1:
push eax
mov eax, 1
jmp .main
align 4
.irq_2:
push eax
mov eax, 2
jmp .main
align 4
.irq_3:
push eax
mov eax, 3
jmp .main
align 4
.irq_4:
push eax
mov eax, 4
jmp .main
align 4
.irq_5:
push eax
mov eax, 5
jmp .main
align 4
.irq_6:
push eax
mov eax, 6
jmp .main
align 4
.irq_7:
push eax
mov eax, 7
jmp .main
align 4
.irq_8:
push eax
mov eax, 8
jmp .main
align 4
.irq_9:
push eax
mov eax, 9
jmp .main
align 4
.irq_10:
push eax
mov eax, 10
jmp .main
align 4
.irq_11:
push eax
mov eax, 11
jmp .main
align 4
.irq_12:
push eax
mov eax, 12
jmp .main
align 4
.irq_13:
push eax
mov eax, 13
jmp .main
align 4
.irq_14:
push eax
mov eax, 14
jmp .main
align 4
.irq_15:
push eax
mov eax, 15
jmp .main
 
align 16
.main:
save_ring3_context
mov bx, os_data
mov ds, bx
mov es, bx
 
mov ebx, [irq_tab+eax*4]
test ebx, ebx
jz .exit
 
call ebx
 
.exit:
restore_ring3_context
 
cmp eax, 8
mov al, 0x20
jb @f
out 0xa0, al
@@:
out 0x20, al
 
pop eax
iret
 
align 4
proc get_notify stdcall, p_ev:dword
 
.wait:
mov ebx,[CURRENT_TASK]
shl ebx,8
test dword [ebx+PROC_BASE+0xA8],EVENT_NOTIFY
jz @f
and dword [ebx+PROC_BASE+0xA8], not EVENT_NOTIFY
mov edi, [p_ev]
mov dword [edi], EV_INTR
mov eax, [ebx+PROC_BASE+APPDATA.event]
mov dword [edi+4], eax
ret
@@:
call change_task
jmp .wait
endp
 
align 4
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 6
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
ret
endp
 
align 4
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 4
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
ret
endp
 
align 4
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 8
mov bh, byte [devfn]
mov bl, byte [reg]
mov ecx, [val]
call pci_write_reg
ret
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
 
align 4
proc srv_handler stdcall, ioctl:dword
mov esi, [ioctl]
test esi, esi
jz .err
 
mov edi, [esi+handle]
cmp [edi+SRV.magic], ' SRV'
jne .fail
 
cmp [edi+SRV.size], SRV_SIZE
jne .fail
 
stdcall [edi+SRV.srv_proc], esi
ret
.fail:
xor eax, eax
not eax
mov [esi+output], eax
mov [esi+out_size], 4
ret
.err:
xor eax, eax
not eax
ret
endp
 
align 4
proc srv_handlerEx stdcall, ioctl:dword
mov esi, [ioctl]
test esi, esi
jz .err
add esi, new_app_base
 
mov edi, [esi+handle]
cmp [edi+SRV.magic], ' SRV'
jne .fail
 
cmp [edi+SRV.size], SRV_SIZE
jne .fail
 
add [esi+input], new_app_base
add [esi+output], new_app_base
 
stdcall [edi+SRV.srv_proc], esi
ret
.fail:
xor eax, eax
not eax
mov [esi+output], eax
mov [esi+out_size], 4
ret
.err:
xor eax, eax
not eax
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
align 4
proc get_service stdcall, sz_name:dword
locals
srv_ptr dd ?
counter dd ?
endl
 
mov eax, [sz_name]
test eax, eax
jnz @F
ret
@@:
mov [srv_ptr], srv_tab
mov [counter], 16
@@:
stdcall strncmp, [srv_ptr], [sz_name], 16
test eax, eax
je .ok
 
add [srv_ptr], SRV_SIZE
dec [counter]
jnz @B
.not_load:
stdcall find_service, [sz_name]
test eax, eax
jnz @F
ret
@@:
stdcall load_driver, eax
ret
.ok:
mov eax, [srv_ptr]
ret
endp
 
align 4
proc find_service stdcall ,sz_name:dword
 
mov eax, [sz_name]
test eax, eax
jz .fail
 
mov esi, services
@@:
mov eax, [esi]
test eax, eax
jz .fail
push esi
stdcall strncmp, eax, [sz_name], 16
pop esi
test eax, eax
je .ok
 
add esi, 8
jmp @B
.ok:
mov eax, [esi+4]
ret
.fail:
xor eax, eax
ret
endp
 
align 4
proc reg_service stdcall, sz_name:dword, handler:dword
locals
srv dd ?
endl
 
mov eax, [sz_name]
test eax, eax
jz .fail
 
mov ebx, [handler]
test ebx, ebx
jz .fail
 
call alloc_service
test eax, eax
jz .fail
 
mov [srv], eax
mov edi, eax
mov esi, [sz_name]
mov ecx, 16
rep movsb
 
mov edi, eax
mov [edi+SRV.magic], ' SRV'
mov [edi+SRV.size], SRV_SIZE
mov ebx, [handler]
mov [edi+SRV.srv_proc], ebx
mov eax, [srv]
ret
.fail:
xor eax, eax
ret
endp
 
align 4
proc get_proc stdcall, exp:dword, sz_name:dword
 
mov edx, [exp]
.next:
mov eax, [edx]
test eax, eax
jz .end
 
push edx
stdcall strncmp, eax, [sz_name], 16
pop edx
test eax, eax
jz .ok
 
add edx,8
jmp .next
.ok:
mov eax, [edx+4]
.end:
ret
endp
 
align 4
proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword
 
@@:
stdcall strncmp, [pSym], [sz_sym], 8
test eax,eax
jz .ok
add [pSym], 18
dec [count]
jnz @b
xor eax, eax
ret
.ok:
mov ebx, [pSym]
mov eax, [ebx+8]
ret
endp
 
align 4
proc get_curr_task
mov eax,[CURRENT_TASK]
shl eax, 8
ret
endp
 
align 4
proc get_fileinfo stdcall, file_name:dword, info:dword
locals
cmd dd ?
offset dd ?
dd ?
count dd ?
buff dd ?
db ?
name dd ?
endl
 
xor eax, eax
mov ebx, [file_name]
sub ebx, new_app_base
mov ecx, [info]
sub ecx, new_app_base
 
mov [cmd], 5
mov [offset], eax
mov [offset+4], eax
mov [count], eax
mov [buff], ecx
mov byte [buff+4], al
mov [name], ebx
 
mov eax, 70
lea ebx, [cmd]
sub ebx, new_app_base
int 0x40
ret
endp
 
align 4
proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
bytes:dword
locals
cmd dd ?
offset dd ?
dd ?
count dd ?
buff dd ?
db ?
name dd ?
endl
 
xor eax, eax
mov ebx, [file_name]
mov ecx, [off]
mov edx, [bytes]
mov esi, [buffer]
sub ebx, new_app_base
sub esi, new_app_base
 
mov [cmd], eax
mov [offset], ecx
mov [offset+4], eax
mov [count], edx
mov [buff], esi
mov byte [buff+4], al
mov [name], ebx
 
mov eax, 70
lea ebx, [cmd]
sub ebx, new_app_base
int 0x40
ret
endp
 
align 4
proc load_file stdcall, file_name:dword
locals
attr dd ?
flags dd ?
cr_time dd ?
cr_date dd ?
acc_time dd ?
acc_date dd ?
mod_time dd ?
mod_date dd ?
file_size dd ?
 
file dd ?
endl
 
lea eax, [attr]
stdcall get_fileinfo, [file_name], eax
test eax, eax
jnz .fail
 
stdcall kernel_alloc, [file_size]
mov [file], eax
 
stdcall read_file, [file_name], eax, dword 0, [file_size]
cmp ebx, [file_size]
jne .cleanup
mov eax, [file]
ret
.cleanup:
stdcall kernel_free, [file]
.fail:
xor eax, eax
ret
endp
 
align 4
proc get_proc_ex stdcall, proc_name:dword, imports:dword
 
.look_up:
mov edx, [imports]
test edx, edx
jz .end
mov edx, [edx]
test edx, edx
jz .end
.next:
mov eax, [edx]
test eax, eax
jz .next_table
 
push edx
stdcall strncmp, eax, [proc_name], 16
pop edx
test eax, eax
jz .ok
 
add edx,8
jmp .next
.next_table:
add [imports], 4
jmp .look_up
.ok:
mov eax, [edx+4]
ret
.end:
xor eax, eax
ret
endp
 
align 4
proc fix_coff_symbols stdcall, sec:dword, symbols:dword,\
sym_count:dword, strings:dword, imports:dword
locals
retval dd ?
endl
 
mov edi, [symbols]
mov [retval], 1
.fix:
movzx ebx, [edi+CSYM.SectionNumber]
test ebx, ebx
jnz .internal
mov eax, dword [edi+CSYM.Name]
test eax, eax
jnz @F
 
mov edi, [edi+4]
add edi, [strings]
@@:
push edi
stdcall get_proc_ex, edi,[imports]
pop edi
 
xor ebx, ebx
test eax, eax
jnz @F
 
mov esi, msg_unresolved
call sys_msg_board_str
mov esi, edi
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
 
mov [retval],0
@@:
mov edi, [symbols]
mov [edi+CSYM.Value], eax
jmp .next
.internal:
dec ebx
shl ebx, 3
lea ebx, [ebx+ebx*4]
add ebx, [sec]
 
mov eax, [ebx+CFS.VirtualAddress]
add [edi+CSYM.Value], eax
.next:
add edi, CSYM_SIZE
mov [symbols], edi
dec [sym_count]
jnz .fix
mov eax, [retval]
ret
endp
 
align 4
proc fix_coff_relocs stdcall, coff:dword, sec:dword, sym:dword
locals
n_sec dd ?
endl
 
mov eax, [coff]
movzx ebx, [eax+CFH.nSections]
mov [n_sec], ebx
.fix_sec:
mov esi, [sec]
mov edi, [esi+CFS.PtrReloc]
add edi, [coff]
 
movzx ecx, [esi+CFS.NumReloc]
test ecx, ecx
jz .next
.next_reloc:
mov ebx, [edi+CRELOC.SymIndex]
add ebx,ebx
lea ebx,[ebx+ebx*8]
add ebx, [sym]
 
mov edx, [ebx+CSYM.Value]
 
cmp [edi+CRELOC.Type], 6
je .dir_32
 
cmp [edi+CRELOC.Type], 20
jne .next_reloc
.rel_32:
mov eax, [edi+CRELOC.VirtualAddress]
add eax, [esi+CFS.VirtualAddress]
sub edx, eax
sub edx, 4
jmp .fix
.dir_32:
mov eax, [edi+CRELOC.VirtualAddress]
add eax, [esi+CFS.VirtualAddress]
.fix:
add [eax], edx
add edi, 10
dec ecx
jnz .next_reloc
.next:
add [sec], 40
dec [n_sec]
jnz .fix_sec
.exit:
ret
endp
 
align 4
proc load_driver stdcall, file_name:dword
locals
coff dd ?
sym dd ?
strings dd ?
img_size dd ?
img_base dd ?
start dd ?
 
exports dd ? ;fake exports table
dd ?
endl
 
stdcall load_file, [file_name]
test eax, eax
jz .fail
 
mov [coff], eax
 
movzx ecx, [eax+CFH.nSections]
xor ebx, ebx
 
lea edx, [eax+20]
@@:
add ebx, [edx+CFS.SizeOfRawData]
add ebx, 15
and ebx, not 15
add edx, 18
dec ecx
jnz @B
mov [img_size], ebx
 
stdcall kernel_alloc, ebx
test eax, eax
jz .fail
mov [img_base], eax
 
mov edi, eax
xor eax, eax
mov ecx, [img_size]
add ecx, 4095
and ecx, not 4095
shr ecx, 2
cld
rep stosd
 
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, [img_base]
lea eax, [edx+20]
@@:
mov [eax+CFS.VirtualAddress], edi
mov esi, [eax+CFS.PtrRawData]
test esi, esi
jnz .copy
add edi, [eax+CFS.SizeOfRawData]
jmp .next
.copy:
add esi, edx
mov ecx, [eax+CFS.SizeOfRawData]
cld
rep movsb
.next:
add edi, 15
and edi, not 15
add eax, 40
dec ebx
jnz @B
 
mov ebx, [edx+CFH.pSymTable]
add ebx, edx
mov [sym], ebx
mov ecx, [edx+CFH.nSymbols]
add ecx,ecx
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE
add ecx, [sym]
mov [strings], ecx
 
lea ebx, [exports]
mov dword [ebx], kernel_export
mov dword [ebx+4], 0
lea eax, [edx+20]
 
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\
[strings], ebx
test eax, eax
jnz @F
 
mov esi, msg_module
call sys_msg_board_str
mov esi, [file_name]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
 
stdcall kernel_free,[coff]
xor eax, eax
ret
@@:
mov ebx, [coff]
add ebx, 20
stdcall fix_coff_relocs, [coff], ebx, [sym]
 
mov ebx, [coff]
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szSTART
mov [start], eax
 
stdcall kernel_free, [coff]
 
mov ebx, [start]
call ebx
test eax, eax
jnz .ok
 
stdcall kernel_free, [img_base]
xor eax, eax
ret
.ok:
mov ebx, [img_base]
mov [eax+SRV.base], ebx
ret
.fail:
xor eax, eax
ret
endp
 
align 4
proc load_library stdcall, file_name:dword
locals
coff dd ?
sym dd ?
strings dd ?
img_size dd ?
img_base dd ?
exports dd ?
endl
 
cli
 
stdcall load_file, [file_name]
 
test eax, eax
jz .fail
 
mov [coff], eax
movzx ecx, [eax+CFH.nSections]
xor ebx, ebx
 
lea edx, [eax+20]
@@:
add ebx, [edx+CFS.SizeOfRawData]
add ebx, 15
and ebx, not 15
add edx, 18
dec ecx
jnz @B
mov [img_size], ebx
 
call init_heap
stdcall user_alloc, [img_size]
 
test eax, eax
jz .fail
mov [img_base], eax
 
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, [img_base]
lea eax, [edx+20]
@@:
mov [eax+CFS.VirtualAddress], edi
mov esi, [eax+CFS.PtrRawData]
test esi, esi
jnz .copy
add edi, [eax+CFS.SizeOfRawData]
jmp .next
.copy:
add esi, edx
add edi, new_app_base
mov ecx, [eax+CFS.SizeOfRawData]
cld
rep movsb
.next:
add edi, 15-new_app_base
and edi, not 15
add eax, 40
dec ebx
jnz @B
 
mov ebx, [edx+CFH.pSymTable]
add ebx, edx
mov [sym], ebx
mov ecx, [edx+CFH.nSymbols]
add ecx,ecx
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE
add ecx, [sym]
mov [strings], ecx
 
lea eax, [edx+20]
 
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\
[strings], dword 0
test eax, eax
jnz @F
 
@@:
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, new_app_base
lea eax, [edx+20]
@@:
add [eax+CFS.VirtualAddress], edi ;patch user space offset
add eax, 40
dec ebx
jnz @B
 
add edx, 20
stdcall fix_coff_relocs, [coff], edx, [sym]
 
mov ebx, [coff]
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szEXPORTS
mov [exports], eax
 
stdcall kernel_free, [coff]
mov eax, [exports]
ret
.fail:
xor eax, eax
ret
endp
 
 
drv_sound db '/rd/1/drivers/unisound.obj', 0
drv_infinity db '/rd/1/drivers/infinity.obj', 0
 
szSound db 'SOUND',0
szInfinity db 'INFINITY',0
 
szSTART db 'START',0
szEXPORTS db 'EXPORTS',0
szIMPORTS db 'IMPORTS',0
 
msg_unresolved db 'unresolved ',0
msg_module db 'in module ',0
msg_CR db 13,10,0
 
align 16
services:
dd szSound, drv_sound
dd szInfinity, drv_infinity
dd 0
/kernel/tags/kolibri0.6.3.0/core/syscall.inc
0,0 → 1,147
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SYSTEM CALL ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 32
i40:
push ds es
pushad
cld
 
mov ax,word os_data
mov ds,ax
mov es,ax
 
; for syscall trace function
call save_registers
 
; load all registers in crossed order
mov edi,[esp+28] ; eax
mov eax,[esp+16] ; ebx
mov ebx,[esp+24] ; ecx
mov ecx,[esp+20] ; edx
mov edx,[esp+4] ; esi
mov esi,[esp+0] ; edi
 
; enable interupts - a task switch or an IRQ _CAN_ interrupt i40 handler
sti
push eax
and edi,0xff
call dword [servetable+edi*4]
pop eax
cli
 
popad
pop es ds
iretd
 
align 4
save_registers:
mov esi, [0x3010]
mov eax, [esi+TASKDATA.pid] ; load PID
lea esi, [esp+4]
inc [save_syscall_count]
mov edi,[save_syscall_count]
and edi,0xF
shl edi,6
add edi,save_syscall_data+32
mov [edi-32],eax
mov ecx,32 / 4
cld
rep movsd
ret
 
uglobal
save_syscall_count dd 0x0
endg
 
;label save_syscall_data dword at 0x5000
 
 
iglobal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SYSTEM FUNCTIONS TABLE ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
servetable:
 
dd sys_drawwindow ; 0-DrawWindow
dd syscall_setpixel ; 1-SetPixel
dd sys_getkey ; 2-GetKey
dd sys_clock ; 3-GetTime
dd syscall_writetext ; 4-WriteText
dd delay_hs ; 5-DelayHs
dd syscall_openramdiskfile ; 6-OpenRamdiskFile
dd syscall_putimage ; 7-PutImage
dd sys_button ; 8-DefineButton
dd sys_cpuusage ; 9-GetProcessInfo
dd sys_waitforevent ; 10-WaitForEvent
dd sys_getevent ; 11-CheckForEvent
dd sys_redrawstat ; 12-BeginDraw and EndDraw
dd syscall_drawrect ; 13-DrawRect
dd syscall_getscreensize ; 14-GetScreenSize
dd sys_background ; 15-bgr
dd sys_cachetodiskette ; 16-FlushFloppyCache
dd sys_getbutton ; 17-GetButton
dd sys_system ; 18-System Services
dd undefined_syscall ; 19-reserved
dd sys_midi ; 20-ResetMidi and OutputMidi
dd sys_setup ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,.
dd sys_settime ; 22-setting date,time,clock and alarm-clock
dd sys_wait_event_timeout ; 23-TimeOutWaitForEvent
dd syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist
dd sys_sb16 ; 25-SetSb16
dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,.
dd sys_wss ; 27-SetWssMainVol and SetWssCdVol
dd sys_sb16II ; 28-SetSb16
dd sys_date ; 29-GetDate
dd undefined_syscall ; 30-reserved
dd undefined_syscall ; 31-reserved
dd syscall_delramdiskfile ; 32-DelRamdiskFile
dd syscall_writeramdiskfile; 33-WriteRamdiskFile
dd undefined_syscall ; 34-reserved
dd syscall_getpixel ; 35-GetPixel
dd syscall_readstring ; 36-ReadString (not yet ready)
dd readmousepos ; 37-GetMousePosition_ScreenRelative,.
dd syscall_drawline ; 38-DrawLine
dd sys_getbackground ; 39-GetBackgroundSize,ReadBgrData,.
dd set_app_param ; 40-WantEvents
dd syscall_getirqowner ; 41-GetIrqOwner
dd get_irq_data ; 42-ReadIrqData
dd sys_outport ; 43-SendDeviceData
dd sys_programirq ; 44-ProgramIrqs
dd reserve_free_irq ; 45-ReserveIrq and FreeIrq
dd syscall_reserveportarea ; 46-ReservePortArea and FreePortArea
dd display_number ; 47-WriteNum
dd display_settings ; 48-SetRedrawType and SetButtonType
dd sys_apm ; 49-Advanced Power Management (APM)
dd random_shaped_window ; 50-Window shape & scale
dd syscall_threads ; 51-Threads
dd stack_driver_stat ; 52-Stack driver status
dd socket ; 53-Socket interface
dd user_events ; 54-User events
dd sound_interface ; 55-Sound interface
dd undefined_syscall ; 56-reserved
dd undefined_syscall ; 57-reserved
dd file_system ; 58-Common file system interface
dd sys_trace ; 59-System call trace
dd sys_IPC ; 60-Inter Process Communication
dd sys_gs ; 61-Direct graphics access
dd sys_pci ; 62-PCI functions
dd sys_msg_board ; 63-System message board
dd sys_resize_app_memory ; 64-Resize application memory usage
dd undefined_syscall ; 65-UTF
dd sys_process_def ; 66-Process definitions - keyboard
dd sys_window_move ; 67-Window move or resize
dd new_services ; 68-Some internal services
dd sys_debug_services ; 69-Debug
dd file_system_lfn ; 70-Common file system interface, version 2
dd syscall_windowsettings ; 71-Window settings
 
times 255 - ( ($-servetable) /4 ) dd undefined_syscall
 
dd sys_end ; -1-end application
endg
/kernel/tags/kolibri0.6.3.0/core/taskman.inc
0,0 → 1,1166
GREEDY_KERNEL equ 0; 1
 
 
struc APP_HEADER_00
{ .banner dq ?
.version dd ? ;+8
.start dd ? ;+12
.i_end dd ? ;+16
.mem_size dd ? ;+20
.i_param dd ? ;+24
}
 
struc APP_HEADER_01
{ .banner dq ?
.version dd ? ;+8
.start dd ? ;+12
.i_end dd ? ;+16
.mem_size dd ? ;+20
.stack_top dd ? ;+24
.i_param dd ? ;+28
.i_icon dd ? ;+32
}
 
align 4
proc test_app_header stdcall, header:dword
virtual at ebx
APP_HEADER_00 APP_HEADER_00
end virtual
 
mov ebx, [header]
cmp [ebx+6], word '00'
jne .check_01_header
 
mov eax,[APP_HEADER_00.start]
mov [app_start],eax
mov eax,[APP_HEADER_00.i_end]
mov [app_i_end],eax
mov eax,[APP_HEADER_00.mem_size]
mov [app_mem],eax
shr eax,1
sub eax,0x10
mov [app_esp],eax
mov eax,[APP_HEADER_00.i_param]
mov [app_i_param],eax
mov [app_i_icon],dword 0
 
mov eax,1
ret
 
.check_01_header:
virtual at ebx
APP_HEADER_01 APP_HEADER_01
end virtual
 
cmp [ebx+6],word '01'
jne .no_01_header
 
mov eax,[APP_HEADER_01.start]
mov [app_start],eax
mov eax,[APP_HEADER_01.i_end]
mov [app_i_end],eax
mov eax,[APP_HEADER_01.mem_size]
mov [app_mem],eax
mov eax,[APP_HEADER_01.stack_top]
mov [app_esp],eax
mov eax,[APP_HEADER_01.i_param]
mov [app_i_param],eax
mov eax,[APP_HEADER_01.i_icon]
mov [app_i_icon],eax
 
mov eax,1
ret
 
.no_01_header:
 
xor eax, eax
ret
endp
 
align 4
proc get_new_process_place
;input:
; none
;result:
; eax=[new_process_place]<>0 - ok
; 0 - failed.
;This function find least empty slot.
;It doesn't increase [TASK_COUNT]!
mov eax,CURRENT_TASK
mov ebx,[TASK_COUNT]
inc ebx
shl ebx,5
add ebx,eax ;ebx - address of process information for (last+1) slot
.newprocessplace:
;eax = address of process information for current slot
cmp eax,ebx
jz .endnewprocessplace ;empty slot after high boundary
add eax,0x20
cmp word [eax+0xa],9 ;check process state, 9 means that process slot is empty
jnz .newprocessplace
.endnewprocessplace:
mov ebx,eax
sub eax,CURRENT_TASK
shr eax,5 ;calculate slot index
cmp eax,256
jge .failed ;it should be <256
mov word [ebx+0xa],9 ;set process state to 9 (for slot after hight boundary)
; mov [new_process_place], eax
ret
 
.failed:
xor eax,eax
ret
endp
 
align 4
proc create_app_space stdcall, app_size:dword,img_size:dword
locals
app_pages dd ?
img_pages dd ?
dir_addr dd ?
app_tabs dd ?
endl
 
stdcall wait_mutex, pg_data.pg_mutex
 
xor eax, eax
mov [dir_addr], eax
 
mov eax, [app_size]
add eax, 4095
and eax, NOT(4095)
mov [app_size], eax
mov ebx, eax
shr eax, 12
mov [app_pages], eax
 
add ebx, 0x3FFFFF
and ebx, NOT(0x3FFFFF)
shr ebx, 22
mov [app_tabs], ebx
 
mov ecx, [img_size]
add ecx, 4095
and ecx, NOT(4095)
 
mov [img_size], ecx
shr ecx, 12
mov [img_pages], ecx
 
if GREEDY_KERNEL
lea eax, [ecx+ebx+2] ;only image size
else
lea eax, [eax+ebx+2] ;all requested memory
end if
cmp eax, [pg_data.pages_free]
ja .fail
 
call alloc_page
test eax, eax
jz .fail
mov [dir_addr], eax
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW
 
mov esi, sys_pgdir
mov edi, [tmp_task_pdir]
mov ecx, 384
cld
rep movsd
 
mov ecx, 384
xor eax, eax
cld
rep stosd
 
mov ecx, 256
mov esi, sys_pgdir+0xc00
rep movsd
 
mov eax, [dir_addr]
or eax, PG_SW
mov ebx, [tmp_task_pdir]
mov [ebx+0x600], eax
 
mov eax, [dir_addr]
call set_cr3
 
mov edx, [app_tabs]
mov edi, new_app_base
@@:
call alloc_page
test eax, eax
jz .fail
 
stdcall map_page_table, edi, eax
add edi, 0x00400000
dec edx
jnz @B
 
mov edi, new_app_base
shr edi, 10
add edi, pages_tab
mov ecx, [app_tabs]
shl ecx, 10
xor eax, eax
rep stosd
 
mov edx, new_app_base
.alloc:
call alloc_page
test eax, eax
jz .fail
 
stdcall map_page,edx,eax,dword PG_UW
add edx, 0x1000
sub [app_pages], 1
sub [img_pages], 1
jnz .alloc
 
mov ecx, [app_pages]
and ecx, ecx
jz .next
 
mov ebx, edx
shr edx, 12
.reserve:
mov dword [pages_tab+edx*4], 0x02
invlpg [ebx]
inc edx
dec ecx
jnz .reserve
.next:
mov edi, new_app_base
mov ecx, [img_size]
shr ecx, 2
xor eax, eax
cld
rep stosd
 
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
 
dec [pg_data.pg_mutex]
mov eax, [dir_addr]
ret
.fail:
dec [pg_data.pg_mutex]
cmp [dir_addr], 0
jz @f
stdcall destroy_app_space, [dir_addr]
@@:
xor eax, eax
ret
endp
 
align 4
set_cr3:
mov esi, [CURRENT_TASK]
mov ebx, esi
shl esi,8
mov [PROC_BASE+esi+0xB8],eax
imul ebx,tss_step
add ebx,tss_data
mov [ebx+28], eax
mov cr3, eax
ret
 
align 4
proc destroy_page_table stdcall, pg_tab:dword
 
push esi
 
mov esi, [pg_tab]
mov ecx, 1024
.free:
mov eax, [esi]
test eax, 1
jz .next
call free_page
.next:
add esi, 4
dec ecx
jnz .free
pop esi
ret
endp
 
align 4
proc destroy_app_space stdcall, pg_dir:dword
 
stdcall wait_mutex, pg_data.pg_mutex
 
xor edx,edx
mov eax,0x2
mov ebx, [pg_dir]
 
.loop:
;eax = current slot of process
mov ecx,eax
shl ecx,5
cmp byte [CURRENT_TASK+ecx+0xa],9 ;if process running?
jz @f ;skip empty slots
shl ecx,3
cmp [PROC_BASE+ecx+0xB8],ebx ;compare page directory addresses
jnz @f
inc edx ;thread found
@@:
inc eax
cmp eax,[TASK_COUNT] ;exit loop if we look through all processes
jle .loop
 
;edx = number of threads
;our process is zombi so it isn't counted
cmp edx,1
jg .exit
;if there isn't threads then clear memory.
 
mov eax, [pg_dir]
and eax, not 0xFFF
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW
mov esi, [tmp_task_pdir]
add esi, 0x604
mov edi, 383
.destroy:
mov eax, [esi]
test eax, 1
jz .next
and eax, not 0xFFF
stdcall map_page,[tmp_task_ptab],eax,dword PG_SW
stdcall destroy_page_table, [tmp_task_ptab]
mov eax, [esi]
call free_page
.next:
add esi, 4
dec edi
jnz .destroy
 
mov eax, [pg_dir]
call free_page
.exit:
stdcall map_page,[tmp_task_ptab],dword 0,dword PG_UNMAP
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
dec [pg_data.pg_mutex]
ret
endp
 
align 4
proc fs_execute
 
;fn_read:dword, file_size:dword, cluster:dword
 
; ebx - cmdline
; edx - flags
; ebp - full filename
; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it
 
locals
cmdline dd ?
flags dd ?
filename dd ?
retval dd ?
endl
 
pushad
 
mov [cmdline], ebx
mov [flags], edx
mov eax, [ebp]
mov [filename], eax
 
stdcall wait_mutex, pg_data.tmp_task_mutex
 
mov edi, [tmp_task_data]
mov ecx, (2048+256)/4
xor eax, eax
rep stosd
 
mov esi, [filename]
mov edi, [tmp_task_data]
add edi, TMP_FILE_NAME
mov ecx, 1024
rep movsb
 
mov esi, [filename]
mov edi, [tmp_task_data]
add edi, TMP_ICON_OFFS
mov ecx, 1024
rep movsb
 
mov esi, [cmdline]
test esi, esi
jz @f
mov edi, [tmp_task_data]
add edi, TMP_CMD_LINE
mov ecx, 256
rep movsb
@@:
mov eax, TMP_FILE_NAME
add eax, [tmp_task_data]
mov ebx, [tmp_task_data] ;cmd line
add ebx, TMP_CMD_LINE
 
stdcall fs_exec, eax, ebx, [flags], [ebp+8],\
[ebp+12], [ebp+16],[ebp+20]
mov [retval], eax
popad
mov [pg_data.tmp_task_mutex], 0
mov eax, [retval]
ret
 
endp
 
align 4
proc fs_exec stdcall file_name:dword, cmd_line:dword, flags:dword,\
fn_read:dword, file_size:dword,\
cluster:dword, some_data:dword
 
locals
slot dd ?
app_path_size dd ?
save_cr3 dd ?
img_size dd ?
endl
 
; check filename length - with terminating NULL must be no more than 1024 symbols
 
mov edi, [file_name]
mov ecx, 1024
xor eax, eax
repnz scasb
jz @f
mov eax, -ERROR_FILE_NOT_FOUND
ret
@@:
sub edi, [file_name]
mov [app_path_size], edi
 
mov esi, new_process_loading
call sys_msg_board_str ; write message to message board
 
pushfd
cli
 
.wait_lock:
cmp [application_table_status],0
je .get_lock
call change_task
jmp .wait_lock
 
.get_lock:
mov eax, 1
xchg eax, [application_table_status]
cmp eax, 0
jne .wait_lock
 
call set_application_table_status
 
call get_new_process_place
test eax, eax
mov ecx, -0x20 ; too many processes
jz .err
mov [slot], eax
 
mov edi,eax
shl edi,8
add edi,PROC_BASE
mov ecx,256/4
xor eax,eax
cld
rep stosd ;clean extended information about process
 
; write application name
 
mov edi, [file_name]
mov ecx, [app_path_size]
add edi, ecx
dec edi
std
mov al, '/'
repnz scasb
cld
jnz @f
inc edi
@@:
inc edi
; now edi points to name without path
 
mov esi, edi
mov ecx, 8 ; 8 chars for name
mov edi, [slot]
shl edi, cl
add edi, PROC_BASE
.copy_process_name_loop:
lodsb
cmp al, '.'
jz .copy_process_name_done
test al, al
jz .copy_process_name_done
stosb
loop .copy_process_name_loop
.copy_process_name_done:
mov al, ' '
rep stosb
pop eax
mov cl, 3 ; 3 chars for extension
dec esi
@@:
dec eax
cmp eax, esi
jbe .copy_process_ext_done
cmp byte [eax], '.'
jnz @b
lea esi, [eax+1]
.copy_process_ext_loop:
lodsb
test al, al
jz .copy_process_ext_done
stosb
loop .copy_process_ext_loop
.copy_process_ext_done:
mov al, ' '
rep stosb
 
; read header
lea eax, [file_size]
mov ebx, [eax]
mov [img_size], ebx
mov edi, TMP_BUFF
call [fn_read]
 
test eax, eax
jnz .err
 
; check menuet signature
 
mov ecx, -0x1F
;check MENUET signature
cmp [TMP_BUFF],dword 'MENU'
jnz .err
cmp [TMP_BUFF+4],word 'ET'
jnz .err
 
stdcall test_app_header, TMP_BUFF
test eax, eax
jz .err
 
mov eax, cr3
mov [save_cr3], eax
if GREEDY_KERNEL
stdcall create_app_space,[app_mem],[img_size]
else
stdcall create_app_space,[app_mem],[app_mem]
end if
test eax, eax
jz .failed
 
mov ebx,[slot]
shl ebx,8
mov [PROC_BASE+ebx+0xB8],eax
 
mov esi, TMP_BUFF
mov edi, new_app_base
mov ecx, 512/4
cld
rep movsd
 
;read file
@@:
lea eax, [file_size]
cmp dword [eax], 0
jz .done
push edi
call [fn_read]
pop edi
add edi, 512
test eax, eax
jz @b
cmp ebx, 6
jne .failed
.done:
stdcall add_app_parameters, [slot], new_app_base,\
[cmd_line],[file_name],[flags]
 
mov eax, [save_cr3]
call set_cr3
 
xor eax, eax
mov [application_table_status],eax ;unlock application_table_status mutex
popfd
mov eax,[process_number] ;set result
ret
 
.failed:
mov eax, [save_cr3]
call set_cr3
.err:
 
popfd
xor eax, eax
mov [application_table_status],eax
ret
endp
 
align 4
proc add_app_parameters stdcall,slot:dword,img_base:dword,\
cmd_line:dword, app_path:dword, flags:dword
 
mov eax,[slot]
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
shl eax, 8
mov ebx, eax
add eax, eax
add eax, [fpu_data]
mov [ebx+PROC_BASE+APPDATA.fpu_state], eax
mov [ebx+PROC_BASE+APPDATA.fpu_handler], 0
mov [ebx+PROC_BASE+APPDATA.sse_handler], 0
jmp .m1
.no_SSE:
mov ecx, eax
mov ebx, eax
shl eax, 7
shl ebx, 4
sub eax, ebx ;eax*=112
add eax, [fpu_data]
shl ecx, 8
mov [ecx+PROC_BASE+APPDATA.fpu_state], eax
mov [ecx+PROC_BASE+APPDATA.fpu_handler], 0
mov [ecx+PROC_BASE+APPDATA.sse_handler], 0
.m1:
mov ebx,[slot]
cmp ebx,[TASK_COUNT]
jle .noinc
inc dword [TASK_COUNT] ;update number of processes
.noinc:
shl ebx,8
mov eax,[app_mem]
mov [PROC_BASE+0x8c+ebx],eax
 
shr ebx,3
mov eax, new_app_base
mov dword [CURRENT_TASK+ebx+0x10],eax
 
.add_command_line:
mov edx,[app_i_param]
test edx,edx
jz .no_command_line ;application don't need parameters
mov eax,[cmd_line]
test eax,eax
jz .no_command_line ;no parameters specified
;calculate parameter length
xor ecx,ecx
.command_line_len:
cmp byte [eax],0
jz .command_line_len_end
inc eax
inc ecx
cmp ecx,255
jl .command_line_len
 
.command_line_len_end:
;ecx - parameter length
;edx - address of parameters in new process address space
inc ecx
mov edi, [img_base]
add edi, edx
mov esi, [cmd_line]
rep movsb
 
.no_command_line:
 
mov edx,[app_i_icon]
test edx,edx
jz .no_command_line_1 ;application don't need path of file
mov esi,[app_path]
test esi, esi
jz .no_command_line_1 ;application don't need path of file
mov ecx, 64
mov edi, [img_base]
add edi, edx
rep movsb
 
.no_command_line_1:
mov ebx,[slot]
mov eax,ebx
shl ebx,5
; set window state to 'normal' (non-minimized/maximized/rolled-up) state
mov [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL
mov [ebx+window_data+WDATA.fl_redraw], 1
add ebx,CURRENT_TASK ;ebx - pointer to information about process
mov [ebx+TASKDATA.wnd_number],al;set window number on screen = process slot
 
mov [ebx+TASKDATA.event_mask],dword 1+2+4 ;set default event flags (see 40 function)
 
inc dword [process_number]
mov eax,[process_number]
mov [ebx+4],eax ;set PID
 
mov ecx,ebx
add ecx,(draw_data-CURRENT_TASK) ;ecx - pointer to draw data
;set draw data to full screen
 
mov [ecx+0],dword 0
mov [ecx+4],dword 0
mov eax,[SCR_X_SIZE]
mov [ecx+8],eax
mov eax,[SCR_Y_SIZE]
mov [ecx+12],eax
;set cr3 register in TSS of application
 
mov ecx,[slot]
shl ecx,8
mov eax,[PROC_BASE+0xB8+ecx]
;or eax, PG_NOCACHE
mov [l.cr3],eax
 
mov eax,[app_start]
mov [l.eip],eax ;set eip in TSS
mov eax,[app_esp]
mov [l.esp],eax ;set stack in TSS
 
;gdt
mov ax,app_code ;ax - selector of code segment
mov [l.cs],ax
mov ax,app_data
mov [l.ss],ax
mov [l.ds],ax
mov [l.es],ax
mov [l.fs],ax
mov ax,graph_data ;ax - selector of graphic segment
mov [l.gs],ax
mov [l.io],word 128
mov [l.eflags],dword 0x1202
 
mov [l.ss0],os_data
mov ebx,[slot]
shl ebx,12
add ebx,sysint_stack_data+4096
mov [l.esp0],ebx
 
;copy tss to it place
mov eax,tss_sceleton
mov ebx,[slot]
imul ebx,tss_step
add ebx,tss_data ;ebx - address of application TSS
mov ecx,120
call memmove
 
;Add IO access table - bit array of permitted ports
or eax,-1
mov edi,[slot]
imul edi,tss_step
add edi,tss_data+128
mov ecx,2048
cld
rep stosd ;full access to 2048*8=16384 ports
 
mov ecx,ebx ;ecx - address of application TSS
mov edi,[slot]
shl edi,3
;set TSS descriptor
mov [edi+gdts+tss0+0],word tss_step ;limit (size)
mov [edi+gdts+tss0+2],cx ;part of offset
mov eax,ecx
shr eax,16
mov [edi+gdts+tss0+4],al ;part of offset
mov [edi+gdts+tss0+7],ah ;part of offset
mov [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags
 
;flush keyboard and buttons queue
mov [KEY_COUNT],byte 0
mov [BTN_COUNT],byte 0
 
mov edi,[slot]
shl edi,5
add edi,window_data
mov ebx,[slot]
movzx esi,word [WIN_STACK+ebx*2]
lea esi,[WIN_POS+esi*2]
call windowactivate ;gui initialization
 
mov ebx,[slot]
shl ebx,5
mov [CURRENT_TASK+ebx+0xa],byte 0 ;set process state - running
; set if debuggee
mov eax, [flags]
test byte [flags], 1
jz .no_debug
mov [CURRENT_TASK+ebx+0xa],byte 1 ;set process state - suspended
mov eax,[CURRENT_TASK]
mov [PROC_BASE+ebx*8+0xac],eax ;set debugger PID - current
.no_debug:
 
mov esi,new_process_running
call sys_msg_board_str ;output information about succefull startup
 
ret
endp
 
pid_to_slot:
;Input:
; eax - pid of process
;Output:
; eax - slot of process or 0 if process don't exists
;Search process by PID.
push ebx
push ecx
mov ebx,[TASK_COUNT]
shl ebx,5
mov ecx,2*32
 
.loop:
;ecx=offset of current process info entry
;ebx=maximum permitted offset
cmp byte [CURRENT_TASK+ecx+0xa],9
jz .endloop ;skip empty slots
cmp [CURRENT_TASK+ecx+0x4],eax ;check PID
jz .pid_found
.endloop:
add ecx,32
cmp ecx,ebx
jle .loop
 
pop ecx
pop ebx
xor eax,eax
ret
 
.pid_found:
shr ecx,5
mov eax,ecx ;convert offset to index of slot
pop ecx
pop ebx
ret
 
check_region:
;input:
; ebx - start of buffer
; ecx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
mov eax,[CURRENT_TASK]
jmp check_process_region
;-----------------------------------------------------------------------------
check_process_region:
;input:
; eax - slot
; ebx - start of buffer
; ecx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
 
test ecx,ecx
jle .ok
shl eax,5
cmp word [CURRENT_TASK+eax+0xa],0
jnz .failed
shl eax,3
mov eax,[PROC_BASE+eax+0xb8]
test eax,eax
jz .failed
 
mov eax,1
ret
 
 
; call MEM_Get_Linear_Address
; push ebx
; push ecx
; push edx
; mov edx,ebx
; and edx,not (4096-1)
; sub ebx,edx
; add ecx,ebx
; mov ebx,edx
; add ecx,(4096-1)
; and ecx,not (4096-1)
;.loop:
;;eax - linear address of page directory
;;ebx - current page
;;ecx - current size
; mov edx,ebx
; shr edx,22
; mov edx,[eax+4*edx]
; and edx,not (4096-1)
; test edx,edx
; jz .failed1
; push eax
; mov eax,edx
; call MEM_Get_Linear_Address
; mov edx,ebx
; shr edx,12
; and edx,(1024-1)
; mov eax,[eax+4*edx]
; and eax,not (4096-1)
; test eax,eax
; pop eax
; jz .failed1
; add ebx,4096
; sub ecx,4096
; jg .loop
; pop edx
; pop ecx
; pop ebx
.ok:
mov eax,1
ret
;
;.failed1:
; pop edx
; pop ecx
; pop ebx
.failed:
xor eax,eax
ret
 
align 4
proc read_process_memory
;Input:
; eax - process slot
; ebx - buffer address
; ecx - buffer size
; edx - start address in other process
;Output:
; eax - number of bytes read.
locals
slot dd ?
buff dd ?
r_count dd ?
offset dd ?
tmp_r_cnt dd ?
endl
 
mov [slot], eax
mov [buff], ebx
mov [r_count], ecx
mov [tmp_r_cnt], ecx
mov [offset], edx
 
pushad
.read_mem:
mov edx, [offset]
mov ebx, [tmp_r_cnt]
 
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
@@:
mov eax, [slot]
shl eax,8
mov ebx, [offset]
add ebx, new_app_base
push ecx
stdcall map_memEx, [proc_mem_map],\
[PROC_BASE+eax+0xB8],\
ebx, ecx
pop ecx
 
mov esi, [offset]
and esi, 0xfff
add esi, [proc_mem_map]
mov edi, [buff]
mov edx, ecx
rep movsb
 
add [offset], edx
sub [tmp_r_cnt], edx
jnz .read_mem
 
popad
mov eax, [r_count]
ret
 
endp
 
align 4
proc write_process_memory
;Input:
; eax - process slot
; ebx - buffer address
; ecx - buffer size
; edx - start address in other process
;Output:
; eax - number of bytes written
 
locals
slot dd ?
buff dd ?
w_count dd ?
offset dd ?
tmp_w_cnt dd ?
endl
 
mov [slot], eax
mov [buff], ebx
mov [w_count], ecx
mov [tmp_w_cnt], ecx
mov [offset], edx
 
pushad
.read_mem:
mov edx, [offset]
mov ebx, [tmp_w_cnt]
 
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
@@:
mov eax, [slot]
shl eax,8
mov ebx, [offset]
add ebx, new_app_base
push ecx
stdcall map_memEx, [proc_mem_map],\
[PROC_BASE+eax+0xB8],\
ebx, ecx
pop ecx
 
mov edi, [offset]
and edi, 0xfff
add edi, [proc_mem_map]
mov esi, [buff]
mov edx, ecx
rep movsb
 
add [offset], edx
sub [tmp_w_cnt], edx
jnz .read_mem
 
popad
mov eax, [w_count]
ret
endp
 
 
align 4
proc new_sys_threads
locals
thread_start dd ?
thread_stack dd ?
params dd ?
slot dd ?
endl
 
mov [thread_start], ebx
mov [thread_stack], ecx
mov [params], 0
 
xor edx,edx ; flags=0
 
cmp eax,1
jnz .failed ;other subfunctions
mov esi,new_process_loading
call sys_msg_board_str
 
.wait_lock:
cmp [application_table_status],0
je .get_lock
call change_task
jmp .wait_lock
 
.get_lock:
mov eax, 1
xchg eax, [application_table_status]
cmp eax, 0
jne .wait_lock
 
call set_application_table_status
 
call get_new_process_place
test eax, eax
jz .failed
 
mov [slot], eax
 
xor eax,eax
mov [app_i_param],eax
mov [app_i_icon],eax
 
mov ebx, [thread_start]
mov ecx, [thread_stack]
 
mov [app_start],ebx
mov [app_esp],ecx
 
mov esi,[CURRENT_TASK]
shl esi,8
add esi,PROC_BASE
mov ebx,esi ;ebx=esi - pointer to extended information about current thread
 
mov edi,[slot]
shl edi,8
add edi,PROC_BASE
mov edx,edi ;edx=edi - pointer to extended infomation about new thread
mov ecx,256/4
rep stosd ;clean extended information about new thread
mov edi,edx
mov ecx,11
rep movsb ;copy process name
mov eax,[ebx+APPDATA.heap_base]
mov [edx+APPDATA.heap_base], eax
mov ecx,[ebx+APPDATA.heap_top]
mov [edx+APPDATA.heap_top], ecx
mov eax,[ebx+APPDATA.mem_size]
mov [app_mem],eax ;set memory size
mov eax,[ebx+0xb8]
mov [edx+0xb8],eax ;copy page directory
 
stdcall add_app_parameters, [slot], new_app_base,\
[params], dword 0,dword 0
 
mov esi,new_process_running
call sys_msg_board_str ;output information about succefull startup
 
mov [application_table_status],0 ;unlock application_table_status mutex
mov eax,[process_number] ;set result
ret
.failed:
mov [application_table_status],0
mov eax,-1
ret
endp
 
align 4
proc wait_mutex stdcall, mutex:dword
mov ebx, [mutex]
.wait_lock:
cmp dword [ebx],0
je .get_lock
push ebx
call change_task
pop ebx
jmp .wait_lock
 
.get_lock:
mov eax, 1
xchg eax, [ebx]
test eax, eax
jnz .wait_lock
ret
endp
 
 
include "debug.inc"
 
iglobal
new_process_loading db 'K : New Process - loading',13,10,0
new_process_running db 'K : New Process - done',13,10,0
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
endg
 
/kernel/tags/kolibri0.6.3.0/core/heap.inc
0,0 → 1,832
 
HEAP_BASE equ 0x01000000
;HEAP_SIZE equ 0x01000000
 
struc MEM_BLOCK
{ .next_block dd ?
.prev_block dd ? ;+4
.list_next dd ? ;+8
.list_prev dd ? ;+12
.base dd ? ;+16
.size dd ? ;+20
.flags dd ? ;+24
.handle dd ? ;+28
}
 
FREE_BLOCK equ 4
USED_BLOCK equ 8
 
virtual at 0
MEM_BLOCK MEM_BLOCK
end virtual
 
MEM_BLOCK_SIZE equ 8*4
 
block_next equ MEM_BLOCK.next_block
block_prev equ MEM_BLOCK.prev_block
list_next equ MEM_BLOCK.list_next
list_prev equ MEM_BLOCK.list_prev
block_base equ MEM_BLOCK.base
block_size equ MEM_BLOCK.size
block_flags equ MEM_BLOCK.flags
 
macro calc_index op
{ shr op, 12
dec op
cmp op, 63
jna @f
mov op, 63
@@:
}
 
macro remove_from_list op
{ mov edx, [op+list_next]
mov ecx, [op+list_prev]
test edx, edx
jz @f
mov [edx+list_prev], ecx
@@:
test ecx, ecx
jz @f
mov [ecx+list_next], edx
@@:
mov [op+list_next],0
mov [op+list_prev],0
}
 
macro remove_from_free op
{
remove_from_list op
 
mov eax, [op+block_size]
calc_index eax
cmp [mem_block_list+eax*4], op
jne @f
mov [mem_block_list+eax*4], edx
@@:
cmp [mem_block_list+eax*4], 0
jne @f
btr [mem_block_mask], eax
@@:
}
 
macro remove_from_used op
{
remove_from_list op
cmp [mem_used_list], op
jne @f
mov [mem_used_list], edx
@@:
}
 
align 4
proc init_kernel_heap
 
mov ecx, 64/4
mov edi, mem_block_list
xor eax, eax
cld
rep stosd
 
mov ecx, 512/4
mov edi, mem_block_map
not eax
rep stosd
 
mov [mem_block_start], mem_block_map
mov [mem_block_end], mem_block_map+512
mov [mem_block_arr], HEAP_BASE
 
stdcall alloc_pages, dword 32
mov ecx, 32
mov edx, eax
mov edi, HEAP_BASE
.l1:
stdcall map_page,edi,edx,PG_SW
add edi, 0x1000
add edx, 0x1000
dec ecx
jnz .l1
 
mov edi, HEAP_BASE
mov ebx, edi
add ebx, MEM_BLOCK_SIZE
xor eax, eax
mov [edi+block_next], ebx
mov [edi+block_prev], eax
mov [edi+list_next], eax
mov [edi+list_prev], eax
mov [edi+block_base], HEAP_BASE
mov [edi+block_size], 4096*MEM_BLOCK_SIZE
mov [edi+block_flags], USED_BLOCK
 
mov [ebx+block_next], eax
mov [ebx+block_prev], eax
mov [ebx+list_next], eax
mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE
 
mov ecx, [MEM_AMOUNT]
sub ecx, 0x01000000 + 4096*MEM_BLOCK_SIZE
mov [heap_size], ecx
mov [heap_free], ecx
mov [ebx+block_size], ecx
mov [ebx+block_flags], FREE_BLOCK
 
mov [mem_block_mask], eax
mov [mem_block_mask+4],0x80000000
 
mov [mem_used_list], eax
mov [mem_block_list+63*4], ebx
mov byte [mem_block_map], 0xFC
mov [heap_blocks], 4095
mov [free_blocks], 4095
ret
endp
 
align 4
proc get_block stdcall, index:dword
 
mov eax, 63
mov ecx, [index]
cmp ecx, eax
jna @f
;cmova ecx, eax
mov ecx, eax
@@:
xor esi, esi
xor ebx, ebx
xor edx, edx
not edx
 
cmp ecx, 32
jb .bit_test
 
sub ecx, 32
add ebx, 32
add esi, 4
 
.bit_test:
shl edx, cl
and edx, [mem_block_mask+esi]
jz .high_mask
bsf eax, edx
add ebx, eax
mov eax, [mem_block_list+ebx*4]
ret
 
.high_mask:
 
add esi, 4
add ebx, 32
test esi, 0xFFFFFFF8
jnz .big_error
mov edx, [mem_block_mask+esi]
and edx, edx
jz .high_mask
bsf eax, edx
add ebx, eax
mov eax, [mem_block_list+ebx*4]
ret
 
.big_error:
xor eax, eax
ret
endp
 
align 4
proc alloc_mem_block
 
pushfd
cli
mov ebx, [mem_block_start]
mov ecx, [mem_block_end]
.l1:
bsf eax,[ebx];
jnz found
add ebx,4
cmp ebx, ecx
jb .l1
popfd
xor eax,eax
ret
 
found:
btr [ebx], eax
mov [mem_block_start],ebx
sub ebx, mem_block_map
shl ebx, 3
add eax,ebx
shl eax, 5
add eax, [mem_block_arr]
dec [free_blocks]
popfd
ret
endp
 
proc free_mem_block
pushfd
cli
sub eax, [mem_block_arr]
shr eax, 5
 
mov ebx, mem_block_map
bts [ebx], eax
inc [free_blocks]
shr eax, 3
and eax, not 3
add eax, ebx
cmp [mem_block_start], eax
ja @f
popfd
ret
@@:
mov [mem_block_start], eax
popfd
ret
.err:
xor eax, eax
popfd
ret
endp
 
align 4
proc alloc_kernel_space stdcall, size:dword
local block_ind:DWORD
 
pushfd
cli
 
mov eax, [size]
add eax, 0xFFF
and eax, 0xFFFFF000;
mov [size], eax
cmp eax, [heap_free]
ja .error
 
shr eax, 12
sub eax, 1
 
mov [block_ind], eax
 
stdcall get_block, eax
and eax, eax
jz .error
 
mov edi, eax ;edi - pBlock
 
cmp [edi+block_flags], FREE_BLOCK
jne .error
 
mov [block_ind], ebx ;index of allocated block
 
mov eax, [edi+block_size]
cmp eax, [size]
je .m_eq_size
 
call alloc_mem_block
and eax, eax
jz .error
 
mov esi, eax ;esi - splitted block
 
mov [esi+block_next], edi
mov eax, [edi+block_prev]
mov [esi+block_prev], eax
mov [edi+block_prev], esi
mov [esi+list_next], 0
mov [esi+list_prev], 0
and eax, eax
jz @f
mov [eax+block_next], esi
@@:
mov ebx, [edi+block_base]
mov [esi+block_base], ebx
mov edx, [size]
mov [esi+block_size], edx
add [edi+block_base], edx
sub [edi+block_size], edx
 
mov eax, [edi+block_size]
shr eax, 12
sub eax, 1
cmp eax, 63
jna @f
mov eax, 63
@@:
cmp eax, [block_ind]
je .m_eq_ind
 
remove_from_list edi
 
mov ecx, [block_ind]
mov [mem_block_list+ecx*4], ebx
 
test ebx, ebx
jnz @f
btr [mem_block_mask], ecx
@@:
mov edx, [mem_block_list+eax*4]
mov [edi+list_next], edx
test edx, edx
jz @f
mov [edx+list_prev], edi
@@:
mov [mem_block_list+eax*4], edi
bts [mem_block_mask], eax
.m_eq_ind:
mov ebx, [mem_used_list]
mov [esi+list_next], ebx
test ebx, ebx
jz @f
mov [ebx+list_prev], esi
@@:
mov [esi+block_flags], USED_BLOCK
mov [mem_used_list], esi
mov eax, [esi+block_base]
mov ebx, [size]
sub [heap_free], ebx
popfd
ret
 
.m_eq_size:
remove_from_list edi
mov [mem_block_list+ebx*4], edx
and edx, edx
jnz @f
btr [mem_block_mask], ebx
@@:
mov ecx, [mem_used_list]
mov [edi+list_next], ecx
test ecx, ecx
jnz @f
mov [ecx+list_prev], edi
@@:
mov [mem_used_list], edi
mov [edi+block_flags], USED_BLOCK
mov eax, [edi+block_base]
mov ebx, [size]
sub [heap_free], ebx
popfd
ret
.error:
xor eax, eax
popfd
ret
endp
 
align 4
proc free_kernel_space stdcall, base:dword
 
mov eax, [base]
mov esi, [mem_used_list]
@@:
test esi, esi
jz .fail
 
cmp [esi+block_base], eax
je .found
mov esi, [esi+list_next]
jmp @b
.found:
cmp [esi+block_flags], USED_BLOCK
jne .fail
 
mov eax, [esi+block_size]
add [heap_free], eax
 
mov edi, [esi+block_next]
test edi, edi
jz .prev
 
cmp [edi+block_flags], FREE_BLOCK
jne .prev
 
remove_from_free edi
 
mov edx, [edi+block_next]
mov [esi+block_next], edx
test edx, edx
jz @f
 
mov [edx+block_prev], esi
@@:
mov ecx, [edi+block_size]
add [esi+block_size], ecx
 
mov eax, edi
call free_mem_block
.prev:
mov edi, [esi+block_prev]
test edi, edi
jz .insert
 
cmp [edi+block_flags], FREE_BLOCK
jne .insert
 
remove_from_used esi
 
mov edx, [esi+block_next]
mov [edi+block_next], edx
test edx, edx
jz @f
mov [edx+block_prev], edi
@@:
mov eax, esi
call free_mem_block
 
mov ecx, [edi+block_size]
mov eax, [esi+block_size]
add eax, ecx
mov [edi+block_size], eax
 
calc_index eax
calc_index ecx
cmp eax, ecx
je .m_eq
 
push ecx
remove_from_list edi
pop ecx
 
cmp [mem_block_list+ecx*4], edi
jne @f
mov [mem_block_list+ecx*4], edx
@@:
cmp [mem_block_list+ecx*4], 0
jne @f
btr [mem_block_mask], ecx
@@:
mov esi, [mem_block_list+eax*4]
mov [mem_block_list+eax*4], edi
mov [edi+list_next], esi
test esi, esi
jz @f
mov [esi+list_prev], edi
@@:
bts [mem_block_mask], eax
.m_eq:
xor eax, eax
not eax
ret
.insert:
remove_from_used esi
 
mov eax, [esi+block_size]
calc_index eax
 
mov edi, [mem_block_list+eax*4]
mov [mem_block_list+eax*4], esi
mov [esi+list_next], edi
test edi, edi
jz @f
mov [edi+list_prev], esi
@@:
bts [mem_block_mask], eax
mov [esi+block_flags],FREE_BLOCK
xor eax, eax
not eax
ret
.fail:
xor eax, eax
ret
endp
 
align 4
proc kernel_alloc stdcall, size:dword
locals
lin_addr dd ?
pages_count dd ?
endl
 
mov eax, [size]
add eax, 0xFFF
and eax, 0xFFFFF000;
mov [size], eax
and eax, eax
jz .error
mov ebx, eax
shr ebx, 12
mov [pages_count], ebx
 
stdcall alloc_kernel_space, eax
and eax, eax
jz .error
mov [lin_addr], eax
 
mov ecx, [pages_count]
mov edx, eax
mov ebx, ecx
 
shr ecx, 3
jz .next
 
and ebx, not 7
push ebx
stdcall alloc_pages, ebx
pop ecx ; yes ecx!!!
and eax, eax
jz .error
 
mov edi, eax
mov edx, [lin_addr]
@@:
stdcall map_page,edx,edi,dword PG_SW
add edx, 0x1000
add edi, 0x1000
dec ecx
jnz @B
.next:
mov ecx, [pages_count]
and ecx, 7
jz .end
 
@@: push ecx
call alloc_page
pop ecx
test eax, eax
jz .error
 
stdcall map_page,edx,eax,dword PG_SW
add edx, 0x1000
dec ecx
jnz @B
.end:
mov eax, [lin_addr]
ret
 
.error:
xor eax, eax
ret
endp
 
align 4
proc kernel_free stdcall, base:dword
locals
size dd ?
endl
 
mov eax, [base]
mov esi, [mem_used_list]
@@:
test esi, esi
jz .fail
 
cmp [esi+block_base], eax
je .found
mov esi, [esi+list_next]
jmp @b
.found:
cmp [esi+block_flags], USED_BLOCK
jne .fail
 
mov ecx, [esi+block_size];
mov [size], ecx
 
stdcall free_kernel_space, [base]
test eax, eax
jz .fail
 
mov ecx, [size]
mov edi, [base]
 
shr ecx, 12
mov esi, edi
shr edi, 10
add edi, pages_tab
xor edx, edx
.release:
mov eax, [edi]
test eax, 1
jz .next
 
call free_page
mov [edi],edx
.next:
invlpg [esi]
add esi, 0x1000
add edi, 4
dec ecx
jnz .release
.fail:
ret
endp
 
restore block_next
restore block_prev
restore block_list
restore block_base
restore block_size
restore block_flags
 
;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;;
 
HEAP_TOP equ 0x5FC00000
 
align 4
proc init_heap
 
mov ebx,[CURRENT_TASK]
shl ebx,8
mov eax, [PROC_BASE+APPDATA.heap_top+ebx]
test eax, eax
jz @F
sub eax,[PROC_BASE+APPDATA.heap_base+ebx]
sub eax, 4096
ret
@@:
mov esi, [PROC_BASE+APPDATA.mem_size+ebx]
add esi, 4095
and esi, not 4095
mov eax, HEAP_TOP
mov [PROC_BASE+APPDATA.heap_base+ebx], esi
mov [PROC_BASE+APPDATA.heap_top+ebx], eax
 
sub eax, esi
add esi, new_app_base
shr esi, 10
mov ecx, eax
sub eax, 4096
or ecx, FREE_BLOCK
mov [pages_tab+esi], ecx
ret
.exit:
xor eax, eax
ret
endp
 
align 4
proc user_alloc stdcall, alloc_size:dword
 
mov ecx, [alloc_size]
add ecx, (4095+4096)
and ecx, not 4095
 
mov ebx, [CURRENT_TASK]
shl ebx, 8
mov esi, dword [ebx+PROC_BASE+APPDATA.heap_base]; heap_base
mov edi, dword [ebx+PROC_BASE+APPDATA.heap_top]; heap_top
add esi, new_app_base
add edi, new_app_base
 
l_0:
cmp esi, edi
jae m_exit
 
mov ebx, esi
shr ebx, 12
mov eax, [pages_tab+ebx*4]
test eax, FREE_BLOCK
jz test_used
and eax, 0xFFFFF000
cmp eax, ecx ;alloc_size
jb m_next
 
mov edx, esi
add edx, ecx
sub eax, ecx;
or eax, FREE_BLOCK
shr edx, 12
mov [pages_tab+edx*4], eax
 
or ecx, USED_BLOCK
mov [pages_tab+ebx*4], ecx
shr ecx, 12
dec ecx
inc ebx
@@:
mov dword [pages_tab+ebx*4], 2
inc ebx
dec ecx
jnz @B
 
mov eax, esi
add eax, 4096
sub eax, new_app_base
ret
m_next:
add esi, eax
jmp l_0
test_used:
test eax, USED_BLOCK
jz m_exit
 
and eax, 0xFFFFF000
add esi, eax
jmp l_0
m_exit:
xor eax, eax
ret
endp
 
align 4
proc user_free stdcall, base:dword
 
mov esi, [base]
test esi, esi
jz .exit
 
sub esi, 4096
shr esi, 12
mov eax, [pages_tab+esi*4]
test eax, USED_BLOCK
jz .not_used
 
and eax, not 4095
mov ecx, eax
or eax, FREE_BLOCK
mov [pages_tab+esi*4], eax
inc esi
sub ecx, 4096
shr ecx, 12
.release:
xor eax, eax
xchg eax, [pages_tab+esi*4]
test eax, 1
jz @F
call free_page
@@:
inc esi
dec ecx
jnz .release
.not_used:
mov ebx, [CURRENT_TASK]
shl ebx, 8
mov esi, dword [ebx+PROC_BASE+APPDATA.heap_base]; heap_base
mov edi, dword [ebx+PROC_BASE+APPDATA.heap_top]; heap_top
shr esi, 12
shr edi, 12
@@:
mov eax, [pages_tab+esi*4]
test eax, USED_BLOCK
jz .test_free
shr eax, 12
add esi, eax
jmp @B
.test_free:
test eax, FREE_BLOCK
jz .err
mov edx, eax
shr edx, 12
add edx, esi
cmp edx, edi
jae .exit
 
mov ebx, [pages_tab+edx*4]
test ebx, USED_BLOCK
jz .next_free
 
shr ebx, 12
add edx, ebx
mov esi, edx
jmp @B
.next_free:
test ebx, FREE_BLOCK
jz .err
and dword [pages_tab+edx*4], 0
add eax, ebx
and eax, not 4095
or eax, FREE_BLOCK
mov [pages_tab+esi*4], eax
jmp @B
.exit:
xor eax, eax
inc eax
ret
.err:
xor eax, eax
ret
endp
 
align 4
proc alloc_dll
pushf
cli
bsf eax, [dll_map]
jnz .find
popf
xor eax, eax
ret
.find:
btr [dll_map], eax
popf
shl eax, 5
add eax, dll_tab
ret
endp
 
align 4
proc alloc_service
pushf
cli
bsf eax, [srv_map]
jnz .find
popf
xor eax, eax
ret
 
.find: btr [srv_map], eax
popf
shl eax,5
add eax, srv_tab
ret
endp
/kernel/tags/kolibri0.6.3.0/core/exports.inc
0,0 → 1,45
 
iglobal
 
align 16
kernel_export:
dd szAttachIntHandler, attach_int_handler
dd szSysMsgBoardStr , sys_msg_board_str
dd szPciApi , pci_api
dd szPciRead32 , pci_read32
dd szPciRead8 , pci_read8
dd szPciWrite8 , pci_write8
dd szAllocKernelSpace, alloc_kernel_space
dd szMapPage , map_page
dd szRegService , reg_service
dd szKernelAlloc , kernel_alloc
dd szKernelFree , kernel_free
dd szGetPgAddr , get_pg_addr
dd szGetCurrentTask , get_curr_task
dd szGetService , get_service
dd szServiceHandler , srv_handler
dd szFpuSave , fpu_save
dd szFpuRestore , fpu_restore
dd 0
 
szKernel db 'KERNEL', 0
szAttachIntHandler db 'AttachIntHandler',0
szSysMsgBoardStr db 'SysMsgBoardStr', 0
szPciApi db 'PciApi', 0
szPciRead32 db 'PciRead32', 0
szPciRead8 db 'PciRead8', 0
szPciWrite8 db 'PciWrite8',0
szAllocKernelSpace db 'AllocKernelSpace',0
szMapPage db 'MapPage',0
szRegService db 'RegService',0
szKernelAlloc db 'KernelAlloc',0
szKernelFree db 'KernelFree',0
szGetPgAddr db 'GetPgAddr',0
szGetCurrentTask db 'GetCurrentTask',0
szGetService db 'GetService',0
szServiceHandler db 'ServiceHandler',0
szFpuSave db 'FpuSave',0
szFpuRestore db 'FpuRestore',0
 
endg
 
/kernel/tags/kolibri0.6.3.0/core/sched.inc
0,0 → 1,204
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; IRQ0 HANDLER (TIMER INTERRUPT) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
align 32
irq0:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
 
inc dword [timer_ticks]
 
mov eax, [timer_ticks]
call playNote ; <<<--- Speaker driver
 
cmp eax,[next_usage_update]
jb .nocounter
add eax,100
mov [next_usage_update],eax
call updatecputimes
.nocounter:
 
cmp [0xffff], byte 1
jne .change_task
 
mov al,0x20 ; send End Of Interrupt signal
mov dx,0x20
out dx,al
 
mov [0xffff], byte 0
 
restore_ring3_context
iret
 
.change_task:
call update_counters
 
call find_next_task
mov ecx, eax
 
mov al,0x20 ; send End Of Interrupt signal
mov dx,0x20
out dx,al
 
test ecx, ecx ; if there is only one running process
jnz .return
 
call do_change_task
.return:
restore_ring3_context
iret
 
 
align 4
change_task:
 
pushfd
cli
pushad
 
call update_counters
; \begin{Mario79}
cmp [dma_task_switched], 1
jne .find_next_task
mov [dma_task_switched], 0
mov ebx, [dma_process]
cmp [0x3000], ebx
je .return
mov edi, [dma_slot_ptr]
mov [0x3000], ebx
mov [0x3010], edi
jmp @f
.find_next_task:
; \end{Mario79}
call find_next_task
test eax, eax ; the same task -> skip switch
jnz .return
@@:
mov [0xffff],byte 1
call do_change_task
 
.return:
popad
popfd
 
ret
 
 
uglobal
align 4
far_jump:
.offs dd ?
.sel dw ?
context_counter dd ? ;noname & halyavin
next_usage_update dd ?
timer_ticks dd ?
prev_slot dd ?
event_sched dd ?
endg
 
 
update_counters:
mov edi, [0x3010]
mov ebx, [edi+TASKDATA.counter_add] ; time stamp counter add
call _rdtsc
sub eax, ebx
add eax, [edi+TASKDATA.counter_sum] ; counter sum
mov [edi+TASKDATA.counter_sum], eax
ret
 
 
; Find next task to execute
; result: ebx = number of the selected task
; eax = 1 if the task is the same
; edi = address of the data for the task in ebx
; [0x3000] = ebx and [0x3010] = edi
; corrupts other regs
find_next_task:
mov ebx, [0x3000]
mov edi, [0x3010]
mov [prev_slot], ebx
 
.waiting_for_termination:
.waiting_for_reuse:
.waiting_for_event:
.suspended:
cmp ebx, [0x3004]
jb @f
mov edi, 0x3000
xor ebx, ebx
@@:
 
add edi,0x20
inc ebx
 
mov al, byte [edi+TASKDATA.state]
test al, al
jz .found
cmp al, 1
jz .suspended
cmp al, 2
jz .suspended
cmp al, 3
je .waiting_for_termination
cmp al, 4
je .waiting_for_termination
cmp al, 9
je .waiting_for_reuse
 
mov [0x3000],ebx
mov [0x3010],edi
 
cmp al, 5
jne .noevents
call get_event_for_app
test eax, eax
jz .waiting_for_event
mov [event_sched], eax
mov [edi+TASKDATA.state], byte 0
.noevents:
.found:
mov [0x3000],ebx
mov [0x3010],edi
call _rdtsc
mov [edi+TASKDATA.counter_add],eax
 
xor eax, eax
cmp ebx, [prev_slot]
sete al
ret
 
; in: ebx = TSS selector index
do_change_task:
shl ebx, 3
xor eax, eax
add ebx, tss0
mov [far_jump.sel], bx ; selector
mov [far_jump.offs], eax ; offset
jmp pword [far_jump]
inc [context_counter] ;noname & halyavin
ret
 
 
 
align 4
updatecputimes:
 
mov eax,[idleuse]
mov [idleusesec],eax
mov [idleuse],dword 0
mov ecx, [0x3004]
mov edi, 0x3020
.newupdate:
mov ebx,[edi+TASKDATA.counter_sum]
mov [edi+TASKDATA.cpu_usage],ebx
mov [edi+TASKDATA.counter_sum],dword 0
add edi,0x20
dec ecx
jnz .newupdate
 
ret
/kernel/tags/kolibri0.6.3.0/core/except.inc
0,0 → 1,117
 
 
reg_eip equ ebp+4
reg_cs equ ebp+8
reg_eflags equ ebp+12
reg_esp equ ebp+16
reg_ss equ ebp+20
;fpu_ctrl equ ebp-28
 
align 4
except_16:
push ebp
mov ebp, esp
; sub esp, 28
 
push eax
push ebx
push ecx
push edx
 
mov ebx, [ss:CURRENT_TASK]
shl ebx, 8
 
mov eax, [ss:ebx+PROC_BASE+APPDATA.fpu_handler]
test eax, eax
jz .default
 
mov ecx, [reg_eip]
mov edx, [reg_esp]
sub edx, 4
mov [ss:edx+new_app_base], ecx
mov [reg_esp], edx
mov dword [reg_eip], eax
 
pop edx
pop ecx
pop ebx
pop eax
 
leave
iretd
 
.default:
pop edx
pop ecx
pop ebx
pop eax
leave
 
save_ring3_context ;debugger support
 
mov bl, 16
jmp exc_c
 
; fnstenv [fpu_ctrl]
; fnclex
; or word [fpu_ctrl], 0111111b
; fldenv [fpu_ctrl]
 
; pop edx
; pop ecx
; pop ebx
; pop eax
 
; leave
; iretd
 
align 16
except_19:
push ebp
mov ebp, esp
 
push eax
push ebx
push ecx
push edx
 
mov ebx, [ss:CURRENT_TASK]
shl ebx, 8
 
mov eax, [ss:ebx+PROC_BASE+APPDATA.sse_handler]
test eax, eax
jz .default
 
mov ecx, [reg_eip]
mov edx, [reg_esp]
sub edx, 4
mov [ss:edx+new_app_base], ecx
mov [reg_esp], edx
mov dword [reg_eip], eax
 
pop edx
pop ecx
pop ebx
pop eax
 
leave
iretd
 
.default:
pop edx
pop ecx
pop ebx
pop eax
leave
 
save_ring3_context ;debugger support
 
mov bl, 19
jmp exc_c
 
restore reg_eip
restore reg_cs
restore reg_eflags
restore reg_esp
restore reg_ss
;restore fpu_ctrl
/kernel/tags/kolibri0.6.3.0/core/newproce.inc
0,0 → 1,1076
if ~defined newprocess_inc
newprocess_inc_fix:
newprocess_inc fix newprocess_inc_fix
include "mem.inc"
include "memmanag.inc"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Working with new types of processes.
;;Author: Khalyavin Andrey halyavin@land.ru
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
iglobal
new_process_loading db 'K : New Process - loading',13,10,0
new_process_running db 'K : New Process - done',13,10,0
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
endg
;-----------------------------------------------------------------------------
find_new_process_place:
;input:
; none
;result:
; eax=[new_process_place]<>0 - ok
; 0 - failed.
;This function find least empty slot.
;It doesn't increase [0x3004]!
mov eax,0x3000+second_base_address
push ebx
mov ebx,[0x3004]
inc ebx
shl ebx,5
add ebx,eax ;ebx - address of process information for (last+1) slot
.newprocessplace:
;eax = address of process information for current slot
cmp eax,ebx
jz .endnewprocessplace ;empty slot after high boundary
add eax,0x20
cmp word [eax+TASKDATA.state],9 ;check process state, 9 means that process slot is empty
jnz .newprocessplace
.endnewprocessplace:
mov ebx,eax
sub eax,0x3000+second_base_address
shr eax,5 ;calculate slot index
cmp eax,256
jge .failed ;it should be <256
mov word [ebx+TASKDATA.state],9 ;set process state to 9 (for slot after hight boundary)
mov [new_process_place],eax ;save process slot
pop ebx
ret
.failed:
xor eax,eax
pop ebx
ret
;-----------------------------------------------------------------------------
safe_sti:
cmp byte [0xe000], 1
jne @f
sti
@@:ret
;-----------------------------------------------------------------------------
new_sys_threads:
;eax=1 - create thread
; ebx=thread start
; ecx=thread stack value
;result:
; eax=pid
xor edx,edx ; flags=0
pushad
cmp eax,1
jnz .ret ;other subfunctions
mov esi,new_process_loading
call sys_msg_board_str
;lock application_table_status mutex
.table_status:
cli
cmp [application_table_status],0
je .stf
sti
call change_task
jmp .table_status
.stf:
call set_application_table_status
;find free process slot
 
call find_new_process_place
test eax,eax
jz .failed
;set parameters for thread
xor eax,eax
mov [app_i_param],eax
mov [app_i_icon],eax
mov [app_start],ebx
mov [app_esp],ecx
 
mov esi,[0x3000]
shl esi,8
add esi,0x80000+APPDATA.app_name
mov ebx,esi ;ebx=esi - pointer to extended information about current thread
mov edi,[new_process_place]
shl edi,8
add edi,0x80000
lea edx, [edi+APPDATA.app_name] ;edx=edi - pointer to extended infomation about new thread
mov ecx,256/4
rep stosd ;clean extended information about new thread
mov edi,edx
mov ecx,11
rep movsb ;copy process name
mov eax,[ebx+APPDATA.mem_size]
mov [app_mem],eax ;set memory size
mov eax,[ebx+APPDATA.dir_table]
mov dword [edx-APPDATA.app_name+APPDATA.dir_table],eax ;copy page directory
; mov eax,[new_process_place]
; mov ebx,[0x3000]
; call addreference_app_cr3_table
 
push 0 ;no parameters
call fs_execute.add_app_parameters ;start thread
mov [esp+28],eax
popad
ret
.failed:
sti
popad
mov eax,-1
ret
.ret:
popad
ret
;-----------------------------------------------------------------------------
new_mem_resize:
;input:
; ebx - new size
;result:
; [esp+36]:=0 - normal
; [esp+36]:=1 - error
;This function set new application memory size.
mov esi,ebx ;save new size
add ebx,4095
and ebx,not (4096-1) ;round up size
mov ecx,[0x3000]
shl ecx,8
mov edx,[0x80000 + APPDATA.mem_size +ecx]
add edx,4095
and edx,not (4096-1) ;old size
mov eax,[0x80000 + APPDATA.dir_table+ecx]
call MEM_Get_Linear_Address
;eax - linear address of page directory
call MEM_Heap_Lock ;guarantee that two threads willn't
;change memory size simultaneously
cmp ebx,edx
; mov esi,ebx ;save new size
jg .expand
.free:
sub edx,ebx
jz .unlock ;do nothing
mov ecx,edx
shr ecx,12
add ebx,std_application_base_address
call mem_free_specified_region ;free unnecessary pages
jmp .unlock
 
.expand:
sub ebx,edx
mov ecx,ebx
shr ecx,12
mov ebx,edx
add ebx,std_application_base_address
call mem_alloc_specified_region ;alloc necessary pages
test eax,eax
jz .failed ;not enough memory
.unlock:
mov ebx,esi
mov eax,[0x3000]
shl eax,8
mov [eax+0x80000 + APPDATA.mem_size],ebx ;write new memory size
;search threads and update
;application memory size infomation
mov ecx,[eax+0x80000 + APPDATA.dir_table]
mov eax,2
.search_threads:
;eax = current slot
;ebx = new memory size
;ecx = page directory
cmp eax,[0x3004]
jg .search_threads_end
mov edx,eax
shl edx,5
cmp word [0x3000+edx+TASKDATA.state],9 ;if slot empty?
jz .search_threads_next
shl edx,3
cmp [edx+0x80000+APPDATA.dir_table],ecx ;if it is our thread?
jnz .search_threads_next
mov [edx+0x80000+APPDATA.mem_size],ebx ;update memory size
.search_threads_next:
inc eax
jmp .search_threads
.search_threads_end:
 
call MEM_Heap_UnLock
mov dword [esp+36],0
ret
.failed:
call MEM_Heap_UnLock
mov dword [esp+36],1
ret
;-----------------------------------------------------------------------------
pid_to_slot:
;Input:
; eax - pid of process
;Output:
; eax - slot of process or 0 if process don't exists
;Search process by PID.
push ebx
push ecx
mov ebx,[0x3004]
shl ebx,5
mov ecx,2*32
.loop:
;ecx=offset of current process info entry
;ebx=maximum permitted offset
cmp byte [second_base_address+0x3000+ecx+TASKDATA.state],9
jz .endloop ;skip empty slots
cmp [second_base_address+0x3000+ecx+TASKDATA.pid],eax ;check PID
jz .pid_found
.endloop:
add ecx,32
cmp ecx,ebx
jle .loop
pop ecx
pop ebx
xor eax,eax
ret
.pid_found:
shr ecx,5
mov eax,ecx ;convert offset to index of slot
pop ecx
pop ebx
ret
;-----------------------------------------------------------------------------
is_new_process:
;Input:
; eax - process slot
;Output:
; eax=1 - it is new process
; eax=0 - it is old process
; shl eax,5
; mov eax,[second_base_address+0x3000+eax+0x10]
; cmp eax,std_application_base_address ;check base address of application
; jz .new_process
; xor eax,eax
; ret
;.new_process:
mov eax,1
ret
;-----------------------------------------------------------------------------
write_process_memory:
;Input:
; eax - process slot
; ebx - buffer address
; ecx - buffer size
; edx - start address in other process
;Output:
; eax - number of bytes written
pushad
shl eax,8
mov eax,[0x80000+eax+APPDATA.dir_table]
call MEM_Get_Linear_Address
mov ebp,eax
;ebp=linear address of page directory of other process.
add edx,std_application_base_address ;convert to linear address
test ecx,ecx
jle .ret
.write_loop:
;ebx = current buffer address
;ecx>0 = current size
;edx = current address in other process
;ebp = linear address of page directory
 
call MEM_Heap_Lock ;cli
mov esi,edx
shr esi,22
mov eax,[ebp+4*esi] ;find page directory entry
and eax,not (4096-1) ;clear flags
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address ;calculate linear address of page table
test eax,eax
jz .page_not_found
mov esi,edx
shr esi,12
and esi,1023
mov eax,[eax+4*esi] ;find page table entry
and eax,not (4096-1)
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address ;calculate linear address of page
test eax,eax
jz .page_not_found
mov edi,eax
call MEM_Add_Reference_Linear;guarantee that page willn't disappear
call MEM_Heap_UnLock ;sti
mov esi,edx
and esi,4095
add edi,esi ;add offset in page
;edi = linear address corresponding edx in other process
sub esi,4096
neg esi ;esi - number of remaining bytes in page
cmp esi,ecx
jl .min_ecx
mov esi,ecx
.min_ecx: ;esi=min(ecx,esi) - number of bytes to write
sub ecx,esi
push ecx
mov ecx,esi ;ecx - number of bytes to write
mov esi,ebx ;esi - source, edi - destination
add edx,ecx ;move pointer in address space of other process
push edi
;move ecx bytes
test ecx,3
jnz .not_aligned
shr ecx,2
rep movsd
jmp .next_iter
.not_aligned:
rep movsb
.next_iter:
 
pop eax
and eax,not (4096-1) ;eax - linear address of current page
call MEM_Free_Page_Linear ;free reference
mov ebx,esi ;new pointer to buffer - movsb automaticaly advance it.
pop ecx ;restore number of remaining bytes
test ecx,ecx
jnz .write_loop
.ret:
popad
mov eax,ecx
ret
.page_not_found:
call MEM_Heap_UnLock ;error has appeared in critical region
sub ecx,[esp+24] ;[esp+24]<-->ecx
neg ecx ;ecx=number_of_written_bytes
mov [esp+28],ecx ;[esp+28]<-->eax
popad
ret
;-----------------------------------------------------------------------------
syscall_test:
;for testing memory manager from applications.
mov edx,ecx
mov ecx,ebx
call trans_address
mov ebx,eax
mov eax,[0x3000]
call read_process_memory
ret
;-----------------------------------------------------------------------------
read_process_memory:
;Input:
; eax - process slot
; ebx - buffer address
; ecx - buffer size
; edx - start address in other process
;Output:
; eax - number of bytes read.
pushad
shl eax,8
mov eax,[0x80000+eax+APPDATA.dir_table]
call MEM_Get_Linear_Address
mov ebp,eax
add edx,std_application_base_address
.read_loop:
;ebx = current buffer address
;ecx>0 = current size
;edx = current address in other process
;ebp = linear address of page directory
 
call MEM_Heap_Lock ;cli
mov esi,edx
shr esi,22
mov eax,[ebp+4*esi] ;find page directory entry
and eax,not (4096-1)
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address
test eax,eax
jz .page_not_found
mov esi,edx
shr esi,12
and esi,1023
mov eax,[eax+4*esi] ;find page table entry
and eax,not (4096-1)
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address ;calculate linear address of page
test eax,eax
jz .page_not_found
mov esi,eax
call MEM_Add_Reference_Linear;guarantee that page willn't disappear
call MEM_Heap_UnLock ;sti
mov edi,edx
and edi,4095
add esi,edi ;add offset in page
;esi = linear address corresponding edx in other process
sub edi,4096
neg edi
;edi=min(edi,ecx) - number of bytes to copy
cmp edi,ecx
jl .min_ecx
mov edi,ecx
.min_ecx:
 
sub ecx,edi ;update size of remaining bytes
add edx,edi ;update current pointer in other address space.
push ecx
mov ecx,edi ;ecx - number of bytes to read
mov edi,ebx ;esi - source, edi - destination
push esi
;move ecx bytes
test ecx,3
jnz .not_aligned
shr ecx,2
rep movsd
jmp .next_iter
.not_aligned:
rep movsb
.next_iter:
pop eax
and eax,not (4096-1) ;eax - linear address of current page
call MEM_Free_Page_Linear ;free reference
mov ebx,edi ;new pointer to buffer - movsb automaticaly advance it.
pop ecx ;restore number of remaining bytes
test ecx,ecx
jnz .read_loop
popad
mov eax,ecx
ret
.page_not_found:
call MEM_Heap_UnLock ;error has appeared in critical region
sub ecx,[esp+24] ;[esp+24]<-->ecx
neg ecx ;ecx=number_of_read_bytes
mov [esp+28],ecx ;[esp+28]<-->eax
popad
ret
;-----------------------------------------------------------------------------
check_region:
;input:
; ebx - start of buffer
; ecx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
mov eax,[0x3000]
jmp check_process_region
;-----------------------------------------------------------------------------
check_process_region:
;input:
; eax - slot
; ebx - start of buffer
; ecx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
test ecx,ecx
jle .ok
shl eax,5
cmp word [0x3000+eax+TASKDATA.state],0
jnz .failed
shl eax,3
mov eax,[0x80000+eax+APPDATA.dir_table]
test eax,eax
jz .failed
call MEM_Get_Linear_Address
push ebx
push ecx
push edx
mov edx,ebx
and edx,not (4096-1)
sub ebx,edx
add ecx,ebx
mov ebx,edx
add ecx,(4096-1)
and ecx,not (4096-1)
.loop:
;eax - linear address of page directory
;ebx - current page
;ecx - current size
mov edx,ebx
shr edx,22
mov edx,[eax+4*edx]
and edx,not (4096-1)
test edx,edx
jz .failed1
push eax
mov eax,edx
call MEM_Get_Linear_Address
mov edx,ebx
shr edx,12
and edx,(1024-1)
mov eax,[eax+4*edx]
and eax,not (4096-1)
test eax,eax
pop eax
jz .failed1
add ebx,4096
sub ecx,4096
jg .loop
pop edx
pop ecx
pop ebx
.ok:
mov eax,1
ret
.failed1:
pop edx
pop ecx
pop ebx
.failed:
xor eax,eax
ret
;-----------------------------------------------------------------------------
new_sys_ipc:
;input:
; eax=1 - set ipc buffer area
; ebx=address of buffer
; ecx=size of buffer
; eax=2 - send message
; ebx=PID
; ecx=address of message
; edx=size of message
cmp eax,1
jnz .no_ipc_def
;set ipc buffer area
mov edi,[0x3000]
shl edi,8
add edi,0x80000
cli
mov [edi+APPDATA.ipc_start],ebx ;set fields in extended information area
mov [edi+APPDATA.ipc_size],ecx
sti
mov [esp+36],dword 0 ;success
ret
.no_ipc_def:
cmp eax,2
jnz .no_ipc_send
;send message
cli
;obtain slot from PID
mov eax,ebx
call pid_to_slot
test eax,eax
jz .no_pid
mov ebp,eax
;ebp = slot of other process
shl eax,8
mov edi,[eax+0x80000+APPDATA.ipc_start] ;is ipc area defined?
test edi,edi
jz .no_ipc_area
mov esi,[eax+0x80000+APPDATA.ipc_size] ;esi - size of buffer
push dword -1 ;temp variable for read_process_memory
mov ebx,esp
push ecx
push edx
mov ecx,4 ;read 4 bytes
mov eax,ebp
mov edx,edi ;from beginning of buffer.
call read_process_memory
mov eax,[esp+8]
test eax,eax
jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now
add edx,4 ;move to next 4 bytes
mov eax,ebp
call read_process_memory ;read size of occupied space in buffer
sub esi,8
sub esi,[esp]
sub esi,[esp+8] ;esi=(buffer size)-(occupied size)-(message size)-(header of message size)
js .buffer_overflow ;esi<0 - not enough memory in buffer
mov esi,[esp+8] ;previous offset
add dword [esp+8],8
mov edi,[esp]
add [esp+8],edi ;add (size of message)+(size of header of message) to [buffer+4]
mov eax,ebp
call write_process_memory
add edx,esi
sub edx,4 ;move to beginning of place for our message
mov eax,[second_base_address+0x3010]
mov eax,[eax+TASKDATA.pid] ;eax - our PID
mov [esp+8],eax
mov eax,ebp
call write_process_memory ;write PID
mov ebx,esp ;address of size of message
mov eax,ebp
add edx,4
call write_process_memory ;write size of message
add edx,4
pop ecx ;ecx - size of message
pop eax
call trans_address
mov ebx,eax ;ebx - linear address of message
add esp,4 ;pop temporary variable
mov eax,ebp
call write_process_memory ;write message
sti
;awake other process
shl ebp,8
mov eax,ebp
or [eax+0x80000+APPDATA.event_mask],dword 0x40
cmp dword [check_idle_semaphore],20
jge .ipc_no_cis
mov dword [check_idle_semaphore],5
.ipc_no_cis:
mov dword [esp+36],0
ret
.no_ipc_send:
mov dword [esp+36],-1
ret
.no_pid:
sti
mov dword [esp+36],4
ret
.no_ipc_area:
sti
mov dword [esp+36],1
ret
.ipc_blocked:
sti
add esp,12
mov dword [esp+36],2
ret
.buffer_overflow:
sti
add esp,12
mov dword [esp+36],3
ret
;-----------------------------------------------------------------------------
trans_address:
;Input
; eax - application address
;Output
; eax - linear address for kernel
add eax,std_application_base_address
ret
;-----------------------------------------------------------------------------
 
; \begin{diamond}
include 'debug.inc'
 
fs_execute:
; ebx - cmdline
; edx - flags
; ebp - full filename
; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it
pushad
; check filename length - with terminating NULL must be no more than 1024 symbols
mov edi, ebp
mov ecx, 1024
xor eax, eax
repnz scasb
jz @f
popad
mov eax, -ERROR_FILE_NOT_FOUND
ret
@@:
 
mov esi, new_process_loading
call sys_msg_board_str ; write message to message board
 
; lock application_table_status mutex
.table_status:
cli
cmp [application_table_status], 0
jz .stf
sti
call change_task
jmp .table_status
.stf:
call set_application_table_status
push ebx ; save command line pointer for add_app_parameters
 
call find_new_process_place ; find new process slot
call safe_sti
test eax, eax
mov ecx, -0x20 ; too many processes
jz .failed
 
; write application name
push edi
mov ecx, edi
sub ecx, ebp
mov [appl_path], ebp
mov [appl_path_size], ecx
dec edi
std
mov al, '/'
repnz scasb
cld
jnz @f
inc edi
@@:
inc edi
; now edi points to name without path
mov esi, edi
mov ecx, 8 ; 8 chars for name
mov edi, [new_process_place]
shl edi, cl
add edi, 0x80000+APPDATA.app_name
.copy_process_name_loop:
lodsb
cmp al, '.'
jz .copy_process_name_done
test al, al
jz .copy_process_name_done
stosb
loop .copy_process_name_loop
.copy_process_name_done:
mov al, ' '
rep stosb
pop eax
mov cl, 3 ; 3 chars for extension
dec esi
@@:
dec eax
cmp eax, esi
jbe .copy_process_ext_done
cmp byte [eax], '.'
jnz @b
lea esi, [eax+1]
.copy_process_ext_loop:
lodsb
test al, al
jz .copy_process_ext_done
stosb
loop .copy_process_ext_loop
.copy_process_ext_done:
mov al, ' '
rep stosb
 
; read header
lea eax, [esp+8+36]
mov edi, 0x90000
call dword [eax-4]
mov ecx, eax
neg ecx
jnz .cleanfailed
; check menuet signature
mov ecx, -0x1F
cmp dword [0x90000], 'MENU'
jnz .cleanfailed
cmp word [0x90004], 'ET'
jnz .cleanfailed
call get_app_params
mov ecx, -0x1F
jc .cleanfailed
; sanity check - because we will load all file,
; file size must be not greater than memory size
mov eax, [esp+8+36]
cmp [app_mem], eax
jb .cleanfailed
 
mov eax, [new_process_place]
inc ecx ; -0x1E = no memory
call create_app_cr3_table
test eax, eax
jz .cleanfailed_mem
 
call MEM_Get_Linear_Address
 
mov ebx, std_application_base_address
mov ecx, [app_mem]
add ecx, 4095
shr ecx, 12
mov edx, eax ; edx - linear address of page directory
call mem_alloc_specified_region
mov ecx, -0x1E ; no memory
test eax, eax
jz .cleanfailed_mem1
 
add edx, std_application_base_address shr 20
mov eax, [edx]
and eax, not 4095
call MEM_Get_Linear_Address
push edx ; save pointer to first page table
mov edx, eax
; read file
; first block is already read to 0x90000
mov eax, [edx]
and eax, not 0xFFF
call MEM_Get_Linear_Address
mov esi, 0x90000
mov edi, eax
mov ecx, 512/4
rep movsd
sub edi, eax
.loop1:
; [esp] = pointer to current page directory entry
; edx = pointer to current page table
; edi = offset in page
mov eax, [edx]
and eax, not 0xFFF
call MEM_Get_Linear_Address
push edi
add edi, eax
lea eax, [esp+8+36+8]
call dword [eax-4]
pop edi
test eax, eax
jnz .endloop1
add edi, 512 ; new offset
cmp edi, 4096
jb .loop1
xor edi, edi
add edx, 4 ; go to next page
test edx, 4096-1
jnz .loop1
pop eax
add eax, 4 ; go to next directory entry
push eax
mov eax, [eax]
and eax, not 0xFFF
call MEM_Get_Linear_Address
mov edx, eax
jmp .loop1
.endloop1:
pop edx
cmp eax, 6
jnz .cleanfailed_mem2
call .add_app_parameters
mov [esp+28], eax
popad
ret
 
.cleanfailed_mem2:
; file read error; free all allocated mem
mov ecx, eax
neg ecx
mov eax, [new_process_place]
call dispose_app_cr3_table
jmp .cleanfailed
.cleanfailed_mem1:
; there is mem for directory entry, but there is no mem for pages
; so free directory entry
mov eax, [new_process_place]
shl eax, 8
mov eax, [0x80000+eax+0xB8]
call MEM_Free_Page
.cleanfailed_mem:
; there is no mem for directory entry, display message
mov esi, start_not_enough_memory
call sys_msg_board_str
.cleanfailed:
push ecx
; clean process name, this avoid problems with @panel
mov edi, [new_process_place]
shl edi, 8
add edi, 0x80000+APPDATA.app_name
mov ecx, 11
mov al, ' '
rep stosb
pop eax
.failed:
pop ebx
mov [esp+28], eax
popad
mov [application_table_status], 0
call safe_sti
ret
; \end{diamond}
.add_app_parameters:
;input:
; [esp] - pointer to parameters
; [esp+4]-[esp+36] pushad registers.
;result
; eax - pid of new process
; or zero if failed
cli
mov ebx,[new_process_place]
cmp ebx,[0x3004]
jle .noinc
inc dword [0x3004] ;update number of processes
.noinc:
 
; mov ebx,[new_process_place]
;set 0x8c field of extended information about process
;(size of application memory)
shl ebx,8
mov eax,[app_mem]
mov [second_base_address+0x80000+APPDATA.mem_size+ebx],eax
;set 0x10 field of information about process
;(application base address)
; mov ebx,[new_process_place]
; shl ebx,5
shr ebx,3
mov dword [second_base_address+0x3000+ebx+TASKDATA.mem_start],std_application_base_address
 
;add command line parameters
.add_command_line:
mov edx,[app_i_param]
test edx,edx
jz .no_command_line ;application don't need parameters
mov eax,[esp+4]
test eax,eax
jz .no_command_line ;no parameters specified
;calculate parameter length
mov esi,eax
xor ecx,ecx
inc ecx ; include terminating null
.command_line_len:
cmp byte [esi],0
jz .command_line_len_end
inc esi
inc ecx
cmp ecx,256
jl .command_line_len
.command_line_len_end:
;ecx - parameter length
;edx - address of parameters in new process address space
mov ebx,eax ;ebx - address of parameters in our address space
mov eax,[new_process_place]
call write_process_memory ;copy parameters to new process address space
.no_command_line:
;******************************************************************
mov edx,[app_i_icon]
test edx,edx
jz .no_command_line_1 ;application don't need path of file
mov ebx,[appl_path]
mov ecx,[appl_path_size]
mov eax,[new_process_place]
call write_process_memory ;copy path of file to new process address space
.no_command_line_1:
;******************************************************************
mov ebx,[new_process_place]
mov eax,ebx
shl ebx,5
mov [ebx+window_data+WDATA.fl_wstate],WSTATE_NORMAL
mov [ebx+window_data+WDATA.fl_redraw],1
add ebx,0x3000 ;ebx - pointer to information about process
mov [ebx+TASKDATA.wnd_number],al ;set window number on screen = process slot
mov [ebx+TASKDATA.event_mask],dword 1+2+4 ;set default event flags (see 40 function)
inc dword [process_number]
mov eax,[process_number]
mov [ebx+TASKDATA.pid],eax ;set PID
mov ecx,ebx
add ecx,draw_data-0x3000 ;ecx - pointer to draw data
;set draw data to full screen
mov [ecx+RECT.left],dword 0
mov [ecx+RECT.top],dword 0
mov eax,[0xfe00]
mov [ecx+RECT.right],eax
mov eax,[0xfe04]
mov [ecx+RECT.bottom],eax
;set cr3 register in TSS of application
mov ecx,[new_process_place]
shl ecx,8
mov eax,[0x80000+APPDATA.dir_table+ecx]
add eax,8+16 ;add flags
mov [l.cr3],eax
mov eax,[app_start]
mov [l.eip],eax ;set eip in TSS
mov eax,[app_esp]
mov [l.esp],eax ;set stack in TSS
;gdt
;mov ebx,[new_process_place]
;shl ebx,3
mov ax,app_code ;ax - selector of code segment
;add ax,bx
mov [l.cs],ax
mov ax,app_data
;add ax,bx ;ax - selector of data segment
mov [l.ss],ax
mov [l.ds],ax
mov [l.es],ax
mov [l.fs],ax
mov ax,graph_data ;ax - selector of graphic segment
mov [l.gs],ax
mov [l.io],word 128
mov [l.eflags],dword 0x11202
mov [l.ss0],os_data
mov ebx,[new_process_place]
shl ebx,12
add ebx,sysint_stack_data+4096
mov [l.esp0],ebx
 
;copy tss to it place
mov eax,tss_sceleton
mov ebx,[new_process_place]
imul ebx,tss_step
add ebx,tss_data ;ebx - address of application TSS
mov ecx,120
call memmove
;Add IO access table - bit array of permitted ports
or eax,-1
mov edi,[new_process_place]
imul edi,tss_step
add edi,tss_data+128
mov ecx,2048
cld
rep stosd ;full access to 2048*8=16384 ports
mov ecx,ebx ;ecx - address of application TSS
mov edi,[new_process_place]
shl edi,3
;set TSS descriptor
mov [edi+gdts+tss0+0],word tss_step ;limit (size)
mov [edi+gdts+tss0+2],cx ;part of offset
mov eax,ecx
shr eax,16
mov [edi+gdts+tss0+4],al ;part of offset
mov [edi+gdts+tss0+7],ah ;part of offset
mov [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags
 
;flush keyboard and buttons queue
mov [0xf400],byte 0
mov [0xf500],byte 0
 
mov edi,[new_process_place]
shl edi,5
add edi,window_data
mov ebx,[new_process_place]
movzx esi,word [0xC000+ebx*2]
lea esi,[0xC400+esi*2]
call windowactivate ;gui initialization
 
mov ebx,[new_process_place]
shl ebx,5
; set if debuggee
test byte [esp+28], 1
jz .no_debug
mov [0x3000+ebx+TASKDATA.state], 1 ; set process state - suspended
mov eax, [0x3000]
mov [0x80000+ebx*8+APPDATA.debugger_slot], eax ;set debugger PID - current
jmp .debug
.no_debug:
mov [0x3000+ebx+TASKDATA.state], 0 ; set process state - running
.debug:
mov esi,new_process_running
call sys_msg_board_str ;output information about succefull startup
; add esp,4 ;pop pointer to parameters
; popad
mov eax,[process_number] ;set result
mov [application_table_status],0 ;unlock application_table_status mutex
call safe_sti
ret 4
 
end if
/kernel/tags/kolibri0.6.3.0/core/debug.inc
0,0 → 1,499
; diamond, 2006
sys_debug_services:
cmp eax, 9
ja @f
jmp dword [sys_debug_services_table+eax*4]
@@: ret
sys_debug_services_table:
dd debug_set_event_data
dd debug_getcontext
dd debug_setcontext
dd debug_detach
dd debug_suspend
dd debug_resume
dd debug_read_process_memory
dd debug_write_process_memory
dd debug_terminate
dd debug_set_drx
 
debug_set_event_data:
; in: ebx = pointer
; destroys eax
mov eax, [0x3000]
shl eax, 8
mov [eax+0x80000+APPDATA.dbg_event_mem], ebx
ret
 
get_debuggee_slot:
; in: ebx=PID
; out: CF=1 if error
; CF=0 and eax=slot*0x20 if ok
; out: interrupts disabled
cli
mov eax, ebx
call pid_to_slot
test eax, eax
jz .ret_bad
shl eax, 5
push ebx
mov ebx, [0x3000]
cmp [0x80000+eax*8+APPDATA.debugger_slot], ebx
pop ebx
jnz .ret_bad
; clc ; automatically
ret
.ret_bad:
stc
ret
 
debug_detach:
; in: ebx=pid
; destroys eax,ebx
call get_debuggee_slot
jc .ret
and dword [eax*8+0x80000+APPDATA.debugger_slot], 0
call do_resume
.ret:
sti
ret
 
debug_terminate:
; in: ebx=pid
call get_debuggee_slot
jc debug_detach.ret
mov ebx, eax
shr ebx, 5
push 2
pop eax
jmp sys_system
 
debug_suspend:
; in: ebx=pid
; destroys eax,ebx
call get_debuggee_slot
jc .ret
mov bl, [0x3000+eax+TASKDATA.state] ; process state
test bl, bl
jz .1
cmp bl, 5
jnz .ret
mov bl, 2
.2: mov [0x3000+eax+TASKDATA.state], bl
.ret:
sti
ret
.1:
inc ebx
jmp .2
 
do_resume:
mov bl, [0x3000+eax+TASKDATA.state]
cmp bl, 1
jz .1
cmp bl, 2
jnz .ret
mov bl, 5
.2: mov [0x3000+eax+TASKDATA.state], bl
.ret: ret
.1: dec ebx
jmp .2
 
debug_resume:
; in: ebx=pid
; destroys eax,ebx
call get_debuggee_slot
jc .ret
call do_resume
.ret: sti
ret
 
debug_getcontext:
; in:
; ebx=pid
; ecx=sizeof(CONTEXT)
; edx->CONTEXT
; destroys eax,ecx,edx,esi,edi
cmp ecx, 28h
jnz .ret
add edx, std_application_base_address
push ebx
mov ebx, edx
call check_region
pop ebx
dec eax
jnz .ret
call get_debuggee_slot
jc .ret
imul eax, tss_step/32
add eax, tss_data
mov edi, edx
cmp [l.cs - tss_sceleton + eax], app_code
jnz .ring0
lea esi, [l.eip - tss_sceleton + eax]
shr ecx, 2
rep movsd
jmp .ret
.ring0:
; note that following code assumes that all interrupt/exception handlers
; saves ring-3 context by push ds es, pushad in this order
mov esi, [l.esp0 - tss_sceleton + eax]
; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), ds, es, pushad
sub esi, 8+12+8+20h
lodsd
mov [edi+24h], eax
lodsd
mov [edi+20h], eax
lodsd
mov [edi+1Ch], eax
lodsd
lodsd
mov [edi+14h], eax
lodsd
mov [edi+10h], eax
lodsd
mov [edi+0Ch], eax
lodsd
mov [edi+8], eax
add esi, 8
lodsd
mov [edi], eax
lodsd
lodsd
mov [edi+4], eax
lodsd
mov [edi+18h], eax
.ret:
sti
ret
 
debug_setcontext:
; in:
; ebx=pid
; ecx=sizeof(CONTEXT)
; edx->CONTEXT
; destroys eax,ecx,edx,esi,edi
cmp ecx, 28h
jnz .ret
add edx, std_application_base_address
push ebx
mov ebx, edx
call check_region
pop ebx
dec eax
jnz .ret
call get_debuggee_slot
jc .stiret
imul eax, tss_step/32
add eax, tss_data
mov esi, edx
cmp [l.cs - tss_sceleton + eax], app_code
jnz .ring0
lea edi, [l.eip - tss_sceleton + eax]
shr ecx, 2
rep movsd
jmp .stiret
.ring0:
mov edi, [l.esp0 - tss_sceleton + eax]
sub edi, 8+12+8+20h
mov eax, [esi+24h]
stosd
mov eax, [esi+20h]
stosd
mov eax, [esi+1Ch]
stosd
scasd
mov eax, [esi+14h]
stosd
mov eax, [esi+10h]
stosd
mov eax, [esi+0Ch]
stosd
mov eax, [esi+8]
stosd
add edi, 8
mov eax, [esi]
stosd
scasd
mov eax, [esi+4]
stosd
mov eax, [esi+18h]
stosd
.stiret:
sti
.ret:
ret
 
debug_set_drx:
call get_debuggee_slot
jc .errret
mov ebp, eax
lea eax, [eax*8+0x80000+APPDATA.dbg_regs]
; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3
; [eax+10]=dr7
add edx, std_application_base_address
jc .errret
cmp cl, 3
ja .errret
mov ebx, dr7
shr ebx, cl
shr ebx, cl
test ebx, 2 ; bit 1+2*index = G0..G3, global break enable
jnz .errret2
test ch, ch
jns .new
; clear breakpoint
movzx ecx, cl
add ecx, ecx
and dword [eax+ecx*2], 0 ; clear DR<i>
btr dword [eax+10h], ecx ; clear L<i> bit
test byte [eax+10h], 55h
jnz .okret
imul eax, ebp, tss_step/32
and byte [eax + tss_data + l.trap - tss_sceleton], not 1
.okret:
and dword [esp+36], 0
sti
ret
.errret:
sti
mov dword [esp+36], 1
ret
.errret2:
sti
mov dword [esp+36], 2
ret
.new:
; add new breakpoint
; cl=index; ch=flags; edx=address
test ch, 0xF0
jnz .errret
mov bl, ch
and bl, 3
cmp bl, 2
jz .errret
mov bl, ch
shr bl, 2
cmp bl, 2
jz .errret
test dl, bl
jnz .errret
or byte [eax+10h+1], 3 ; set GE and LE flags
movzx ebx, ch
movzx ecx, cl
add ecx, ecx
bts dword [eax+10h], ecx ; set L<i> flag
add ecx, ecx
mov [eax+ecx], edx ; set DR<i>
shl ebx, cl
mov edx, 0xF
shl edx, cl
not edx
and [eax+10h+2], dx
or [eax+10h+2], bx ; set R/W and LEN fields
imul eax, ebp, tss_step/32
or byte [eax + tss_data + l.trap - tss_sceleton], 1
jmp .okret
 
debug_read_process_memory:
; in:
; ebx=pid
; ecx=length
; esi->buffer in debugger
; edx=address in debuggee
; out: [esp+36]=sizeof(read)
; destroys all
add esi, std_application_base_address
push ebx
mov ebx, esi
call check_region
pop ebx
dec eax
jnz .err
call get_debuggee_slot
jc .err
shr eax, 5
mov ebx, esi
call read_process_memory
sti
mov dword [esp+36], eax
ret
.err:
or dword [esp+36], -1
ret
 
debug_write_process_memory:
; in:
; ebx=pid
; ecx=length
; esi->buffer in debugger
; edx=address in debuggee
; out: [esp+36]=sizeof(write)
; destroys all
add esi, std_application_base_address
push ebx
mov ebx, esi
call check_region
pop ebx
dec eax
jnz debug_read_process_memory.err
call get_debuggee_slot
jc debug_read_process_memory.err
shr eax, 5
mov ebx, esi
call write_process_memory
sti
mov [esp+36], eax
ret
 
debugger_notify:
; in: eax=debugger slot
; ecx=size of debug message
; [esp+4]..[esp+4+ecx]=message
; interrupts must be disabled!
; destroys all general registers
; interrupts remain disabled
xchg ebp, eax
mov edi, [timer_ticks]
add edi, 500 ; 5 sec timeout
.1:
mov eax, ebp
shl eax, 8
mov edx, [0x80000+eax+APPDATA.dbg_event_mem]
test edx, edx
jz .ret
; read buffer header
push ecx
push eax
push eax
mov eax, ebp
mov ebx, esp
mov ecx, 8
call read_process_memory
cmp eax, ecx
jz @f
add esp, 12
jmp .ret
@@:
cmp dword [ebx], 0
jg @f
.2:
pop ecx
pop ecx
pop ecx
cmp dword [0x3000], 1
jnz .notos
cmp [timer_ticks], edi
jae .ret
.notos:
sti
call change_task
cli
jmp .1
@@:
mov ecx, [ebx+8]
add ecx, [ebx+4]
cmp ecx, [ebx]
ja .2
; advance buffer position
push ecx
mov ecx, 4
sub ebx, ecx
mov eax, ebp
add edx, ecx
call write_process_memory
pop eax
; write message
mov eax, ebp
add edx, ecx
add edx, [ebx+8]
add ebx, 20
pop ecx
pop ecx
pop ecx
call write_process_memory
; new debug event
mov eax, ebp
shl eax, 8
or byte [0x80000+eax+APPDATA.event_mask+1], 1 ; set flag 100h
.ret:
ret
 
debug_exc:
; int 1 = #DB
save_ring3_context
cld
mov ax, os_data
mov ds, ax
mov es, ax
mov eax, dr6
test ax, ax
jns @f
; this is exception from task switch
; set DRx registers for task and continue
mov eax, [0x3000]
shl eax, 8
add eax, 0x80000+APPDATA.dbg_regs
mov ecx, [eax+0]
mov dr0, ecx
mov ecx, [eax+4]
mov dr1, ecx
mov ecx, [eax+8]
mov dr2, ecx
mov ecx, [eax+0Ch]
mov dr3, ecx
xor ecx, ecx
mov dr6, ecx
mov ecx, [eax+10h]
mov dr7, ecx
restore_ring3_context
iretd
@@:
push eax
xor eax, eax
mov dr6, eax
; test if debugging
cli
mov eax, [0x3000]
shl eax, 8
mov eax, [0x80000+eax+APPDATA.debugger_slot]
test eax, eax
jnz .debug
sti
; not debuggee => say error and terminate
add esp, 28h+4
mov [error_interrupt], 1
call show_error_parameters
mov edx, [0x3010]
mov byte [edx+TASKDATA.state], 4
jmp change_task
.debug:
; we are debugged process, notify debugger and suspend ourself
; eax=debugger PID
pop edx
mov ebx, dr7
mov cl, not 1
.l1:
test bl, 1
jnz @f
and dl, cl
@@:
shr ebx, 2
add cl, cl
inc ecx
cmp cl, not 10h
jnz .l1
push edx ; DR6 image
mov ecx, [0x3010]
push dword [ecx+TASKDATA.pid] ; PID
push 12
pop ecx
push 3 ; 3 = debug exception
call debugger_notify
pop ecx
pop ecx
pop ecx
mov edx, [0x3010]
mov byte [edx+TASKDATA.state], 1 ; suspended
call change_task
restore_ring3_context
iretd
/kernel/tags/kolibri0.6.3.0/core/mem.inc
0,0 → 1,469
if ~defined mem_inc
mem_inc_fix:
mem_inc fix mem_inc_fix
;include "memmanag.inc"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;High-level memory management in MenuetOS.
;;It uses memory manager in memmanager.inc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
second_base_address=0xC0000000
std_application_base_address=0x10000000
general_page_table_ dd 0
general_page_table=general_page_table_+second_base_address
;-----------------------------------------------------------------------------
create_general_page_table:
;input
; none
;output
; none
;Procedure create general page directory and write
;it address to [general_page_table].
pushad
mov eax,1 ;alloc 1 page
mov ebx,general_page_table ;write address to [general_page_table]
call MEM_Alloc_Pages ;allocate page directory
mov eax,[general_page_table]
call MEM_Get_Linear_Address ;eax - linear address of page directory
mov edi,eax
mov ebx,eax ;copy address of page directory to safe place
xor eax,eax
mov ecx,4096/4
cld
rep stosd ;clear page directory
mov eax,4
mov edx,eax
call MEM_Alloc_Pages ;alloc page tables for 0x0-0x1000000 region
cmp eax,edx
jnz $ ;hang if not enough memory
;fill page tables
xor esi,esi
mov ebp,7
.loop:
;esi - number of page in page directory
;ebp - current page address
;ebx - linear address of page directory
mov eax,[ebx+4*esi]
add dword [ebx+4*esi],7 ;add flags to address of page table
call MEM_Get_Linear_Address
;eax - linear address of page table
mov ecx,4096/4
;ecx (counter) - number of pages in page table
;current address=4Mb*esi
.loop1:
mov [eax],ebp ;write page address (with flags) in page table
add eax,4
add ebp,4096 ;size of page=4096 bytes
loop .loop1
inc esi ;next page directory entry
cmp esi,edx
jnz .loop
;map region 0x80000000-0x807fffff to LFB
mov eax,2 ;size of the region is 4Mb so only 1 page table needed
mov edx,ebx ;ebx still contains linear address of the page directory
add ebx,0x800
call MEM_Alloc_Pages ;alloc page table for the region
mov eax,[ebx]
add dword [ebx],7 ;add flags
call MEM_Get_Linear_Address ;get linear address of the page table
mov ecx,4096/4 ;number of pages in page table
mov edi,[0xfe80]
add edi,7
.loop3:
;eax - linear address of page table
;edi - current linear address with flags
mov [eax],edi
add eax,4
add edi,4096
loop .loop3
mov eax,[ebx+4]
call MEM_Get_Linear_Address
add dword [ebx+4],7
mov ecx,4096/4
.loop31:
mov [eax],edi
add eax,4
add edi,4096
loop .loop31
;map region 0xC0000000-* to 0x0-*
mov esi,edx ;esi=linear address of the page directory
lea edi,[esi+(second_base_address shr 20)];add offset of entry (0xC00)
mov ecx,4
rep movsd ;first 16Mb of the region mapped as 0x0-0x1000000 block
mov eax,[0xfe8c] ;eax=memory size
add eax,0x3fffff
shr eax,22
mov esi,eax ;calculate number of entries in page directory
sub esi,4 ;subtract entries for first 16Mb.
mov ebp,0x1000000+7 ;start physical address with flags
;mapping memory higher than 16Mb
.loop4:
;esi (counter) - number of entries in page directory
;edi - address of entry
test esi,esi
jle .loop4end
call MEM_Alloc_Page ;alloc page table for entry in page directory
mov [edi],eax
add dword [edi],7 ;write physical address of page table in page directory
add edi,4 ;move entry pointer
call MEM_Get_Linear_Address
mov ecx,eax
xor edx,edx
.loop5:
;ecx - linear address of page table
;edx - index of page in page table
;ebp - current mapped physical address with flags
mov [ecx+4*edx],ebp ;write address of page in page table
add ebp,0x1000 ;move to next page
inc edx
cmp edx,4096/4
jl .loop5
dec esi
jmp .loop4
.loop4end:
.set_cr3:
;set value of cr3 register to the address of page directory
mov eax,[general_page_table]
add eax,8+16 ;add flags
mov cr3,eax ;now we have full access paging
popad
ret
;-----------------------------------------------------------------------------
simple_clone_cr3_table:
;Parameters:
; eax - physical address of cr3 table (page directory)
;result:
; eax - physical address of clone of cr3 table.
;Function copy only page directory.
push ecx
push edx
push esi
push edi
call MEM_Get_Linear_Address
;eax - linear address of cr3 table
mov esi,eax
call MEM_Alloc_Page
test eax,eax
jz .failed
;eax - physical address of new page diretory
mov edx,eax
call MEM_Get_Linear_Address
mov edi,eax
mov ecx,4096/4
cld
;esi - address of old page directory
;edi - address of new page directory
rep movsd ;copy page directory
mov eax,edx
.failed:
pop edi
pop esi
pop edx
pop ecx
ret
;-----------------------------------------------------------------------------
create_app_cr3_table:
;Parameters:
; eax - slot of process (index in 0x3000 table)
;result:
; eax - physical address of table.
;This function create page directory for new process and
;write it physical address to offset 0xB8 of extended
;process information.
push ebx
 
mov ebx,eax
mov eax,[general_page_table]
call simple_clone_cr3_table ;clone general page table
shl ebx,8
mov [second_base_address+0x80000+ebx+APPDATA.dir_table],eax ;save address of page directory
pop ebx
ret
;-----------------------------------------------------------------------------
get_cr3_table:
;Input:
; eax - slot of process
;result:
; eax - physical address of page directory
shl eax,8 ;size of process extended information=256 bytes
mov eax,[second_base_address+0x80000+eax+APPDATA.dir_table]
ret
;-----------------------------------------------------------------------------
dispose_app_cr3_table:
;Input:
; eax - slot of process
;result:
; none
;This procedure frees page directory,
;page tables and all memory of process.
pushad
mov ebp,eax
;ebp = process slot in the procedure.
shl eax,8
mov eax,[second_base_address+0x80000+eax+APPDATA.dir_table]
mov ebx,eax
;ebx = physical address of page directory
call MEM_Get_Linear_Address
mov edi,eax
;edi = linear address of page directory
mov eax,[edi+(std_application_base_address shr 20)]
and eax,not (4096-1)
call MEM_Get_Linear_Address
mov esi,eax
;esi = linear address of first page table
 
;search threads
; mov ecx,0x200
xor edx,edx
mov eax,0x2
.loop:
;eax = current slot of process
mov ecx,eax
shl ecx,5
cmp byte [second_base_address+0x3000+ecx+TASKDATA.state],9 ;if process running?
jz .next ;skip empty slots
shl ecx,3
cmp [second_base_address+0x80000+ecx+APPDATA.dir_table],ebx ;compare page directory addresses
jnz .next
inc edx ;thread found
.next:
inc eax
cmp eax,[0x3004] ;exit loop if we look through all processes
jle .loop
;edx = number of threads
;our process is zombi so it isn't counted
cmp edx,1
jg .threadsexists
;if there isn't threads then clear memory.
add edi,std_application_base_address shr 20
.loop1:
;edi = linear address of current directory entry
;esi = linear address of current page table
test esi,esi
jz .loop1end
xor ecx,ecx
.loop2:
;ecx = index of page
mov eax,[esi+4*ecx]
test eax,eax
jz .loopend ;skip empty entries
and eax,not (4096-1) ;clear flags
push ecx
call MEM_Free_Page ;free page
pop ecx
.loopend:
inc ecx
cmp ecx,1024 ;there are 1024 pages in page table
jl .loop2
mov eax,esi
call MEM_Free_Page_Linear ;free page table
.loop1end:
add edi,4 ;move to next directory entry
mov eax,[edi]
and eax,not (4096-1)
call MEM_Get_Linear_Address
mov esi,eax ;calculate linear address of new page table
test edi,0x800
jz .loop1 ;test if we at 0x80000000 address?
and edi,not (4096-1) ;clear offset of page directory entry
mov eax,edi
call MEM_Free_Page_Linear ;free page directory
popad
ret
.threadsexists: ;do nothing
popad ;last thread will free memory
ret
;-----------------------------------------------------------------------------
mem_alloc_specified_region:
;eax - linear directory address
;ebx - start address (aligned to 4096 bytes)
;ecx - size in pages
;result:
; eax=1 - ok
; eax=0 - failed
;Try to alloc and map ecx pages to [ebx;ebx+4096*ecx) interval.
pushad
mov ebp,ebx ;save start address for recoil
mov esi,eax
.gen_loop:
;esi = linear directory address
;ebx = current address
;ecx = remaining size in pages
mov edx,ebx
shr edx,22
mov edi,[esi+4*edx] ;find directory entry for current address
test edi,edi
jnz .table_exists ;check if page table allocated
call MEM_Alloc_Page ;alloc page table
test eax,eax
jz .failed
mov [esi+4*edx],eax
add dword [esi+4*edx],7 ;write it address with flags
call MEM_Get_Linear_Address
call mem_fill_page ;clear page table
jmp .table_linear
.table_exists:
;calculate linear address of page table
mov eax,edi
and eax,not (4096-1) ;clear flags
call MEM_Get_Linear_Address
.table_linear:
;eax = linear address of page table
mov edx,ebx
shr edx,12
and edx,(1024-1) ;calculate index in page table
mov edi,eax
.loop:
;edi = linear address of page table
;edx = current page table index
;ecx = remaining size in pages
;ebx = current address
test ecx,ecx
jle .endloop1 ;all requested pages allocated
call MEM_Alloc_Page ;alloc new page
test eax,eax
jz .failed
mov [edi+4*edx],eax
add dword [edi+4*edx],7 ;write it address with flags
call MEM_Get_Linear_Address
call mem_fill_page ;clear new page
;go to next page table entry
dec ecx
add ebx,4096
inc edx
test edx,(1024-1)
jnz .loop
jmp .gen_loop
.endloop1:
popad
mov eax,1 ;ok
ret
.failed:
;calculate data for recoil
sub ebx,ebp
shr ebx,12
mov ecx,ebx ;calculate number of allocated pages
mov eax,esi ;restore linear address of page directory
mov ebx,ebp ;restore initial address
call mem_free_specified_region ;free all allocated pages
popad
xor eax,eax ;fail
ret
;-----------------------------------------------------------------------------
mem_fill_page:
;Input:
; eax - address
;result:
; none
;set to zero 4096 bytes at eax address.
push ecx
push edi
mov edi,eax
mov ecx,4096/4
xor eax,eax
rep stosd
lea eax,[edi-4096]
pop edi
pop ecx
ret
;-----------------------------------------------------------------------------
mem_free_specified_region:
;eax - linear page directory address
;ebx - start address (aligned to 4096 bytes)
;ecx - size in pages
;result - none
;Free pages in [ebx;ebx+4096*ecx) region.
pushad
mov esi,eax
xor ebp,ebp
.gen_loop:
;esi = linear page directory address
;ebx = current address
;ecx = remaining pages
;ebp = 0 for first page table
; 1 otherwise
mov edx,ebx
shr edx,22
mov eax,[esi+4*edx] ;find directory entry for current address
and eax,not (4096-1)
test eax,eax
jnz .table_exists
;skip absent page tables
mov edx,ebx
shr edx,12
and edx,(1024-1) ;edx - index of current page
add ebx,1 shl 22
add ecx,edx
and ebx,not ((1 shl 22)-1)
mov ebp,1 ;set flag
sub ecx,1024 ;ecx=ecx-(1024-edx)
jg .gen_loop
popad
ret
.table_exists:
call MEM_Get_Linear_Address
;eax - linear address of table
mov edx,ebx
shr edx,12
and edx,(1024-1) ;edx - index of current page
mov edi,eax
.loop:
;edi = linear address of page table entry
;edx = index of page table entry
;ecx = remaining pages
test ecx,ecx
jle .endloop1
mov eax,[edi+4*edx]
and eax,not (4096-1)
call MEM_Free_Page ;free page
mov dword [edi+4*edx],0 ;and clear page table entry
dec ecx
inc edx
cmp edx,1024
jl .loop
test ebp,ebp
jz .first_page
mov eax,edi
call MEM_Free_Page_Linear ;free page table
mov edx,ebx
shr edx,22
mov dword [esi+4*edx],0 ;and clear page directory entry
.first_page:
add ebx,1 shl 22
and ebx,not ((1 shl 22)-1) ;calculate new current address
mov ebp,1 ;set flag
jmp .gen_loop
.endloop1:
popad
ret
end if
/kernel/tags/kolibri0.6.3.0/core/physmem.inc
0,0 → 1,220
virtual at 0
physical_mem_block:
.start rd 1
.size rd 1
.flags rd 1 ;0-free, pid-used.
.sizeof:
end virtual
max_physical_mem_blocks = 24
uglobal
num_physical_mem_blocks rd 1
physical_mem_blocks rd 3*max_physical_mem_blocks
endg
Init_Physical_Memory_Manager:
pushad
mov edi,physical_mem_blocks
mov ecx,3*max_physical_mem_blocks
xor eax,eax
cld
rep stosd
mov dword [num_physical_mem_blocks],2
mov [physical_mem_blocks+physical_mem_block.start],0x60000
mov [physical_mem_blocks+physical_mem_block.size],0x20000 ;128Kb
mov [physical_mem_blocks+physical_mem_block.sizeof+physical_mem_block.start],0x780000
mov [physical_mem_blocks+physical_mem_block.sizeof+physical_mem_block.size],0x80000 ;512Kb
popad
ret
Insert_Block:
;input:
; eax - handle
;output:
; none
push eax ecx esi edi
sub eax,[num_physical_mem_blocks]
neg eax
mov edi,physical_mem_block.sizeof
imul eax,edi
shr eax,2
mov ecx,eax
mov esi,[num_physical_mem_blocks]
imul esi,edi
add esi,physical_mem_blocks
lea edi,[esi+physical_mem_block.sizeof]
std
rep movsd
pop edi esi ecx eax
ret
Delete_Block:
;input:
; eax - handle
;output:
; none
pushad
mov edi,eax
sub eax,[num_physical_mem_blocks]
neg eax
dec eax
mov esi,physical_mem_block.sizeof
imul eax,esi
imul edi,esi
add edi,physical_mem_blocks
lea esi,[edi+physical_mem_block.sizeof]
mov ecx,eax
shr ecx,2
cld
rep movsd
popad
ret
Allocate_Physical_Block:
;input:
; eax - size
;output:
; eax - address or 0 if not enough memory.
pushad
cmp [num_physical_mem_blocks],max_physical_mem_blocks
jge .error
mov ebx,eax
xor eax,eax
mov esi,physical_mem_blocks
.loop:
cmp dword [esi+physical_mem_block.flags],0
jnz .next
cmp [esi+physical_mem_block.size],ebx
jg .addblock
jz .noaddblock
.next:
inc eax
add esi,physical_mem_block.sizeof
cmp eax,[num_physical_mem_blocks]
jl .loop
.error:
popad
xor eax,eax
ret
.noaddblock:
mov eax,[esi+physical_mem_block.start]
mov [esp+28],eax
mov eax,[0x3010]
mov eax,[eax+TASKDATA.pid]
mov [esi+physical_mem_block.flags],eax
popad
ret
.addblock:
call Insert_Block
inc dword [num_physical_mem_blocks]
mov eax,[esi+physical_mem_block.start]
mov [esp+28],eax
mov ecx,[0x3010]
mov ecx,[ecx+TASKDATA.pid]
mov [esi+physical_mem_block.flags],ecx
mov ecx,[esi+physical_mem_block.size]
mov [esi+physical_mem_block.size],ebx
sub ecx,ebx
mov [esi+physical_mem_block.sizeof+physical_mem_block.size],ecx
add ebx,[esi+physical_mem_block.start]
mov [esi+physical_mem_block.sizeof+physical_mem_block.start],ebx
mov dword [esi+physical_mem_block.sizeof+physical_mem_block.flags],0
popad
ret
Free_Physical_Block:
;input:
; eax - address
;output:
; none
pushad
test eax,eax
jz .ret
mov ebx,eax
xor eax,eax
mov esi,physical_mem_blocks
.loop:
cmp ebx,[esi+physical_mem_block.start]
jz .endloop
inc eax
add esi,physical_mem_block.sizeof
cmp eax,[num_physical_mem_blocks]
jl .loop
jmp .ret
.endloop:
mov dword [esi+physical_mem_block.flags],0
test eax,eax
jz .no_union_previous
cmp dword [esi-physical_mem_block.sizeof+physical_mem_block.flags],0
jnz .no_union_previous
mov ebx,[esi-physical_mem_block.sizeof+physical_mem_block.start]
add ebx,[esi-physical_mem_block.sizeof+physical_mem_block.size]
cmp ebx,[esi+physical_mem_block.start]
jnz .no_union_previous
mov ebx,[esi+physical_mem_block.size]
add [esi-physical_mem_block.sizeof+physical_mem_block.size],ebx
call Delete_Block
dec eax
dec [num_physical_mem_blocks]
.no_union_previous:
inc eax
cmp eax,[num_physical_mem_blocks]
jge .no_union_next
cmp dword [esi+physical_mem_block.sizeof+physical_mem_block.flags],0
jnz .no_union_next
mov ebx,[esi+physical_mem_block.start]
add ebx,[esi+physical_mem_block.size]
cmp ebx,[esi+physical_mem_block.sizeof+physical_mem_block.start]
jnz .no_union_next
mov ebx,[esi+physical_mem_block.sizeof+physical_mem_block.size]
add [esi+physical_mem_block.size],ebx
call Delete_Block
dec [num_physical_mem_blocks]
.no_union_next:
.ret:
popad
ret
sys_allocate_physical_block:
;eax - subfunction number
mov eax,ebx
call Allocate_Physical_Block
mov [esp+36],eax
ret
sys_free_physical_block:
;eax - subfunction number
mov eax,ebx
call Free_Physical_Block
ret
sys_set_buffer:
add ecx,std_application_base_address
isys_set_buffer: ;for using in kernel
;eax - subfunction number
;ebx - physical address
;ecx - buffer start
;edx - buffer size
lea edi,[ebx+second_base_address]
mov esi,ecx
mov ecx,edx
cld
rep movsb
ret
sys_get_buffer:
add ecx,std_application_base_address
isys_get_buffer: ;for using in kernel
;eax - subfunction number
;ebx - physical address
;ecx - buffer start
;edx - buffer size
mov edi,ecx
lea esi,[ebx+second_base_address]
mov ecx,edx
cld
rep movsb
ret
sys_internal_services:
cmp eax,4
jle sys_sheduler
cmp eax,5
jz sys_allocate_physical_block
cmp eax,6
jz sys_free_physical_block
cmp eax,7
jz sys_set_buffer
cmp eax,8
jz sys_get_buffer
ret
/kernel/tags/kolibri0.6.3.0/core/sync.inc
0,0 → 1,111
if ~defined sync_inc
sync_inc_fix:
sync_inc fix sync_inc_fix
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Synhronization for MenuetOS. ;;
;;Author: Halyavin Andrey, halyavin@land.ru ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;simplest mutex.
macro SimpleMutex name
{
; iglobal
name dd 0
name#.type = 1
; endg
}
macro WaitSimpleMutex name
{
local start_wait,ok
start_wait=$
cli
cmp [name],dword 0
jz ok
sti
call change_task
jmp start_wait
ok=$
push eax
mov eax,dword [0x3010+second_base_address]
mov eax,[eax+TASKDATA.pid]
mov [name],eax
pop eax
sti
}
macro ReleaseSimpleMutex name
{
mov [name],dword 0
}
macro TryWaitSimpleMutex name ;result in eax and in flags
{
local ok,try_end
cmp [name],dword 0
jz ok
xor eax,eax
jmp try_end
ok=$
xor eax,eax
inc eax
try_end=$
}
macro SimpleCriticalSection name
{
; iglobal
name dd 0
dd 0
name#.type=2
; endg
}
macro WaitSimpleCriticalSection name
{
local start_wait,first_wait,inc_counter,end_wait
push eax
mov eax,[0x3010+second_base_address]
mov eax,[eax+TASKDATA.pid]
start_wait=$
cli
cmp [name],dword 0
jz first_wait
cmp [name],eax
jz inc_counter
sti
call change_task
jmp start_wait
first_wait=$
mov [name],eax
mov [name+4],dword 1
jmp end_wait
inc_counter=$
inc dword [name+4]
end_wait=$
sti
pop eax
}
macro ReleaseSimpleCriticalSection name
{
local release_end
dec dword [name+4]
jnz release_end
mov [name],dword 0
release_end=$
}
macro TryWaitSimpleCriticalSection name ;result in eax and in flags
{
local ok,try_end
mov eax,[0x3000+second_base_address]
mov eax,[eax+TASKDATA.pid]
cmp [name],eax
jz ok
cmp [name],0
jz ok
xor eax,eax
jmp try_end
ok=$
xor eax,eax
inc eax
try_end=$
}
_cli equ call MEM_HeapLock
_sti equ call MEM_HeapUnLock
end if
 
/kernel/tags/kolibri0.6.3.0/core/memmanag.inc
0,0 → 1,833
if ~defined memmanager_inc
memmanager_inc_fix:
memmanager_inc fix memmanager_inc_fix
;for testing in applications
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Memory allocator for MenuetOS kernel
;; Andrey Halyavin, halyavin@land.ru 2005
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; heap block structure -
;; you can handle several ranges of
;; pages simultaneosly.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.heap_linear_address equ 0
.heap_block_size equ 4
.heap_physical_address equ 8
.heap_reserved equ 12
.heap_block_info equ 16
max_heaps equ 8
.range_info equ 36
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; memory manager data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
uglobal
MEM_heap_block rd .heap_block_info*max_heaps/4
MEM_heap_count rd 1
MEM_cli_count rd 1
MEM_cli_prev rd 1
MEM_FreeSpace rd 1
; MEM_AllSpace rd 1
endg
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Init
;;Initialize memory manager structures.
;;Must be called first.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Init:
push eax
xor eax,eax
mov [MEM_cli_prev],eax ;init value = 0
dec eax
mov [MEM_cli_count],eax ;init value = -1
pop eax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Heap_Lock
;;Wait until all operations with heap will be finished.
;;Between MEM_Heap_Lock and MEM_Heap_UnLock operations
;;with heap are forbidden.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Heap_Lock:
pushfd
cli
inc dword [MEM_cli_count]
jz MEM_Heap_First_Lock
add esp,4
ret
MEM_Heap_First_Lock: ;save interrupt flag
shr dword [esp],9
and dword [esp],1
pop dword [MEM_cli_prev]
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Heap_UnLock
;;After this routine operations with heap are allowed.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Heap_UnLock:
dec dword [MEM_cli_count]
js MEM_Heap_UnLock_last
ret
MEM_Heap_UnLock_last:
cmp dword [MEM_cli_prev],0 ;restore saved interrupt flag
jz MEM_Heap_UnLock_No_sti
sti
MEM_Heap_UnLock_No_sti:
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Add_Heap
;;Add new range to memory manager.
;;eax - linear address
;;ebx - size in pages
;;ecx - physical address
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Add_Heap:
push edx
call MEM_Heap_Lock
mov edx,[MEM_heap_count]
cmp edx,max_heaps
jz MEM_Add_Heap_Error
inc dword [MEM_heap_count]
shl edx,4
mov [MEM_heap_block+edx+.heap_linear_address],eax
mov [MEM_heap_block+edx+.heap_block_size],ebx
shl dword [MEM_heap_block+edx+.heap_block_size],12
mov [MEM_heap_block+edx+.heap_physical_address],ecx
lea edx,[4*ebx+.range_info+4095] ;calculate space for page info table
and edx,0xFFFFF000
 
push edi
mov edi,edx
shr edi,12
sub edi,ebx ;edi=-free space
sub [MEM_FreeSpace],edi
; sub [MEM_AllSpace],edi
 
mov [eax],eax
add [eax],edx ;first 4 bytes - pointer to first free page
;clean page info area
lea edi,[eax+4]
mov ecx,edx
shr ecx,2
push eax
xor eax,eax
rep stosd
pop eax
pop edi
;create free pages list.
mov ecx,[eax]
shl ebx,12
add eax,ebx ;eax - address after block
MEM_Add_Heap_loop:
add ecx,4096
mov [ecx-4096],ecx ;set forward pointer
cmp ecx,eax
jnz MEM_Add_Heap_loop
mov dword [ecx-4096],0 ;set end of list
MEM_Add_Heap_ret:
call MEM_Heap_UnLock
pop edx
ret
MEM_Add_Heap_Error:
xor eax,eax
jmp MEM_Add_Heap_ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Physical_Address
;;Translate linear address to physical address
;;Parameters:
;; eax - linear address
;;Result:
;; eax - physical address
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Physical_Address
MEM_Get_Physical_Address:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Physical_Address_loop:
sub eax,[MEM_heap_block+ecx+.heap_linear_address]
jl MEM_Get_Physical_Address_next
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jge MEM_Get_Physical_Address_next
add eax,[MEM_heap_block+ecx+.heap_physical_address]
jmp MEM_Get_Physical_Address_loopend
MEM_Get_Physical_Address_next:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
sub ecx,16
jns MEM_Get_Physical_Address_loop
xor eax,eax ;address not found
MEM_Get_Physical_Address_loopend:
call MEM_Heap_UnLock
pop ecx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Linear_Address
;;Translate physical address to linear address.
;;Parameters:
;; eax - physical address
;;Result:
;; eax - linear address
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Linear_Address
MEM_Get_Linear_Address:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Linear_Address_loop:
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
jl MEM_Get_Linear_Address_Next
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jge MEM_Get_Linear_Address_Next
add eax,[MEM_heap_block+ecx+.heap_linear_address]
call MEM_Heap_UnLock
pop ecx
ret
MEM_Get_Linear_Address_Next:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
sub ecx,16
jns MEM_Get_Linear_Address_loop
call MEM_Heap_UnLock
pop ecx
xor eax,eax ;address not found
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Page
;;Allocate and add reference to page
;;Result:
;; eax<>0 - physical address of page
;; eax=0 - not enough memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Page
MEM_Alloc_Page:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Alloc_Page_loop:
push ecx
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
cmp dword [ecx],0
jz MEM_Alloc_Page_loopend
mov eax,[ecx]
push dword [eax]
pop dword [ecx]
sub eax,ecx
push eax
shr eax,10
mov word [ecx+.range_info+eax],1
pop eax
pop ecx
add eax,[MEM_heap_block+ecx+.heap_physical_address]
dec [MEM_FreeSpace]
jmp MEM_Alloc_Page_ret
MEM_Alloc_Page_loopend:
pop ecx
sub ecx,16
jns MEM_Alloc_Page_loop
xor eax,eax
MEM_Alloc_Page_ret:
call MEM_Heap_UnLock
pop ecx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Page_Linear
;;Allocate and add reference to page
;;Result:
;; eax<>0 - linear address of page
;; eax=0 - not enough memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Page_Linear
MEM_Alloc_Page_Linear:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Alloc_Page_Linear_loop:
push ecx
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
cmp dword [ecx],0
jz MEM_Alloc_Page_Linear_loopend
mov eax,[ecx]
push dword [eax]
pop dword [ecx]
push eax
sub eax,ecx
shr eax,10
mov word [ecx+.range_info+eax],1
pop eax
pop ecx
dec [MEM_FreeSpace]
jmp MEM_Alloc_Page_Linear_ret
MEM_Alloc_Page_Linear_loopend:
pop ecx
sub ecx,16
jns MEM_Alloc_Page_Linear_loop
xor eax,eax
MEM_Alloc_Page_Linear_ret:
call MEM_Heap_UnLock
pop ecx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Page
;;Remove reference and free page if number of
;;references is equal to 0
;;Parameters:
;; eax - physical address of page
;;Result:
;; eax - 1 success
;; eax - 0 failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if (used MEM_Free_Page) | (used MEM_Free_Page_Linear)
MEM_Free_Page:
test eax,eax
jz MEM_Free_Page_Zero
test eax,0xFFF
jnz MEM_Free_Page_Not_Aligned
push ebx
push ecx
push edx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Free_Page_Heap_loop:
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
js MEM_Free_Page_Heap_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Free_Page_Heap_loopend
MEM_Free_Page_Heap_loopnext:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
sub ecx,16
jns MEM_Free_Page_Heap_loop
xor eax,eax
inc eax
jmp MEM_Free_Page_ret
MEM_Free_Page_Heap_loopend:
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
mov ebx,eax
add eax,ecx
shr ebx,10
mov edx,[ecx+.range_info+ebx]
test edx,0x80000000
jnz MEM_Free_Page_Bucket
test dx,dx
jz MEM_Free_Page_Error
dec word [ecx+.range_info+ebx]
jnz MEM_Free_Page_OK
MEM_Free_Page_Bucket:
push dword [ecx]
mov [ecx],eax
pop dword [eax]
mov dword [ecx+.range_info+ebx],0
inc [MEM_FreeSpace]
MEM_Free_Page_OK:
mov eax,1
MEM_Free_Page_ret:
call MEM_Heap_UnLock
pop edx
pop ecx
pop ebx
ret
MEM_Free_Page_Error:
xor eax,eax
jmp MEM_Free_Page_ret
MEM_Free_Page_Zero:
inc eax
ret
MEM_Free_Page_Not_Aligned:
xor eax,eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Page_Linear
;;Remove reference and free page if number of
;;references is equal to 0
;;Parameters:
;; eax - linear address of page
;;Result:
;; eax - 1 success
;; eax - 0 failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free_Page_Linear
MEM_Free_Page_Linear:
test eax,eax
jz MEM_Free_Page_Zero
test eax,0xFFF
jnz MEM_Free_Page_Not_Aligned
push ebx
push ecx
push edx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Free_Page_Linear_Heap_loop:
sub eax,[MEM_heap_block+ecx+.heap_linear_address]
js MEM_Free_Page_Linear_Heap_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Free_Page_Heap_loopend
MEM_Free_Page_Linear_Heap_loopnext:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
sub ecx,16
jns MEM_Free_Page_Linear_Heap_loop
xor eax,eax
inc eax
jmp MEM_Free_Page_ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Pages
;;Allocates set of pages.
;;Parameters:
;; eax - number of pages
;; ebx - buffer for physical addresses
;;Result:
;; eax - number of allocated pages
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Pages
MEM_Alloc_Pages:
push eax
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Alloc_Pages_ret
MEM_Alloc_Pages_loop:
call MEM_Alloc_Page
test eax,eax
jz MEM_Alloc_Pages_ret
mov [ebx],eax
add ebx,4
dec ecx
jnz MEM_Alloc_Pages_loop
MEM_Alloc_Pages_ret:
sub [esp+8],ecx
pop ecx
pop ebx
pop eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Pages_Linear
;;Allocates set of pages.
;;Parameters:
;; eax - number of pages
;; ebx - buffer for linear addresses
;;Result:
;; eax - number of allocated pages
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Pages_Linear
MEM_Alloc_Pages_Linear:
push eax
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Alloc_Pages_Linear_ret
MEM_Alloc_Pages_Linear_loop:
call MEM_Alloc_Page_Linear
test eax,eax
jz MEM_Alloc_Pages_Linear_ret
mov [ebx],eax
add ebx,4
dec ecx
jnz MEM_Alloc_Pages_Linear_loop
MEM_Alloc_Pages_Linear_ret:
sub [esp+8],ecx
pop ecx
pop ebx
pop eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Pages
;;Parameters:
;; eax - number of pages
;; ebx - array of addresses
;;Result:
;; eax=1 - succcess
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free_Pages
MEM_Free_Pages:
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Free_Pages_ret
MEM_Free_Pages_loop:
mov eax,[ebx]
call MEM_Free_Page
add ebx,4
test eax,eax
jz MEM_Free_Pages_ret
dec ecx
jnz MEM_Free_Pages_loop
MEM_Free_Pages_ret:
pop ecx
pop ebx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Pages_Linear
;;Parameters:
;; eax - number of pages
;; ebx - array of addresses
;;Result:
;; eax=1 - succcess
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free_Pages_Linear
MEM_Free_Pages_Linear:
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Free_Pages_Linear_ret
MEM_Free_Pages_Linear_loop:
mov eax,[ebx]
call MEM_Free_Page_Linear
add ebx,4
test eax,eax
jz MEM_Free_Pages_Linear_ret
dec ecx
jnz MEM_Free_Pages_Linear_loop
MEM_Free_Pages_Linear_ret:
pop ecx
pop ebx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Heap_Number
;;Calculate number of heap which pointer belongs to.
;;Parameter:
;; eax - address
;;Result:
;; ecx - number of heap*16.
;; eax=0 if address not found.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Heap_Number
MEM_Get_Heap_Number:
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Heap_loop:
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
jl MEM_Get_Heap_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Get_Heap_loopend
MEM_Get_Heap_loopnext:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
sub ecx,16
jns MEM_Get_Heap_loop
call MEM_Heap_UnLock
xor eax,eax
ret
MEM_Get_Heap_loopend:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
call MEM_Heap_UnLock
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Heap_Number_Linear
;;Calculate number of heap which pointer belongs to.
;;Parameter:
;; eax - address
;;Result:
;; ecx - number of heap*16.
;; eax=0 if address not found.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Heap_Number_Linear
MEM_Get_Heap_Number_Linear:
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Heap_Linear_loop:
sub eax,[MEM_heap_block+ecx+.heap_linear_address]
jl MEM_Get_Heap_Linear_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Get_Heap_Linear_loopend
MEM_Get_Heap_Linear_loopnext:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
sub ecx,16
jns MEM_Get_Heap_Linear_loop
call MEM_Heap_UnLock
xor eax,eax
ret
MEM_Get_Heap_Linear_loopend:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
call MEM_Heap_UnLock
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc
;;Allocate small region.
;;Parameters:
;; eax - size (0<eax<=4096)
;;Result:
;; eax - linear address
;; eax=0 - not enough memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc
MEM_Alloc:
;find chain
test eax,eax
jng MEM_Alloc_Wrong_Size
cmp eax,4096
jg MEM_Alloc_Wrong_Size
push ebx
push ecx
push edx
push esi
dec eax
shr eax,4
xor edx,edx
MEM_Alloc_Find_Size:
add edx,4
shr eax,1
jnz MEM_Alloc_Find_Size
MEM_Alloc_Size_Found:
mov ecx,edx
shr ecx,2
add ecx,4
mov eax,1
shl eax,cl
mov esi,eax
;esi - block size
;edx - offset
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Alloc_Find_Heap:
mov eax,[MEM_heap_block+ecx+.heap_linear_address]
cmp dword [eax+edx],0
jnz MEM_Alloc_Use_Existing
sub ecx,16
jns MEM_Alloc_Find_Heap
;create new bucket page
call MEM_Alloc_Page_Linear
call MEM_Get_Heap_Number_Linear
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
mov [ecx+edx],eax
lea ebx,[eax+4096]
MEM_Alloc_List_loop:
mov [eax],eax
mov [eax+4],eax
add [eax],esi
sub [eax+4],esi
add eax,esi
cmp eax,ebx
jnz MEM_Alloc_List_loop
sub ebx,esi
mov dword [ebx],0
sub eax,4096
mov dword [eax+4],0
mov eax,ecx
MEM_Alloc_Use_Existing:
mov ebx,eax
mov eax,[eax+edx]
mov ecx,[eax]
mov [ebx+edx],ecx
test ecx,ecx
jz MEM_Alloc_Became_Empty
mov dword [ecx+4],0
MEM_Alloc_Became_Empty:
mov ecx,eax
sub ecx,ebx
shr ecx,10
and ecx,0xFFFFFFFC
inc byte [ebx+.range_info+ecx+2]
shr edx,2
add edx,128
dec edx
mov [ebx+.range_info+ecx+3],dl
MEM_Alloc_ret:
call MEM_Heap_UnLock
pop esi
pop edx
pop ecx
pop ebx
ret
MEM_Alloc_Wrong_Size:
xor eax,eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free
;;Parameters:
;; eax - linear address
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free
MEM_Free:
test eax,eax
jz MEM_Free_Zero
push ebx
push ecx
push edx
push esi
push edi
push ebp
call MEM_Heap_Lock
call MEM_Get_Heap_Number_Linear
test eax,eax
jz MEM_Free_ret
mov edx,eax
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
sub edx,ecx
shr edx,10
and edx,0xFFFFFFFC
mov ebx,[ecx+.range_info+edx]
mov esi,ebx
shr esi,24
sub esi,128
mov edi,[ecx+4+4*esi]
mov [eax],edi
mov dword [eax+4],0
test edi,edi
jz MEM_Free_Empty_List
mov [edi+4],eax
MEM_Free_Empty_List:
mov [ecx+4+4*esi],eax
sub ebx,0x10000
mov [ecx+.range_info+edx],ebx
test ebx,0xFF0000
jnz MEM_Free_ret
;delete empty blocks on the page
lea edx,[esi+5]
and eax,0xFFFFF000
mov edi,eax
mov eax,1
xchg ecx,edx
shl eax,cl
mov ecx,edx
mov edx,eax
;edx - size of block
;edi - start of page
mov eax,edi
lea ebx,[eax+4096]
MEM_Free_Block_loop:
cmp dword [eax+4],0
jnz MEM_Free_Block_Not_First
mov ebp,dword [eax]
mov [ecx+4+4*esi],ebp
test ebp,ebp
jz MEM_Free_Block_Last
mov dword [ebp+4],0
MEM_Free_Block_Last:
jmp MEM_Free_Block_loop_end
MEM_Free_Block_Not_First:
mov ebp,dword [eax]
push ebp
mov ebp,dword [eax+4]
pop dword [ebp]
mov ebp,dword [eax]
test ebp,ebp
jz MEM_Free_Block_loop_end
push dword [eax+4]
pop dword [ebp+4]
; jmp MEM_Free_Block_loop_end
MEM_Free_Block_loop_end:
add eax,edx
cmp eax,ebx
jnz MEM_Free_Block_loop
mov eax,edi
call MEM_Free_Page_Linear
MEM_Free_ret:
call MEM_Heap_UnLock
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
ret
MEM_Free_Zero:
inc eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Add_Reference
;; eax - physical address of page
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Add_Reference
MEM_Add_Reference:
push ebx
push ecx
call MEM_Heap_Lock
call MEM_Get_Heap_Number
test eax,eax
jz MEM_Add_Reference_ret
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
shr eax,10
and eax,0xFFFFFFFC
test dword [ecx+eax+.range_info],0x80000000
jnz MEM_Add_Reference_failed
inc dword [ecx+eax+.range_info]
MEM_Add_Reference_ret:
call MEM_Heap_UnLock
pop ecx
pop ebx
ret
MEM_Add_Reference_failed:
xor eax,eax
jmp MEM_Add_Reference_ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Add_Reference_Linear
;; eax - linear address of page
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Add_Reference_Linear
MEM_Add_Reference_Linear:
push ebx
push ecx
call MEM_Heap_Lock
call MEM_Get_Heap_Number_Linear
test eax,eax
jz MEM_Add_Reference_Linear_ret
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
sub eax,ecx
shr eax,10
and eax,0xFFFFFFFC
test dword [ecx+eax+.range_info],0x80000000
jnz MEM_Add_Reference_Linear_failed
inc dword [ecx+eax+.range_info]
mov eax,1
MEM_Add_Reference_Linear_ret:
call MEM_Heap_UnLock
pop ecx
pop ebx
ret
MEM_Add_Reference_Linear_failed:
xor eax,eax
jmp MEM_Add_Reference_Linear_ret
end if
end if ;memmanager.inc