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