forked from KolibriOS/kolibrios
merge trunk
git-svn-id: svn://kolibrios.org@2130 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
246c135659
commit
836a2f71bd
@ -645,7 +645,7 @@ virtual at 0
|
||||
end virtual
|
||||
|
||||
struc MEM_STATE
|
||||
{ .mutex rd 1
|
||||
{ .mutex MUTEX
|
||||
.smallmap rd 1
|
||||
.treemap rd 1
|
||||
.topsize rd 1
|
||||
@ -664,7 +664,7 @@ struc PG_DATA
|
||||
.kernel_pages dd ?
|
||||
.kernel_tables dd ?
|
||||
.sys_page_dir dd ?
|
||||
.pg_mutex dd ?
|
||||
.mutex MUTEX
|
||||
}
|
||||
|
||||
;struc LIB
|
||||
|
@ -5,7 +5,7 @@
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
IRQ_RESERVE = 24 ; 16 or 24
|
||||
IRQ_RESERVED = 24 ; 16 or 24
|
||||
|
||||
iglobal
|
||||
IRQ_COUNT dd 24
|
||||
@ -62,10 +62,11 @@ APIC_init:
|
||||
shr eax, 16
|
||||
inc al
|
||||
movzx eax, al
|
||||
cmp al, IRQ_RESERVE
|
||||
cmp al, IRQ_RESERVED
|
||||
jbe @f
|
||||
mov al, IRQ_RESERVE
|
||||
@@: mov [IRQ_COUNT], eax
|
||||
mov al, IRQ_RESERVED
|
||||
@@:
|
||||
mov [IRQ_COUNT], eax
|
||||
|
||||
; Reroute IOAPIC & mask all interrupts
|
||||
xor ecx, ecx
|
||||
@ -106,7 +107,7 @@ APIC_init:
|
||||
|
||||
;init handlers table
|
||||
|
||||
mov ecx, IRQ_RESERVE
|
||||
mov ecx, IRQ_RESERVED
|
||||
mov edi, irqh_tab
|
||||
@@:
|
||||
mov eax, edi
|
||||
|
@ -85,6 +85,13 @@ iglobal
|
||||
szStrchr db 'strchr',0
|
||||
szStrrchr db 'strrchr',0
|
||||
|
||||
szDiskAdd db 'DiskAdd',0
|
||||
szDiskDel db 'DiskDel',0
|
||||
szDiskMediaChanged db 'DiskMediaChanged',0
|
||||
|
||||
szTimerHS db 'TimerHS',0
|
||||
szCancelTimerHS db 'CancelTimerHS',0
|
||||
|
||||
|
||||
align 16
|
||||
kernel_export:
|
||||
|
@ -151,7 +151,8 @@ proc init_kernel_heap
|
||||
|
||||
mov [mem_block_list+63*4], ebx
|
||||
mov byte [mem_block_map], 0xFC
|
||||
and [heap_mutex], 0
|
||||
mov ecx, heap_mutex
|
||||
call mutex_init
|
||||
mov [heap_blocks], 4095
|
||||
mov [free_blocks], 4094
|
||||
ret
|
||||
@ -272,14 +273,14 @@ proc alloc_kernel_space stdcall, size:dword
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov ecx, heap_mutex
|
||||
call mutex_lock
|
||||
|
||||
mov eax, [size]
|
||||
add eax, 4095
|
||||
and eax, not 4095
|
||||
mov [size], eax
|
||||
|
||||
mov ebx, heap_mutex
|
||||
call wait_mutex ;ebx
|
||||
|
||||
cmp eax, [heap_free]
|
||||
ja .error
|
||||
|
||||
@ -355,10 +356,11 @@ proc alloc_kernel_space stdcall, size:dword
|
||||
mov [edx+list_bk], esi
|
||||
|
||||
mov [esi+block_flags], USED_BLOCK
|
||||
mov eax, [esi+block_base]
|
||||
mov ebx, [size]
|
||||
sub [heap_free], ebx
|
||||
and [heap_mutex], 0
|
||||
mov ecx, heap_mutex
|
||||
call mutex_unlock
|
||||
mov eax, [esi+block_base]
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
@ -378,17 +380,19 @@ proc alloc_kernel_space stdcall, size:dword
|
||||
mov [edx+list_bk], edi
|
||||
|
||||
mov [edi+block_flags], USED_BLOCK
|
||||
mov eax, [edi+block_base]
|
||||
mov ebx, [size]
|
||||
sub [heap_free], ebx
|
||||
and [heap_mutex], 0
|
||||
mov ecx, heap_mutex
|
||||
call mutex_unlock
|
||||
mov eax, [edi+block_base]
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
ret
|
||||
.error:
|
||||
mov ecx, heap_mutex
|
||||
call mutex_unlock
|
||||
xor eax, eax
|
||||
mov [heap_mutex], eax
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
@ -400,8 +404,9 @@ proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
mov ebx, heap_mutex
|
||||
call wait_mutex ;ebx
|
||||
|
||||
mov ecx, heap_mutex
|
||||
call mutex_lock
|
||||
|
||||
mov eax, [base]
|
||||
mov esi, [mem_used.fd]
|
||||
@ -491,9 +496,10 @@ proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
|
||||
@@:
|
||||
bts [mem_block_mask], eax
|
||||
.m_eq:
|
||||
mov ecx, heap_mutex
|
||||
call mutex_unlock
|
||||
xor eax, eax
|
||||
mov [heap_mutex], eax
|
||||
dec eax
|
||||
not eax
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
@ -513,16 +519,18 @@ proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
|
||||
@@:
|
||||
bts [mem_block_mask], eax
|
||||
mov [esi+block_flags],FREE_BLOCK
|
||||
mov ecx, heap_mutex
|
||||
call mutex_unlock
|
||||
xor eax, eax
|
||||
mov [heap_mutex], eax
|
||||
dec eax
|
||||
not eax
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
ret
|
||||
.fail:
|
||||
mov ecx, heap_mutex
|
||||
call mutex_unlock
|
||||
xor eax, eax
|
||||
mov [heap_mutex], eax
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
@ -607,8 +615,8 @@ align 4
|
||||
proc kernel_free stdcall, base:dword
|
||||
push ebx esi
|
||||
|
||||
mov ebx, heap_mutex
|
||||
call wait_mutex ;ebx
|
||||
mov ecx, heap_mutex
|
||||
call mutex_lock
|
||||
|
||||
mov eax, [base]
|
||||
mov esi, [mem_used.fd]
|
||||
@ -624,19 +632,17 @@ proc kernel_free stdcall, base:dword
|
||||
cmp [esi+block_flags], USED_BLOCK
|
||||
jne .fail
|
||||
|
||||
and [heap_mutex], 0
|
||||
call mutex_unlock
|
||||
|
||||
push ecx
|
||||
mov ecx, [esi+block_size];
|
||||
shr ecx, 12
|
||||
call release_pages ;eax, ecx
|
||||
pop ecx
|
||||
stdcall free_kernel_space, [base]
|
||||
pop esi ebx
|
||||
ret
|
||||
.fail:
|
||||
call mutex_unlock
|
||||
xor eax, eax
|
||||
mov [heap_mutex], eax
|
||||
pop esi ebx
|
||||
ret
|
||||
endp
|
||||
|
@ -5,6 +5,10 @@
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
IRQ_POOL_SIZE equ 48
|
||||
|
||||
|
||||
macro __list_add new, prev, next
|
||||
{
|
||||
mov [next+LHEAD.prev], new
|
||||
@ -28,13 +32,13 @@ macro list_add_tail new, head
|
||||
uglobal
|
||||
|
||||
align 16
|
||||
irqh_tab rd LHEAD.sizeof * IRQ_RESERVE / 4
|
||||
irqh_tab rd LHEAD.sizeof * IRQ_RESERVED / 4
|
||||
|
||||
irqh_pool rd IRQH.sizeof *48 /4
|
||||
irqh_pool rd IRQH.sizeof * IRQ_POOL_SIZE /4
|
||||
next_irqh rd 1
|
||||
|
||||
irq_active_set rd 1
|
||||
irq_failed rd IRQ_RESERVE
|
||||
irq_failed rd IRQ_RESERVED
|
||||
|
||||
endg
|
||||
|
||||
@ -44,8 +48,6 @@ proc attach_int_handler stdcall, irq:dword, handler:dword, user_data:dword
|
||||
.irqh dd ?
|
||||
endl
|
||||
|
||||
xchg bx, bx
|
||||
|
||||
and [.irqh], 0
|
||||
|
||||
push ebx
|
||||
@ -54,7 +56,7 @@ proc attach_int_handler stdcall, irq:dword, handler:dword, user_data:dword
|
||||
test ebx, ebx
|
||||
jz .err
|
||||
|
||||
cmp ebx, IRQ_RESERVE
|
||||
cmp ebx, IRQ_RESERVED
|
||||
jae .err
|
||||
|
||||
mov edx, [handler]
|
||||
@ -72,17 +74,17 @@ proc attach_int_handler stdcall, irq:dword, handler:dword, user_data:dword
|
||||
|
||||
mov eax, [ecx]
|
||||
mov [next_irqh], eax
|
||||
|
||||
mov [.irqh], ecx
|
||||
|
||||
mov [irq_failed+ebx*4], 0 ;clear counter
|
||||
|
||||
mov eax, [user_data]
|
||||
mov [ecx+IRQH.handler], edx
|
||||
mov [ecx+IRQH.data], eax
|
||||
|
||||
lea edx, [irqh_tab+ebx*8]
|
||||
list_add_tail ecx, edx ;clobber eax
|
||||
|
||||
stdcall enable_irq, [irq]
|
||||
stdcall enable_irq, ebx
|
||||
|
||||
.fail:
|
||||
popfd
|
||||
@ -116,7 +118,6 @@ proc detach_int_handler
|
||||
endp
|
||||
|
||||
|
||||
|
||||
macro irq_serv_h [num] {
|
||||
forward
|
||||
align 4
|
||||
@ -142,8 +143,6 @@ align 16
|
||||
.main:
|
||||
save_ring3_context
|
||||
|
||||
xchg bx, bx
|
||||
|
||||
mov ebp, [esp + 32]
|
||||
mov bx, app_data ;os_data
|
||||
mov ds, bx
|
||||
@ -212,4 +211,15 @@ align 16
|
||||
add esp, 4
|
||||
iret
|
||||
|
||||
align 4
|
||||
irqD:
|
||||
push eax
|
||||
push ecx
|
||||
xor eax,eax
|
||||
out 0xf0,al
|
||||
mov eax, 13
|
||||
call IRQ_EOI
|
||||
pop ecx
|
||||
pop eax
|
||||
iret
|
||||
|
||||
|
@ -20,7 +20,7 @@ $Revision$
|
||||
; esi= nb
|
||||
; ebx= idx
|
||||
;
|
||||
align 16
|
||||
align 4
|
||||
malloc:
|
||||
push esi
|
||||
|
||||
@ -31,8 +31,8 @@ malloc:
|
||||
and esi, -8
|
||||
add esi, 8
|
||||
|
||||
mov ebx, mst.mutex
|
||||
call wait_mutex ;ebx
|
||||
mov ecx, mst.mutex
|
||||
call mutex_lock
|
||||
|
||||
cmp esi, 256
|
||||
jae .large
|
||||
@ -92,9 +92,13 @@ malloc:
|
||||
pop edi
|
||||
pop ebp
|
||||
.done:
|
||||
mov esi, eax
|
||||
mov ecx, mst.mutex
|
||||
call mutex_unlock
|
||||
mov eax, esi
|
||||
pop esi
|
||||
mov [mst.mutex], 0
|
||||
ret
|
||||
|
||||
.split:
|
||||
lea ebx, [edx+8] ;ebx=mem
|
||||
|
||||
@ -133,10 +137,10 @@ malloc:
|
||||
mov [edx+12], eax ; F->bk = r;
|
||||
mov [eax+8], edx ; r->fd = F;
|
||||
mov [eax+12], ecx ; r->bk = B;
|
||||
|
||||
mov eax, ebx
|
||||
pop esi
|
||||
mov [mst.mutex], 0
|
||||
ret
|
||||
jmp .done
|
||||
|
||||
.small:
|
||||
|
||||
; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0)
|
||||
@ -150,9 +154,8 @@ malloc:
|
||||
call malloc_small
|
||||
test eax, eax
|
||||
jz .from_top
|
||||
pop esi
|
||||
and [mst.mutex], 0
|
||||
ret
|
||||
jmp .done
|
||||
|
||||
.large:
|
||||
|
||||
; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0)
|
||||
@ -189,18 +192,15 @@ malloc:
|
||||
mov [edx+4], eax
|
||||
mov [ecx+4], esi
|
||||
lea eax, [ecx+8]
|
||||
pop esi
|
||||
and [mst.mutex], 0
|
||||
ret
|
||||
jmp .done
|
||||
|
||||
.fail:
|
||||
xor eax, eax
|
||||
pop esi
|
||||
and [mst.mutex], 0
|
||||
ret
|
||||
jmp .done
|
||||
|
||||
; param
|
||||
; eax= mem
|
||||
|
||||
align 4
|
||||
free:
|
||||
push edi
|
||||
mov edi, eax
|
||||
@ -211,8 +211,8 @@ free:
|
||||
test byte [edi+4], 2
|
||||
je .fail
|
||||
|
||||
mov ebx, mst.mutex
|
||||
call wait_mutex ;ebx
|
||||
mov ecx, mst.mutex
|
||||
call mutex_lock
|
||||
|
||||
; psize = p->head & (~3);
|
||||
|
||||
@ -289,7 +289,10 @@ free:
|
||||
mov [mst.top], edi
|
||||
mov [edi+4], eax
|
||||
.fail2:
|
||||
and [mst.mutex], 0
|
||||
mov esi, eax
|
||||
mov ecx, mst.mutex
|
||||
call mutex_unlock
|
||||
mov eax, esi
|
||||
pop esi
|
||||
.fail:
|
||||
pop edi
|
||||
@ -410,13 +413,15 @@ insert_chunk:
|
||||
mov [esi+8], edx ;P->fd = F
|
||||
mov [esi+12], eax ;P->bk = B
|
||||
pop esi
|
||||
and [mst.mutex], 0
|
||||
mov ecx, mst.mutex
|
||||
call mutex_unlock
|
||||
ret
|
||||
.large:
|
||||
mov ebx, eax
|
||||
call insert_large_chunk
|
||||
pop esi
|
||||
and [mst.mutex], 0
|
||||
mov ecx, mst.mutex
|
||||
call mutex_unlock
|
||||
ret
|
||||
|
||||
|
||||
@ -1025,5 +1030,8 @@ init_malloc:
|
||||
cmp eax, mst.smallbins+512
|
||||
jb @B
|
||||
|
||||
mov ecx, mst.mutex
|
||||
call mutex_init
|
||||
|
||||
ret
|
||||
|
||||
|
@ -214,30 +214,32 @@ endp
|
||||
|
||||
align 4
|
||||
commit_pages:
|
||||
push edi
|
||||
test ecx, ecx
|
||||
jz .fail
|
||||
|
||||
mov edi, ebx
|
||||
mov ebx, pg_data.pg_mutex
|
||||
call wait_mutex ;ebx
|
||||
push edi
|
||||
push eax
|
||||
push ecx
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_lock
|
||||
pop ecx
|
||||
pop eax
|
||||
|
||||
mov edx, 0x1000
|
||||
mov ebx, edi
|
||||
shr ebx, 12
|
||||
mov edi, ebx
|
||||
shr edi, 12
|
||||
lea edi, [page_tabs+edi*4]
|
||||
@@:
|
||||
mov [page_tabs+ebx*4], eax
|
||||
; push eax
|
||||
invlpg [edi]
|
||||
; pop eax
|
||||
add edi, edx
|
||||
add eax, edx
|
||||
inc ebx
|
||||
dec ecx
|
||||
jnz @B
|
||||
mov [pg_data.pg_mutex],ecx
|
||||
.fail:
|
||||
stosd
|
||||
invlpg [ebx]
|
||||
add eax, 0x1000
|
||||
add ebx, 0x1000
|
||||
loop @B
|
||||
|
||||
pop edi
|
||||
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_unlock
|
||||
.fail:
|
||||
ret
|
||||
|
||||
|
||||
@ -248,15 +250,21 @@ commit_pages:
|
||||
align 4
|
||||
release_pages:
|
||||
|
||||
pushad
|
||||
mov ebx, pg_data.pg_mutex
|
||||
call wait_mutex ;ebx
|
||||
push ebp
|
||||
push esi
|
||||
push edi
|
||||
push ebx
|
||||
|
||||
mov esi, eax
|
||||
mov edi, eax
|
||||
|
||||
shr esi, 10
|
||||
add esi, page_tabs
|
||||
shr esi, 12
|
||||
lea esi, [page_tabs+esi*4]
|
||||
|
||||
push ecx
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_lock
|
||||
pop ecx
|
||||
|
||||
mov ebp, [pg_data.pages_free]
|
||||
mov ebx, [page_start]
|
||||
@ -264,9 +272,7 @@ release_pages:
|
||||
@@:
|
||||
xor eax, eax
|
||||
xchg eax, [esi]
|
||||
push eax
|
||||
invlpg [edi]
|
||||
pop eax
|
||||
|
||||
test eax, 1
|
||||
jz .next
|
||||
@ -285,11 +291,16 @@ release_pages:
|
||||
.next:
|
||||
add edi, 0x1000
|
||||
add esi, 4
|
||||
dec ecx
|
||||
jnz @B
|
||||
loop @B
|
||||
|
||||
mov [pg_data.pages_free], ebp
|
||||
and [pg_data.pg_mutex],0
|
||||
popad
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_unlock
|
||||
|
||||
pop ebx
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
; param
|
||||
@ -423,8 +434,8 @@ endp
|
||||
align 4
|
||||
proc new_mem_resize stdcall, new_size:dword
|
||||
|
||||
mov ebx, pg_data.pg_mutex
|
||||
call wait_mutex ;ebx
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_lock
|
||||
|
||||
mov edi, [new_size]
|
||||
add edi,4095
|
||||
@ -464,8 +475,10 @@ proc new_mem_resize stdcall, new_size:dword
|
||||
mov ebx, [new_size]
|
||||
call update_mem_size
|
||||
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_unlock
|
||||
|
||||
xor eax, eax
|
||||
dec [pg_data.pg_mutex]
|
||||
ret
|
||||
.expand:
|
||||
|
||||
@ -539,9 +552,11 @@ proc new_mem_resize stdcall, new_size:dword
|
||||
pop edi
|
||||
pop esi
|
||||
.exit:
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_unlock
|
||||
|
||||
xor eax, eax
|
||||
inc eax
|
||||
dec [pg_data.pg_mutex]
|
||||
ret
|
||||
endp
|
||||
|
||||
|
@ -54,7 +54,7 @@ iglobal
|
||||
dd irq_serv.irq_22
|
||||
dd irq_serv.irq_23
|
||||
|
||||
times 32 - IRQ_RESERVE dd unknown_interrupt
|
||||
times 32 - IRQ_RESERVED dd unknown_interrupt
|
||||
;int_0x40 gate trap (for directly copied)
|
||||
dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16
|
||||
|
||||
@ -245,18 +245,6 @@ show_error_parameters:
|
||||
restore reg_edi
|
||||
|
||||
|
||||
align 4
|
||||
irqD:
|
||||
push eax
|
||||
xor eax,eax
|
||||
out 0xf0,al
|
||||
mov al,0x20
|
||||
out 0xa0,al
|
||||
out 0x20,al
|
||||
pop eax
|
||||
iret
|
||||
|
||||
|
||||
align 4
|
||||
set_application_table_status:
|
||||
push eax
|
||||
@ -682,8 +670,13 @@ term9:
|
||||
restore .slot
|
||||
|
||||
iglobal
|
||||
if lang eq ru
|
||||
boot_sched_1 db '‘®§¤ ¨¥ GDT TSS 㪠§ ⥫ï',0
|
||||
boot_sched_2 db '‘®§¤ ¨¥ IDT â ¡«¨æë',0
|
||||
else
|
||||
boot_sched_1 db 'Building gdt tss pointer',0
|
||||
boot_sched_2 db 'Building IDT table',0
|
||||
end if
|
||||
endg
|
||||
|
||||
|
||||
|
@ -360,8 +360,8 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
|
||||
app_tabs dd ?
|
||||
endl
|
||||
|
||||
mov ebx, pg_data.pg_mutex
|
||||
call wait_mutex ;ebx
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_lock
|
||||
|
||||
xor eax, eax
|
||||
mov [dir_addr], eax
|
||||
@ -387,11 +387,11 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
|
||||
shr ecx, 12
|
||||
mov [img_pages], ecx
|
||||
|
||||
if GREEDY_KERNEL
|
||||
if GREEDY_KERNEL
|
||||
lea eax, [ecx+ebx+2] ;only image size
|
||||
else
|
||||
else
|
||||
lea eax, [eax+ebx+2] ;all requested memory
|
||||
end if
|
||||
end if
|
||||
cmp eax, [pg_data.pages_free]
|
||||
ja .fail
|
||||
|
||||
@ -480,11 +480,13 @@ end if
|
||||
.done:
|
||||
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
|
||||
|
||||
dec [pg_data.pg_mutex]
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_unlock
|
||||
mov eax, [dir_addr]
|
||||
ret
|
||||
.fail:
|
||||
dec [pg_data.pg_mutex]
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_unlock
|
||||
cmp [dir_addr], 0
|
||||
je @f
|
||||
stdcall destroy_app_space, [dir_addr], 0
|
||||
@ -554,10 +556,10 @@ proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword
|
||||
jg .ret
|
||||
;if there isn't threads then clear memory.
|
||||
mov esi, [dlls_list]
|
||||
call destroy_all_hdlls
|
||||
call destroy_all_hdlls ;ecx=APPDATA
|
||||
|
||||
mov ebx, pg_data.pg_mutex
|
||||
call wait_mutex ;ebx
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_lock
|
||||
|
||||
mov eax, [pg_dir]
|
||||
and eax, not 0xFFF
|
||||
@ -583,7 +585,8 @@ proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword
|
||||
.exit:
|
||||
stdcall map_page,[tmp_task_ptab],0,PG_UNMAP
|
||||
stdcall map_page,[tmp_task_pdir],0,PG_UNMAP
|
||||
dec [pg_data.pg_mutex]
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_unlock
|
||||
.ret:
|
||||
ret
|
||||
endp
|
||||
@ -956,24 +959,6 @@ proc new_sys_threads
|
||||
ret
|
||||
endp
|
||||
|
||||
; param
|
||||
; ebx=mutex
|
||||
|
||||
align 4
|
||||
wait_mutex:
|
||||
;;Maxis use atomic bts for mutex 4.4.2009
|
||||
push eax
|
||||
push ebx
|
||||
.do_wait:
|
||||
bts dword [ebx],0
|
||||
jnc .locked
|
||||
call change_task
|
||||
jmp .do_wait
|
||||
.locked:
|
||||
pop ebx
|
||||
pop eax
|
||||
ret
|
||||
|
||||
align 4
|
||||
tls_app_entry:
|
||||
|
||||
|
205
kernel/branches/Kolibri-acpi/core/timers.inc
Normal file
205
kernel/branches/Kolibri-acpi/core/timers.inc
Normal file
@ -0,0 +1,205 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2011. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 2122 $
|
||||
|
||||
; Simple implementation of timers. All timers are organized in a double-linked
|
||||
; list, and the OS loop after every timer tick processes the list.
|
||||
|
||||
; This structure describes a timer for the kernel.
|
||||
struct TIMER
|
||||
.Next dd ?
|
||||
.Prev dd ?
|
||||
; These fields organize a double-linked list of all timers.
|
||||
.TimerFunc dd ?
|
||||
; Function to be called when the timer is activated.
|
||||
.UserData dd ?
|
||||
; The value that is passed as is to .TimerFunc.
|
||||
.Time dd ?
|
||||
; Time at which the timer should be activated.
|
||||
.Interval dd ?
|
||||
; Interval between activations of the timer, in 0.01s.
|
||||
ends
|
||||
|
||||
iglobal
|
||||
align 4
|
||||
; The head of timer list.
|
||||
timer_list:
|
||||
dd timer_list
|
||||
dd timer_list
|
||||
endg
|
||||
uglobal
|
||||
; These two variables are used to synchronize access to the global list.
|
||||
; Logically, they form an recursive mutex. Physically, the first variable holds
|
||||
; the slot number of the current owner or 0, the second variable holds the
|
||||
; recursion count.
|
||||
; The mutex should be recursive to allow a timer function to add/delete other
|
||||
; timers or itself.
|
||||
timer_list_owner dd 0
|
||||
timer_list_numlocks dd 0
|
||||
; A timer function can delete any timer, including itself and the next timer in
|
||||
; the chain. To handle such situation correctly, we keep the next timer in a
|
||||
; global variable, so the removing operation can update it.
|
||||
timer_next dd 0
|
||||
endg
|
||||
|
||||
; This internal function acquires the lock for the global list.
|
||||
lock_timer_list:
|
||||
mov edx, [CURRENT_TASK]
|
||||
@@:
|
||||
xor eax, eax
|
||||
lock cmpxchg [timer_list_owner], edx
|
||||
jz @f
|
||||
cmp eax, edx
|
||||
jz @f
|
||||
call change_task
|
||||
jmp @b
|
||||
@@:
|
||||
inc [timer_list_numlocks]
|
||||
ret
|
||||
|
||||
; This internal function releases the lock for the global list.
|
||||
unlock_timer_list:
|
||||
dec [timer_list_numlocks]
|
||||
jnz .nothing
|
||||
mov [timer_list_owner], 0
|
||||
.nothing:
|
||||
ret
|
||||
|
||||
; This function adds a timer.
|
||||
; If deltaStart is nonzero, the timer is activated after deltaStart hundredths
|
||||
; of seconds starting from the current time. If interval is nonzero, the timer
|
||||
; is activated every deltaWork hundredths of seconds starting from the first
|
||||
; activation. The activated timer calls timerFunc as stdcall function with one
|
||||
; argument userData.
|
||||
; Return value is NULL if something has failed or some value which is opaque
|
||||
; for the caller. Later this value can be used for cancel_timer_hs.
|
||||
proc timer_hs stdcall uses ebx, deltaStart:dword, interval:dword, \
|
||||
timerFunc:dword, userData:dword
|
||||
; 1. Allocate memory for the TIMER structure.
|
||||
; 1a. Call the allocator.
|
||||
push sizeof.TIMER
|
||||
pop eax
|
||||
call malloc
|
||||
; 1b. If allocation failed, return (go to 5) with eax = 0.
|
||||
test eax, eax
|
||||
jz .nothing
|
||||
; 2. Setup the TIMER structure.
|
||||
xchg ebx, eax
|
||||
; 2a. Copy values from the arguments.
|
||||
mov ecx, [interval]
|
||||
mov [ebx+TIMER.Interval], ecx
|
||||
mov ecx, [timerFunc]
|
||||
mov [ebx+TIMER.TimerFunc], ecx
|
||||
mov ecx, [userData]
|
||||
mov [ebx+TIMER.UserData], ecx
|
||||
; 2b. Get time of the next activation.
|
||||
mov ecx, [deltaStart]
|
||||
test ecx, ecx
|
||||
jnz @f
|
||||
mov ecx, [interval]
|
||||
@@:
|
||||
add ecx, [timer_ticks]
|
||||
mov [ebx+TIMER.Time], ecx
|
||||
; 3. Insert the TIMER structure to the global list.
|
||||
; 3a. Acquire the lock.
|
||||
call lock_timer_list
|
||||
; 3b. Insert an item at ebx to the tail of the timer_list.
|
||||
mov eax, timer_list
|
||||
mov ecx, [eax+TIMER.Prev]
|
||||
mov [ebx+TIMER.Next], eax
|
||||
mov [ebx+TIMER.Prev], ecx
|
||||
mov [eax+TIMER.Prev], ebx
|
||||
mov [ecx+TIMER.Next], ebx
|
||||
; 3c. Release the lock.
|
||||
call unlock_timer_list
|
||||
; 4. Return with eax = pointer to TIMER structure.
|
||||
xchg ebx, eax
|
||||
.nothing:
|
||||
; 5. Returning.
|
||||
ret
|
||||
endp
|
||||
|
||||
; This function removes a timer.
|
||||
; The only argument is [esp+4] = the value which was returned from timer_hs.
|
||||
cancel_timer_hs:
|
||||
push ebx ; save used register to be stdcall
|
||||
; 1. Remove the TIMER structure from the global list.
|
||||
; 1a. Acquire the lock.
|
||||
call lock_timer_list
|
||||
mov ebx, [esp+4+4]
|
||||
; 1b. Delete an item at ebx from the double-linked list.
|
||||
mov eax, [ebx+TIMER.Next]
|
||||
mov ecx, [ebx+TIMER.Prev]
|
||||
mov [eax+TIMER.Prev], ecx
|
||||
mov [ecx+TIMER.Next], eax
|
||||
; 1c. If we are removing the next timer in currently processing chain,
|
||||
; the next timer for this timer becomes new next timer.
|
||||
cmp ebx, [timer_next]
|
||||
jnz @f
|
||||
mov [timer_next], eax
|
||||
@@:
|
||||
; 1d. Release the lock.
|
||||
call unlock_timer_list
|
||||
; 2. Free the TIMER structure.
|
||||
xchg eax, ebx
|
||||
call free
|
||||
; 3. Return.
|
||||
pop ebx ; restore used register to be stdcall
|
||||
ret 4 ; purge one dword argument to be stdcall
|
||||
|
||||
; This function is regularly called from osloop. It processes the global list
|
||||
; and activates the corresponding timers.
|
||||
check_timers:
|
||||
; 1. Acquire the lock.
|
||||
call lock_timer_list
|
||||
; 2. Loop over all registered timers, checking time.
|
||||
; 2a. Get the first item.
|
||||
mov eax, [timer_list+TIMER.Next]
|
||||
mov [timer_next], eax
|
||||
.loop:
|
||||
; 2b. Check for end of list.
|
||||
cmp eax, timer_list
|
||||
jz .done
|
||||
; 2c. Get and store the next timer.
|
||||
mov edx, [eax+TIMER.Next]
|
||||
mov [timer_next], edx
|
||||
; 2d. Check time for timer activation.
|
||||
; We can't just compare [timer_ticks] and [TIMER.Time], since overflows are
|
||||
; possible: if the current time is 0FFFFFFFFh ticks and timer should be
|
||||
; activated in 3 ticks, the simple comparison will produce incorrect result.
|
||||
; So we calculate the difference [timer_ticks] - [TIMER.Time]; if it is
|
||||
; non-negative, the time is over; if it is negative, then either the time is
|
||||
; not over or we have not processed this timer for 2^31 ticks, what is very
|
||||
; unlikely.
|
||||
mov edx, [timer_ticks]
|
||||
sub edx, [eax+TIMER.Time]
|
||||
js .next
|
||||
; The timer should be activated now.
|
||||
; 2e. Store the timer data in the stack. This is required since 2f can delete
|
||||
; the timer, invalidating the content.
|
||||
push [eax+TIMER.UserData] ; parameter for TimerFunc
|
||||
push [eax+TIMER.TimerFunc] ; to be restored in 2g
|
||||
; 2f. Calculate time of next activation or delete the timer if it is one-shot.
|
||||
mov ecx, [eax+TIMER.Interval]
|
||||
add [eax+TIMER.Time], ecx
|
||||
test ecx, ecx
|
||||
jnz .nodelete
|
||||
stdcall cancel_timer_hs, eax
|
||||
.nodelete:
|
||||
; 2g. Activate timer, using data from the stack.
|
||||
pop eax
|
||||
call eax
|
||||
.next:
|
||||
; 2h. Advance to the next timer and continue the loop.
|
||||
mov eax, [timer_next]
|
||||
jmp .loop
|
||||
.done:
|
||||
; 3. Release the lock.
|
||||
call unlock_timer_list
|
||||
; 4. Return.
|
||||
ret
|
@ -328,7 +328,7 @@ v86_start:
|
||||
cmp edx, -1
|
||||
jz .noirqhook
|
||||
uglobal
|
||||
v86_irqhooks rd IRQ_RESERVE * 2
|
||||
v86_irqhooks rd IRQ_RESERVED * 2
|
||||
endg
|
||||
cmp [v86_irqhooks+edx*8], 0
|
||||
jz @f
|
||||
@ -839,6 +839,7 @@ end if
|
||||
; mov byte [BOOT_VAR + 48Eh], 0FFh
|
||||
; ret
|
||||
|
||||
align 4
|
||||
v86_irq:
|
||||
; push irq/pushad/jmp v86_irq
|
||||
; eax = irq
|
||||
|
@ -47,8 +47,34 @@ keymap_alt:
|
||||
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
|
||||
|
||||
boot_memdetect db 'Determining amount of memory',0
|
||||
|
||||
if lang eq ru
|
||||
boot_fonts db '˜à¨äâë § £à㦥ë',0
|
||||
boot_memdetect db 'Š®«¨ç¥á⢮ ®¯¥à ⨢®© ¯ ¬ïâ¨',' ',' Œ¡',0
|
||||
boot_tss db '“áâ ®¢ª TSSs',0
|
||||
boot_cpuid db '—⥨¥ CPUIDs',0
|
||||
boot_devices db '<27>®¨áª ãáâனáâ¢',0
|
||||
boot_timer db '“áâ ®¢ª â ©¬¥à ',0
|
||||
boot_irqs db '<27>¥à¥®¯à¥¤¥«¥¨¥ IRQ',0
|
||||
boot_setmouse db '“áâ ®¢ª ¬ëè¨',0
|
||||
boot_windefs db '“áâ ®¢ª áâ஥ª ®ª® ¯® 㬮«ç ¨î',0
|
||||
boot_bgr db '“áâ ®¢ª ä® ',0
|
||||
boot_resirqports db '<27>¥§¥à¢¨à®¢ ¨¥ IRQ ¨ ¯®à⮢',0
|
||||
boot_setrports db '“áâ ®¢ª ¤à¥á®¢ IRQ',0
|
||||
boot_setostask db '‘®§¤ ¨¥ ¯à®æ¥áá ï¤à ',0
|
||||
boot_allirqs db 'Žâªàë⨥ ¢á¥å IRQ',0
|
||||
boot_tsc db '—⥨¥ TSC',0
|
||||
boot_cpufreq db '— áâ®â ¯à®æ¥áá®à ',' ',' Œƒæ',0
|
||||
boot_pal_ega db '“áâ ®¢ª EGA/CGA 320x200 ¯ «¨âàë',0
|
||||
boot_pal_vga db '“áâ ®¢ª VGA 640x480 ¯ «¨âàë',0
|
||||
boot_failed db '‡ £à㧪 ¯¥à¢®£® ¯à¨«®¦¥¨ï ¥ 㤠« áì',0
|
||||
boot_mtrr db '“áâ ®¢ª MTRR',0
|
||||
if preboot_blogesc
|
||||
boot_tasking db '‚ᥠ£®â®¢® ¤«ï § ¯ã᪠, ¦¬¨âॠESC ¤«ï áâ àâ ',0
|
||||
end if
|
||||
else
|
||||
boot_fonts db 'Fonts loaded',0
|
||||
boot_memdetect db 'Determining amount of memory',0
|
||||
boot_tss db 'Setting TSSs',0
|
||||
boot_cpuid db 'Reading CPUIDs',0
|
||||
boot_devices db 'Detecting devices',0
|
||||
@ -63,12 +89,14 @@ keymap_alt:
|
||||
boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0
|
||||
boot_pal_vga db 'Setting VGA 640x480 palette',0
|
||||
boot_failed db 'Failed to start first app',0
|
||||
boot_APIC_found db 'APIC enabled', 0
|
||||
boot_APIC_nfound db 'APIC not found', 0
|
||||
|
||||
boot_mtrr db 'Setting MTRR',0
|
||||
if preboot_blogesc
|
||||
boot_tasking db 'All set - press ESC to start',0
|
||||
end if
|
||||
end if
|
||||
|
||||
boot_APIC_found db 'APIC enabled', 0
|
||||
boot_APIC_nfound db 'APIC not found', 0
|
||||
|
||||
;new_process_loading db 'K : New Process - loading',13,10,0
|
||||
;new_process_running db 'K : New Process - done',13,10,0
|
||||
@ -280,7 +308,7 @@ mem_block_arr rd 1
|
||||
mem_block_start rd 1
|
||||
mem_block_end rd 1
|
||||
|
||||
heap_mutex rd 1
|
||||
heap_mutex MUTEX
|
||||
heap_size rd 1
|
||||
heap_free rd 1
|
||||
heap_blocks rd 1
|
||||
|
94
kernel/branches/Kolibri-acpi/docs/drivers_api.txt
Normal file
94
kernel/branches/Kolibri-acpi/docs/drivers_api.txt
Normal file
@ -0,0 +1,94 @@
|
||||
All functions are stdcall unless mentioned otherwise.
|
||||
|
||||
=== Disk ===
|
||||
The kernel exports the functions 'DiskAdd', 'DiskMediaChanged', 'DiskDel' for
|
||||
drivers. They must be called in the following order: DiskAdd, then zero or
|
||||
more DiskMediaChanged, then optionally DiskDel. The driver must not call
|
||||
two functions in parallel, including two calls to DiskMediaChanged.
|
||||
|
||||
void* DiskAdd(DISKFUNC* functions, const char* name, void* userdata, int flags);
|
||||
; The pointer 'functions' must be valid at least until the disk will be deleted
|
||||
; (until DISKFUNC.close is called).
|
||||
; The pointer 'name' can be invalid after this function returns.
|
||||
; It should point to ASCIIZ-string without leading '/' in latin lowercase and
|
||||
; digits, like 'usbhd0'.
|
||||
; The value 'userdata' is any pointer-sized data, passed as is to all
|
||||
; callbacks.
|
||||
DISK_NO_INSERT_NOTIFICATION = 1
|
||||
; The bitfield 'flags' has currently only one bit defined. If it is set, the
|
||||
; driver will never call DiskMediaChanged(hDisk, true), so the kernel must scan
|
||||
; for media insertion when the operation is requested.
|
||||
struc DISKFUNC
|
||||
{
|
||||
.strucsize dd ?
|
||||
.close dd ?
|
||||
; void close(void* userdata);
|
||||
; Optional.
|
||||
; The last function that is called for the given disk. The kernel calls it when
|
||||
; the kernel has finished all operations with the disk and it is safe to free
|
||||
; all driver-specific data identified by 'userdata'.
|
||||
.closemedia dd ?
|
||||
; void closemedia(void* userdata);
|
||||
; Optional.
|
||||
; The kernel calls this function when it finished all processing with the
|
||||
; current media. If media is removed, the driver should decline all requests
|
||||
; to that media with DISK_STATUS_NO_MEDIA, even if new media is inserted,
|
||||
; until this function is called. If media is removed, a new call to
|
||||
; DiskMediaChanged(hDisk, true) is not allowed until this function is called.
|
||||
.querymedia dd ?
|
||||
; int querymedia(void* userdata, DISKMEDIAINFO* info);
|
||||
; return value: 0 = success, otherwise = error
|
||||
.read dd ?
|
||||
; int read(void* userdata, void* buffer, __int64 startsector,
|
||||
; int* numsectors);
|
||||
; return value: 0 = success, otherwise = error
|
||||
.write dd ?
|
||||
; int write(void* userdata, const void* buffer, __int64 startsector,
|
||||
; int* numsectors);
|
||||
; Optional.
|
||||
; return value: 0 = success, otherwise = error
|
||||
.flush dd ?
|
||||
; int flush(void* userdata);
|
||||
; Optional.
|
||||
; Flushes the hardware cache, if it exists. Note that a driver should not
|
||||
; implement a software cache for read/write, since they are called from the
|
||||
; kernel cache manager.
|
||||
}
|
||||
struc DISKMEDIAINFO
|
||||
{
|
||||
.flags dd ?
|
||||
DISK_MEDIA_READONLY = 1
|
||||
.sectorsize dd ?
|
||||
.capacity dq ?
|
||||
}
|
||||
void DiskDel(void* hDisk);
|
||||
; This function informs the kernel that the disk should be deleted from the
|
||||
; system. This function removes the disk from the global file system; however,
|
||||
; it is possible that active operations with the disk are still running. When
|
||||
; the disk is actually removed, the kernel calls the 'close' function, which
|
||||
; can free all device-related resources.
|
||||
void DiskMediaChanged(void* hDisk, int newstate);
|
||||
; This function informs the kernel that a media has been inserted, removed or
|
||||
; changed. 'newstate' should be zero if currently there is no media inserted
|
||||
; and nonzero in the other case. This function must not be called with nonzero
|
||||
; 'newstate' from any of callbacks. This function must not be called if another
|
||||
; call to this function is active.
|
||||
|
||||
=== Timers ===
|
||||
Timers allow to schedule a function call to some time in the future, once
|
||||
or periodically. A timer function can do anything, including adding/removing
|
||||
other timers and itself, but it should not run time-consuming tasks, since that
|
||||
would block the processing thread for a long time; for such tasks it is
|
||||
recommended to create new thread.
|
||||
|
||||
void* TimerHS(unsigned int deltaStart, unsigned int interval,
|
||||
void* timerFunc, void* userData);
|
||||
; Registers a timer which is activated in (deltaStart == 0 ? deltaStart :
|
||||
; interval) 1/100ths of second starting from the current time. If interval
|
||||
; is zero, this timer is automatically deleted when activated. Otherwise,
|
||||
; this timer will be activated every (interval) 1/100ths of second from the
|
||||
; first activation. Activated timer calls timerFunc(userData) as stdcall.
|
||||
; Returned value: NULL = failed, otherwise = timer handle which can be passed
|
||||
; to CancelTimerHS.
|
||||
void CancelTimerHS(void* hTimer);
|
||||
; Cancels previously registered timer.
|
@ -332,7 +332,7 @@ irq_handler:
|
||||
|
||||
mov [esi+COM_MOUSE_DATA.MouseByteNumber],0
|
||||
.EndMouseInterrupt:
|
||||
|
||||
mov al, 1
|
||||
ret
|
||||
|
||||
;all initialized data place here
|
||||
|
@ -239,7 +239,8 @@ else if sb_buffer_size eq full_buffer
|
||||
stdcall [callback],SB16Buffer0 ;for 64k buffer
|
||||
stdcall [callback],SB16Buffer1 ;for 64k buffer
|
||||
end if
|
||||
xor eax,eax
|
||||
xor eax, eax
|
||||
not eax
|
||||
ret
|
||||
|
||||
.fill_second_half:
|
||||
@ -249,7 +250,8 @@ else if sb_buffer_size eq full_buffer
|
||||
stdcall [callback],SB16Buffer2 ;for 64k buffer
|
||||
stdcall [callback],SB16Buffer3 ;for 64k buffer
|
||||
end if
|
||||
xor eax,eax
|
||||
xor eax, eax
|
||||
not eax
|
||||
ret
|
||||
endp
|
||||
;-------------------------------------------------------------------------------
|
||||
|
465
kernel/branches/Kolibri-acpi/drivers/vidintel.asm
Normal file
465
kernel/branches/Kolibri-acpi/drivers/vidintel.asm
Normal file
@ -0,0 +1,465 @@
|
||||
; Stub of videodriver for Intel videocards.
|
||||
; (c) CleverMouse
|
||||
|
||||
; When the start procedure gots control,
|
||||
; it tries to detect preferred resolution,
|
||||
; sets the detected resolution assuming 32-bpp VESA mode and exits
|
||||
; (without registering a service).
|
||||
; Detection can be overloaded with compile-time settings
|
||||
; use_predefined_mode/predefined_width/predefined_height.
|
||||
|
||||
; set predefined resolution here
|
||||
use_predefined_mode = 0;1
|
||||
predefined_width = 0;1366
|
||||
predefined_height = 0;768
|
||||
|
||||
; standard driver stuff
|
||||
format MS COFF
|
||||
|
||||
DEBUG = 1
|
||||
|
||||
include 'proc32.inc'
|
||||
include 'imports.inc'
|
||||
|
||||
public START
|
||||
public version
|
||||
|
||||
section '.flat' code readable align 16
|
||||
; the start procedure (see the description above)
|
||||
START:
|
||||
; 1. Detect device. Abort if not found.
|
||||
push esi
|
||||
call DetectDevice
|
||||
test esi, esi
|
||||
jz .return0
|
||||
; 2. Detect optimal mode unless the mode is given explicitly. Abort if failed.
|
||||
if use_predefined_mode = 0
|
||||
call DetectMode
|
||||
end if
|
||||
cmp [width], 0
|
||||
jz .return0_cleanup
|
||||
; 3. Set the detected mode.
|
||||
call SetMode
|
||||
; 4. Cleanup and return.
|
||||
.return0_cleanup:
|
||||
stdcall FreeKernelSpace, esi
|
||||
.return0:
|
||||
pop esi
|
||||
xor eax, eax
|
||||
ret 4
|
||||
|
||||
; check that there is Intel videocard
|
||||
; if so, map MMIO registers and set internal variables
|
||||
; esi points to MMIO block; NULL means no device
|
||||
DetectDevice:
|
||||
; 1. Sanity check: check that we are dealing with Intel videocard.
|
||||
; Integrated video device for Intel is always at PCI:0:2:0.
|
||||
xor esi, esi ; initialize return value to NULL
|
||||
; 1a. Get PCI VendorID and DeviceID.
|
||||
push esi
|
||||
push 10h
|
||||
push esi
|
||||
call PciRead32
|
||||
; 1b. loword(eax) = ax = VendorID, hiword(eax) = DeviceID.
|
||||
; Test whether we have Intel chipset.
|
||||
cmp ax, 8086h
|
||||
jnz .return
|
||||
; 1c. Say hi including DeviceID.
|
||||
shr eax, 10h
|
||||
push edi
|
||||
pusha
|
||||
mov edi, pciid_text
|
||||
call WriteWord
|
||||
mov esi, hellomsg
|
||||
call SysMsgBoardStr
|
||||
popa
|
||||
; 1d. Test whether we know this DeviceID.
|
||||
; If this is the case, remember the position of the device in line of Intel cards;
|
||||
; this knowledge will be useful later.
|
||||
; Tested on devices with id: 8086:0046, partially 8086:2A02.
|
||||
mov ecx, pciids_num
|
||||
mov edi, pciids
|
||||
repnz scasw
|
||||
pop edi
|
||||
jnz .return_unknown_pciid
|
||||
sub ecx, pciids_num - 1
|
||||
neg ecx
|
||||
mov [deviceType], ecx
|
||||
; 1e. Continue saying hi with positive intonation.
|
||||
pusha
|
||||
mov esi, knownmsg
|
||||
call SysMsgBoardStr
|
||||
popa
|
||||
; 2. Prepare MMIO region to control the card.
|
||||
; 2a. Read MMIO physical address from PCI config space.
|
||||
push 10h
|
||||
cmp ecx, i9xx_start
|
||||
jae @f
|
||||
mov byte [esp], 14h
|
||||
@@:
|
||||
push 10h
|
||||
push esi
|
||||
call PciRead32
|
||||
; 2b. Mask out PCI region type, lower 4 bits.
|
||||
and al, not 0xF
|
||||
; 2c. Create virtual mapping of the physical memory.
|
||||
push 1Bh
|
||||
push 100000h
|
||||
push eax
|
||||
call MapIoMem
|
||||
; 3. Return.
|
||||
xchg esi, eax
|
||||
.return:
|
||||
ret
|
||||
; 1f. If we do not know DeviceID, continue saying hi with negative intonation.
|
||||
.return_unknown_pciid:
|
||||
pusha
|
||||
mov esi, unknownmsg
|
||||
call SysMsgBoardStr
|
||||
popa
|
||||
ret
|
||||
|
||||
; Convert word in ax to hexadecimal text in edi, advance edi.
|
||||
WriteWord:
|
||||
; 1. Convert high byte.
|
||||
push eax
|
||||
mov al, ah
|
||||
call WriteByte
|
||||
pop eax
|
||||
; 2. Convert low byte.
|
||||
; Fall through to WriteByte; ret from WriteByte is ret from WriteWord too.
|
||||
|
||||
; Convert byte in al to hexadecimal text in edi, advance edi.
|
||||
WriteByte:
|
||||
; 1. Convert high nibble.
|
||||
push eax
|
||||
shr al, 4
|
||||
call WriteNibble
|
||||
pop eax
|
||||
; 2. Convert low nibble.
|
||||
and al, 0xF
|
||||
; Fall through to WriteNibble; ret from WriteNibble is ret from WriteByte too.
|
||||
|
||||
; Convert nibble in al to hexadecimal text in edi, advance edi.
|
||||
WriteNibble:
|
||||
; Obvious, isn't it?
|
||||
cmp al, 10
|
||||
sbb al, 69h
|
||||
das
|
||||
stosb
|
||||
ret
|
||||
|
||||
if use_predefined_mode = 0
|
||||
; detect resolution of the flat panel
|
||||
DetectMode:
|
||||
push esi edi
|
||||
; 1. Get the location of block of GMBUS* registers.
|
||||
; Starting with Ironlake, GMBUS* registers were moved.
|
||||
add esi, 5100h
|
||||
cmp [deviceType], ironlake_start
|
||||
jb @f
|
||||
add esi, 0xC0000
|
||||
@@:
|
||||
; 2. Initialize GMBUS engine.
|
||||
mov edi, edid
|
||||
mov ecx, 0x10000
|
||||
@@:
|
||||
test byte [esi+8+1], 80h
|
||||
loopnz @b
|
||||
jnz .fail
|
||||
mov dword [esi], 3
|
||||
test byte [esi+8+1], 4
|
||||
jz .noreset
|
||||
call ResetGMBus
|
||||
jnz .fail
|
||||
.noreset:
|
||||
; 3. Send read command.
|
||||
and dword [esi+20h], 0
|
||||
mov dword [esi+4], 4E8000A1h
|
||||
; 4. Wait for data, writing to the buffer as data arrive.
|
||||
.getdata:
|
||||
mov ecx, 0x10000
|
||||
@@:
|
||||
test byte [esi+8+1], 8
|
||||
loopz @b
|
||||
test byte [esi+8+1], 4
|
||||
jz .dataok
|
||||
call ResetGMBus
|
||||
jmp .fail
|
||||
.dataok:
|
||||
mov eax, [esi+0Ch]
|
||||
stosd
|
||||
cmp edi, edid+80h
|
||||
jb .getdata
|
||||
; 5. Wait for bus idle.
|
||||
mov ecx, 0x10000
|
||||
@@:
|
||||
test byte [esi+8+1], 2
|
||||
loopnz @b
|
||||
; 6. We got EDID; dump it if DEBUG.
|
||||
if DEBUG
|
||||
pusha
|
||||
xor ecx, ecx
|
||||
mov esi, edid
|
||||
mov edi, edid_text
|
||||
.dumploop:
|
||||
lodsb
|
||||
call WriteByte
|
||||
mov al, ' '
|
||||
stosb
|
||||
inc cl
|
||||
test cl, 15
|
||||
jnz @f
|
||||
mov byte [edi-1], 13
|
||||
mov al, 10
|
||||
stosb
|
||||
@@:
|
||||
test cl, cl
|
||||
jns .dumploop
|
||||
mov esi, edidmsg
|
||||
call SysMsgBoardStr
|
||||
popa
|
||||
end if
|
||||
; 7. Test whether EDID is good.
|
||||
; 7a. Signature: 00 FF FF FF FF FF FF 00.
|
||||
mov esi, edid
|
||||
cmp dword [esi], 0xFFFFFF00
|
||||
jnz .fail
|
||||
cmp dword [esi+4], 0x00FFFFFF
|
||||
jnz .fail
|
||||
; 7b. Checksum must be zero.
|
||||
xor edx, edx
|
||||
mov ecx, 80h
|
||||
@@:
|
||||
lodsb
|
||||
add dl, al
|
||||
loop @b
|
||||
jnz .fail
|
||||
; 8. Get width and height from EDID.
|
||||
xor eax, eax
|
||||
mov ah, [esi-80h+3Ah]
|
||||
shr ah, 4
|
||||
mov al, [esi-80h+38h]
|
||||
mov [width], eax
|
||||
mov ah, [esi-80h+3Dh]
|
||||
shr ah, 4
|
||||
mov al, [esi-80h+3Bh]
|
||||
mov [height], eax
|
||||
; 9. Return.
|
||||
.fail:
|
||||
pop edi esi
|
||||
ret
|
||||
|
||||
; reset bus, clear all errors
|
||||
ResetGMBus:
|
||||
; look into the PRM
|
||||
mov dword [esi+4], 80000000h
|
||||
mov dword [esi+4], 0
|
||||
mov ecx, 0x10000
|
||||
@@:
|
||||
test byte [esi+8+1], 2
|
||||
loopnz @b
|
||||
ret
|
||||
end if
|
||||
|
||||
; set resolution [width]*[height]
|
||||
SetMode:
|
||||
; 1. Program the registers of videocard.
|
||||
; look into the PRM
|
||||
cli
|
||||
; or byte [esi+7000Ah], 0Ch ; PIPEACONF: disable Display+Cursor Planes
|
||||
; or byte [esi+7100Ah], 0Ch ; PIPEBCONF: disable Display+Cursor Planes
|
||||
xor eax, eax
|
||||
xor edx, edx
|
||||
cmp [deviceType], i965_start
|
||||
jb @f
|
||||
mov dl, 9Ch - 84h
|
||||
@@:
|
||||
; or byte [esi+71403h], 80h ; VGACNTRL: VGA Display Disable
|
||||
and byte [esi+70080h], not 27h ; CURACNTR: disable cursor A
|
||||
mov dword [esi+70084h], eax ; CURABASE: force write to CURA* regs
|
||||
and byte [esi+700C0h], not 27h ; CURBCNTR: disable cursor B
|
||||
mov dword [esi+700C4h], eax ; CURBBASE: force write to CURB* regs
|
||||
and byte [esi+70183h], not 80h ; DSPACNTR: disable Primary A Plane
|
||||
mov dword [esi+edx+70184h], eax ; DSPALINOFF/DSPASURF: force write to DSPA* regs
|
||||
and byte [esi+71183h], not 80h ; DSPBCNTR: disable Primary B Plane
|
||||
mov dword [esi+edx+71184h], eax ; DSPBLINOFF/DSPBSURF: force write to DSPB* regs
|
||||
if 1
|
||||
cmp [deviceType], ironlake_start
|
||||
jae .disable_pipes
|
||||
mov edx, 10000h
|
||||
or byte [esi+70024h], 2 ; PIPEASTAT: clear VBLANK status
|
||||
or byte [esi+71024h], 2 ; PIPEBSTAT: clear VBLANK status
|
||||
.wait_vblank_preironlake1:
|
||||
mov ecx, 1000h
|
||||
loop $
|
||||
test byte [esi+7000Bh], 80h ; PIPEACONF: pipe A active?
|
||||
jz @f
|
||||
test byte [esi+70024h], 2 ; PIPEASTAT: got VBLANK?
|
||||
jz .wait_vblank_preironlake2
|
||||
@@:
|
||||
test byte [esi+7100Bh], 80h ; PIPEBCONF: pipe B active?
|
||||
jz .disable_pipes
|
||||
test byte [esi+71024h], 2 ; PIPEBSTAT: got VBLANK?
|
||||
jnz .disable_pipes
|
||||
.wait_vblank_preironlake2:
|
||||
dec edx
|
||||
jnz .wait_vblank_preironlake1
|
||||
jmp .not_disabled
|
||||
.disable_pipes:
|
||||
end if
|
||||
and byte [esi+7000Bh], not 80h ; PIPEACONF: disable pipe
|
||||
and byte [esi+7100Bh], not 80h ; PIPEBCONF: disable pipe
|
||||
if 1
|
||||
mov edx, 10000h
|
||||
@@:
|
||||
mov ecx, 1000h
|
||||
loop $
|
||||
test byte [esi+7000Bh], 40h ; PIPEACONF: wait until pipe disabled
|
||||
jz @f
|
||||
dec edx
|
||||
jnz @b
|
||||
.not_disabled:
|
||||
sti
|
||||
jmp .return
|
||||
@@:
|
||||
test byte [esi+7100Bh], 40h ; PIPEBCONF: wait until pipe disabled
|
||||
jz @f
|
||||
mov ecx, 1000h
|
||||
loop $
|
||||
dec edx
|
||||
jnz @b
|
||||
jmp .not_disabled
|
||||
@@:
|
||||
else
|
||||
; alternative way of waiting for pipe stop, works too
|
||||
mov edx, 1000h
|
||||
.dis1:
|
||||
push dword [esi+71000h]
|
||||
push dword [esi+70000h]
|
||||
mov ecx, 10000h
|
||||
loop $
|
||||
pop eax
|
||||
xor eax, [esi+70000h]
|
||||
and eax, 1FFFh
|
||||
pop eax
|
||||
jnz .notdis1
|
||||
xor eax, [esi+71000h]
|
||||
and eax, 1FFFh
|
||||
jz .disabled
|
||||
.notdis1:
|
||||
dec edx
|
||||
jnz .dis1
|
||||
.not_disabled:
|
||||
sti
|
||||
jmp .return
|
||||
.disabled:
|
||||
end if
|
||||
lea eax, [esi+61183h]
|
||||
cmp [deviceType], ironlake_start
|
||||
jb @f
|
||||
add eax, 0xE0000 - 0x60000
|
||||
@@:
|
||||
lea edx, [esi+60000h]
|
||||
test byte [eax], 40h
|
||||
jz @f
|
||||
add edx, 1000h
|
||||
@@:
|
||||
mov eax, [width]
|
||||
dec eax
|
||||
shl eax, 16
|
||||
mov ax, word [height]
|
||||
dec eax
|
||||
mov dword [edx+1Ch], eax ; PIPEASRC: set source image size
|
||||
ror eax, 16
|
||||
mov dword [edx+10190h], eax ; for old cards
|
||||
mov ecx, [width]
|
||||
add ecx, 15
|
||||
and ecx, not 15
|
||||
shl ecx, 2
|
||||
mov dword [edx+10188h], ecx ; DSPASTRIDE: set scanline length
|
||||
and byte [esi+61233h], not 80h ; PFIT_CONTROL: disable panel fitting
|
||||
or byte [edx+1000Bh], 80h ; PIPEACONF: enable pipe
|
||||
; and byte [edx+1000Ah], not 0Ch ; PIPEACONF: enable Display+Cursor Planes
|
||||
or byte [edx+10183h], 80h ; DSPACNTR: enable Display Plane A
|
||||
sti
|
||||
; 2. Notify the kernel that resolution has changed.
|
||||
call GetDisplay
|
||||
mov edx, [width]
|
||||
mov dword [eax+8], edx
|
||||
mov edx, [height]
|
||||
mov dword [eax+0Ch], edx
|
||||
mov [eax+18h], ecx
|
||||
mov eax, [width]
|
||||
dec eax
|
||||
dec edx
|
||||
call SetScreen
|
||||
.return:
|
||||
ret
|
||||
|
||||
align 4
|
||||
hellomsg db 'Intel videocard detected, PciId=8086:'
|
||||
pciid_text db '0000'
|
||||
db ', which is ', 0
|
||||
knownmsg db 'known',13,10,0
|
||||
unknownmsg db 'unknown',13,10,0
|
||||
|
||||
if DEBUG
|
||||
edidmsg db 'EDID successfully read:',13,10
|
||||
edid_text rb 8*(16*3+1)
|
||||
db 0
|
||||
end if
|
||||
|
||||
version:
|
||||
dd 0x50005
|
||||
|
||||
width dd predefined_width
|
||||
height dd predefined_height
|
||||
|
||||
pciids:
|
||||
dw 0x3577 ; i830m
|
||||
dw 0x2562 ; 845g
|
||||
dw 0x3582 ; i855gm
|
||||
i865_start = ($ - pciids) / 2
|
||||
dw 0x2572 ; i865g
|
||||
i9xx_start = ($ - pciids) / 2
|
||||
dw 0x2582 ; i915g
|
||||
dw 0x258a ; e7221g (i915g)
|
||||
dw 0x2592 ; i915gm
|
||||
dw 0x2772 ; i945g
|
||||
dw 0x27a2 ; i945gm
|
||||
dw 0x27ae ; i945gme
|
||||
i965_start = ($ - pciids) / 2
|
||||
dw 0x2972 ; i946qz (i965g)
|
||||
dw 0x2982 ; g35g (i965g)
|
||||
dw 0x2992 ; i965q (i965g)
|
||||
dw 0x29a2 ; i965g
|
||||
dw 0x29b2 ; q35g
|
||||
dw 0x29c2 ; g33g
|
||||
dw 0x29d2 ; q33g
|
||||
dw 0x2a02 ; i965gm
|
||||
dw 0x2a12 ; i965gm
|
||||
dw 0x2a42 ; gm45
|
||||
dw 0x2e02 ; g45
|
||||
dw 0x2e12 ; g45
|
||||
dw 0x2e22 ; g45
|
||||
dw 0x2e32 ; g45
|
||||
dw 0x2e42 ; g45
|
||||
dw 0x2e92 ; g45
|
||||
dw 0xa001 ; pineview
|
||||
dw 0xa011 ; pineview
|
||||
ironlake_start = ($ - pciids) / 2
|
||||
dw 0x0042 ; ironlake_d
|
||||
dw 0x0046 ; ironlake_m
|
||||
dw 0x0102 ; sandybridge_d
|
||||
dw 0x0112 ; sandybridge_d
|
||||
dw 0x0122 ; sandybridge_d
|
||||
dw 0x0106 ; sandybridge_m
|
||||
dw 0x0116 ; sandybridge_m
|
||||
dw 0x0126 ; sandybridge_m
|
||||
dw 0x010A ; sandybridge_d
|
||||
pciids_num = ($ - pciids) / 2
|
||||
|
||||
align 4
|
||||
deviceType dd ?
|
||||
edid rb 0x80
|
1281
kernel/branches/Kolibri-acpi/drivers/vt823x.asm
Normal file
1281
kernel/branches/Kolibri-acpi/drivers/vt823x.asm
Normal file
File diff suppressed because it is too large
Load Diff
1216
kernel/branches/Kolibri-acpi/fs/disk.inc
Normal file
1216
kernel/branches/Kolibri-acpi/fs/disk.inc
Normal file
File diff suppressed because it is too large
Load Diff
@ -60,6 +60,7 @@ ERROR_MEMORY_POINTER = 7
|
||||
ERROR_DISK_FULL = 8
|
||||
ERROR_FAT_TABLE = 9
|
||||
ERROR_ACCESS_DENIED = 10
|
||||
ERROR_DEVICE = 11
|
||||
|
||||
PUSHAD_EAX equ [esp+28]
|
||||
PUSHAD_ECX equ [esp+24]
|
||||
|
@ -85,6 +85,7 @@ virtual_root_query:
|
||||
|
||||
fs_additional_handlers:
|
||||
dd biosdisk_handler, biosdisk_enum_root
|
||||
dd dyndisk_handler, dyndisk_enum_root
|
||||
; add new handlers here
|
||||
dd 0
|
||||
|
||||
@ -383,7 +384,8 @@ file_system_lfn:
|
||||
.notfounda:
|
||||
cmp edi, esp
|
||||
jnz .notfound
|
||||
add esp, 8
|
||||
call dword [edi+4]
|
||||
add esp, 16
|
||||
jmp .notfound
|
||||
|
||||
.found1:
|
||||
@ -850,6 +852,8 @@ biosdisk_handler:
|
||||
jmp file_system_lfn.maindir_noesi
|
||||
@@:
|
||||
push ecx
|
||||
push ecx
|
||||
push biosdisk_cleanup
|
||||
push fs_OnBd
|
||||
mov edi, esp
|
||||
jmp file_system_lfn.found2
|
||||
@ -858,10 +862,11 @@ fs_BdNext:
|
||||
cmp eax, [BiosDiskPartitions+ecx*4]
|
||||
inc eax
|
||||
cmc
|
||||
biosdisk_cleanup:
|
||||
ret
|
||||
|
||||
fs_OnBd:
|
||||
pop edx edx
|
||||
pop edx edx edx edx
|
||||
; edx = disk number, ecx = partition number
|
||||
; esi+ebp = name
|
||||
call reserve_hd1
|
||||
|
@ -266,7 +266,6 @@ proc init_page_map
|
||||
add ebx, [pg_data.pagemap_size-OS_BASE]
|
||||
mov [page_end-OS_BASE], ebx
|
||||
|
||||
mov [pg_data.pg_mutex-OS_BASE], 0
|
||||
ret
|
||||
endp
|
||||
|
||||
|
@ -321,6 +321,12 @@ high_code:
|
||||
mov eax, cr3
|
||||
mov cr3, eax ; flush TLB
|
||||
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_init
|
||||
|
||||
mov ecx, disk_list_mutex
|
||||
call mutex_init
|
||||
|
||||
; SAVE REAL MODE VARIABLES
|
||||
mov ax, [BOOT_VAR + 0x9031]
|
||||
mov [IDEContrRegsBaseAddr], ax
|
||||
@ -713,7 +719,11 @@ end if
|
||||
call boot_log
|
||||
|
||||
movzx ecx, word [boot_y]
|
||||
or ecx, (10+29*6) shl 16 ; "Determining amount of memory"
|
||||
if lang eq ru
|
||||
or ecx, (10+30*6) shl 16
|
||||
else
|
||||
or ecx, (10+29*6) shl 16
|
||||
end if
|
||||
sub ecx, 10
|
||||
mov edx, 0xFFFFFF
|
||||
mov ebx, [MEM_AMOUNT]
|
||||
@ -832,7 +842,11 @@ end if
|
||||
|
||||
mov ebx, edx
|
||||
movzx ecx, word [boot_y]
|
||||
add ecx, (10+17*6) shl 16 - 10 ; 'CPU frequency is '
|
||||
if lang eq ru
|
||||
add ecx, (10+19*6) shl 16 - 10; 'Determining amount of memory'
|
||||
else
|
||||
add ecx, (10+17*6) shl 16 - 10; 'Determining amount of memory'
|
||||
end if
|
||||
mov edx, 0xFFFFFF
|
||||
xor edi,edi
|
||||
mov eax, 0x00040000
|
||||
@ -2270,18 +2284,18 @@ window_minimize db 0
|
||||
sound_flag db 0
|
||||
endg
|
||||
|
||||
iglobal
|
||||
version_inf:
|
||||
db 0,7,7,0 ; version 0.7.7.0
|
||||
db UID_KOLIBRI
|
||||
dd __REV__
|
||||
version_end:
|
||||
endg
|
||||
|
||||
UID_NONE=0
|
||||
UID_MENUETOS=1 ;official
|
||||
UID_KOLIBRI=2 ;russian
|
||||
|
||||
iglobal
|
||||
version_inf:
|
||||
db 0,7,7,0 ; version 0.7.7.0
|
||||
db 0
|
||||
dd __REV__
|
||||
version_end:
|
||||
endg
|
||||
|
||||
sys_cachetodiskette:
|
||||
cmp ebx, 1
|
||||
jne .no_floppy_a_save
|
||||
|
@ -223,6 +223,7 @@ include "core/string.inc"
|
||||
include "core/v86.inc" ; virtual-8086 manager
|
||||
include "core/apic.inc" ; Interrupt Controller functions
|
||||
include "core/irq.inc" ; irq handling functions
|
||||
include "core/timers.inc"
|
||||
|
||||
; GUI stuff
|
||||
include "gui/window.inc"
|
||||
@ -234,6 +235,7 @@ include "gui/button.inc"
|
||||
|
||||
; file system
|
||||
|
||||
include "fs/disk.inc" ; support for plug-n-play disks
|
||||
include "fs/fs.inc" ; syscall
|
||||
include "fs/fat32.inc" ; read / write for fat32 filesystem
|
||||
include "fs/ntfs.inc" ; read / write for ntfs filesystem
|
||||
|
@ -20,13 +20,16 @@ macro struct name, [arg]
|
||||
struc name arg {
|
||||
}
|
||||
|
||||
macro declare_sizeof xname,value
|
||||
{ sizeof.#xname = value }
|
||||
|
||||
macro struct_helper name
|
||||
{
|
||||
match xname,name
|
||||
\{
|
||||
virtual at 0
|
||||
xname xname
|
||||
sizeof.#xname = $ - xname
|
||||
declare_sizeof xname, $ - xname
|
||||
name equ sizeof.#xname
|
||||
end virtual
|
||||
\}
|
||||
|
@ -54,7 +54,7 @@ struct SOCKET
|
||||
.SEG_LEN dd ? ; segment length
|
||||
.SEG_WND dd ? ; segment window
|
||||
.wndsizeTimer dd ? ; window size timer
|
||||
.lock dd ? ; lock mutex
|
||||
.lock MUTEX ; lock mutex
|
||||
.rxData dd ? ; receive data buffer here
|
||||
ends
|
||||
|
||||
@ -99,6 +99,11 @@ proc net_socket_alloc stdcall uses ebx ecx edx edi
|
||||
rep stosd
|
||||
pop eax
|
||||
|
||||
mov ebx, eax
|
||||
lea ecx, [eax+SOCKET.lock]
|
||||
call mutex_init
|
||||
mov eax, ebx
|
||||
|
||||
; add socket to the list by changing pointers
|
||||
mov ebx, net_sockets
|
||||
push [ebx + SOCKET.NextPtr]
|
||||
@ -703,10 +708,10 @@ proc socket_read stdcall
|
||||
or eax, eax
|
||||
jz .error
|
||||
|
||||
lea ebx, [eax + SOCKET.lock]
|
||||
call wait_mutex
|
||||
mov ebx, eax
|
||||
lea ecx, [eax + SOCKET.lock]
|
||||
call mutex_lock
|
||||
|
||||
mov ebx, eax
|
||||
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes
|
||||
test eax, eax
|
||||
jz .error_release
|
||||
@ -727,15 +732,18 @@ proc socket_read stdcall
|
||||
and ecx, 3
|
||||
rep movsb
|
||||
|
||||
mov [ebx + SOCKET.lock], 0
|
||||
lea ecx, [ebx + SOCKET.lock]
|
||||
mov ebx, eax
|
||||
|
||||
call mutex_unlock
|
||||
mov eax, ebx
|
||||
ret
|
||||
|
||||
.error_release:
|
||||
mov [ebx + SOCKET.lock], 0
|
||||
lea ecx, [ebx + SOCKET.lock]
|
||||
call mutex_unlock
|
||||
.error:
|
||||
xor ebx, ebx
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
@ -756,10 +764,11 @@ proc socket_read_packet stdcall
|
||||
or eax, eax
|
||||
jz .error
|
||||
|
||||
lea ebx, [eax + SOCKET.lock]
|
||||
call wait_mutex
|
||||
mov ebx, eax
|
||||
|
||||
lea ecx, [eax + SOCKET.lock]
|
||||
call mutex_lock
|
||||
|
||||
mov ebx, eax
|
||||
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes
|
||||
test eax, eax ; if count of bytes is zero..
|
||||
jz .exit ; exit function (eax will be zero)
|
||||
@ -789,7 +798,9 @@ proc socket_read_packet stdcall
|
||||
rep movsb ; copy remaining bytes
|
||||
|
||||
.exit:
|
||||
mov [ebx + SOCKET.lock], 0
|
||||
lea ecx, [ebx + SOCKET.lock]
|
||||
call mutex_unlock
|
||||
mov eax, edx
|
||||
ret ; at last, exit
|
||||
|
||||
.error:
|
||||
@ -800,7 +811,9 @@ proc socket_read_packet stdcall
|
||||
xor esi, esi
|
||||
mov [ebx + SOCKET.rxDataCount], esi ; store new count (zero)
|
||||
call .start_copy
|
||||
mov [ebx + SOCKET.lock], 0
|
||||
lea ecx, [ebx + SOCKET.lock]
|
||||
call mutex_unlock
|
||||
mov eax, edx
|
||||
ret
|
||||
|
||||
.start_copy:
|
||||
|
@ -963,12 +963,10 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
|
||||
jmp .exit
|
||||
|
||||
.data:
|
||||
push ebx
|
||||
add ebx, SOCKET.lock
|
||||
call wait_mutex
|
||||
pop ebx
|
||||
push ecx
|
||||
lea ecx, [ebx+SOCKET.lock]
|
||||
call mutex_lock
|
||||
|
||||
push ecx
|
||||
push ebx
|
||||
mov eax, [ebx + SOCKET.rxDataCount]
|
||||
add eax, ecx
|
||||
@ -986,7 +984,9 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
|
||||
|
||||
cld
|
||||
rep movsb ; copy the data across
|
||||
mov [ebx + SOCKET.lock], 0 ; release mutex
|
||||
|
||||
lea ecx,[ebx + SOCKET.lock]
|
||||
call mutex_unlock
|
||||
|
||||
; flag an event to the application
|
||||
pop ebx
|
||||
@ -1031,8 +1031,9 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
|
||||
.overflow:
|
||||
; no place in buffer
|
||||
; so simply restore stack and exit
|
||||
lea ecx, [ebx + SOCKET.lock]
|
||||
call mutex_unlock
|
||||
pop eax ecx
|
||||
mov [ebx + SOCKET.lock], 0
|
||||
ret
|
||||
endp
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user