Merge master.kernel.org:/home/rmk/linux-2.6-arm-smp
[linux-2.6] / drivers / scsi / 53c7xx_d.h_shipped
1 /* DO NOT EDIT - Generated automatically by script_asm.pl */
2 static u32 SCRIPT[] = {
3 /*
4
5
6
7
8
9 ; 53c710 driver.  Modified from Drew Eckhardts driver
10 ; for 53c810 by Richard Hirst [richard@sleepie.demon.co.uk]
11 ;
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.
14
15 ; NCR 53c810 driver, main script
16 ; Sponsored by 
17 ;       iX Multiuser Multitasking Magazine
18 ;       hm@ix.de
19 ;
20 ; Copyright 1993, 1994, 1995 Drew Eckhardt
21 ;      Visionary Computing 
22 ;      (Unix and Linux consulting and custom programming)
23 ;      drew@PoohSticks.ORG
24 ;      +1 (303) 786-7975
25 ;
26 ; TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
27 ;
28 ; PRE-ALPHA
29 ;
30 ; For more information, please consult 
31 ;
32 ; NCR 53C810
33 ; PCI-SCSI I/O Processor
34 ; Data Manual
35 ;
36 ; NCR 53C710 
37 ; SCSI I/O Processor
38 ; Programmers Guide
39 ;
40 ; NCR Microelectronics
41 ; 1635 Aeroplaza Drive
42 ; Colorado Springs, CO 80916
43 ; 1+ (719) 578-3400
44 ;
45 ; Toll free literature number
46 ; +1 (800) 334-5454
47 ;
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.
52 ;
53 ; Design:
54 ; The NCR53c7,8xx family of SCSI chips are busmasters with an onboard 
55 ; microcontroller using a simple instruction set.   
56 ;
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
60 ; structure.
61 ;
62 ; Where tradeoffs were needed between efficiency on the older
63 ; chips and the newer NCR53c800 series, the NCR53c800 series 
64 ; was chosen.
65 ;
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 
69 ;
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.
74
75 ; - table indirect addressing for some instructions. This allows 
76 ;       pointers to be located relative to the DSA ((Data Structure
77 ;       Address) register.
78 ;
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.
84 ;
85 ; - Mailboxes are a mixture of code and data.  This lets us greatly
86 ;       simplify the NCR53c810 code and do things that would otherwise
87 ;       not be possible.
88 ;
89 ; The saved data pointer is now implemented as follows :
90 ;
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.
95 ;
96
97 ;
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
101 ; NCR registers.
102 ;
103
104 ; For some systems (MVME166, for example) dmode is always the same, so don't
105 ; waste time writing it
106
107
108
109
110
111
112
113
114
115
116
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 
120                                         ;       for current dsa
121 ABSOLUTE dsa_temp_sync = 0              ; Patch to address of per-target
122                                         ;       sync routine
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
127                                         ;       saved data pointer
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
135
136 ;
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
142 ; pointer.
143
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.
149 ;
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.
157 ;
158 ; Perhaps more concisely, the net effect of the mess is 
159 ;
160 ; for (dsa = reconnect_dsa_head, dest = &reconnect_dsa_head, 
161 ;     src = NULL; dsa; dest = &dsa->next, dsa = dsa->next) {
162 ;       src = &dsa->next;
163 ;       if (target_id == dsa->id && target_lun == dsa->lun) {
164 ;               *dest = *src;
165 ;               break;
166 ;         }     
167 ; }
168 ;
169 ; if (!dsa)
170 ;           error (int_err_unexpected_reselect);
171 ; else  
172 ;     longjmp (dsa->jump_resume, 0);
173 ;
174 ;       
175
176
177 ; Define DSA structure used for mailboxes
178 ENTRY dsa_code_template
179 dsa_code_template:
180 ENTRY dsa_code_begin
181 dsa_code_begin:
182 ; RGH: Don't care about TEMP and DSA here
183         
184         MOVE MEMORY 4, dsa_temp_addr_dsa_value, addr_scratch
185
186 at 0x00000000 : */      0xc0000004,0x00000000,0x00000000,
187 /*
188         
189
190         MOVE MEMORY 4, addr_scratch, saved_dsa
191
192 at 0x00000003 : */      0xc0000004,0x00000000,0x00000000,
193 /*
194         ; We are about to go and select the device, so must set SSCF bits
195         MOVE MEMORY 4, dsa_sscf_710, addr_scratch
196
197 at 0x00000006 : */      0xc0000004,0x00000000,0x00000000,
198 /*
199
200         MOVE SCRATCH3 TO SFBR
201
202 at 0x00000009 : */      0x72370000,0x00000000,
203 /*
204
205
206
207         MOVE SFBR TO SBCL
208
209 at 0x0000000b : */      0x6a0b0000,0x00000000,
210 /*
211         MOVE MEMORY 4, saved_dsa, addr_dsa
212
213 at 0x0000000d : */      0xc0000004,0x00000000,0x00000000,
214 /*
215
216
217
218         CALL select
219
220 at 0x00000010 : */      0x88080000,0x000001f8,
221 /*
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.
226     CLEAR ATN
227
228 at 0x00000012 : */      0x60000008,0x00000000,
229 /*
230     CLEAR ACK
231
232 at 0x00000014 : */      0x60000040,0x00000000,
233 /*
234
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
238 dsa_code_fix_jump:
239         MOVE MEMORY 4, NOP_insn, 0
240
241 at 0x00000016 : */      0xc0000004,0x00000000,0x00000000,
242 /*
243         JUMP select_done
244
245 at 0x00000019 : */      0x80080000,0x00000230,
246 /*
247
248 ; wrong_dsa loads the DSA register with the value of the dsa_next
249 ; field.
250 ;
251 wrong_dsa:
252
253 ;                NOTE DSA is corrupt when we arrive here!
254
255 ;               Patch the MOVE MEMORY INSTRUCTION such that 
256 ;               the destination address is the address of the OLD 
257 ;               next pointer.
258 ;
259         MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok_patch + 8
260
261 at 0x0000001b : */      0xc0000004,0x00000000,0x000007ec,
262 /*
263         
264 ;
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
267 ;       nexus.
268 ;
269         MOVE MEMORY 4, dsa_temp_next, addr_scratch
270
271 at 0x0000001e : */      0xc0000004,0x00000000,0x00000000,
272 /*
273         
274
275         MOVE MEMORY 4, addr_scratch, saved_dsa
276
277 at 0x00000021 : */      0xc0000004,0x00000000,0x00000000,
278 /*
279         MOVE MEMORY 4, saved_dsa, addr_dsa
280
281 at 0x00000024 : */      0xc0000004,0x00000000,0x00000000,
282 /*
283
284
285
286         JUMP reselected_check_next
287
288 at 0x00000027 : */      0x80080000,0x000006f0,
289 /*
290
291 ABSOLUTE dsa_save_data_pointer = 0
292 ENTRY dsa_code_save_data_pointer
293 dsa_code_save_data_pointer:
294
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
298
299 at 0x00000029 : */      0xc0000004,0x000009c8,0x00000000,
300 /*
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
303
304 at 0x0000002c : */      0xc0000018,0x00000000,0x00000000,
305 /*
306         CLEAR ACK
307
308 at 0x0000002f : */      0x60000040,0x00000000,
309 /*
310
311
312
313         MOVE MEMORY 4, saved_dsa, addr_dsa
314
315 at 0x00000031 : */      0xc0000004,0x00000000,0x00000000,
316 /*
317         JUMP jump_temp
318
319 at 0x00000034 : */      0x80080000,0x000009c4,
320 /*
321
322 ABSOLUTE dsa_restore_pointers = 0
323 ENTRY dsa_code_restore_pointers
324 dsa_code_restore_pointers:
325
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
328
329 at 0x00000036 : */      0xc0000004,0x00000000,0x000009c8,
330 /*
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
333
334 at 0x00000039 : */      0xc0000018,0x00000000,0x00000000,
335 /*
336         CLEAR ACK
337
338 at 0x0000003c : */      0x60000040,0x00000000,
339 /*
340         ; Restore DSA, note we don't care about TEMP
341         MOVE MEMORY 4, saved_dsa, addr_dsa
342
343 at 0x0000003e : */      0xc0000004,0x00000000,0x00000000,
344 /*
345
346
347
348         JUMP jump_temp
349
350 at 0x00000041 : */      0x80080000,0x000009c4,
351 /*
352
353
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:
359
360         
361         
362         MOVE LCRC TO SFBR               ; LCRC has our ID and his ID bits set
363
364 at 0x00000043 : */      0x72230000,0x00000000,
365 /*
366         JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 0x80
367
368 at 0x00000045 : */      0x80848000,0x00ffff50,
369 /*
370
371
372
373
374
375 ;
376 ; Hack - move to scratch first, since SFBR is not writeable
377 ;       via the CPU and hence a MOVE MEMORY instruction.
378 ;
379         
380         MOVE MEMORY 1, reselected_identify, addr_scratch
381
382 at 0x00000047 : */      0xc0000001,0x00000000,0x00000000,
383 /*
384         
385
386         ; BIG ENDIAN ON MVME16x
387         MOVE SCRATCH3 TO SFBR
388
389 at 0x0000004a : */      0x72370000,0x00000000,
390 /*
391
392
393
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
397
398 at 0x0000004c : */      0x8084f800,0x00ffff34,
399 /*
400 ;               Patch the MOVE MEMORY INSTRUCTION such that
401 ;               the source address is the address of this dsa's
402 ;               next pointer.
403         MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok_patch + 4
404
405 at 0x0000004e : */      0xc0000004,0x00000000,0x000007e8,
406 /*
407         CALL reselected_ok
408
409 at 0x00000051 : */      0x88080000,0x00000798,
410 /*
411
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
416
417 at 0x00000053 : */      0xc0000004,0x00000000,0x00000000,
418 /*
419
420         CALL dsa_temp_sync      
421
422 at 0x00000056 : */      0x88080000,0x00000000,
423 /*
424 ; Release ACK on the IDENTIFY message _after_ we've set the synchronous 
425 ; transfer parameters! 
426         CLEAR ACK
427
428 at 0x00000058 : */      0x60000040,0x00000000,
429 /*
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)
433
434 at 0x0000005a : */      0x88880000,0x00ffff68,
435 /*
436         RETURN
437
438 at 0x0000005c : */      0x90080000,0x00000000,
439 /*
440 ENTRY dsa_zero
441 dsa_zero:
442 ENTRY dsa_code_template_end
443 dsa_code_template_end:
444
445 ; Perform sanity check for dsa_fields_start == dsa_code_template_end - 
446 ; dsa_zero, puke.
447
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 
456                                 ;       select message
457 ABSOLUTE dsa_cmdout = 72        ; len 8 table indirect move parameter for 
458                                 ;       command
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
466
467 ABSOLUTE schedule = 0           ; Array of JUMP dsa_begin or JUMP (next),
468                                 ; terminated by a call to JUMP wait_reselect
469
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
474
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
479
480 ABSOLUTE addr_scratch = 0x0
481 ABSOLUTE addr_temp = 0x0
482
483 ABSOLUTE saved_dsa = 0x0
484 ABSOLUTE emulfly = 0x0
485 ABSOLUTE addr_dsa = 0x0
486
487
488
489 ; Interrupts - 
490 ; MSB indicates type
491 ; 0     handle error condition
492 ; 1     handle message 
493 ; 2     handle normal condition
494 ; 3     debugging interrupt
495 ; 4     testing interrupt 
496 ; Next byte indicates specific error
497
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
501  
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
510                                                 ; received
511
512 ABSOLUTE int_norm_select_complete = 0x02000000  ; Select complete, reprogram
513                                                 ; registers.
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
521
522 ABSOLUTE int_debug_panic = 0x030b0000           ; Panic driver
523
524
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
528
529
530 ; These should start with 0x05000000, with low bits incrementing for 
531 ; each one.
532
533
534                                                 
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
540
541 ; Pointer to message, potentially multi-byte
542 ABSOLUTE msg_buf = 0
543
544 ; Pointer to holding area for reselection information
545 ABSOLUTE reselected_identify = 0
546 ABSOLUTE reselected_tag = 0
547
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
553
554
555 ; dsa_schedule  
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.
559 ;
560 ; CALLS : OK
561 ;
562 ; INPUTS : dsa - current DSA structure, reconnect_dsa_head - list
563 ;       of disconnected commands
564 ;
565 ; MODIFIES : SCRATCH, reconnect_dsa_head
566
567 ; EXITS : always passes control to schedule
568
569 ENTRY dsa_schedule
570 dsa_schedule:
571
572
573
574
575 ;
576 ; Calculate the address of the next pointer within the DSA 
577 ; structure of the command that is currently disconnecting
578 ;
579
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
583
584 at 0x0000005e : */      0xc0000004,0x00000000,0x00000000,
585 /*
586
587
588
589     MOVE SCRATCH0 + dsa_next TO SCRATCH0
590
591 at 0x00000061 : */      0x7e343000,0x00000000,
592 /*
593     MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
594
595 at 0x00000063 : */      0x7f350000,0x00000000,
596 /*
597     MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
598
599 at 0x00000065 : */      0x7f360000,0x00000000,
600 /*
601     MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
602
603 at 0x00000067 : */      0x7f370000,0x00000000,
604 /*
605
606 ; Point the next field of this DSA structure at the current disconnected 
607 ; list
608     
609     MOVE MEMORY 4, addr_scratch, dsa_schedule_insert + 8
610
611 at 0x00000069 : */      0xc0000004,0x00000000,0x000001b8,
612 /*
613     
614 dsa_schedule_insert:
615     MOVE MEMORY 4, reconnect_dsa_head, 0 
616
617 at 0x0000006c : */      0xc0000004,0x00000000,0x00000000,
618 /*
619
620 ; And update the head pointer.
621
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
625
626 at 0x0000006f : */      0xc0000004,0x00000000,0x00000000,
627 /*
628
629
630
631     
632     MOVE MEMORY 4, addr_scratch, reconnect_dsa_head
633
634 at 0x00000072 : */      0xc0000004,0x00000000,0x00000000,
635 /*
636     
637
638
639
640
641
642     CLEAR ACK
643
644 at 0x00000075 : */      0x60000040,0x00000000,
645 /*
646
647
648     ; Time to correct DSA following memory move
649     MOVE MEMORY 4, saved_dsa, addr_dsa
650
651 at 0x00000077 : */      0xc0000004,0x00000000,0x00000000,
652 /*
653
654     WAIT DISCONNECT
655
656 at 0x0000007a : */      0x48000000,0x00000000,
657 /*
658
659
660
661
662
663
664     JUMP schedule
665
666 at 0x0000007c : */      0x80080000,0x00000000,
667 /*
668
669
670 ;
671 ; select
672 ;
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
680 ;       is handled.
681 ;
682 ; INPUTS : DSA - SCSI command, issue_dsa_head
683 ;
684 ; CALLS : NOT OK
685 ;
686 ; MODIFIES : SCRATCH, issue_dsa_head
687 ;
688 ; EXITS : on reselection or selection, go to select_failed
689 ;       otherwise, RETURN so control is passed back to 
690 ;       dsa_begin.
691 ;
692
693 ENTRY select
694 select:
695
696
697
698
699
700
701
702
703     CLEAR TARGET
704
705 at 0x0000007e : */      0x60000200,0x00000000,
706 /*
707
708 ; XXX
709 ;
710 ; In effect, SELECTION operations are backgrounded, with execution
711 ; continuing until code which waits for REQ or a fatal interrupt is 
712 ; encountered.
713 ;
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.
717 ;
718
719
720
721     ; Enable selection timer
722
723
724
725     MOVE CTEST7 & 0xef TO CTEST7
726
727 at 0x00000080 : */      0x7c1bef00,0x00000000,
728 /*
729
730
731     SELECT ATN FROM dsa_select, select_failed
732
733 at 0x00000082 : */      0x4300003c,0x00000828,
734 /*
735     JUMP select_msgout, WHEN MSG_OUT
736
737 at 0x00000084 : */      0x860b0000,0x00000218,
738 /*
739 ENTRY select_msgout
740 select_msgout:
741
742     ; Disable selection timer
743     MOVE CTEST7 | 0x10 TO CTEST7
744
745 at 0x00000086 : */      0x7a1b1000,0x00000000,
746 /*
747
748     MOVE FROM dsa_msgout, WHEN MSG_OUT
749
750 at 0x00000088 : */      0x1e000000,0x00000040,
751 /*
752
753
754
755
756
757
758
759
760
761
762    RETURN
763
764 at 0x0000008a : */      0x90080000,0x00000000,
765 /*
766
767
768 ; select_done
769
770 ; PURPOSE: continue on to normal data transfer; called as the exit 
771 ;       point from dsa_begin.
772 ;
773 ; INPUTS: dsa
774 ;
775 ; CALLS: OK
776 ;
777 ;
778
779 select_done:
780
781 ; NOTE DSA is corrupt when we arrive here!
782     MOVE MEMORY 4, saved_dsa, addr_dsa
783
784 at 0x0000008c : */      0xc0000004,0x00000000,0x00000000,
785 /*
786
787
788
789
790
791
792
793
794 ; After a successful selection, we should get either a CMD phase or 
795 ; some transfer request negotiation message.
796
797     JUMP cmdout, WHEN CMD
798
799 at 0x0000008f : */      0x820b0000,0x0000025c,
800 /*
801     INT int_err_unexpected_phase, WHEN NOT MSG_IN 
802
803 at 0x00000091 : */      0x9f030000,0x00000000,
804 /*
805
806 select_msg_in:
807     CALL msg_in, WHEN MSG_IN
808
809 at 0x00000093 : */      0x8f0b0000,0x0000041c,
810 /*
811     JUMP select_msg_in, WHEN MSG_IN
812
813 at 0x00000095 : */      0x870b0000,0x0000024c,
814 /*
815
816 cmdout:
817     INT int_err_unexpected_phase, WHEN NOT CMD
818
819 at 0x00000097 : */      0x9a030000,0x00000000,
820 /*
821
822
823
824 ENTRY cmdout_cmdout
825 cmdout_cmdout:
826
827     MOVE FROM dsa_cmdout, WHEN CMD
828
829 at 0x00000099 : */      0x1a000000,0x00000048,
830 /*
831
832
833
834
835 ;
836 ; data_transfer  
837 ; other_out
838 ; other_in
839 ; other_transfer
840 ;
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 
846 ;       phases.
847 ;
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.
853 ;
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.
857 ;
858 ; INPUTS : DSA - SCSI command
859 ;
860 ; CALLS : OK in data_transfer_start, not ok in other_out and other_in, ok in
861 ;       other_transfer
862 ;
863 ; MODIFIES : SCRATCH
864 ;
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 
868 ;       an infinite loop.
869 ;       
870
871 ENTRY data_transfer
872 data_transfer:
873     JUMP cmdout_cmdout, WHEN CMD
874
875 at 0x0000009b : */      0x820b0000,0x00000264,
876 /*
877     CALL msg_in, WHEN MSG_IN
878
879 at 0x0000009d : */      0x8f0b0000,0x0000041c,
880 /*
881     INT int_err_unexpected_phase, WHEN MSG_OUT
882
883 at 0x0000009f : */      0x9e0b0000,0x00000000,
884 /*
885     JUMP do_dataout, WHEN DATA_OUT
886
887 at 0x000000a1 : */      0x800b0000,0x000002a4,
888 /*
889     JUMP do_datain, WHEN DATA_IN
890
891 at 0x000000a3 : */      0x810b0000,0x000002fc,
892 /*
893     JUMP command_complete, WHEN STATUS
894
895 at 0x000000a5 : */      0x830b0000,0x0000065c,
896 /*
897     JUMP data_transfer
898
899 at 0x000000a7 : */      0x80080000,0x0000026c,
900 /*
901 ENTRY end_data_transfer
902 end_data_transfer:
903
904 ;
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.
908 ;
909
910
911 ; Nasty jump to dsa->dataout
912 do_dataout:
913
914     MOVE MEMORY 4, saved_dsa, addr_scratch
915
916 at 0x000000a9 : */      0xc0000004,0x00000000,0x00000000,
917 /*
918
919
920
921     MOVE SCRATCH0 + dsa_dataout TO SCRATCH0     
922
923 at 0x000000ac : */      0x7e345000,0x00000000,
924 /*
925     MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY 
926
927 at 0x000000ae : */      0x7f350000,0x00000000,
928 /*
929     MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY 
930
931 at 0x000000b0 : */      0x7f360000,0x00000000,
932 /*
933     MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY 
934
935 at 0x000000b2 : */      0x7f370000,0x00000000,
936 /*
937     
938     MOVE MEMORY 4, addr_scratch, dataout_to_jump + 4
939
940 at 0x000000b4 : */      0xc0000004,0x00000000,0x000002e0,
941 /*
942     
943 dataout_to_jump:
944     MOVE MEMORY 4, 0, dataout_jump + 4 
945
946 at 0x000000b7 : */      0xc0000004,0x00000000,0x000002f8,
947 /*
948
949     ; Time to correct DSA following memory move
950     MOVE MEMORY 4, saved_dsa, addr_dsa
951
952 at 0x000000ba : */      0xc0000004,0x00000000,0x00000000,
953 /*
954
955 dataout_jump:
956     JUMP 0
957
958 at 0x000000bd : */      0x80080000,0x00000000,
959 /*
960
961 ; Nasty jump to dsa->dsain
962 do_datain:
963
964     MOVE MEMORY 4, saved_dsa, addr_scratch
965
966 at 0x000000bf : */      0xc0000004,0x00000000,0x00000000,
967 /*
968
969
970
971     MOVE SCRATCH0 + dsa_datain TO SCRATCH0      
972
973 at 0x000000c2 : */      0x7e345400,0x00000000,
974 /*
975     MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY 
976
977 at 0x000000c4 : */      0x7f350000,0x00000000,
978 /*
979     MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY 
980
981 at 0x000000c6 : */      0x7f360000,0x00000000,
982 /*
983     MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY 
984
985 at 0x000000c8 : */      0x7f370000,0x00000000,
986 /*
987     
988     MOVE MEMORY 4, addr_scratch, datain_to_jump + 4
989
990 at 0x000000ca : */      0xc0000004,0x00000000,0x00000338,
991 /*
992     
993 ENTRY datain_to_jump
994 datain_to_jump:
995     MOVE MEMORY 4, 0, datain_jump + 4
996
997 at 0x000000cd : */      0xc0000004,0x00000000,0x00000350,
998 /*
999
1000     ; Time to correct DSA following memory move
1001     MOVE MEMORY 4, saved_dsa, addr_dsa
1002
1003 at 0x000000d0 : */      0xc0000004,0x00000000,0x00000000,
1004 /*
1005
1006
1007
1008
1009 datain_jump:
1010     JUMP 0
1011
1012 at 0x000000d3 : */      0x80080000,0x00000000,
1013 /*
1014
1015
1016
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.
1020
1021 ENTRY other_out
1022 other_out:
1023
1024
1025
1026     INT int_err_unexpected_phase, WHEN CMD
1027
1028 at 0x000000d5 : */      0x9a0b0000,0x00000000,
1029 /*
1030     JUMP msg_in_restart, WHEN MSG_IN 
1031
1032 at 0x000000d7 : */      0x870b0000,0x000003fc,
1033 /*
1034     INT int_err_unexpected_phase, WHEN MSG_OUT
1035
1036 at 0x000000d9 : */      0x9e0b0000,0x00000000,
1037 /*
1038     INT int_err_unexpected_phase, WHEN DATA_IN
1039
1040 at 0x000000db : */      0x990b0000,0x00000000,
1041 /*
1042     JUMP command_complete, WHEN STATUS
1043
1044 at 0x000000dd : */      0x830b0000,0x0000065c,
1045 /*
1046     JUMP other_out, WHEN NOT DATA_OUT
1047
1048 at 0x000000df : */      0x80030000,0x00000354,
1049 /*
1050
1051 ; TEMP should be OK, as we got here from a call in the user dataout code.
1052
1053     RETURN
1054
1055 at 0x000000e1 : */      0x90080000,0x00000000,
1056 /*
1057
1058 ENTRY other_in
1059 other_in:
1060
1061
1062
1063     INT int_err_unexpected_phase, WHEN CMD
1064
1065 at 0x000000e3 : */      0x9a0b0000,0x00000000,
1066 /*
1067     JUMP msg_in_restart, WHEN MSG_IN 
1068
1069 at 0x000000e5 : */      0x870b0000,0x000003fc,
1070 /*
1071     INT int_err_unexpected_phase, WHEN MSG_OUT
1072
1073 at 0x000000e7 : */      0x9e0b0000,0x00000000,
1074 /*
1075     INT int_err_unexpected_phase, WHEN DATA_OUT
1076
1077 at 0x000000e9 : */      0x980b0000,0x00000000,
1078 /*
1079     JUMP command_complete, WHEN STATUS
1080
1081 at 0x000000eb : */      0x830b0000,0x0000065c,
1082 /*
1083     JUMP other_in, WHEN NOT DATA_IN
1084
1085 at 0x000000ed : */      0x81030000,0x0000038c,
1086 /*
1087
1088 ; TEMP should be OK, as we got here from a call in the user datain code.
1089
1090     RETURN
1091
1092 at 0x000000ef : */      0x90080000,0x00000000,
1093 /*
1094
1095
1096 ENTRY other_transfer
1097 other_transfer:
1098     INT int_err_unexpected_phase, WHEN CMD
1099
1100 at 0x000000f1 : */      0x9a0b0000,0x00000000,
1101 /*
1102     CALL msg_in, WHEN MSG_IN
1103
1104 at 0x000000f3 : */      0x8f0b0000,0x0000041c,
1105 /*
1106     INT int_err_unexpected_phase, WHEN MSG_OUT
1107
1108 at 0x000000f5 : */      0x9e0b0000,0x00000000,
1109 /*
1110     INT int_err_unexpected_phase, WHEN DATA_OUT
1111
1112 at 0x000000f7 : */      0x980b0000,0x00000000,
1113 /*
1114     INT int_err_unexpected_phase, WHEN DATA_IN
1115
1116 at 0x000000f9 : */      0x990b0000,0x00000000,
1117 /*
1118     JUMP command_complete, WHEN STATUS
1119
1120 at 0x000000fb : */      0x830b0000,0x0000065c,
1121 /*
1122     JUMP other_transfer
1123
1124 at 0x000000fd : */      0x80080000,0x000003c4,
1125 /*
1126
1127 ;
1128 ; msg_in_restart
1129 ; msg_in
1130 ; munge_msg
1131 ;
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.
1139 ;
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.
1143 ;
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.
1151 ;
1152 ;       DISCONNECT messages are handled by moving the command
1153 ;       to the reconnect_dsa_queue.
1154
1155 ; NOTE: DSA should be valid when we get here - we cannot save both it
1156 ;       and TEMP in this routine.
1157
1158 ;
1159 ; INPUTS : DSA - SCSI COMMAND, SFBR - first byte of message (munge_msg
1160 ;       only)
1161 ;
1162 ; CALLS : NO.  The TEMP register isn't backed up to allow nested calls.
1163 ;
1164 ; MODIFIES : SCRATCH, DSA on DISCONNECT
1165 ;
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.
1170 ;
1171 ENTRY msg_in_restart
1172 msg_in_restart:
1173 ; XXX - hackish
1174 ;
1175 ; Since it's easier to debug changes to the statically 
1176 ; compiled code, rather than the dynamically generated 
1177 ; stuff, such as
1178 ;
1179 ;       MOVE x, y, WHEN data_phase
1180 ;       CALL other_z, WHEN NOT data_phase
1181 ;       MOVE x, y, WHEN data_phase
1182 ;
1183 ; I'd like to have certain routines (notably the message handler)
1184 ; restart on the conditional call rather than the next instruction.
1185 ;
1186 ; So, subtract 8 from the return address
1187
1188     MOVE TEMP0 + 0xf8 TO TEMP0
1189
1190 at 0x000000ff : */      0x7e1cf800,0x00000000,
1191 /*
1192     MOVE TEMP1 + 0xff TO TEMP1 WITH CARRY
1193
1194 at 0x00000101 : */      0x7f1dff00,0x00000000,
1195 /*
1196     MOVE TEMP2 + 0xff TO TEMP2 WITH CARRY
1197
1198 at 0x00000103 : */      0x7f1eff00,0x00000000,
1199 /*
1200     MOVE TEMP3 + 0xff TO TEMP3 WITH CARRY
1201
1202 at 0x00000105 : */      0x7f1fff00,0x00000000,
1203 /*
1204
1205 ENTRY msg_in
1206 msg_in:
1207     MOVE 1, msg_buf, WHEN MSG_IN
1208
1209 at 0x00000107 : */      0x0f000001,0x00000000,
1210 /*
1211
1212 munge_msg:
1213     JUMP munge_extended, IF 0x01                ; EXTENDED MESSAGE
1214
1215 at 0x00000109 : */      0x800c0001,0x00000574,
1216 /*
1217     JUMP munge_2, IF 0x20, AND MASK 0xdf        ; two byte message
1218
1219 at 0x0000010b : */      0x800cdf20,0x00000464,
1220 /*
1221 ;
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 
1225 ;       restored.  
1226 ;
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 
1229 ; doing that here. 
1230 ;
1231     JUMP munge_save_data_pointer, IF 0x02       ; SAVE DATA POINTER
1232
1233 at 0x0000010d : */      0x800c0002,0x0000046c,
1234 /*
1235     JUMP munge_restore_pointers, IF 0x03        ; RESTORE POINTERS 
1236
1237 at 0x0000010f : */      0x800c0003,0x00000518,
1238 /*
1239     JUMP munge_disconnect, IF 0x04              ; DISCONNECT
1240
1241 at 0x00000111 : */      0x800c0004,0x0000056c,
1242 /*
1243     INT int_msg_1, IF 0x07                      ; MESSAGE REJECT
1244
1245 at 0x00000113 : */      0x980c0007,0x01020000,
1246 /*
1247     INT int_msg_1, IF 0x0f                      ; INITIATE RECOVERY
1248
1249 at 0x00000115 : */      0x980c000f,0x01020000,
1250 /*
1251
1252
1253
1254     JUMP reject_message
1255
1256 at 0x00000117 : */      0x80080000,0x00000604,
1257 /*
1258
1259 munge_2:
1260     JUMP reject_message
1261
1262 at 0x00000119 : */      0x80080000,0x00000604,
1263 /*
1264 ;
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.  
1268 ;       
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. 
1273 ;
1274
1275 munge_save_data_pointer:
1276
1277     ; We have something in TEMP here, so first we must save that
1278     MOVE TEMP0 TO SFBR
1279
1280 at 0x0000011b : */      0x721c0000,0x00000000,
1281 /*
1282     MOVE SFBR TO SCRATCH0
1283
1284 at 0x0000011d : */      0x6a340000,0x00000000,
1285 /*
1286     MOVE TEMP1 TO SFBR
1287
1288 at 0x0000011f : */      0x721d0000,0x00000000,
1289 /*
1290     MOVE SFBR TO SCRATCH1
1291
1292 at 0x00000121 : */      0x6a350000,0x00000000,
1293 /*
1294     MOVE TEMP2 TO SFBR
1295
1296 at 0x00000123 : */      0x721e0000,0x00000000,
1297 /*
1298     MOVE SFBR TO SCRATCH2
1299
1300 at 0x00000125 : */      0x6a360000,0x00000000,
1301 /*
1302     MOVE TEMP3 TO SFBR
1303
1304 at 0x00000127 : */      0x721f0000,0x00000000,
1305 /*
1306     MOVE SFBR TO SCRATCH3
1307
1308 at 0x00000129 : */      0x6a370000,0x00000000,
1309 /*
1310     MOVE MEMORY 4, addr_scratch, jump_temp + 4
1311
1312 at 0x0000012b : */      0xc0000004,0x00000000,0x000009c8,
1313 /*
1314     ; Now restore DSA
1315     MOVE MEMORY 4, saved_dsa, addr_dsa
1316
1317 at 0x0000012e : */      0xc0000004,0x00000000,0x00000000,
1318 /*
1319
1320     MOVE DSA0 + dsa_save_data_pointer TO SFBR
1321
1322 at 0x00000131 : */      0x76100000,0x00000000,
1323 /*
1324     MOVE SFBR TO SCRATCH0
1325
1326 at 0x00000133 : */      0x6a340000,0x00000000,
1327 /*
1328     MOVE DSA1 + 0xff TO SFBR WITH CARRY
1329
1330 at 0x00000135 : */      0x7711ff00,0x00000000,
1331 /*
1332     MOVE SFBR TO SCRATCH1
1333
1334 at 0x00000137 : */      0x6a350000,0x00000000,
1335 /*
1336     MOVE DSA2 + 0xff TO SFBR WITH CARRY 
1337
1338 at 0x00000139 : */      0x7712ff00,0x00000000,
1339 /*
1340     MOVE SFBR TO SCRATCH2
1341
1342 at 0x0000013b : */      0x6a360000,0x00000000,
1343 /*
1344     MOVE DSA3 + 0xff TO SFBR WITH CARRY
1345
1346 at 0x0000013d : */      0x7713ff00,0x00000000,
1347 /*
1348     MOVE SFBR TO SCRATCH3
1349
1350 at 0x0000013f : */      0x6a370000,0x00000000,
1351 /*
1352
1353     
1354     MOVE MEMORY 4, addr_scratch, jump_dsa_save + 4
1355
1356 at 0x00000141 : */      0xc0000004,0x00000000,0x00000514,
1357 /*
1358     
1359 jump_dsa_save:
1360     JUMP 0
1361
1362 at 0x00000144 : */      0x80080000,0x00000000,
1363 /*
1364
1365 munge_restore_pointers:
1366
1367     ; The code at dsa_restore_pointers will RETURN, but we don't care
1368     ; about TEMP here, as it will overwrite it anyway.
1369
1370     MOVE DSA0 + dsa_restore_pointers TO SFBR
1371
1372 at 0x00000146 : */      0x76100000,0x00000000,
1373 /*
1374     MOVE SFBR TO SCRATCH0
1375
1376 at 0x00000148 : */      0x6a340000,0x00000000,
1377 /*
1378     MOVE DSA1 + 0xff TO SFBR WITH CARRY
1379
1380 at 0x0000014a : */      0x7711ff00,0x00000000,
1381 /*
1382     MOVE SFBR TO SCRATCH1
1383
1384 at 0x0000014c : */      0x6a350000,0x00000000,
1385 /*
1386     MOVE DSA2 + 0xff TO SFBR WITH CARRY
1387
1388 at 0x0000014e : */      0x7712ff00,0x00000000,
1389 /*
1390     MOVE SFBR TO SCRATCH2
1391
1392 at 0x00000150 : */      0x6a360000,0x00000000,
1393 /*
1394     MOVE DSA3 + 0xff TO SFBR WITH CARRY
1395
1396 at 0x00000152 : */      0x7713ff00,0x00000000,
1397 /*
1398     MOVE SFBR TO SCRATCH3
1399
1400 at 0x00000154 : */      0x6a370000,0x00000000,
1401 /*
1402
1403     
1404     MOVE MEMORY 4, addr_scratch, jump_dsa_restore + 4
1405
1406 at 0x00000156 : */      0xc0000004,0x00000000,0x00000568,
1407 /*
1408     
1409 jump_dsa_restore:
1410     JUMP 0
1411
1412 at 0x00000159 : */      0x80080000,0x00000000,
1413 /*
1414
1415
1416 munge_disconnect:
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426  
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437     JUMP dsa_schedule
1438
1439 at 0x0000015b : */      0x80080000,0x00000178,
1440 /*
1441
1442
1443
1444
1445
1446 munge_extended:
1447     CLEAR ACK
1448
1449 at 0x0000015d : */      0x60000040,0x00000000,
1450 /*
1451     INT int_err_unexpected_phase, WHEN NOT MSG_IN
1452
1453 at 0x0000015f : */      0x9f030000,0x00000000,
1454 /*
1455     MOVE 1, msg_buf + 1, WHEN MSG_IN
1456
1457 at 0x00000161 : */      0x0f000001,0x00000001,
1458 /*
1459     JUMP munge_extended_2, IF 0x02
1460
1461 at 0x00000163 : */      0x800c0002,0x000005a4,
1462 /*
1463     JUMP munge_extended_3, IF 0x03 
1464
1465 at 0x00000165 : */      0x800c0003,0x000005d4,
1466 /*
1467     JUMP reject_message
1468
1469 at 0x00000167 : */      0x80080000,0x00000604,
1470 /*
1471
1472 munge_extended_2:
1473     CLEAR ACK
1474
1475 at 0x00000169 : */      0x60000040,0x00000000,
1476 /*
1477     MOVE 1, msg_buf + 2, WHEN MSG_IN
1478
1479 at 0x0000016b : */      0x0f000001,0x00000002,
1480 /*
1481     JUMP reject_message, IF NOT 0x02    ; Must be WDTR
1482
1483 at 0x0000016d : */      0x80040002,0x00000604,
1484 /*
1485     CLEAR ACK
1486
1487 at 0x0000016f : */      0x60000040,0x00000000,
1488 /*
1489     MOVE 1, msg_buf + 3, WHEN MSG_IN
1490
1491 at 0x00000171 : */      0x0f000001,0x00000003,
1492 /*
1493     INT int_msg_wdtr
1494
1495 at 0x00000173 : */      0x98080000,0x01000000,
1496 /*
1497
1498 munge_extended_3:
1499     CLEAR ACK
1500
1501 at 0x00000175 : */      0x60000040,0x00000000,
1502 /*
1503     MOVE 1, msg_buf + 2, WHEN MSG_IN
1504
1505 at 0x00000177 : */      0x0f000001,0x00000002,
1506 /*
1507     JUMP reject_message, IF NOT 0x01    ; Must be SDTR
1508
1509 at 0x00000179 : */      0x80040001,0x00000604,
1510 /*
1511     CLEAR ACK
1512
1513 at 0x0000017b : */      0x60000040,0x00000000,
1514 /*
1515     MOVE 2, msg_buf + 3, WHEN MSG_IN
1516
1517 at 0x0000017d : */      0x0f000002,0x00000003,
1518 /*
1519     INT int_msg_sdtr
1520
1521 at 0x0000017f : */      0x98080000,0x01010000,
1522 /*
1523
1524 ENTRY reject_message
1525 reject_message:
1526     SET ATN
1527
1528 at 0x00000181 : */      0x58000008,0x00000000,
1529 /*
1530     CLEAR ACK
1531
1532 at 0x00000183 : */      0x60000040,0x00000000,
1533 /*
1534     MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT
1535
1536 at 0x00000185 : */      0x0e000001,0x00000000,
1537 /*
1538     RETURN
1539
1540 at 0x00000187 : */      0x90080000,0x00000000,
1541 /*
1542
1543 ENTRY accept_message
1544 accept_message:
1545     CLEAR ATN
1546
1547 at 0x00000189 : */      0x60000008,0x00000000,
1548 /*
1549     CLEAR ACK
1550
1551 at 0x0000018b : */      0x60000040,0x00000000,
1552 /*
1553     RETURN
1554
1555 at 0x0000018d : */      0x90080000,0x00000000,
1556 /*
1557
1558 ENTRY respond_message
1559 respond_message:
1560     SET ATN
1561
1562 at 0x0000018f : */      0x58000008,0x00000000,
1563 /*
1564     CLEAR ACK
1565
1566 at 0x00000191 : */      0x60000040,0x00000000,
1567 /*
1568     MOVE FROM dsa_msgout_other, WHEN MSG_OUT
1569
1570 at 0x00000193 : */      0x1e000000,0x00000068,
1571 /*
1572     RETURN
1573
1574 at 0x00000195 : */      0x90080000,0x00000000,
1575 /*
1576
1577 ;
1578 ; command_complete
1579 ;
1580 ; PURPOSE : handle command termination when STATUS IN is detected by reading
1581 ;       a status byte followed by a command termination message. 
1582 ;
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;
1587 ;
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.
1592 ;       
1593 ;
1594 ; INPUTS : DSA - command        
1595 ;
1596 ; CALLS : OK
1597 ;
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
1601 ;       to select.
1602 ;
1603
1604 ENTRY command_complete
1605 command_complete:
1606     MOVE FROM dsa_status, WHEN STATUS
1607
1608 at 0x00000197 : */      0x1b000000,0x00000060,
1609 /*
1610
1611     MOVE SFBR TO SCRATCH0               ; Save status
1612
1613 at 0x00000199 : */      0x6a340000,0x00000000,
1614 /*
1615
1616 ENTRY command_complete_msgin
1617 command_complete_msgin:
1618     MOVE FROM dsa_msgin, WHEN MSG_IN
1619
1620 at 0x0000019b : */      0x1f000000,0x00000058,
1621 /*
1622 ; Indicate that we should be expecting a disconnect
1623
1624
1625
1626     ; Above code cleared the Unexpected Disconnect bit, what do we do?
1627
1628     CLEAR ACK
1629
1630 at 0x0000019d : */      0x60000040,0x00000000,
1631 /*
1632
1633     WAIT DISCONNECT
1634
1635 at 0x0000019f : */      0x48000000,0x00000000,
1636 /*
1637
1638 ;
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.
1646 ;
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.
1653
1654
1655
1656
1657
1658
1659
1660     INT int_norm_emulateintfly
1661
1662 at 0x000001a1 : */      0x98080000,0x02060000,
1663 /*
1664
1665
1666
1667
1668
1669
1670     ; Time to correct DSA following memory move
1671     MOVE MEMORY 4, saved_dsa, addr_dsa
1672
1673 at 0x000001a3 : */      0xc0000004,0x00000000,0x00000000,
1674 /*
1675
1676
1677
1678
1679
1680     JUMP schedule
1681
1682 at 0x000001a6 : */      0x80080000,0x00000000,
1683 /*
1684 command_failed:
1685     INT int_err_check_condition
1686
1687 at 0x000001a8 : */      0x98080000,0x00030000,
1688 /*
1689
1690
1691
1692
1693 ;
1694 ; wait_reselect
1695 ;
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.
1699 ;
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.
1704 ;
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.
1709 ;
1710 ; INPUTS : NONE
1711 ;
1712 ; CALLS : OK
1713 ;
1714 ; MODIFIES : DSA,
1715 ;
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.
1723
1724 ENTRY wait_reselect
1725 wait_reselect:
1726
1727
1728
1729
1730
1731
1732     WAIT RESELECT wait_reselect_failed
1733
1734 at 0x000001aa : */      0x50000000,0x00000800,
1735 /*
1736
1737 reselected:
1738
1739
1740
1741     CLEAR TARGET
1742
1743 at 0x000001ac : */      0x60000200,0x00000000,
1744 /*
1745     
1746     ; Read all data needed to reestablish the nexus - 
1747     MOVE 1, reselected_identify, WHEN MSG_IN
1748
1749 at 0x000001ae : */      0x0f000001,0x00000000,
1750 /*
1751     ; We used to CLEAR ACK here.
1752
1753
1754
1755
1756
1757     ; Point DSA at the current head of the disconnected queue.
1758     
1759     MOVE MEMORY 4, reconnect_dsa_head, addr_scratch
1760
1761 at 0x000001b0 : */      0xc0000004,0x00000000,0x00000000,
1762 /*
1763     
1764
1765     MOVE MEMORY 4, addr_scratch, saved_dsa
1766
1767 at 0x000001b3 : */      0xc0000004,0x00000000,0x00000000,
1768 /*
1769
1770
1771
1772
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.
1776
1777     MOVE MEMORY 4, addr_reconnect_dsa_head, reselected_ok_patch + 8
1778
1779 at 0x000001b6 : */      0xc0000004,0x00000000,0x000007ec,
1780 /*
1781
1782     ; Time to correct DSA following memory move
1783     MOVE MEMORY 4, saved_dsa, addr_dsa
1784
1785 at 0x000001b9 : */      0xc0000004,0x00000000,0x00000000,
1786 /*
1787
1788
1789 ENTRY reselected_check_next
1790 reselected_check_next:
1791
1792
1793
1794     ; Check for a NULL pointer.
1795     MOVE DSA0 TO SFBR
1796
1797 at 0x000001bc : */      0x72100000,0x00000000,
1798 /*
1799     JUMP reselected_not_end, IF NOT 0
1800
1801 at 0x000001be : */      0x80040000,0x00000738,
1802 /*
1803     MOVE DSA1 TO SFBR
1804
1805 at 0x000001c0 : */      0x72110000,0x00000000,
1806 /*
1807     JUMP reselected_not_end, IF NOT 0
1808
1809 at 0x000001c2 : */      0x80040000,0x00000738,
1810 /*
1811     MOVE DSA2 TO SFBR
1812
1813 at 0x000001c4 : */      0x72120000,0x00000000,
1814 /*
1815     JUMP reselected_not_end, IF NOT 0
1816
1817 at 0x000001c6 : */      0x80040000,0x00000738,
1818 /*
1819     MOVE DSA3 TO SFBR
1820
1821 at 0x000001c8 : */      0x72130000,0x00000000,
1822 /*
1823     JUMP reselected_not_end, IF NOT 0
1824
1825 at 0x000001ca : */      0x80040000,0x00000738,
1826 /*
1827     INT int_err_unexpected_reselect
1828
1829 at 0x000001cc : */      0x98080000,0x00020000,
1830 /*
1831
1832 reselected_not_end:
1833     ;
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.
1838     ;
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.
1843     ;
1844
1845     MOVE DSA0 TO SFBR
1846
1847 at 0x000001ce : */      0x72100000,0x00000000,
1848 /*
1849     MOVE SFBR + dsa_check_reselect TO SCRATCH0
1850
1851 at 0x000001d0 : */      0x6e340000,0x00000000,
1852 /*
1853     MOVE DSA1 TO SFBR
1854
1855 at 0x000001d2 : */      0x72110000,0x00000000,
1856 /*
1857     MOVE SFBR + 0xff TO SCRATCH1 WITH CARRY
1858
1859 at 0x000001d4 : */      0x6f35ff00,0x00000000,
1860 /*
1861     MOVE DSA2 TO SFBR
1862
1863 at 0x000001d6 : */      0x72120000,0x00000000,
1864 /*
1865     MOVE SFBR + 0xff TO SCRATCH2 WITH CARRY
1866
1867 at 0x000001d8 : */      0x6f36ff00,0x00000000,
1868 /*
1869     MOVE DSA3 TO SFBR
1870
1871 at 0x000001da : */      0x72130000,0x00000000,
1872 /*
1873     MOVE SFBR + 0xff TO SCRATCH3 WITH CARRY
1874
1875 at 0x000001dc : */      0x6f37ff00,0x00000000,
1876 /*
1877
1878     
1879     MOVE MEMORY 4, addr_scratch, reselected_check + 4
1880
1881 at 0x000001de : */      0xc0000004,0x00000000,0x00000794,
1882 /*
1883     
1884
1885     ; Time to correct DSA following memory move
1886     MOVE MEMORY 4, saved_dsa, addr_dsa
1887
1888 at 0x000001e1 : */      0xc0000004,0x00000000,0x00000000,
1889 /*
1890
1891 reselected_check:
1892     JUMP 0
1893
1894 at 0x000001e4 : */      0x80080000,0x00000000,
1895 /*
1896
1897
1898 ;
1899 ;
1900
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.
1904 ; We have to:
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
1910
1911 ENTRY reselected_ok
1912 reselected_ok:
1913     MOVE TEMP0 TO SFBR
1914
1915 at 0x000001e6 : */      0x721c0000,0x00000000,
1916 /*
1917     MOVE SFBR TO SCRATCH0
1918
1919 at 0x000001e8 : */      0x6a340000,0x00000000,
1920 /*
1921     MOVE TEMP1 TO SFBR
1922
1923 at 0x000001ea : */      0x721d0000,0x00000000,
1924 /*
1925     MOVE SFBR TO SCRATCH1
1926
1927 at 0x000001ec : */      0x6a350000,0x00000000,
1928 /*
1929     MOVE TEMP2 TO SFBR
1930
1931 at 0x000001ee : */      0x721e0000,0x00000000,
1932 /*
1933     MOVE SFBR TO SCRATCH2
1934
1935 at 0x000001f0 : */      0x6a360000,0x00000000,
1936 /*
1937     MOVE TEMP3 TO SFBR
1938
1939 at 0x000001f2 : */      0x721f0000,0x00000000,
1940 /*
1941     MOVE SFBR TO SCRATCH3
1942
1943 at 0x000001f4 : */      0x6a370000,0x00000000,
1944 /*
1945     MOVE MEMORY 4, addr_scratch, reselected_ok_jump + 4
1946
1947 at 0x000001f6 : */      0xc0000004,0x00000000,0x000007f4,
1948 /*
1949 reselected_ok_patch:
1950     MOVE MEMORY 4, 0, 0
1951
1952 at 0x000001f9 : */      0xc0000004,0x00000000,0x00000000,
1953 /*
1954 reselected_ok_jump:
1955     JUMP 0
1956
1957 at 0x000001fc : */      0x80080000,0x00000000,
1958 /*
1959
1960
1961
1962
1963
1964 selected:
1965     INT int_err_selected;
1966
1967 at 0x000001fe : */      0x98080000,0x00010000,
1968 /*
1969
1970 ;
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.
1974 ;
1975 ; 2.  The NCR53c810 was selected or reselected by another device.
1976 ;
1977 ; 3.  The bus was already busy since we were selected or reselected
1978 ;       before starting the command.
1979
1980 wait_reselect_failed:
1981
1982
1983
1984 ; Check selected bit.  
1985
1986     ; Must work out how to tell if we are selected....
1987
1988
1989
1990
1991 ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
1992     MOVE CTEST2 & 0x40 TO SFBR  
1993
1994 at 0x00000200 : */      0x74164000,0x00000000,
1995 /*
1996     JUMP schedule, IF 0x40
1997
1998 at 0x00000202 : */      0x800c0040,0x00000000,
1999 /*
2000 ; Check connected bit.  
2001 ; FIXME: this needs to change if we support target mode
2002     MOVE ISTAT & 0x08 TO SFBR
2003
2004 at 0x00000204 : */      0x74210800,0x00000000,
2005 /*
2006     JUMP reselected, IF 0x08
2007
2008 at 0x00000206 : */      0x800c0008,0x000006b0,
2009 /*
2010 ; FIXME : Something bogus happened, and we shouldn't fail silently.
2011
2012
2013
2014     INT int_debug_panic
2015
2016 at 0x00000208 : */      0x98080000,0x030b0000,
2017 /*
2018
2019
2020
2021 select_failed:
2022
2023     ; Disable selection timer
2024     MOVE CTEST7 | 0x10 TO CTEST7
2025
2026 at 0x0000020a : */      0x7a1b1000,0x00000000,
2027 /*
2028
2029
2030
2031
2032 ; Otherwise, mask the selected and reselected bits off SIST0
2033
2034     ; Let's assume we don't get selected for now
2035     MOVE SSTAT0 & 0x10 TO SFBR
2036
2037 at 0x0000020c : */      0x740d1000,0x00000000,
2038 /*
2039
2040
2041
2042
2043     JUMP reselected, IF 0x10 
2044
2045 at 0x0000020e : */      0x800c0010,0x000006b0,
2046 /*
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  
2051
2052 at 0x00000210 : */      0x74164000,0x00000000,
2053 /*
2054     JUMP select, IF 0x40
2055
2056 at 0x00000212 : */      0x800c0040,0x000001f8,
2057 /*
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
2062
2063 at 0x00000214 : */      0x74210800,0x00000000,
2064 /*
2065     JUMP reselected, IF 0x08
2066
2067 at 0x00000216 : */      0x800c0008,0x000006b0,
2068 /*
2069 ; FIXME : Something bogus happened, and we shouldn't fail silently.
2070
2071
2072
2073     INT int_debug_panic
2074
2075 at 0x00000218 : */      0x98080000,0x030b0000,
2076 /*
2077
2078
2079 ;
2080 ; test_1
2081 ; test_2
2082 ;
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.
2087 ;
2088 ;       test_2 runs a command with offsets relative to the 
2089 ;       DSA on entry, and is useful for miscellaneous experimentation.
2090 ;
2091
2092 ; Verify that interrupts are working correctly and that we don't 
2093 ; have a cache invalidation problem.
2094
2095 ABSOLUTE test_src = 0, test_dest = 0
2096 ENTRY test_1
2097 test_1:
2098     MOVE MEMORY 4, test_src, test_dest
2099
2100 at 0x0000021a : */      0xc0000004,0x00000000,0x00000000,
2101 /*
2102     INT int_test_1
2103
2104 at 0x0000021d : */      0x98080000,0x04000000,
2105 /*
2106
2107 ;
2108 ; Run arbitrary commands, with test code establishing a DSA
2109 ;
2110  
2111 ENTRY test_2
2112 test_2:
2113     CLEAR TARGET
2114
2115 at 0x0000021f : */      0x60000200,0x00000000,
2116 /*
2117
2118     ; Enable selection timer
2119
2120
2121
2122     MOVE CTEST7 & 0xef TO CTEST7
2123
2124 at 0x00000221 : */      0x7c1bef00,0x00000000,
2125 /*
2126
2127
2128     SELECT ATN FROM 0, test_2_fail
2129
2130 at 0x00000223 : */      0x43000000,0x000008dc,
2131 /*
2132     JUMP test_2_msgout, WHEN MSG_OUT
2133
2134 at 0x00000225 : */      0x860b0000,0x0000089c,
2135 /*
2136 ENTRY test_2_msgout
2137 test_2_msgout:
2138
2139     ; Disable selection timer
2140     MOVE CTEST7 | 0x10 TO CTEST7
2141
2142 at 0x00000227 : */      0x7a1b1000,0x00000000,
2143 /*
2144
2145     MOVE FROM 8, WHEN MSG_OUT
2146
2147 at 0x00000229 : */      0x1e000000,0x00000008,
2148 /*
2149     MOVE FROM 16, WHEN CMD 
2150
2151 at 0x0000022b : */      0x1a000000,0x00000010,
2152 /*
2153     MOVE FROM 24, WHEN DATA_IN
2154
2155 at 0x0000022d : */      0x19000000,0x00000018,
2156 /*
2157     MOVE FROM 32, WHEN STATUS
2158
2159 at 0x0000022f : */      0x1b000000,0x00000020,
2160 /*
2161     MOVE FROM 40, WHEN MSG_IN
2162
2163 at 0x00000231 : */      0x1f000000,0x00000028,
2164 /*
2165
2166
2167
2168     CLEAR ACK
2169
2170 at 0x00000233 : */      0x60000040,0x00000000,
2171 /*
2172     WAIT DISCONNECT
2173
2174 at 0x00000235 : */      0x48000000,0x00000000,
2175 /*
2176 test_2_fail:
2177
2178     ; Disable selection timer
2179     MOVE CTEST7 | 0x10 TO CTEST7
2180
2181 at 0x00000237 : */      0x7a1b1000,0x00000000,
2182 /*
2183
2184     INT int_test_2
2185
2186 at 0x00000239 : */      0x98080000,0x04010000,
2187 /*
2188
2189 ENTRY debug_break
2190 debug_break:
2191     INT int_debug_break
2192
2193 at 0x0000023b : */      0x98080000,0x03000000,
2194 /*
2195
2196 ;
2197 ; initiator_abort
2198 ; target_abort
2199 ;
2200 ; PURPOSE : Abort the currently established nexus from with initiator
2201 ;       or target mode.
2202 ;
2203 ;  
2204
2205 ENTRY target_abort
2206 target_abort:
2207     SET TARGET
2208
2209 at 0x0000023d : */      0x58000200,0x00000000,
2210 /*
2211     DISCONNECT
2212
2213 at 0x0000023f : */      0x48000000,0x00000000,
2214 /*
2215     CLEAR TARGET
2216
2217 at 0x00000241 : */      0x60000200,0x00000000,
2218 /*
2219     JUMP schedule
2220
2221 at 0x00000243 : */      0x80080000,0x00000000,
2222 /*
2223     
2224 ENTRY initiator_abort
2225 initiator_abort:
2226     SET ATN
2227
2228 at 0x00000245 : */      0x58000008,0x00000000,
2229 /*
2230 ;
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.
2235 ;
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
2240
2241 at 0x00000247 : */      0x820b0000,0x0000094c,
2242 /*
2243     JUMP eat_msgin, WHEN MSG_IN
2244
2245 at 0x00000249 : */      0x870b0000,0x0000095c,
2246 /*
2247     JUMP eat_datain, WHEN DATA_IN
2248
2249 at 0x0000024b : */      0x810b0000,0x0000098c,
2250 /*
2251     JUMP eat_status, WHEN STATUS
2252
2253 at 0x0000024d : */      0x830b0000,0x00000974,
2254 /*
2255     JUMP spew_dataout, WHEN DATA_OUT
2256
2257 at 0x0000024f : */      0x800b0000,0x000009a4,
2258 /*
2259     JUMP sated
2260
2261 at 0x00000251 : */      0x80080000,0x000009ac,
2262 /*
2263 spew_cmd:
2264     MOVE 1, NCR53c7xx_zero, WHEN CMD
2265
2266 at 0x00000253 : */      0x0a000001,0x00000000,
2267 /*
2268     JUMP sated
2269
2270 at 0x00000255 : */      0x80080000,0x000009ac,
2271 /*
2272 eat_msgin:
2273     MOVE 1, NCR53c7xx_sink, WHEN MSG_IN
2274
2275 at 0x00000257 : */      0x0f000001,0x00000000,
2276 /*
2277     JUMP eat_msgin, WHEN MSG_IN
2278
2279 at 0x00000259 : */      0x870b0000,0x0000095c,
2280 /*
2281     JUMP sated
2282
2283 at 0x0000025b : */      0x80080000,0x000009ac,
2284 /*
2285 eat_status:
2286     MOVE 1, NCR53c7xx_sink, WHEN STATUS
2287
2288 at 0x0000025d : */      0x0b000001,0x00000000,
2289 /*
2290     JUMP eat_status, WHEN STATUS
2291
2292 at 0x0000025f : */      0x830b0000,0x00000974,
2293 /*
2294     JUMP sated
2295
2296 at 0x00000261 : */      0x80080000,0x000009ac,
2297 /*
2298 eat_datain:
2299     MOVE 1, NCR53c7xx_sink, WHEN DATA_IN
2300
2301 at 0x00000263 : */      0x09000001,0x00000000,
2302 /*
2303     JUMP eat_datain, WHEN DATA_IN
2304
2305 at 0x00000265 : */      0x810b0000,0x0000098c,
2306 /*
2307     JUMP sated
2308
2309 at 0x00000267 : */      0x80080000,0x000009ac,
2310 /*
2311 spew_dataout:
2312     MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT
2313
2314 at 0x00000269 : */      0x08000001,0x00000000,
2315 /*
2316 sated:
2317
2318
2319
2320     MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
2321
2322 at 0x0000026b : */      0x0e000001,0x00000000,
2323 /*
2324     WAIT DISCONNECT
2325
2326 at 0x0000026d : */      0x48000000,0x00000000,
2327 /*
2328     INT int_norm_aborted
2329
2330 at 0x0000026f : */      0x98080000,0x02040000,
2331 /*
2332
2333
2334  
2335
2336 ; Little patched jump, used to overcome problems with TEMP getting
2337 ; corrupted on memory moves.
2338
2339 jump_temp:
2340     JUMP 0
2341
2342 at 0x00000271 : */      0x80080000,0x00000000,
2343 };
2344
2345 #define A_NCR53c7xx_msg_abort   0x00000000
2346 static u32 A_NCR53c7xx_msg_abort_used[] __attribute((unused)) = {
2347         0x0000026c,
2348 };
2349
2350 #define A_NCR53c7xx_msg_reject  0x00000000
2351 static u32 A_NCR53c7xx_msg_reject_used[] __attribute((unused)) = {
2352         0x00000186,
2353 };
2354
2355 #define A_NCR53c7xx_sink        0x00000000
2356 static u32 A_NCR53c7xx_sink_used[] __attribute((unused)) = {
2357         0x00000258,
2358         0x0000025e,
2359         0x00000264,
2360 };
2361
2362 #define A_NCR53c7xx_zero        0x00000000
2363 static u32 A_NCR53c7xx_zero_used[] __attribute((unused)) = {
2364         0x00000254,
2365         0x0000026a,
2366 };
2367
2368 #define A_NOP_insn      0x00000000
2369 static u32 A_NOP_insn_used[] __attribute((unused)) = {
2370         0x00000017,
2371 };
2372
2373 #define A_addr_dsa      0x00000000
2374 static u32 A_addr_dsa_used[] __attribute((unused)) = {
2375         0x0000000f,
2376         0x00000026,
2377         0x00000033,
2378         0x00000040,
2379         0x00000055,
2380         0x00000079,
2381         0x0000008e,
2382         0x000000bc,
2383         0x000000d2,
2384         0x00000130,
2385         0x000001a5,
2386         0x000001bb,
2387         0x000001e3,
2388 };
2389
2390 #define A_addr_reconnect_dsa_head       0x00000000
2391 static u32 A_addr_reconnect_dsa_head_used[] __attribute((unused)) = {
2392         0x000001b7,
2393 };
2394
2395 #define A_addr_scratch  0x00000000
2396 static u32 A_addr_scratch_used[] __attribute((unused)) = {
2397         0x00000002,
2398         0x00000004,
2399         0x00000008,
2400         0x00000020,
2401         0x00000022,
2402         0x00000049,
2403         0x00000060,
2404         0x0000006a,
2405         0x00000071,
2406         0x00000073,
2407         0x000000ab,
2408         0x000000b5,
2409         0x000000c1,
2410         0x000000cb,
2411         0x0000012c,
2412         0x00000142,
2413         0x00000157,
2414         0x000001b2,
2415         0x000001b4,
2416         0x000001df,
2417         0x000001f7,
2418 };
2419
2420 #define A_addr_temp     0x00000000
2421 static u32 A_addr_temp_used[] __attribute((unused)) = {
2422 };
2423
2424 #define A_dmode_memory_to_memory        0x00000000
2425 static u32 A_dmode_memory_to_memory_used[] __attribute((unused)) = {
2426 };
2427
2428 #define A_dmode_memory_to_ncr   0x00000000
2429 static u32 A_dmode_memory_to_ncr_used[] __attribute((unused)) = {
2430 };
2431
2432 #define A_dmode_ncr_to_memory   0x00000000
2433 static u32 A_dmode_ncr_to_memory_used[] __attribute((unused)) = {
2434 };
2435
2436 #define A_dsa_check_reselect    0x00000000
2437 static u32 A_dsa_check_reselect_used[] __attribute((unused)) = {
2438         0x000001d0,
2439 };
2440
2441 #define A_dsa_cmdout    0x00000048
2442 static u32 A_dsa_cmdout_used[] __attribute((unused)) = {
2443         0x0000009a,
2444 };
2445
2446 #define A_dsa_cmnd      0x00000038
2447 static u32 A_dsa_cmnd_used[] __attribute((unused)) = {
2448 };
2449
2450 #define A_dsa_datain    0x00000054
2451 static u32 A_dsa_datain_used[] __attribute((unused)) = {
2452         0x000000c2,
2453 };
2454
2455 #define A_dsa_dataout   0x00000050
2456 static u32 A_dsa_dataout_used[] __attribute((unused)) = {
2457         0x000000ac,
2458 };
2459
2460 #define A_dsa_end       0x00000070
2461 static u32 A_dsa_end_used[] __attribute((unused)) = {
2462 };
2463
2464 #define A_dsa_fields_start      0x00000000
2465 static u32 A_dsa_fields_start_used[] __attribute((unused)) = {
2466 };
2467
2468 #define A_dsa_msgin     0x00000058
2469 static u32 A_dsa_msgin_used[] __attribute((unused)) = {
2470         0x0000019c,
2471 };
2472
2473 #define A_dsa_msgout    0x00000040
2474 static u32 A_dsa_msgout_used[] __attribute((unused)) = {
2475         0x00000089,
2476 };
2477
2478 #define A_dsa_msgout_other      0x00000068
2479 static u32 A_dsa_msgout_other_used[] __attribute((unused)) = {
2480         0x00000194,
2481 };
2482
2483 #define A_dsa_next      0x00000030
2484 static u32 A_dsa_next_used[] __attribute((unused)) = {
2485         0x00000061,
2486 };
2487
2488 #define A_dsa_restore_pointers  0x00000000
2489 static u32 A_dsa_restore_pointers_used[] __attribute((unused)) = {
2490         0x00000146,
2491 };
2492
2493 #define A_dsa_save_data_pointer 0x00000000
2494 static u32 A_dsa_save_data_pointer_used[] __attribute((unused)) = {
2495         0x00000131,
2496 };
2497
2498 #define A_dsa_select    0x0000003c
2499 static u32 A_dsa_select_used[] __attribute((unused)) = {
2500         0x00000082,
2501 };
2502
2503 #define A_dsa_sscf_710  0x00000000
2504 static u32 A_dsa_sscf_710_used[] __attribute((unused)) = {
2505         0x00000007,
2506 };
2507
2508 #define A_dsa_status    0x00000060
2509 static u32 A_dsa_status_used[] __attribute((unused)) = {
2510         0x00000198,
2511 };
2512
2513 #define A_dsa_temp_addr_array_value     0x00000000
2514 static u32 A_dsa_temp_addr_array_value_used[] __attribute((unused)) = {
2515 };
2516
2517 #define A_dsa_temp_addr_dsa_value       0x00000000
2518 static u32 A_dsa_temp_addr_dsa_value_used[] __attribute((unused)) = {
2519         0x00000001,
2520 };
2521
2522 #define A_dsa_temp_addr_new_value       0x00000000
2523 static u32 A_dsa_temp_addr_new_value_used[] __attribute((unused)) = {
2524 };
2525
2526 #define A_dsa_temp_addr_next    0x00000000
2527 static u32 A_dsa_temp_addr_next_used[] __attribute((unused)) = {
2528         0x0000001c,
2529         0x0000004f,
2530 };
2531
2532 #define A_dsa_temp_addr_residual        0x00000000
2533 static u32 A_dsa_temp_addr_residual_used[] __attribute((unused)) = {
2534         0x0000002d,
2535         0x0000003b,
2536 };
2537
2538 #define A_dsa_temp_addr_saved_pointer   0x00000000
2539 static u32 A_dsa_temp_addr_saved_pointer_used[] __attribute((unused)) = {
2540         0x0000002b,
2541         0x00000037,
2542 };
2543
2544 #define A_dsa_temp_addr_saved_residual  0x00000000
2545 static u32 A_dsa_temp_addr_saved_residual_used[] __attribute((unused)) = {
2546         0x0000002e,
2547         0x0000003a,
2548 };
2549
2550 #define A_dsa_temp_lun  0x00000000
2551 static u32 A_dsa_temp_lun_used[] __attribute((unused)) = {
2552         0x0000004c,
2553 };
2554
2555 #define A_dsa_temp_next 0x00000000
2556 static u32 A_dsa_temp_next_used[] __attribute((unused)) = {
2557         0x0000001f,
2558 };
2559
2560 #define A_dsa_temp_sync 0x00000000
2561 static u32 A_dsa_temp_sync_used[] __attribute((unused)) = {
2562         0x00000057,
2563 };
2564
2565 #define A_dsa_temp_target       0x00000000
2566 static u32 A_dsa_temp_target_used[] __attribute((unused)) = {
2567         0x00000045,
2568 };
2569
2570 #define A_emulfly       0x00000000
2571 static u32 A_emulfly_used[] __attribute((unused)) = {
2572 };
2573
2574 #define A_int_debug_break       0x03000000
2575 static u32 A_int_debug_break_used[] __attribute((unused)) = {
2576         0x0000023c,
2577 };
2578
2579 #define A_int_debug_panic       0x030b0000
2580 static u32 A_int_debug_panic_used[] __attribute((unused)) = {
2581         0x00000209,
2582         0x00000219,
2583 };
2584
2585 #define A_int_err_check_condition       0x00030000
2586 static u32 A_int_err_check_condition_used[] __attribute((unused)) = {
2587         0x000001a9,
2588 };
2589
2590 #define A_int_err_no_phase      0x00040000
2591 static u32 A_int_err_no_phase_used[] __attribute((unused)) = {
2592 };
2593
2594 #define A_int_err_selected      0x00010000
2595 static u32 A_int_err_selected_used[] __attribute((unused)) = {
2596         0x000001ff,
2597 };
2598
2599 #define A_int_err_unexpected_phase      0x00000000
2600 static u32 A_int_err_unexpected_phase_used[] __attribute((unused)) = {
2601         0x00000092,
2602         0x00000098,
2603         0x000000a0,
2604         0x000000d6,
2605         0x000000da,
2606         0x000000dc,
2607         0x000000e4,
2608         0x000000e8,
2609         0x000000ea,
2610         0x000000f2,
2611         0x000000f6,
2612         0x000000f8,
2613         0x000000fa,
2614         0x00000160,
2615 };
2616
2617 #define A_int_err_unexpected_reselect   0x00020000
2618 static u32 A_int_err_unexpected_reselect_used[] __attribute((unused)) = {
2619         0x000001cd,
2620 };
2621
2622 #define A_int_msg_1     0x01020000
2623 static u32 A_int_msg_1_used[] __attribute((unused)) = {
2624         0x00000114,
2625         0x00000116,
2626 };
2627
2628 #define A_int_msg_sdtr  0x01010000
2629 static u32 A_int_msg_sdtr_used[] __attribute((unused)) = {
2630         0x00000180,
2631 };
2632
2633 #define A_int_msg_wdtr  0x01000000
2634 static u32 A_int_msg_wdtr_used[] __attribute((unused)) = {
2635         0x00000174,
2636 };
2637
2638 #define A_int_norm_aborted      0x02040000
2639 static u32 A_int_norm_aborted_used[] __attribute((unused)) = {
2640         0x00000270,
2641 };
2642
2643 #define A_int_norm_command_complete     0x02020000
2644 static u32 A_int_norm_command_complete_used[] __attribute((unused)) = {
2645 };
2646
2647 #define A_int_norm_disconnected 0x02030000
2648 static u32 A_int_norm_disconnected_used[] __attribute((unused)) = {
2649 };
2650
2651 #define A_int_norm_emulateintfly        0x02060000
2652 static u32 A_int_norm_emulateintfly_used[] __attribute((unused)) = {
2653         0x000001a2,
2654 };
2655
2656 #define A_int_norm_reselect_complete    0x02010000
2657 static u32 A_int_norm_reselect_complete_used[] __attribute((unused)) = {
2658 };
2659
2660 #define A_int_norm_reset        0x02050000
2661 static u32 A_int_norm_reset_used[] __attribute((unused)) = {
2662 };
2663
2664 #define A_int_norm_select_complete      0x02000000
2665 static u32 A_int_norm_select_complete_used[] __attribute((unused)) = {
2666 };
2667
2668 #define A_int_test_1    0x04000000
2669 static u32 A_int_test_1_used[] __attribute((unused)) = {
2670         0x0000021e,
2671 };
2672
2673 #define A_int_test_2    0x04010000
2674 static u32 A_int_test_2_used[] __attribute((unused)) = {
2675         0x0000023a,
2676 };
2677
2678 #define A_int_test_3    0x04020000
2679 static u32 A_int_test_3_used[] __attribute((unused)) = {
2680 };
2681
2682 #define A_msg_buf       0x00000000
2683 static u32 A_msg_buf_used[] __attribute((unused)) = {
2684         0x00000108,
2685         0x00000162,
2686         0x0000016c,
2687         0x00000172,
2688         0x00000178,
2689         0x0000017e,
2690 };
2691
2692 #define A_reconnect_dsa_head    0x00000000
2693 static u32 A_reconnect_dsa_head_used[] __attribute((unused)) = {
2694         0x0000006d,
2695         0x00000074,
2696         0x000001b1,
2697 };
2698
2699 #define A_reselected_identify   0x00000000
2700 static u32 A_reselected_identify_used[] __attribute((unused)) = {
2701         0x00000048,
2702         0x000001af,
2703 };
2704
2705 #define A_reselected_tag        0x00000000
2706 static u32 A_reselected_tag_used[] __attribute((unused)) = {
2707 };
2708
2709 #define A_saved_dsa     0x00000000
2710 static u32 A_saved_dsa_used[] __attribute((unused)) = {
2711         0x00000005,
2712         0x0000000e,
2713         0x00000023,
2714         0x00000025,
2715         0x00000032,
2716         0x0000003f,
2717         0x00000054,
2718         0x0000005f,
2719         0x00000070,
2720         0x00000078,
2721         0x0000008d,
2722         0x000000aa,
2723         0x000000bb,
2724         0x000000c0,
2725         0x000000d1,
2726         0x0000012f,
2727         0x000001a4,
2728         0x000001b5,
2729         0x000001ba,
2730         0x000001e2,
2731 };
2732
2733 #define A_schedule      0x00000000
2734 static u32 A_schedule_used[] __attribute((unused)) = {
2735         0x0000007d,
2736         0x000001a7,
2737         0x00000203,
2738         0x00000244,
2739 };
2740
2741 #define A_test_dest     0x00000000
2742 static u32 A_test_dest_used[] __attribute((unused)) = {
2743         0x0000021c,
2744 };
2745
2746 #define A_test_src      0x00000000
2747 static u32 A_test_src_used[] __attribute((unused)) = {
2748         0x0000021b,
2749 };
2750
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)) = {
2786         0x00000011,
2787         0x0000001a,
2788         0x0000001d,
2789         0x00000028,
2790         0x0000002a,
2791         0x00000035,
2792         0x00000038,
2793         0x00000042,
2794         0x00000050,
2795         0x00000052,
2796         0x0000006b,
2797         0x00000083,
2798         0x00000085,
2799         0x00000090,
2800         0x00000094,
2801         0x00000096,
2802         0x0000009c,
2803         0x0000009e,
2804         0x000000a2,
2805         0x000000a4,
2806         0x000000a6,
2807         0x000000a8,
2808         0x000000b6,
2809         0x000000b9,
2810         0x000000cc,
2811         0x000000cf,
2812         0x000000d8,
2813         0x000000de,
2814         0x000000e0,
2815         0x000000e6,
2816         0x000000ec,
2817         0x000000ee,
2818         0x000000f4,
2819         0x000000fc,
2820         0x000000fe,
2821         0x0000010a,
2822         0x0000010c,
2823         0x0000010e,
2824         0x00000110,
2825         0x00000112,
2826         0x00000118,
2827         0x0000011a,
2828         0x0000012d,
2829         0x00000143,
2830         0x00000158,
2831         0x0000015c,
2832         0x00000164,
2833         0x00000166,
2834         0x00000168,
2835         0x0000016e,
2836         0x0000017a,
2837         0x000001ab,
2838         0x000001b8,
2839         0x000001bf,
2840         0x000001c3,
2841         0x000001c7,
2842         0x000001cb,
2843         0x000001e0,
2844         0x000001f8,
2845         0x00000207,
2846         0x0000020f,
2847         0x00000213,
2848         0x00000217,
2849         0x00000224,
2850         0x00000226,
2851         0x00000248,
2852         0x0000024a,
2853         0x0000024c,
2854         0x0000024e,
2855         0x00000250,
2856         0x00000252,
2857         0x00000256,
2858         0x0000025a,
2859         0x0000025c,
2860         0x00000260,
2861         0x00000262,
2862         0x00000266,
2863         0x00000268,
2864 };
2865
2866 static struct {
2867         u32     offset;
2868         void            *address;
2869 } EXTERNAL_PATCHES[] __attribute((unused)) = {
2870 };
2871
2872 static u32 INSTRUCTIONS __attribute((unused))   = 290;
2873 static u32 PATCHES __attribute((unused))        = 78;
2874 static u32 EXTERNAL_PATCHES_LEN __attribute((unused))   = 0;