kolibrios-fun/kernel/trunk/core/memory.inc
Sergey Semyonov (Serge) c3f06c82fb rename pages_tab -> page_tabs
git-svn-id: svn://kolibrios.org@365 a494cfbc-eb01-0410-851d-a64ba20cac60
2007-02-20 12:05:24 +00:00

1663 lines
35 KiB
PHP

tmp_page_tab equ HEAP_BASE
align 4
proc mem_test
mov eax, cr0
and eax, not (CR0_CD+CR0_NW)
or eax, CR0_CD ;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
mov [MEM_AMOUNT], edi
and eax, not (CR0_CD+CR0_NW) ;enable caching
mov cr0, eax
mov eax, edi
mov [LFBSize], 0x00800000
ret
endp
align 4
proc init_mem
mov eax, [MEM_AMOUNT]
mov [pg_data.mem_amount], eax
mov [pg_data.kernel_max], eax
shr eax, 12
mov edx, eax
mov [pg_data.pages_count], eax
mov [pg_data.kernel_pages], eax
shr eax, 3
mov [pg_data.pagemap_size], eax
shr edx, 10
cmp edx, 3
ja @f
inc edx ;at least 4Mb for kernel heap
@@:
mov [pg_data.kernel_tables], edx
xor eax, eax
mov edi, sys_pgdir
mov ecx, 2048
cld
rep stosd
mov edx, sys_pgdir
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
sub [pg_data.kernel_tables], 2
mov [edx], eax
add eax, 0x00400000
mov [edx+4], eax
add edx, 8
mov eax, 0x800000+PG_SW
mov ecx, (HEAP_BASE-0x800000)/4096
jmp .map_low
.no_PSE:
mov eax, PG_SW
mov ecx, HEAP_BASE/4096
.map_low:
mov edi, tmp_page_tab
@@: ;
stosd
add eax, 0x1000
dec ecx
jnz @B
mov ecx, [pg_data.kernel_tables]
shl ecx, 10
xor eax, eax
rep stosd
mov ecx, [pg_data.kernel_tables]
mov eax, tmp_page_tab+PG_SW
mov edi, edx
.map_kernel_tabs:
stosd
add eax, 0x1000
dec ecx
jnz .map_kernel_tabs
mov dword [sys_pgdir+0x600], sys_pgdir+PG_SW
ret
endp
align 4
proc init_page_map
mov edi, sys_pgmap
mov ecx, (HEAP_BASE/4096)/32 ;384/4
mov ebx, ecx
xor eax,eax
cld
rep stosd
not eax
mov ecx, [pg_data.pagemap_size]
sub ecx, ebx
shr ecx, 2
rep stosd
lea edi, [sys_pgmap+ebx*4] ;+384
mov edx, [pg_data.pages_count]
mov ecx, [pg_data.kernel_tables]
add ecx, (HEAP_BASE/4096) and 31
sub edx, HEAP_BASE/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
mov [page_start], edi; sys_pgmap+384
stosd
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
lea eax, [eax+ebx*8]
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
push ebx
mov eax, [phis_addr]
and eax, not 0xFFF
or eax, [flags]
mov ebx, [lin_addr]
shr ebx, 12
mov [page_tabs+ebx*4], eax
mov eax, [lin_addr]
invlpg [eax]
pop ebx
ret
endp
align 4
map_space: ;not implemented
ret
align 4
proc free_page
;arg: eax page address
pushfd
cli
shr eax, 12 ;page index
mov ebx, sys_pgmap
bts [ebx], eax ;that's all!
cmc
adc [pg_data.pages_free], 0
shr eax, 3
and eax, not 3 ;dword offset from page_map
add eax, ebx
cmp [page_start], eax
ja @f
popfd
ret
@@:
mov [page_start], eax
popfd
ret
endp
; param
; eax= page base + page flags
; ebx= liear address
; ecx= count
align 4
commit_pages:
test ecx, ecx
jz .fail
mov edi, ebx
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
mov edx, 0x1000
mov ebx, edi
shr ebx, 12
@@:
mov [page_tabs+ebx*4], eax
invlpg [edi]
add edi, edx
add eax, edx
inc ebx
dec ecx
jnz @B
mov [pg_data.pg_mutex],ecx
.fail:
ret
; param
; eax= base
; ecx= count
align 4
release_pages:
pushad
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
mov esi, eax
mov edi, eax
shr esi, 10
add esi, page_tabs
mov ebp, [pg_data.pages_free]
mov ebx, [page_start]
mov edx, sys_pgmap
@@:
xor eax, eax
xchg eax, [esi]
invlpg [edi]
test eax, 1
jz .next
shr eax, 12
bts [edx], eax
cmc
adc ebp, 0
shr eax, 3
and eax, -4
add eax, edx
cmp eax, ebx
jae .next
mov ebx, eax
.next:
add edi, 0x1000
add esi, 4
dec ecx
jnz @B
mov [pg_data.pages_free], ebp
and [pg_data.pg_mutex],0
popad
ret
align 4
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
push ebx
mov ebx, [lin_addr]
shr ebx, 22
mov eax, [phis_addr]
and eax, not 0xFFF
or eax, PG_UW ;+PG_NOCACHE
mov dword [current_pgdir+ebx*4], eax
mov eax, [lin_addr]
shr eax, 10
add eax, page_tabs
invlpg [eax]
pop ebx
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
jnz @f
mov [0x2f0000+0x901c],byte 2
ret
@@:
call map_LFB
ret
endp
align 4
proc map_LFB
locals
pg_count dd ?
endl
mov edi, [LFBSize]
mov esi, [LFBAddress]
mov dword [exp_lfb+4], esi
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
bt [cpu_caps], CAPS_PGE
jnc @F
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, page_tabs
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
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
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, [page_tabs+0x00181000+edi*4]
test eax, 1
jz .next
mov dword [page_tabs+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]
call update_mem_size
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, page_tabs
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
jb @B
jmp .update_size
.exit:
xor eax, eax
inc eax
dec [pg_data.pg_mutex]
ret
endp
update_mem_size:
; in: edx = slot shl 8
; ebx = new memory size
; destroys eax,ecx,edx
mov [PROC_BASE+APPDATA.mem_size+edx],ebx
;search threads and update
;application memory size infomation
mov ecx,[PROC_BASE+APPDATA.dir_table+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+TASKDATA.state],9 ;if slot empty?
jz .search_threads_next
shl edx,3
cmp [PROC_BASE+edx+APPDATA.dir_table],ecx ;if it is our thread?
jnz .search_threads_next
mov [PROC_BASE+edx+APPDATA.mem_size],ebx ;update memory size
.search_threads_next:
inc eax
jmp .search_threads
.search_threads_end:
ret
; param
; eax= linear address
;
; retval
; eax= phisical page address
align 4
get_pg_addr:
shr eax, 12
mov eax, [page_tabs+eax*4]
and eax, 0xFFFFF000
ret
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, [page_tabs+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, [page_tabs+ebx*4]
; shr ebx, 10
; mov eax, [master_tab+ebx*4]
jmp .exit
.old_addr:
; shr ebx, 12
; mov eax, [page_tabs+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, [page_tabs+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 [page_tabs+ebx*4], eax
invlpg [edx]
mov ebx, [ipc_pdir]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [page_tabs+ebx*4], eax
invlpg [edx]
mov ebx, [ipc_ptab]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [page_tabs+ebx*4], eax
invlpg [edx]
mov eax, [dst_slot]
shl eax, 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_event_ex, ebx, ecx
mov [esp+36], eax
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 .fail
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 test_cpu
locals
cpu_type dd ?
cpu_id dd ?
cpu_Intel dd ?
cpu_AMD dd ?
endl
mov [cpu_type], 0
xor eax, eax
mov [cpu_caps], eax
mov [cpu_caps+4], eax
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_cpuid
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_cpuid
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
ret
.end_cpuid:
mov eax, [cpu_type]
ret
.check_AMD:
cmp ebx, dword [AMD_str]
jne .unknown
cmp edx, dword [AMD_str+4]
jne .unknown
cmp ecx, dword [AMD_str+8]
jne .unknown
mov [cpu_AMD], 1
cmp eax, 1
jl .unknown
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
ret
.unknown:
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
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
bt [cpu_caps], CAPS_MTRR
jnc .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
fdd_buff rd 1
LFBSize rd 1
stall_mcs rd 1
;;CPUID information
cpu_vendor rd 3
cpu_sign rd 1
cpu_info rd 1
;;;;; cursors data
align 16
cur_saved_data rb 4096
def_cursor rd 1
hw_cursor rd 1
scr_width rd 1
scr_height rd 1
cur_def_interl rd 1
cur_saved_base rd 1
cur_saved_interl rd 1
cur_saved_w rd 1
cur_saved_h rd 1
endg
uglobal
align 16
fpu_data:
rb 512
mst MEM_STATE
mem_block_map rb 512
event_map rb 64
mem_block_list rd 64
mem_block_mask rd 2
srv.fd rd 1
srv.bk rd 1
mem_used.fd rd 1
mem_used.bk rd 1
mem_block_arr rd 1
mem_block_start rd 1
mem_block_end rd 1
heap_mutex rd 1
heap_size rd 1
heap_free rd 1
heap_blocks rd 1
free_blocks rd 1
page_start rd 1
page_end rd 1
events rd 1
event_start rd 1
event_end rd 1
event_uid rd 1
sys_page_map rd 1
os_stack rd 1
endg
if 0
push eax
push edx
mov edx, 0x400 ;bocsh
mov al,0xff ;bocsh
out dx, al ;bocsh
pop edx
pop eax
end if
align 4
k_strrchr:
push eax
xor eax,eax
or ecx,-1
repne scasb
add ecx,1
neg ecx
sub edi,1
pop eax
std
repne scasb
cld
add edi,1
cmp [edi],al
jne @F
mov eax,edi
ret
@@:
xor eax,eax
ret
align 4
proc k_strncpy stdcall, dest:dword, src:dword, maxlen:dword
mov eax, [dest]
mov esi, [src]
mov ecx, [maxlen]
test eax, eax
jz .L9
test esi, esi
jz .L9
test ecx, ecx
jz .L9
sub esi, eax
jmp .L1
align 4
.L2:
mov edx, [esi+eax]
mov [eax], dl
test dl, dl
jz .L7
mov [eax+1], dh
test dh, dh
jz .L6
shr edx, 16
mov [eax+2],dl
test dl, dl
jz .L5
mov [eax+3], dh
test dh, dh
jz .L4
add eax, 4
.L1:
sub ecx, 4
jae .L2
add ecx, 4
jz .L9
mov dl, [eax+esi]
mov [eax], dl
test dl, dl
jz .L3
inc eax
dec ecx
jz .L9
mov dl, [eax+esi]
mov [eax], dl
test dl, dl
jz .L3
inc eax
dec ecx
jz .L9
mov dl, [eax+esi]
mov [eax], dl
test dl, dl
jz .L3
inc eax
jmp .L9
.L4: dec ecx
inc eax
.L5: dec ecx
inc eax
.L6: dec ecx
inc eax
.L7:
add ecx,3
jz .L9
.L8:
mov byte [ecx+eax], 0
.L3:
dec ecx
jnz .L8
.L9:
ret
endp
if 0
magic equ 0xfefefeff
k_strlen:
mov eax,[esp+4]
mov edx, 3
and edx, eax
jz .L1
jp .L0
cmp dh, byte [eax]
je .L2
inc eax
cmp dh, byte [eax]
je .L2
inc eax
xor edx, 2
jz .L1
.L0:
cmp dh, [eax]
je .L2
inc eax
xor edx, edx
.L1:
mov ecx, [eax]
add eax, 4
sub edx, ecx
add ecx, magic
dec edx
jnc .L3
xor edx, ecx
and edx, not magic
jne .L3
mov ecx, [eax]
add eax, 4
sub edx, ecx
add ecx, magic
dec edx
jnc .L3
xor edx, ecx
and edx, not magic
jne .L3
mov ecx, [eax]
add eax, 4
sub edx, ecx
add ecx, magic
dec edx
jnc .L3
xor edx, ecx
and edx, not magic
jne .L3
mov ecx, [eax]
add eax, 4
sub edx, ecx
add ecx, magic
dec edx
jnc .L3
xor edx, ecx
and edx, not magic
je .L1
.L3: sub eax ,4
sub ecx, magic
cmp cl, 0
jz .L2
inc eax
test ch, ch
jz .L2
shr ecx, 16
inc eax
cmp cl,0
jz .L2
inc eax
.L2:
sub eax, [esp+4]
ret
end if