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