Contents of /trunk/mkinitrd-magellan/isolinux/serirq.inc
Parent Directory | Revision Log
Revision 1133 -
(show annotations)
(download)
Thu Aug 19 09:50:43 2010 UTC (14 years, 1 month ago) by niro
File size: 4022 byte(s)
Thu Aug 19 09:50:43 2010 UTC (14 years, 1 month ago) by niro
File size: 4022 byte(s)
-updated to isolinux-3.86
1 | ;; ----------------------------------------------------------------------- |
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 |