1 /* DO NOT EDIT - Generated automatically by script_asm.pl */
2 static u32 SCRIPT[] = {
9 ; 53c710 driver. Modified from Drew Eckhardts driver
10 ; for 53c810 by Richard Hirst [richard@sleepie.demon.co.uk]
12 ; I have left the script for the 53c8xx family in here, as it is likely
13 ; to be useful to see what I changed when bug hunting.
15 ; NCR 53c810 driver, main script
17 ; iX Multiuser Multitasking Magazine
20 ; Copyright 1993, 1994, 1995 Drew Eckhardt
22 ; (Unix and Linux consulting and custom programming)
26 ; TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
30 ; For more information, please consult
33 ; PCI-SCSI I/O Processor
40 ; NCR Microelectronics
41 ; 1635 Aeroplaza Drive
42 ; Colorado Springs, CO 80916
45 ; Toll free literature number
48 ; IMPORTANT : This code is self modifying due to the limitations of
49 ; the NCR53c7,8xx series chips. Persons debugging this code with
50 ; the remote debugger should take this into account, and NOT set
51 ; breakpoints in modified instructions.
54 ; The NCR53c7,8xx family of SCSI chips are busmasters with an onboard
55 ; microcontroller using a simple instruction set.
57 ; So, to minimize the effects of interrupt latency, and to maximize
58 ; throughput, this driver offloads the practical maximum amount
59 ; of processing to the SCSI chip while still maintaining a common
62 ; Where tradeoffs were needed between efficiency on the older
63 ; chips and the newer NCR53c800 series, the NCR53c800 series
66 ; While the NCR53c700 and NCR53c700-66 lacked the facilities to fully
67 ; automate SCSI transfers without host processor intervention, this
68 ; isn't the case with the NCR53c710 and newer chips which allow
70 ; - reads and writes to the internal registers from within the SCSI
71 ; scripts, allowing the SCSI SCRIPTS(tm) code to save processor
72 ; state so that multiple threads of execution are possible, and also
73 ; provide an ALU for loop control, etc.
75 ; - table indirect addressing for some instructions. This allows
76 ; pointers to be located relative to the DSA ((Data Structure
79 ; These features make it possible to implement a mailbox style interface,
80 ; where the same piece of code is run to handle I/O for multiple threads
81 ; at once minimizing our need to relocate code. Since the NCR53c700/
82 ; NCR53c800 series have a unique combination of features, making a
83 ; a standard ingoing/outgoing mailbox system, costly, I've modified it.
85 ; - Mailboxes are a mixture of code and data. This lets us greatly
86 ; simplify the NCR53c810 code and do things that would otherwise
89 ; The saved data pointer is now implemented as follows :
91 ; Control flow has been architected such that if control reaches
92 ; munge_save_data_pointer, on a restore pointers message or
93 ; reconnection, a jump to the address formerly in the TEMP register
94 ; will allow the SCSI command to resume execution.
98 ; Note : the DSA structures must be aligned on 32 bit boundaries,
99 ; since the source and destination of MOVE MEMORY instructions
100 ; must share the same alignment and this is the alignment of the
104 ; For some systems (MVME166, for example) dmode is always the same, so don't
105 ; waste time writing it
117 ABSOLUTE dsa_temp_lun = 0 ; Patch to lun for current dsa
118 ABSOLUTE dsa_temp_next = 0 ; Patch to dsa next for current dsa
119 ABSOLUTE dsa_temp_addr_next = 0 ; Patch to address of dsa next address
121 ABSOLUTE dsa_temp_sync = 0 ; Patch to address of per-target
123 ABSOLUTE dsa_sscf_710 = 0 ; Patch to address of per-target
124 ; sscf value (53c710)
125 ABSOLUTE dsa_temp_target = 0 ; Patch to id for current dsa
126 ABSOLUTE dsa_temp_addr_saved_pointer = 0; Patch to address of per-command
128 ABSOLUTE dsa_temp_addr_residual = 0 ; Patch to address of per-command
129 ; current residual code
130 ABSOLUTE dsa_temp_addr_saved_residual = 0; Patch to address of per-command
131 ; saved residual code
132 ABSOLUTE dsa_temp_addr_new_value = 0 ; Address of value for JUMP operand
133 ABSOLUTE dsa_temp_addr_array_value = 0 ; Address to copy to
134 ABSOLUTE dsa_temp_addr_dsa_value = 0 ; Address of this DSA value
137 ; Once a device has initiated reselection, we need to compare it
138 ; against the singly linked list of commands which have disconnected
139 ; and are pending reselection. These commands are maintained in
140 ; an unordered singly linked list of DSA structures, through the
141 ; DSA pointers at their 'centers' headed by the reconnect_dsa_head
144 ; To avoid complications in removing commands from the list,
145 ; I minimize the amount of expensive (at eight operations per
146 ; addition @ 500-600ns each) pointer operations which must
147 ; be done in the NCR driver by precomputing them on the
148 ; host processor during dsa structure generation.
150 ; The fixed-up per DSA code knows how to recognize the nexus
151 ; associated with the corresponding SCSI command, and modifies
152 ; the source and destination pointers for the MOVE MEMORY
153 ; instruction which is executed when reselected_ok is called
154 ; to remove the command from the list. Similarly, DSA is
155 ; loaded with the address of the next DSA structure and
156 ; reselected_check_next is called if a failure occurs.
158 ; Perhaps more concisely, the net effect of the mess is
160 ; for (dsa = reconnect_dsa_head, dest = &reconnect_dsa_head,
161 ; src = NULL; dsa; dest = &dsa->next, dsa = dsa->next) {
163 ; if (target_id == dsa->id && target_lun == dsa->lun) {
170 ; error (int_err_unexpected_reselect);
172 ; longjmp (dsa->jump_resume, 0);
177 ; Define DSA structure used for mailboxes
178 ENTRY dsa_code_template
182 ; RGH: Don't care about TEMP and DSA here
184 MOVE MEMORY 4, dsa_temp_addr_dsa_value, addr_scratch
186 at 0x00000000 : */ 0xc0000004,0x00000000,0x00000000,
190 MOVE MEMORY 4, addr_scratch, saved_dsa
192 at 0x00000003 : */ 0xc0000004,0x00000000,0x00000000,
194 ; We are about to go and select the device, so must set SSCF bits
195 MOVE MEMORY 4, dsa_sscf_710, addr_scratch
197 at 0x00000006 : */ 0xc0000004,0x00000000,0x00000000,
200 MOVE SCRATCH3 TO SFBR
202 at 0x00000009 : */ 0x72370000,0x00000000,
209 at 0x0000000b : */ 0x6a0b0000,0x00000000,
211 MOVE MEMORY 4, saved_dsa, addr_dsa
213 at 0x0000000d : */ 0xc0000004,0x00000000,0x00000000,
220 at 0x00000010 : */ 0x88080000,0x000001f8,
222 ; Handle the phase mismatch which may have resulted from the
223 ; MOVE FROM dsa_msgout if we returned here. The CLEAR ATN
224 ; may or may not be necessary, and we should update script_asm.pl
225 ; to handle multiple pieces.
228 at 0x00000012 : */ 0x60000008,0x00000000,
232 at 0x00000014 : */ 0x60000040,0x00000000,
235 ; Replace second operand with address of JUMP instruction dest operand
236 ; in schedule table for this DSA. Becomes dsa_jump_dest in 53c7,8xx.c.
237 ENTRY dsa_code_fix_jump
239 MOVE MEMORY 4, NOP_insn, 0
241 at 0x00000016 : */ 0xc0000004,0x00000000,0x00000000,
245 at 0x00000019 : */ 0x80080000,0x00000230,
248 ; wrong_dsa loads the DSA register with the value of the dsa_next
253 ; NOTE DSA is corrupt when we arrive here!
255 ; Patch the MOVE MEMORY INSTRUCTION such that
256 ; the destination address is the address of the OLD
259 MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok_patch + 8
261 at 0x0000001b : */ 0xc0000004,0x00000000,0x000007ec,
265 ; Move the _contents_ of the next pointer into the DSA register as
266 ; the next I_T_L or I_T_L_Q tupple to check against the established
269 MOVE MEMORY 4, dsa_temp_next, addr_scratch
271 at 0x0000001e : */ 0xc0000004,0x00000000,0x00000000,
275 MOVE MEMORY 4, addr_scratch, saved_dsa
277 at 0x00000021 : */ 0xc0000004,0x00000000,0x00000000,
279 MOVE MEMORY 4, saved_dsa, addr_dsa
281 at 0x00000024 : */ 0xc0000004,0x00000000,0x00000000,
286 JUMP reselected_check_next
288 at 0x00000027 : */ 0x80080000,0x000006f0,
291 ABSOLUTE dsa_save_data_pointer = 0
292 ENTRY dsa_code_save_data_pointer
293 dsa_code_save_data_pointer:
295 ; When we get here, TEMP has been saved in jump_temp+4, DSA is corrupt
296 ; We MUST return with DSA correct
297 MOVE MEMORY 4, jump_temp+4, dsa_temp_addr_saved_pointer
299 at 0x00000029 : */ 0xc0000004,0x000009c8,0x00000000,
301 ; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
302 MOVE MEMORY 24, dsa_temp_addr_residual, dsa_temp_addr_saved_residual
304 at 0x0000002c : */ 0xc0000018,0x00000000,0x00000000,
308 at 0x0000002f : */ 0x60000040,0x00000000,
313 MOVE MEMORY 4, saved_dsa, addr_dsa
315 at 0x00000031 : */ 0xc0000004,0x00000000,0x00000000,
319 at 0x00000034 : */ 0x80080000,0x000009c4,
322 ABSOLUTE dsa_restore_pointers = 0
323 ENTRY dsa_code_restore_pointers
324 dsa_code_restore_pointers:
326 ; TEMP and DSA are corrupt when we get here, but who cares!
327 MOVE MEMORY 4, dsa_temp_addr_saved_pointer, jump_temp + 4
329 at 0x00000036 : */ 0xc0000004,0x00000000,0x000009c8,
331 ; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
332 MOVE MEMORY 24, dsa_temp_addr_saved_residual, dsa_temp_addr_residual
334 at 0x00000039 : */ 0xc0000018,0x00000000,0x00000000,
338 at 0x0000003c : */ 0x60000040,0x00000000,
340 ; Restore DSA, note we don't care about TEMP
341 MOVE MEMORY 4, saved_dsa, addr_dsa
343 at 0x0000003e : */ 0xc0000004,0x00000000,0x00000000,
350 at 0x00000041 : */ 0x80080000,0x000009c4,
354 ABSOLUTE dsa_check_reselect = 0
355 ; dsa_check_reselect determines whether or not the current target and
356 ; lun match the current DSA
357 ENTRY dsa_code_check_reselect
358 dsa_code_check_reselect:
362 MOVE LCRC TO SFBR ; LCRC has our ID and his ID bits set
364 at 0x00000043 : */ 0x72230000,0x00000000,
366 JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 0x80
368 at 0x00000045 : */ 0x80848000,0x00ffff50,
376 ; Hack - move to scratch first, since SFBR is not writeable
377 ; via the CPU and hence a MOVE MEMORY instruction.
380 MOVE MEMORY 1, reselected_identify, addr_scratch
382 at 0x00000047 : */ 0xc0000001,0x00000000,0x00000000,
386 ; BIG ENDIAN ON MVME16x
387 MOVE SCRATCH3 TO SFBR
389 at 0x0000004a : */ 0x72370000,0x00000000,
394 ; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips
395 ; Are you sure about that? richard@sleepie.demon.co.uk
396 JUMP REL (wrong_dsa), IF NOT dsa_temp_lun, AND MASK 0xf8
398 at 0x0000004c : */ 0x8084f800,0x00ffff34,
400 ; Patch the MOVE MEMORY INSTRUCTION such that
401 ; the source address is the address of this dsa's
403 MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok_patch + 4
405 at 0x0000004e : */ 0xc0000004,0x00000000,0x000007e8,
409 at 0x00000051 : */ 0x88080000,0x00000798,
412 ; Restore DSA following memory moves in reselected_ok
413 ; dsa_temp_sync doesn't really care about DSA, but it has an
414 ; optional debug INT so a valid DSA is a good idea.
415 MOVE MEMORY 4, saved_dsa, addr_dsa
417 at 0x00000053 : */ 0xc0000004,0x00000000,0x00000000,
422 at 0x00000056 : */ 0x88080000,0x00000000,
424 ; Release ACK on the IDENTIFY message _after_ we've set the synchronous
425 ; transfer parameters!
428 at 0x00000058 : */ 0x60000040,0x00000000,
430 ; Implicitly restore pointers on reselection, so a RETURN
431 ; will transfer control back to the right spot.
432 CALL REL (dsa_code_restore_pointers)
434 at 0x0000005a : */ 0x88880000,0x00ffff68,
438 at 0x0000005c : */ 0x90080000,0x00000000,
442 ENTRY dsa_code_template_end
443 dsa_code_template_end:
445 ; Perform sanity check for dsa_fields_start == dsa_code_template_end -
448 ABSOLUTE dsa_fields_start = 0 ; Sanity marker
449 ; pad 48 bytes (fix this RSN)
450 ABSOLUTE dsa_next = 48 ; len 4 Next DSA
451 ; del 4 Previous DSA address
452 ABSOLUTE dsa_cmnd = 56 ; len 4 Scsi_Cmnd * for this thread.
453 ABSOLUTE dsa_select = 60 ; len 4 Device ID, Period, Offset for
454 ; table indirect select
455 ABSOLUTE dsa_msgout = 64 ; len 8 table indirect move parameter for
457 ABSOLUTE dsa_cmdout = 72 ; len 8 table indirect move parameter for
459 ABSOLUTE dsa_dataout = 80 ; len 4 code pointer for dataout
460 ABSOLUTE dsa_datain = 84 ; len 4 code pointer for datain
461 ABSOLUTE dsa_msgin = 88 ; len 8 table indirect move for msgin
462 ABSOLUTE dsa_status = 96 ; len 8 table indirect move for status byte
463 ABSOLUTE dsa_msgout_other = 104 ; len 8 table indirect for normal message out
464 ; (Synchronous transfer negotiation, etc).
465 ABSOLUTE dsa_end = 112
467 ABSOLUTE schedule = 0 ; Array of JUMP dsa_begin or JUMP (next),
468 ; terminated by a call to JUMP wait_reselect
470 ; Linked lists of DSA structures
471 ABSOLUTE reconnect_dsa_head = 0 ; Link list of DSAs which can reconnect
472 ABSOLUTE addr_reconnect_dsa_head = 0 ; Address of variable containing
473 ; address of reconnect_dsa_head
475 ; These select the source and destination of a MOVE MEMORY instruction
476 ABSOLUTE dmode_memory_to_memory = 0x0
477 ABSOLUTE dmode_memory_to_ncr = 0x0
478 ABSOLUTE dmode_ncr_to_memory = 0x0
480 ABSOLUTE addr_scratch = 0x0
481 ABSOLUTE addr_temp = 0x0
483 ABSOLUTE saved_dsa = 0x0
484 ABSOLUTE emulfly = 0x0
485 ABSOLUTE addr_dsa = 0x0
491 ; 0 handle error condition
493 ; 2 handle normal condition
494 ; 3 debugging interrupt
495 ; 4 testing interrupt
496 ; Next byte indicates specific error
498 ; XXX not yet implemented, I'm not sure if I want to -
499 ; Next byte indicates the routine the error occurred in
500 ; The LSB indicates the specific place the error occurred
502 ABSOLUTE int_err_unexpected_phase = 0x00000000 ; Unexpected phase encountered
503 ABSOLUTE int_err_selected = 0x00010000 ; SELECTED (nee RESELECTED)
504 ABSOLUTE int_err_unexpected_reselect = 0x00020000
505 ABSOLUTE int_err_check_condition = 0x00030000
506 ABSOLUTE int_err_no_phase = 0x00040000
507 ABSOLUTE int_msg_wdtr = 0x01000000 ; WDTR message received
508 ABSOLUTE int_msg_sdtr = 0x01010000 ; SDTR received
509 ABSOLUTE int_msg_1 = 0x01020000 ; single byte special message
512 ABSOLUTE int_norm_select_complete = 0x02000000 ; Select complete, reprogram
514 ABSOLUTE int_norm_reselect_complete = 0x02010000 ; Nexus established
515 ABSOLUTE int_norm_command_complete = 0x02020000 ; Command complete
516 ABSOLUTE int_norm_disconnected = 0x02030000 ; Disconnected
517 ABSOLUTE int_norm_aborted =0x02040000 ; Aborted *dsa
518 ABSOLUTE int_norm_reset = 0x02050000 ; Generated BUS reset.
519 ABSOLUTE int_norm_emulateintfly = 0x02060000 ; 53C710 Emulated intfly
520 ABSOLUTE int_debug_break = 0x03000000 ; Break point
522 ABSOLUTE int_debug_panic = 0x030b0000 ; Panic driver
525 ABSOLUTE int_test_1 = 0x04000000 ; Test 1 complete
526 ABSOLUTE int_test_2 = 0x04010000 ; Test 2 complete
527 ABSOLUTE int_test_3 = 0x04020000 ; Test 3 complete
530 ; These should start with 0x05000000, with low bits incrementing for
535 ABSOLUTE NCR53c7xx_msg_abort = 0 ; Pointer to abort message
536 ABSOLUTE NCR53c7xx_msg_reject = 0 ; Pointer to reject message
537 ABSOLUTE NCR53c7xx_zero = 0 ; long with zero in it, use for source
538 ABSOLUTE NCR53c7xx_sink = 0 ; long to dump worthless data in
539 ABSOLUTE NOP_insn = 0 ; NOP instruction
541 ; Pointer to message, potentially multi-byte
544 ; Pointer to holding area for reselection information
545 ABSOLUTE reselected_identify = 0
546 ABSOLUTE reselected_tag = 0
548 ; Request sense command pointer, it's a 6 byte command, should
549 ; be constant for all commands since we always want 16 bytes of
550 ; sense and we don't need to change any fields as we did under
551 ; SCSI-I when we actually cared about the LUN field.
552 ;EXTERNAL NCR53c7xx_sense ; Request sense command
556 ; PURPOSE : after a DISCONNECT message has been received, and pointers
557 ; saved, insert the current DSA structure at the head of the
558 ; disconnected queue and fall through to the scheduler.
562 ; INPUTS : dsa - current DSA structure, reconnect_dsa_head - list
563 ; of disconnected commands
565 ; MODIFIES : SCRATCH, reconnect_dsa_head
567 ; EXITS : always passes control to schedule
576 ; Calculate the address of the next pointer within the DSA
577 ; structure of the command that is currently disconnecting
580 ; Read what should be the current DSA from memory - actual DSA
581 ; register is probably corrupt
582 MOVE MEMORY 4, saved_dsa, addr_scratch
584 at 0x0000005e : */ 0xc0000004,0x00000000,0x00000000,
589 MOVE SCRATCH0 + dsa_next TO SCRATCH0
591 at 0x00000061 : */ 0x7e343000,0x00000000,
593 MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
595 at 0x00000063 : */ 0x7f350000,0x00000000,
597 MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
599 at 0x00000065 : */ 0x7f360000,0x00000000,
601 MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
603 at 0x00000067 : */ 0x7f370000,0x00000000,
606 ; Point the next field of this DSA structure at the current disconnected
609 MOVE MEMORY 4, addr_scratch, dsa_schedule_insert + 8
611 at 0x00000069 : */ 0xc0000004,0x00000000,0x000001b8,
615 MOVE MEMORY 4, reconnect_dsa_head, 0
617 at 0x0000006c : */ 0xc0000004,0x00000000,0x00000000,
620 ; And update the head pointer.
622 ; Read what should be the current DSA from memory - actual DSA
623 ; register is probably corrupt
624 MOVE MEMORY 4, saved_dsa, addr_scratch
626 at 0x0000006f : */ 0xc0000004,0x00000000,0x00000000,
632 MOVE MEMORY 4, addr_scratch, reconnect_dsa_head
634 at 0x00000072 : */ 0xc0000004,0x00000000,0x00000000,
644 at 0x00000075 : */ 0x60000040,0x00000000,
648 ; Time to correct DSA following memory move
649 MOVE MEMORY 4, saved_dsa, addr_dsa
651 at 0x00000077 : */ 0xc0000004,0x00000000,0x00000000,
656 at 0x0000007a : */ 0x48000000,0x00000000,
666 at 0x0000007c : */ 0x80080000,0x00000000,
673 ; PURPOSE : establish a nexus for the SCSI command referenced by DSA.
674 ; On success, the current DSA structure is removed from the issue
675 ; queue. Usually, this is entered as a fall-through from schedule,
676 ; although the contingent allegiance handling code will write
677 ; the select entry address to the DSP to restart a command as a
678 ; REQUEST SENSE. A message is sent (usually IDENTIFY, although
679 ; additional SDTR or WDTR messages may be sent). COMMAND OUT
682 ; INPUTS : DSA - SCSI command, issue_dsa_head
686 ; MODIFIES : SCRATCH, issue_dsa_head
688 ; EXITS : on reselection or selection, go to select_failed
689 ; otherwise, RETURN so control is passed back to
705 at 0x0000007e : */ 0x60000200,0x00000000,
710 ; In effect, SELECTION operations are backgrounded, with execution
711 ; continuing until code which waits for REQ or a fatal interrupt is
714 ; So, for more performance, we could overlap the code which removes
715 ; the command from the NCRs issue queue with the selection, but
716 ; at this point I don't want to deal with the error recovery.
721 ; Enable selection timer
725 MOVE CTEST7 & 0xef TO CTEST7
727 at 0x00000080 : */ 0x7c1bef00,0x00000000,
731 SELECT ATN FROM dsa_select, select_failed
733 at 0x00000082 : */ 0x4300003c,0x00000828,
735 JUMP select_msgout, WHEN MSG_OUT
737 at 0x00000084 : */ 0x860b0000,0x00000218,
742 ; Disable selection timer
743 MOVE CTEST7 | 0x10 TO CTEST7
745 at 0x00000086 : */ 0x7a1b1000,0x00000000,
748 MOVE FROM dsa_msgout, WHEN MSG_OUT
750 at 0x00000088 : */ 0x1e000000,0x00000040,
764 at 0x0000008a : */ 0x90080000,0x00000000,
770 ; PURPOSE: continue on to normal data transfer; called as the exit
771 ; point from dsa_begin.
781 ; NOTE DSA is corrupt when we arrive here!
782 MOVE MEMORY 4, saved_dsa, addr_dsa
784 at 0x0000008c : */ 0xc0000004,0x00000000,0x00000000,
794 ; After a successful selection, we should get either a CMD phase or
795 ; some transfer request negotiation message.
797 JUMP cmdout, WHEN CMD
799 at 0x0000008f : */ 0x820b0000,0x0000025c,
801 INT int_err_unexpected_phase, WHEN NOT MSG_IN
803 at 0x00000091 : */ 0x9f030000,0x00000000,
807 CALL msg_in, WHEN MSG_IN
809 at 0x00000093 : */ 0x8f0b0000,0x0000041c,
811 JUMP select_msg_in, WHEN MSG_IN
813 at 0x00000095 : */ 0x870b0000,0x0000024c,
817 INT int_err_unexpected_phase, WHEN NOT CMD
819 at 0x00000097 : */ 0x9a030000,0x00000000,
827 MOVE FROM dsa_cmdout, WHEN CMD
829 at 0x00000099 : */ 0x1a000000,0x00000048,
841 ; PURPOSE : handle the main data transfer for a SCSI command in
842 ; several parts. In the first part, data_transfer, DATA_IN
843 ; and DATA_OUT phases are allowed, with the user provided
844 ; code (usually dynamically generated based on the scatter/gather
845 ; list associated with a SCSI command) called to handle these
848 ; After control has passed to one of the user provided
849 ; DATA_IN or DATA_OUT routines, back calls are made to
850 ; other_transfer_in or other_transfer_out to handle non-DATA IN
851 ; and DATA OUT phases respectively, with the state of the active
852 ; data pointer being preserved in TEMP.
854 ; On completion, the user code passes control to other_transfer
855 ; which causes DATA_IN and DATA_OUT to result in unexpected_phase
856 ; interrupts so that data overruns may be trapped.
858 ; INPUTS : DSA - SCSI command
860 ; CALLS : OK in data_transfer_start, not ok in other_out and other_in, ok in
865 ; EXITS : if STATUS IN is detected, signifying command completion,
866 ; the NCR jumps to command_complete. If MSG IN occurs, a
867 ; CALL is made to msg_in. Otherwise, other_transfer runs in
873 JUMP cmdout_cmdout, WHEN CMD
875 at 0x0000009b : */ 0x820b0000,0x00000264,
877 CALL msg_in, WHEN MSG_IN
879 at 0x0000009d : */ 0x8f0b0000,0x0000041c,
881 INT int_err_unexpected_phase, WHEN MSG_OUT
883 at 0x0000009f : */ 0x9e0b0000,0x00000000,
885 JUMP do_dataout, WHEN DATA_OUT
887 at 0x000000a1 : */ 0x800b0000,0x000002a4,
889 JUMP do_datain, WHEN DATA_IN
891 at 0x000000a3 : */ 0x810b0000,0x000002fc,
893 JUMP command_complete, WHEN STATUS
895 at 0x000000a5 : */ 0x830b0000,0x0000065c,
899 at 0x000000a7 : */ 0x80080000,0x0000026c,
901 ENTRY end_data_transfer
905 ; FIXME: On NCR53c700 and NCR53c700-66 chips, do_dataout/do_datain
906 ; should be fixed up whenever the nexus changes so it can point to the
907 ; correct routine for that command.
911 ; Nasty jump to dsa->dataout
914 MOVE MEMORY 4, saved_dsa, addr_scratch
916 at 0x000000a9 : */ 0xc0000004,0x00000000,0x00000000,
921 MOVE SCRATCH0 + dsa_dataout TO SCRATCH0
923 at 0x000000ac : */ 0x7e345000,0x00000000,
925 MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
927 at 0x000000ae : */ 0x7f350000,0x00000000,
929 MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
931 at 0x000000b0 : */ 0x7f360000,0x00000000,
933 MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
935 at 0x000000b2 : */ 0x7f370000,0x00000000,
938 MOVE MEMORY 4, addr_scratch, dataout_to_jump + 4
940 at 0x000000b4 : */ 0xc0000004,0x00000000,0x000002e0,
944 MOVE MEMORY 4, 0, dataout_jump + 4
946 at 0x000000b7 : */ 0xc0000004,0x00000000,0x000002f8,
949 ; Time to correct DSA following memory move
950 MOVE MEMORY 4, saved_dsa, addr_dsa
952 at 0x000000ba : */ 0xc0000004,0x00000000,0x00000000,
958 at 0x000000bd : */ 0x80080000,0x00000000,
961 ; Nasty jump to dsa->dsain
964 MOVE MEMORY 4, saved_dsa, addr_scratch
966 at 0x000000bf : */ 0xc0000004,0x00000000,0x00000000,
971 MOVE SCRATCH0 + dsa_datain TO SCRATCH0
973 at 0x000000c2 : */ 0x7e345400,0x00000000,
975 MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
977 at 0x000000c4 : */ 0x7f350000,0x00000000,
979 MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
981 at 0x000000c6 : */ 0x7f360000,0x00000000,
983 MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
985 at 0x000000c8 : */ 0x7f370000,0x00000000,
988 MOVE MEMORY 4, addr_scratch, datain_to_jump + 4
990 at 0x000000ca : */ 0xc0000004,0x00000000,0x00000338,
995 MOVE MEMORY 4, 0, datain_jump + 4
997 at 0x000000cd : */ 0xc0000004,0x00000000,0x00000350,
1000 ; Time to correct DSA following memory move
1001 MOVE MEMORY 4, saved_dsa, addr_dsa
1003 at 0x000000d0 : */ 0xc0000004,0x00000000,0x00000000,
1012 at 0x000000d3 : */ 0x80080000,0x00000000,
1017 ; Note that other_out and other_in loop until a non-data phase
1018 ; is discovered, so we only execute return statements when we
1019 ; can go on to the next data phase block move statement.
1026 INT int_err_unexpected_phase, WHEN CMD
1028 at 0x000000d5 : */ 0x9a0b0000,0x00000000,
1030 JUMP msg_in_restart, WHEN MSG_IN
1032 at 0x000000d7 : */ 0x870b0000,0x000003fc,
1034 INT int_err_unexpected_phase, WHEN MSG_OUT
1036 at 0x000000d9 : */ 0x9e0b0000,0x00000000,
1038 INT int_err_unexpected_phase, WHEN DATA_IN
1040 at 0x000000db : */ 0x990b0000,0x00000000,
1042 JUMP command_complete, WHEN STATUS
1044 at 0x000000dd : */ 0x830b0000,0x0000065c,
1046 JUMP other_out, WHEN NOT DATA_OUT
1048 at 0x000000df : */ 0x80030000,0x00000354,
1051 ; TEMP should be OK, as we got here from a call in the user dataout code.
1055 at 0x000000e1 : */ 0x90080000,0x00000000,
1063 INT int_err_unexpected_phase, WHEN CMD
1065 at 0x000000e3 : */ 0x9a0b0000,0x00000000,
1067 JUMP msg_in_restart, WHEN MSG_IN
1069 at 0x000000e5 : */ 0x870b0000,0x000003fc,
1071 INT int_err_unexpected_phase, WHEN MSG_OUT
1073 at 0x000000e7 : */ 0x9e0b0000,0x00000000,
1075 INT int_err_unexpected_phase, WHEN DATA_OUT
1077 at 0x000000e9 : */ 0x980b0000,0x00000000,
1079 JUMP command_complete, WHEN STATUS
1081 at 0x000000eb : */ 0x830b0000,0x0000065c,
1083 JUMP other_in, WHEN NOT DATA_IN
1085 at 0x000000ed : */ 0x81030000,0x0000038c,
1088 ; TEMP should be OK, as we got here from a call in the user datain code.
1092 at 0x000000ef : */ 0x90080000,0x00000000,
1096 ENTRY other_transfer
1098 INT int_err_unexpected_phase, WHEN CMD
1100 at 0x000000f1 : */ 0x9a0b0000,0x00000000,
1102 CALL msg_in, WHEN MSG_IN
1104 at 0x000000f3 : */ 0x8f0b0000,0x0000041c,
1106 INT int_err_unexpected_phase, WHEN MSG_OUT
1108 at 0x000000f5 : */ 0x9e0b0000,0x00000000,
1110 INT int_err_unexpected_phase, WHEN DATA_OUT
1112 at 0x000000f7 : */ 0x980b0000,0x00000000,
1114 INT int_err_unexpected_phase, WHEN DATA_IN
1116 at 0x000000f9 : */ 0x990b0000,0x00000000,
1118 JUMP command_complete, WHEN STATUS
1120 at 0x000000fb : */ 0x830b0000,0x0000065c,
1124 at 0x000000fd : */ 0x80080000,0x000003c4,
1132 ; PURPOSE : process messages from a target. msg_in is called when the
1133 ; caller hasn't read the first byte of the message. munge_message
1134 ; is called when the caller has read the first byte of the message,
1135 ; and left it in SFBR. msg_in_restart is called when the caller
1136 ; hasn't read the first byte of the message, and wishes RETURN
1137 ; to transfer control back to the address of the conditional
1138 ; CALL instruction rather than to the instruction after it.
1140 ; Various int_* interrupts are generated when the host system
1141 ; needs to intervene, as is the case with SDTR, WDTR, and
1142 ; INITIATE RECOVERY messages.
1144 ; When the host system handles one of these interrupts,
1145 ; it can respond by reentering at reject_message,
1146 ; which rejects the message and returns control to
1147 ; the caller of msg_in or munge_msg, accept_message
1148 ; which clears ACK and returns control, or reply_message
1149 ; which sends the message pointed to by the DSA
1150 ; msgout_other table indirect field.
1152 ; DISCONNECT messages are handled by moving the command
1153 ; to the reconnect_dsa_queue.
1155 ; NOTE: DSA should be valid when we get here - we cannot save both it
1156 ; and TEMP in this routine.
1159 ; INPUTS : DSA - SCSI COMMAND, SFBR - first byte of message (munge_msg
1162 ; CALLS : NO. The TEMP register isn't backed up to allow nested calls.
1164 ; MODIFIES : SCRATCH, DSA on DISCONNECT
1166 ; EXITS : On receipt of SAVE DATA POINTER, RESTORE POINTERS,
1167 ; and normal return from message handlers running under
1168 ; Linux, control is returned to the caller. Receipt
1169 ; of DISCONNECT messages pass control to dsa_schedule.
1171 ENTRY msg_in_restart
1175 ; Since it's easier to debug changes to the statically
1176 ; compiled code, rather than the dynamically generated
1179 ; MOVE x, y, WHEN data_phase
1180 ; CALL other_z, WHEN NOT data_phase
1181 ; MOVE x, y, WHEN data_phase
1183 ; I'd like to have certain routines (notably the message handler)
1184 ; restart on the conditional call rather than the next instruction.
1186 ; So, subtract 8 from the return address
1188 MOVE TEMP0 + 0xf8 TO TEMP0
1190 at 0x000000ff : */ 0x7e1cf800,0x00000000,
1192 MOVE TEMP1 + 0xff TO TEMP1 WITH CARRY
1194 at 0x00000101 : */ 0x7f1dff00,0x00000000,
1196 MOVE TEMP2 + 0xff TO TEMP2 WITH CARRY
1198 at 0x00000103 : */ 0x7f1eff00,0x00000000,
1200 MOVE TEMP3 + 0xff TO TEMP3 WITH CARRY
1202 at 0x00000105 : */ 0x7f1fff00,0x00000000,
1207 MOVE 1, msg_buf, WHEN MSG_IN
1209 at 0x00000107 : */ 0x0f000001,0x00000000,
1213 JUMP munge_extended, IF 0x01 ; EXTENDED MESSAGE
1215 at 0x00000109 : */ 0x800c0001,0x00000574,
1217 JUMP munge_2, IF 0x20, AND MASK 0xdf ; two byte message
1219 at 0x0000010b : */ 0x800cdf20,0x00000464,
1222 ; XXX - I've seen a handful of broken SCSI devices which fail to issue
1223 ; a SAVE POINTERS message before disconnecting in the middle of
1224 ; a transfer, assuming that the DATA POINTER will be implicitly
1227 ; Historically, I've often done an implicit save when the DISCONNECT
1228 ; message is processed. We may want to consider having the option of
1231 JUMP munge_save_data_pointer, IF 0x02 ; SAVE DATA POINTER
1233 at 0x0000010d : */ 0x800c0002,0x0000046c,
1235 JUMP munge_restore_pointers, IF 0x03 ; RESTORE POINTERS
1237 at 0x0000010f : */ 0x800c0003,0x00000518,
1239 JUMP munge_disconnect, IF 0x04 ; DISCONNECT
1241 at 0x00000111 : */ 0x800c0004,0x0000056c,
1243 INT int_msg_1, IF 0x07 ; MESSAGE REJECT
1245 at 0x00000113 : */ 0x980c0007,0x01020000,
1247 INT int_msg_1, IF 0x0f ; INITIATE RECOVERY
1249 at 0x00000115 : */ 0x980c000f,0x01020000,
1256 at 0x00000117 : */ 0x80080000,0x00000604,
1262 at 0x00000119 : */ 0x80080000,0x00000604,
1265 ; The SCSI standard allows targets to recover from transient
1266 ; error conditions by backing up the data pointer with a
1267 ; RESTORE POINTERS message.
1269 ; So, we must save and restore the _residual_ code as well as
1270 ; the current instruction pointer. Because of this messiness,
1271 ; it is simpler to put dynamic code in the dsa for this and to
1272 ; just do a simple jump down there.
1275 munge_save_data_pointer:
1277 ; We have something in TEMP here, so first we must save that
1280 at 0x0000011b : */ 0x721c0000,0x00000000,
1282 MOVE SFBR TO SCRATCH0
1284 at 0x0000011d : */ 0x6a340000,0x00000000,
1288 at 0x0000011f : */ 0x721d0000,0x00000000,
1290 MOVE SFBR TO SCRATCH1
1292 at 0x00000121 : */ 0x6a350000,0x00000000,
1296 at 0x00000123 : */ 0x721e0000,0x00000000,
1298 MOVE SFBR TO SCRATCH2
1300 at 0x00000125 : */ 0x6a360000,0x00000000,
1304 at 0x00000127 : */ 0x721f0000,0x00000000,
1306 MOVE SFBR TO SCRATCH3
1308 at 0x00000129 : */ 0x6a370000,0x00000000,
1310 MOVE MEMORY 4, addr_scratch, jump_temp + 4
1312 at 0x0000012b : */ 0xc0000004,0x00000000,0x000009c8,
1315 MOVE MEMORY 4, saved_dsa, addr_dsa
1317 at 0x0000012e : */ 0xc0000004,0x00000000,0x00000000,
1320 MOVE DSA0 + dsa_save_data_pointer TO SFBR
1322 at 0x00000131 : */ 0x76100000,0x00000000,
1324 MOVE SFBR TO SCRATCH0
1326 at 0x00000133 : */ 0x6a340000,0x00000000,
1328 MOVE DSA1 + 0xff TO SFBR WITH CARRY
1330 at 0x00000135 : */ 0x7711ff00,0x00000000,
1332 MOVE SFBR TO SCRATCH1
1334 at 0x00000137 : */ 0x6a350000,0x00000000,
1336 MOVE DSA2 + 0xff TO SFBR WITH CARRY
1338 at 0x00000139 : */ 0x7712ff00,0x00000000,
1340 MOVE SFBR TO SCRATCH2
1342 at 0x0000013b : */ 0x6a360000,0x00000000,
1344 MOVE DSA3 + 0xff TO SFBR WITH CARRY
1346 at 0x0000013d : */ 0x7713ff00,0x00000000,
1348 MOVE SFBR TO SCRATCH3
1350 at 0x0000013f : */ 0x6a370000,0x00000000,
1354 MOVE MEMORY 4, addr_scratch, jump_dsa_save + 4
1356 at 0x00000141 : */ 0xc0000004,0x00000000,0x00000514,
1362 at 0x00000144 : */ 0x80080000,0x00000000,
1365 munge_restore_pointers:
1367 ; The code at dsa_restore_pointers will RETURN, but we don't care
1368 ; about TEMP here, as it will overwrite it anyway.
1370 MOVE DSA0 + dsa_restore_pointers TO SFBR
1372 at 0x00000146 : */ 0x76100000,0x00000000,
1374 MOVE SFBR TO SCRATCH0
1376 at 0x00000148 : */ 0x6a340000,0x00000000,
1378 MOVE DSA1 + 0xff TO SFBR WITH CARRY
1380 at 0x0000014a : */ 0x7711ff00,0x00000000,
1382 MOVE SFBR TO SCRATCH1
1384 at 0x0000014c : */ 0x6a350000,0x00000000,
1386 MOVE DSA2 + 0xff TO SFBR WITH CARRY
1388 at 0x0000014e : */ 0x7712ff00,0x00000000,
1390 MOVE SFBR TO SCRATCH2
1392 at 0x00000150 : */ 0x6a360000,0x00000000,
1394 MOVE DSA3 + 0xff TO SFBR WITH CARRY
1396 at 0x00000152 : */ 0x7713ff00,0x00000000,
1398 MOVE SFBR TO SCRATCH3
1400 at 0x00000154 : */ 0x6a370000,0x00000000,
1404 MOVE MEMORY 4, addr_scratch, jump_dsa_restore + 4
1406 at 0x00000156 : */ 0xc0000004,0x00000000,0x00000568,
1412 at 0x00000159 : */ 0x80080000,0x00000000,
1439 at 0x0000015b : */ 0x80080000,0x00000178,
1449 at 0x0000015d : */ 0x60000040,0x00000000,
1451 INT int_err_unexpected_phase, WHEN NOT MSG_IN
1453 at 0x0000015f : */ 0x9f030000,0x00000000,
1455 MOVE 1, msg_buf + 1, WHEN MSG_IN
1457 at 0x00000161 : */ 0x0f000001,0x00000001,
1459 JUMP munge_extended_2, IF 0x02
1461 at 0x00000163 : */ 0x800c0002,0x000005a4,
1463 JUMP munge_extended_3, IF 0x03
1465 at 0x00000165 : */ 0x800c0003,0x000005d4,
1469 at 0x00000167 : */ 0x80080000,0x00000604,
1475 at 0x00000169 : */ 0x60000040,0x00000000,
1477 MOVE 1, msg_buf + 2, WHEN MSG_IN
1479 at 0x0000016b : */ 0x0f000001,0x00000002,
1481 JUMP reject_message, IF NOT 0x02 ; Must be WDTR
1483 at 0x0000016d : */ 0x80040002,0x00000604,
1487 at 0x0000016f : */ 0x60000040,0x00000000,
1489 MOVE 1, msg_buf + 3, WHEN MSG_IN
1491 at 0x00000171 : */ 0x0f000001,0x00000003,
1495 at 0x00000173 : */ 0x98080000,0x01000000,
1501 at 0x00000175 : */ 0x60000040,0x00000000,
1503 MOVE 1, msg_buf + 2, WHEN MSG_IN
1505 at 0x00000177 : */ 0x0f000001,0x00000002,
1507 JUMP reject_message, IF NOT 0x01 ; Must be SDTR
1509 at 0x00000179 : */ 0x80040001,0x00000604,
1513 at 0x0000017b : */ 0x60000040,0x00000000,
1515 MOVE 2, msg_buf + 3, WHEN MSG_IN
1517 at 0x0000017d : */ 0x0f000002,0x00000003,
1521 at 0x0000017f : */ 0x98080000,0x01010000,
1524 ENTRY reject_message
1528 at 0x00000181 : */ 0x58000008,0x00000000,
1532 at 0x00000183 : */ 0x60000040,0x00000000,
1534 MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT
1536 at 0x00000185 : */ 0x0e000001,0x00000000,
1540 at 0x00000187 : */ 0x90080000,0x00000000,
1543 ENTRY accept_message
1547 at 0x00000189 : */ 0x60000008,0x00000000,
1551 at 0x0000018b : */ 0x60000040,0x00000000,
1555 at 0x0000018d : */ 0x90080000,0x00000000,
1558 ENTRY respond_message
1562 at 0x0000018f : */ 0x58000008,0x00000000,
1566 at 0x00000191 : */ 0x60000040,0x00000000,
1568 MOVE FROM dsa_msgout_other, WHEN MSG_OUT
1570 at 0x00000193 : */ 0x1e000000,0x00000068,
1574 at 0x00000195 : */ 0x90080000,0x00000000,
1580 ; PURPOSE : handle command termination when STATUS IN is detected by reading
1581 ; a status byte followed by a command termination message.
1583 ; Normal termination results in an INTFLY instruction, and
1584 ; the host system can pick out which command terminated by
1585 ; examining the MESSAGE and STATUS buffers of all currently
1586 ; executing commands;
1588 ; Abnormal (CHECK_CONDITION) termination results in an
1589 ; int_err_check_condition interrupt so that a REQUEST SENSE
1590 ; command can be issued out-of-order so that no other command
1591 ; clears the contingent allegiance condition.
1594 ; INPUTS : DSA - command
1598 ; EXITS : On successful termination, control is passed to schedule.
1599 ; On abnormal termination, the user will usually modify the
1600 ; DSA fields and corresponding buffers and return control
1604 ENTRY command_complete
1606 MOVE FROM dsa_status, WHEN STATUS
1608 at 0x00000197 : */ 0x1b000000,0x00000060,
1611 MOVE SFBR TO SCRATCH0 ; Save status
1613 at 0x00000199 : */ 0x6a340000,0x00000000,
1616 ENTRY command_complete_msgin
1617 command_complete_msgin:
1618 MOVE FROM dsa_msgin, WHEN MSG_IN
1620 at 0x0000019b : */ 0x1f000000,0x00000058,
1622 ; Indicate that we should be expecting a disconnect
1626 ; Above code cleared the Unexpected Disconnect bit, what do we do?
1630 at 0x0000019d : */ 0x60000040,0x00000000,
1635 at 0x0000019f : */ 0x48000000,0x00000000,
1639 ; The SCSI specification states that when a UNIT ATTENTION condition
1640 ; is pending, as indicated by a CHECK CONDITION status message,
1641 ; the target shall revert to asynchronous transfers. Since
1642 ; synchronous transfers parameters are maintained on a per INITIATOR/TARGET
1643 ; basis, and returning control to our scheduler could work on a command
1644 ; running on another lun on that target using the old parameters, we must
1645 ; interrupt the host processor to get them changed, or change them ourselves.
1647 ; Once SCSI-II tagged queueing is implemented, things will be even more
1648 ; hairy, since contingent allegiance conditions exist on a per-target/lun
1649 ; basis, and issuing a new command with a different tag would clear it.
1650 ; In these cases, we must interrupt the host processor to get a request
1651 ; added to the HEAD of the queue with the request sense command, or we
1652 ; must automatically issue the request sense command.
1660 INT int_norm_emulateintfly
1662 at 0x000001a1 : */ 0x98080000,0x02060000,
1670 ; Time to correct DSA following memory move
1671 MOVE MEMORY 4, saved_dsa, addr_dsa
1673 at 0x000001a3 : */ 0xc0000004,0x00000000,0x00000000,
1682 at 0x000001a6 : */ 0x80080000,0x00000000,
1685 INT int_err_check_condition
1687 at 0x000001a8 : */ 0x98080000,0x00030000,
1696 ; PURPOSE : This is essentially the idle routine, where control lands
1697 ; when there are no new processes to schedule. wait_reselect
1698 ; waits for reselection, selection, and new commands.
1700 ; When a successful reselection occurs, with the aid
1701 ; of fixed up code in each DSA, wait_reselect walks the
1702 ; reconnect_dsa_queue, asking each dsa if the target ID
1703 ; and LUN match its.
1705 ; If a match is found, a call is made back to reselected_ok,
1706 ; which through the miracles of self modifying code, extracts
1707 ; the found DSA from the reconnect_dsa_queue and then
1708 ; returns control to the DSAs thread of execution.
1716 ; EXITS : On successful reselection, control is returned to the
1717 ; DSA which called reselected_ok. If the WAIT RESELECT
1718 ; was interrupted by a new commands arrival signaled by
1719 ; SIG_P, control is passed to schedule. If the NCR is
1720 ; selected, the host system is interrupted with an
1721 ; int_err_selected which is usually responded to by
1722 ; setting DSP to the target_abort address.
1732 WAIT RESELECT wait_reselect_failed
1734 at 0x000001aa : */ 0x50000000,0x00000800,
1743 at 0x000001ac : */ 0x60000200,0x00000000,
1746 ; Read all data needed to reestablish the nexus -
1747 MOVE 1, reselected_identify, WHEN MSG_IN
1749 at 0x000001ae : */ 0x0f000001,0x00000000,
1751 ; We used to CLEAR ACK here.
1757 ; Point DSA at the current head of the disconnected queue.
1759 MOVE MEMORY 4, reconnect_dsa_head, addr_scratch
1761 at 0x000001b0 : */ 0xc0000004,0x00000000,0x00000000,
1765 MOVE MEMORY 4, addr_scratch, saved_dsa
1767 at 0x000001b3 : */ 0xc0000004,0x00000000,0x00000000,
1773 ; Fix the update-next pointer so that the reconnect_dsa_head
1774 ; pointer is the one that will be updated if this DSA is a hit
1775 ; and we remove it from the queue.
1777 MOVE MEMORY 4, addr_reconnect_dsa_head, reselected_ok_patch + 8
1779 at 0x000001b6 : */ 0xc0000004,0x00000000,0x000007ec,
1782 ; Time to correct DSA following memory move
1783 MOVE MEMORY 4, saved_dsa, addr_dsa
1785 at 0x000001b9 : */ 0xc0000004,0x00000000,0x00000000,
1789 ENTRY reselected_check_next
1790 reselected_check_next:
1794 ; Check for a NULL pointer.
1797 at 0x000001bc : */ 0x72100000,0x00000000,
1799 JUMP reselected_not_end, IF NOT 0
1801 at 0x000001be : */ 0x80040000,0x00000738,
1805 at 0x000001c0 : */ 0x72110000,0x00000000,
1807 JUMP reselected_not_end, IF NOT 0
1809 at 0x000001c2 : */ 0x80040000,0x00000738,
1813 at 0x000001c4 : */ 0x72120000,0x00000000,
1815 JUMP reselected_not_end, IF NOT 0
1817 at 0x000001c6 : */ 0x80040000,0x00000738,
1821 at 0x000001c8 : */ 0x72130000,0x00000000,
1823 JUMP reselected_not_end, IF NOT 0
1825 at 0x000001ca : */ 0x80040000,0x00000738,
1827 INT int_err_unexpected_reselect
1829 at 0x000001cc : */ 0x98080000,0x00020000,
1834 ; XXX the ALU is only eight bits wide, and the assembler
1835 ; wont do the dirt work for us. As long as dsa_check_reselect
1836 ; is negative, we need to sign extend with 1 bits to the full
1837 ; 32 bit width of the address.
1839 ; A potential work around would be to have a known alignment
1840 ; of the DSA structure such that the base address plus
1841 ; dsa_check_reselect doesn't require carrying from bytes
1842 ; higher than the LSB.
1847 at 0x000001ce : */ 0x72100000,0x00000000,
1849 MOVE SFBR + dsa_check_reselect TO SCRATCH0
1851 at 0x000001d0 : */ 0x6e340000,0x00000000,
1855 at 0x000001d2 : */ 0x72110000,0x00000000,
1857 MOVE SFBR + 0xff TO SCRATCH1 WITH CARRY
1859 at 0x000001d4 : */ 0x6f35ff00,0x00000000,
1863 at 0x000001d6 : */ 0x72120000,0x00000000,
1865 MOVE SFBR + 0xff TO SCRATCH2 WITH CARRY
1867 at 0x000001d8 : */ 0x6f36ff00,0x00000000,
1871 at 0x000001da : */ 0x72130000,0x00000000,
1873 MOVE SFBR + 0xff TO SCRATCH3 WITH CARRY
1875 at 0x000001dc : */ 0x6f37ff00,0x00000000,
1879 MOVE MEMORY 4, addr_scratch, reselected_check + 4
1881 at 0x000001de : */ 0xc0000004,0x00000000,0x00000794,
1885 ; Time to correct DSA following memory move
1886 MOVE MEMORY 4, saved_dsa, addr_dsa
1888 at 0x000001e1 : */ 0xc0000004,0x00000000,0x00000000,
1894 at 0x000001e4 : */ 0x80080000,0x00000000,
1901 ; We have problems here - the memory move corrupts TEMP and DSA. This
1902 ; routine is called from DSA code, and patched from many places. Scratch
1903 ; is probably free when it is called.
1905 ; copy temp to scratch, one byte at a time
1906 ; write scratch to patch a jump in place of the return
1907 ; do the move memory
1908 ; jump to the patched in return address
1909 ; DSA is corrupt when we get here, and can be left corrupt
1915 at 0x000001e6 : */ 0x721c0000,0x00000000,
1917 MOVE SFBR TO SCRATCH0
1919 at 0x000001e8 : */ 0x6a340000,0x00000000,
1923 at 0x000001ea : */ 0x721d0000,0x00000000,
1925 MOVE SFBR TO SCRATCH1
1927 at 0x000001ec : */ 0x6a350000,0x00000000,
1931 at 0x000001ee : */ 0x721e0000,0x00000000,
1933 MOVE SFBR TO SCRATCH2
1935 at 0x000001f0 : */ 0x6a360000,0x00000000,
1939 at 0x000001f2 : */ 0x721f0000,0x00000000,
1941 MOVE SFBR TO SCRATCH3
1943 at 0x000001f4 : */ 0x6a370000,0x00000000,
1945 MOVE MEMORY 4, addr_scratch, reselected_ok_jump + 4
1947 at 0x000001f6 : */ 0xc0000004,0x00000000,0x000007f4,
1949 reselected_ok_patch:
1952 at 0x000001f9 : */ 0xc0000004,0x00000000,0x00000000,
1957 at 0x000001fc : */ 0x80080000,0x00000000,
1965 INT int_err_selected;
1967 at 0x000001fe : */ 0x98080000,0x00010000,
1971 ; A select or reselect failure can be caused by one of two conditions :
1972 ; 1. SIG_P was set. This will be the case if the user has written
1973 ; a new value to a previously NULL head of the issue queue.
1975 ; 2. The NCR53c810 was selected or reselected by another device.
1977 ; 3. The bus was already busy since we were selected or reselected
1978 ; before starting the command.
1980 wait_reselect_failed:
1984 ; Check selected bit.
1986 ; Must work out how to tell if we are selected....
1991 ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
1992 MOVE CTEST2 & 0x40 TO SFBR
1994 at 0x00000200 : */ 0x74164000,0x00000000,
1996 JUMP schedule, IF 0x40
1998 at 0x00000202 : */ 0x800c0040,0x00000000,
2000 ; Check connected bit.
2001 ; FIXME: this needs to change if we support target mode
2002 MOVE ISTAT & 0x08 TO SFBR
2004 at 0x00000204 : */ 0x74210800,0x00000000,
2006 JUMP reselected, IF 0x08
2008 at 0x00000206 : */ 0x800c0008,0x000006b0,
2010 ; FIXME : Something bogus happened, and we shouldn't fail silently.
2016 at 0x00000208 : */ 0x98080000,0x030b0000,
2023 ; Disable selection timer
2024 MOVE CTEST7 | 0x10 TO CTEST7
2026 at 0x0000020a : */ 0x7a1b1000,0x00000000,
2032 ; Otherwise, mask the selected and reselected bits off SIST0
2034 ; Let's assume we don't get selected for now
2035 MOVE SSTAT0 & 0x10 TO SFBR
2037 at 0x0000020c : */ 0x740d1000,0x00000000,
2043 JUMP reselected, IF 0x10
2045 at 0x0000020e : */ 0x800c0010,0x000006b0,
2047 ; If SIGP is set, the user just gave us another command, and
2048 ; we should restart or return to the scheduler.
2049 ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
2050 MOVE CTEST2 & 0x40 TO SFBR
2052 at 0x00000210 : */ 0x74164000,0x00000000,
2054 JUMP select, IF 0x40
2056 at 0x00000212 : */ 0x800c0040,0x000001f8,
2058 ; Check connected bit.
2059 ; FIXME: this needs to change if we support target mode
2060 ; FIXME: is this really necessary?
2061 MOVE ISTAT & 0x08 TO SFBR
2063 at 0x00000214 : */ 0x74210800,0x00000000,
2065 JUMP reselected, IF 0x08
2067 at 0x00000216 : */ 0x800c0008,0x000006b0,
2069 ; FIXME : Something bogus happened, and we shouldn't fail silently.
2075 at 0x00000218 : */ 0x98080000,0x030b0000,
2083 ; PURPOSE : run some verification tests on the NCR. test_1
2084 ; copies test_src to test_dest and interrupts the host
2085 ; processor, testing for cache coherency and interrupt
2086 ; problems in the processes.
2088 ; test_2 runs a command with offsets relative to the
2089 ; DSA on entry, and is useful for miscellaneous experimentation.
2092 ; Verify that interrupts are working correctly and that we don't
2093 ; have a cache invalidation problem.
2095 ABSOLUTE test_src = 0, test_dest = 0
2098 MOVE MEMORY 4, test_src, test_dest
2100 at 0x0000021a : */ 0xc0000004,0x00000000,0x00000000,
2104 at 0x0000021d : */ 0x98080000,0x04000000,
2108 ; Run arbitrary commands, with test code establishing a DSA
2115 at 0x0000021f : */ 0x60000200,0x00000000,
2118 ; Enable selection timer
2122 MOVE CTEST7 & 0xef TO CTEST7
2124 at 0x00000221 : */ 0x7c1bef00,0x00000000,
2128 SELECT ATN FROM 0, test_2_fail
2130 at 0x00000223 : */ 0x43000000,0x000008dc,
2132 JUMP test_2_msgout, WHEN MSG_OUT
2134 at 0x00000225 : */ 0x860b0000,0x0000089c,
2139 ; Disable selection timer
2140 MOVE CTEST7 | 0x10 TO CTEST7
2142 at 0x00000227 : */ 0x7a1b1000,0x00000000,
2145 MOVE FROM 8, WHEN MSG_OUT
2147 at 0x00000229 : */ 0x1e000000,0x00000008,
2149 MOVE FROM 16, WHEN CMD
2151 at 0x0000022b : */ 0x1a000000,0x00000010,
2153 MOVE FROM 24, WHEN DATA_IN
2155 at 0x0000022d : */ 0x19000000,0x00000018,
2157 MOVE FROM 32, WHEN STATUS
2159 at 0x0000022f : */ 0x1b000000,0x00000020,
2161 MOVE FROM 40, WHEN MSG_IN
2163 at 0x00000231 : */ 0x1f000000,0x00000028,
2170 at 0x00000233 : */ 0x60000040,0x00000000,
2174 at 0x00000235 : */ 0x48000000,0x00000000,
2178 ; Disable selection timer
2179 MOVE CTEST7 | 0x10 TO CTEST7
2181 at 0x00000237 : */ 0x7a1b1000,0x00000000,
2186 at 0x00000239 : */ 0x98080000,0x04010000,
2193 at 0x0000023b : */ 0x98080000,0x03000000,
2200 ; PURPOSE : Abort the currently established nexus from with initiator
2209 at 0x0000023d : */ 0x58000200,0x00000000,
2213 at 0x0000023f : */ 0x48000000,0x00000000,
2217 at 0x00000241 : */ 0x60000200,0x00000000,
2221 at 0x00000243 : */ 0x80080000,0x00000000,
2224 ENTRY initiator_abort
2228 at 0x00000245 : */ 0x58000008,0x00000000,
2231 ; The SCSI-I specification says that targets may go into MSG out at
2232 ; their leisure upon receipt of the ATN single. On all versions of the
2233 ; specification, we can't change phases until REQ transitions true->false,
2234 ; so we need to sink/source one byte of data to allow the transition.
2236 ; For the sake of safety, we'll only source one byte of data in all
2237 ; cases, but to accommodate the SCSI-I dain bramage, we'll sink an
2238 ; arbitrary number of bytes.
2239 JUMP spew_cmd, WHEN CMD
2241 at 0x00000247 : */ 0x820b0000,0x0000094c,
2243 JUMP eat_msgin, WHEN MSG_IN
2245 at 0x00000249 : */ 0x870b0000,0x0000095c,
2247 JUMP eat_datain, WHEN DATA_IN
2249 at 0x0000024b : */ 0x810b0000,0x0000098c,
2251 JUMP eat_status, WHEN STATUS
2253 at 0x0000024d : */ 0x830b0000,0x00000974,
2255 JUMP spew_dataout, WHEN DATA_OUT
2257 at 0x0000024f : */ 0x800b0000,0x000009a4,
2261 at 0x00000251 : */ 0x80080000,0x000009ac,
2264 MOVE 1, NCR53c7xx_zero, WHEN CMD
2266 at 0x00000253 : */ 0x0a000001,0x00000000,
2270 at 0x00000255 : */ 0x80080000,0x000009ac,
2273 MOVE 1, NCR53c7xx_sink, WHEN MSG_IN
2275 at 0x00000257 : */ 0x0f000001,0x00000000,
2277 JUMP eat_msgin, WHEN MSG_IN
2279 at 0x00000259 : */ 0x870b0000,0x0000095c,
2283 at 0x0000025b : */ 0x80080000,0x000009ac,
2286 MOVE 1, NCR53c7xx_sink, WHEN STATUS
2288 at 0x0000025d : */ 0x0b000001,0x00000000,
2290 JUMP eat_status, WHEN STATUS
2292 at 0x0000025f : */ 0x830b0000,0x00000974,
2296 at 0x00000261 : */ 0x80080000,0x000009ac,
2299 MOVE 1, NCR53c7xx_sink, WHEN DATA_IN
2301 at 0x00000263 : */ 0x09000001,0x00000000,
2303 JUMP eat_datain, WHEN DATA_IN
2305 at 0x00000265 : */ 0x810b0000,0x0000098c,
2309 at 0x00000267 : */ 0x80080000,0x000009ac,
2312 MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT
2314 at 0x00000269 : */ 0x08000001,0x00000000,
2320 MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
2322 at 0x0000026b : */ 0x0e000001,0x00000000,
2326 at 0x0000026d : */ 0x48000000,0x00000000,
2328 INT int_norm_aborted
2330 at 0x0000026f : */ 0x98080000,0x02040000,
2336 ; Little patched jump, used to overcome problems with TEMP getting
2337 ; corrupted on memory moves.
2342 at 0x00000271 : */ 0x80080000,0x00000000,
2345 #define A_NCR53c7xx_msg_abort 0x00000000
2346 static u32 A_NCR53c7xx_msg_abort_used[] __attribute((unused)) = {
2350 #define A_NCR53c7xx_msg_reject 0x00000000
2351 static u32 A_NCR53c7xx_msg_reject_used[] __attribute((unused)) = {
2355 #define A_NCR53c7xx_sink 0x00000000
2356 static u32 A_NCR53c7xx_sink_used[] __attribute((unused)) = {
2362 #define A_NCR53c7xx_zero 0x00000000
2363 static u32 A_NCR53c7xx_zero_used[] __attribute((unused)) = {
2368 #define A_NOP_insn 0x00000000
2369 static u32 A_NOP_insn_used[] __attribute((unused)) = {
2373 #define A_addr_dsa 0x00000000
2374 static u32 A_addr_dsa_used[] __attribute((unused)) = {
2390 #define A_addr_reconnect_dsa_head 0x00000000
2391 static u32 A_addr_reconnect_dsa_head_used[] __attribute((unused)) = {
2395 #define A_addr_scratch 0x00000000
2396 static u32 A_addr_scratch_used[] __attribute((unused)) = {
2420 #define A_addr_temp 0x00000000
2421 static u32 A_addr_temp_used[] __attribute((unused)) = {
2424 #define A_dmode_memory_to_memory 0x00000000
2425 static u32 A_dmode_memory_to_memory_used[] __attribute((unused)) = {
2428 #define A_dmode_memory_to_ncr 0x00000000
2429 static u32 A_dmode_memory_to_ncr_used[] __attribute((unused)) = {
2432 #define A_dmode_ncr_to_memory 0x00000000
2433 static u32 A_dmode_ncr_to_memory_used[] __attribute((unused)) = {
2436 #define A_dsa_check_reselect 0x00000000
2437 static u32 A_dsa_check_reselect_used[] __attribute((unused)) = {
2441 #define A_dsa_cmdout 0x00000048
2442 static u32 A_dsa_cmdout_used[] __attribute((unused)) = {
2446 #define A_dsa_cmnd 0x00000038
2447 static u32 A_dsa_cmnd_used[] __attribute((unused)) = {
2450 #define A_dsa_datain 0x00000054
2451 static u32 A_dsa_datain_used[] __attribute((unused)) = {
2455 #define A_dsa_dataout 0x00000050
2456 static u32 A_dsa_dataout_used[] __attribute((unused)) = {
2460 #define A_dsa_end 0x00000070
2461 static u32 A_dsa_end_used[] __attribute((unused)) = {
2464 #define A_dsa_fields_start 0x00000000
2465 static u32 A_dsa_fields_start_used[] __attribute((unused)) = {
2468 #define A_dsa_msgin 0x00000058
2469 static u32 A_dsa_msgin_used[] __attribute((unused)) = {
2473 #define A_dsa_msgout 0x00000040
2474 static u32 A_dsa_msgout_used[] __attribute((unused)) = {
2478 #define A_dsa_msgout_other 0x00000068
2479 static u32 A_dsa_msgout_other_used[] __attribute((unused)) = {
2483 #define A_dsa_next 0x00000030
2484 static u32 A_dsa_next_used[] __attribute((unused)) = {
2488 #define A_dsa_restore_pointers 0x00000000
2489 static u32 A_dsa_restore_pointers_used[] __attribute((unused)) = {
2493 #define A_dsa_save_data_pointer 0x00000000
2494 static u32 A_dsa_save_data_pointer_used[] __attribute((unused)) = {
2498 #define A_dsa_select 0x0000003c
2499 static u32 A_dsa_select_used[] __attribute((unused)) = {
2503 #define A_dsa_sscf_710 0x00000000
2504 static u32 A_dsa_sscf_710_used[] __attribute((unused)) = {
2508 #define A_dsa_status 0x00000060
2509 static u32 A_dsa_status_used[] __attribute((unused)) = {
2513 #define A_dsa_temp_addr_array_value 0x00000000
2514 static u32 A_dsa_temp_addr_array_value_used[] __attribute((unused)) = {
2517 #define A_dsa_temp_addr_dsa_value 0x00000000
2518 static u32 A_dsa_temp_addr_dsa_value_used[] __attribute((unused)) = {
2522 #define A_dsa_temp_addr_new_value 0x00000000
2523 static u32 A_dsa_temp_addr_new_value_used[] __attribute((unused)) = {
2526 #define A_dsa_temp_addr_next 0x00000000
2527 static u32 A_dsa_temp_addr_next_used[] __attribute((unused)) = {
2532 #define A_dsa_temp_addr_residual 0x00000000
2533 static u32 A_dsa_temp_addr_residual_used[] __attribute((unused)) = {
2538 #define A_dsa_temp_addr_saved_pointer 0x00000000
2539 static u32 A_dsa_temp_addr_saved_pointer_used[] __attribute((unused)) = {
2544 #define A_dsa_temp_addr_saved_residual 0x00000000
2545 static u32 A_dsa_temp_addr_saved_residual_used[] __attribute((unused)) = {
2550 #define A_dsa_temp_lun 0x00000000
2551 static u32 A_dsa_temp_lun_used[] __attribute((unused)) = {
2555 #define A_dsa_temp_next 0x00000000
2556 static u32 A_dsa_temp_next_used[] __attribute((unused)) = {
2560 #define A_dsa_temp_sync 0x00000000
2561 static u32 A_dsa_temp_sync_used[] __attribute((unused)) = {
2565 #define A_dsa_temp_target 0x00000000
2566 static u32 A_dsa_temp_target_used[] __attribute((unused)) = {
2570 #define A_emulfly 0x00000000
2571 static u32 A_emulfly_used[] __attribute((unused)) = {
2574 #define A_int_debug_break 0x03000000
2575 static u32 A_int_debug_break_used[] __attribute((unused)) = {
2579 #define A_int_debug_panic 0x030b0000
2580 static u32 A_int_debug_panic_used[] __attribute((unused)) = {
2585 #define A_int_err_check_condition 0x00030000
2586 static u32 A_int_err_check_condition_used[] __attribute((unused)) = {
2590 #define A_int_err_no_phase 0x00040000
2591 static u32 A_int_err_no_phase_used[] __attribute((unused)) = {
2594 #define A_int_err_selected 0x00010000
2595 static u32 A_int_err_selected_used[] __attribute((unused)) = {
2599 #define A_int_err_unexpected_phase 0x00000000
2600 static u32 A_int_err_unexpected_phase_used[] __attribute((unused)) = {
2617 #define A_int_err_unexpected_reselect 0x00020000
2618 static u32 A_int_err_unexpected_reselect_used[] __attribute((unused)) = {
2622 #define A_int_msg_1 0x01020000
2623 static u32 A_int_msg_1_used[] __attribute((unused)) = {
2628 #define A_int_msg_sdtr 0x01010000
2629 static u32 A_int_msg_sdtr_used[] __attribute((unused)) = {
2633 #define A_int_msg_wdtr 0x01000000
2634 static u32 A_int_msg_wdtr_used[] __attribute((unused)) = {
2638 #define A_int_norm_aborted 0x02040000
2639 static u32 A_int_norm_aborted_used[] __attribute((unused)) = {
2643 #define A_int_norm_command_complete 0x02020000
2644 static u32 A_int_norm_command_complete_used[] __attribute((unused)) = {
2647 #define A_int_norm_disconnected 0x02030000
2648 static u32 A_int_norm_disconnected_used[] __attribute((unused)) = {
2651 #define A_int_norm_emulateintfly 0x02060000
2652 static u32 A_int_norm_emulateintfly_used[] __attribute((unused)) = {
2656 #define A_int_norm_reselect_complete 0x02010000
2657 static u32 A_int_norm_reselect_complete_used[] __attribute((unused)) = {
2660 #define A_int_norm_reset 0x02050000
2661 static u32 A_int_norm_reset_used[] __attribute((unused)) = {
2664 #define A_int_norm_select_complete 0x02000000
2665 static u32 A_int_norm_select_complete_used[] __attribute((unused)) = {
2668 #define A_int_test_1 0x04000000
2669 static u32 A_int_test_1_used[] __attribute((unused)) = {
2673 #define A_int_test_2 0x04010000
2674 static u32 A_int_test_2_used[] __attribute((unused)) = {
2678 #define A_int_test_3 0x04020000
2679 static u32 A_int_test_3_used[] __attribute((unused)) = {
2682 #define A_msg_buf 0x00000000
2683 static u32 A_msg_buf_used[] __attribute((unused)) = {
2692 #define A_reconnect_dsa_head 0x00000000
2693 static u32 A_reconnect_dsa_head_used[] __attribute((unused)) = {
2699 #define A_reselected_identify 0x00000000
2700 static u32 A_reselected_identify_used[] __attribute((unused)) = {
2705 #define A_reselected_tag 0x00000000
2706 static u32 A_reselected_tag_used[] __attribute((unused)) = {
2709 #define A_saved_dsa 0x00000000
2710 static u32 A_saved_dsa_used[] __attribute((unused)) = {
2733 #define A_schedule 0x00000000
2734 static u32 A_schedule_used[] __attribute((unused)) = {
2741 #define A_test_dest 0x00000000
2742 static u32 A_test_dest_used[] __attribute((unused)) = {
2746 #define A_test_src 0x00000000
2747 static u32 A_test_src_used[] __attribute((unused)) = {
2751 #define Ent_accept_message 0x00000624
2752 #define Ent_cmdout_cmdout 0x00000264
2753 #define Ent_command_complete 0x0000065c
2754 #define Ent_command_complete_msgin 0x0000066c
2755 #define Ent_data_transfer 0x0000026c
2756 #define Ent_datain_to_jump 0x00000334
2757 #define Ent_debug_break 0x000008ec
2758 #define Ent_dsa_code_begin 0x00000000
2759 #define Ent_dsa_code_check_reselect 0x0000010c
2760 #define Ent_dsa_code_fix_jump 0x00000058
2761 #define Ent_dsa_code_restore_pointers 0x000000d8
2762 #define Ent_dsa_code_save_data_pointer 0x000000a4
2763 #define Ent_dsa_code_template 0x00000000
2764 #define Ent_dsa_code_template_end 0x00000178
2765 #define Ent_dsa_schedule 0x00000178
2766 #define Ent_dsa_zero 0x00000178
2767 #define Ent_end_data_transfer 0x000002a4
2768 #define Ent_initiator_abort 0x00000914
2769 #define Ent_msg_in 0x0000041c
2770 #define Ent_msg_in_restart 0x000003fc
2771 #define Ent_other_in 0x0000038c
2772 #define Ent_other_out 0x00000354
2773 #define Ent_other_transfer 0x000003c4
2774 #define Ent_reject_message 0x00000604
2775 #define Ent_reselected_check_next 0x000006f0
2776 #define Ent_reselected_ok 0x00000798
2777 #define Ent_respond_message 0x0000063c
2778 #define Ent_select 0x000001f8
2779 #define Ent_select_msgout 0x00000218
2780 #define Ent_target_abort 0x000008f4
2781 #define Ent_test_1 0x00000868
2782 #define Ent_test_2 0x0000087c
2783 #define Ent_test_2_msgout 0x0000089c
2784 #define Ent_wait_reselect 0x000006a8
2785 static u32 LABELPATCHES[] __attribute((unused)) = {
2869 } EXTERNAL_PATCHES[] __attribute((unused)) = {
2872 static u32 INSTRUCTIONS __attribute((unused)) = 290;
2873 static u32 PATCHES __attribute((unused)) = 78;
2874 static u32 EXTERNAL_PATCHES_LEN __attribute((unused)) = 0;