Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 163 → Rev 164

/kernel/trunk/core/memory.inc
0,0 → 1,1417
 
tmp_page_tab equ 0x01000000
 
align 4
proc mem_test
mov eax, cr0
or eax, 0x60000000 ;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, 0x21
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 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_master_tab+PG_SW
mov dword [sys_master_tab+0x600], sys_master_tab+PG_SW
 
mov cr4, ebx
 
mov ecx, [pg_data.kernel_tables]
sub ecx, 4
mov eax, tmp_page_tab+PG_SW
mov edi, sys_pgdir+16
mov esi, sys_master_tab+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
mov esi, sys_master_tab
 
.map_kernel_tabs:
 
mov [edi], eax
mov [esi], eax
add eax, 0x1000
add edi, 4
add esi, 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_master_tab+PG_SW
mov dword [sys_master_tab+0x600], sys_master_tab+PG_SW
ret
endp
 
;align 4
;proc init_mem
;
; xor eax, eax
; mov edi, sys_pgdir
; mov ecx, 2048
; rep stosd
;
; bt [cpu_caps], CAPS_PSE
; jc .use_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 eax, tmp_page_tab+PG_SW
; mov ecx, 4
; xor ebx, ebx
 
;.map_page_tables:
; mov [sys_pgdir+ebx], eax
; mov [sys_master_tab+ebx], eax
; add eax, 0x1000
; add ebx, 4
; dec ecx
; jnz .map_page_tables
 
; mov dword [sys_pgdir+0x600], sys_master_tab+PG_SW
; mov dword [sys_master_tab+0x600], sys_master_tab+PG_SW
 
; ret
 
;.use_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 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_master_tab+PG_SW
; mov dword [sys_master_tab+0x600], sys_master_tab+PG_SW
 
; mov cr4, ebx
; 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 init_pg_mem
;
; 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
;
; shl eax, PAGES_USED
; mov [sys_pgmap+512], eax
;
; mov [page_start], sys_pgmap+512
; mov ebx, sys_pgmap
; add ebx, [pg_data.pagemap_size]
; mov [page_end], ebx
; mov eax, [pg_data.pages_count]
; sub eax, 4096+PAGES_USED
; mov [pg_data.pages_free], eax
;
; mov [pg_data.pages_faults], 0
;
; mov edi, OS_BASE+0x01000000
; mov esi, [pg_data.kernel_tables]
; sub esi, 4
; ja @f
; mov esi, 1
;@@:
; call alloc_page
; stdcall map_page_table, sys_pgdir, edi, eax
; add edi, 0x00400000
; dec esi
; jnz @B
;
; mov ecx, [pg_data.kernel_tables]
; sub ecx, 4
; shl ecx, 10
; mov edi, OS_BASE+0x01000000
; shr edi, 10
; add edi, pages_tab
; xor eax, eax
; cld
; rep stosd
;
; mov eax, cr3
; mov cr3, eax
;
; 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,page_dir:dword, 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 ecx, [page_dir]
mov dword [ecx+ebx*4], eax
mov dword [master_tab+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
 
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,sys_pgdir, 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
mov esi, [PROC_BASE+0x8c+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
 
mov eax, cr3
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW+PG_NOCACHE
 
@@:
call alloc_page
test eax, eax
jz .exit
 
stdcall map_page_table,[tmp_task_pdir], 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
 
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
.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 16
proc page_fault_handler
pushad
 
mov ebp, esp
mov eax, cr2
sub esp, 4
mov [esp], eax
push ds
 
mov ax, 0x10
mov ds, ax
 
; mov edx, 0x400 ;bocsh
; mov al,0xff ;bocsh
; out dx, al ;bocsh
; nop ;bocsh fix
 
 
mov ebx, [ebp-4]
 
cmp ebx, 0xe0000000
jae .lfb_addr
 
cmp ebx, 0x60400000
jae .user_space
 
cmp ebx, 0x60000000
jae .tab_space
 
jmp .kernel_space
 
.user_space:
inc [pg_data.pages_faults]
 
shr ebx, 12
mov eax, [pages_tab+ebx*4]
 
shr ebx, 10
mov edx, [master_tab+ebx*4]
 
test eax, 2
jz .exit
 
call alloc_page
and eax, eax
jz .exit
 
stdcall map_page,[ebp-4],eax,dword PG_UW
 
mov esi, [ebp-4]
and esi, 0xFFFFF000
mov ecx, 1024
xor eax, eax
@@:
mov [esi], eax
add esi, 4
dec ecx
jnz @B
.exit:
pop ds
mov esp, ebp
popad
add esp, 4
iretd
 
.kernel_space:
shr ebx, 12
mov eax, [pages_tab+ebx*4]
shr ebx, 10
mov eax, [master_tab+ebx*4]
 
pop ds
mov esp, ebp
popad
add esp, 4
iretd
 
.old_addr:
shr ebx, 12
; mov eax, [pages_tab+ebx*4]
shr ebx, 10
mov eax, [master_tab+ebx*4]
 
pop ds
mov esp, ebp
popad
add esp, 4
iretd
 
.lfb_addr:
shr ebx, 22
;mov ecx, [sys_page_dir]
mov eax, [master_tab+ebx*4]
 
pop ds
mov esp, ebp
popad
add esp, 4
iretd
 
.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]
 
pop ds
mov esp, ebp
popad
add esp, 4
iretd
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
proc get_mem_info stdcall, val:dword
 
mov esi, [val]
 
mov eax, [pg_data.pages_count]
mov [esi], eax
mov ebx, [pg_data.pages_free]
mov [esi+4], ebx
mov ecx, [pg_data.pages_faults]
mov [esi+8], ecx
 
ret
endp
 
align 4
new_services:
 
cmp eax,4
jle sys_sheduler
 
cmp eax, 10
jb .fail
ja @f
 
add ebx, new_app_base
stdcall get_mem_info, ebx
mov [esp+36], eax
ret
@@:
cmp eax, 11
ja @f
 
stdcall init_heap, ebx
mov [esp+36], eax
ret
@@:
cmp eax, 12
ja @f
 
stdcall user_alloc, ebx
mov [esp+36], eax
ret
@@:
cmp eax, 13
ja @f
 
stdcall user_free, ebx
mov [esp+36], eax
ret
@@:
cmp eax, 14
ja @f
add ebx,new_app_base
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
 
add ebx, new_app_base
stdcall get_service, ebx
mov [esp+36], eax
ret
@@:
cmp eax, 17
ja @f
stdcall srv_handlerEx, 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]
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:
frstor [eax]
ret
endp
 
align 4
proc test_cpu
locals
cpu_type dd 0
cpu_id dd 0
cpu_Intel dd 0
cpu_AMD dd 0
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
 
 
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
 
;;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
 
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
; nop ;bocsh fix
; pop edx
; pop eax