Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 383 → Rev 384

/kernel/branches/gfx_kernel/core/dll.inc
0,0 → 1,1058
 
DRV_ENTRY equ 1
DRV_EXIT equ -1
DRV_COMPAT equ 4 ;minimal required drivers version
DRV_CURRENT equ 4 ;current drivers model version
 
DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT
 
align 4
proc attach_int_handler stdcall, irq:dword, handler:dword
 
mov ebx, [irq] ;irq num
test ebx, ebx
jz .err
mov eax, [handler]
test eax, eax
jz .err
mov [irq_tab+ebx*4], eax
stdcall enable_irq, [irq]
ret
.err:
xor eax, eax
ret
endp
 
align 4
proc detach_int_handler
 
ret
endp
 
align 4
proc enable_irq stdcall, irq_line:dword
mov ebx, [irq_line]
mov edx, 0x21
cmp ebx, 8
jb @F
mov edx, 0xA1
sub ebx,8
@@:
in al,dx
btr eax, ebx
out dx, al
ret
endp
 
align 16
;; proc irq_serv
 
irq_serv:
 
.irq_1:
push eax
mov eax, 1
jmp .main
align 4
.irq_2:
push eax
mov eax, 2
jmp .main
align 4
.irq_3:
push eax
mov eax, 3
jmp .main
align 4
.irq_4:
push eax
mov eax, 4
jmp .main
align 4
.irq_5:
push eax
mov eax, 5
jmp .main
align 4
.irq_6:
push eax
mov eax, 6
jmp .main
align 4
.irq_7:
push eax
mov eax, 7
jmp .main
align 4
.irq_8:
push eax
mov eax, 8
jmp .main
align 4
.irq_9:
push eax
mov eax, 9
jmp .main
align 4
.irq_10:
push eax
mov eax, 10
jmp .main
align 4
.irq_11:
push eax
mov eax, 11
jmp .main
align 4
.irq_12:
push eax
mov eax, 12
jmp .main
align 4
.irq_13:
push eax
mov eax, 13
jmp .main
align 4
.irq_14:
push eax
mov eax, 14
jmp .main
align 4
.irq_15:
push eax
mov eax, 15
jmp .main
 
align 16
.main:
save_ring3_context
mov bx, os_data
mov ds, bx
mov es, bx
 
mov ebx, [irq_tab+eax*4]
test ebx, ebx
jz .exit
 
call ebx
 
.exit:
restore_ring3_context
 
cmp eax, 8
mov al, 0x20
jb @f
out 0xa0, al
@@:
out 0x20, al
 
pop eax
iret
 
align 4
proc get_notify stdcall, p_ev:dword
 
.wait:
mov ebx,[CURRENT_TASK]
shl ebx,8
test dword [ebx+SLOT_BASE+0xA8],EVENT_NOTIFY
jz @f
and dword [ebx+SLOT_BASE+0xA8], not EVENT_NOTIFY
mov edi, [p_ev]
mov dword [edi], EV_INTR
mov eax, [ebx+SLOT_BASE+APPDATA.event]
mov dword [edi+4], eax
ret
@@:
call change_task
jmp .wait
endp
 
align 4
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 6
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
ret
endp
 
align 4
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 4
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
ret
endp
 
align 4
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 8
mov bh, byte [devfn]
mov bl, byte [reg]
mov ecx, [val]
call pci_write_reg
ret
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
 
align 4
proc srv_handler stdcall, ioctl:dword
mov esi, [ioctl]
test esi, esi
jz .err
 
mov edi, [esi+handle]
cmp [edi+SRV.magic], ' SRV'
jne .fail
 
cmp [edi+SRV.size], SRV_SIZE
jne .fail
 
stdcall [edi+SRV.srv_proc], esi
ret
.fail:
xor eax, eax
not eax
mov [esi+output], eax
mov [esi+out_size], 4
ret
.err:
xor eax, eax
not eax
ret
endp
 
; param
; ebx= io_control
;
; retval
; eax= error code
 
align 4
srv_handlerEx:
test ebx, ebx
jz .fail
add ebx, new_app_base
 
mov eax, [ebx+handle]
cmp [eax+SRV.magic], ' SRV'
jne .fail
 
