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

📄 53c7,8xx.scr

📁 基于组件方式开发操作系统的OSKIT源代码
💻 SCR
📖 第 1 页 / 共 3 页
字号:
#undef DEBUG#undef EVENTS; NCR 53c810 driver, main script; Sponsored by ;	iX Multiuser Multitasking Magazine;	hm@ix.de;; Copyright 1993, 1994, 1995 Drew Eckhardt;      Visionary Computing ;      (Unix and Linux consulting and custom programming);      drew@PoohSticks.ORG;      +1 (303) 786-7975;; TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.;; PRE-ALPHA;; For more information, please consult ;; NCR 53C810; PCI-SCSI I/O Processor; Data Manual;; NCR 53C710 ; SCSI I/O Processor; Programmers Guide;; NCR Microelectronics; 1635 Aeroplaza Drive; Colorado Springs, CO 80916; 1+ (719) 578-3400;; Toll free literature number; +1 (800) 334-5454;; IMPORTANT : This code is self modifying due to the limitations of ;	the NCR53c7,8xx series chips.  Persons debugging this code with;	the remote debugger should take this into account, and NOT set;	breakpoints in modified instructions.;; Design:; The NCR53c7,8xx family of SCSI chips are busmasters with an onboard ; microcontroller using a simple instruction set.   ;; So, to minimize the effects of interrupt latency, and to maximize ; throughput, this driver offloads the practical maximum amount ; of processing to the SCSI chip while still maintaining a common; structure.;; Where tradeoffs were needed between efficiency on the older; chips and the newer NCR53c800 series, the NCR53c800 series ; was chosen.;; While the NCR53c700 and NCR53c700-66 lacked the facilities to fully; automate SCSI transfers without host processor intervention, this ; isn't the case with the NCR53c710 and newer chips which allow ;; - reads and writes to the internal registers from within the SCSI; 	scripts, allowing the SCSI SCRIPTS(tm) code to save processor; 	state so that multiple threads of execution are possible, and also; 	provide an ALU for loop control, etc.; ; - table indirect addressing for some instructions. This allows ;	pointers to be located relative to the DSA ((Data Structure;	Address) register.;; These features make it possible to implement a mailbox style interface,; where the same piece of code is run to handle I/O for multiple threads; at once minimizing our need to relocate code.  Since the NCR53c700/; NCR53c800 series have a unique combination of features, making a ; a standard ingoing/outgoing mailbox system, costly, I've modified it.;; - Mailboxes are a mixture of code and data.  This lets us greatly; 	simplify the NCR53c810 code and do things that would otherwise;	not be possible.;; The saved data pointer is now implemented as follows :;; 	Control flow has been architected such that if control reaches;	munge_save_data_pointer, on a restore pointers message or ;	reconnection, a jump to the address formerly in the TEMP register;	will allow the SCSI command to resume execution.;;; Note : the DSA structures must be aligned on 32 bit boundaries,; since the source and destination of MOVE MEMORY instructions ; must share the same alignment and this is the alignment of the; NCR registers.;ABSOLUTE dsa_temp_lun = 0		; Patch to lun for current dsaABSOLUTE dsa_temp_next = 0		; Patch to dsa next for current dsaABSOLUTE dsa_temp_addr_next = 0		; Patch to address of dsa next address 					; 	for current dsaABSOLUTE dsa_temp_sync = 0		; Patch to address of per-target					;	sync routineABSOLUTE dsa_temp_target = 0		; Patch to id for current dsaABSOLUTE dsa_temp_addr_saved_pointer = 0; Patch to address of per-command					; 	saved data pointerABSOLUTE dsa_temp_addr_residual = 0	; Patch to address of per-command					;	current residual codeABSOLUTE dsa_temp_addr_saved_residual = 0; Patch to address of per-command					; saved residual codeABSOLUTE dsa_temp_addr_new_value = 0	; Address of value for JUMP operandABSOLUTE dsa_temp_addr_array_value = 0 	; Address to copy toABSOLUTE dsa_temp_addr_dsa_value = 0	; Address of this DSA value;; Once a device has initiated reselection, we need to compare it ; against the singly linked list of commands which have disconnected; and are pending reselection.  These commands are maintained in ; an unordered singly linked list of DSA structures, through the; DSA pointers at their 'centers' headed by the reconnect_dsa_head; pointer.; ; To avoid complications in removing commands from the list,; I minimize the amount of expensive (at eight operations per; addition @ 500-600ns each) pointer operations which must; be done in the NCR driver by precomputing them on the ; host processor during dsa structure generation.;; The fixed-up per DSA code knows how to recognize the nexus; associated with the corresponding SCSI command, and modifies; the source and destination pointers for the MOVE MEMORY ; instruction which is executed when reselected_ok is called; to remove the command from the list.  Similarly, DSA is ; loaded with the address of the next DSA structure and; reselected_check_next is called if a failure occurs.;; Perhaps more concisely, the net effect of the mess is ;; for (dsa = reconnect_dsa_head, dest = &reconnect_dsa_head, ;     src = NULL; dsa; dest = &dsa->next, dsa = dsa->next) {; 	src = &dsa->next;; 	if (target_id == dsa->id && target_lun == dsa->lun) {; 		*dest = *src;; 		break;;         }	; };; if (!dsa);           error (int_err_unexpected_reselect);; else  ;     longjmp (dsa->jump_resume, 0);;; 	#if (CHIP != 700) && (CHIP != 70066); Define DSA structure used for mailboxesENTRY dsa_code_templatedsa_code_template:ENTRY dsa_code_begindsa_code_begin:	MOVE dmode_memory_to_ncr TO DMODE	MOVE MEMORY 4, dsa_temp_addr_dsa_value, addr_scratch	MOVE dmode_memory_to_memory TO DMODE	CALL scratch_to_dsa	CALL select; Handle the phase mismatch which may have resulted from the ; MOVE FROM dsa_msgout if we returned here.  The CLEAR ATN ; may or may not be necessary, and we should update script_asm.pl; to handle multiple pieces.    CLEAR ATN    CLEAR ACK; Replace second operand with address of JUMP instruction dest operand; in schedule table for this DSA.  Becomes dsa_jump_dest in 53c7,8xx.c.ENTRY dsa_code_fix_jumpdsa_code_fix_jump:	MOVE MEMORY 4, NOP_insn, 0	JUMP select_done; wrong_dsa loads the DSA register with the value of the dsa_next; field.;wrong_dsa:;		Patch the MOVE MEMORY INSTRUCTION such that ;		the destination address is the address of the OLD ;		next pointer.;	MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 8	MOVE dmode_memory_to_ncr TO DMODE	;; 	Move the _contents_ of the next pointer into the DSA register as ;	the next I_T_L or I_T_L_Q tupple to check against the established;	nexus.;	MOVE MEMORY 4, dsa_temp_next, addr_scratch	MOVE dmode_memory_to_memory TO DMODE	CALL scratch_to_dsa	JUMP reselected_check_nextABSOLUTE dsa_save_data_pointer = 0ENTRY dsa_code_save_data_pointerdsa_code_save_data_pointer:    	MOVE dmode_ncr_to_memory TO DMODE    	MOVE MEMORY 4, addr_temp, dsa_temp_addr_saved_pointer    	MOVE dmode_memory_to_memory TO DMODE; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h    	MOVE MEMORY 24, dsa_temp_addr_residual, dsa_temp_addr_saved_residual        CLEAR ACK#ifdef DEBUG        INT int_debug_saved#endif    	RETURNABSOLUTE dsa_restore_pointers = 0ENTRY dsa_code_restore_pointersdsa_code_restore_pointers:    	MOVE dmode_memory_to_ncr TO DMODE    	MOVE MEMORY 4, dsa_temp_addr_saved_pointer, addr_temp    	MOVE dmode_memory_to_memory TO DMODE; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h    	MOVE MEMORY 24, dsa_temp_addr_saved_residual, dsa_temp_addr_residual        CLEAR ACK#ifdef DEBUG        INT int_debug_restored#endif    	RETURNABSOLUTE dsa_check_reselect = 0; dsa_check_reselect determines whether or not the current target and; lun match the current DSAENTRY dsa_code_check_reselectdsa_code_check_reselect:	MOVE SSID TO SFBR		; SSID contains 3 bit target ID; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips	JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 0xf8;; Hack - move to scratch first, since SFBR is not writeable; 	via the CPU and hence a MOVE MEMORY instruction.;	MOVE dmode_memory_to_ncr TO DMODE	MOVE MEMORY 1, reselected_identify, addr_scratch	MOVE dmode_memory_to_memory TO DMODE	MOVE SCRATCH0 TO SFBR; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips	JUMP REL (wrong_dsa), IF NOT dsa_temp_lun, AND MASK 0xf8;		Patch the MOVE MEMORY INSTRUCTION such that;		the source address is the address of this dsa's;		next pointer.	MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 4	CALL reselected_ok	CALL dsa_temp_sync	; Release ACK on the IDENTIFY message _after_ we've set the synchronous ; transfer parameters! 	CLEAR ACK; Implicitly restore pointers on reselection, so a RETURN; will transfer control back to the right spot.    	CALL REL (dsa_code_restore_pointers)    	RETURNENTRY dsa_zerodsa_zero:ENTRY dsa_code_template_enddsa_code_template_end:; Perform sanity check for dsa_fields_start == dsa_code_template_end - ; dsa_zero, puke.ABSOLUTE dsa_fields_start =  0	; Sanity marker				; 	pad 48 bytes (fix this RSN)ABSOLUTE dsa_next = 48		; len 4 Next DSA 				; del 4 Previous DSA addressABSOLUTE dsa_cmnd = 56		; len 4 Scsi_Cmnd * for this thread.ABSOLUTE dsa_select = 60	; len 4 Device ID, Period, Offset for 			 	;	table indirect selectABSOLUTE dsa_msgout = 64	; len 8 table indirect move parameter for 				;       select messageABSOLUTE dsa_cmdout = 72	; len 8 table indirect move parameter for 				;	commandABSOLUTE dsa_dataout = 80	; len 4 code pointer for dataoutABSOLUTE dsa_datain = 84	; len 4 code pointer for datainABSOLUTE dsa_msgin = 88		; len 8 table indirect move for msginABSOLUTE dsa_status = 96 	; len 8 table indirect move for status byteABSOLUTE dsa_msgout_other = 104	; len 8 table indirect for normal message out				; (Synchronous transfer negotiation, etc).ABSOLUTE dsa_end = 112ABSOLUTE schedule = 0 		; Array of JUMP dsa_begin or JUMP (next),				; terminated by a call to JUMP wait_reselect; Linked lists of DSA structuresABSOLUTE reconnect_dsa_head = 0	; Link list of DSAs which can reconnectABSOLUTE addr_reconnect_dsa_head = 0 ; Address of variable containing				; address of reconnect_dsa_head; These select the source and destination of a MOVE MEMORY instructionABSOLUTE dmode_memory_to_memory = 0x0ABSOLUTE dmode_memory_to_ncr = 0x0ABSOLUTE dmode_ncr_to_memory = 0x0ABSOLUTE addr_scratch = 0x0ABSOLUTE addr_temp = 0x0#endif /* CHIP != 700 && CHIP != 70066 */; Interrupts - ; MSB indicates type; 0	handle error condition; 1 	handle message ; 2 	handle normal condition; 3	debugging interrupt; 4 	testing interrupt ; Next byte indicates specific error; XXX not yet implemented, I'm not sure if I want to - ; Next byte indicates the routine the error occurred in; The LSB indicates the specific place the error occurred ABSOLUTE int_err_unexpected_phase = 0x00000000	; Unexpected phase encounteredABSOLUTE int_err_selected = 0x00010000		; SELECTED (nee RESELECTED)ABSOLUTE int_err_unexpected_reselect = 0x00020000 ABSOLUTE int_err_check_condition = 0x00030000	ABSOLUTE int_err_no_phase = 0x00040000ABSOLUTE int_msg_wdtr = 0x01000000		; WDTR message receivedABSOLUTE int_msg_sdtr = 0x01010000		; SDTR receivedABSOLUTE int_msg_1 = 0x01020000			; single byte special message						; receivedABSOLUTE int_norm_select_complete = 0x02000000	; Select complete, reprogram						; registers.ABSOLUTE int_norm_reselect_complete = 0x02010000	; Nexus establishedABSOLUTE int_norm_command_complete = 0x02020000 ; Command completeABSOLUTE int_norm_disconnected = 0x02030000	; Disconnected ABSOLUTE int_norm_aborted =0x02040000		; Aborted *dsaABSOLUTE int_norm_reset = 0x02050000		; Generated BUS reset.ABSOLUTE int_debug_break = 0x03000000		; Break point#ifdef DEBUGABSOLUTE int_debug_scheduled = 0x03010000	; new I/O scheduled ABSOLUTE int_debug_idle = 0x03020000		; scheduler is idleABSOLUTE int_debug_dsa_loaded = 0x03030000	; dsa reloadedABSOLUTE int_debug_reselected = 0x03040000	; NCR reselectedABSOLUTE int_debug_head = 0x03050000		; issue head overwrittenABSOLUTE int_debug_disconnected = 0x03060000	; disconnectedABSOLUTE int_debug_disconnect_msg = 0x03070000	; got message to disconnectABSOLUTE int_debug_dsa_schedule = 0x03080000	; in dsa_scheduleABSOLUTE int_debug_reselect_check = 0x03090000  ; Check for reselection of DSAABSOLUTE int_debug_reselected_ok = 0x030a0000 	; Reselection accepted#endifABSOLUTE int_debug_panic = 0x030b0000		; Panic driver#ifdef DEBUGABSOLUTE int_debug_saved = 0x030c0000 		; save/restore pointersABSOLUTE int_debug_restored = 0x030d0000ABSOLUTE int_debug_sync = 0x030e0000		; Sanity check synchronous 						; parameters. ABSOLUTE int_debug_datain = 0x030f0000		; going into data in phase 						; now.ABSOLUTE int_debug_check_dsa = 0x03100000	; Sanity check DSA against						; SDID.#endifABSOLUTE int_test_1 = 0x04000000		; Test 1 completeABSOLUTE int_test_2 = 0x04010000		; Test 2 completeABSOLUTE int_test_3 = 0x04020000		; Test 3 complete; These should start with 0x05000000, with low bits incrementing for ; each one.#ifdef EVENTSABSOLUTE int_EVENT_SELECT = 0ABSOLUTE int_EVENT_DISCONNECT = 0ABSOLUTE int_EVENT_RESELECT = 0ABSOLUTE int_EVENT_COMPLETE = 0ABSOLUTE int_EVENT_IDLE = 0ABSOLUTE int_EVENT_SELECT_FAILED = 0ABSOLUTE int_EVENT_BEFORE_SELECT = 0ABSOLUTE int_EVENT_RESELECT_FAILED = 0#endif						ABSOLUTE NCR53c7xx_msg_abort = 0	; Pointer to abort messageABSOLUTE NCR53c7xx_msg_reject = 0       ; Pointer to reject messageABSOLUTE NCR53c7xx_zero	= 0		; long with zero in it, use for sourceABSOLUTE NCR53c7xx_sink = 0		; long to dump worthless data inABSOLUTE NOP_insn = 0			; NOP instruction; Pointer to message, potentially multi-byteABSOLUTE msg_buf = 0; Pointer to holding area for reselection informationABSOLUTE reselected_identify = 0ABSOLUTE reselected_tag = 0; Request sense command pointer, it's a 6 byte command, should; be constant for all commands since we always want 16 bytes of ; sense and we don't need to change any fields as we did under ; SCSI-I when we actually cared about the LUN field.;EXTERNAL NCR53c7xx_sense		; Request sense command#if (CHIP != 700) && (CHIP != 70066); dsa_schedule  ; PURPOSE : after a DISCONNECT message has been received, and pointers;	saved, insert the current DSA structure at the head of the ; 	disconnected queue and fall through to the scheduler.;; CALLS : OK;; INPUTS : dsa - current DSA structure, reconnect_dsa_head - list;	of disconnected commands;; MODIFIES : SCRATCH, reconnect_dsa_head; ; EXITS : always passes control to scheduleENTRY dsa_scheduledsa_schedule:#if 0    INT int_debug_dsa_schedule#endif;; Calculate the address of the next pointer within the DSA ; structure of the command that is currently disconnecting;    CALL dsa_to_scratch    MOVE SCRATCH0 + dsa_next TO SCRATCH0    MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY    MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY    MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY; Point the next field of this DSA structure at the current disconnected ; list    MOVE dmode_ncr_to_memory TO DMODE    MOVE MEMORY 4, addr_scratch, dsa_schedule_insert + 8    MOVE dmode_memory_to_memory TO DMODEdsa_schedule_insert:    MOVE MEMORY 4, reconnect_dsa_head, 0 ; And update the head pointer.    CALL dsa_to_scratch    MOVE dmode_ncr_to_memory TO DMODE	    MOVE MEMORY 4, addr_scratch, reconnect_dsa_head    MOVE dmode_memory_to_memory TO DMODE/* Temporarily, see what happens. */#ifndef ORIGINAL    MOVE SCNTL2 & 0x7f TO SCNTL2

⌨️ 快捷键说明

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