199 lines
2.3 KiB
PHP
199 lines
2.3 KiB
PHP
;; File: com.inc
|
|
;; UART 8250, 16750 driver
|
|
;;
|
|
;; Usefull links:
|
|
;; - <PC16550D datasheet at https://www.scs.stanford.edu/10wi-cs140/pintos/specs/pc16550d.pdf>
|
|
|
|
COM1 = 0x3F8
|
|
COM2 = 0x2F8
|
|
COM3 = 0x3E8
|
|
COM4 = 0x2E8
|
|
|
|
NCOM = 4
|
|
|
|
UART8250_RBR = 0x0
|
|
UART8250_THR = 0x0
|
|
|
|
UART8250_IER = 0x1
|
|
UART8250_IER_RDA = 0x1
|
|
UART8250_IER_THRE = 0x2
|
|
UART8250_IER_RLSRC = 0x4
|
|
UART8250_IER_MSRC = 0x8
|
|
UART16750_IER_SLEEP = 0x10
|
|
UART16750_IER_LPM = 0x20
|
|
|
|
UART8250_IIR = 0x2
|
|
|
|
UART8250_FCR = 0x2
|
|
UART8250_FCR_EN = 0x1
|
|
UART8250_FCR_CLSR = 0x2
|
|
UART8250_FCR_CLST = 0x4
|
|
UART8250_FCR_DMA = 0x8
|
|
UART16750_FCR_64EN = 0x20
|
|
|
|
UART8250_LCR = 0x3
|
|
UART8250_MCR = 0x4
|
|
UART8250_MCR_OUT2 = 0x08
|
|
UART8250_LSR = 0x5
|
|
UART8250_LSR_THRE = 0x20
|
|
UART8250_MSR = 0x6
|
|
UART8250_SCR = 0x7
|
|
|
|
; DLAB = 1
|
|
UART8250_DLL = 0x0
|
|
UART8250_DLH = 0x1
|
|
|
|
com_init:
|
|
push ebx
|
|
xor cx, cx
|
|
.loop:
|
|
inc ch
|
|
|
|
; get io address
|
|
movzx eax, cl
|
|
shl eax, 1
|
|
add eax, aComPorts
|
|
mov bx, [eax]
|
|
|
|
mov ax, bx
|
|
push ecx
|
|
call com_probe
|
|
pop ecx
|
|
or eax, eax
|
|
jnz @f
|
|
; comX found yeah
|
|
movzx eax, ch
|
|
push ecx
|
|
push eax
|
|
mov esi, szMsgComFound
|
|
call klog
|
|
pop ecx
|
|
|
|
; mark comX as active
|
|
mov al, 1
|
|
shl al, cl
|
|
or byte [uComActive], al
|
|
@@:
|
|
inc cl
|
|
cmp cl, NCOM
|
|
jb .loop
|
|
|
|
pop ebx
|
|
ret
|
|
|
|
;; Function: com_probe
|
|
;;
|
|
;; In:
|
|
;; AX - IO port
|
|
com_probe:
|
|
mov dx, ax
|
|
add dx, UART8250_LCR
|
|
xor al, al
|
|
out dx, al
|
|
dec dx
|
|
out dx, al
|
|
xor ecx, ecx
|
|
|
|
;; wait a little
|
|
@@:
|
|
inc ecx
|
|
cmp ecx, 100
|
|
jbe @b
|
|
|
|
in al, dx
|
|
and al, 0x38
|
|
or al, al
|
|
jz @f
|
|
mov eax, 1
|
|
ret
|
|
@@:
|
|
xor eax, eax
|
|
ret
|
|
|
|
;; Function: com_putc
|
|
;;
|
|
;; In:
|
|
;; AL - Char to print
|
|
;; DX - IO port
|
|
;;
|
|
com_putc:
|
|
add dx, UART8250_LSR
|
|
push eax
|
|
@@:
|
|
in al, dx
|
|
and al, UART8250_LSR_THRE
|
|
jnz @b
|
|
pop eax
|
|
sub dx, UART8250_LSR
|
|
out dx, al
|
|
ret
|
|
ret
|
|
|
|
com_irq1:
|
|
pusha
|
|
mov esi, szMsgComIRQ
|
|
call klog
|
|
popa
|
|
iret
|
|
|
|
com_irq2:
|
|
pusha
|
|
popa
|
|
iret
|
|
|
|
com_open:
|
|
ret
|
|
|
|
com_close:
|
|
ret
|
|
|
|
com_read:
|
|
ret
|
|
|
|
com_write:
|
|
ret
|
|
|
|
com_ioctl:
|
|
ret
|
|
|
|
com_select:
|
|
ret
|
|
|
|
com_stop:
|
|
ret
|
|
|
|
com_mmap:
|
|
ret
|
|
|
|
com_reset:
|
|
ret
|
|
|
|
uCom1Lock dd 0
|
|
uCom2Lock dd 0
|
|
uComActive db 0
|
|
|
|
szMsgComFound db "COM: com%u found", 0
|
|
szMsgComIRQ db "com irq", 0
|
|
|
|
aComPorts:
|
|
dw COM1
|
|
dw COM2
|
|
dw COM3
|
|
dw COM4
|
|
.end:
|
|
|
|
com_device:
|
|
db 'com', 0, 0, 0, 0, 0
|
|
dd com_init
|
|
|
|
com_cdevsw:
|
|
dd com_open
|
|
dd com_close
|
|
dd com_read
|
|
dd com_write
|
|
dd com_ioctl
|
|
dd com_select
|
|
dd com_stop
|
|
dd com_mmap
|
|
dd com_reset
|