cmp [eax+SRV.size], SRV_SIZE
jne .fail
 
add [ebx+input], new_app_base
add [ebx+output], new_app_base
 
stdcall [eax+SRV.srv_proc], ebx
ret
.fail:
or eax, -1
ret
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
align 4
proc get_service stdcall, sz_name:dword
mov eax, [sz_name]
test eax, eax
jnz @F
ret
@@:
mov edx, [srv.fd]
@@:
cmp edx, srv.fd-SRV_FD_OFFSET
je .not_load
 
stdcall strncmp, edx, [sz_name], 16
test eax, eax
je .ok
 
mov edx, [edx+SRV.fd]
jmp @B
.not_load:
pop ebp
jmp load_driver
.ok:
mov eax, edx
ret
endp
 
align 4
reg_service:
.sz_name equ esp+4
.handler equ esp+8
mov eax, [.sz_name]
test eax, eax
jz .fail
 
mov ebx, [.handler]
test ebx, ebx
jz .fail
 
mov eax, SRV_SIZE
call malloc ;call alloc_service
test eax, eax
jz .fail
 
mov edi, eax
mov esi, [.sz_name]
mov ecx, 16/4
rep movsd
 
mov [eax+SRV.magic], ' SRV'
mov [eax+SRV.size], SRV_SIZE
 
mov ebx, srv.fd-SRV_FD_OFFSET
mov edx, [ebx+SRV.fd]
mov [eax+SRV.fd], edx
mov [eax+SRV.bk], ebx
mov [ebx+SRV.fd], eax
mov [edx+SRV.bk], eax
 
mov ecx, [.handler]
mov [eax+SRV.srv_proc], ecx
ret 8
.fail:
xor eax, eax
ret 8
 
align 4
proc get_proc stdcall, exp:dword, sz_name:dword
 
mov edx, [exp]
.next:
mov eax, [edx]
test eax, eax
jz .end
 
push edx
stdcall strncmp, eax, [sz_name], 16
pop edx
test eax, eax
jz .ok
 
add edx,8
jmp .next
.ok:
mov eax, [edx+4]
.end:
ret
endp
 
align 4
proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword
 
@@:
stdcall strncmp, [pSym], [sz_sym], 8
test eax,eax
jz .ok
add [pSym], 18
dec [count]
jnz @b
xor eax, eax
ret
.ok:
mov ebx, [pSym]
mov eax, [ebx+8]
ret
endp
 
align 4
proc get_curr_task
mov eax,[CURRENT_TASK]
shl eax, 8
ret
endp
 
align 4
proc get_fileinfo stdcall, file_name:dword, info:dword
locals
cmd dd ?
offset dd ?
dd ?
count dd ?
buff dd ?
db ?
name dd ?
endl
 
xor eax, eax
mov ebx, [file_name]
sub ebx, new_app_base
mov ecx, [info]
sub ecx, new_app_base
 
mov [cmd], 5
mov [offset], eax
mov [offset+4], eax
mov [count], eax
mov [buff], ecx
mov byte [buff+4], al
mov [name], ebx
 
mov eax, 70
lea ebx, [cmd]
sub ebx, new_app_base
int 0x40
ret
endp
 
align 4
proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
bytes:dword
locals
cmd dd ?
offset dd ?
dd ?
count dd ?
buff dd ?
db ?
name dd ?
endl
 
xor eax, eax
mov ebx, [file_name]
mov ecx, [off]
mov edx, [bytes]
mov esi, [buffer]
sub ebx, new_app_base
sub esi, new_app_base
 
mov [cmd], eax
mov [offset], ecx
mov [offset+4], eax
mov [count], edx
mov [buff], esi
mov byte [buff+4], al
mov [name], ebx
 
mov eax, 70
lea ebx, [cmd]
sub ebx, new_app_base
int 0x40
ret
endp
 
; description
; allocate kernel memory and loads the specified file
;
; param
; file_name= full path to file
;
; retval
; eax= file image in kernel memory
; ebx= size of file
;
; warging
; You mast call kernel_free() to delete each file
; loaded by the load_file() function
 
align 4
proc load_file stdcall, file_name:dword
locals
attr dd ?
flags dd ?
cr_time dd ?
cr_date dd ?
acc_time dd ?
acc_date dd ?
mod_time dd ?
mod_date dd ?
file_size dd ?
 
