⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 53c7,8xx.scr

📁 基于组件方式开发操作系统的OSKIT源代码
💻 SCR
📖 第 1 页 / 共 3 页
字号:
    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    MOVE SCNTL2 & 0x7f TO SCNTL2    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    INTFLY#endif /* (CHIP != 700) && (CHIP != 70066) */#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,;; EXITS : On successful reselection, control is returned to the ;	DSA which called reselected_ok.  If the WAIT RESELECT;	was interrupted by a new commands arrival signaled by ;	SIG_P, control is passed to schedule.  If the NCR is ;	selected, the host system is interrupted with an ;	int_err_selected which is usually responded to by;	setting DSP to the target_abort address.ENTRY wait_reselectwait_reselect:#ifdef EVENTS    int int_EVENT_IDLE#endif#if 0    int int_debug_idle#endif    WAIT RESELECT wait_reselect_failedreselected:#ifdef EVENTS    int int_EVENT_RESELECT#endif    CLEAR TARGET    MOVE dmode_memory_to_memory TO DMODE    ; Read all data needed to reestablish the nexus -     MOVE 1, reselected_identify, WHEN MSG_IN    ; We used to CLEAR ACK here.#if (CHIP != 700) && (CHIP != 70066)#if 0    int int_debug_reselected#endif    ; Point DSA at the current head of the disconnected queue.    MOVE dmode_memory_to_ncr  TO DMODE    MOVE MEMORY 4, reconnect_dsa_head, addr_scratch    MOVE dmode_memory_to_memory TO DMODE    CALL scratch_to_dsa    ; Fix the update-next pointer so that the reconnect_dsa_head    ; pointer is the one that will be updated if this DSA is a hit     ; and we remove it from the queue.    MOVE MEMORY 4, addr_reconnect_dsa_head, reselected_ok + 8ENTRY reselected_check_nextreselected_check_next:#if 0    INT int_debug_reselect_check#endif    ; Check for a NULL pointer.    MOVE DSA0 TO SFBR    JUMP reselected_not_end, IF NOT 0    MOVE DSA1 TO SFBR    JUMP reselected_not_end, IF NOT 0    MOVE DSA2 TO SFBR    JUMP reselected_not_end, IF NOT 0    MOVE DSA3 TO SFBR    JUMP reselected_not_end, IF NOT 0    INT int_err_unexpected_reselectreselected_not_end:    ;    ; XXX the ALU is only eight bits wide, and the assembler    ; wont do the dirt work for us.  As long as dsa_check_reselect    ; is negative, we need to sign extend with 1 bits to the full    ; 32 bit width of the address.    ;    ; A potential work around would be to have a known alignment     ; of the DSA structure such that the base address plus     ; dsa_check_reselect doesn't require carrying from bytes     ; higher than the LSB.    ;    MOVE DSA0 TO SFBR    MOVE SFBR + dsa_check_reselect TO SCRATCH0    MOVE DSA1 TO SFBR    MOVE SFBR + 0xff TO SCRATCH1 WITH CARRY    MOVE DSA2 TO SFBR    MOVE SFBR + 0xff TO SCRATCH2 WITH CARRY    MOVE DSA3 TO SFBR    MOVE SFBR + 0xff TO SCRATCH3 WITH CARRY    MOVE dmode_ncr_to_memory TO DMODE    MOVE MEMORY 4, addr_scratch, reselected_check + 4    MOVE dmode_memory_to_memory TO DMODEreselected_check:    JUMP 0;;ENTRY reselected_okreselected_ok:    MOVE MEMORY 4, 0, 0				; Patched : first word						; 	is address of 						;       successful dsa_next						; Second word is last 						;	unsuccessful dsa_next,						;	starting with 						;       dsa_reconnect_head    ; We used to CLEAR ACK here.#if 0    INT int_debug_reselected_ok#endif#ifdef DEBUG    INT int_debug_check_dsa#endif    RETURN					; Return control to where#else    INT int_norm_reselected#endif /* (CHIP != 700) && (CHIP != 70066) */selected:    INT int_err_selected;;; A select or reselect failure can be caused by one of two conditions : ; 1.  SIG_P was set.  This will be the case if the user has written;	a new value to a previously NULL head of the issue queue.;; 2.  The NCR53c810 was selected or reselected by another device.;; 3.  The bus was already busy since we were selected or reselected;	before starting the command.wait_reselect_failed:#ifdef EVENTS 	INT int_EVENT_RESELECT_FAILED#endif; Check selected bit.      MOVE SIST0 & 0x20 TO SFBR    JUMP selected, IF 0x20; Reading CTEST2 clears the SIG_P bit in the ISTAT register.    MOVE CTEST2 & 0x40 TO SFBR	    JUMP schedule, IF 0x40; Check connected bit.  ; FIXME: this needs to change if we support target mode    MOVE ISTAT & 0x08 TO SFBR    JUMP reselected, IF 0x08; FIXME : Something bogus happened, and we shouldn't fail silently.#if 0    JUMP schedule#else    INT int_debug_panic#endifselect_failed:#ifdef EVENTS  int int_EVENT_SELECT_FAILED#endif; Otherwise, mask the selected and reselected bits off SIST0    MOVE SIST0 & 0x30 TO SFBR    JUMP selected, IF 0x20    JUMP reselected, IF 0x10 ; If SIGP is set, the user just gave us another command, and; we should restart or return to the scheduler.; Reading CTEST2 clears the SIG_P bit in the ISTAT register.    MOVE CTEST2 & 0x40 TO SFBR	    JUMP select, IF 0x40; Check connected bit.  ; FIXME: this needs to change if we support target mode; FIXME: is this really necessary?     MOVE ISTAT & 0x08 TO SFBR    JUMP reselected, IF 0x08; FIXME : Something bogus happened, and we shouldn't fail silently.#if 0    JUMP schedule#else    INT int_debug_panic#endif;; test_1; test_2;; PURPOSE : run some verification tests on the NCR.  test_1;	copies test_src to test_dest and interrupts the host;	processor, testing for cache coherency and interrupt; 	problems in the processes.;;	test_2 runs a command with offsets relative to the ;	DSA on entry, and is useful for miscellaneous experimentation.;; Verify that interrupts are working correctly and that we don't ; have a cache invalidation problem.ABSOLUTE test_src = 0, test_dest = 0ENTRY test_1test_1:    MOVE MEMORY 4, test_src, test_dest    INT int_test_1;; Run arbitrary commands, with test code establishing a DSA; ENTRY test_2test_2:    CLEAR TARGET    SELECT ATN FROM 0, test_2_fail    JUMP test_2_msgout, WHEN MSG_OUTENTRY test_2_msgouttest_2_msgout:    MOVE FROM 8, WHEN MSG_OUT    MOVE FROM 16, WHEN CMD     MOVE FROM 24, WHEN DATA_IN    MOVE FROM 32, WHEN STATUS    MOVE FROM 40, WHEN MSG_IN    MOVE SCNTL2 & 0x7f TO SCNTL2    CLEAR ACK    WAIT DISCONNECTtest_2_fail:    INT int_test_2ENTRY debug_breakdebug_break:    INT int_debug_break;; initiator_abort; target_abort;; PURPOSE : Abort the currently established nexus from with initiator;	or target mode.;;  ENTRY target_aborttarget_abort:    SET TARGET    DISCONNECT    CLEAR TARGET    JUMP schedule    ENTRY initiator_abortinitiator_abort:    SET ATN;; The SCSI-I specification says that targets may go into MSG out at ; their leisure upon receipt of the ATN single.  On all versions of the ; specification, we can't change phases until REQ transitions true->false, ; so we need to sink/source one byte of data to allow the transition.;; For the sake of safety, we'll only source one byte of data in all ; cases, but to accommodate the SCSI-I dain bramage, we'll sink an  ; arbitrary number of bytes.    JUMP spew_cmd, WHEN CMD    JUMP eat_msgin, WHEN MSG_IN    JUMP eat_datain, WHEN DATA_IN    JUMP eat_status, WHEN STATUS    JUMP spew_dataout, WHEN DATA_OUT    JUMP satedspew_cmd:    MOVE 1, NCR53c7xx_zero, WHEN CMD    JUMP satedeat_msgin:    MOVE 1, NCR53c7xx_sink, WHEN MSG_IN    JUMP eat_msgin, WHEN MSG_IN    JUMP satedeat_status:    MOVE 1, NCR53c7xx_sink, WHEN STATUS    JUMP eat_status, WHEN STATUS    JUMP satedeat_datain:    MOVE 1, NCR53c7xx_sink, WHEN DATA_IN    JUMP eat_datain, WHEN DATA_IN    JUMP satedspew_dataout:    MOVE 1, NCR53c7xx_zero, WHEN DATA_OUTsated:    MOVE SCNTL2 & 0x7f TO SCNTL2    MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT    WAIT DISCONNECT    INT int_norm_aborted;; dsa_to_scratch; scratch_to_dsa;; PURPOSE :; 	The NCR chips cannot do a move memory instruction with the DSA register ; 	as the source or destination.  So, we provide a couple of subroutines; 	that let us switch between the DSA register and scratch register.;; 	Memory moves to/from the DSPS  register also don't work, but we ; 	don't use them.;; dsa_to_scratch:    MOVE DSA0 TO SFBR    MOVE SFBR TO SCRATCH0    MOVE DSA1 TO SFBR    MOVE SFBR TO SCRATCH1    MOVE DSA2 TO SFBR    MOVE SFBR TO SCRATCH2    MOVE DSA3 TO SFBR    MOVE SFBR TO SCRATCH3    RETURNscratch_to_dsa:    MOVE SCRATCH0 TO SFBR    MOVE SFBR TO DSA0    MOVE SCRATCH1 TO SFBR    MOVE SFBR TO DSA1    MOVE SCRATCH2 TO SFBR    MOVE SFBR TO DSA2    MOVE SCRATCH3 TO SFBR    MOVE SFBR TO DSA3    RETURN    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -