summaryrefslogtreecommitdiff
path: root/sys/dev/microcode/siop
diff options
context:
space:
mode:
authorbouyer <bouyer@NetBSD.org>2000-10-18 17:01:13 +0000
committerbouyer <bouyer@NetBSD.org>2000-10-18 17:01:13 +0000
commit75246b83c08dceeb3b9ccfaf0a1e1b387a8a8297 (patch)
tree8922e34811d8cc863e7a98e49249e36f300e4e80 /sys/dev/microcode/siop
parent9836ff3913f1e1a70e85fe38ad8ed9819bc24c41 (diff)
Redo the target/lun sw in a better way, and handle queue tag messages.
Diffstat (limited to 'sys/dev/microcode/siop')
-rw-r--r--sys/dev/microcode/siop/siop.ss207
1 files changed, 138 insertions, 69 deletions
diff --git a/sys/dev/microcode/siop/siop.ss b/sys/dev/microcode/siop/siop.ss
index 2eae8d512ba..abf21060d21 100644
--- a/sys/dev/microcode/siop/siop.ss
+++ b/sys/dev/microcode/siop/siop.ss
@@ -1,4 +1,4 @@
-; $NetBSD: siop.ss,v 1.9 2000/10/06 16:39:04 bouyer Exp $
+; $NetBSD: siop.ss,v 1.10 2000/10/18 17:01:13 bouyer Exp $
;
; Copyright (c) 2000 Manuel Bouyer.
@@ -42,14 +42,17 @@ ABSOLUTE t_status = 80;
ABSOLUTE t_data = 88;
;; interrupt codes
+; interrupts that need a valid DSA
ABSOLUTE int_done = 0xff00;
ABSOLUTE int_msgin = 0xff01;
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_disc = 0xff04;
+; interrupts that don't have a valid DSA
+ABSOLUTE int_reseltarg = 0xff80;
+ABSOLUTE int_resellun = 0xff81;
+ABSOLUTE int_reseltag = 0xff82;
+ABSOLUTE int_resfail = 0xff83;
ABSOLUTE int_err = 0xffff;
; flags for scratcha0
@@ -57,10 +60,13 @@ ABSOLUTE flag_sdp = 0x01 ; got save data pointer
ABSOLUTE flag_data = 0x02 ; we're in data phase
ABSOLUTE flag_data_mask = 0xfd ; ~flag_data
+; main script symbols
+
ENTRY waitphase;
ENTRY send_msgout;
ENTRY msgout;
ENTRY msgin;
+ENTRY handle_msgin;
ENTRY msgin_ack;
ENTRY dataout;
ENTRY datain;
@@ -68,44 +74,55 @@ ENTRY cmdout;
ENTRY status;
ENTRY disconnect;
ENTRY reselect;
+ENTRY reselected;
ENTRY selected;
+ENTRY script_sched;
ENTRY get_extmsgdata;
+ENTRY resel_targ0;
+ENTRY msgin_space;
+ENTRY lunsw_return;
+EXTERN abs_targ0;
+EXTERN abs_msgin;
+
+; lun switch symbols
+ENTRY resel_lun0;
+ENTRY restore_scntl3;
+EXTERN abs_lun0;
+EXTERN abs_lunsw_return;
+
+; command reselect script symbols
+ENTRY rdsa0;
+ENTRY rdsa1;
+ENTRY rdsa2;
+ENTRY rdsa3;
+ENTRY reload_dsa;
+
+EXTERN resel_abs_reselected;
+
+; command scheduler symbols
ENTRY slot;
-ENTRY idsa0;
-ENTRY idsa1;
-ENTRY idsa2;
-ENTRY idsa3;
ENTRY slotdata;
ENTRY nextslot;
-ENTRY endslot;
EXTERN script_abs_sched;
EXTERN slot_nextp;
EXTERN slot_sched_addrsrc;
EXTERN slot_abs_reselect;
EXTERN slot_abs_selected;
+EXTERN slot_abs_loaddsa;
EXTERN endslot_abs_reselect;
-EXTERN abs_find_dsa;
-ENTRY rtarget;
-ENTRY rlun;
-ENTRY rdsa0;
-ENTRY rdsa1;
-ENTRY rdsa2;
-ENTRY rdsa3;
-ENTRY rsxfer;
-ENTRY rscntl3;
-ENTRY res_nextld;
-EXTERN resel_abs_selected;
+; main script
PROC siop_script:
-selected:
+reselected:
; starting a new session, init 'local variables'
MOVE 0 to SCRATCHA0 ; flags
MOVE 0 to SCRATCHA1 ; DSA offset (for S/G save data pointer)
- CLEAR ACK;
+ MOVE SCRATCHA3 to SFBR ; pending message ?
+ JUMP REL(handle_msgin), IF not 0x08;
waitphase:
JUMP REL(msgout), WHEN MSG_OUT;
JUMP REL(msgin), WHEN MSG_IN;
@@ -117,28 +134,81 @@ err:
INT int_err;
reselect:
+ ; Clear DSA and init status
+ MOVE 0xff to DSA0;
+ MOVE 0xff to DSA1;
+ MOVE 0xff to DSA2;
+ MOVE 0xff to DSA3;
+ MOVE 0xff to SCRATCHA2; no tag
+ MOVE 0x08 to SCRATCHA3; NOP message
WAIT RESELECT REL(reselect_fail)
MOVE SSID & 0x8f to SFBR
MOVE SFBR to SCRATCHA0 ; save reselect ID
+; find the rigth param for this target
+resel_targ0:
+ JUMP abs_targ0, IF 0xff;
+ JUMP abs_targ0, IF 0xff;
+ JUMP abs_targ0, IF 0xff;
+ JUMP abs_targ0, IF 0xff;
+ JUMP abs_targ0, IF 0xff;
+ JUMP abs_targ0, IF 0xff;
+ JUMP abs_targ0, IF 0xff;
+ JUMP abs_targ0, IF 0xff;
+ JUMP abs_targ0, IF 0xff;
+ JUMP abs_targ0, IF 0xff;
+ JUMP abs_targ0, IF 0xff;
+ JUMP abs_targ0, IF 0xff;
+ JUMP abs_targ0, IF 0xff;
+ JUMP abs_targ0, IF 0xff;
+ JUMP abs_targ0, IF 0xff;
+ INT int_reseltarg;
+lunsw_return:
INT int_err, WHEN NOT MSG_IN;
- MOVE FROM t_msg_in, WHEN MSG_IN;
- MOVE SFBR & 0x07 to SCRATCHA2; save LUN
- JUMP abs_find_dsa;
+ MOVE 1, abs_msgin, WHEN MSG_IN;
+ MOVE SFBR & 0x07 to SCRATCHA1; save LUN
+ CLEAR ACK;
+ RETURN, WHEN NOT MSG_IN; If no more message, jump to lun sw
+ MOVE 1, abs_msgin, WHEN MSG_IN;
+ CLEAR ACK;
+ JUMP REL(gettag), IF 0x20; simple tag message ?
+ MOVE SFBR to SCRATCHA3; save message
+ RETURN; jump to lun sw and handle message
+gettag:
+ INT int_err, WHEN NOT MSG_IN;
+ MOVE 1, abs_msgin, WHEN MSG_IN; get tag
+ CLEAR ACK;
+ MOVE SFBR to SCRATCHA2; save tag
+ RETURN; jump to lun sw
+
reselect_fail:
; check that host asserted SIGP, this'll clear SIGP in ISTAT
MOVE CTEST2 & 0x40 TO SFBR;
INT int_resfail, IF 0x00;
+script_sched:
+ ; Clear DSA and init status
+ MOVE 0xff to DSA0;
+ MOVE 0xff to DSA1;
+ MOVE 0xff to DSA2;
+ MOVE 0xff to DSA3;
+ MOVE 0 to SCRATCHA0 ; flags
+ MOVE 0 to SCRATCHA1 ; DSA offset (for S/G save data pointer)
JUMP script_abs_sched;
+handle_sdp:
+ CLEAR ACK;
+ MOVE SCRATCHA0 | flag_sdp TO SCRATCHA0;
+ ; should get a disconnect message now
msgin:
CLEAR ATN
MOVE FROM t_msg_in, WHEN MSG_IN;
+handle_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:
+selected:
CLEAR ACK;
JUMP REL(waitphase);
@@ -219,19 +289,15 @@ 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 script_abs_sched, if 0x00;
+ JUMP REL(script_sched), if 0x00;
MOVE SCRATCHA1 TO SFBR;
- JUMP script_abs_sched, if 0x00;
+ JUMP REL(script_sched), if 0x00;
; Ok, we need to save data pointers
INT int_disc;
handle_cmpl:
CALL REL(disconnect);
INT int_done;
-handle_sdp:
- CLEAR ACK;
- MOVE SCRATCHA0 | flag_sdp TO SCRATCHA0;
- JUMP REL(msgin) ; should get a disconnect message now
handle_extin:
CLEAR ACK;
@@ -243,6 +309,9 @@ get_extmsgdata:
INT int_err, IF NOT MSG_IN;
MOVE FROM t_ext_msg_data, WHEN MSG_IN;
INT int_extmsgdata;
+msgin_space:
+ NOP; space to store msgin when reselect
+
; script used for the scheduler: when a slot is free the JUMP points to
; the next slot so that instructions for this slot are not run.
@@ -256,52 +325,52 @@ get_extmsgdata:
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;
+ CALL slot_abs_loaddsa;
SELECT ATN FROM t_id, slot_abs_reselect;
MOVE MEMORY 4, slot_sched_addrsrc, slot_nextp;
JUMP slot_abs_selected;
slotdata:
- NOP; slot variables: dsa & jumppatchp
-nextslot: NOP; /* will be changed to the next slot entry
+ NOP; slot variables: jumppatchp
+nextslot:
+ NOP; /* will be changed to the next slot entry
PROC endslot_script:
JUMP endslot_abs_reselect;
-;; script used to find the DSA after a reselect.
-;; each slot contain a target/lun identifier (when free target = 0xff, so it's
-;; ignored) used to load the appropriate DSA for this reselect
-
-PROC reselected_script:
- MOVE SCRATCHA0 to SFBR; load ID
-rtarget:
- JUMP REL(res_nextid), IF NOT 0xff;
- MOVE SCRATCHA2 to SFBR; load LUN
-rlun:
- JUMP REL(res_nextld), IF NOT 0xff;
+;; per-target switch script for LUNs
+; hack: we first to a call to the target-specific code, so that a return
+; in the main switch will jump to the lun switch.
+PROC lun_switch:
+ CALL REL(restore_scntl3);
+ MOVE SCRATCHA1 TO SFBR;
+resel_lun0:
+ JUMP abs_lun0, IF 0x00;
+ JUMP abs_lun0, IF 0x01;
+ JUMP abs_lun0, IF 0x02;
+ JUMP abs_lun0, IF 0x03;
+ JUMP abs_lun0, IF 0x04;
+ JUMP abs_lun0, IF 0x05;
+ JUMP abs_lun0, IF 0x06;
+ JUMP abs_lun0, IF 0x07;
+ INT int_resellun;
+restore_scntl3:
+ MOVE 0xff TO SCNTL3;
+ MOVE 0xff TO SXFER;
+ JUMP abs_lunsw_return;
+
+;; script used to load the DSA after a reselect.
+
+PROC load_dsa:
+; Can't use MOVE MEMORY to load DSA, doesn't work I/O mapped
rdsa0:
- MOVE 0x00 to dsa0;
+ MOVE 0xf0 to DSA0;
rdsa1:
- MOVE 0x01 to dsa1;
+ MOVE 0xf1 to DSA1;
rdsa2:
- MOVE 0x02 to dsa2;
+ MOVE 0xf2 to DSA2;
rdsa3:
- MOVE 0x03 to dsa3;
-; the select is here to reload sxfer and scntl3 from the table. As we're
-; already reselected is always fais, and always jumps to the main script.
- SELECT FROM t_id, resel_abs_selected;
-
-res_nextld:
- NOP ; MOVE SCRATCHA0 to SFBR
-res_nextid:
- NOP ; JUMP REL(res_nextid), IF NOT 0xff
-
-PROC reselected_end_script:
- INT int_resel;
- INT int_resel; /* need two because res_nextld and res_nextid */
+ MOVE 0xf3 to DSA3;
+ RETURN;
+reload_dsa:
+ CALL REL(rdsa0);
+ JUMP resel_abs_reselected;