Magellan Linux

Annotation of /tags/mkinitrd-6_3_2/isolinux/serirq.inc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1164 - (hide annotations) (download)
Tue Sep 14 20:33:28 2010 UTC (13 years, 8 months ago) by niro
File size: 4022 byte(s)
tagged 'mkinitrd-6_3_2'
1 niro 1133 ;; -----------------------------------------------------------------------
2     ;;
3     ;; Copyright 2009 Intel Corporation; author: H. Peter Anvin
4     ;;
5     ;; This program is free software; you can redistribute it and/or modify
6     ;; it under the terms of the GNU General Public License as published by
7     ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8     ;; Boston MA 02111-1307, USA; either version 2 of the License, or
9     ;; (at your option) any later version; incorporated herein by reference.
10     ;;
11     ;; -----------------------------------------------------------------------
12    
13     ;;
14     ;; serirq.inc
15     ;;
16     ;; Serial port IRQ code
17     ;;
18     ;; We don't know what IRQ, if any, we have, so map all of them...
19     ;;
20    
21     section .text
22     bits 16
23     align 8
24    
25     section .bss
26     alignb 8
27    
28     %assign n 0
29     %rep 16
30     section .text
31     serstub_irq %+ n :
32     push dword [cs:oldirq %+ n]
33     jmp short irq_common
34    
35     section .bss
36     oldirq %+ n resd 1
37     %assign n n+1
38     %endrep
39    
40     section .text
41     irq_common:
42     pushf
43     push ax
44     push dx
45     mov dx,[cs:SerialPort]
46     add dx,5 ; DX -> LSR
47     in al,dx
48     test al,1 ; Received data
49     jnz .data
50     .done:
51     pop dx
52     pop ax
53     popf
54     retf ; Chain to next handler
55     .data:
56     push es
57     push di
58     mov ax,aux_seg + (aux.serial >> 4)
59     mov es,ax
60     mov di,[cs:SerialHead]
61     .loop:
62     mov dx,[cs:SerialPort] ; DX -> RDR
63     in al,dx
64     stosb
65     mov ah,[cs:FlowIgnore]
66     add dx,5 ; DX -> LSR
67     in al,dx
68     push ax
69     and al,ah
70     cmp al,ah
71     jne .drop
72     and di,serial_buf_size-1 ; Wrap around if necessary
73     cmp di,[cs:SerialTail] ; Would this cause overflow?
74     je .drop ; If so, just drop the data
75     mov [cs:SerialHead],di
76     .drop:
77     pop ax
78     test al,1 ; More data?
79     jnz .loop
80     .full:
81     pop di
82     pop es
83     jmp .done
84    
85     section .data
86     ;
87     ; SerialIRQPort will generally track SerialPort, but will be 0 when an
88     ; IRQ service is not installed.
89     ;
90     SerialIRQPort dw 0 ; Serial port w IRQ service
91     SerialHead dw 0 ; Head of serial port rx buffer
92     SerialTail dw 0 ; Tail of serial port rx buffer
93    
94     section .bss
95     IRQMask resw 1 ; PIC IRQ mask status
96    
97     section .text
98    
99     sirq_install:
100     pushad
101    
102     call sirq_cleanup
103    
104     ; Save the old interrupt vectors
105     mov si,4*08h
106     mov di,oldirq0
107     mov cx,8
108     rep movsd
109     mov si,4*70h
110     mov cx,8
111     rep movsd
112    
113     ; Install new interrupt vectors
114     mov di,4*08h
115     mov cx,8
116     mov eax,serstub_irq0
117     .pic0:
118     stosd
119     add ax,serstub_irq1 - serstub_irq0
120     loop .pic0
121     mov di,4*70h
122     mov cx,8
123     .pic1:
124     stosd
125     add ax,serstub_irq1 - serstub_irq0
126     loop .pic1
127    
128     mov bx,[SerialPort]
129     mov [SerialIRQPort],bx
130    
131     lea dx,[bx+5] ; DX -> LCR
132     mov al,03h ; Clear DLAB (should already be...)
133     slow_out dx,al
134    
135     lea dx,[bx+1] ; DX -> IER
136     mov al,1 ; Enable receive interrupt
137     slow_out dx,al
138    
139     ;
140     ; Enable all ther interupt lines at the PIC. Some BIOSes
141     ; only enable the timer interrupts and other interrupts
142     ; actively in use by the BIOS.
143     ;
144     in al,0xA1 ; Secondary PIC mask register
145     mov ah,al
146     in al,0x21 ; Primary PIC mask register
147     mov [IRQMask],ax
148    
149     io_delay
150    
151     xor ax,ax ; Remove all interrupt masks
152     out 0x21,al
153     out 0xA1,al
154    
155     popad
156     ret
157    
158     sirq_cleanup_nowipe:
159     pushad
160     push ds
161     push es
162     xor ax,ax
163     mov ds,ax
164     mov es,ax
165    
166     mov bx,[SerialIRQPort]
167     and bx,bx
168     jz .done
169    
170     lea dx,[bx+5] ; DX -> LCR
171     mov al,03h ; Clear DLAB (should already be...)
172     slow_out dx,al
173    
174     lea dx,[bx+1] ; DX -> IER
175     xor ax,ax
176     slow_out dx,al ; Clear IER
177    
178     ; Restore PIC masks
179     mov ax,[IRQMask]
180     out 0x21,al
181     mov al,ah
182     out 0xA1,al
183    
184     ; Restore the original interrupt vectors
185     mov si,oldirq0
186     mov di,4*08h
187     mov cx,8
188     rep movsd
189     mov di,4*70h
190     mov cx,8
191     rep movsd
192    
193     xor ax,ax
194     mov [SerialIRQPort],ax ; No active interrupt system
195    
196     .done:
197     pop es
198     pop ds
199     popad
200     ret
201    
202     sirq_cleanup:
203     call sirq_cleanup_nowipe
204     pushad
205     push es
206     ; Just in case it might contain a password, erase the
207     ; serial port receive buffer...
208     mov ax,aux_seg + (aux.serial >> 4)
209     mov es,ax
210     xor eax,eax
211     mov [cs:SerialHead],eax
212     mov cx,serial_buf_size >> 2
213     xor di,di
214     rep stosd
215     pop es
216     popad
217     ret
218    
219     section .text