aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-05-23 17:40:17 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-05-23 17:40:17 -0700
commit2b052241f002e2cfe3fed022e56bbc7fb532939c (patch)
treeb2257bc5f3ca5cb2ba5529a634572bb15429c3eb /core
parenta7f5583796e1b38b1fabd9d50f65e724468541d3 (diff)
downloadsyslinux.git-2b052241f002e2cfe3fed022e56bbc7fb532939c.tar.gz
syslinux.git-2b052241f002e2cfe3fed022e56bbc7fb532939c.tar.xz
syslinux.git-2b052241f002e2cfe3fed022e56bbc7fb532939c.zip
core: add file missing from previous checkin (serirq.inc)syslinux-3.81-pre11
Add the file serirq.inc missing from previous checkin. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'core')
-rw-r--r--core/serirq.inc184
1 files changed, 184 insertions, 0 deletions
diff --git a/core/serirq.inc b/core/serirq.inc
new file mode 100644
index 00000000..8b04728a
--- /dev/null
+++ b/core/serirq.inc
@@ -0,0 +1,184 @@
+;; -----------------------------------------------------------------------
+;;
+;; Copyright 2009 Intel Corporation; author: H. Peter Anvin
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+;; Boston MA 02111-1307, USA; either version 2 of the License, or
+;; (at your option) any later version; incorporated herein by reference.
+;;
+;; -----------------------------------------------------------------------
+
+;;
+;; serirq.inc
+;;
+;; Serial port IRQ code
+;;
+;; We don't know what IRQ, if any, we have, so map all of them...
+;;
+
+ section .text
+ bits 16
+ align 8
+
+ section .bss
+ alignb 8
+
+%assign n 0
+%rep 16
+ section .text
+serstub_irq %+ n :
+ push dword [cs:oldirq %+ n]
+ jmp short irq_common
+
+ section .bss
+oldirq %+ n resd 1
+%assign n n+1
+%endrep
+
+ section .text
+irq_common:
+ pushf
+ push ax
+ push dx
+ mov dx,[cs:SerialPort]
+ add dx,5 ; DX -> LSR
+ in al,dx
+ test al,1 ; Received data
+ jnz .data
+.done:
+ pop dx
+ pop ax
+ popf
+ retf ; Chain to next handler
+.data:
+ push es
+ push di
+ mov ax,aux_seg + (aux.serial >> 4)
+ mov es,ax
+ mov di,[cs:SerialHead]
+.loop:
+ mov dx,[cs:SerialPort] ; DX -> RDR
+ in al,dx
+ stosb
+ mov ah,[cs:FlowIgnore]
+ add dx,5 ; DX -> LSR
+ in al,dx
+ push ax
+ and al,ah
+ cmp al,ah
+ jne .drop
+ and di,serial_buf_size-1 ; Wrap around if necessary
+ cmp di,[cs:SerialTail] ; Would this cause overflow?
+ je .drop ; If so, just drop the data
+ mov [cs:SerialHead],di
+.drop:
+ pop ax
+ test al,1 ; More data?
+ jnz .loop
+.full:
+ pop di
+ pop es
+ jmp .done
+
+ section .data
+;
+; SerialIRQPort will generally track SerialPort, but will be 0 when an
+; IRQ service is not installed.
+;
+SerialIRQPort dw 0 ; Serial port w IRQ service
+SerialHead dw 0 ; Head of serial port rx buffer
+SerialTail dw 0 ; Tail of serial port rx buffer
+
+sirq_install:
+ pushad
+
+ call sirq_cleanup
+
+ ; Save the old interrupt vectors
+ mov si,4*08h
+ mov di,oldirq0
+ mov cx,8
+ rep movsd
+ mov si,4*70h
+ mov cx,8
+ rep movsd
+
+ ; Install new interrupt vectors
+ mov di,4*08h
+ mov cx,8
+ mov eax,serstub_irq0
+.pic0:
+ stosd
+ add ax,serstub_irq1 - serstub_irq0
+ loop .pic0
+ mov di,4*70h
+ mov cx,8
+.pic1:
+ stosd
+ add ax,serstub_irq1 - serstub_irq0
+ loop .pic1
+
+ mov bx,[SerialPort]
+ mov [SerialIRQPort],bx
+
+ lea dx,[bx+5] ; DX -> LCR
+ in al,dx
+ and al,7Fh ; Clear DLAB (should already be...)
+ slow_out dx,al
+
+ lea dx,[bx+1] ; DX -> IER
+ mov al,1 ; Enable receive interrupt
+ slow_out dx,al
+
+ popad
+ ret
+
+sirq_cleanup:
+ pushad
+ push ds
+ push es
+ xor ax,ax
+ mov ds,ax
+ mov es,ax
+
+ mov bx,[SerialIRQPort]
+ and bx,bx
+ jz .done
+
+ lea dx,[bx+5] ; DX -> LCR
+ in al,dx
+ and al,7Fh ; Clear DLAB (should already be...)
+ slow_out dx,al
+
+ lea dx,[bx+1] ; DX -> IER
+ xor ax,ax
+ slow_out dx,al ; Clear IER
+
+ ; Restore the original interrupt vectors
+ mov si,oldirq0
+ mov di,4*08h
+ mov cx,8
+ rep movsd
+ mov di,4*70h
+ mov cx,8
+ rep movsd
+
+ ; Just in case it might contain a password, erase the
+ ; serial port receive buffer...
+ mov [SerialIRQPort],ax
+ mov [SerialHead],eax
+ mov cx,aux_seg + (aux.serial >> 4)
+ mov es,cx
+ mov cx,serial_buf_size >> 2
+ xor di,di
+ rep stosd
+
+.done:
+ pop es
+ pop ds
+ popad
+ ret
+
+ section .text