file dd ?
file2 dd ?
endl
 
lea eax, [attr]
stdcall get_fileinfo, [file_name], eax
test eax, eax
jnz .fail
 
mov eax, [file_size]
cmp eax, 1024*1024*16
ja .fail
 
stdcall kernel_alloc, [file_size]
mov [file], eax
 
stdcall read_file, [file_name], eax, dword 0, [file_size]
cmp ebx, [file_size]
jne .cleanup
 
mov eax, [file]
cmp dword [eax], 0x4B43504B
jne .exit
mov ebx, [eax+4]
mov [file_size], ebx
stdcall kernel_alloc, ebx
 
test eax, eax
jz .cleanup
 
mov [file2], eax
stdcall unpack, [file], eax
stdcall kernel_free, [file]
mov eax, [file2]
mov ebx, [file_size]
.exit:
push eax
lea edi, [eax+ebx] ;cleanup remain space
mov ecx, 4096 ;from file end
and ebx, 4095
sub ecx, ebx
xor eax, eax
cld
rep stosb
mov ebx, [file_size]
pop eax
ret
.cleanup:
stdcall kernel_free, [file]
.fail:
xor eax, eax
xor ebx, ebx
ret
endp
 
align 4
proc get_proc_ex stdcall, proc_name:dword, imports:dword
 
.look_up:
mov edx, [imports]
test edx, edx
jz .end
mov edx, [edx]
test edx, edx
jz .end
.next:
mov eax, [edx]
test eax, eax
jz .next_table
 
push edx
stdcall strncmp, eax, [proc_name], 16
pop edx
test eax, eax
jz .ok
 
add edx,8
jmp .next
.next_table:
add [imports], 4
jmp .look_up
.ok:
mov eax, [edx+4]
ret
.end:
xor eax, eax
ret
endp
 
align 4
proc fix_coff_symbols stdcall, sec:dword, symbols:dword,\
sym_count:dword, strings:dword, imports:dword
locals
retval dd ?
endl
 
mov edi, [symbols]
mov [retval], 1
.fix:
movzx ebx, [edi+CSYM.SectionNumber]
test ebx, ebx
jnz .internal
mov eax, dword [edi+CSYM.Name]
test eax, eax
jnz @F
 
mov edi, [edi+4]
add edi, [strings]
@@:
push edi
stdcall get_proc_ex, edi,[imports]
pop edi
 
xor ebx, ebx
test eax, eax
jnz @F
 
mov esi, msg_unresolved
call sys_msg_board_str
mov esi, edi
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
 
mov [retval],0
@@:
mov edi, [symbols]
mov [edi+CSYM.Value], eax
jmp .next
.internal:
dec ebx
shl ebx, 3
lea ebx, [ebx+ebx*4]
add ebx, [sec]
 
mov eax, [ebx+CFS.VirtualAddress]
add [edi+CSYM.Value], eax
.next:
add edi, CSYM_SIZE
mov [symbols], edi
dec [sym_count]
jnz .fix
mov eax, [retval]
ret
endp
 
align 4
proc fix_coff_relocs stdcall, coff:dword, sec:dword, sym:dword
locals
n_sec dd ?
endl
 
mov eax, [coff]
movzx ebx, [eax+CFH.nSections]
mov [n_sec], ebx
.fix_sec:
mov esi, [sec]
mov edi, [esi+CFS.PtrReloc]
add edi, [coff]
 
movzx ecx, [esi+CFS.NumReloc]
test ecx, ecx
jz .next
.next_reloc:
mov ebx, [edi+CRELOC.SymIndex]
add ebx,ebx
lea ebx,[ebx+ebx*8]
add ebx, [sym]
 
mov edx, [ebx+CSYM.Value]
 
cmp [edi+CRELOC.Type], 6
je .dir_32
 
cmp [edi+CRELOC.Type], 20
jne .next_reloc
.rel_32:
mov eax, [edi+CRELOC.VirtualAddress]
add eax, [esi+CFS.VirtualAddress]
sub edx, eax
sub edx, 4
jmp .fix
.dir_32:
mov eax, [edi+CRELOC.VirtualAddress]
add eax, [esi+CFS.VirtualAddress]
.fix:
add [eax], edx
add edi, 10
dec ecx
jnz .next_reloc
.next:
add [sec], COFF_SECTION_SIZE
dec [n_sec]
jnz .fix_sec
.exit:
ret
endp
 
align 4
proc load_driver stdcall, driver_name:dword
locals
coff dd ?
sym dd ?
strings dd ?
img_size dd ?
img_base dd ?
start dd ?
 
exports dd ? ;fake exports table
dd ?
file_name rb 14+16+4+1 ; '/rd/1/drivers/<up-to-16-chars>.obj'
endl
 
lea edx, [file_name]
mov dword [edx], '/rd/'
mov dword [edx+4], '1/dr'
mov dword [edx+8], 'iver'
mov word [edx+12], 's/'
mov esi, [driver_name]
lea edi, [edx+14]
mov ecx, 16
@@:
lodsb
test al, al
jz @f
stosb
loop @b
@@:
mov dword [edi], '.obj'
mov byte [edi+4], 0
stdcall load_file, edx
 
test eax, eax
jz .exit
 
mov [coff], eax
 
movzx ecx, [eax+CFH.nSections]
xor ebx, ebx
 
lea edx, [eax+20]
@@:
add ebx, [edx+CFS.SizeOfRawData]
add ebx, 15
and ebx, not 15
add edx, COFF_SECTION_SIZE
dec ecx
jnz @B
mov [img_size], ebx
 
stdcall kernel_alloc, ebx
test eax, eax
jz .fail
mov [img_base], eax
 
mov edi, eax
xor eax, eax
mov ecx, [img_size]
add ecx, 4095
and ecx, not 4095
shr ecx, 2
cld
rep stosd
 
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, [img_base]
lea eax, [edx+20]
@@:
mov [eax+CFS.VirtualAddress], edi
mov esi, [eax+CFS.PtrRawData]
test esi, esi
jnz .copy
add edi, [eax+CFS.SizeOfRawData]
jmp .next
.copy:
add esi, edx
mov ecx, [eax+CFS.SizeOfRawData]
cld
rep movsb
.next:
add edi, 15
and edi, not 15
add eax, COFF_SECTION_SIZE
dec ebx
jnz @B
 
mov ebx, [edx+CFH.pSymTable]
add ebx, edx
mov [sym], ebx
mov ecx, [edx+CFH.nSymbols]
add ecx,ecx
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE
add ecx, [sym]
mov [strings], ecx
 
lea ebx, [exports]
mov dword [ebx], kernel_export
mov dword [ebx+4], 0
lea eax, [edx+20]
 
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\
[strings], ebx
test eax, eax
jz .link_fail
 
mov ebx, [coff]
add ebx, 20
stdcall fix_coff_relocs, [coff], ebx, [sym]
 
mov ebx, [coff]
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szVersion
test eax, eax
jz .link_fail
 
mov eax, [eax]
shr eax, 16
cmp eax, DRV_COMPAT
jb .ver_fail
 
cmp eax, DRV_CURRENT
ja .ver_fail
 
mov ebx, [coff]
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szSTART
mov [start], eax
 
stdcall kernel_free, [coff]
 
mov ebx, [start]
stdcall ebx, DRV_ENTRY
test eax, eax
jnz .ok
 
stdcall kernel_free, [img_base]
xor eax, eax
ret
.ok:
mov ebx, [img_base]
mov [eax+SRV.base], ebx
mov ecx, [start]
mov [eax+SRV.entry], ecx
ret
 
.ver_fail:
mov esi, msg_CR
call sys_msg_board_str
mov esi, [driver_name]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
mov esi, msg_version
call sys_msg_board_str
mov esi, msg_www
call sys_msg_board_str
jmp .cleanup
 
.link_fail:
mov esi, msg_module
call sys_msg_board_str
mov esi, [driver_name]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
.cleanup:
stdcall kernel_free,[img_base]
.fail:
stdcall kernel_free, [coff]
.exit:
xor eax, eax
ret
endp
 
align 4
proc load_library stdcall, file_name:dword
locals
coff dd ?
sym dd ?
strings dd ?
img_size dd ?
img_base dd ?
exports dd ?
endl
 
cli
 
stdcall load_file, [file_name]
test eax, eax
jz .fail
 
mov [coff], eax
movzx ecx, [eax+CFH.nSections]
xor ebx, ebx
 
lea edx, [eax+20]
@@:
add ebx, [edx+CFS.SizeOfRawData]
add ebx, 15
and ebx, not 15
add edx, COFF_SECTION_SIZE
dec ecx
jnz @B
mov [img_size], ebx
 
call init_heap
stdcall user_alloc, [img_size]
 
test eax, eax
jz .fail
mov [img_base], eax
 
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, [img_base]
lea eax, [edx+20]
@@:
mov [eax+CFS.VirtualAddress], edi
mov esi, [eax+CFS.PtrRawData]
test esi, esi
jnz .copy
add edi, [eax+CFS.SizeOfRawData]
jmp .next
.copy:
add esi, edx
add edi, new_app_base
mov ecx, [eax+CFS.SizeOfRawData]
cld
rep movsb
.next:
add edi, 15-new_app_base
and edi, not 15
add eax, COFF_SECTION_SIZE
dec ebx
jnz @B
 
mov ebx, [edx+CFH.pSymTable]
add ebx, edx
mov [sym], ebx
mov ecx, [edx+CFH.nSymbols]
add ecx,ecx
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE
add ecx, [sym]
mov [strings], ecx
 
lea eax, [edx+20]
 
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\
[strings], dword 0
test eax, eax
jnz @F
 
@@:
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, new_app_base
lea eax, [edx+20]
@@:
add [eax+CFS.VirtualAddress], edi ;patch user space offset
add eax, COFF_SECTION_SIZE
dec ebx
jnz @B
 
add edx, 20
stdcall fix_coff_relocs, [coff], edx, [sym]
 
mov ebx, [coff]
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szEXPORTS
mov [exports], eax
 
stdcall kernel_free, [coff]
mov eax, [exports]
ret
.fail:
xor eax, eax
ret
endp
 
align 4
proc stop_all_services
 
mov edx, [srv.fd]
.next:
cmp edx, srv.fd-SRV_FD_OFFSET
je .done
cmp [edx+SRV.magic], ' SRV'
jne .next
cmp [edx+SRV.size], SRV_SIZE
jne .next
mov ebx, [edx+SRV.entry]
mov edx, [edx+SRV.fd]
push edx
stdcall ebx, dword -1
pop edx
jmp .next
.done:
ret
endp
 
; param
; eax= size
; ebx= pid
 
align 4
create_kernel_object:
 
push ebx
call malloc
pop ebx
test eax, eax
jz .fail
 
mov ecx,[CURRENT_TASK]
shl ecx,8
add ecx, SLOT_BASE+APP_OBJ_OFFSET
 
pushfd
cli
mov edx, [ecx+APPOBJ.fd]
mov [eax+APPOBJ.fd], edx
mov [eax+APPOBJ.bk], ecx
mov [eax+APPOBJ.pid], ebx
 
mov [ecx+APPOBJ.fd], eax
mov [edx+APPOBJ.bk], eax
popfd
.fail:
ret
 
; param
; eax= object
 
align 4
destroy_kernel_object:
 
pushfd
cli
mov ebx, [eax+APPOBJ.fd]
mov ecx, [eax+APPOBJ.bk]
mov [ebx+APPOBJ.bk], ecx
mov [ecx+APPOBJ.fd], ebx
popfd
 
xor edx, edx ;clear common header
mov [eax], edx
mov [eax+4], edx
mov [eax+8], edx
mov [eax+12], edx
mov [eax+16], edx
 
call free ;release object memory
ret
 
 
;szSound db 'SOUND',0
;szInfinity db 'INFINITY',0
szHwMouse db 'ATI2D',0
 
szSTART db 'START',0
szEXPORTS db 'EXPORTS',0
szIMPORTS db 'IMPORTS',0
 
msg_unresolved db 'unresolved ',0
msg_module db 'in module ',0
msg_version db 'incompatible driver version',13,10,0
msg_www db 'please visit www.kolibrios.org',13,10,0
msg_CR db 13,10,0
 
align 4
create_cursor dd 0
set_hw_cursor dd 0
hw_restore dd 0