Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / dev / microcode / siop / siop.ss
blob3e593615f5c808dc6d38cc72f8d1523c399c8bb4
1 ;       $NetBSD: siop.ss,v 1.20 2005/11/18 23:10:32 bouyer Exp $
4 ;  Copyright (c) 2000 Manuel Bouyer.
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.
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.
26 ARCH 720
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;
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;
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
58 ; main script symbols
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;
87 ; lun switch symbols
88 ENTRY lun_switch_entry;
89 ENTRY resel_lun0;
90 ENTRY restore_scntl3;
91 EXTERN abs_lunsw_return;
93 ; tag switch symbols
94 ENTRY tag_switch_entry;
95 ENTRY resel_tag0;
96 EXTERN abs_tag0;
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;
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;
113 ; main script
115 PROC  siop_script:
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;
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
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;
267 msgin_ack:
268 selected:
269         CLEAR ACK;
270         JUMP REL(waitphase);
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);
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);
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;
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;
338 disconnect:
339         MOVE SCNTL2 & 0x7f TO SCNTL2;
340         CLEAR ATN;
341         CLEAR ACK;
342         WAIT DISCONNECT;
343         RETURN;
345 handle_cmpl:
346         CALL REL(disconnect);
347         INT int_done;
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
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;
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;
398 ;; per-command script: select, and called after a reselect to load DSA
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
422 PROC siop_led_on:
423         MOVE GPREG & 0xfe TO GPREG;
425 PROC siop_led_off:
426         MOVE GPREG | 0x01 TO GPREG;