Home | History | Annotate | Line # | Download | only in siop
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