📄 53c7xx.scr
字号:
; can go on to the next data phase block move statement.ENTRY other_outother_out:#if 0 INT 0x03ffdead#endif INT int_err_unexpected_phase, WHEN CMD JUMP msg_in_restart, WHEN MSG_IN INT int_err_unexpected_phase, WHEN MSG_OUT INT int_err_unexpected_phase, WHEN DATA_IN JUMP command_complete, WHEN STATUS JUMP other_out, WHEN NOT DATA_OUT#if (CHIP == 710); TEMP should be OK, as we got here from a call in the user dataout code.#endif RETURNENTRY other_inother_in:#if 0 INT 0x03ffdead#endif INT int_err_unexpected_phase, WHEN CMD JUMP msg_in_restart, WHEN MSG_IN INT int_err_unexpected_phase, WHEN MSG_OUT INT int_err_unexpected_phase, WHEN DATA_OUT JUMP command_complete, WHEN STATUS JUMP other_in, WHEN NOT DATA_IN#if (CHIP == 710); TEMP should be OK, as we got here from a call in the user datain code.#endif RETURNENTRY other_transferother_transfer: INT int_err_unexpected_phase, WHEN CMD CALL msg_in, WHEN MSG_IN INT int_err_unexpected_phase, WHEN MSG_OUT INT int_err_unexpected_phase, WHEN DATA_OUT INT int_err_unexpected_phase, WHEN DATA_IN JUMP command_complete, WHEN STATUS JUMP other_transfer;; msg_in_restart; msg_in; munge_msg;; PURPOSE : process messages from a target. msg_in is called when the ; caller hasn't read the first byte of the message. munge_message; is called when the caller has read the first byte of the message,; and left it in SFBR. msg_in_restart is called when the caller ; hasn't read the first byte of the message, and wishes RETURN; to transfer control back to the address of the conditional; CALL instruction rather than to the instruction after it.;; Various int_* interrupts are generated when the host system; needs to intervene, as is the case with SDTR, WDTR, and; INITIATE RECOVERY messages.;; When the host system handles one of these interrupts,; it can respond by reentering at reject_message, ; which rejects the message and returns control to; the caller of msg_in or munge_msg, accept_message; which clears ACK and returns control, or reply_message; which sends the message pointed to by the DSA ; msgout_other table indirect field.;; DISCONNECT messages are handled by moving the command; to the reconnect_dsa_queue.#if (CHIP == 710); NOTE: DSA should be valid when we get here - we cannot save both it; and TEMP in this routine.#endif;; INPUTS : DSA - SCSI COMMAND, SFBR - first byte of message (munge_msg; only);; CALLS : NO. The TEMP register isn't backed up to allow nested calls.;; MODIFIES : SCRATCH, DSA on DISCONNECT;; EXITS : On receipt of SAVE DATA POINTER, RESTORE POINTERS,; and normal return from message handlers running under; Linux, control is returned to the caller. Receipt; of DISCONNECT messages pass control to dsa_schedule.;ENTRY msg_in_restartmsg_in_restart:; XXX - hackish;; Since it's easier to debug changes to the statically ; compiled code, rather than the dynamically generated ; stuff, such as;; MOVE x, y, WHEN data_phase; CALL other_z, WHEN NOT data_phase; MOVE x, y, WHEN data_phase;; I'd like to have certain routines (notably the message handler); restart on the conditional call rather than the next instruction.;; So, subtract 8 from the return address MOVE TEMP0 + 0xf8 TO TEMP0 MOVE TEMP1 + 0xff TO TEMP1 WITH CARRY MOVE TEMP2 + 0xff TO TEMP2 WITH CARRY MOVE TEMP3 + 0xff TO TEMP3 WITH CARRYENTRY msg_inmsg_in: MOVE 1, msg_buf, WHEN MSG_INmunge_msg: JUMP munge_extended, IF 0x01 ; EXTENDED MESSAGE JUMP munge_2, IF 0x20, AND MASK 0xdf ; two byte message;; XXX - I've seen a handful of broken SCSI devices which fail to issue; a SAVE POINTERS message before disconnecting in the middle of ; a transfer, assuming that the DATA POINTER will be implicitly ; restored. ;; Historically, I've often done an implicit save when the DISCONNECT; message is processed. We may want to consider having the option of ; doing that here. ; JUMP munge_save_data_pointer, IF 0x02 ; SAVE DATA POINTER JUMP munge_restore_pointers, IF 0x03 ; RESTORE POINTERS JUMP munge_disconnect, IF 0x04 ; DISCONNECT INT int_msg_1, IF 0x07 ; MESSAGE REJECT INT int_msg_1, IF 0x0f ; INITIATE RECOVERY#ifdef EVENTS INT int_EVENT_SELECT_FAILED #endif JUMP reject_messagemunge_2: JUMP reject_message;; The SCSI standard allows targets to recover from transient ; error conditions by backing up the data pointer with a ; RESTORE POINTERS message. ; ; So, we must save and restore the _residual_ code as well as ; the current instruction pointer. Because of this messiness,; it is simpler to put dynamic code in the dsa for this and to; just do a simple jump down there. ;munge_save_data_pointer:#if (CHIP == 710) ; We have something in TEMP here, so first we must save that MOVE TEMP0 TO SFBR MOVE SFBR TO SCRATCH0 MOVE TEMP1 TO SFBR MOVE SFBR TO SCRATCH1 MOVE TEMP2 TO SFBR MOVE SFBR TO SCRATCH2 MOVE TEMP3 TO SFBR MOVE SFBR TO SCRATCH3 MOVE MEMORY 4, addr_scratch, jump_temp + 4 ; Now restore DSA MOVE MEMORY 4, saved_dsa, addr_dsa#endif MOVE DSA0 + dsa_save_data_pointer TO SFBR MOVE SFBR TO SCRATCH0 MOVE DSA1 + 0xff TO SFBR WITH CARRY MOVE SFBR TO SCRATCH1 MOVE DSA2 + 0xff TO SFBR WITH CARRY MOVE SFBR TO SCRATCH2 MOVE DSA3 + 0xff TO SFBR WITH CARRY MOVE SFBR TO SCRATCH3 DMODE_NCR_TO_MEMORY MOVE MEMORY 4, addr_scratch, jump_dsa_save + 4 DMODE_MEMORY_TO_MEMORYjump_dsa_save: JUMP 0munge_restore_pointers:#if (CHIP == 710) ; The code at dsa_restore_pointers will RETURN, but we don't care ; about TEMP here, as it will overwrite it anyway.#endif MOVE DSA0 + dsa_restore_pointers TO SFBR MOVE SFBR TO SCRATCH0 MOVE DSA1 + 0xff TO SFBR WITH CARRY MOVE SFBR TO SCRATCH1 MOVE DSA2 + 0xff TO SFBR WITH CARRY MOVE SFBR TO SCRATCH2 MOVE DSA3 + 0xff TO SFBR WITH CARRY MOVE SFBR TO SCRATCH3 DMODE_NCR_TO_MEMORY MOVE MEMORY 4, addr_scratch, jump_dsa_restore + 4 DMODE_MEMORY_TO_MEMORYjump_dsa_restore: JUMP 0munge_disconnect:#ifdef DEBUG INT int_debug_disconnect_msg#endif/* * Before, we overlapped processing with waiting for disconnect, but * debugging was beginning to appear messy. Temporarily move things * to just before the WAIT DISCONNECT. */ #ifdef ORIGINAL#if (CHIP == 710); Following clears Unexpected Disconnect bit. What do we do?#else MOVE SCNTL2 & 0x7f TO SCNTL2#endif CLEAR ACK#endif#if (CHIP != 700) && (CHIP != 70066) JUMP dsa_schedule#else WAIT DISCONNECT INT int_norm_disconnected#endifmunge_extended: CLEAR ACK INT int_err_unexpected_phase, WHEN NOT MSG_IN MOVE 1, msg_buf + 1, WHEN MSG_IN JUMP munge_extended_2, IF 0x02 JUMP munge_extended_3, IF 0x03 JUMP reject_messagemunge_extended_2: CLEAR ACK MOVE 1, msg_buf + 2, WHEN MSG_IN JUMP reject_message, IF NOT 0x02 ; Must be WDTR CLEAR ACK MOVE 1, msg_buf + 3, WHEN MSG_IN INT int_msg_wdtrmunge_extended_3: CLEAR ACK MOVE 1, msg_buf + 2, WHEN MSG_IN JUMP reject_message, IF NOT 0x01 ; Must be SDTR CLEAR ACK MOVE 2, msg_buf + 3, WHEN MSG_IN INT int_msg_sdtrENTRY reject_messagereject_message: SET ATN CLEAR ACK MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT RETURNENTRY accept_messageaccept_message: CLEAR ATN CLEAR ACK RETURNENTRY respond_messagerespond_message: SET ATN CLEAR ACK MOVE FROM dsa_msgout_other, WHEN MSG_OUT RETURN;; command_complete;; PURPOSE : handle command termination when STATUS IN is detected by reading; a status byte followed by a command termination message. ;; Normal termination results in an INTFLY instruction, and ; the host system can pick out which command terminated by ; examining the MESSAGE and STATUS buffers of all currently ; executing commands;;; Abnormal (CHECK_CONDITION) termination results in an; int_err_check_condition interrupt so that a REQUEST SENSE; command can be issued out-of-order so that no other command; clears the contingent allegiance condition.; ;; INPUTS : DSA - command ;; CALLS : OK;; EXITS : On successful termination, control is passed to schedule.; On abnormal termination, the user will usually modify the ; DSA fields and corresponding buffers and return control; to select.;ENTRY command_completecommand_complete: MOVE FROM dsa_status, WHEN STATUS#if (CHIP != 700) && (CHIP != 70066) MOVE SFBR TO SCRATCH0 ; Save status#endif /* (CHIP != 700) && (CHIP != 70066) */ENTRY command_complete_msgincommand_complete_msgin: MOVE FROM dsa_msgin, WHEN MSG_IN; Indicate that we should be expecting a disconnect#if (CHIP != 710) MOVE SCNTL2 & 0x7f TO SCNTL2#else ; Above code cleared the Unexpected Disconnect bit, what do we do?#endif CLEAR ACK#if (CHIP != 700) && (CHIP != 70066) WAIT DISCONNECT;; The SCSI specification states that when a UNIT ATTENTION condition; is pending, as indicated by a CHECK CONDITION status message,; the target shall revert to asynchronous transfers. Since; synchronous transfers parameters are maintained on a per INITIATOR/TARGET ; basis, and returning control to our scheduler could work on a command; running on another lun on that target using the old parameters, we must; interrupt the host processor to get them changed, or change them ourselves.;; Once SCSI-II tagged queueing is implemented, things will be even more; hairy, since contingent allegiance conditions exist on a per-target/lun; basis, and issuing a new command with a different tag would clear it.; In these cases, we must interrupt the host processor to get a request ; added to the HEAD of the queue with the request sense command, or we; must automatically issue the request sense command.#if 0 MOVE SCRATCH0 TO SFBR JUMP command_failed, IF 0x02#endif#if (CHIP == 710)#if defined(MVME16x_INTFLY); For MVME16x (ie CHIP=710) we will force an INTFLY by triggering a software; interupt (SW7). We can use SCRATCH, as we are about to jump to; schedule, which corrupts it anyway. Will probably remove this later,; but want to check performance effects first.#define INTFLY_ADDR 0xfff40070 MOVE 0 TO SCRATCH0 MOVE 0x80 TO SCRATCH1 MOVE 0 TO SCRATCH2 MOVE 0 TO SCRATCH3 MOVE MEMORY 4, addr_scratch, INTFLY_ADDR#else INT int_norm_emulateintfly#endif#else INTFLY#endif#endif /* (CHIP != 700) && (CHIP != 70066) */#if (CHIP == 710) ; Time to correct DSA following memory move MOVE MEMORY 4, saved_dsa, addr_dsa#endif#ifdef EVENTS INT int_EVENT_COMPLETE#endif#if (CHIP != 700) && (CHIP != 70066) JUMP schedulecommand_failed: INT int_err_check_condition#else INT int_norm_command_complete#endif;; wait_reselect;; PURPOSE : This is essentially the idle routine, where control lands; when there are no new processes to schedule. wait_reselect; waits for reselection, selection, and new commands.;; When a successful reselection occurs, with the aid ; of fixed up code in each DSA, wait_reselect walks the ; reconnect_dsa_queue, asking each dsa if the target ID; and LUN match its.;; If a match is found, a call is made back to reselected_ok,; which through the miracles of self modifying code, extracts; the found DSA from the reconnect_dsa_queue and then ; returns control to the DSAs thread of execution.;; INPUTS : NONE;; CALLS : OK;; MODIFIES : DSA,;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -