com driver

git-svn-id: svn://kolibrios.org@414 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2007-03-12 14:14:24 +00:00
parent 8670b710f7
commit 2a81124ad8

View File

@ -70,7 +70,7 @@ IER_MSI equ 0x08 ;modem status interrupt
MCR_DTR equ 0x01 ;0-> DTR=1, 1-> DTR=0 MCR_DTR equ 0x01 ;0-> DTR=1, 1-> DTR=0
MCR_RTS equ 0x02 ;0-> RTS=1, 1-> RTS=0 MCR_RTS equ 0x02 ;0-> RTS=1, 1-> RTS=0
MCR_OUT_1 equ 0x04 ;0-> OUT1=1, 1-> OUT1=0 MCR_OUT_1 equ 0x04 ;0-> OUT1=1, 1-> OUT1=0
MCR_OUT_2 equ 0x08 ;0-> OUT2=1, 1-> OUT2=0 enable intr MCR_OUT_2 equ 0x08 ;0-> OUT2=1, 1-> OUT2=0; enable intr
MCR_LOOP equ 0x10 ;lopback mode MCR_LOOP equ 0x10 ;lopback mode
MSR_DCTS equ 0x01 ;delta clear to send MSR_DCTS equ 0x01 ;delta clear to send
@ -113,10 +113,10 @@ COM_2_IRQ equ 3
UART_CLOSED equ 0 UART_CLOSED equ 0
UART_TRANSMIT equ 1 UART_TRANSMIT equ 1
UART_STOP equ 2
struc UART struc UART
{ {
; .owner dd ? unused
.lock dd ? .lock dd ?
.base dd ? .base dd ?
.lcr_reg dd ? .lcr_reg dd ?
@ -127,21 +127,20 @@ struc UART
.rcvr_rp dd ? .rcvr_rp dd ?
.rcvr_wp dd ? .rcvr_wp dd ?
.rcvr_free dd ? .rcvr_cnt dd ?
.xmit_buff dd ?
.xmit_rp dd ? .xmit_rp dd ?
.xmit_wp dd ? .xmit_wp dd ?
.xmit_count dd ?
.xmit_free dd ? .xmit_free dd ?
.rcvr_buffer rb 128 .xmit_top dd ?
.xmit_buffer rb 128
} }
virtual at 0 virtual at 0
UART UART UART UART
end virtual end virtual
RCVR_OFFSET equ 14*4 UART_SIZE equ 16*4
XMIT_OFFSET equ (13*4*128)
UART_SIZE equ (256+13*4)
struc CONNECTION struc CONNECTION
{ {
@ -179,7 +178,39 @@ init_uart_service:
mov eax, [com1] mov eax, [com1]
mov [eax+UART.base], COM_1_BASE mov [eax+UART.base], COM_1_BASE
call uart_reset ;eax= uart stdcall alloc_kernel_space, 16384
mov edi, [com1]
mov edx, eax
mov [edi+UART.xmit_buff], eax
add eax, 8192
mov [edi+UART.xmit_top], eax
call alloc_page
test eax, eax
jz .fail
shr edx, 12
or eax, PG_SW
mov [page_tabs+edx*4], eax
mov [page_tabs+edx*4+8], eax
call alloc_page
test eax, eax
jz .fail
or eax, PG_SW
mov [page_tabs+edx*4+4], eax
mov [page_tabs+edx*4+12], eax
mov eax, [edi+UART.xmit_buff]
invlpg [eax]
invlpg [eax+0x1000]
invlpg [eax+0x2000]
invlpg [eax+0x3000]
mov eax, edi
call uart_reset.internal ;eax= uart
stdcall attach_int_handler, COM_1_IRQ, com_1_isr stdcall attach_int_handler, COM_1_IRQ, com_1_isr
stdcall reg_service, sz_uart_srv, uart_proc stdcall reg_service, sz_uart_srv, uart_proc
@ -234,6 +265,7 @@ proc uart_proc stdcall, ioctl:dword
ret ret
@@: @@:
mov esi, [ebx+input] ;input buffer mov esi, [ebx+input] ;input buffer
mov edi, [ebx+output]
call [uart_func+eax*4] call [uart_func+eax*4]
ret ret
.fail: .fail:
@ -250,6 +282,26 @@ restore output
restore out_size restore out_size
; param
; esi= input buffer
; +0 connection
;
; retval
; eax= error code
align 4
uart_reset:
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
mov eax, [eax+CONNECTION.uart]
test eax, eax
jz .fail
; set mode 2400 bod 8-bit ; set mode 2400 bod 8-bit
; disable DTR & RTS ; disable DTR & RTS
; clear FIFO ; clear FIFO
@ -259,7 +311,7 @@ restore out_size
; eax= uart ; eax= uart
align 4 align 4
uart_reset: .internal:
mov esi, eax mov esi, eax
mov [eax+UART.state], UART_CLOSED mov [eax+UART.state], UART_CLOSED
mov edx, [eax+UART.base] mov edx, [eax+UART.base]
@ -322,22 +374,28 @@ uart_reset:
in al, dx in al, dx
jmp .clear_IIR jmp .clear_IIR
.done: .done:
lea edi, [esi+UART.rcvr_buffer] mov edi, [esi+UART.xmit_buff]
mov ecx, 256/4 mov ecx, 8192/4
xor eax, eax xor eax, eax
mov [esi+UART.rcvr_rp], eax mov [esi+UART.xmit_rp], edi
mov [esi+UART.rcvr_wp], eax mov [esi+UART.xmit_wp], edi
mov [esi+UART.rcvr_free], 128 mov [esi+UART.xmit_count], eax
mov [esi+UART.xmit_rp], eax mov [esi+UART.xmit_free], 8192
mov [esi+UART.xmit_wp], eax
mov [esi+UART.xmit_free], 128
cld cld
rep stosd rep stosd
ret
; mov [esi+UART.rcvr_rp], eax
; mov [esi+UART.rcvr_wp], eax
; mov [esi+UART.rcvr_cnt], eax
ret
.fail:
or eax, -1
ret
; param ; param
; esi= input buffer ; esi= input buffer
; +0 connection ; +0 connection
@ -406,15 +464,39 @@ align 4
or eax, -1 or eax, -1
ret ret
; param
; esi= input buffer
; +0 connection
; +4 modem control reg valie
;
; retval
; eax= error code
align 4 align 4
uart_set_modem: uart_set_mcr:
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
mov eax, [eax+CONNECTION.uart]
test eax, eax
jz .fail
mov ebx, [esi+4]
mov [eax+UART.mcr_reg], ebx mov [eax+UART.mcr_reg], ebx
mov edx, [eax+UART.base] mov edx, [eax+UART.base]
add edx, MCR_REG add edx, MCR_REG
mov al, bl mov al, bl
out dx, al out dx, al
xor eax, eax
ret
.fail:
or eax, -1
ret ret
; param ; param
@ -444,7 +526,7 @@ uart_open:
jnz .do_wait jnz .do_wait
mov eax, esi ;uart mov eax, esi ;uart
call uart_reset call uart_reset.internal
mov ebx, [CURRENT_TASK] mov ebx, [CURRENT_TASK]
shl ebx, 5 shl ebx, 5
@ -534,56 +616,145 @@ align 4
transmit: transmit:
push esi push esi
push edi push edi
push ebp
mov edx, [ebx+UART.base] mov edx, [ebx+UART.base]
pushfd pushfd
cli cli
mov ebp, 16
mov esi, [ebx+UART.xmit_rp] mov esi, [ebx+UART.xmit_rp]
lea edi, [ebx+UART.xmit_buffer] mov ecx, [ebx+UART.xmit_count]
mov ecx, [ebx+UART.xmit_free] test ecx, ecx
je .stop
cmp ecx, 128 cmp ecx, 16
je .exit jbe @F
mov ecx, 16
@@: @@:
and esi, 127 sub [ebx+UART.xmit_count], ecx
mov al, [esi+edi] add [ebx+UART.xmit_free], ecx
inc esi cld
@@:
lodsb
out dx, al out dx, al
inc ecx dec ecx
dec ebp jnz @B
jz .done
cmp ecx, 128 cmp esi,[ebx+UART.xmit_top]
jne @B jb @F
.done: sub esi, 8192
@@:
mov [ebx+UART.xmit_rp], esi mov [ebx+UART.xmit_rp], esi
mov [ebx+UART.xmit_free], ecx
cmp [ebx+UART.xmit_count], 0
je .stop
mov [ebx+UART.state], UART_TRANSMIT mov [ebx+UART.state], UART_TRANSMIT
.exit: jmp @F
.stop:
mov [ebx+UART.state], UART_STOP
@@:
popfd popfd
pop ebp
pop edi pop edi
pop esi pop esi
ret ret
; param
; esi= input buffer
; +0 connection
; +4 dst buffer
; +8 dst size
; edi= output buffer
; +0 bytes read
; retval
; eax= error code
align 4
uart_read:
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
mov eax, [eax+CONNECTION.uart]
test eax, eax
jz .fail
mov ebx, [esi+8] ;dst size
mov ecx, [eax+UART.rcvr_cnt]
cmp ecx, ebx
jbe @F
mov ecx, ebx
@@:
mov [edi], ecx ;bytes read
test ecx, ecx
jz .done
sub [eax+UART.rcvr_cnt], ecx
push eax
mov edi, [esi+4] ;dst
; lea esi, [eax+RCVR_OFFSET]
mov ebx, [eax+UART.rcvr_rp]
cld
@@:
and ebx, 127
mov al, [esi+ebx]
stosb
inc ebx
dec ecx
jnz @B
pop eax
mov [eax+UART.rcvr_rp], ebx
.done:
xor eax, eax
rep
.fail:
or eax, -1
ret
; param
; esi= input buffer
; +0 connection
; +4 src buffer
; +8 src size
;
; retval
; eax= error code
align 4
uart_write:
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
mov eax, [eax+CONNECTION.uart]
test eax, eax
jz .fail
mov ebx, [esi+4]
mov edx, [esi+8]
; param ; param
; eax= uart ; eax= uart
; ebx= src ; ebx= src
; edx= count ; edx= count
align 4 align 4
uart_write: .internal:
mov esi, ebx mov esi, ebx
mov edi, [eax+UART.xmit_wp] mov edi, [eax+UART.xmit_wp]
lea ebx, [eax+UART.xmit_buffer]
.write: .write:
test edx, edx test edx, edx
jz .done jz .fail
.wait: .wait:
cmp [eax+UART.xmit_free], 0 cmp [eax+UART.xmit_free], 0
jne .fill jne .fill
@ -596,40 +767,38 @@ uart_write:
call transmit call transmit
pop edx pop edx
mov eax, ebx mov eax, ebx
lea ebx, [ebx+UART.xmit_buffer]
jmp .write jmp .write
.fill: .fill:
mov ecx, 128
sub ecx, edi
jz .clip
cmp ecx, [eax+UART.xmit_free]
jbe @F
mov ecx, [eax+UART.xmit_free] mov ecx, [eax+UART.xmit_free]
@@:
cmp ecx, edx cmp ecx, edx
jbe @F jbe @F
mov ecx, edx mov ecx, edx
@@: @@:
sub [eax+UART.xmit_free], ecx push ecx
sub edx, ecx
add edi, ebx
cld cld
rep movsb rep movsb
pop ecx
sub edi, ebx sub [eax+UART.xmit_free], ecx
.clip: add [eax+UART.xmit_count], ecx
and edi, 127 sub edx, ecx
jmp .write jnz .wait
.done: .done:
cmp edi, [eax+UART.xmit_top]
jb @F
sub edi, 8192
@@:
mov [eax+UART.xmit_wp], edi mov [eax+UART.xmit_wp], edi
cmp [eax+UART.state], UART_TRANSMIT cmp [eax+UART.state], UART_TRANSMIT
je @F je @F
mov ebx, eax mov ebx, eax
call transmit call transmit
@@: @@:
xor eax, eax
ret ret
.fail:
or eax, -1
ret
align 4 align 4
com_2_isr: com_2_isr:
@ -638,7 +807,6 @@ com_2_isr:
align 4 align 4
com_1_isr: com_1_isr:
mov ebx, [com1] mov ebx, [com1]
.get_info: .get_info:
mov edx, [ebx+UART.base] mov edx, [ebx+UART.base]
add edx, IIR_REG add edx, IIR_REG
@ -684,16 +852,13 @@ align 4
uart_func dd 0 ;SRV_GETVERSION uart_func dd 0 ;SRV_GETVERSION
dd 0 ;PORT_OPEN dd 0 ;PORT_OPEN
dd uart_close ;PORT_CLOSE dd uart_close ;PORT_CLOSE
dd 0 ;PORT_RESET dd uart_reset ;PORT_RESET
dd uart_set_mode ;PORT_SETMODE dd uart_set_mode ;PORT_SETMODE
; dd uart.get_mode ;PORT_GETMODE dd 0 ;PORT_GETMODE
; dd uart.set_mcr ;PORT_SETMCR dd uart_set_mcr ;PORT_SETMODEM
;PORT_GETMCR equ 7 dd 0 ;PORT_GETMODEM
;PORT_READ equ 8 dd uart_read ;PORT_READ
;PORT_WRITE equ 9 dd uart_write ;PORT_WRITE
isr_action dd isr_modem isr_action dd isr_modem
dd transmit dd transmit