siop.ss revision 1.10 1 1.10 bouyer ; $NetBSD: siop.ss,v 1.10 2000/10/18 17:01:13 bouyer Exp $
2 1.3 bouyer
3 1.3 bouyer ;
4 1.3 bouyer ; Copyright (c) 2000 Manuel Bouyer.
5 1.3 bouyer ;
6 1.3 bouyer ; Redistribution and use in source and binary forms, with or without
7 1.3 bouyer ; modification, are permitted provided that the following conditions
8 1.3 bouyer ; are met:
9 1.3 bouyer ; 1. Redistributions of source code must retain the above copyright
10 1.3 bouyer ; notice, this list of conditions and the following disclaimer.
11 1.3 bouyer ; 2. Redistributions in binary form must reproduce the above copyright
12 1.3 bouyer ; notice, this list of conditions and the following disclaimer in the
13 1.3 bouyer ; documentation and/or other materials provided with the distribution.
14 1.3 bouyer ; 3. All advertising materials mentioning features or use of this software
15 1.3 bouyer ; must display the following acknowledgement:
16 1.3 bouyer ; This product includes software developed by Manuel Bouyer
17 1.3 bouyer ; 4. The name of the author may not be used to endorse or promote products
18 1.3 bouyer ; derived from this software without specific prior written permission.
19 1.3 bouyer ;
20 1.5 bouyer ; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 1.5 bouyer ; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 1.5 bouyer ; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 1.5 bouyer ; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 1.5 bouyer ; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 1.5 bouyer ; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 1.5 bouyer ; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 1.5 bouyer ; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 1.5 bouyer ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 1.5 bouyer ; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 1.3 bouyer
31 1.1 bouyer ARCH 720
32 1.1 bouyer
33 1.2 bouyer ; offsets in sym_xfer
34 1.4 bouyer ABSOLUTE t_id = 24;
35 1.4 bouyer ABSOLUTE t_msg_in = 32;
36 1.4 bouyer ABSOLUTE t_ext_msg_in = 40;
37 1.4 bouyer ABSOLUTE t_ext_msg_data = 48;
38 1.5 bouyer ABSOLUTE t_msg_tag = 56;
39 1.4 bouyer ABSOLUTE t_msg_out = 64;
40 1.4 bouyer ABSOLUTE t_cmd = 72;
41 1.4 bouyer ABSOLUTE t_status = 80;
42 1.4 bouyer ABSOLUTE t_data = 88;
43 1.1 bouyer
44 1.1 bouyer ;; interrupt codes
45 1.10 bouyer ; interrupts that need a valid DSA
46 1.1 bouyer ABSOLUTE int_done = 0xff00;
47 1.1 bouyer ABSOLUTE int_msgin = 0xff01;
48 1.2 bouyer ABSOLUTE int_extmsgin = 0xff02;
49 1.2 bouyer ABSOLUTE int_extmsgdata = 0xff03;
50 1.10 bouyer ABSOLUTE int_disc = 0xff04;
51 1.10 bouyer ; interrupts that don't have a valid DSA
52 1.10 bouyer ABSOLUTE int_reseltarg = 0xff80;
53 1.10 bouyer ABSOLUTE int_resellun = 0xff81;
54 1.10 bouyer ABSOLUTE int_reseltag = 0xff82;
55 1.10 bouyer ABSOLUTE int_resfail = 0xff83;
56 1.1 bouyer ABSOLUTE int_err = 0xffff;
57 1.1 bouyer
58 1.1 bouyer ; flags for scratcha0
59 1.1 bouyer ABSOLUTE flag_sdp = 0x01 ; got save data pointer
60 1.4 bouyer ABSOLUTE flag_data = 0x02 ; we're in data phase
61 1.4 bouyer ABSOLUTE flag_data_mask = 0xfd ; ~flag_data
62 1.1 bouyer
63 1.10 bouyer ; main script symbols
64 1.10 bouyer
65 1.1 bouyer ENTRY waitphase;
66 1.2 bouyer ENTRY send_msgout;
67 1.1 bouyer ENTRY msgout;
68 1.1 bouyer ENTRY msgin;
69 1.10 bouyer ENTRY handle_msgin;
70 1.2 bouyer ENTRY msgin_ack;
71 1.1 bouyer ENTRY dataout;
72 1.1 bouyer ENTRY datain;
73 1.1 bouyer ENTRY cmdout;
74 1.1 bouyer ENTRY status;
75 1.1 bouyer ENTRY disconnect;
76 1.1 bouyer ENTRY reselect;
77 1.10 bouyer ENTRY reselected;
78 1.2 bouyer ENTRY selected;
79 1.10 bouyer ENTRY script_sched;
80 1.2 bouyer ENTRY get_extmsgdata;
81 1.10 bouyer ENTRY resel_targ0;
82 1.10 bouyer ENTRY msgin_space;
83 1.10 bouyer ENTRY lunsw_return;
84 1.10 bouyer EXTERN abs_targ0;
85 1.10 bouyer EXTERN abs_msgin;
86 1.10 bouyer
87 1.10 bouyer ; lun switch symbols
88 1.10 bouyer ENTRY resel_lun0;
89 1.10 bouyer ENTRY restore_scntl3;
90 1.10 bouyer EXTERN abs_lun0;
91 1.10 bouyer EXTERN abs_lunsw_return;
92 1.10 bouyer
93 1.10 bouyer ; command reselect script symbols
94 1.10 bouyer ENTRY rdsa0;
95 1.10 bouyer ENTRY rdsa1;
96 1.10 bouyer ENTRY rdsa2;
97 1.10 bouyer ENTRY rdsa3;
98 1.10 bouyer ENTRY reload_dsa;
99 1.10 bouyer
100 1.10 bouyer EXTERN resel_abs_reselected;
101 1.10 bouyer
102 1.10 bouyer ; command scheduler symbols
103 1.2 bouyer ENTRY slot;
104 1.2 bouyer ENTRY slotdata;
105 1.2 bouyer ENTRY nextslot;
106 1.2 bouyer
107 1.9 bouyer EXTERN script_abs_sched;
108 1.2 bouyer EXTERN slot_nextp;
109 1.9 bouyer EXTERN slot_sched_addrsrc;
110 1.2 bouyer EXTERN slot_abs_reselect;
111 1.2 bouyer EXTERN slot_abs_selected;
112 1.10 bouyer EXTERN slot_abs_loaddsa;
113 1.2 bouyer
114 1.2 bouyer EXTERN endslot_abs_reselect;
115 1.1 bouyer
116 1.10 bouyer ; main script
117 1.8 bouyer
118 1.1 bouyer PROC siop_script:
119 1.1 bouyer
120 1.10 bouyer reselected:
121 1.1 bouyer ; starting a new session, init 'local variables'
122 1.1 bouyer MOVE 0 to SCRATCHA0 ; flags
123 1.1 bouyer MOVE 0 to SCRATCHA1 ; DSA offset (for S/G save data pointer)
124 1.10 bouyer MOVE SCRATCHA3 to SFBR ; pending message ?
125 1.10 bouyer JUMP REL(handle_msgin), IF not 0x08;
126 1.1 bouyer waitphase:
127 1.1 bouyer JUMP REL(msgout), WHEN MSG_OUT;
128 1.1 bouyer JUMP REL(msgin), WHEN MSG_IN;
129 1.1 bouyer JUMP REL(dataout), WHEN DATA_OUT;
130 1.1 bouyer JUMP REL(datain), WHEN DATA_IN;
131 1.1 bouyer JUMP REL(cmdout), WHEN CMD;
132 1.1 bouyer JUMP REL(status), WHEN STATUS;
133 1.1 bouyer err:
134 1.1 bouyer INT int_err;
135 1.1 bouyer
136 1.1 bouyer reselect:
137 1.10 bouyer ; Clear DSA and init status
138 1.10 bouyer MOVE 0xff to DSA0;
139 1.10 bouyer MOVE 0xff to DSA1;
140 1.10 bouyer MOVE 0xff to DSA2;
141 1.10 bouyer MOVE 0xff to DSA3;
142 1.10 bouyer MOVE 0xff to SCRATCHA2; no tag
143 1.10 bouyer MOVE 0x08 to SCRATCHA3; NOP message
144 1.1 bouyer WAIT RESELECT REL(reselect_fail)
145 1.1 bouyer MOVE SSID & 0x8f to SFBR
146 1.1 bouyer MOVE SFBR to SCRATCHA0 ; save reselect ID
147 1.10 bouyer ; find the rigth param for this target
148 1.10 bouyer resel_targ0:
149 1.10 bouyer JUMP abs_targ0, IF 0xff;
150 1.10 bouyer JUMP abs_targ0, IF 0xff;
151 1.10 bouyer JUMP abs_targ0, IF 0xff;
152 1.10 bouyer JUMP abs_targ0, IF 0xff;
153 1.10 bouyer JUMP abs_targ0, IF 0xff;
154 1.10 bouyer JUMP abs_targ0, IF 0xff;
155 1.10 bouyer JUMP abs_targ0, IF 0xff;
156 1.10 bouyer JUMP abs_targ0, IF 0xff;
157 1.10 bouyer JUMP abs_targ0, IF 0xff;
158 1.10 bouyer JUMP abs_targ0, IF 0xff;
159 1.10 bouyer JUMP abs_targ0, IF 0xff;
160 1.10 bouyer JUMP abs_targ0, IF 0xff;
161 1.10 bouyer JUMP abs_targ0, IF 0xff;
162 1.10 bouyer JUMP abs_targ0, IF 0xff;
163 1.10 bouyer JUMP abs_targ0, IF 0xff;
164 1.10 bouyer INT int_reseltarg;
165 1.10 bouyer lunsw_return:
166 1.10 bouyer INT int_err, WHEN NOT MSG_IN;
167 1.10 bouyer MOVE 1, abs_msgin, WHEN MSG_IN;
168 1.10 bouyer MOVE SFBR & 0x07 to SCRATCHA1; save LUN
169 1.10 bouyer CLEAR ACK;
170 1.10 bouyer RETURN, WHEN NOT MSG_IN; If no more message, jump to lun sw
171 1.10 bouyer MOVE 1, abs_msgin, WHEN MSG_IN;
172 1.10 bouyer CLEAR ACK;
173 1.10 bouyer JUMP REL(gettag), IF 0x20; simple tag message ?
174 1.10 bouyer MOVE SFBR to SCRATCHA3; save message
175 1.10 bouyer RETURN; jump to lun sw and handle message
176 1.10 bouyer gettag:
177 1.1 bouyer INT int_err, WHEN NOT MSG_IN;
178 1.10 bouyer MOVE 1, abs_msgin, WHEN MSG_IN; get tag
179 1.10 bouyer CLEAR ACK;
180 1.10 bouyer MOVE SFBR to SCRATCHA2; save tag
181 1.10 bouyer RETURN; jump to lun sw
182 1.10 bouyer
183 1.1 bouyer reselect_fail:
184 1.2 bouyer ; check that host asserted SIGP, this'll clear SIGP in ISTAT
185 1.2 bouyer MOVE CTEST2 & 0x40 TO SFBR;
186 1.2 bouyer INT int_resfail, IF 0x00;
187 1.10 bouyer script_sched:
188 1.10 bouyer ; Clear DSA and init status
189 1.10 bouyer MOVE 0xff to DSA0;
190 1.10 bouyer MOVE 0xff to DSA1;
191 1.10 bouyer MOVE 0xff to DSA2;
192 1.10 bouyer MOVE 0xff to DSA3;
193 1.10 bouyer MOVE 0 to SCRATCHA0 ; flags
194 1.10 bouyer MOVE 0 to SCRATCHA1 ; DSA offset (for S/G save data pointer)
195 1.9 bouyer JUMP script_abs_sched;
196 1.1 bouyer
197 1.10 bouyer handle_sdp:
198 1.10 bouyer CLEAR ACK;
199 1.10 bouyer MOVE SCRATCHA0 | flag_sdp TO SCRATCHA0;
200 1.10 bouyer ; should get a disconnect message now
201 1.1 bouyer msgin:
202 1.1 bouyer CLEAR ATN
203 1.1 bouyer MOVE FROM t_msg_in, WHEN MSG_IN;
204 1.10 bouyer handle_msgin:
205 1.1 bouyer JUMP REL(handle_dis), IF 0x04 ; disconnect message
206 1.1 bouyer JUMP REL(handle_cmpl), IF 0x00 ; command complete message
207 1.1 bouyer JUMP REL(handle_sdp), IF 0x02 ; save data pointer message
208 1.2 bouyer JUMP REL(handle_extin), IF 0x01 ; extended message
209 1.1 bouyer INT int_msgin;
210 1.2 bouyer msgin_ack:
211 1.10 bouyer selected:
212 1.2 bouyer CLEAR ACK;
213 1.2 bouyer JUMP REL(waitphase);
214 1.2 bouyer
215 1.2 bouyer ; entry point for msgout after a msgin or status phase
216 1.2 bouyer send_msgout:
217 1.2 bouyer SET ATN;
218 1.2 bouyer CLEAR ACK;
219 1.1 bouyer msgout:
220 1.1 bouyer MOVE FROM t_msg_out, WHEN MSG_OUT;
221 1.1 bouyer CLEAR ATN;
222 1.1 bouyer JUMP REL(waitphase);
223 1.1 bouyer cmdout:
224 1.1 bouyer MOVE FROM t_cmd, WHEN CMD;
225 1.1 bouyer JUMP REL(waitphase);
226 1.1 bouyer status:
227 1.1 bouyer MOVE FROM t_status, WHEN STATUS;
228 1.1 bouyer JUMP REL(waitphase);
229 1.1 bouyer datain:
230 1.1 bouyer CALL REL(savedsa);
231 1.4 bouyer MOVE SCRATCHA0 | flag_data TO SCRATCHA0;
232 1.1 bouyer datain_loop:
233 1.1 bouyer MOVE FROM t_data, WHEN DATA_IN;
234 1.1 bouyer MOVE SCRATCHA1 + 1 TO SCRATCHA1 ; adjust offset
235 1.1 bouyer MOVE DSA0 + 8 to DSA0;
236 1.1 bouyer MOVE DSA1 + 0 to DSA1 WITH CARRY;
237 1.1 bouyer MOVE DSA2 + 0 to DSA2 WITH CARRY;
238 1.1 bouyer MOVE DSA3 + 0 to DSA3 WITH CARRY;
239 1.1 bouyer JUMP REL(datain_loop), WHEN DATA_IN;
240 1.1 bouyer CALL REL(restoredsa);
241 1.4 bouyer MOVE SCRATCHA0 & flag_data_mask TO SCRATCHA0;
242 1.1 bouyer JUMP REL(waitphase);
243 1.1 bouyer
244 1.1 bouyer dataout:
245 1.1 bouyer CALL REL(savedsa);
246 1.4 bouyer MOVE SCRATCHA0 | flag_data TO SCRATCHA0;
247 1.1 bouyer dataout_loop:
248 1.1 bouyer MOVE FROM t_data, WHEN DATA_OUT;
249 1.1 bouyer MOVE SCRATCHA1 + 1 TO SCRATCHA1 ; adjust offset
250 1.1 bouyer MOVE DSA0 + 8 to DSA0;
251 1.1 bouyer MOVE DSA1 + 0 to DSA1 WITH CARRY;
252 1.1 bouyer MOVE DSA2 + 0 to DSA2 WITH CARRY;
253 1.1 bouyer MOVE DSA3 + 0 to DSA3 WITH CARRY;
254 1.1 bouyer JUMP REL(dataout_loop), WHEN DATA_OUT;
255 1.1 bouyer CALL REL(restoredsa);
256 1.4 bouyer MOVE SCRATCHA0 & flag_data_mask TO SCRATCHA0;
257 1.1 bouyer JUMP REL(waitphase);
258 1.1 bouyer
259 1.1 bouyer savedsa:
260 1.1 bouyer MOVE DSA0 to SFBR;
261 1.1 bouyer MOVE SFBR to SCRATCHB0;
262 1.1 bouyer MOVE DSA1 to SFBR;
263 1.1 bouyer MOVE SFBR to SCRATCHB1;
264 1.1 bouyer MOVE DSA2 to SFBR;
265 1.1 bouyer MOVE SFBR to SCRATCHB2;
266 1.1 bouyer MOVE DSA3 to SFBR;
267 1.1 bouyer MOVE SFBR to SCRATCHB3;
268 1.1 bouyer RETURN;
269 1.1 bouyer
270 1.1 bouyer restoredsa:
271 1.1 bouyer MOVE SCRATCHB0 TO SFBR;
272 1.1 bouyer MOVE SFBR TO DSA0;
273 1.1 bouyer MOVE SCRATCHB1 TO SFBR;
274 1.1 bouyer MOVE SFBR TO DSA1;
275 1.1 bouyer MOVE SCRATCHB2 TO SFBR;
276 1.1 bouyer MOVE SFBR TO DSA2;
277 1.1 bouyer MOVE SCRATCHB3 TO SFBR;
278 1.1 bouyer MOVE SFBR TO DSA3;
279 1.1 bouyer RETURN;
280 1.1 bouyer
281 1.1 bouyer disconnect:
282 1.1 bouyer MOVE SCNTL2 & 0x7f TO SCNTL2;
283 1.1 bouyer CLEAR ATN;
284 1.1 bouyer CLEAR ACK;
285 1.1 bouyer WAIT DISCONNECT;
286 1.1 bouyer RETURN;
287 1.1 bouyer
288 1.1 bouyer handle_dis:
289 1.1 bouyer CALL REL(disconnect);
290 1.1 bouyer ; if we didn't get sdp, or if offset is 0, no need to interrupt
291 1.1 bouyer MOVE SCRATCHA0 & flag_sdp TO SFBR;
292 1.10 bouyer JUMP REL(script_sched), if 0x00;
293 1.1 bouyer MOVE SCRATCHA1 TO SFBR;
294 1.10 bouyer JUMP REL(script_sched), if 0x00;
295 1.1 bouyer ; Ok, we need to save data pointers
296 1.1 bouyer INT int_disc;
297 1.1 bouyer
298 1.1 bouyer handle_cmpl:
299 1.1 bouyer CALL REL(disconnect);
300 1.1 bouyer INT int_done;
301 1.2 bouyer
302 1.2 bouyer handle_extin:
303 1.2 bouyer CLEAR ACK;
304 1.2 bouyer INT int_err, IF NOT MSG_IN;
305 1.2 bouyer MOVE FROM t_ext_msg_in, WHEN MSG_IN;
306 1.2 bouyer INT int_extmsgin; /* let host fill in t_ext_msg_data */
307 1.2 bouyer get_extmsgdata:
308 1.2 bouyer CLEAR ACK;
309 1.2 bouyer INT int_err, IF NOT MSG_IN;
310 1.2 bouyer MOVE FROM t_ext_msg_data, WHEN MSG_IN;
311 1.2 bouyer INT int_extmsgdata;
312 1.10 bouyer msgin_space:
313 1.10 bouyer NOP; space to store msgin when reselect
314 1.10 bouyer
315 1.2 bouyer
316 1.7 bouyer ; script used for the scheduler: when a slot is free the JUMP points to
317 1.2 bouyer ; the next slot so that instructions for this slot are not run.
318 1.2 bouyer ; once the CPU has set up the slot variables (DSA address) it changes
319 1.2 bouyer ; the JUMP address to 0 (so that it'll jump to the next instruction) and
320 1.7 bouyer ; this command will be processed next time the scheduler is executed.
321 1.2 bouyer ; When the target has been successfully selected the script changes the jump
322 1.2 bouyer ; addr back to the next slot, so that it's ignored the next time.
323 1.2 bouyer ;
324 1.2 bouyer
325 1.2 bouyer PROC slot_script:
326 1.2 bouyer slot:
327 1.2 bouyer JUMP REL(nextslot);
328 1.10 bouyer CALL slot_abs_loaddsa;
329 1.2 bouyer SELECT ATN FROM t_id, slot_abs_reselect;
330 1.9 bouyer MOVE MEMORY 4, slot_sched_addrsrc, slot_nextp;
331 1.2 bouyer JUMP slot_abs_selected;
332 1.2 bouyer slotdata:
333 1.10 bouyer NOP; slot variables: jumppatchp
334 1.10 bouyer nextslot:
335 1.10 bouyer NOP; /* will be changed to the next slot entry
336 1.2 bouyer
337 1.2 bouyer PROC endslot_script:
338 1.2 bouyer JUMP endslot_abs_reselect;
339 1.8 bouyer
340 1.10 bouyer ;; per-target switch script for LUNs
341 1.10 bouyer ; hack: we first to a call to the target-specific code, so that a return
342 1.10 bouyer ; in the main switch will jump to the lun switch.
343 1.10 bouyer PROC lun_switch:
344 1.10 bouyer CALL REL(restore_scntl3);
345 1.10 bouyer MOVE SCRATCHA1 TO SFBR;
346 1.10 bouyer resel_lun0:
347 1.10 bouyer JUMP abs_lun0, IF 0x00;
348 1.10 bouyer JUMP abs_lun0, IF 0x01;
349 1.10 bouyer JUMP abs_lun0, IF 0x02;
350 1.10 bouyer JUMP abs_lun0, IF 0x03;
351 1.10 bouyer JUMP abs_lun0, IF 0x04;
352 1.10 bouyer JUMP abs_lun0, IF 0x05;
353 1.10 bouyer JUMP abs_lun0, IF 0x06;
354 1.10 bouyer JUMP abs_lun0, IF 0x07;
355 1.10 bouyer INT int_resellun;
356 1.10 bouyer restore_scntl3:
357 1.10 bouyer MOVE 0xff TO SCNTL3;
358 1.10 bouyer MOVE 0xff TO SXFER;
359 1.10 bouyer JUMP abs_lunsw_return;
360 1.10 bouyer
361 1.10 bouyer ;; script used to load the DSA after a reselect.
362 1.10 bouyer
363 1.10 bouyer PROC load_dsa:
364 1.10 bouyer ; Can't use MOVE MEMORY to load DSA, doesn't work I/O mapped
365 1.8 bouyer rdsa0:
366 1.10 bouyer MOVE 0xf0 to DSA0;
367 1.8 bouyer rdsa1:
368 1.10 bouyer MOVE 0xf1 to DSA1;
369 1.8 bouyer rdsa2:
370 1.10 bouyer MOVE 0xf2 to DSA2;
371 1.8 bouyer rdsa3:
372 1.10 bouyer MOVE 0xf3 to DSA3;
373 1.10 bouyer RETURN;
374 1.10 bouyer reload_dsa:
375 1.10 bouyer CALL REL(rdsa0);
376 1.10 bouyer JUMP resel_abs_reselected;
377