siop.ss revision 1.21 1 ; $NetBSD: siop.ss,v 1.21 2009/10/19 18:41:13 bouyer Exp $
2
3 ;
4 ; Copyright (c) 2000 Manuel Bouyer.
5 ;
6 ; Redistribution and use in source and binary forms, with or without
7 ; modification, are permitted provided that the following conditions
8 ; are met:
9 ; 1. Redistributions of source code must retain the above copyright
10 ; notice, this list of conditions and the following disclaimer.
11 ; 2. Redistributions in binary form must reproduce the above copyright
12 ; notice, this list of conditions and the following disclaimer in the
13 ; documentation and/or other materials provided with the distribution.
14 ;
15 ; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 ; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 ; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 ; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 ; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 ; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 ; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 ; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 ; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26 ARCH 720
27
28 ; offsets in siop_common_xfer
29 ABSOLUTE t_id = 40;
30 ABSOLUTE t_msg_in = 48;
31 ABSOLUTE t_ext_msg_in = 56;
32 ABSOLUTE t_ext_msg_data = 64;
33 ABSOLUTE t_msg_out = 72;
34 ABSOLUTE t_cmd = 80;
35 ABSOLUTE t_status = 88;
36 ABSOLUTE t_data = 96;
37
38 ;; interrupt codes
39 ; interrupts that need a valid DSA
40 ABSOLUTE int_done = 0xff00;
41 ABSOLUTE int_msgin = 0xff01;
42 ABSOLUTE int_extmsgin = 0xff02;
43 ABSOLUTE int_extmsgdata = 0xff03;
44 ABSOLUTE int_disc = 0xff04;
45 ABSOLUTE int_saveoffset = 0xff05;
46 ; interrupts that don't have a valid DSA
47 ABSOLUTE int_reseltarg = 0xff80;
48 ABSOLUTE int_resellun = 0xff81;
49 ABSOLUTE int_reseltag = 0xff82;
50 ABSOLUTE int_resfail = 0xff83;
51 ABSOLUTE int_err = 0xffff;
52
53 ; flags for scratcha0
54 ABSOLUTE flag_sdp = 0x01 ; got save data pointer
55 ABSOLUTE flag_data = 0x02 ; we're in data phase
56 ABSOLUTE flag_data_mask = 0xfd ; ~flag_data
57
58 ; main script symbols
59
60 ENTRY waitphase;
61 ENTRY send_msgout;
62 ENTRY msgout;
63 ENTRY msgin;
64 ENTRY handle_msgin;
65 ENTRY msgin_ack;
66 ENTRY dataout;
67 ENTRY datain;
68 ENTRY cmdout;
69 ENTRY status;
70 ENTRY disconnect;
71 ENTRY reselect;
72 ENTRY reselected;
73 ENTRY selected;
74 ENTRY script_sched;
75 ENTRY script_sched_slot0;
76 ENTRY get_extmsgdata;
77 ENTRY resel_targ0;
78 ENTRY msgin_space;
79 ENTRY lunsw_return;
80 ENTRY led_on1;
81 ENTRY led_on2;
82 ENTRY led_off;
83 EXTERN abs_script_sched_slot0;
84 EXTERN abs_targ0;
85 EXTERN abs_msgin;
86
87 ; lun switch symbols
88 ENTRY lun_switch_entry;
89 ENTRY resel_lun0;
90 ENTRY restore_scntl3;
91 EXTERN abs_lunsw_return;
92
93 ; tag switch symbols
94 ENTRY tag_switch_entry;
95 ENTRY resel_tag0;
96 EXTERN abs_tag0;
97
98 ; command reselect script symbols
99 ENTRY rdsa0;
100 ENTRY rdsa1;
101 ENTRY rdsa2;
102 ENTRY rdsa3;
103 ENTRY ldsa_reload_dsa;
104 ENTRY ldsa_select;
105 ENTRY ldsa_data;
106
107 EXTERN ldsa_abs_reselected;
108 EXTERN ldsa_abs_reselect;
109 EXTERN ldsa_abs_selected;
110 EXTERN ldsa_abs_data;
111 EXTERN ldsa_abs_slot;
112
113 ; main script
114
115 PROC siop_script:
116
117 reselected:
118 ; starting a new session, init 'local variables'
119 MOVE 0 to SCRATCHA0 ; flags
120 MOVE 0 to SCRATCHA1 ; DSA offset (for S/G save data pointer)
121 MOVE SCRATCHA3 to SFBR ; pending message ?
122 JUMP REL(handle_msgin), IF not 0x20;
123 waitphase:
124 JUMP REL(msgout), WHEN MSG_OUT;
125 JUMP REL(msgin), WHEN MSG_IN;
126 JUMP REL(dataout), WHEN DATA_OUT;
127 JUMP REL(datain), WHEN DATA_IN;
128 JUMP REL(cmdout), WHEN CMD;
129 JUMP REL(status), WHEN STATUS;
130 INT int_err;
131
132 reselect_fail:
133 ; check that host asserted SIGP, this'll clear SIGP in ISTAT
134 MOVE CTEST2 & 0x40 TO SFBR;
135 INT int_resfail, IF 0x00;
136 ; a NOP by default; patched with MOVE GPREG & 0xfe to GPREG on compile-time
137 ; option "SIOP_SYMLED"
138 led_on1:
139 NOP;
140 script_sched:
141 ; Clear DSA and init status
142 MOVE 0xff to DSA0;
143 MOVE 0xff to DSA1;
144 MOVE 0xff to DSA2;
145 MOVE 0xff to DSA3;
146 MOVE 0 to SCRATCHA0 ; flags
147 MOVE 0 to SCRATCHA1 ; DSA offset (for S/G save data pointer)
148 ; the script scheduler: siop_start() we set the absolute jump addr, and then
149 ; changes the FALSE to TRUE. The select script will change it back to false
150 ; once the target is selected.
151 ; The RAM could hold 370 slot entry, we limit it to 40. Should be more than
152 ; enough.
153 script_sched_slot0:
154 JUMP abs_script_sched_slot0, IF FALSE;
155 JUMP abs_script_sched_slot0, IF FALSE;
156 JUMP abs_script_sched_slot0, IF FALSE;
157 JUMP abs_script_sched_slot0, IF FALSE;
158 JUMP abs_script_sched_slot0, IF FALSE;
159 JUMP abs_script_sched_slot0, IF FALSE;
160 JUMP abs_script_sched_slot0, IF FALSE;
161 JUMP abs_script_sched_slot0, IF FALSE;
162 JUMP abs_script_sched_slot0, IF FALSE;
163 JUMP abs_script_sched_slot0, IF FALSE;
164 JUMP abs_script_sched_slot0, IF FALSE;
165 JUMP abs_script_sched_slot0, IF FALSE;
166 JUMP abs_script_sched_slot0, IF FALSE;
167 JUMP abs_script_sched_slot0, IF FALSE;
168 JUMP abs_script_sched_slot0, IF FALSE;
169 JUMP abs_script_sched_slot0, IF FALSE;
170 JUMP abs_script_sched_slot0, IF FALSE;
171 JUMP abs_script_sched_slot0, IF FALSE;
172 JUMP abs_script_sched_slot0, IF FALSE;
173 JUMP abs_script_sched_slot0, IF FALSE;
174 JUMP abs_script_sched_slot0, IF FALSE;
175 JUMP abs_script_sched_slot0, IF FALSE;
176 JUMP abs_script_sched_slot0, IF FALSE;
177 JUMP abs_script_sched_slot0, IF FALSE;
178 JUMP abs_script_sched_slot0, IF FALSE;
179 JUMP abs_script_sched_slot0, IF FALSE;
180 JUMP abs_script_sched_slot0, IF FALSE;
181 JUMP abs_script_sched_slot0, IF FALSE;
182 JUMP abs_script_sched_slot0, IF FALSE;
183 JUMP abs_script_sched_slot0, IF FALSE;
184 JUMP abs_script_sched_slot0, IF FALSE;
185 JUMP abs_script_sched_slot0, IF FALSE;
186 JUMP abs_script_sched_slot0, IF FALSE;
187 JUMP abs_script_sched_slot0, IF FALSE;
188 JUMP abs_script_sched_slot0, IF FALSE;
189 JUMP abs_script_sched_slot0, IF FALSE;
190 JUMP abs_script_sched_slot0, IF FALSE;
191 JUMP abs_script_sched_slot0, IF FALSE;
192 JUMP abs_script_sched_slot0, IF FALSE;
193 JUMP abs_script_sched_slot0, IF FALSE;
194 ; Nothing to do, wait for reselect
195 reselect:
196 ; Clear DSA and init status
197 MOVE 0xff to DSA0;
198 MOVE 0xff to DSA1;
199 MOVE 0xff to DSA2;
200 MOVE 0xff to DSA3;
201 MOVE 0x00 to SCRATCHA2; no tag
202 MOVE 0x20 to SCRATCHA3; simple tag msg, ignored by reselected:
203 ; a NOP by default; patched with MOVE GPREG | 0x01 to GPREG on compile-time
204 ; option "SIOP_SYMLED"
205 led_off:
206 NOP;
207 WAIT RESELECT REL(reselect_fail)
208 ; a NOP by default; patched with MOVE GPREG & 0xfe to GPREG on compile-time
209 ; option "SIOP_SYMLED"
210 led_on2:
211 NOP;
212 MOVE SSID & 0x8f to SFBR
213 MOVE SFBR to SCRATCHA0 ; save reselect ID
214 ; find the right param for this target
215 resel_targ0:
216 JUMP abs_targ0, IF 0xff;
217 JUMP abs_targ0, IF 0xff;
218 JUMP abs_targ0, IF 0xff;
219 JUMP abs_targ0, IF 0xff;
220 JUMP abs_targ0, IF 0xff;
221 JUMP abs_targ0, IF 0xff;
222 JUMP abs_targ0, IF 0xff;
223 JUMP abs_targ0, IF 0xff;
224 JUMP abs_targ0, IF 0xff;
225 JUMP abs_targ0, IF 0xff;
226 JUMP abs_targ0, IF 0xff;
227 JUMP abs_targ0, IF 0xff;
228 JUMP abs_targ0, IF 0xff;
229 JUMP abs_targ0, IF 0xff;
230 JUMP abs_targ0, IF 0xff;
231 INT int_reseltarg;
232 lunsw_return:
233 MOVE 1, abs_msgin, WHEN MSG_IN;
234 MOVE SFBR & 0x07 to SCRATCHA1; save LUN
235 CLEAR ACK;
236 RETURN, WHEN NOT MSG_IN; If no more message, jump to lun sw
237 MOVE 1, abs_msgin, WHEN MSG_IN;
238 CLEAR ACK;
239 MOVE SFBR to SCRATCHA3; save message
240 RETURN, IF NOT 0x20; jump to lun sw if not simple tag msg
241 MOVE 1, abs_msgin, WHEN MSG_IN; get tag
242 CLEAR ACK;
243 MOVE SFBR to SCRATCHA2; save tag
244 RETURN; jump to lun sw
245
246 handle_sdp:
247 CLEAR ACK;
248 MOVE SCRATCHA0 | flag_sdp TO SCRATCHA0;
249 ; should get a disconnect message now
250 msgin:
251 CLEAR ATN
252 MOVE FROM t_msg_in, WHEN MSG_IN;
253 handle_msgin:
254 JUMP REL(handle_cmpl), IF 0x00 ; command complete message
255 JUMP REL(handle_sdp), IF 0x02 ; save data pointer message
256 JUMP REL(handle_extin), IF 0x01 ; extended message
257 INT int_msgin, IF not 0x04;
258 CALL REL(disconnect) ; disconnect message;
259 ; if we didn't get sdp, no need to interrupt
260 MOVE SCRATCHA0 & flag_sdp TO SFBR;
261 INT int_disc, IF not 0x00;
262 ; update offset if we did some data transfer
263 MOVE SCRATCHA1 TO SFBR;
264 JUMP REL(script_sched), if 0x00;
265 INT int_saveoffset;
266
267 msgin_ack:
268 selected:
269 CLEAR ACK;
270 JUMP REL(waitphase);
271
272 ; entry point for msgout after a msgin or status phase
273 send_msgout:
274 SET ATN;
275 CLEAR ACK;
276 msgout:
277 MOVE FROM t_msg_out, WHEN MSG_OUT;
278 CLEAR ATN;
279 JUMP REL(waitphase);
280 cmdout:
281 MOVE FROM t_cmd, WHEN CMD;
282 JUMP REL(waitphase);
283 status:
284 MOVE FROM t_status, WHEN STATUS;
285 JUMP REL(waitphase);
286 datain:
287 CALL REL(savedsa);
288 MOVE SCRATCHA0 | flag_data TO SCRATCHA0;
289 datain_loop:
290 MOVE FROM t_data, WHEN DATA_IN;
291 MOVE SCRATCHA1 + 1 TO SCRATCHA1 ; adjust offset
292 MOVE DSA0 + 8 to DSA0;
293 MOVE DSA1 + 0 to DSA1 WITH CARRY;
294 MOVE DSA2 + 0 to DSA2 WITH CARRY;
295 MOVE DSA3 + 0 to DSA3 WITH CARRY;
296 JUMP REL(datain_loop), WHEN DATA_IN;
297 CALL REL(restoredsa);
298 MOVE SCRATCHA0 & flag_data_mask TO SCRATCHA0;
299 JUMP REL(waitphase);
300
301 dataout:
302 CALL REL(savedsa);
303 MOVE SCRATCHA0 | flag_data TO SCRATCHA0;
304 dataout_loop:
305 MOVE FROM t_data, WHEN DATA_OUT;
306 MOVE SCRATCHA1 + 1 TO SCRATCHA1 ; adjust offset
307 MOVE DSA0 + 8 to DSA0;
308 MOVE DSA1 + 0 to DSA1 WITH CARRY;
309 MOVE DSA2 + 0 to DSA2 WITH CARRY;
310 MOVE DSA3 + 0 to DSA3 WITH CARRY;
311 JUMP REL(dataout_loop), WHEN DATA_OUT;
312 CALL REL(restoredsa);
313 MOVE SCRATCHA0 & flag_data_mask TO SCRATCHA0;
314 JUMP REL(waitphase);
315
316 savedsa:
317 MOVE DSA0 to SFBR;
318 MOVE SFBR to SCRATCHB0;
319 MOVE DSA1 to SFBR;
320 MOVE SFBR to SCRATCHB1;
321 MOVE DSA2 to SFBR;
322 MOVE SFBR to SCRATCHB2;
323 MOVE DSA3 to SFBR;
324 MOVE SFBR to SCRATCHB3;
325 RETURN;
326
327 restoredsa:
328 MOVE SCRATCHB0 TO SFBR;
329 MOVE SFBR TO DSA0;
330 MOVE SCRATCHB1 TO SFBR;
331 MOVE SFBR TO DSA1;
332 MOVE SCRATCHB2 TO SFBR;
333 MOVE SFBR TO DSA2;
334 MOVE SCRATCHB3 TO SFBR;
335 MOVE SFBR TO DSA3;
336 RETURN;
337
338 disconnect:
339 MOVE SCNTL2 & 0x7f TO SCNTL2;
340 CLEAR ATN;
341 CLEAR ACK;
342 WAIT DISCONNECT;
343 RETURN;
344
345 handle_cmpl:
346 CALL REL(disconnect);
347 INT int_done;
348
349 handle_extin:
350 CLEAR ACK;
351 MOVE FROM t_ext_msg_in, WHEN MSG_IN;
352 INT int_extmsgin; /* let host fill in t_ext_msg_data */
353 get_extmsgdata:
354 CLEAR ACK;
355 MOVE FROM t_ext_msg_data, WHEN MSG_IN;
356 INT int_extmsgdata;
357 msgin_space:
358 NOP; space to store msgin when reselect
359
360
361 ;; per-target switch script for LUNs
362 ; hack: we first do a call to the target-specific code, so that a return
363 ; in the main switch will jump to the lun switch.
364 PROC lun_switch:
365 restore_scntl3:
366 MOVE 0xff TO SCNTL3;
367 MOVE 0xff TO SXFER;
368 JUMP abs_lunsw_return;
369 lun_switch_entry:
370 CALL REL(restore_scntl3);
371 MOVE SCRATCHA1 TO SFBR;
372 resel_lun0:
373 INT int_resellun;
374
375 ;; Per-device switch script for tag
376 PROC tag_switch:
377 tag_switch_entry:
378 MOVE SCRATCHA2 TO SFBR; restore tag
379 resel_tag0:
380 JUMP abs_tag0, IF 0x00;
381 JUMP abs_tag0, IF 0x01;
382 JUMP abs_tag0, IF 0x02;
383 JUMP abs_tag0, IF 0x03;
384 JUMP abs_tag0, IF 0x04;
385 JUMP abs_tag0, IF 0x05;
386 JUMP abs_tag0, IF 0x06;
387 JUMP abs_tag0, IF 0x07;
388 JUMP abs_tag0, IF 0x08;
389 JUMP abs_tag0, IF 0x09;
390 JUMP abs_tag0, IF 0x0a;
391 JUMP abs_tag0, IF 0x0b;
392 JUMP abs_tag0, IF 0x0c;
393 JUMP abs_tag0, IF 0x0d;
394 JUMP abs_tag0, IF 0x0e;
395 JUMP abs_tag0, IF 0x0f;
396 INT int_reseltag;
397
398 ;; per-command script: select, and called after a reselect to load DSA
399
400 PROC load_dsa:
401 ; Can't use MOVE MEMORY to load DSA, doesn't work I/O mapped
402 rdsa0:
403 MOVE 0xf0 to DSA0;
404 rdsa1:
405 MOVE 0xf1 to DSA1;
406 rdsa2:
407 MOVE 0xf2 to DSA2;
408 rdsa3:
409 MOVE 0xf3 to DSA3;
410 RETURN;
411 ldsa_reload_dsa:
412 CALL REL(rdsa0);
413 JUMP ldsa_abs_reselected;
414 ldsa_select:
415 CALL REL(rdsa0);
416 SELECT ATN FROM t_id, ldsa_abs_reselect;
417 MOVE MEMORY 4, ldsa_abs_data, ldsa_abs_slot;
418 JUMP ldsa_abs_selected;
419 ldsa_data:
420 NOP; contains data used by the MOVE MEMORY
421
422 PROC siop_led_on:
423 MOVE GPREG & 0xfe TO GPREG;
424
425 PROC siop_led_off:
426 MOVE GPREG | 0x01 TO GPREG;
427