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