summaryrefslogtreecommitdiff
path: root/sys/dev/microcode/siop/siop.ss
diff options
context:
space:
mode:
authorbouyer <bouyer@NetBSD.org>2000-04-25 16:27:05 +0000
committerbouyer <bouyer@NetBSD.org>2000-04-25 16:27:05 +0000
commit88be4752d04db3caaabd06cbe7b450a0dd2b6a1d (patch)
treeb0a30d91a0498094bd13337422b475ed087325e7 /sys/dev/microcode/siop/siop.ss
parent151b83e2e1453854e0170f0955d8842f0e8787a6 (diff)
- Change the script to start new commands in an asyncronous way, using
'command slots' in which the host can put command and wait for the script to start them - Change siop.c to do full disconnect/reslelect, allowing as much as one command per target/lun to run in parallel. - Fix bug in registers init where a board without BIOS would end at ID 0 (now the driver works on alpha too). - better handling of messages, sending back a MSG_EXT_SDTR in response to an incoming MSG_EXT_SDTR, and MSG_MESSAGE_REJECT for unhandled messages. - fix use of bus_dmamap_sync() and htole32(). - supports shared interrups - change some int8 and int16 to int, for alpha and mips benefits ( suggested by Toru Nishimura)
Diffstat (limited to 'sys/dev/microcode/siop/siop.ss')
-rw-r--r--sys/dev/microcode/siop/siop.ss115
1 files changed, 96 insertions, 19 deletions
diff --git a/sys/dev/microcode/siop/siop.ss b/sys/dev/microcode/siop/siop.ss
index e7e6b61220f..77b9a29318a 100644
--- a/sys/dev/microcode/siop/siop.ss
+++ b/sys/dev/microcode/siop/siop.ss
@@ -1,42 +1,63 @@
ARCH 720
-; offsets of sym_xfer
-ABSOLUTE t_id = 4;
-ABSOLUTE t_msg_in = 12;
-ABSOLUTE t_msg_out = 20;
-ABSOLUTE t_cmd = 28;
-ABSOLUTE t_status = 36;
-ABSOLUTE t_data = 44;
+; offsets in sym_xfer
+ABSOLUTE t_id = 20;
+ABSOLUTE t_msg_in = 28;
+ABSOLUTE t_ext_msg_in = 36;
+ABSOLUTE t_ext_msg_data = 44;
+ABSOLUTE t_ext_msg_tag = 52;
+ABSOLUTE t_msg_out = 60;
+ABSOLUTE t_cmd = 68;
+ABSOLUTE t_status = 76;
+ABSOLUTE t_data = 84;
;; interrupt codes
ABSOLUTE int_done = 0xff00;
ABSOLUTE int_msgin = 0xff01;
-ABSOLUTE int_resel = 0xff02;
-ABSOLUTE int_resfail = 0xff03;
-ABSOLUTE int_disc = 0xff04;
+ABSOLUTE int_extmsgin = 0xff02;
+ABSOLUTE int_extmsgdata = 0xff03;
+ABSOLUTE int_resel = 0xff04;
+ABSOLUTE int_reseltag = 0xff05;
+ABSOLUTE int_resfail = 0xff06;
+ABSOLUTE int_disc = 0xff07;
ABSOLUTE int_err = 0xffff;
; flags for scratcha0
ABSOLUTE flag_sdp = 0x01 ; got save data pointer
ENTRY waitphase;
-ENTRY select;
+ENTRY send_msgout;
ENTRY msgout;
ENTRY msgin;
+ENTRY msgin_ack;
ENTRY dataout;
ENTRY datain;
ENTRY cmdout;
ENTRY status;
ENTRY disconnect;
ENTRY reselect;
-ENTRY reselected;
-ENTRY handle_reselect;
+ENTRY selected;
+ENTRY get_extmsgdata;
+ENTRY sheduler;
+ENTRY slot;
+ENTRY idsa0;
+ENTRY idsa1;
+ENTRY idsa2;
+ENTRY idsa3;
+ENTRY slotdata;
+ENTRY nextslot;
+ENTRY endslot;
+
+EXTERN slot_nextp;
+EXTERN slot_shed_addrsrc;
+EXTERN slot_abs_reselect;
+EXTERN slot_abs_selected;
+
+EXTERN endslot_abs_reselect;
PROC siop_script:
-select:
- SELECT ATN FROM t_id, REL(reselect);
-reselected:
+selected:
; starting a new session, init 'local variables'
MOVE 0 to SCRATCHA0 ; flags
MOVE 0 to SCRATCHA1 ; DSA offset (for S/G save data pointer)
@@ -60,7 +81,10 @@ reselect:
INT int_resel;
reselect_fail:
- INT int_resfail;
+ ; check that host asserted SIGP, this'll clear SIGP in ISTAT
+ MOVE CTEST2 & 0x40 TO SFBR;
+ INT int_resfail, IF 0x00;
+ JUMP REL(sheduler);
msgin:
CLEAR ATN
@@ -68,7 +92,16 @@ msgin:
JUMP REL(handle_dis), IF 0x04 ; disconnect message
JUMP REL(handle_cmpl), IF 0x00 ; command complete message
JUMP REL(handle_sdp), IF 0x02 ; save data pointer message
+ JUMP REL(handle_extin), IF 0x01 ; extended message
INT int_msgin;
+msgin_ack:
+ CLEAR ACK;
+ JUMP REL(waitphase);
+
+; entry point for msgout after a msgin or status phase
+send_msgout:
+ SET ATN;
+ CLEAR ACK;
msgout:
MOVE FROM t_msg_out, WHEN MSG_OUT;
CLEAR ATN;
@@ -138,9 +171,9 @@ handle_dis:
CALL REL(disconnect);
; if we didn't get sdp, or if offset is 0, no need to interrupt
MOVE SCRATCHA0 & flag_sdp TO SFBR;
- JUMP REL(reselect), if 0x00;
+ JUMP REL(sheduler), if 0x00;
MOVE SCRATCHA1 TO SFBR;
- JUMP REL(reselect), if 0x00;
+ JUMP REL(sheduler), if 0x00;
; Ok, we need to save data pointers
INT int_disc;
@@ -151,3 +184,47 @@ handle_sdp:
CLEAR ACK;
MOVE SCRATCHA0 | flag_sdp TO SCRATCHA0;
JUMP REL(msgin) ; should get a disconnect message now
+
+handle_extin:
+ CLEAR ACK;
+ INT int_err, IF NOT MSG_IN;
+ MOVE FROM t_ext_msg_in, WHEN MSG_IN;
+ INT int_extmsgin; /* let host fill in t_ext_msg_data */
+get_extmsgdata:
+ CLEAR ACK;
+ INT int_err, IF NOT MSG_IN;
+ MOVE FROM t_ext_msg_data, WHEN MSG_IN;
+ INT int_extmsgdata;
+
+sheduler:
+ NOP; /* will be changed by the slot scripts */
+
+; script used for the sheduler: when a slot is free the JUMP points to
+; the next slot so that instructions for this slot are not run.
+; once the CPU has set up the slot variables (DSA address) it changes
+; the JUMP address to 0 (so that it'll jump to the next instruction) and
+; this command will be processed next time the sheduler is executed.
+; When the target has been successfully selected the script changes the jump
+; addr back to the next slot, so that it's ignored the next time.
+;
+
+PROC slot_script:
+slot:
+ JUMP REL(nextslot);
+idsa0:
+ MOVE 0x00 to dsa0;
+idsa1:
+ MOVE 0x01 to dsa1;
+idsa2:
+ MOVE 0x02 to dsa2;
+idsa3:
+ MOVE 0x03 to dsa3;
+ SELECT ATN FROM t_id, slot_abs_reselect;
+ MOVE MEMORY 4, slot_shed_addrsrc, slot_nextp;
+ JUMP slot_abs_selected;
+slotdata:
+ NOP; slot variables: dsa & jumppatchp
+nextslot: NOP; /* will be changed to the next slot entry
+
+PROC endslot_script:
+ JUMP endslot_abs_reselect;