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