Home | History | Annotate | Line # | Download | only in siop
siop.ss revision 1.20
      1 ;	$NetBSD: siop.ss,v 1.20 2005/11/18 23:10:32 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 siop_common_xfer
     34 ABSOLUTE t_id = 40;
     35 ABSOLUTE t_msg_in = 48;
     36 ABSOLUTE t_ext_msg_in = 56;
     37 ABSOLUTE t_ext_msg_data = 64;
     38 ABSOLUTE t_msg_out = 72;
     39 ABSOLUTE t_cmd = 80;
     40 ABSOLUTE t_status = 88;
     41 ABSOLUTE t_data = 96;
     42 
     43 ;; interrupt codes
     44 ; interrupts that need a valid DSA
     45 ABSOLUTE int_done	= 0xff00;
     46 ABSOLUTE int_msgin	= 0xff01;
     47 ABSOLUTE int_extmsgin	= 0xff02;
     48 ABSOLUTE int_extmsgdata	= 0xff03;
     49 ABSOLUTE int_disc	= 0xff04;
     50 ABSOLUTE int_saveoffset	= 0xff05;
     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 script_sched_slot0;
     81 ENTRY get_extmsgdata;
     82 ENTRY resel_targ0;
     83 ENTRY msgin_space;
     84 ENTRY lunsw_return;
     85 ENTRY led_on1;
     86 ENTRY led_on2;
     87 ENTRY led_off;
     88 EXTERN abs_script_sched_slot0;
     89 EXTERN abs_targ0;
     90 EXTERN abs_msgin;
     91 
     92 ; lun switch symbols
     93 ENTRY lun_switch_entry;
     94 ENTRY resel_lun0;
     95 ENTRY restore_scntl3;
     96 EXTERN abs_lunsw_return;
     97 
     98 ; tag switch symbols
     99 ENTRY tag_switch_entry;
    100 ENTRY resel_tag0;
    101 EXTERN abs_tag0;
    102 
    103 ; command reselect script symbols
    104 ENTRY rdsa0;
    105 ENTRY rdsa1;
    106 ENTRY rdsa2;
    107 ENTRY rdsa3;
    108 ENTRY ldsa_reload_dsa;
    109 ENTRY ldsa_select;
    110 ENTRY ldsa_data;
    111 
    112 EXTERN ldsa_abs_reselected;
    113 EXTERN ldsa_abs_reselect;
    114 EXTERN ldsa_abs_selected;
    115 EXTERN ldsa_abs_data;
    116 EXTERN ldsa_abs_slot;
    117 
    118 ; main script
    119 
    120 PROC  siop_script:
    121 
    122 reselected:
    123 ; starting a new session, init 'local variables'
    124 	MOVE 0 to SCRATCHA0	; flags
    125 	MOVE 0 to SCRATCHA1	; DSA offset (for S/G save data pointer)
    126 	MOVE SCRATCHA3 to SFBR  ; pending message ?
    127 	JUMP REL(handle_msgin), IF not 0x20;
    128 waitphase:
    129 	JUMP REL(msgout), WHEN MSG_OUT;
    130 	JUMP REL(msgin), WHEN MSG_IN;
    131 	JUMP REL(dataout), WHEN DATA_OUT;
    132 	JUMP REL(datain), WHEN DATA_IN;
    133 	JUMP REL(cmdout), WHEN CMD;
    134 	JUMP REL(status), WHEN STATUS;
    135 	INT int_err;
    136 
    137 reselect_fail:
    138 	; check that host asserted SIGP, this'll clear SIGP in ISTAT
    139 	MOVE CTEST2 & 0x40 TO SFBR;
    140 	INT int_resfail,  IF 0x00;
    141 ; a NOP by default; patched with MOVE GPREG & 0xfe to GPREG on compile-time
    142 ; option "SIOP_SYMLED"
    143 led_on1:
    144 	NOP;
    145 script_sched:
    146 	; Clear DSA and init status
    147 	MOVE 0xff to DSA0;
    148 	MOVE 0xff to DSA1;
    149 	MOVE 0xff to DSA2;
    150 	MOVE 0xff to DSA3;
    151 	MOVE 0 to SCRATCHA0	; flags
    152 	MOVE 0 to SCRATCHA1	; DSA offset (for S/G save data pointer)
    153 ; the script scheduler: siop_start() we set the absolute jump addr, and then
    154 ; changes the FALSE to TRUE. The select script will change it back to false
    155 ; once the target is selected.
    156 ; The RAM could hold 370 slot entry, we limit it to 40. Should be more than
    157 ; enough.
    158 script_sched_slot0:
    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 	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 ; Nothing to do, wait for reselect
    200 reselect:
    201 	; Clear DSA and init status
    202 	MOVE 0xff to DSA0;
    203 	MOVE 0xff to DSA1;
    204 	MOVE 0xff to DSA2;
    205 	MOVE 0xff to DSA3;
    206 	MOVE 0x00 to SCRATCHA2; no tag
    207 	MOVE 0x20 to SCRATCHA3; simple tag msg, ignored by reselected:
    208 ; a NOP by default; patched with MOVE GPREG | 0x01 to GPREG on compile-time
    209 ; option "SIOP_SYMLED"
    210 led_off:
    211 	NOP;
    212 	WAIT RESELECT REL(reselect_fail)
    213 ; a NOP by default; patched with MOVE GPREG & 0xfe to GPREG on compile-time
    214 ; option "SIOP_SYMLED"
    215 led_on2:
    216 	NOP;
    217 	MOVE SSID & 0x8f to SFBR
    218 	MOVE SFBR to SCRATCHA0 ; save reselect ID
    219 ; find the right param for this target
    220 resel_targ0:
    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 	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 	INT int_reseltarg;
    237 lunsw_return:
    238 	MOVE 1, abs_msgin, WHEN MSG_IN;
    239 	MOVE SFBR & 0x07 to SCRATCHA1; save LUN
    240 	CLEAR ACK;
    241 	RETURN, WHEN NOT MSG_IN; If no more message, jump to lun sw
    242 	MOVE 1, abs_msgin, WHEN MSG_IN;
    243 	CLEAR ACK;
    244 	MOVE SFBR  to SCRATCHA3; save message
    245 	RETURN, IF NOT 0x20; jump to lun sw if not simple tag msg
    246 	MOVE 1, abs_msgin, WHEN MSG_IN; get tag
    247 	CLEAR ACK;
    248 	MOVE SFBR  to SCRATCHA2; save tag
    249 	RETURN; jump to lun sw
    250 
    251 handle_sdp:
    252 	CLEAR ACK;
    253 	MOVE SCRATCHA0 | flag_sdp TO SCRATCHA0;
    254 	; should get a disconnect message now
    255 msgin:
    256 	CLEAR ATN
    257 	MOVE FROM t_msg_in, WHEN MSG_IN;
    258 handle_msgin:
    259 	JUMP REL(handle_cmpl), IF 0x00        ; command complete message
    260 	JUMP REL(handle_sdp), IF 0x02	      ; save data pointer message
    261 	JUMP REL(handle_extin), IF 0x01	      ; extended message
    262 	INT int_msgin, IF not 0x04;
    263 	CALL REL(disconnect)                  ; disconnect message;
    264 ; if we didn't get sdp, no need to interrupt
    265 	MOVE SCRATCHA0 & flag_sdp TO SFBR;
    266 	INT int_disc, IF not 0x00;
    267 ; update offset if we did some data transfer
    268 	MOVE SCRATCHA1 TO SFBR;
    269 	JUMP REL(script_sched), if 0x00;
    270 	INT int_saveoffset;
    271 
    272 msgin_ack:
    273 selected:
    274 	CLEAR ACK;
    275 	JUMP REL(waitphase);
    276 
    277 ; entry point for msgout after a msgin or status phase
    278 send_msgout:
    279 	SET ATN;
    280 	CLEAR ACK;
    281 msgout:
    282 	MOVE FROM t_msg_out, WHEN MSG_OUT;
    283 	CLEAR ATN;
    284 	JUMP REL(waitphase);
    285 cmdout:
    286 	MOVE FROM t_cmd, WHEN CMD;
    287 	JUMP REL(waitphase);
    288 status:
    289 	MOVE FROM t_status, WHEN STATUS;
    290 	JUMP REL(waitphase);
    291 datain:
    292 	CALL REL(savedsa);
    293 	MOVE SCRATCHA0 | flag_data TO SCRATCHA0;
    294 datain_loop:
    295 	MOVE FROM t_data, WHEN DATA_IN;
    296 	MOVE SCRATCHA1 + 1 TO SCRATCHA1	; adjust offset
    297 	MOVE DSA0 + 8 to DSA0;
    298 	MOVE DSA1 + 0 to DSA1 WITH CARRY;
    299 	MOVE DSA2 + 0 to DSA2 WITH CARRY;
    300 	MOVE DSA3 + 0 to DSA3 WITH CARRY;
    301 	JUMP REL(datain_loop), WHEN DATA_IN;
    302 	CALL REL(restoredsa);
    303 	MOVE SCRATCHA0 & flag_data_mask TO SCRATCHA0;
    304 	JUMP REL(waitphase);
    305 
    306 dataout:
    307 	CALL REL(savedsa);
    308 	MOVE SCRATCHA0 | flag_data TO SCRATCHA0;
    309 dataout_loop:
    310 	MOVE FROM t_data, WHEN DATA_OUT;
    311 	MOVE SCRATCHA1 + 1 TO SCRATCHA1	; adjust offset
    312 	MOVE DSA0 + 8 to DSA0;
    313 	MOVE DSA1 + 0 to DSA1 WITH CARRY;
    314 	MOVE DSA2 + 0 to DSA2 WITH CARRY;
    315 	MOVE DSA3 + 0 to DSA3 WITH CARRY;
    316 	JUMP REL(dataout_loop), WHEN DATA_OUT;
    317 	CALL REL(restoredsa);
    318 	MOVE SCRATCHA0 & flag_data_mask TO SCRATCHA0;
    319 	JUMP REL(waitphase);
    320 
    321 savedsa:
    322 	MOVE DSA0 to SFBR;
    323 	MOVE SFBR to SCRATCHB0;
    324 	MOVE DSA1 to SFBR;
    325 	MOVE SFBR to SCRATCHB1;
    326 	MOVE DSA2 to SFBR;
    327 	MOVE SFBR to SCRATCHB2;
    328 	MOVE DSA3 to SFBR;
    329 	MOVE SFBR to SCRATCHB3;
    330 	RETURN;
    331 
    332 restoredsa:
    333 	MOVE SCRATCHB0 TO SFBR;
    334 	MOVE SFBR TO DSA0;
    335 	MOVE SCRATCHB1 TO SFBR;
    336 	MOVE SFBR TO DSA1;
    337 	MOVE SCRATCHB2 TO SFBR;
    338 	MOVE SFBR TO DSA2;
    339 	MOVE SCRATCHB3 TO SFBR;
    340 	MOVE SFBR TO DSA3;
    341 	RETURN;
    342 
    343 disconnect:
    344 	MOVE SCNTL2 & 0x7f TO SCNTL2;
    345 	CLEAR ATN;
    346 	CLEAR ACK;
    347 	WAIT DISCONNECT;
    348 	RETURN;
    349 
    350 handle_cmpl:
    351 	CALL REL(disconnect);
    352 	INT int_done;
    353 
    354 handle_extin:
    355 	CLEAR ACK;
    356 	MOVE FROM t_ext_msg_in, WHEN MSG_IN;
    357 	INT int_extmsgin; /* let host fill in t_ext_msg_data */
    358 get_extmsgdata:
    359 	CLEAR ACK;
    360 	MOVE FROM t_ext_msg_data, WHEN MSG_IN;
    361 	INT int_extmsgdata;
    362 msgin_space:
    363 	NOP; space to store msgin when reselect
    364 
    365 
    366 ;; per-target switch script for LUNs
    367 ; hack: we first do a call to the target-specific code, so that a return
    368 ; in the main switch will jump to the lun switch.
    369 PROC lun_switch:
    370 restore_scntl3:
    371 	MOVE 0xff TO SCNTL3;
    372 	MOVE 0xff TO SXFER;
    373 	JUMP abs_lunsw_return;
    374 lun_switch_entry:
    375 	CALL REL(restore_scntl3);
    376 	MOVE SCRATCHA1 TO SFBR;
    377 resel_lun0:
    378 	INT int_resellun;
    379 
    380 ;; Per-device switch script for tag
    381 PROC tag_switch:
    382 tag_switch_entry:
    383 	MOVE SCRATCHA2 TO SFBR; restore tag
    384 resel_tag0:
    385 	JUMP abs_tag0, IF 0x00;
    386 	JUMP abs_tag0, IF 0x01;
    387 	JUMP abs_tag0, IF 0x02;
    388 	JUMP abs_tag0, IF 0x03;
    389 	JUMP abs_tag0, IF 0x04;
    390 	JUMP abs_tag0, IF 0x05;
    391 	JUMP abs_tag0, IF 0x06;
    392 	JUMP abs_tag0, IF 0x07;
    393 	JUMP abs_tag0, IF 0x08;
    394 	JUMP abs_tag0, IF 0x09;
    395 	JUMP abs_tag0, IF 0x0a;
    396 	JUMP abs_tag0, IF 0x0b;
    397 	JUMP abs_tag0, IF 0x0c;
    398 	JUMP abs_tag0, IF 0x0d;
    399 	JUMP abs_tag0, IF 0x0e;
    400 	JUMP abs_tag0, IF 0x0f;
    401 	INT int_reseltag;
    402 
    403 ;; per-command script: select, and called after a reselect to load DSA
    404 
    405 PROC load_dsa:
    406 ; Can't use MOVE MEMORY to load DSA, doesn't work I/O mapped
    407 rdsa0:
    408 	MOVE 0xf0 to DSA0;
    409 rdsa1:
    410 	MOVE 0xf1 to DSA1;
    411 rdsa2:
    412 	MOVE 0xf2 to DSA2;
    413 rdsa3:
    414 	MOVE 0xf3 to DSA3;
    415 	RETURN;
    416 ldsa_reload_dsa:
    417 	CALL REL(rdsa0);
    418 	JUMP ldsa_abs_reselected;
    419 ldsa_select:
    420 	CALL REL(rdsa0);
    421 	SELECT ATN FROM t_id, ldsa_abs_reselect;
    422 	MOVE MEMORY 4, ldsa_abs_data, ldsa_abs_slot;
    423 	JUMP ldsa_abs_selected;
    424 ldsa_data:
    425 	NOP; contains data used by the MOVE MEMORY
    426 
    427 PROC siop_led_on:
    428 	MOVE GPREG & 0xfe TO GPREG;
    429 
    430 PROC siop_led_off:
    431 	MOVE GPREG | 0x01 TO GPREG;
    432