bsd_fdintr.s revision 1.11 1 /* $NetBSD: bsd_fdintr.s,v 1.11 1997/04/07 21:00:36 pk Exp $ */
2
3 /*
4 * Copyright (c) 1995 Paul Kranenburg
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Paul Kranenburg.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34 #ifndef FDC_C_HANDLER
35 #include "assym.h"
36 #include <machine/param.h>
37 #include <machine/psl.h>
38 #include <sparc/sparc/intreg.h>
39 #include <sparc/sparc/auxreg.h>
40 #include <sparc/sparc/vaddrs.h>
41 #include <sparc/dev/fdreg.h>
42 #include <sparc/dev/fdvar.h>
43
44 #define FD_SET_SWINTR_4C \
45 sethi %hi(INTRREG_VA), %l5; \
46 ldub [%l5 + %lo(INTRREG_VA)], %l6; \
47 or %l6, IE_L4, %l6; \
48 stb %l6, [%l5 + %lo(INTRREG_VA)]
49
50 ! raise(0,PIL_AUSOFT) ! NOTE: CPU#0 and PIL_AUSOFT=4
51 #define FD_SET_SWINTR_4M \
52 sethi %hi(1 << (16 + 4)), %l5; \
53 set ICR_PI_SET, %l6; \
54 st %l5, [%l6]
55
56 /* set software interrupt */
57 #if (defined(SUN4) || defined(SUN4C)) && !defined(SUN4M)
58 #define FD_SET_SWINTR FD_SET_SWINTR_4C
59 #elif !(defined(SUN4) || defined(SUN4C)) && defined(SUN4M)
60 #define FD_SET_SWINTR FD_SET_SWINTR_4M
61 #else
62 #define FD_SET_SWINTR \
63 sethi %hi(_cputyp), %l5; \
64 ld [%l5 + %lo(_cputyp)], %l5; \
65 cmp %l5, CPU_SUN4M; \
66 be 8f; \
67 FD_SET_SWINTR_4C; \
68 ba,a 9f; \
69 8: \
70 FD_SET_SWINTR_4M; \
71 9:
72 #endif
73
74 ! flip TC bit in auxreg
75 ! assumes %l6 remains unchanged between ASSERT and DEASSERT
76 #define FD_ASSERT_TC_4C \
77 sethi %hi(AUXREG_VA), %l6; \
78 ldub [%l6 + %lo(AUXREG_VA) + 3], %l7; \
79 or %l7, AUXIO4C_MB1|AUXIO4C_FTC, %l7; \
80 stb %l7, [%l6 + %lo(AUXREG_VA) + 3];
81
82 #define FD_DEASSERT_TC_4C \
83 ldub [%l6 + %lo(AUXREG_VA) + 3], %l7; \
84 andn %l7, AUXIO4C_FTC, %l7; \
85 or %l7, AUXIO4C_MB1, %l7; \
86 stb %l7, [%l6 + %lo(AUXREG_VA) + 3];
87
88 ! flip TC bit in auxreg
89 #define FD_ASSERT_TC_4M \
90 sethi %hi(AUXREG_VA), %l6; \
91 ldub [%l6 + %lo(AUXREG_VA) + 3], %l7; \
92 or %l7, AUXIO4M_MB1|AUXIO4M_FTC, %l7; \
93 stb %l7, [%l6 + %lo(AUXREG_VA) + 3];
94
95 #define FD_DEASSERT_TC_4M
96
97 /*
98 * flip TC bit in auxreg
99 * assumes %l5 remains unchanged between ASSERT and DEASSERT
100 */
101 #if (defined(SUN4) || defined(SUN4C)) && !defined(SUN4M)
102 #define FD_ASSERT_TC FD_ASSERT_TC_4C
103 #define FD_DEASSERT_TC FD_DEASSERT_TC_4C
104 #elif !(defined(SUN4) || defined(SUN4C)) && defined(SUN4M)
105 #define FD_ASSERT_TC FD_ASSERT_TC_4M
106 #define FD_DEASSERT_TC FD_DEASSERT_TC_4M
107 #else
108 #define FD_ASSERT_TC \
109 sethi %hi(_cputyp), %l5; \
110 ld [%l5 + %lo(_cputyp)], %l5; \
111 cmp %l5, CPU_SUN4M; \
112 be 8f; \
113 nop; \
114 FD_ASSERT_TC_4C; \
115 ba,a 9f; \
116 8: \
117 FD_ASSERT_TC_4M; \
118 9:
119 #define FD_DEASSERT_TC \
120 cmp %l5, CPU_SUN4M; \
121 be 8f; \
122 nop; \
123 FD_DEASSERT_TC_4C; \
124 ba,a 9f; \
125 8: \
126 FD_DEASSERT_TC_4M; \
127 9:
128 #endif
129
130
131 /* Timeout waiting for chip ready */
132 #define POLL_TIMO 100000
133
134 /*
135 * register mnemonics. note overlapping assignments.
136 */
137 #define R_fdc %l0
138 #define R_msr %l1
139 #define R_fifo %l2
140 #define R_buf %l3
141 #define R_tc %l4
142 #define R_stat %l3
143 #define R_nstat %l4
144 #define R_stcnt %l5
145 /* use %l6 and %l7 as short term temporaries */
146
147
148 .seg "data"
149 .align 8
150 .global _fdciop
151 /* A save haven for three precious registers */
152 save_l:
153 .word 0
154 .word 0
155 .word 0
156 /* Pointer to a `struct fdcio', set in fd.c */
157 _fdciop:
158 .word 0
159
160 .seg "text"
161 .align 4
162 .global _fdchwintr
163
164 _fdchwintr:
165 set save_l, %l7
166 std %l0, [%l7]
167 st %l2, [%l7 + 8]
168
169 ! tally interrupt
170 sethi %hi(_cnt+V_INTR), %l7
171 ld [%l7 + %lo(_cnt+V_INTR)], %l6
172 inc %l6
173 st %l6, [%l7 + %lo(_cnt+V_INTR)]
174
175 ! load fdc, if it's NULL there's nothing to do: schedule soft interrupt
176 sethi %hi(_fdciop), %l7
177 ld [%l7 + %lo(_fdciop)], R_fdc
178
179 ! tally interrupt
180 ld [R_fdc + FDC_EVCNT], %l6
181 inc %l6
182 st %l6, [R_fdc + FDC_EVCNT]
183
184 ! load chips register addresses
185 ld [R_fdc + FDC_REG_MSR], R_msr ! get chip MSR reg addr
186 ld [R_fdc + FDC_REG_FIFO], R_fifo ! get chip FIFO reg addr
187 !!ld [R_fdc + FDC_REG_DOR], R_dor ! get chip DOR reg addr
188
189 ! find out what we are supposed to do
190 ld [R_fdc + FDC_ISTATE], %l7 ! examine flags
191 cmp %l7, ISTATE_SENSEI
192 be sensei
193 nop
194 cmp %l7, ISTATE_DMA
195 bne spurious
196 nop
197
198 ! pseudo DMA
199 ld [R_fdc + FDC_TC], R_tc ! residual count
200 ld [R_fdc + FDC_DATA], R_buf ! IO buffer
201
202 ldub [R_msr], %l7 ! get MSR value
203 nextc:
204 btst NE7_RQM, %l7 ! room in fifo?
205 bnz,a 0f
206 btst NE7_NDM, %l7 ! overrun?
207
208 ! we filled/emptied the FIFO; update fdc->sc_buf & fdc->sc_tc
209 st R_tc, [R_fdc + FDC_TC]
210 b x
211 st R_buf, [R_fdc + FDC_DATA]
212
213 0:
214 bz resultphase ! overrun/underrun
215 btst NE7_DIO, %l7 ! IO direction
216 bz 1f
217 deccc R_tc
218 ldub [R_fifo], %l7 ! reading:
219 b 2f
220 stb %l7, [R_buf] ! *fdc->sc_bufp = *reg_fifo
221
222 1:
223 ldub [R_buf], %l7 ! writing:
224 stb %l7, [R_fifo] ! *reg_fifo = *fdc->sc_bufp
225 2:
226 inc R_buf ! fdc->sc_bufp++
227 bne,a nextc ! if (--fdc->sc_tc) goto ...
228 ldub [R_msr], %l7 ! get MSR value
229
230 ! xfer done: update fdc->sc_buf & fdc->sc_tc, mark istate DONE
231 st R_tc, [R_fdc + FDC_TC]
232 st R_buf, [R_fdc + FDC_DATA]
233
234 ! flip TC bit in auxreg
235 FD_ASSERT_TC
236
237 ! we have some time to kill; anticipate on upcoming
238 ! result phase.
239 add R_fdc, FDC_STATUS, R_stat ! &fdc->sc_status[0]
240 mov -1, %l7
241 st %l7, [R_fdc + FDC_NSTAT] ! fdc->sc_nstat = -1;
242
243 FD_DEASSERT_TC
244 b,a resultphase1
245
246 spurious:
247 mov ISTATE_SPURIOUS, %l7
248 st %l7, [R_fdc + FDC_ISTATE]
249 b,a ssi
250
251 sensei:
252 ldub [R_msr], %l7
253 set POLL_TIMO, %l6
254 1: deccc %l6 ! timeout?
255 be ssi
256 and %l7, (NE7_RQM | NE7_DIO | NE7_CB), %l7
257 cmp %l7, NE7_RQM
258 bne,a 1b ! loop till chip ready
259 ldub [R_msr], %l7
260 mov NE7CMD_SENSEI, %l7
261 stb %l7, [R_fifo]
262
263 resultphase:
264 ! prepare for result phase
265 add R_fdc, FDC_STATUS, R_stat ! &fdc->sc_status[0]
266 mov -1, %l7
267 st %l7, [R_fdc + FDC_NSTAT] ! fdc->sc_nstat = -1;
268
269 resultphase1:
270 clr R_stcnt
271 ldub [R_msr], %l7
272 set POLL_TIMO, %l6
273 1: deccc %l6 ! timeout?
274 be ssi
275 and %l7, (NE7_RQM | NE7_DIO | NE7_CB), %l7
276 cmp %l7, NE7_RQM
277 be 3f ! done
278 cmp %l7, (NE7_RQM | NE7_DIO | NE7_CB)
279 bne,a 1b ! loop till chip ready
280 ldub [R_msr], %l7
281
282 cmp R_stcnt, FDC_NSTATUS ! status overrun?
283 bge 2f ! if so, load but dont store
284 ldub [R_fifo], %l7 ! load the status byte
285 stb %l7, [R_stat]
286 inc R_stat
287 inc R_stcnt
288 2: b 1b
289 ldub [R_msr], %l7
290
291 3:
292 ! got status, update sc_nstat and mark istate DONE
293 st R_stcnt, [R_fdc + FDC_NSTAT]
294 mov ISTATE_DONE, %l7
295 st %l7, [R_fdc + FDC_ISTATE]
296
297 ssi:
298 ! set software interrupt
299 FD_SET_SWINTR
300
301 x:
302 /*
303 * Restore psr -- note: psr delay honored by pc restore loads.
304 */
305 set save_l, %l7
306 ldd [%l7], %l0
307 mov %l0, %psr
308 nop
309 ld [%l7 + 8], %l2
310 jmp %l1
311 rett %l2
312 #endif
313