diff options
| author | bouyer <bouyer@NetBSD.org> | 2000-04-25 16:27:05 +0000 |
|---|---|---|
| committer | bouyer <bouyer@NetBSD.org> | 2000-04-25 16:27:05 +0000 |
| commit | 88be4752d04db3caaabd06cbe7b450a0dd2b6a1d (patch) | |
| tree | b0a30d91a0498094bd13337422b475ed087325e7 /sys/dev/microcode/siop/siop.ss | |
| parent | 151b83e2e1453854e0170f0955d8842f0e8787a6 (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.ss | 115 |
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; |
