esiop.ss revision 1.1
11.1Sbouyer; $NetBSD: esiop.ss,v 1.1 2002/04/21 22:52:06 bouyer Exp $ 21.1Sbouyer 31.1Sbouyer; 41.1Sbouyer; Copyright (c) 2002 Manuel Bouyer. 51.1Sbouyer; 61.1Sbouyer; Redistribution and use in source and binary forms, with or without 71.1Sbouyer; modification, are permitted provided that the following conditions 81.1Sbouyer; are met: 91.1Sbouyer; 1. Redistributions of source code must retain the above copyright 101.1Sbouyer; notice, this list of conditions and the following disclaimer. 111.1Sbouyer; 2. Redistributions in binary form must reproduce the above copyright 121.1Sbouyer; notice, this list of conditions and the following disclaimer in the 131.1Sbouyer; documentation and/or other materials provided with the distribution. 141.1Sbouyer; 3. All advertising materials mentioning features or use of this software 151.1Sbouyer; must display the following acknowledgement: 161.1Sbouyer; This product includes software developed by the University of 171.1Sbouyer; California, Berkeley and its contributors. 181.1Sbouyer; 4. Neither the name of the University nor the names of its contributors 191.1Sbouyer; may be used to endorse or promote products derived from this software 201.1Sbouyer; without specific prior written permission. 211.1Sbouyer; 221.1Sbouyer; THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 231.1Sbouyer; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 241.1Sbouyer; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 251.1Sbouyer; ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 261.1Sbouyer; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 271.1Sbouyer; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 281.1Sbouyer; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 291.1Sbouyer; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 301.1Sbouyer; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 311.1Sbouyer; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 321.1Sbouyer; SUCH DAMAGE. 331.1Sbouyer; 341.1Sbouyer 351.1SbouyerARCH 825 361.1Sbouyer 371.1Sbouyer; offsets in sym_xfer 381.1SbouyerABSOLUTE t_id = 24; 391.1SbouyerABSOLUTE t_msg_in = 32; 401.1SbouyerABSOLUTE t_ext_msg_in = 40; 411.1SbouyerABSOLUTE t_ext_msg_data = 48; 421.1SbouyerABSOLUTE t_msg_out = 56; 431.1SbouyerABSOLUTE t_cmd = 64; 441.1SbouyerABSOLUTE t_status = 72; 451.1SbouyerABSOLUTE t_data = 80; 461.1Sbouyer 471.1Sbouyer; offsets in the per-target lun table 481.1SbouyerABSOLUTE target_id = 0x0; 491.1SbouyerABSOLUTE target_luntbl = 0x8; 501.1Sbouyer 511.1Sbouyer;; interrupt codes 521.1Sbouyer; interrupts that needs a valid target/lun/tag 531.1SbouyerABSOLUTE int_done = 0xff00; 541.1SbouyerABSOLUTE int_msgin = 0xff01; 551.1SbouyerABSOLUTE int_extmsgin = 0xff02; 561.1SbouyerABSOLUTE int_extmsgdata = 0xff03; 571.1SbouyerABSOLUTE int_disc = 0xff04; 581.1Sbouyer; interrupts that don't have a valid I/T/Q 591.1SbouyerABSOLUTE int_resfail = 0xff80; 601.1SbouyerABSOLUTE int_err = 0xffff; 611.1Sbouyer 621.1Sbouyer; We use the various scratch[a-j] registers to keep internal status: 631.1Sbouyer 641.1Sbouyer; scratchA1: offset in data DSA (for save data pointer) 651.1Sbouyer; scratchB: save/restore DSA in data loop 661.1Sbouyer; scratchC: current target/lun/tag 671.1Sbouyer; scratchC0: flags 681.1SbouyerABSOLUTE f_c_target = 0x01 ; target valid 691.1SbouyerABSOLUTE f_c_lun = 0x02 ; lun valud 701.1SbouyerABSOLUTE f_c_tag = 0x04 ; tag valid 711.1SbouyerABSOLUTE f_c_data = 0x08 ; data I/O in progress 721.1SbouyerABSOLUTE f_c_data_mask = 0xf7 ; ~f_c_data 731.1SbouyerABSOLUTE f_c_sdp = 0x10 ; got save data pointer message 741.1Sbouyer; scratchC[1-3]: target/lun/tag 751.1Sbouyer 761.1Sbouyer; scratchD: current DSA in start cmd ring 771.1Sbouyer; scratchE0: index in start cmd ring 781.1SbouyerABSOLUTE ncmd_slots = 64 ; number of slots in CMD ring 791.1Sbouyer; flags in a cmd slot 801.1SbouyerABSOLUTE f_cmd_free = 0x01 ; this slot is free 811.1Sbouyer; offsets in a cmd slot 821.1SbouyerABSOLUTE o_cmd_dsa = 0; also holds f_cmd_free 831.1SbouyerABSOLUTE o_cmd_id = 4; 841.1Sbouyer 851.1Sbouyer; SCRATCHE1: last status 861.1Sbouyer 871.1SbouyerENTRY reselect; 881.1SbouyerENTRY ring_reset; 891.1SbouyerENTRY cmdr0; 901.1SbouyerENTRY cmdr1; 911.1SbouyerENTRY cmdr2; 921.1SbouyerENTRY cmdr3; 931.1SbouyerENTRY led_on1; 941.1SbouyerENTRY led_on2; 951.1SbouyerENTRY led_off; 961.1SbouyerENTRY status; 971.1SbouyerENTRY msgin; 981.1SbouyerENTRY msgin_ack; 991.1SbouyerENTRY get_extmsgdata; 1001.1SbouyerENTRY send_msgout; 1011.1SbouyerENTRY script_sched; 1021.1SbouyerENTRY load_targtable; 1031.1Sbouyer 1041.1SbouyerEXTERN tlq_offset; 1051.1SbouyerEXTERN abs_msgin2; 1061.1Sbouyer 1071.1SbouyerPROC esiop_script: 1081.1Sbouyer 1091.1Sbouyerno_cmd: 1101.1Sbouyer MOVE ISTAT & 0x10 TO SFBR; pending done command ? 1111.1Sbouyer INTFLY 0, IF NOT 0x00; 1121.1Sbouyerreselect: 1131.1Sbouyer MOVE 0x00 TO SCRATCHA1; 1141.1Sbouyer MOVE 0x00 TO SCRATCHC0; 1151.1Sbouyer MOVE 0xff TO SCRATCHE1; 1161.1Sbouyer; a NOP by default; patched with MOVE GPREG | 0x01 to GPREG on compile-time 1171.1Sbouyer; option "SIOP_SYMLED" 1181.1Sbouyerled_off: 1191.1Sbouyer NOP; 1201.1Sbouyer WAIT RESELECT REL(reselect_fail); 1211.1Sbouyer; a NOP by default; patched with MOVE GPREG & 0xfe to GPREG on compile-time 1221.1Sbouyer; option "SIOP_SYMLED" 1231.1Sbouyerled_on2: 1241.1Sbouyer NOP; 1251.1Sbouyer MOVE SSID & 0x0f to SFBR; 1261.1Sbouyer MOVE SFBR to SCRATCHC1; 1271.1Sbouyer MOVE SCRATCHC0 | f_c_target to SCRATCHC0; save target 1281.1Sbouyer CLEAR CARRY; 1291.1Sbouyer MOVE SCRATCHC1 SHL SFBR; 1301.1Sbouyer MOVE SFBR SHL DSA0; target * 4 1311.1Sbouyer MOVE 0x0 to DSA1; 1321.1Sbouyer MOVE 0x0 to DSA2; 1331.1Sbouyer MOVE 0x0 to DSA3; 1341.1Sbouyer; load DSA for the target table 1351.1Sbouyerload_targtable: 1361.1Sbouyer MOVE DSA0 + 0x00 to DSA0; 1371.1Sbouyer MOVE DSA1 + 0x00 to DSA1 with carry; 1381.1Sbouyer MOVE DSA2 + 0x00 to DSA2 with carry; 1391.1Sbouyer MOVE DSA3 + 0x00 to DSA3 with carry; 1401.1Sbouyer LOAD DSA0, 4, FROM 0; now load DSA for this target 1411.1Sbouyer SELECT FROM target_id, REL(nextisn); 1421.1Sbouyernextisn: 1431.1Sbouyer MOVE 1, abs_msgin2, WHEN MSG_IN; 1441.1Sbouyer MOVE SFBR & 0x07 to SCRATCHC2; 1451.1Sbouyer MOVE SCRATCHC0 | f_c_lun to SCRATCHC0; save LUN 1461.1Sbouyer CLEAR ACK and CARRY; 1471.1Sbouyer MOVE SCRATCHC2 SHL SFBR; 1481.1Sbouyer MOVE SFBR SHL SFBR; target * 4 1491.1Sbouyer MOVE DSA0 + SFBR TO DSA0; 1501.1Sbouyer MOVE DSA1 + 0x0 TO DSA1 with carry; 1511.1Sbouyer MOVE DSA2 + 0x0 TO DSA2 with carry; 1521.1Sbouyer MOVE DSA3 + 0x0 TO DSA3 with carry; 1531.1Sbouyer LOAD DSA0, 4, from target_luntbl; load DSA for ths LUN 1541.1Sbouyer JUMP REL(waitphase); 1551.1Sbouyer 1561.1Sbouyerreselect_fail: 1571.1Sbouyer ; check that host asserted SIGP, this'll clear SIGP in ISTAT 1581.1Sbouyer MOVE CTEST2 & 0x40 TO SFBR; 1591.1Sbouyer INT int_resfail, IF 0x00; 1601.1Sbouyerscript_sched: 1611.1Sbouyer; Load ring DSA 1621.1Sbouyer MOVE SCRATCHD0 to SFBR; 1631.1Sbouyer MOVE SFBR to DSA0; 1641.1Sbouyer MOVE SCRATCHD1 to SFBR; 1651.1Sbouyer MOVE SFBR to DSA1; 1661.1Sbouyer MOVE SCRATCHD2 to SFBR; 1671.1Sbouyer MOVE SFBR to DSA2; 1681.1Sbouyer MOVE SCRATCHD3 to SFBR; 1691.1Sbouyer MOVE SFBR to DSA3; 1701.1Sbouyer LOAD SCRATCHA0,4, from o_cmd_dsa; /* get flags */ 1711.1Sbouyer MOVE SCRATCHA0 & f_cmd_free to SFBR; 1721.1Sbouyer JUMP REL(no_cmd), IF NOT 0x0; 1731.1Sbouyer; this slot is busy, attempt to exec command 1741.1Sbouyer SELECT ATN FROM o_cmd_id, REL(reselect); 1751.1Sbouyer; select either succeeded or timed out. In either case update ring pointer. 1761.1Sbouyer; if timed out the STO interrupt will be posted at the first SCSI bus access 1771.1Sbouyer; waiting for a valid phase. 1781.1Sbouyer MOVE SCRATCHE0 + 1 to SFBR; 1791.1Sbouyer MOVE SFBR to SCRATCHE0; 1801.1Sbouyer JUMP REL(ring_reset), IF ncmd_slots; 1811.1Sbouyer MOVE SCRATCHD0 + 8 to SCRATCHD0; sizeof (esiop_cmd_slot) 1821.1Sbouyer MOVE SCRATCHD1 + 0 to SCRATCHD1 WITH CARRY; 1831.1Sbouyer MOVE SCRATCHD2 + 0 to SCRATCHD2 WITH CARRY; 1841.1Sbouyer MOVE SCRATCHD3 + 0 to SCRATCHD3 WITH CARRY; 1851.1Sbouyer JUMP REL(handle_cmd); 1861.1Sbouyerring_reset: 1871.1Sbouyercmdr0: 1881.1Sbouyer MOVE 0xff to SCRATCHD0; correct value will be patched by driver 1891.1Sbouyercmdr1: 1901.1Sbouyer MOVE 0xff to SCRATCHD1; 1911.1Sbouyercmdr2: 1921.1Sbouyer MOVE 0xff to SCRATCHD2; 1931.1Sbouyercmdr3: 1941.1Sbouyer MOVE 0xff to SCRATCHD3; 1951.1Sbouyer MOVE 0x00 to SCRATCHE0; 1961.1Sbouyerhandle_cmd: 1971.1Sbouyer; a NOP by default; patched with MOVE GPREG & 0xfe to GPREG on compile-time 1981.1Sbouyer; option "SIOP_SYMLED" 1991.1Sbouyerled_on1: 2001.1Sbouyer NOP; 2011.1Sbouyer MOVE SCRATCHA0 | f_cmd_free to SCRATCHA0; 2021.1Sbouyer STORE noflush SCRATCHA0, 4, FROM o_cmd_dsa; 2031.1Sbouyer LOAD DSA0, 4, FROM o_cmd_dsa; /* load new DSA */ 2041.1Sbouyer MOVE DSA0 & 0xfc to DSA0; /* clear flags */ 2051.1Sbouyer MOVE 0x00 TO SCRATCHA1; 2061.1Sbouyer MOVE 0xff TO SCRATCHE1; 2071.1Sbouyer LOAD SCRATCHC0, 4, FROM tlq_offset; 2081.1Sbouyermsgin_ack: 2091.1Sbouyer CLEAR ACK; 2101.1Sbouyerwaitphase: 2111.1Sbouyer JUMP REL(msgout), WHEN MSG_OUT; 2121.1Sbouyer JUMP REL(msgin), WHEN MSG_IN; 2131.1Sbouyer JUMP REL(dataout), WHEN DATA_OUT; 2141.1Sbouyer JUMP REL(datain), WHEN DATA_IN; 2151.1Sbouyer JUMP REL(cmdout), WHEN CMD; 2161.1Sbouyer JUMP REL(status), WHEN STATUS; 2171.1Sbouyer INT int_err; 2181.1Sbouyer 2191.1Sbouyer; entry point for msgout after a msgin or status phase 2201.1Sbouyersend_msgout: 2211.1Sbouyer SET ATN; 2221.1Sbouyer CLEAR ACK; 2231.1Sbouyermsgout: 2241.1Sbouyer MOVE FROM t_msg_out, WHEN MSG_OUT; 2251.1Sbouyer CLEAR ATN; 2261.1Sbouyer JUMP REL(waitphase); 2271.1Sbouyer 2281.1Sbouyerhandle_sdp: 2291.1Sbouyer CLEAR ACK; 2301.1Sbouyer MOVE SCRATCHC0 | f_c_sdp TO SCRATCHC0; 2311.1Sbouyer ; should get a disconnect message now 2321.1Sbouyermsgin: 2331.1Sbouyer CLEAR ATN 2341.1Sbouyer MOVE FROM t_msg_in, WHEN MSG_IN; 2351.1Sbouyerhandle_msgin: 2361.1Sbouyer JUMP REL(handle_cmpl), IF 0x00 ; command complete message 2371.1Sbouyer JUMP REL(handle_sdp), IF 0x02 ; save data pointer message 2381.1Sbouyer JUMP REL(handle_extin), IF 0x01 ; extended message 2391.1Sbouyer INT int_msgin, IF NOT 0x04; 2401.1Sbouyer CALL REL(disconnect) ; disconnect message 2411.1Sbouyer; if we didn't get sdp, or if offset is 0, no need to interrupt 2421.1Sbouyer MOVE SCRATCHC0 & f_c_sdp TO SFBR; 2431.1Sbouyer JUMP REL(script_sched), if 0x00; 2441.1Sbouyer MOVE SCRATCHA1 TO SFBR; 2451.1Sbouyer JUMP REL(script_sched), if 0x00; 2461.1Sbouyer; Ok, we need to save data pointers 2471.1Sbouyer INT int_disc; 2481.1Sbouyer 2491.1Sbouyercmdout: 2501.1Sbouyer MOVE FROM t_cmd, WHEN CMD; 2511.1Sbouyer JUMP REL(waitphase); 2521.1Sbouyerstatus: 2531.1Sbouyer MOVE FROM t_status, WHEN STATUS; 2541.1Sbouyer MOVE SFBR TO SCRATCHE1; 2551.1Sbouyer JUMP REL(waitphase); 2561.1Sbouyerdatain: 2571.1Sbouyer CALL REL(savedsa); 2581.1Sbouyer MOVE SCRATCHC0 | f_c_data TO SCRATCHC0; 2591.1Sbouyer datain_loop: 2601.1Sbouyer MOVE FROM t_data, WHEN DATA_IN; 2611.1Sbouyer MOVE SCRATCHA1 + 1 TO SCRATCHA1 ; adjust offset 2621.1Sbouyer MOVE DSA0 + 8 to DSA0; 2631.1Sbouyer MOVE DSA1 + 0 to DSA1 WITH CARRY; 2641.1Sbouyer MOVE DSA2 + 0 to DSA2 WITH CARRY; 2651.1Sbouyer MOVE DSA3 + 0 to DSA3 WITH CARRY; 2661.1Sbouyer JUMP REL(datain_loop), WHEN DATA_IN; 2671.1Sbouyer CALL REL(restoredsa); 2681.1Sbouyer MOVE SCRATCHC0 & f_c_data_mask TO SCRATCHC0; 2691.1Sbouyer JUMP REL(waitphase); 2701.1Sbouyer 2711.1Sbouyerdataout: 2721.1Sbouyer CALL REL(savedsa); 2731.1Sbouyer MOVE SCRATCHC0 | f_c_data TO SCRATCHC0; 2741.1Sbouyerdataout_loop: 2751.1Sbouyer MOVE FROM t_data, WHEN DATA_OUT; 2761.1Sbouyer MOVE SCRATCHA1 + 1 TO SCRATCHA1 ; adjust offset 2771.1Sbouyer MOVE DSA0 + 8 to DSA0; 2781.1Sbouyer MOVE DSA1 + 0 to DSA1 WITH CARRY; 2791.1Sbouyer MOVE DSA2 + 0 to DSA2 WITH CARRY; 2801.1Sbouyer MOVE DSA3 + 0 to DSA3 WITH CARRY; 2811.1Sbouyer JUMP REL(dataout_loop), WHEN DATA_OUT; 2821.1Sbouyer CALL REL(restoredsa); 2831.1Sbouyer MOVE SCRATCHC0 & f_c_data_mask TO SCRATCHC0; 2841.1Sbouyer JUMP REL(waitphase); 2851.1Sbouyer 2861.1Sbouyersavedsa: 2871.1Sbouyer MOVE DSA0 to SFBR; 2881.1Sbouyer MOVE SFBR to SCRATCHB0; 2891.1Sbouyer MOVE DSA1 to SFBR; 2901.1Sbouyer MOVE SFBR to SCRATCHB1; 2911.1Sbouyer MOVE DSA2 to SFBR; 2921.1Sbouyer MOVE SFBR to SCRATCHB2; 2931.1Sbouyer MOVE DSA3 to SFBR; 2941.1Sbouyer MOVE SFBR to SCRATCHB3; 2951.1Sbouyer RETURN; 2961.1Sbouyer 2971.1Sbouyerrestoredsa: 2981.1Sbouyer MOVE SCRATCHB0 TO SFBR; 2991.1Sbouyer MOVE SFBR TO DSA0; 3001.1Sbouyer MOVE SCRATCHB1 TO SFBR; 3011.1Sbouyer MOVE SFBR TO DSA1; 3021.1Sbouyer MOVE SCRATCHB2 TO SFBR; 3031.1Sbouyer MOVE SFBR TO DSA2; 3041.1Sbouyer MOVE SCRATCHB3 TO SFBR; 3051.1Sbouyer MOVE SFBR TO DSA3; 3061.1Sbouyer RETURN; 3071.1Sbouyer 3081.1Sbouyerdisconnect: 3091.1Sbouyer MOVE SCNTL2 & 0x7f TO SCNTL2; 3101.1Sbouyer CLEAR ATN; 3111.1Sbouyer CLEAR ACK; 3121.1Sbouyer WAIT DISCONNECT; 3131.1Sbouyer RETURN; 3141.1Sbouyer 3151.1Sbouyerhandle_cmpl: 3161.1Sbouyer CALL REL(disconnect); 3171.1Sbouyer MOVE SCRATCHE1 to SFBR; 3181.1Sbouyer INT int_done, IF NOT 0x00; if status is not "done", let host handle it 3191.1Sbouyer MOVE ISTAT | 0x10 TO ISTAT; else signal that cmd is done in ISTAT 3201.1Sbouyer JUMP REL(script_sched); and attempt next command 3211.1Sbouyer 3221.1Sbouyerhandle_extin: 3231.1Sbouyer CLEAR ACK; 3241.1Sbouyer MOVE FROM t_ext_msg_in, WHEN MSG_IN; 3251.1Sbouyer INT int_extmsgin; /* let host fill in t_ext_msg_data */ 3261.1Sbouyerget_extmsgdata: 3271.1Sbouyer CLEAR ACK; 3281.1Sbouyer MOVE FROM t_ext_msg_data, WHEN MSG_IN; 3291.1Sbouyer INT int_extmsgdata; 330