esiop.ss revision 1.6
1; $NetBSD: esiop.ss,v 1.6 2002/04/23 20:12:39 bouyer Exp $ 2 3; 4; Copyright (c) 2002 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. Neither the name of the University nor the names of its contributors 18; may be used to endorse or promote products derived from this software 19; without specific prior written permission. 20; 21; THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24; ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31; SUCH DAMAGE. 32; 33 34ARCH 825 35 36; offsets in siop_common_xfer 37ABSOLUTE t_id = 40; 38ABSOLUTE t_msg_in = 48; 39ABSOLUTE t_ext_msg_in = 56; 40ABSOLUTE t_ext_msg_data = 64; 41ABSOLUTE t_msg_out = 72; 42ABSOLUTE t_cmd = 80; 43ABSOLUTE t_status = 88; 44ABSOLUTE t_data = 96; 45 46; offsets in the per-target lun table 47ABSOLUTE target_id = 0x0; 48ABSOLUTE target_luntbl = 0x8; 49 50;; interrupt codes 51; interrupts that needs a valid target/lun/tag 52ABSOLUTE int_done = 0xff00; 53ABSOLUTE int_msgin = 0xff01; 54ABSOLUTE int_extmsgin = 0xff02; 55ABSOLUTE int_extmsgdata = 0xff03; 56ABSOLUTE int_disc = 0xff04; 57; interrupts that don't have a valid I/T/Q 58ABSOLUTE int_resfail = 0xff80; 59ABSOLUTE int_err = 0xffff; 60 61; We use the various scratch[a-j] registers to keep internal status: 62 63; scratchA1: offset in data DSA (for save data pointer) 64; scratchB: save/restore DSA in data loop 65; scratchC: current target/lun/tag 66; scratchC0: flags 67ABSOLUTE f_c_target = 0x01 ; target valid 68ABSOLUTE f_c_lun = 0x02 ; lun valud 69ABSOLUTE f_c_tag = 0x04 ; tag valid 70ABSOLUTE f_c_data = 0x08 ; data I/O in progress 71ABSOLUTE f_c_data_mask = 0xf7 ; ~f_c_data 72ABSOLUTE f_c_sdp = 0x10 ; got save data pointer message 73; scratchC[1-3]: target/lun/tag 74 75; scratchD: current DSA in start cmd ring 76; scratchE0: index in start cmd ring 77ABSOLUTE ncmd_slots = 64 ; number of slots in CMD ring 78; flags in a cmd slot 79ABSOLUTE f_cmd_free = 0x01 ; this slot is free 80ABSOLUTE f_cmd_ignore = 0x02 ; this slot is not free but don't start it 81; offsets in a cmd slot 82ABSOLUTE o_cmd_dsa = 0; also holds f_cmd_* 83ABSOLUTE o_cmd_id = 4; 84 85; SCRATCHE1: last status 86 87ENTRY reselect; 88ENTRY cmdr0; 89ENTRY cmdr1; 90ENTRY cmdr2; 91ENTRY cmdr3; 92ENTRY led_on1; 93ENTRY led_on2; 94ENTRY led_off; 95ENTRY status; 96ENTRY msgin; 97ENTRY msgin_ack; 98ENTRY get_extmsgdata; 99ENTRY send_msgout; 100ENTRY script_sched; 101ENTRY load_targtable; 102 103EXTERN tlq_offset; 104EXTERN abs_msgin2; 105 106PROC esiop_script: 107 108no_cmd: 109 MOVE ISTAT & 0x10 TO SFBR; pending done command ? 110 INTFLY 0, IF NOT 0x00; 111reselect: 112 MOVE 0x00 TO SCRATCHA1; 113 MOVE 0x00 TO SCRATCHC0; 114 MOVE 0xff TO SCRATCHE1; 115; a NOP by default; patched with MOVE GPREG | 0x01 to GPREG on compile-time 116; option "SIOP_SYMLED" 117led_off: 118 NOP; 119 WAIT RESELECT REL(reselect_fail); 120; a NOP by default; patched with MOVE GPREG & 0xfe to GPREG on compile-time 121; option "SIOP_SYMLED" 122led_on2: 123 NOP; 124 MOVE SSID & 0x0f to SFBR; 125 MOVE SFBR to SCRATCHC1; 126 MOVE SCRATCHC0 | f_c_target to SCRATCHC0; save target 127 CLEAR CARRY; 128 MOVE SCRATCHC1 SHL SFBR; 129 MOVE SFBR SHL DSA0; target * 4 in dsa 130 MOVE 0x0 to DSA1; 131 MOVE 0x0 to DSA2; 132 MOVE 0x0 to DSA3; 133; load DSA for the target table 134load_targtable: 135 MOVE DSA0 + 0x00 to DSA0; host will patch 0x0 with base of table 136 MOVE DSA1 + 0x00 to DSA1 with carry; 137 MOVE DSA2 + 0x00 to DSA2 with carry; 138 MOVE DSA3 + 0x00 to DSA3 with carry; now dsa -> basetable + target * 4 139 LOAD DSA0, 4, FROM 0; now load DSA for this target 140 SELECT FROM target_id, REL(nextisn); 141nextisn: 142 MOVE 1, abs_msgin2, WHEN MSG_IN; 143 MOVE SFBR & 0x07 to SCRATCHC2; 144 MOVE SCRATCHC0 | f_c_lun to SCRATCHC0; save LUN 145 CLEAR ACK and CARRY; 146 MOVE SCRATCHC2 SHL SFBR; 147 MOVE SFBR SHL SFBR; lun * 4 148 MOVE DSA0 + SFBR TO DSA0; 149 MOVE DSA1 + 0x0 TO DSA1 with carry; 150 MOVE DSA2 + 0x0 TO DSA2 with carry; 151 MOVE DSA3 + 0x0 TO DSA3 with carry; 152 LOAD DSA0, 4, from target_luntbl; load DSA for this LUN 153 JUMP REL(waitphase), WHEN NOT MSG_IN; 154 MOVE 1, abs_msgin2, WHEN MSG_IN; 155 CLEAR ACK; 156 INT int_msgin, IF NOT 0x20; not a simple tag message, let host handle it 157 MOVE 1, abs_msgin2, WHEN MSG_IN; get tag 158 CLEAR ACK; 159 MOVE SFBR to SCRATCHA2; 160 MOVE SFBR to SCRATCHC3; 161 MOVE SCRATCHC0 | f_c_tag to SCRATCHC0; save TAG 162 MOVE 0x0 to SCRATCHA3; 163 CLEAR CARRY; 164 MOVE SCRATCHA2 SHL SCRATCHA2; 165 MOVE SCRATCHA3 SHL SCRATCHA3; 166 MOVE SCRATCHA2 SHL SCRATCHA2; 167 MOVE SCRATCHA3 SHL SCRATCHA3; TAG * 4 to SCRATCHA(2,3) 168 MOVE SCRATCHA2 TO SFBR; 169 MOVE DSA0 + SFBR TO DSA0; 170 MOVE DSA1 + 0x00 TO DSA1 with CARRY; 171 MOVE DSA2 + 0x00 TO DSA2 with CARRY; 172 MOVE DSA3 + 0x00 TO DSA3 with CARRY; 173 MOVE SCRATCHA3 TO SFBR; 174 MOVE DSA1 + SFBR TO DSA1; 175 MOVE DSA2 + 0x00 TO DSA2 with CARRY; 176 MOVE DSA3 + 0x00 TO DSA3 with CARRY; SCRACHA(2,3) + DSA to DSA 177 LOAD DSA0, 4, from 0; load DSA for this tag 178 JUMP REL(waitphase); 179 180reselect_fail: 181 ; check that host asserted SIGP, this'll clear SIGP in ISTAT 182 MOVE CTEST2 & 0x40 TO SFBR; 183 INT int_resfail, IF 0x00; 184script_sched: 185; Load ring DSA 186 MOVE SCRATCHD0 to SFBR; 187 MOVE SFBR to DSA0; 188 MOVE SCRATCHD1 to SFBR; 189 MOVE SFBR to DSA1; 190 MOVE SCRATCHD2 to SFBR; 191 MOVE SFBR to DSA2; 192 MOVE SCRATCHD3 to SFBR; 193 MOVE SFBR to DSA3; 194 LOAD SCRATCHA0,4, from o_cmd_dsa; /* get flags */ 195 MOVE SCRATCHA0 & f_cmd_free to SFBR; 196 JUMP REL(no_cmd), IF NOT 0x0; 197 MOVE SCRATCHA0 & f_cmd_ignore to SFBR; 198 JUMP REL(ignore_cmd), IF NOT 0x0; 199; this slot is busy, attempt to exec command 200 SELECT ATN FROM o_cmd_id, REL(reselect); 201; select either succeeded or timed out. 202; if timed out the STO interrupt will be posted at the first SCSI bus access 203; waiting for a valid phase, so we have to do it now. If not a MSG_OUT phase, 204; this is an error anyway (we selected with ATN) 205 INT int_err, WHEN NOT MSG_OUT; 206ignore_cmd: 207 MOVE SCRATCHE0 + 1 to SCRATCHE0; 208 MOVE SCRATCHD0 + 8 to SCRATCHD0; sizeof (esiop_cmd_slot) 209 MOVE SCRATCHD1 + 0 to SCRATCHD1 WITH CARRY; 210 MOVE SCRATCHD2 + 0 to SCRATCHD2 WITH CARRY; 211 MOVE SCRATCHD3 + 0 to SCRATCHD3 WITH CARRY; 212 MOVE SCRATCHE0 TO SFBR; 213 JUMP REL(handle_cmd), IF NOT ncmd_slots; 214; reset pointers to beggining of area 215cmdr0: 216 MOVE 0xff to SCRATCHD0; correct value will be patched by driver 217cmdr1: 218 MOVE 0xff to SCRATCHD1; 219cmdr2: 220 MOVE 0xff to SCRATCHD2; 221cmdr3: 222 MOVE 0xff to SCRATCHD3; 223 MOVE 0x00 to SCRATCHE0; 224handle_cmd: 225 MOVE SCRATCHA0 | f_cmd_free to SCRATCHA0; 226 STORE noflush SCRATCHA0, 4, FROM o_cmd_dsa; 227 MOVE SCRATCHA0 & f_cmd_ignore to SFBR; 228 JUMP REL(script_sched), IF NOT 0x00; /* next command if ignore */ 229 230; a NOP by default; patched with MOVE GPREG & 0xfe to GPREG on compile-time 231; option "SIOP_SYMLED" 232led_on1: 233 NOP; 234 LOAD DSA0, 4, FROM o_cmd_dsa; /* load new DSA */ 235 MOVE DSA0 & 0xfe to DSA0; /* clear f_cmd_free */ 236 MOVE 0x00 TO SCRATCHA1; 237 MOVE 0xff TO SCRATCHE1; 238 LOAD SCRATCHC0, 4, FROM tlq_offset; 239;we can now send our identify message 240send_msgout: ; entry point for msgout after a msgin or status phase 241 SET ATN; 242 CLEAR ACK; 243msgout: 244 MOVE FROM t_msg_out, WHEN MSG_OUT; 245 CLEAR ATN; 246 JUMP REL(waitphase); 247 248msgin_ack: 249 CLEAR ACK; 250waitphase: 251 JUMP REL(msgout), WHEN MSG_OUT; 252 JUMP REL(msgin), WHEN MSG_IN; 253 JUMP REL(dataout), WHEN DATA_OUT; 254 JUMP REL(datain), WHEN DATA_IN; 255 JUMP REL(cmdout), WHEN CMD; 256 JUMP REL(status), WHEN STATUS; 257 INT int_err; 258 259 260handle_sdp: 261 CLEAR ACK; 262 MOVE SCRATCHC0 | f_c_sdp TO SCRATCHC0; 263 ; should get a disconnect message now 264msgin: 265 CLEAR ATN 266 MOVE FROM t_msg_in, WHEN MSG_IN; 267handle_msgin: 268 JUMP REL(handle_cmpl), IF 0x00 ; command complete message 269 JUMP REL(handle_sdp), IF 0x02 ; save data pointer message 270 JUMP REL(handle_extin), IF 0x01 ; extended message 271 INT int_msgin, IF NOT 0x04; 272 CALL REL(disconnect) ; disconnect message 273; if we didn't get sdp, or if offset is 0, no need to interrupt 274 MOVE SCRATCHC0 & f_c_sdp TO SFBR; 275 JUMP REL(script_sched), if 0x00; 276 MOVE SCRATCHA1 TO SFBR; 277 JUMP REL(script_sched), if 0x00; 278; Ok, we need to save data pointers 279 INT int_disc; 280 281cmdout: 282 MOVE FROM t_cmd, WHEN CMD; 283 JUMP REL(waitphase); 284status: 285 MOVE FROM t_status, WHEN STATUS; 286 MOVE SFBR TO SCRATCHE1; 287 JUMP REL(waitphase); 288datain: 289 CALL REL(savedsa); 290 MOVE SCRATCHC0 | f_c_data TO SCRATCHC0; 291 datain_loop: 292 MOVE FROM t_data, WHEN DATA_IN; 293 MOVE SCRATCHA1 + 1 TO SCRATCHA1 ; adjust offset 294 MOVE DSA0 + 8 to DSA0; 295 MOVE DSA1 + 0 to DSA1 WITH CARRY; 296 MOVE DSA2 + 0 to DSA2 WITH CARRY; 297 MOVE DSA3 + 0 to DSA3 WITH CARRY; 298 JUMP REL(datain_loop), WHEN DATA_IN; 299 CALL REL(restoredsa); 300 MOVE SCRATCHC0 & f_c_data_mask TO SCRATCHC0; 301 JUMP REL(waitphase); 302 303dataout: 304 CALL REL(savedsa); 305 MOVE SCRATCHC0 | f_c_data TO SCRATCHC0; 306dataout_loop: 307 MOVE FROM t_data, WHEN DATA_OUT; 308 MOVE SCRATCHA1 + 1 TO SCRATCHA1 ; adjust offset 309 MOVE DSA0 + 8 to DSA0; 310 MOVE DSA1 + 0 to DSA1 WITH CARRY; 311 MOVE DSA2 + 0 to DSA2 WITH CARRY; 312 MOVE DSA3 + 0 to DSA3 WITH CARRY; 313 JUMP REL(dataout_loop), WHEN DATA_OUT; 314 CALL REL(restoredsa); 315 MOVE SCRATCHC0 & f_c_data_mask TO SCRATCHC0; 316 JUMP REL(waitphase); 317 318savedsa: 319 MOVE DSA0 to SFBR; 320 MOVE SFBR to SCRATCHB0; 321 MOVE DSA1 to SFBR; 322 MOVE SFBR to SCRATCHB1; 323 MOVE DSA2 to SFBR; 324 MOVE SFBR to SCRATCHB2; 325 MOVE DSA3 to SFBR; 326 MOVE SFBR to SCRATCHB3; 327 RETURN; 328 329restoredsa: 330 MOVE SCRATCHB0 TO SFBR; 331 MOVE SFBR TO DSA0; 332 MOVE SCRATCHB1 TO SFBR; 333 MOVE SFBR TO DSA1; 334 MOVE SCRATCHB2 TO SFBR; 335 MOVE SFBR TO DSA2; 336 MOVE SCRATCHB3 TO SFBR; 337 MOVE SFBR TO DSA3; 338 RETURN; 339 340disconnect: 341 MOVE SCNTL2 & 0x7f TO SCNTL2; 342 CLEAR ATN; 343 CLEAR ACK; 344 WAIT DISCONNECT; 345 RETURN; 346 347handle_cmpl: 348 CALL REL(disconnect); 349 MOVE SCRATCHE1 to SFBR; 350 INT int_done, IF NOT 0x00; if status is not "done", let host handle it 351 MOVE ISTAT | 0x10 TO ISTAT; else signal that cmd is done in ISTAT 352 JUMP REL(script_sched); and attempt next command 353 354handle_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 */ 358get_extmsgdata: 359 CLEAR ACK; 360 MOVE FROM t_ext_msg_data, WHEN MSG_IN; 361 INT int_extmsgdata; 362 363PROC esiop_led_on: 364 MOVE GPREG & 0xfe TO GPREG; 365 366PROC esiop_led_off: 367 MOVE GPREG | 0x01 TO GPREG; 368