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