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