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