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