siop.ss revision 1.8 1 ; $NetBSD: siop.ss,v 1.8 2000/10/06 16:31:17 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 ABSOLUTE int_done = 0xff00;
46 ABSOLUTE int_msgin = 0xff01;
47 ABSOLUTE int_extmsgin = 0xff02;
48 ABSOLUTE int_extmsgdata = 0xff03;
49 ABSOLUTE int_resel = 0xff04;
50 ABSOLUTE int_reseltag = 0xff05;
51 ABSOLUTE int_resfail = 0xff06;
52 ABSOLUTE int_disc = 0xff07;
53 ABSOLUTE int_err = 0xffff;
54
55 ; flags for scratcha0
56 ABSOLUTE flag_sdp = 0x01 ; got save data pointer
57 ABSOLUTE flag_data = 0x02 ; we're in data phase
58 ABSOLUTE flag_data_mask = 0xfd ; ~flag_data
59
60 ENTRY waitphase;
61 ENTRY send_msgout;
62 ENTRY msgout;
63 ENTRY msgin;
64 ENTRY msgin_ack;
65 ENTRY dataout;
66 ENTRY datain;
67 ENTRY cmdout;
68 ENTRY status;
69 ENTRY disconnect;
70 ENTRY reselect;
71 ENTRY selected;
72 ENTRY get_extmsgdata;
73 ENTRY slot;
74 ENTRY idsa0;
75 ENTRY idsa1;
76 ENTRY idsa2;
77 ENTRY idsa3;
78 ENTRY slotdata;
79 ENTRY nextslot;
80 ENTRY endslot;
81
82 EXTERN script_abs_shed;
83 EXTERN slot_nextp;
84 EXTERN slot_shed_addrsrc;
85 EXTERN slot_abs_reselect;
86 EXTERN slot_abs_selected;
87
88 EXTERN endslot_abs_reselect;
89
90 EXTERN abs_find_dsa;
91 ENTRY rtarget;
92 ENTRY rlun;
93 ENTRY rdsa0;
94 ENTRY rdsa1;
95 ENTRY rdsa2;
96 ENTRY rdsa3;
97 ENTRY rsxfer;
98 ENTRY rscntl3;
99 ENTRY res_nextld;
100 EXTERN resel_abs_selected;
101
102 PROC siop_script:
103
104 selected:
105 ; starting a new session, init 'local variables'
106 MOVE 0 to SCRATCHA0 ; flags
107 MOVE 0 to SCRATCHA1 ; DSA offset (for S/G save data pointer)
108 CLEAR ACK;
109 waitphase:
110 JUMP REL(msgout), WHEN MSG_OUT;
111 JUMP REL(msgin), WHEN MSG_IN;
112 JUMP REL(dataout), WHEN DATA_OUT;
113 JUMP REL(datain), WHEN DATA_IN;
114 JUMP REL(cmdout), WHEN CMD;
115 JUMP REL(status), WHEN STATUS;
116 err:
117 INT int_err;
118
119 reselect:
120 WAIT RESELECT REL(reselect_fail)
121 MOVE SSID & 0x8f to SFBR
122 MOVE SFBR to SCRATCHA0 ; save reselect ID
123 INT int_err, WHEN NOT MSG_IN;
124 MOVE FROM t_msg_in, WHEN MSG_IN;
125 MOVE SFBR & 0x07 to SCRATCHA2; save LUN
126 JUMP abs_find_dsa;
127 reselect_fail:
128 ; check that host asserted SIGP, this'll clear SIGP in ISTAT
129 MOVE CTEST2 & 0x40 TO SFBR;
130 INT int_resfail, IF 0x00;
131 JUMP script_abs_shed;
132
133 msgin:
134 CLEAR ATN
135 MOVE FROM t_msg_in, WHEN MSG_IN;
136 JUMP REL(handle_dis), IF 0x04 ; disconnect message
137 JUMP REL(handle_cmpl), IF 0x00 ; command complete message
138 JUMP REL(handle_sdp), IF 0x02 ; save data pointer message
139 JUMP REL(handle_extin), IF 0x01 ; extended message
140 INT int_msgin;
141 msgin_ack:
142 CLEAR ACK;
143 JUMP REL(waitphase);
144
145 ; entry point for msgout after a msgin or status phase
146 send_msgout:
147 SET ATN;
148 CLEAR ACK;
149 msgout:
150 MOVE FROM t_msg_out, WHEN MSG_OUT;
151 CLEAR ATN;
152 JUMP REL(waitphase);
153 cmdout:
154 MOVE FROM t_cmd, WHEN CMD;
155 JUMP REL(waitphase);
156 status:
157 MOVE FROM t_status, WHEN STATUS;
158 JUMP REL(waitphase);
159 datain:
160 CALL REL(savedsa);
161 MOVE SCRATCHA0 | flag_data TO SCRATCHA0;
162 datain_loop:
163 MOVE FROM t_data, WHEN DATA_IN;
164 MOVE SCRATCHA1 + 1 TO SCRATCHA1 ; adjust offset
165 MOVE DSA0 + 8 to DSA0;
166 MOVE DSA1 + 0 to DSA1 WITH CARRY;
167 MOVE DSA2 + 0 to DSA2 WITH CARRY;
168 MOVE DSA3 + 0 to DSA3 WITH CARRY;
169 JUMP REL(datain_loop), WHEN DATA_IN;
170 CALL REL(restoredsa);
171 MOVE SCRATCHA0 & flag_data_mask TO SCRATCHA0;
172 JUMP REL(waitphase);
173
174 dataout:
175 CALL REL(savedsa);
176 MOVE SCRATCHA0 | flag_data TO SCRATCHA0;
177 dataout_loop:
178 MOVE FROM t_data, WHEN DATA_OUT;
179 MOVE SCRATCHA1 + 1 TO SCRATCHA1 ; adjust offset
180 MOVE DSA0 + 8 to DSA0;
181 MOVE DSA1 + 0 to DSA1 WITH CARRY;
182 MOVE DSA2 + 0 to DSA2 WITH CARRY;
183 MOVE DSA3 + 0 to DSA3 WITH CARRY;
184 JUMP REL(dataout_loop), WHEN DATA_OUT;
185 CALL REL(restoredsa);
186 MOVE SCRATCHA0 & flag_data_mask TO SCRATCHA0;
187 JUMP REL(waitphase);
188
189 savedsa:
190 MOVE DSA0 to SFBR;
191 MOVE SFBR to SCRATCHB0;
192 MOVE DSA1 to SFBR;
193 MOVE SFBR to SCRATCHB1;
194 MOVE DSA2 to SFBR;
195 MOVE SFBR to SCRATCHB2;
196 MOVE DSA3 to SFBR;
197 MOVE SFBR to SCRATCHB3;
198 RETURN;
199
200 restoredsa:
201 MOVE SCRATCHB0 TO SFBR;
202 MOVE SFBR TO DSA0;
203 MOVE SCRATCHB1 TO SFBR;
204 MOVE SFBR TO DSA1;
205 MOVE SCRATCHB2 TO SFBR;
206 MOVE SFBR TO DSA2;
207 MOVE SCRATCHB3 TO SFBR;
208 MOVE SFBR TO DSA3;
209 RETURN;
210
211 disconnect:
212 MOVE SCNTL2 & 0x7f TO SCNTL2;
213 CLEAR ATN;
214 CLEAR ACK;
215 WAIT DISCONNECT;
216 RETURN;
217
218 handle_dis:
219 CALL REL(disconnect);
220 ; if we didn't get sdp, or if offset is 0, no need to interrupt
221 MOVE SCRATCHA0 & flag_sdp TO SFBR;
222 JUMP script_abs_shed, if 0x00;
223 MOVE SCRATCHA1 TO SFBR;
224 JUMP script_abs_shed, if 0x00;
225 ; Ok, we need to save data pointers
226 INT int_disc;
227
228 handle_cmpl:
229 CALL REL(disconnect);
230 INT int_done;
231 handle_sdp:
232 CLEAR ACK;
233 MOVE SCRATCHA0 | flag_sdp TO SCRATCHA0;
234 JUMP REL(msgin) ; should get a disconnect message now
235
236 handle_extin:
237 CLEAR ACK;
238 INT int_err, IF NOT MSG_IN;
239 MOVE FROM t_ext_msg_in, WHEN MSG_IN;
240 INT int_extmsgin; /* let host fill in t_ext_msg_data */
241 get_extmsgdata:
242 CLEAR ACK;
243 INT int_err, IF NOT MSG_IN;
244 MOVE FROM t_ext_msg_data, WHEN MSG_IN;
245 INT int_extmsgdata;
246
247 ; script used for the scheduler: when a slot is free the JUMP points to
248 ; the next slot so that instructions for this slot are not run.
249 ; once the CPU has set up the slot variables (DSA address) it changes
250 ; the JUMP address to 0 (so that it'll jump to the next instruction) and
251 ; this command will be processed next time the scheduler is executed.
252 ; When the target has been successfully selected the script changes the jump
253 ; addr back to the next slot, so that it's ignored the next time.
254 ;
255
256 PROC slot_script:
257 slot:
258 JUMP REL(nextslot);
259 idsa0:
260 MOVE 0x00 to dsa0;
261 idsa1:
262 MOVE 0x01 to dsa1;
263 idsa2:
264 MOVE 0x02 to dsa2;
265 idsa3:
266 MOVE 0x03 to dsa3;
267 SELECT ATN FROM t_id, slot_abs_reselect;
268 MOVE MEMORY 4, slot_shed_addrsrc, slot_nextp;
269 JUMP slot_abs_selected;
270 slotdata:
271 NOP; slot variables: dsa & jumppatchp
272 nextslot: NOP; /* will be changed to the next slot entry
273
274 PROC endslot_script:
275 JUMP endslot_abs_reselect;
276
277 ;; script used to find the DSA after a reselect.
278 ;; each slot contain a target/lun identifier (when free target = 0xff, so it's
279 ;; ignored) used to load the appropriate DSA for this reselect
280
281 PROC reselected_script:
282 MOVE SCRATCHA0 to SFBR; load ID
283 rtarget:
284 JUMP REL(res_nextid), IF NOT 0xff;
285 MOVE SCRATCHA2 to SFBR; load LUN
286 rlun:
287 JUMP REL(res_nextld), IF NOT 0xff;
288 rdsa0:
289 MOVE 0x00 to dsa0;
290 rdsa1:
291 MOVE 0x01 to dsa1;
292 rdsa2:
293 MOVE 0x02 to dsa2;
294 rdsa3:
295 MOVE 0x03 to dsa3;
296 ; the select is here to reload sxfer and scntl3 from the table. As we're
297 ; already reselected is always fais, and always jumps to the main script.
298 SELECT FROM t_id, resel_abs_selected;
299
300 res_nextld:
301 NOP ; MOVE SCRATCHA0 to SFBR
302 res_nextid:
303 NOP ; JUMP REL(res_nextid), IF NOT 0xff
304
305 PROC reselected_end_script:
306 INT int_resel;
307 INT int_resel; /* need two because res_nextld and res_nextid */
308