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