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