1 u32 SCRIPT[] = {
2 /*
3
4
5 ; NCR 53c810 driver, main script
6 ; Sponsored by
7 ; iX Multiuser Multitasking Magazine
8 ; hm@ix.de
9 ;
10 ; Copyright 1993, 1994, 1995 Drew Eckhardt
11 ; Visionary Computing
12 ; (Unix and Linux consulting and custom programming)
13 ; drew@PoohSticks.ORG
14 ; +1 (303) 786-7975
15 ;
16 ; TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
17 ;
18 ; PRE-ALPHA
19 ;
20 ; For more information, please consult
21 ;
22 ; NCR 53C810
23 ; PCI-SCSI I/O Processor
24 ; Data Manual
25 ;
26 ; NCR 53C710
27 ; SCSI I/O Processor
28 ; Programmers Guide
29 ;
30 ; NCR Microelectronics
31 ; 1635 Aeroplaza Drive
32 ; Colorado Springs, CO 80916
33 ; 1+ (719) 578-3400
34 ;
35 ; Toll free literature number
36 ; +1 (800) 334-5454
37 ;
38 ; IMPORTANT : This code is self modifying due to the limitations of
39 ; the NCR53c7,8xx series chips. Persons debugging this code with
40 ; the remote debugger should take this into account, and NOT set
41 ; breakpoints in modified instructions.
42 ;
43 ; Design:
44 ; The NCR53c7,8xx family of SCSI chips are busmasters with an onboard
45 ; microcontroller using a simple instruction set.
46 ;
47 ; So, to minimize the effects of interrupt latency, and to maximize
48 ; throughput, this driver offloads the practical maximum amount
49 ; of processing to the SCSI chip while still maintaining a common
50 ; structure.
51 ;
52 ; Where tradeoffs were needed between efficiency on the older
53 ; chips and the newer NCR53c800 series, the NCR53c800 series
54 ; was chosen.
55 ;
56 ; While the NCR53c700 and NCR53c700-66 lacked the facilities to fully
57 ; automate SCSI transfers without host processor intervention, this
58 ; isn't the case with the NCR53c710 and newer chips which allow
59 ;
60 ; - reads and writes to the internal registers from within the SCSI
61 ; scripts, allowing the SCSI SCRIPTS(tm) code to save processor
62 ; state so that multiple threads of execution are possible, and also
63 ; provide an ALU for loop control, etc.
64 ;
65 ; - table indirect addressing for some instructions. This allows
66 ; pointers to be located relative to the DSA ((Data Structure
67 ; Address) register.
68 ;
69 ; These features make it possible to implement a mailbox style interface,
70 ; where the same piece of code is run to handle I/O for multiple threads
71 ; at once minimizing our need to relocate code. Since the NCR53c700/
72 ; NCR53c800 series have a unique combination of features, making a
73 ; a standard ingoing/outgoing mailbox system, costly, I've modified it.
74 ;
75 ; - Mailboxes are a mixture of code and data. This lets us greatly
76 ; simplify the NCR53c810 code and do things that would otherwise
77 ; not be possible.
78 ;
79 ; The saved data pointer is now implemented as follows :
80 ;
81 ; Control flow has been architected such that if control reaches
82 ; munge_save_data_pointer, on a restore pointers message or
83 ; reconnection, a jump to the address formerly in the TEMP register
84 ; will allow the SCSI command to resume execution.
85 ;
86
87 ;
88 ; Note : the DSA structures must be aligned on 32 bit boundaries,
89 ; since the source and destination of MOVE MEMORY instructions
90 ; must share the same alignment and this is the alignment of the
91 ; NCR registers.
92 ;
93
94 ABSOLUTE dsa_temp_lun = 0 ; Patch to lun for current dsa
95 ABSOLUTE dsa_temp_next = 0 ; Patch to dsa next for current dsa
96 ABSOLUTE dsa_temp_addr_next = 0 ; Patch to address of dsa next address
97 ; for current dsa
98 ABSOLUTE dsa_temp_sync = 0 ; Patch to address of per-target
99 ; sync routine
100 ABSOLUTE dsa_temp_target = 0 ; Patch to id for current dsa
101 ABSOLUTE dsa_temp_addr_saved_pointer = 0; Patch to address of per-command
102 ; saved data pointer
103 ABSOLUTE dsa_temp_addr_residual = 0 ; Patch to address of per-command
104 ; current residual code
105 ABSOLUTE dsa_temp_addr_saved_residual = 0; Patch to address of per-command
106 ; saved residual code
107 ABSOLUTE dsa_temp_addr_new_value = 0 ; Address of value for JUMP operand
108 ABSOLUTE dsa_temp_addr_array_value = 0 ; Address to copy to
109 ABSOLUTE dsa_temp_addr_dsa_value = 0 ; Address of this DSA value
110
111 ;
112 ; Once a device has initiated reselection, we need to compare it
113 ; against the singly linked list of commands which have disconnected
114 ; and are pending reselection. These commands are maintained in
115 ; an unordered singly linked list of DSA structures, through the
116 ; DSA pointers at their 'centers' headed by the reconnect_dsa_head
117 ; pointer.
118 ;
119 ; To avoid complications in removing commands from the list,
120 ; I minimize the amount of expensive (at eight operations per
121 ; addition @ 500-600ns each) pointer operations which must
122 ; be done in the NCR driver by precomputing them on the
123 ; host processor during dsa structure generation.
124 ;
125 ; The fixed-up per DSA code knows how to recognize the nexus
126 ; associated with the corresponding SCSI command, and modifies
127 ; the source and destination pointers for the MOVE MEMORY
128 ; instruction which is executed when reselected_ok is called
129 ; to remove the command from the list. Similarly, DSA is
130 ; loaded with the address of the next DSA structure and
131 ; reselected_check_next is called if a failure occurs.
132 ;
133 ; Perhaps more conscisely, the net effect of the mess is
134 ;
135 ; for (dsa = reconnect_dsa_head, dest = &reconnect_dsa_head,
136 ; src = NULL; dsa; dest = &dsa->next, dsa = dsa->next) {
137 ; src = &dsa->next;
138 ; if (target_id == dsa->id && target_lun == dsa->lun) {
139 ; *dest = *src;
140 ; break;
141 ; }
142 ; }
143 ;
144 ; if (!dsa)
145 ; error (int_err_unexpected_reselect);
146 ; else
147 ; longjmp (dsa->jump_resume, 0);
148 ;
149 ;
150
151
152 ; Define DSA structure used for mailboxes
153 ENTRY dsa_code_template
154 dsa_code_template:
155 ENTRY dsa_code_begin
156 dsa_code_begin:
157 MOVE dmode_memory_to_ncr TO DMODE
158
159 at 0x00000000 : */ 0x78380000,0x00000000,
160 /*
161 MOVE MEMORY 4, dsa_temp_addr_dsa_value, addr_scratch
162
163 at 0x00000002 : */ 0xc0000004,0x00000000,0x00000000,
164 /*
165 MOVE dmode_memory_to_memory TO DMODE
166
167 at 0x00000005 : */ 0x78380000,0x00000000,
168 /*
169 CALL scratch_to_dsa
170
171 at 0x00000007 : */ 0x88080000,0x00000960,
172 /*
173 CALL select
174
175 at 0x00000009 : */ 0x88080000,0x000001fc,
176 /*
177 ; Handle the phase mismatch which may have resulted from the
178 ; MOVE FROM dsa_msgout if we returned here. The CLEAR ATN
179 ; may or may not be necessary, and we should update script_asm.pl
180 ; to handle multiple pieces.
181 CLEAR ATN
182
183 at 0x0000000b : */ 0x60000008,0x00000000,
184 /*
185 CLEAR ACK
186
187 at 0x0000000d : */ 0x60000040,0x00000000,
188 /*
189
190 ; Replace second operand with address of JUMP instruction dest operand
191 ; in schedule table for this DSA. Becomes dsa_jump_dest in 53c7,8xx.c.
192 ENTRY dsa_code_fix_jump
193 dsa_code_fix_jump:
194 MOVE MEMORY 4, NOP_insn, 0
195
196 at 0x0000000f : */ 0xc0000004,0x00000000,0x00000000,
197 /*
198 JUMP select_done
199
200 at 0x00000012 : */ 0x80080000,0x00000224,
201 /*
202
203 ; wrong_dsa loads the DSA register with the value of the dsa_next
204 ; field.
205 ;
206 wrong_dsa:
207 ; Patch the MOVE MEMORY INSTRUCTION such that
208 ; the destination address is the address of the OLD
209 ; next pointer.
210 ;
211 MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 8
212
213 at 0x00000014 : */ 0xc0000004,0x00000000,0x00000758,
214 /*
215 MOVE dmode_memory_to_ncr TO DMODE
216
217 at 0x00000017 : */ 0x78380000,0x00000000,
218 /*
219 ;
220 ; Move the _contents_ of the next pointer into the DSA register as
221 ; the next I_T_L or I_T_L_Q tupple to check against the established
222 ; nexus.
223 ;
224 MOVE MEMORY 4, dsa_temp_next, addr_scratch
225
226 at 0x00000019 : */ 0xc0000004,0x00000000,0x00000000,
227 /*
228 MOVE dmode_memory_to_memory TO DMODE
229
230 at 0x0000001c : */ 0x78380000,0x00000000,
231 /*
232 CALL scratch_to_dsa
233
234 at 0x0000001e : */ 0x88080000,0x00000960,
235 /*
236 JUMP reselected_check_next
237
238 at 0x00000020 : */ 0x80080000,0x000006a4,
239 /*
240
241 ABSOLUTE dsa_save_data_pointer = 0
242 ENTRY dsa_code_save_data_pointer
243 dsa_code_save_data_pointer:
244 MOVE dmode_ncr_to_memory TO DMODE
245
246 at 0x00000022 : */ 0x78380000,0x00000000,
247 /*
248 MOVE MEMORY 4, addr_temp, dsa_temp_addr_saved_pointer
249
250 at 0x00000024 : */ 0xc0000004,0x00000000,0x00000000,
251 /*
252 MOVE dmode_memory_to_memory TO DMODE
253
254 at 0x00000027 : */ 0x78380000,0x00000000,
255 /*
256 ; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
257 MOVE MEMORY 24, dsa_temp_addr_residual, dsa_temp_addr_saved_residual
258
259 at 0x00000029 : */ 0xc0000018,0x00000000,0x00000000,
260 /*
261 CLEAR ACK
262
263 at 0x0000002c : */ 0x60000040,0x00000000,
264 /*
265
266
267
268 RETURN
269
270 at 0x0000002e : */ 0x90080000,0x00000000,
271 /*
272 ABSOLUTE dsa_restore_pointers = 0
273 ENTRY dsa_code_restore_pointers
274 dsa_code_restore_pointers:
275 MOVE dmode_memory_to_ncr TO DMODE
276
277 at 0x00000030 : */ 0x78380000,0x00000000,
278 /*
279 MOVE MEMORY 4, dsa_temp_addr_saved_pointer, addr_temp
280
281 at 0x00000032 : */ 0xc0000004,0x00000000,0x00000000,
282 /*
283 MOVE dmode_memory_to_memory TO DMODE
284
285 at 0x00000035 : */ 0x78380000,0x00000000,
286 /*
287 ; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
288 MOVE MEMORY 24, dsa_temp_addr_saved_residual, dsa_temp_addr_residual
289
290 at 0x00000037 : */ 0xc0000018,0x00000000,0x00000000,
291 /*
292 CLEAR ACK
293
294 at 0x0000003a : */ 0x60000040,0x00000000,
295 /*
296
297
298
299 RETURN
300
301 at 0x0000003c : */ 0x90080000,0x00000000,
302 /*
303
304 ABSOLUTE dsa_check_reselect = 0
305 ; dsa_check_reselect determines whether or not the current target and
306 ; lun match the current DSA
307 ENTRY dsa_code_check_reselect
308 dsa_code_check_reselect:
309 MOVE SSID TO SFBR ; SSID contains 3 bit target ID
310
311 at 0x0000003e : */ 0x720a0000,0x00000000,
312 /*
313 ; FIXME : we need to accomodate bit fielded and binary here for '7xx/'8xx chips
314 JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 0xf8
315
316 at 0x00000040 : */ 0x8084f800,0x00ffff48,
317 /*
318 ;
319 ; Hack - move to scratch first, since SFBR is not writeable
320 ; via the CPU and hence a MOVE MEMORY instruction.
321 ;
322 MOVE dmode_memory_to_ncr TO DMODE
323
324 at 0x00000042 : */ 0x78380000,0x00000000,
325 /*
326 MOVE MEMORY 1, reselected_identify, addr_scratch
327
328 at 0x00000044 : */ 0xc0000001,0x00000000,0x00000000,
329 /*
330 MOVE dmode_memory_to_memory TO DMODE
331
332 at 0x00000047 : */ 0x78380000,0x00000000,
333 /*
334 MOVE SCRATCH0 TO SFBR
335
336 at 0x00000049 : */ 0x72340000,0x00000000,
337 /*
338 ; FIXME : we need to accomodate bit fielded and binary here for '7xx/'8xx chips
339 JUMP REL (wrong_dsa), IF NOT dsa_temp_lun, AND MASK 0xf8
340
341 at 0x0000004b : */ 0x8084f800,0x00ffff1c,
342 /*
343 ; Patch the MOVE MEMORY INSTRUCTION such that
344 ; the source address is the address of this dsa's
345 ; next pointer.
346 MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 4
347
348 at 0x0000004d : */ 0xc0000004,0x00000000,0x00000754,
349 /*
350 CALL reselected_ok
351
352 at 0x00000050 : */ 0x88080000,0x00000750,
353 /*
354 CALL dsa_temp_sync
355
356 at 0x00000052 : */ 0x88080000,0x00000000,
357 /*
358 ; Release ACK on the IDENTIFY message _after_ we've set the synchronous
359 ; transfer parameters!
360 CLEAR ACK
361
362 at 0x00000054 : */ 0x60000040,0x00000000,
363 /*
364 ; Implicitly restore pointers on reselection, so a RETURN
365 ; will transfer control back to the right spot.
366 CALL REL (dsa_code_restore_pointers)
367
368 at 0x00000056 : */ 0x88880000,0x00ffff60,
369 /*
370 RETURN
371
372 at 0x00000058 : */ 0x90080000,0x00000000,
373 /*
374 ENTRY dsa_zero
375 dsa_zero:
376 ENTRY dsa_code_template_end
377 dsa_code_template_end:
378
379 ; Perform sanity check for dsa_fields_start == dsa_code_template_end -
380 ; dsa_zero, puke.
381
382 ABSOLUTE dsa_fields_start = 0 ; Sanity marker
383 ; pad 48 bytes (fix this RSN)
384 ABSOLUTE dsa_next = 48 ; len 4 Next DSA
385 ; del 4 Previous DSA address
386 ABSOLUTE dsa_cmnd = 56 ; len 4 Scsi_Cmnd * for this thread.
387 ABSOLUTE dsa_select = 60 ; len 4 Device ID, Period, Offset for
388 ; table indirect select
389 ABSOLUTE dsa_msgout = 64 ; len 8 table indirect move parameter for
390 ; select message
391 ABSOLUTE dsa_cmdout = 72 ; len 8 table indirect move parameter for
392 ; command
393 ABSOLUTE dsa_dataout = 80 ; len 4 code pointer for dataout
394 ABSOLUTE dsa_datain = 84 ; len 4 code pointer for datain
395 ABSOLUTE dsa_msgin = 88 ; len 8 table indirect move for msgin
396 ABSOLUTE dsa_status = 96 ; len 8 table indirect move for status byte
397 ABSOLUTE dsa_msgout_other = 104 ; len 8 table indirect for normal message out
398 ; (Synchronous transfer negotiation, etc).
399 ABSOLUTE dsa_end = 112
400
401 ABSOLUTE schedule = 0 ; Array of JUMP dsa_begin or JUMP (next),
402 ; terminated by a call to JUMP wait_reselect
403
404 ; Linked lists of DSA structures
405 ABSOLUTE reconnect_dsa_head = 0 ; Link list of DSAs which can reconnect
406 ABSOLUTE addr_reconnect_dsa_head = 0 ; Address of variable contataining
407 ; address of reconnect_dsa_head
408
409 ; These select the source and destination of a MOVE MEMORY instruction
410 ABSOLUTE dmode_memory_to_memory = 0x0
411 ABSOLUTE dmode_memory_to_ncr = 0x0
412 ABSOLUTE dmode_ncr_to_memory = 0x0
413
414 ABSOLUTE addr_scratch = 0x0
415 ABSOLUTE addr_temp = 0x0
416
417
418 ; Interrupts -
419 ; MSB indicates type
420 ; 0 handle error condition
421 ; 1 handle message
422 ; 2 handle normal condition
423 ; 3 debugging interrupt
424 ; 4 testing interrupt
425 ; Next byte indicates specific error
426
427 ; XXX not yet implemented, I'm not sure if I want to -
428 ; Next byte indicates the routine the error occurred in
429 ; The LSB indicates the specific place the error occurred
430
431 ABSOLUTE int_err_unexpected_phase = 0x00000000 ; Unexpected phase encountered
432 ABSOLUTE int_err_selected = 0x00010000 ; SELECTED (nee RESELECTED)
433 ABSOLUTE int_err_unexpected_reselect = 0x00020000
434 ABSOLUTE int_err_check_condition = 0x00030000
435 ABSOLUTE int_err_no_phase = 0x00040000
436 ABSOLUTE int_msg_wdtr = 0x01000000 ; WDTR message received
437 ABSOLUTE int_msg_sdtr = 0x01010000 ; SDTR received
438 ABSOLUTE int_msg_1 = 0x01020000 ; single byte special message
439 ; received
440
441 ABSOLUTE int_norm_select_complete = 0x02000000 ; Select complete, reprogram
442 ; registers.
443 ABSOLUTE int_norm_reselect_complete = 0x02010000 ; Nexus established
444 ABSOLUTE int_norm_command_complete = 0x02020000 ; Command complete
445 ABSOLUTE int_norm_disconnected = 0x02030000 ; Disconnected
446 ABSOLUTE int_norm_aborted =0x02040000 ; Aborted *dsa
447 ABSOLUTE int_norm_reset = 0x02050000 ; Generated BUS reset.
448 ABSOLUTE int_debug_break = 0x03000000 ; Break point
449
450 ABSOLUTE int_debug_panic = 0x030b0000 ; Panic driver
451
452
453 ABSOLUTE int_test_1 = 0x04000000 ; Test 1 complete
454 ABSOLUTE int_test_2 = 0x04010000 ; Test 2 complete
455 ABSOLUTE int_test_3 = 0x04020000 ; Test 3 complete
456
457
458 ; These should start with 0x05000000, with low bits incrementing for
459 ; each one.
460
461
462
463 ABSOLUTE NCR53c7xx_msg_abort = 0 ; Pointer to abort message
464 ABSOLUTE NCR53c7xx_msg_reject = 0 ; Pointer to reject message
465 ABSOLUTE NCR53c7xx_zero = 0 ; long with zero in it, use for source
466 ABSOLUTE NCR53c7xx_sink = 0 ; long to dump worthless data in
467 ABSOLUTE NOP_insn = 0 ; NOP instruction
468
469 ; Pointer to message, potentially multi-byte
470 ABSOLUTE msg_buf = 0
471
472 ; Pointer to holding area for reselection information
473 ABSOLUTE reselected_identify = 0
474 ABSOLUTE reselected_tag = 0
475
476 ; Request sense command pointer, it's a 6 byte command, should
477 ; be constant for all commands since we always want 16 bytes of
478 ; sense and we don't need to change any fields as we did under
479 ; SCSI-I when we actually cared about the LUN field.
480 ;EXTERNAL NCR53c7xx_sense ; Request sense command
481
482
483 ; dsa_schedule
484 ; PURPOSE : after a DISCONNECT message has been received, and pointers
485 ; saved, insert the current DSA structure at the head of the
486 ; disconnected queue and fall through to the scheduler.
487 ;
488 ; CALLS : OK
489 ;
490 ; INPUTS : dsa - current DSA structure, reconnect_dsa_head - list
491 ; of disconnected commands
492 ;
493 ; MODIFIES : SCRATCH, reconnect_dsa_head
494 ;
495 ; EXITS : always passes control to schedule
496
497 ENTRY dsa_schedule
498 dsa_schedule:
499
500
501
502
503 ;
504 ; Calculate the address of the next pointer within the DSA
505 ; structure of the command that is currently disconnecting
506 ;
507 CALL dsa_to_scratch
508
509 at 0x0000005a : */ 0x88080000,0x00000918,
510 /*
511 MOVE SCRATCH0 + dsa_next TO SCRATCH0
512
513 at 0x0000005c : */ 0x7e343000,0x00000000,
514 /*
515 MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
516
517 at 0x0000005e : */ 0x7f350000,0x00000000,
518 /*
519 MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
520
521 at 0x00000060 : */ 0x7f360000,0x00000000,
522 /*
523 MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
524
525 at 0x00000062 : */ 0x7f370000,0x00000000,
526 /*
527
528 ; Point the next field of this DSA structure at the current disconnected
529 ; list
530 MOVE dmode_ncr_to_memory TO DMODE
531
532 at 0x00000064 : */ 0x78380000,0x00000000,
533 /*
534 MOVE MEMORY 4, addr_scratch, dsa_schedule_insert + 8
535
536 at 0x00000066 : */ 0xc0000004,0x00000000,0x000001b4,
537 /*
538 MOVE dmode_memory_to_memory TO DMODE
539
540 at 0x00000069 : */ 0x78380000,0x00000000,
541 /*
542 dsa_schedule_insert:
543 MOVE MEMORY 4, reconnect_dsa_head, 0
544
545 at 0x0000006b : */ 0xc0000004,0x00000000,0x00000000,
546 /*
547
548 ; And update the head pointer.
549 CALL dsa_to_scratch
550
551 at 0x0000006e : */ 0x88080000,0x00000918,
552 /*
553 MOVE dmode_ncr_to_memory TO DMODE
554
555 at 0x00000070 : */ 0x78380000,0x00000000,
556 /*
557 MOVE MEMORY 4, addr_scratch, reconnect_dsa_head
558
559 at 0x00000072 : */ 0xc0000004,0x00000000,0x00000000,
560 /*
561 MOVE dmode_memory_to_memory TO DMODE
562
563 at 0x00000075 : */ 0x78380000,0x00000000,
564 /*
565
566
567 MOVE SCNTL2 & 0x7f TO SCNTL2
568
569 at 0x00000077 : */ 0x7c027f00,0x00000000,
570 /*
571 CLEAR ACK
572
573 at 0x00000079 : */ 0x60000040,0x00000000,
574 /*
575
576 WAIT DISCONNECT
577
578 at 0x0000007b : */ 0x48000000,0x00000000,
579 /*
580
581
582
583
584
585
586 JUMP schedule
587
588 at 0x0000007d : */ 0x80080000,0x00000000,
589 /*
590
591
592 ;
593 ; select
594 ;
595 ; PURPOSE : establish a nexus for the SCSI command referenced by DSA.
596 ; On success, the current DSA structure is removed from the issue
597 ; queue. Usually, this is entered as a fall-through from schedule,
598 ; although the contingent allegiance handling code will write
599 ; the select entry address to the DSP to restart a command as a
600 ; REQUEST SENSE. A message is sent (usually IDENTIFY, although
601 ; additional SDTR or WDTR messages may be sent). COMMAND OUT
602 ; is handled.
603 ;
604 ; INPUTS : DSA - SCSI command, issue_dsa_head
605 ;
606 ; CALLS : NOT OK
607 ;
608 ; MODIFIES : SCRATCH, issue_dsa_head
609 ;
610 ; EXITS : on reselection or selection, go to select_failed
611 ; otherwise, RETURN so control is passed back to
612 ; dsa_begin.
613 ;
614
615 ENTRY select
616 select:
617
618
619
620
621
622
623
624
625
626
627
628
629 CLEAR TARGET
630
631 at 0x0000007f : */ 0x60000200,0x00000000,
632 /*
633
634 ; XXX
635 ;
636 ; In effect, SELECTION operations are backgrounded, with execution
637 ; continuing until code which waits for REQ or a fatal interrupt is
638 ; encountered.
639 ;
640 ; So, for more performance, we could overlap the code which removes
641 ; the command from the NCRs issue queue with the selection, but
642 ; at this point I don't want to deal with the error recovery.
643 ;
644
645
646 SELECT ATN FROM dsa_select, select_failed
647
648 at 0x00000081 : */ 0x4300003c,0x00000794,
649 /*
650 JUMP select_msgout, WHEN MSG_OUT
651
652 at 0x00000083 : */ 0x860b0000,0x00000214,
653 /*
654 ENTRY select_msgout
655 select_msgout:
656 MOVE FROM dsa_msgout, WHEN MSG_OUT
657
658 at 0x00000085 : */ 0x1e000000,0x00000040,
659 /*
660
661
662
663
664
665
666
667
668
669
670 RETURN
671
672 at 0x00000087 : */ 0x90080000,0x00000000,
673 /*
674
675 ;
676 ; select_done
677 ;
678 ; PURPOSE: continue on to normal data transfer; called as the exit
679 ; point from dsa_begin.
680 ;
681 ; INPUTS: dsa
682 ;
683 ; CALLS: OK
684 ;
685 ;
686
687 select_done:
688
689
690
691
692
693
694
695 ; After a successful selection, we should get either a CMD phase or
696 ; some transfer request negotiation message.
697
698 JUMP cmdout, WHEN CMD
699
700 at 0x00000089 : */ 0x820b0000,0x00000244,
701 /*
702 INT int_err_unexpected_phase, WHEN NOT MSG_IN
703
704 at 0x0000008b : */ 0x9f030000,0x00000000,
705 /*
706
707 select_msg_in:
708 CALL msg_in, WHEN MSG_IN
709
710 at 0x0000008d : */ 0x8f0b0000,0x00000404,
711 /*
712 JUMP select_msg_in, WHEN MSG_IN
713
714 at 0x0000008f : */ 0x870b0000,0x00000234,
715 /*
716
717 cmdout:
718 INT int_err_unexpected_phase, WHEN NOT CMD
719
720 at 0x00000091 : */ 0x9a030000,0x00000000,
721 /*
722
723
724
725 ENTRY cmdout_cmdout
726 cmdout_cmdout:
727
728 MOVE FROM dsa_cmdout, WHEN CMD
729
730 at 0x00000093 : */ 0x1a000000,0x00000048,
731 /*
732
733
734
735
736 ;
737 ; data_transfer
738 ; other_out
739 ; other_in
740 ; other_transfer
741 ;
742 ; PURPOSE : handle the main data transfer for a SCSI command in
743 ; several parts. In the first part, data_transfer, DATA_IN
744 ; and DATA_OUT phases are allowed, with the user provided
745 ; code (usually dynamically generated based on the scatter/gather
746 ; list associated with a SCSI command) called to handle these
747 ; phases.
748 ;
749 ; After control has passed to one of the user provided
750 ; DATA_IN or DATA_OUT routines, back calls are made to
751 ; other_tranfer_in or other_transfer_out to handle non-DATA IN
752 ; and DATA OUT phases respectively, with the state of the active
753 ; data pointer being preserved in TEMP.
754 ;
755 ; On completion, the user code passes control to other_transfer
756 ; which causes DATA_IN and DATA_OUT to result in unexpected_phase
757 ; interrupts so that data overruns may be trapped.
758 ;
759 ; INPUTS : DSA - SCSI command
760 ;
761 ; CALLS : OK in data_transfer_start, not ok in other_out and other_in, ok in
762 ; other_transfer
763 ;
764 ; MODIFIES : SCRATCH
765 ;
766 ; EXITS : if STATUS IN is detected, signifying command completion,
767 ; the NCR jumps to command_complete. If MSG IN occurs, a
768 ; CALL is made to msg_in. Otherwise, other_transfer runs in
769 ; an infinite loop.
770 ;
771
772 ENTRY data_transfer
773 data_transfer:
774 JUMP cmdout_cmdout, WHEN CMD
775
776 at 0x00000095 : */ 0x820b0000,0x0000024c,
777 /*
778 CALL msg_in, WHEN MSG_IN
779
780 at 0x00000097 : */ 0x8f0b0000,0x00000404,
781 /*
782 INT int_err_unexpected_phase, WHEN MSG_OUT
783
784 at 0x00000099 : */ 0x9e0b0000,0x00000000,
785 /*
786 JUMP do_dataout, WHEN DATA_OUT
787
788 at 0x0000009b : */ 0x800b0000,0x0000028c,
789 /*
790 JUMP do_datain, WHEN DATA_IN
791
792 at 0x0000009d : */ 0x810b0000,0x000002e4,
793 /*
794 JUMP command_complete, WHEN STATUS
795
796 at 0x0000009f : */ 0x830b0000,0x0000060c,
797 /*
798 JUMP data_transfer
799
800 at 0x000000a1 : */ 0x80080000,0x00000254,
801 /*
802 ENTRY end_data_transfer
803 end_data_transfer:
804
805 ;
806 ; FIXME: On NCR53c700 and NCR53c700-66 chips, do_dataout/do_datain
807 ; should be fixed up whenever the nexus changes so it can point to the
808 ; correct routine for that command.
809 ;
810
811
812 ; Nasty jump to dsa->dataout
813 do_dataout:
814 CALL dsa_to_scratch
815
816 at 0x000000a3 : */ 0x88080000,0x00000918,
817 /*
818 MOVE SCRATCH0 + dsa_dataout TO SCRATCH0
819
820 at 0x000000a5 : */ 0x7e345000,0x00000000,
821 /*
822 MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
823
824 at 0x000000a7 : */ 0x7f350000,0x00000000,
825 /*
826 MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
827
828 at 0x000000a9 : */ 0x7f360000,0x00000000,
829 /*
830 MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
831
832 at 0x000000ab : */ 0x7f370000,0x00000000,
833 /*
834 MOVE dmode_ncr_to_memory TO DMODE
835
836 at 0x000000ad : */ 0x78380000,0x00000000,
837 /*
838 MOVE MEMORY 4, addr_scratch, dataout_to_jump + 4
839
840 at 0x000000af : */ 0xc0000004,0x00000000,0x000002d4,
841 /*
842 MOVE dmode_memory_to_memory TO DMODE
843
844 at 0x000000b2 : */ 0x78380000,0x00000000,
845 /*
846 dataout_to_jump:
847 MOVE MEMORY 4, 0, dataout_jump + 4
848
849 at 0x000000b4 : */ 0xc0000004,0x00000000,0x000002e0,
850 /*
851 dataout_jump:
852 JUMP 0
853
854 at 0x000000b7 : */ 0x80080000,0x00000000,
855 /*
856
857 ; Nasty jump to dsa->dsain
858 do_datain:
859 CALL dsa_to_scratch
860
861 at 0x000000b9 : */ 0x88080000,0x00000918,
862 /*
863 MOVE SCRATCH0 + dsa_datain TO SCRATCH0
864
865 at 0x000000bb : */ 0x7e345400,0x00000000,
866 /*
867 MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
868
869 at 0x000000bd : */ 0x7f350000,0x00000000,
870 /*
871 MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
872
873 at 0x000000bf : */ 0x7f360000,0x00000000,
874 /*
875 MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
876
877 at 0x000000c1 : */ 0x7f370000,0x00000000,
878 /*
879 MOVE dmode_ncr_to_memory TO DMODE
880
881 at 0x000000c3 : */ 0x78380000,0x00000000,
882 /*
883 MOVE MEMORY 4, addr_scratch, datain_to_jump + 4
884
885 at 0x000000c5 : */ 0xc0000004,0x00000000,0x0000032c,
886 /*
887 MOVE dmode_memory_to_memory TO DMODE
888
889 at 0x000000c8 : */ 0x78380000,0x00000000,
890 /*
891 ENTRY datain_to_jump
892 datain_to_jump:
893 MOVE MEMORY 4, 0, datain_jump + 4
894
895 at 0x000000ca : */ 0xc0000004,0x00000000,0x00000338,
896 /*
897
898
899
900 datain_jump:
901 JUMP 0
902
903 at 0x000000cd : */ 0x80080000,0x00000000,
904 /*
905
906
907
908 ; Note that other_out and other_in loop until a non-data phase
909 ; is discoverred, so we only execute return statements when we
910 ; can go on to the next data phase block move statement.
911
912 ENTRY other_out
913 other_out:
914
915
916
917 INT int_err_unexpected_phase, WHEN CMD
918
919 at 0x000000cf : */ 0x9a0b0000,0x00000000,
920 /*
921 JUMP msg_in_restart, WHEN MSG_IN
922
923 at 0x000000d1 : */ 0x870b0000,0x000003e4,
924 /*
925 INT int_err_unexpected_phase, WHEN MSG_OUT
926
927 at 0x000000d3 : */ 0x9e0b0000,0x00000000,
928 /*
929 INT int_err_unexpected_phase, WHEN DATA_IN
930
931 at 0x000000d5 : */ 0x990b0000,0x00000000,
932 /*
933 JUMP command_complete, WHEN STATUS
934
935 at 0x000000d7 : */ 0x830b0000,0x0000060c,
936 /*
937 JUMP other_out, WHEN NOT DATA_OUT
938
939 at 0x000000d9 : */ 0x80030000,0x0000033c,
940 /*
941 RETURN
942
943 at 0x000000db : */ 0x90080000,0x00000000,
944 /*
945
946 ENTRY other_in
947 other_in:
948
949
950
951 INT int_err_unexpected_phase, WHEN CMD
952
953 at 0x000000dd : */ 0x9a0b0000,0x00000000,
954 /*
955 JUMP msg_in_restart, WHEN MSG_IN
956
957 at 0x000000df : */ 0x870b0000,0x000003e4,
958 /*
959 INT int_err_unexpected_phase, WHEN MSG_OUT
960
961 at 0x000000e1 : */ 0x9e0b0000,0x00000000,
962 /*
963 INT int_err_unexpected_phase, WHEN DATA_OUT
964
965 at 0x000000e3 : */ 0x980b0000,0x00000000,
966 /*
967 JUMP command_complete, WHEN STATUS
968
969 at 0x000000e5 : */ 0x830b0000,0x0000060c,
970 /*
971 JUMP other_in, WHEN NOT DATA_IN
972
973 at 0x000000e7 : */ 0x81030000,0x00000374,
974 /*
975 RETURN
976
977 at 0x000000e9 : */ 0x90080000,0x00000000,
978 /*
979
980
981 ENTRY other_transfer
982 other_transfer:
983 INT int_err_unexpected_phase, WHEN CMD
984
985 at 0x000000eb : */ 0x9a0b0000,0x00000000,
986 /*
987 CALL msg_in, WHEN MSG_IN
988
989 at 0x000000ed : */ 0x8f0b0000,0x00000404,
990 /*
991 INT int_err_unexpected_phase, WHEN MSG_OUT
992
993 at 0x000000ef : */ 0x9e0b0000,0x00000000,
994 /*
995 INT int_err_unexpected_phase, WHEN DATA_OUT
996
997 at 0x000000f1 : */ 0x980b0000,0x00000000,
998 /*
999 INT int_err_unexpected_phase, WHEN DATA_IN
1000
1001 at 0x000000f3 : */ 0x990b0000,0x00000000,
1002 /*
1003 JUMP command_complete, WHEN STATUS
1004
1005 at 0x000000f5 : */ 0x830b0000,0x0000060c,
1006 /*
1007 JUMP other_transfer
1008
1009 at 0x000000f7 : */ 0x80080000,0x000003ac,
1010 /*
1011
1012 ;
1013 ; msg_in_restart
1014 ; msg_in
1015 ; munge_msg
1016 ;
1017 ; PURPOSE : process messages from a target. msg_in is called when the
1018 ; caller hasn't read the first byte of the message. munge_message
1019 ; is called when the caller has read the first byte of the message,
1020 ; and left it in SFBR. msg_in_restart is called when the caller
1021 ; hasnt read the first byte of the message, and wishes RETURN
1022 ; to transfer control back to the address of the conditional
1023 ; CALL instruction rather than to the instruction after it.
1024 ;
1025 ; Various int_* interrupts are generated when the host system
1026 ; needs to intervene, as is the case with SDTR, WDTR, and
1027 ; INITIATE RECOVERY messages.
1028 ;
1029 ; When the host system handles one of these interrupts,
1030 ; it can respond by reentering at reject_message,
1031 ; which rejects the message and returns control to
1032 ; the caller of msg_in or munge_msg, accept_message
1033 ; which clears ACK and returns control, or reply_message
1034 ; which sends the message pointed to by the DSA
1035 ; msgout_other table indirect field.
1036 ;
1037 ; DISCONNECT messages are handled by moving the command
1038 ; to the reconnect_dsa_queue.
1039 ;
1040 ; INPUTS : DSA - SCSI COMMAND, SFBR - first byte of message (munge_msg
1041 ; only)
1042 ;
1043 ; CALLS : NO. The TEMP register isn't backed up to allow nested calls.
1044 ;
1045 ; MODIFIES : SCRATCH, DSA on DISCONNECT
1046 ;
1047 ; EXITS : On receipt of SAVE DATA POINTER, RESTORE POINTERS,
1048 ; and normal return from message handlers running under
1049 ; Linux, control is returned to the caller. Receipt
1050 ; of DISCONNECT messages pass control to dsa_schedule.
1051 ;
1052 ENTRY msg_in_restart
1053 msg_in_restart:
1054 ; XXX - hackish
1055 ;
1056 ; Since it's easier to debug changes to the statically
1057 ; compiled code, rather than the dynamically generated
1058 ; stuff, such as
1059 ;
1060 ; MOVE x, y, WHEN data_phase
1061 ; CALL other_z, WHEN NOT data_phase
1062 ; MOVE x, y, WHEN data_phase
1063 ;
1064 ; I'd like to have certain routines (notably the message handler)
1065 ; restart on the conditional call rather than the next instruction.
1066 ;
1067 ; So, subtract 8 from the return address
1068
1069 MOVE TEMP0 + 0xf8 TO TEMP0
1070
1071 at 0x000000f9 : */ 0x7e1cf800,0x00000000,
1072 /*
1073 MOVE TEMP1 + 0xff TO TEMP1 WITH CARRY
1074
1075 at 0x000000fb : */ 0x7f1dff00,0x00000000,
1076 /*
1077 MOVE TEMP2 + 0xff TO TEMP2 WITH CARRY
1078
1079 at 0x000000fd : */ 0x7f1eff00,0x00000000,
1080 /*
1081 MOVE TEMP3 + 0xff TO TEMP3 WITH CARRY
1082
1083 at 0x000000ff : */ 0x7f1fff00,0x00000000,
1084 /*
1085
1086 ENTRY msg_in
1087 msg_in:
1088 MOVE 1, msg_buf, WHEN MSG_IN
1089
1090 at 0x00000101 : */ 0x0f000001,0x00000000,
1091 /*
1092
1093 munge_msg:
1094 JUMP munge_extended, IF 0x01 ; EXTENDED MESSAGE
1095
1096 at 0x00000103 : */ 0x800c0001,0x00000524,
1097 /*
1098 JUMP munge_2, IF 0x20, AND MASK 0xdf ; two byte message
1099
1100 at 0x00000105 : */ 0x800cdf20,0x0000044c,
1101 /*
1102 ;
1103 ; XXX - I've seen a handful of broken SCSI devices which fail to issue
1104 ; a SAVE POINTERS message before disconnecting in the middle of
1105 ; a transfer, assuming that the DATA POINTER will be implicitly
1106 ; restored.
1107 ;
1108 ; Historically, I've often done an implicit save when the DISCONNECT
1109 ; message is processed. We may want to consider having the option of
1110 ; doing that here.
1111 ;
1112 JUMP munge_save_data_pointer, IF 0x02 ; SAVE DATA POINTER
1113
1114 at 0x00000107 : */ 0x800c0002,0x00000454,
1115 /*
1116 JUMP munge_restore_pointers, IF 0x03 ; RESTORE POINTERS
1117
1118 at 0x00000109 : */ 0x800c0003,0x000004b8,
1119 /*
1120 JUMP munge_disconnect, IF 0x04 ; DISCONNECT
1121
1122 at 0x0000010b : */ 0x800c0004,0x0000051c,
1123 /*
1124 INT int_msg_1, IF 0x07 ; MESSAGE REJECT
1125
1126 at 0x0000010d : */ 0x980c0007,0x01020000,
1127 /*
1128 INT int_msg_1, IF 0x0f ; INITIATE RECOVERY
1129
1130 at 0x0000010f : */ 0x980c000f,0x01020000,
1131 /*
1132
1133
1134
1135 JUMP reject_message
1136
1137 at 0x00000111 : */ 0x80080000,0x000005b4,
1138 /*
1139
1140 munge_2:
1141 JUMP reject_message
1142
1143 at 0x00000113 : */ 0x80080000,0x000005b4,
1144 /*
1145 ;
1146 ; The SCSI standard allows targets to recover from transient
1147 ; error conditions by backing up the data pointer with a
1148 ; RESTORE POINTERS message.
1149 ;
1150 ; So, we must save and restore the _residual_ code as well as
1151 ; the current instruction pointer. Because of this messiness,
1152 ; it is simpler to put dynamic code in the dsa for this and to
1153 ; just do a simple jump down there.
1154 ;
1155
1156 munge_save_data_pointer:
1157 MOVE DSA0 + dsa_save_data_pointer TO SFBR
1158
1159 at 0x00000115 : */ 0x76100000,0x00000000,
1160 /*
1161 MOVE SFBR TO SCRATCH0
1162
1163 at 0x00000117 : */ 0x6a340000,0x00000000,
1164 /*
1165 MOVE DSA1 + 0xff TO SFBR WITH CARRY
1166
1167 at 0x00000119 : */ 0x7711ff00,0x00000000,
1168 /*
1169 MOVE SFBR TO SCRATCH1
1170
1171 at 0x0000011b : */ 0x6a350000,0x00000000,
1172 /*
1173 MOVE DSA2 + 0xff TO SFBR WITH CARRY
1174
1175 at 0x0000011d : */ 0x7712ff00,0x00000000,
1176 /*
1177 MOVE SFBR TO SCRATCH2
1178
1179 at 0x0000011f : */ 0x6a360000,0x00000000,
1180 /*
1181 MOVE DSA3 + 0xff TO SFBR WITH CARRY
1182
1183 at 0x00000121 : */ 0x7713ff00,0x00000000,
1184 /*
1185 MOVE SFBR TO SCRATCH3
1186
1187 at 0x00000123 : */ 0x6a370000,0x00000000,
1188 /*
1189
1190 MOVE dmode_ncr_to_memory TO DMODE
1191
1192 at 0x00000125 : */ 0x78380000,0x00000000,
1193 /*
1194 MOVE MEMORY 4, addr_scratch, jump_dsa_save + 4
1195
1196 at 0x00000127 : */ 0xc0000004,0x00000000,0x000004b4,
1197 /*
1198 MOVE dmode_memory_to_memory TO DMODE
1199
1200 at 0x0000012a : */ 0x78380000,0x00000000,
1201 /*
1202 jump_dsa_save:
1203 JUMP 0
1204
1205 at 0x0000012c : */ 0x80080000,0x00000000,
1206 /*
1207
1208 munge_restore_pointers:
1209 MOVE DSA0 + dsa_restore_pointers TO SFBR
1210
1211 at 0x0000012e : */ 0x76100000,0x00000000,
1212 /*
1213 MOVE SFBR TO SCRATCH0
1214
1215 at 0x00000130 : */ 0x6a340000,0x00000000,
1216 /*
1217 MOVE DSA1 + 0xff TO SFBR WITH CARRY
1218
1219 at 0x00000132 : */ 0x7711ff00,0x00000000,
1220 /*
1221 MOVE SFBR TO SCRATCH1
1222
1223 at 0x00000134 : */ 0x6a350000,0x00000000,
1224 /*
1225 MOVE DSA2 + 0xff TO SFBR WITH CARRY
1226
1227 at 0x00000136 : */ 0x7712ff00,0x00000000,
1228 /*
1229 MOVE SFBR TO SCRATCH2
1230
1231 at 0x00000138 : */ 0x6a360000,0x00000000,
1232 /*
1233 MOVE DSA3 + 0xff TO SFBR WITH CARRY
1234
1235 at 0x0000013a : */ 0x7713ff00,0x00000000,
1236 /*
1237 MOVE SFBR TO SCRATCH3
1238
1239 at 0x0000013c : */ 0x6a370000,0x00000000,
1240 /*
1241
1242 MOVE dmode_ncr_to_memory TO DMODE
1243
1244 at 0x0000013e : */ 0x78380000,0x00000000,
1245 /*
1246 MOVE MEMORY 4, addr_scratch, jump_dsa_restore + 4
1247
1248 at 0x00000140 : */ 0xc0000004,0x00000000,0x00000518,
1249 /*
1250 MOVE dmode_memory_to_memory TO DMODE
1251
1252 at 0x00000143 : */ 0x78380000,0x00000000,
1253 /*
1254 jump_dsa_restore:
1255 JUMP 0
1256
1257 at 0x00000145 : */ 0x80080000,0x00000000,
1258 /*
1259
1260
1261 munge_disconnect:
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278 JUMP dsa_schedule
1279
1280 at 0x00000147 : */ 0x80080000,0x00000168,
1281 /*
1282
1283
1284
1285
1286
1287 munge_extended:
1288 CLEAR ACK
1289
1290 at 0x00000149 : */ 0x60000040,0x00000000,
1291 /*
1292 INT int_err_unexpected_phase, WHEN NOT MSG_IN
1293
1294 at 0x0000014b : */ 0x9f030000,0x00000000,
1295 /*
1296 MOVE 1, msg_buf + 1, WHEN MSG_IN
1297
1298 at 0x0000014d : */ 0x0f000001,0x00000001,
1299 /*
1300 JUMP munge_extended_2, IF 0x02
1301
1302 at 0x0000014f : */ 0x800c0002,0x00000554,
1303 /*
1304 JUMP munge_extended_3, IF 0x03
1305
1306 at 0x00000151 : */ 0x800c0003,0x00000584,
1307 /*
1308 JUMP reject_message
1309
1310 at 0x00000153 : */ 0x80080000,0x000005b4,
1311 /*
1312
1313 munge_extended_2:
1314 CLEAR ACK
1315
1316 at 0x00000155 : */ 0x60000040,0x00000000,
1317 /*
1318 MOVE 1, msg_buf + 2, WHEN MSG_IN
1319
1320 at 0x00000157 : */ 0x0f000001,0x00000002,
1321 /*
1322 JUMP reject_message, IF NOT 0x02 ; Must be WDTR
1323
1324 at 0x00000159 : */ 0x80040002,0x000005b4,
1325 /*
1326 CLEAR ACK
1327
1328 at 0x0000015b : */ 0x60000040,0x00000000,
1329 /*
1330 MOVE 1, msg_buf + 3, WHEN MSG_IN
1331
1332 at 0x0000015d : */ 0x0f000001,0x00000003,
1333 /*
1334 INT int_msg_wdtr
1335
1336 at 0x0000015f : */ 0x98080000,0x01000000,
1337 /*
1338
1339 munge_extended_3:
1340 CLEAR ACK
1341
1342 at 0x00000161 : */ 0x60000040,0x00000000,
1343 /*
1344 MOVE 1, msg_buf + 2, WHEN MSG_IN
1345
1346 at 0x00000163 : */ 0x0f000001,0x00000002,
1347 /*
1348 JUMP reject_message, IF NOT 0x01 ; Must be SDTR
1349
1350 at 0x00000165 : */ 0x80040001,0x000005b4,
1351 /*
1352 CLEAR ACK
1353
1354 at 0x00000167 : */ 0x60000040,0x00000000,
1355 /*
1356 MOVE 2, msg_buf + 3, WHEN MSG_IN
1357
1358 at 0x00000169 : */ 0x0f000002,0x00000003,
1359 /*
1360 INT int_msg_sdtr
1361
1362 at 0x0000016b : */ 0x98080000,0x01010000,
1363 /*
1364
1365 ENTRY reject_message
1366 reject_message:
1367 SET ATN
1368
1369 at 0x0000016d : */ 0x58000008,0x00000000,
1370 /*
1371 CLEAR ACK
1372
1373 at 0x0000016f : */ 0x60000040,0x00000000,
1374 /*
1375 MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT
1376
1377 at 0x00000171 : */ 0x0e000001,0x00000000,
1378 /*
1379 RETURN
1380
1381 at 0x00000173 : */ 0x90080000,0x00000000,
1382 /*
1383
1384 ENTRY accept_message
1385 accept_message:
1386 CLEAR ATN
1387
1388 at 0x00000175 : */ 0x60000008,0x00000000,
1389 /*
1390 CLEAR ACK
1391
1392 at 0x00000177 : */ 0x60000040,0x00000000,
1393 /*
1394 RETURN
1395
1396 at 0x00000179 : */ 0x90080000,0x00000000,
1397 /*
1398
1399 ENTRY respond_message
1400 respond_message:
1401 SET ATN
1402
1403 at 0x0000017b : */ 0x58000008,0x00000000,
1404 /*
1405 CLEAR ACK
1406
1407 at 0x0000017d : */ 0x60000040,0x00000000,
1408 /*
1409 MOVE FROM dsa_msgout_other, WHEN MSG_OUT
1410
1411 at 0x0000017f : */ 0x1e000000,0x00000068,
1412 /*
1413 RETURN
1414
1415 at 0x00000181 : */ 0x90080000,0x00000000,
1416 /*
1417
1418 ;
1419 ; command_complete
1420 ;
1421 ; PURPOSE : handle command termination when STATUS IN is detected by reading
1422 ; a status byte followed by a command termination message.
1423 ;
1424 ; Normal termination results in an INTFLY instruction, and
1425 ; the host system can pick out which command terminated by
1426 ; examining the MESSAGE and STATUS buffers of all currently
1427 ; executing commands;
1428 ;
1429 ; Abnormal (CHECK_CONDITION) termination results in an
1430 ; int_err_check_condition interrupt so that a REQUEST SENSE
1431 ; command can be issued out-of-order so that no other command
1432 ; clears the contingent allegiance condition.
1433 ;
1434 ;
1435 ; INPUTS : DSA - command
1436 ;
1437 ; CALLS : OK
1438 ;
1439 ; EXITS : On successful termination, control is passed to schedule.
1440 ; On abnormal termination, the user will usually modify the
1441 ; DSA fields and corresponding buffers and return control
1442 ; to select.
1443 ;
1444
1445 ENTRY command_complete
1446 command_complete:
1447 MOVE FROM dsa_status, WHEN STATUS
1448
1449 at 0x00000183 : */ 0x1b000000,0x00000060,
1450 /*
1451
1452 MOVE SFBR TO SCRATCH0 ; Save status
1453
1454 at 0x00000185 : */ 0x6a340000,0x00000000,
1455 /*
1456
1457 ENTRY command_complete_msgin
1458 command_complete_msgin:
1459 MOVE FROM dsa_msgin, WHEN MSG_IN
1460
1461 at 0x00000187 : */ 0x1f000000,0x00000058,
1462 /*
1463 ; Indicate that we should be expecting a disconnect
1464 MOVE SCNTL2 & 0x7f TO SCNTL2
1465
1466 at 0x00000189 : */ 0x7c027f00,0x00000000,
1467 /*
1468 CLEAR ACK
1469
1470 at 0x0000018b : */ 0x60000040,0x00000000,
1471 /*
1472
1473 WAIT DISCONNECT
1474
1475 at 0x0000018d : */ 0x48000000,0x00000000,
1476 /*
1477
1478 ;
1479 ; The SCSI specification states that when a UNIT ATTENTION condition
1480 ; is pending, as indicated by a CHECK CONDITION status message,
1481 ; the target shall revert to asynchronous transfers. Since
1482 ; synchronous transfers parameters are maintained on a per INITIATOR/TARGET
1483 ; basis, and returning control to our scheduler could work on a command
1484 ; running on another lun on that target using the old parameters, we must
1485 ; interrupt the host processor to get them changed, or change them ourselves.
1486 ;
1487 ; Once SCSI-II tagged queueing is implemented, things will be even more
1488 ; hairy, since contingent allegiance conditions exist on a per-target/lun
1489 ; basis, and issuing a new command with a different tag would clear it.
1490 ; In these cases, we must interrupt the host processor to get a request
1491 ; added to the HEAD of the queue with the request sense command, or we
1492 ; must automatically issue the request sense command.
1493
1494
1495
1496
1497
1498 INTFLY
1499
1500 at 0x0000018f : */ 0x98180000,0x00000000,
1501 /*
1502
1503
1504
1505
1506
1507 JUMP schedule
1508
1509 at 0x00000191 : */ 0x80080000,0x00000000,
1510 /*
1511 command_failed:
1512 INT int_err_check_condition
1513
1514 at 0x00000193 : */ 0x98080000,0x00030000,
1515 /*
1516
1517
1518
1519
1520 ;
1521 ; wait_reselect
1522 ;
1523 ; PURPOSE : This is essentially the idle routine, where control lands
1524 ; when there are no new processes to schedule. wait_reselect
1525 ; waits for reselection, selection, and new commands.
1526 ;
1527 ; When a successful reselection occurs, with the aid
1528 ; of fixed up code in each DSA, wait_reselect walks the
1529 ; reconnect_dsa_queue, asking each dsa if the target ID
1530 ; and LUN match its.
1531 ;
1532 ; If a match is found, a call is made back to reselected_ok,
1533 ; which through the miracles of self modifying code, extracts
1534 ; the found DSA from the reconnect_dsa_queue and then
1535 ; returns control to the DSAs thread of execution.
1536 ;
1537 ; INPUTS : NONE
1538 ;
1539 ; CALLS : OK
1540 ;
1541 ; MODIFIES : DSA,
1542 ;
1543 ; EXITS : On successful reselection, control is returned to the
1544 ; DSA which called reselected_ok. If the WAIT RESELECT
1545 ; was interrupted by a new commands arrival signaled by
1546 ; SIG_P, control is passed to schedule. If the NCR is
1547 ; selected, the host system is interrupted with an
1548 ; int_err_selected which is usually responded to by
1549 ; setting DSP to the target_abort address.
1550
1551 ENTRY wait_reselect
1552 wait_reselect:
1553
1554
1555
1556
1557
1558
1559 WAIT RESELECT wait_reselect_failed
1560
1561 at 0x00000195 : */ 0x50000000,0x0000076c,
1562 /*
1563
1564 reselected:
1565
1566
1567
1568 CLEAR TARGET
1569
1570 at 0x00000197 : */ 0x60000200,0x00000000,
1571 /*
1572 MOVE dmode_memory_to_memory TO DMODE
1573
1574 at 0x00000199 : */ 0x78380000,0x00000000,
1575 /*
1576 ; Read all data needed to reestablish the nexus -
1577 MOVE 1, reselected_identify, WHEN MSG_IN
1578
1579 at 0x0000019b : */ 0x0f000001,0x00000000,
1580 /*
1581 ; We used to CLEAR ACK here.
1582
1583
1584
1585
1586
1587 ; Point DSA at the current head of the disconnected queue.
1588 MOVE dmode_memory_to_ncr TO DMODE
1589
1590 at 0x0000019d : */ 0x78380000,0x00000000,
1591 /*
1592 MOVE MEMORY 4, reconnect_dsa_head, addr_scratch
1593
1594 at 0x0000019f : */ 0xc0000004,0x00000000,0x00000000,
1595 /*
1596 MOVE dmode_memory_to_memory TO DMODE
1597
1598 at 0x000001a2 : */ 0x78380000,0x00000000,
1599 /*
1600 CALL scratch_to_dsa
1601
1602 at 0x000001a4 : */ 0x88080000,0x00000960,
1603 /*
1604
1605 ; Fix the update-next pointer so that the reconnect_dsa_head
1606 ; pointer is the one that will be updated if this DSA is a hit
1607 ; and we remove it from the queue.
1608
1609 MOVE MEMORY 4, addr_reconnect_dsa_head, reselected_ok + 8
1610
1611 at 0x000001a6 : */ 0xc0000004,0x00000000,0x00000758,
1612 /*
1613
1614 ENTRY reselected_check_next
1615 reselected_check_next:
1616
1617
1618
1619 ; Check for a NULL pointer.
1620 MOVE DSA0 TO SFBR
1621
1622 at 0x000001a9 : */ 0x72100000,0x00000000,
1623 /*
1624 JUMP reselected_not_end, IF NOT 0
1625
1626 at 0x000001ab : */ 0x80040000,0x000006ec,
1627 /*
1628 MOVE DSA1 TO SFBR
1629
1630 at 0x000001ad : */ 0x72110000,0x00000000,
1631 /*
1632 JUMP reselected_not_end, IF NOT 0
1633
1634 at 0x000001af : */ 0x80040000,0x000006ec,
1635 /*
1636 MOVE DSA2 TO SFBR
1637
1638 at 0x000001b1 : */ 0x72120000,0x00000000,
1639 /*
1640 JUMP reselected_not_end, IF NOT 0
1641
1642 at 0x000001b3 : */ 0x80040000,0x000006ec,
1643 /*
1644 MOVE DSA3 TO SFBR
1645
1646 at 0x000001b5 : */ 0x72130000,0x00000000,
1647 /*
1648 JUMP reselected_not_end, IF NOT 0
1649
1650 at 0x000001b7 : */ 0x80040000,0x000006ec,
1651 /*
1652 INT int_err_unexpected_reselect
1653
1654 at 0x000001b9 : */ 0x98080000,0x00020000,
1655 /*
1656
1657 reselected_not_end:
1658 ;
1659 ; XXX the ALU is only eight bits wide, and the assembler
1660 ; wont do the dirt work for us. As long as dsa_check_reselect
1661 ; is negative, we need to sign extend with 1 bits to the full
1662 ; 32 bit width of the address.
1663 ;
1664 ; A potential work around would be to have a known alignment
1665 ; of the DSA structure such that the base address plus
1666 ; dsa_check_reselect doesn't require carrying from bytes
1667 ; higher than the LSB.
1668 ;
1669
1670 MOVE DSA0 TO SFBR
1671
1672 at 0x000001bb : */ 0x72100000,0x00000000,
1673 /*
1674 MOVE SFBR + dsa_check_reselect TO SCRATCH0
1675
1676 at 0x000001bd : */ 0x6e340000,0x00000000,
1677 /*
1678 MOVE DSA1 TO SFBR
1679
1680 at 0x000001bf : */ 0x72110000,0x00000000,
1681 /*
1682 MOVE SFBR + 0xff TO SCRATCH1 WITH CARRY
1683
1684 at 0x000001c1 : */ 0x6f35ff00,0x00000000,
1685 /*
1686 MOVE DSA2 TO SFBR
1687
1688 at 0x000001c3 : */ 0x72120000,0x00000000,
1689 /*
1690 MOVE SFBR + 0xff TO SCRATCH2 WITH CARRY
1691
1692 at 0x000001c5 : */ 0x6f36ff00,0x00000000,
1693 /*
1694 MOVE DSA3 TO SFBR
1695
1696 at 0x000001c7 : */ 0x72130000,0x00000000,
1697 /*
1698 MOVE SFBR + 0xff TO SCRATCH3 WITH CARRY
1699
1700 at 0x000001c9 : */ 0x6f37ff00,0x00000000,
1701 /*
1702
1703 MOVE dmode_ncr_to_memory TO DMODE
1704
1705 at 0x000001cb : */ 0x78380000,0x00000000,
1706 /*
1707 MOVE MEMORY 4, addr_scratch, reselected_check + 4
1708
1709 at 0x000001cd : */ 0xc0000004,0x00000000,0x0000074c,
1710 /*
1711 MOVE dmode_memory_to_memory TO DMODE
1712
1713 at 0x000001d0 : */ 0x78380000,0x00000000,
1714 /*
1715 reselected_check:
1716 JUMP 0
1717
1718 at 0x000001d2 : */ 0x80080000,0x00000000,
1719 /*
1720
1721
1722 ;
1723 ;
1724 ENTRY reselected_ok
1725 reselected_ok:
1726 MOVE MEMORY 4, 0, 0 ; Patched : first word
1727
1728 at 0x000001d4 : */ 0xc0000004,0x00000000,0x00000000,
1729 /*
1730 ; is address of
1731 ; successful dsa_next
1732 ; Second word is last
1733 ; unsuccessful dsa_next,
1734 ; starting with
1735 ; dsa_reconnect_head
1736 ; We used to CLEAR ACK here.
1737
1738
1739
1740
1741
1742
1743 RETURN ; Return control to where
1744
1745 at 0x000001d7 : */ 0x90080000,0x00000000,
1746 /*
1747
1748
1749
1750
1751 selected:
1752 INT int_err_selected;
1753
1754 at 0x000001d9 : */ 0x98080000,0x00010000,
1755 /*
1756
1757 ;
1758 ; A select or reselect failure can be caused by one of two conditions :
1759 ; 1. SIG_P was set. This will be the case if the user has written
1760 ; a new value to a previously NULL head of the issue queue.
1761 ;
1762 ; 2. The NCR53c810 was selected or reselected by another device.
1763 ;
1764
1765 wait_reselect_failed:
1766
1767
1768
1769 MOVE SIST0 & 0x20 TO SFBR
1770
1771 at 0x000001db : */ 0x74422000,0x00000000,
1772 /*
1773 JUMP selected, IF 0x20
1774
1775 at 0x000001dd : */ 0x800c0020,0x00000764,
1776 /*
1777 ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
1778 MOVE CTEST2 & 0x40 TO SFBR
1779
1780 at 0x000001df : */ 0x741a4000,0x00000000,
1781 /*
1782 JUMP schedule, IF 0x40
1783
1784 at 0x000001e1 : */ 0x800c0040,0x00000000,
1785 /*
1786 ; FIXME : Something bogus happened, and we shouldn't fail silently.
1787
1788
1789
1790 INT int_debug_panic
1791
1792 at 0x000001e3 : */ 0x98080000,0x030b0000,
1793 /*
1794
1795
1796
1797 select_failed:
1798
1799
1800
1801 ; Otherwise, mask the selected and reselected bits off SIST0
1802 MOVE SIST0 & 0x30 TO SFBR
1803
1804 at 0x000001e5 : */ 0x74423000,0x00000000,
1805 /*
1806 JUMP selected, IF 0x20
1807
1808 at 0x000001e7 : */ 0x800c0020,0x00000764,
1809 /*
1810 JUMP reselected, IF 0x10
1811
1812 at 0x000001e9 : */ 0x800c0010,0x0000065c,
1813 /*
1814 ; If SIGP is set, the user just gave us another command, and
1815 ; we should restart or return to the scheduler.
1816 ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
1817 MOVE CTEST2 & 0x40 TO SFBR
1818
1819 at 0x000001eb : */ 0x741a4000,0x00000000,
1820 /*
1821 JUMP select, IF 0x40
1822
1823 at 0x000001ed : */ 0x800c0040,0x000001fc,
1824 /*
1825 ; FIXME : Something bogus happened, and we shouldn't fail silently.
1826
1827
1828
1829 INT int_debug_panic
1830
1831 at 0x000001ef : */ 0x98080000,0x030b0000,
1832 /*
1833
1834
1835 ;
1836 ; test_1
1837 ; test_2
1838 ;
1839 ; PURPOSE : run some verification tests on the NCR. test_1
1840 ; copies test_src to test_dest and interrupts the host
1841 ; processor, testing for cache coherency and interrupt
1842 ; problems in the processes.
1843 ;
1844 ; test_2 runs a command with offsets relative to the
1845 ; DSA on entry, and is useful for miscellaneous experimentation.
1846 ;
1847
1848 ; Verify that interrupts are working correctly and that we don't
1849 ; have a cache invalidation problem.
1850
1851 ABSOLUTE test_src = 0, test_dest = 0
1852 ENTRY test_1
1853 test_1:
1854 MOVE MEMORY 4, test_src, test_dest
1855
1856 at 0x000001f1 : */ 0xc0000004,0x00000000,0x00000000,
1857 /*
1858 INT int_test_1
1859
1860 at 0x000001f4 : */ 0x98080000,0x04000000,
1861 /*
1862
1863 ;
1864 ; Run arbitrary commands, with test code establishing a DSA
1865 ;
1866
1867 ENTRY test_2
1868 test_2:
1869 CLEAR TARGET
1870
1871 at 0x000001f6 : */ 0x60000200,0x00000000,
1872 /*
1873 SELECT ATN FROM 0, test_2_fail
1874
1875 at 0x000001f8 : */ 0x43000000,0x00000830,
1876 /*
1877 JUMP test_2_msgout, WHEN MSG_OUT
1878
1879 at 0x000001fa : */ 0x860b0000,0x000007f0,
1880 /*
1881 ENTRY test_2_msgout
1882 test_2_msgout:
1883 MOVE FROM 8, WHEN MSG_OUT
1884
1885 at 0x000001fc : */ 0x1e000000,0x00000008,
1886 /*
1887 MOVE FROM 16, WHEN CMD
1888
1889 at 0x000001fe : */ 0x1a000000,0x00000010,
1890 /*
1891 MOVE FROM 24, WHEN DATA_IN
1892
1893 at 0x00000200 : */ 0x19000000,0x00000018,
1894 /*
1895 MOVE FROM 32, WHEN STATUS
1896
1897 at 0x00000202 : */ 0x1b000000,0x00000020,
1898 /*
1899 MOVE FROM 40, WHEN MSG_IN
1900
1901 at 0x00000204 : */ 0x1f000000,0x00000028,
1902 /*
1903 MOVE SCNTL2 & 0x7f TO SCNTL2
1904
1905 at 0x00000206 : */ 0x7c027f00,0x00000000,
1906 /*
1907 CLEAR ACK
1908
1909 at 0x00000208 : */ 0x60000040,0x00000000,
1910 /*
1911 WAIT DISCONNECT
1912
1913 at 0x0000020a : */ 0x48000000,0x00000000,
1914 /*
1915 test_2_fail:
1916 INT int_test_2
1917
1918 at 0x0000020c : */ 0x98080000,0x04010000,
1919 /*
1920
1921 ENTRY debug_break
1922 debug_break:
1923 INT int_debug_break
1924
1925 at 0x0000020e : */ 0x98080000,0x03000000,
1926 /*
1927
1928 ;
1929 ; initiator_abort
1930 ; target_abort
1931 ;
1932 ; PURPOSE : Abort the currently established nexus from with initiator
1933 ; or target mode.
1934 ;
1935 ;
1936
1937 ENTRY target_abort
1938 target_abort:
1939 SET TARGET
1940
1941 at 0x00000210 : */ 0x58000200,0x00000000,
1942 /*
1943 DISCONNECT
1944
1945 at 0x00000212 : */ 0x48000000,0x00000000,
1946 /*
1947 CLEAR TARGET
1948
1949 at 0x00000214 : */ 0x60000200,0x00000000,
1950 /*
1951 JUMP schedule
1952
1953 at 0x00000216 : */ 0x80080000,0x00000000,
1954 /*
1955
1956 ENTRY initiator_abort
1957 initiator_abort:
1958 SET ATN
1959
1960 at 0x00000218 : */ 0x58000008,0x00000000,
1961 /*
1962 ;
1963 ; The SCSI-I specification says that targets may go into MSG out at
1964 ; their leisure upon receipt of the ATN single. On all versions of the
1965 ; specification, we can't change phases until REQ transitions true->false,
1966 ; so we need to sink/source one byte of data to allow the transition.
1967 ;
1968 ; For the sake of safety, we'll only source one byte of data in all
1969 ; cases, but to accomodate the SCSI-I dain bramage, we'll sink an
1970 ; arbitrary number of bytes.
1971 JUMP spew_cmd, WHEN CMD
1972
1973 at 0x0000021a : */ 0x820b0000,0x00000898,
1974 /*
1975 JUMP eat_msgin, WHEN MSG_IN
1976
1977 at 0x0000021c : */ 0x870b0000,0x000008a8,
1978 /*
1979 JUMP eat_datain, WHEN DATA_IN
1980
1981 at 0x0000021e : */ 0x810b0000,0x000008d8,
1982 /*
1983 JUMP eat_status, WHEN STATUS
1984
1985 at 0x00000220 : */ 0x830b0000,0x000008c0,
1986 /*
1987 JUMP spew_dataout, WHEN DATA_OUT
1988
1989 at 0x00000222 : */ 0x800b0000,0x000008f0,
1990 /*
1991 JUMP sated
1992
1993 at 0x00000224 : */ 0x80080000,0x000008f8,
1994 /*
1995 spew_cmd:
1996 MOVE 1, NCR53c7xx_zero, WHEN CMD
1997
1998 at 0x00000226 : */ 0x0a000001,0x00000000,
1999 /*
2000 JUMP sated
2001
2002 at 0x00000228 : */ 0x80080000,0x000008f8,
2003 /*
2004 eat_msgin:
2005 MOVE 1, NCR53c7xx_sink, WHEN MSG_IN
2006
2007 at 0x0000022a : */ 0x0f000001,0x00000000,
2008 /*
2009 JUMP eat_msgin, WHEN MSG_IN
2010
2011 at 0x0000022c : */ 0x870b0000,0x000008a8,
2012 /*
2013 JUMP sated
2014
2015 at 0x0000022e : */ 0x80080000,0x000008f8,
2016 /*
2017 eat_status:
2018 MOVE 1, NCR53c7xx_sink, WHEN STATUS
2019
2020 at 0x00000230 : */ 0x0b000001,0x00000000,
2021 /*
2022 JUMP eat_status, WHEN STATUS
2023
2024 at 0x00000232 : */ 0x830b0000,0x000008c0,
2025 /*
2026 JUMP sated
2027
2028 at 0x00000234 : */ 0x80080000,0x000008f8,
2029 /*
2030 eat_datain:
2031 MOVE 1, NCR53c7xx_sink, WHEN DATA_IN
2032
2033 at 0x00000236 : */ 0x09000001,0x00000000,
2034 /*
2035 JUMP eat_datain, WHEN DATA_IN
2036
2037 at 0x00000238 : */ 0x810b0000,0x000008d8,
2038 /*
2039 JUMP sated
2040
2041 at 0x0000023a : */ 0x80080000,0x000008f8,
2042 /*
2043 spew_dataout:
2044 MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT
2045
2046 at 0x0000023c : */ 0x08000001,0x00000000,
2047 /*
2048 sated:
2049 MOVE SCNTL2 & 0x7f TO SCNTL2
2050
2051 at 0x0000023e : */ 0x7c027f00,0x00000000,
2052 /*
2053 MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
2054
2055 at 0x00000240 : */ 0x0e000001,0x00000000,
2056 /*
2057 WAIT DISCONNECT
2058
2059 at 0x00000242 : */ 0x48000000,0x00000000,
2060 /*
2061 INT int_norm_aborted
2062
2063 at 0x00000244 : */ 0x98080000,0x02040000,
2064 /*
2065
2066 ;
2067 ; dsa_to_scratch
2068 ; scratch_to_dsa
2069 ;
2070 ; PURPOSE :
2071 ; The NCR chips cannot do a move memory instruction with the DSA register
2072 ; as the source or destination. So, we provide a couple of subroutines
2073 ; that let us switch between the DSA register and scratch register.
2074 ;
2075 ; Memory moves to/from the DSPS register also don't work, but we
2076 ; don't use them.
2077 ;
2078 ;
2079
2080
2081 dsa_to_scratch:
2082 MOVE DSA0 TO SFBR
2083
2084 at 0x00000246 : */ 0x72100000,0x00000000,
2085 /*
2086 MOVE SFBR TO SCRATCH0
2087
2088 at 0x00000248 : */ 0x6a340000,0x00000000,
2089 /*
2090 MOVE DSA1 TO SFBR
2091
2092 at 0x0000024a : */ 0x72110000,0x00000000,
2093 /*
2094 MOVE SFBR TO SCRATCH1
2095
2096 at 0x0000024c : */ 0x6a350000,0x00000000,
2097 /*
2098 MOVE DSA2 TO SFBR
2099
2100 at 0x0000024e : */ 0x72120000,0x00000000,
2101 /*
2102 MOVE SFBR TO SCRATCH2
2103
2104 at 0x00000250 : */ 0x6a360000,0x00000000,
2105 /*
2106 MOVE DSA3 TO SFBR
2107
2108 at 0x00000252 : */ 0x72130000,0x00000000,
2109 /*
2110 MOVE SFBR TO SCRATCH3
2111
2112 at 0x00000254 : */ 0x6a370000,0x00000000,
2113 /*
2114 RETURN
2115
2116 at 0x00000256 : */ 0x90080000,0x00000000,
2117 /*
2118
2119 scratch_to_dsa:
2120 MOVE SCRATCH0 TO SFBR
2121
2122 at 0x00000258 : */ 0x72340000,0x00000000,
2123 /*
2124 MOVE SFBR TO DSA0
2125
2126 at 0x0000025a : */ 0x6a100000,0x00000000,
2127 /*
2128 MOVE SCRATCH1 TO SFBR
2129
2130 at 0x0000025c : */ 0x72350000,0x00000000,
2131 /*
2132 MOVE SFBR TO DSA1
2133
2134 at 0x0000025e : */ 0x6a110000,0x00000000,
2135 /*
2136 MOVE SCRATCH2 TO SFBR
2137
2138 at 0x00000260 : */ 0x72360000,0x00000000,
2139 /*
2140 MOVE SFBR TO DSA2
2141
2142 at 0x00000262 : */ 0x6a120000,0x00000000,
2143 /*
2144 MOVE SCRATCH3 TO SFBR
2145
2146 at 0x00000264 : */ 0x72370000,0x00000000,
2147 /*
2148 MOVE SFBR TO DSA3
2149
2150 at 0x00000266 : */ 0x6a130000,0x00000000,
2151 /*
2152 RETURN
2153
2154 at 0x00000268 : */ 0x90080000,0x00000000,
2155 };
2156
2157 #define A_NCR53c7xx_msg_abort 0x00000000
2158 u32 A_NCR53c7xx_msg_abort_used[] = {
2159 0x00000241,
2160 };
2161
2162 #define A_NCR53c7xx_msg_reject 0x00000000
2163 u32 A_NCR53c7xx_msg_reject_used[] = {
2164 0x00000172,
2165 };
2166
2167 #define A_NCR53c7xx_sink 0x00000000
2168 u32 A_NCR53c7xx_sink_used[] = {
2169 0x0000022b,
2170 0x00000231,
2171 0x00000237,
2172 };
2173
2174 #define A_NCR53c7xx_zero 0x00000000
2175 u32 A_NCR53c7xx_zero_used[] = {
2176 0x00000227,
2177 0x0000023d,
2178 };
2179
2180 #define A_NOP_insn 0x00000000
2181 u32 A_NOP_insn_used[] = {
2182 0x00000010,
2183 };
2184
2185 #define A_addr_reconnect_dsa_head 0x00000000
2186 u32 A_addr_reconnect_dsa_head_used[] = {
2187 0x000001a7,
2188 };
2189
2190 #define A_addr_scratch 0x00000000
2191 u32 A_addr_scratch_used[] = {
2192 0x00000004,
2193 0x0000001b,
2194 0x00000046,
2195 0x00000067,
2196 0x00000073,
2197 0x000000b0,
2198 0x000000c6,
2199 0x00000128,
2200 0x00000141,
2201 0x000001a1,
2202 0x000001ce,
2203 };
2204
2205 #define A_addr_temp 0x00000000
2206 u32 A_addr_temp_used[] = {
2207 0x00000025,
2208 0x00000034,
2209 };
2210
2211 #define A_dmode_memory_to_memory 0x00000000
2212 u32 A_dmode_memory_to_memory_used[] = {
2213 0x00000005,
2214 0x0000001c,
2215 0x00000027,
2216 0x00000035,
2217 0x00000047,
2218 0x00000069,
2219 0x00000075,
2220 0x000000b2,
2221 0x000000c8,
2222 0x0000012a,
2223 0x00000143,
2224 0x00000199,
2225 0x000001a2,
2226 0x000001d0,
2227 };
2228
2229 #define A_dmode_memory_to_ncr 0x00000000
2230 u32 A_dmode_memory_to_ncr_used[] = {
2231 0x00000000,
2232 0x00000017,
2233 0x00000030,
2234 0x00000042,
2235 0x0000019d,
2236 };
2237
2238 #define A_dmode_ncr_to_memory 0x00000000
2239 u32 A_dmode_ncr_to_memory_used[] = {
2240 0x00000022,
2241 0x00000064,
2242 0x00000070,
2243 0x000000ad,
2244 0x000000c3,
2245 0x00000125,
2246 0x0000013e,
2247 0x000001cb,
2248 };
2249
2250 #define A_dsa_check_reselect 0x00000000
2251 u32 A_dsa_check_reselect_used[] = {
2252 0x000001bd,
2253 };
2254
2255 #define A_dsa_cmdout 0x00000048
2256 u32 A_dsa_cmdout_used[] = {
2257 0x00000094,
2258 };
2259
2260 #define A_dsa_cmnd 0x00000038
2261 u32 A_dsa_cmnd_used[] = {
2262 };
2263
2264 #define A_dsa_datain 0x00000054
2265 u32 A_dsa_datain_used[] = {
2266 0x000000bb,
2267 };
2268
2269 #define A_dsa_dataout 0x00000050
2270 u32 A_dsa_dataout_used[] = {
2271 0x000000a5,
2272 };
2273
2274 #define A_dsa_end 0x00000070
2275 u32 A_dsa_end_used[] = {
2276 };
2277
2278 #define A_dsa_fields_start 0x00000000
2279 u32 A_dsa_fields_start_used[] = {
2280 };
2281
2282 #define A_dsa_msgin 0x00000058
2283 u32 A_dsa_msgin_used[] = {
2284 0x00000188,
2285 };
2286
2287 #define A_dsa_msgout 0x00000040
2288 u32 A_dsa_msgout_used[] = {
2289 0x00000086,
2290 };
2291
2292 #define A_dsa_msgout_other 0x00000068
2293 u32 A_dsa_msgout_other_used[] = {
2294 0x00000180,
2295 };
2296
2297 #define A_dsa_next 0x00000030
2298 u32 A_dsa_next_used[] = {
2299 0x0000005c,
2300 };
2301
2302 #define A_dsa_restore_pointers 0x00000000
2303 u32 A_dsa_restore_pointers_used[] = {
2304 0x0000012e,
2305 };
2306
2307 #define A_dsa_save_data_pointer 0x00000000
2308 u32 A_dsa_save_data_pointer_used[] = {
2309 0x00000115,
2310 };
2311
2312 #define A_dsa_select 0x0000003c
2313 u32 A_dsa_select_used[] = {
2314 0x00000081,
2315 };
2316
2317 #define A_dsa_status 0x00000060
2318 u32 A_dsa_status_used[] = {
2319 0x00000184,
2320 };
2321
2322 #define A_dsa_temp_addr_array_value 0x00000000
2323 u32 A_dsa_temp_addr_array_value_used[] = {
2324 };
2325
2326 #define A_dsa_temp_addr_dsa_value 0x00000000
2327 u32 A_dsa_temp_addr_dsa_value_used[] = {
2328 0x00000003,
2329 };
2330
2331 #define A_dsa_temp_addr_new_value 0x00000000
2332 u32 A_dsa_temp_addr_new_value_used[] = {
2333 };
2334
2335 #define A_dsa_temp_addr_next 0x00000000
2336 u32 A_dsa_temp_addr_next_used[] = {
2337 0x00000015,
2338 0x0000004e,
2339 };
2340
2341 #define A_dsa_temp_addr_residual 0x00000000
2342 u32 A_dsa_temp_addr_residual_used[] = {
2343 0x0000002a,
2344 0x00000039,
2345 };
2346
2347 #define A_dsa_temp_addr_saved_pointer 0x00000000
2348 u32 A_dsa_temp_addr_saved_pointer_used[] = {
2349 0x00000026,
2350 0x00000033,
2351 };
2352
2353 #define A_dsa_temp_addr_saved_residual 0x00000000
2354 u32 A_dsa_temp_addr_saved_residual_used[] = {
2355 0x0000002b,
2356 0x00000038,
2357 };
2358
2359 #define A_dsa_temp_lun 0x00000000
2360 u32 A_dsa_temp_lun_used[] = {
2361 0x0000004b,
2362 };
2363
2364 #define A_dsa_temp_next 0x00000000
2365 u32 A_dsa_temp_next_used[] = {
2366 0x0000001a,
2367 };
2368
2369 #define A_dsa_temp_sync 0x00000000
2370 u32 A_dsa_temp_sync_used[] = {
2371 0x00000053,
2372 };
2373
2374 #define A_dsa_temp_target 0x00000000
2375 u32 A_dsa_temp_target_used[] = {
2376 0x00000040,
2377 };
2378
2379 #define A_int_debug_break 0x03000000
2380 u32 A_int_debug_break_used[] = {
2381 0x0000020f,
2382 };
2383
2384 #define A_int_debug_panic 0x030b0000
2385 u32 A_int_debug_panic_used[] = {
2386 0x000001e4,
2387 0x000001f0,
2388 };
2389
2390 #define A_int_err_check_condition 0x00030000
2391 u32 A_int_err_check_condition_used[] = {
2392 0x00000194,
2393 };
2394
2395 #define A_int_err_no_phase 0x00040000
2396 u32 A_int_err_no_phase_used[] = {
2397 };
2398
2399 #define A_int_err_selected 0x00010000
2400 u32 A_int_err_selected_used[] = {
2401 0x000001da,
2402 };
2403
2404 #define A_int_err_unexpected_phase 0x00000000
2405 u32 A_int_err_unexpected_phase_used[] = {
2406 0x0000008c,
2407 0x00000092,
2408 0x0000009a,
2409 0x000000d0,
2410 0x000000d4,
2411 0x000000d6,
2412 0x000000de,
2413 0x000000e2,
2414 0x000000e4,
2415 0x000000ec,
2416 0x000000f0,
2417 0x000000f2,
2418 0x000000f4,
2419 0x0000014c,
2420 };
2421
2422 #define A_int_err_unexpected_reselect 0x00020000
2423 u32 A_int_err_unexpected_reselect_used[] = {
2424 0x000001ba,
2425 };
2426
2427 #define A_int_msg_1 0x01020000
2428 u32 A_int_msg_1_used[] = {
2429 0x0000010e,
2430 0x00000110,
2431 };
2432
2433 #define A_int_msg_sdtr 0x01010000
2434 u32 A_int_msg_sdtr_used[] = {
2435 0x0000016c,
2436 };
2437
2438 #define A_int_msg_wdtr 0x01000000
2439 u32 A_int_msg_wdtr_used[] = {
2440 0x00000160,
2441 };
2442
2443 #define A_int_norm_aborted 0x02040000
2444 u32 A_int_norm_aborted_used[] = {
2445 0x00000245,
2446 };
2447
2448 #define A_int_norm_command_complete 0x02020000
2449 u32 A_int_norm_command_complete_used[] = {
2450 };
2451
2452 #define A_int_norm_disconnected 0x02030000
2453 u32 A_int_norm_disconnected_used[] = {
2454 };
2455
2456 #define A_int_norm_reselect_complete 0x02010000
2457 u32 A_int_norm_reselect_complete_used[] = {
2458 };
2459
2460 #define A_int_norm_reset 0x02050000
2461 u32 A_int_norm_reset_used[] = {
2462 };
2463
2464 #define A_int_norm_select_complete 0x02000000
2465 u32 A_int_norm_select_complete_used[] = {
2466 };
2467
2468 #define A_int_test_1 0x04000000
2469 u32 A_int_test_1_used[] = {
2470 0x000001f5,
2471 };
2472
2473 #define A_int_test_2 0x04010000
2474 u32 A_int_test_2_used[] = {
2475 0x0000020d,
2476 };
2477
2478 #define A_int_test_3 0x04020000
2479 u32 A_int_test_3_used[] = {
2480 };
2481
2482 #define A_msg_buf 0x00000000
2483 u32 A_msg_buf_used[] = {
2484 0x00000102,
2485 0x0000014e,
2486 0x00000158,
2487 0x0000015e,
2488 0x00000164,
2489 0x0000016a,
2490 };
2491
2492 #define A_reconnect_dsa_head 0x00000000
2493 u32 A_reconnect_dsa_head_used[] = {
2494 0x0000006c,
2495 0x00000074,
2496 0x000001a0,
2497 };
2498
2499 #define A_reselected_identify 0x00000000
2500 u32 A_reselected_identify_used[] = {
2501 0x00000045,
2502 0x0000019c,
2503 };
2504
2505 #define A_reselected_tag 0x00000000
2506 u32 A_reselected_tag_used[] = {
2507 };
2508
2509 #define A_schedule 0x00000000
2510 u32 A_schedule_used[] = {
2511 0x0000007e,
2512 0x00000192,
2513 0x000001e2,
2514 0x00000217,
2515 };
2516
2517 #define A_test_dest 0x00000000
2518 u32 A_test_dest_used[] = {
2519 0x000001f3,
2520 };
2521
2522 #define A_test_src 0x00000000
2523 u32 A_test_src_used[] = {
2524 0x000001f2,
2525 };
2526
2527 #define Ent_accept_message 0x000005d4
2528 #define Ent_cmdout_cmdout 0x0000024c
2529 #define Ent_command_complete 0x0000060c
2530 #define Ent_command_complete_msgin 0x0000061c
2531 #define Ent_data_transfer 0x00000254
2532 #define Ent_datain_to_jump 0x00000328
2533 #define Ent_debug_break 0x00000838
2534 #define Ent_dsa_code_begin 0x00000000
2535 #define Ent_dsa_code_check_reselect 0x000000f8
2536 #define Ent_dsa_code_fix_jump 0x0000003c
2537 #define Ent_dsa_code_restore_pointers 0x000000c0
2538 #define Ent_dsa_code_save_data_pointer 0x00000088
2539 #define Ent_dsa_code_template 0x00000000
2540 #define Ent_dsa_code_template_end 0x00000168
2541 #define Ent_dsa_schedule 0x00000168
2542 #define Ent_dsa_zero 0x00000168
2543 #define Ent_end_data_transfer 0x0000028c
2544 #define Ent_initiator_abort 0x00000860
2545 #define Ent_msg_in 0x00000404
2546 #define Ent_msg_in_restart 0x000003e4
2547 #define Ent_other_in 0x00000374
2548 #define Ent_other_out 0x0000033c
2549 #define Ent_other_transfer 0x000003ac
2550 #define Ent_reject_message 0x000005b4
2551 #define Ent_reselected_check_next 0x000006a4
2552 #define Ent_reselected_ok 0x00000750
2553 #define Ent_respond_message 0x000005ec
2554 #define Ent_select 0x000001fc
2555 #define Ent_select_msgout 0x00000214
2556 #define Ent_target_abort 0x00000840
2557 #define Ent_test_1 0x000007c4
2558 #define Ent_test_2 0x000007d8
2559 #define Ent_test_2_msgout 0x000007f0
2560 #define Ent_wait_reselect 0x00000654
2561 u32 LABELPATCHES[] = {
2562 0x00000008,
2563 0x0000000a,
2564 0x00000013,
2565 0x00000016,
2566 0x0000001f,
2567 0x00000021,
2568 0x0000004f,
2569 0x00000051,
2570 0x0000005b,
2571 0x00000068,
2572 0x0000006f,
2573 0x00000082,
2574 0x00000084,
2575 0x0000008a,
2576 0x0000008e,
2577 0x00000090,
2578 0x00000096,
2579 0x00000098,
2580 0x0000009c,
2581 0x0000009e,
2582 0x000000a0,
2583 0x000000a2,
2584 0x000000a4,
2585 0x000000b1,
2586 0x000000b6,
2587 0x000000ba,
2588 0x000000c7,
2589 0x000000cc,
2590 0x000000d2,
2591 0x000000d8,
2592 0x000000da,
2593 0x000000e0,
2594 0x000000e6,
2595 0x000000e8,
2596 0x000000ee,
2597 0x000000f6,
2598 0x000000f8,
2599 0x00000104,
2600 0x00000106,
2601 0x00000108,
2602 0x0000010a,
2603 0x0000010c,
2604 0x00000112,
2605 0x00000114,
2606 0x00000129,
2607 0x00000142,
2608 0x00000148,
2609 0x00000150,
2610 0x00000152,
2611 0x00000154,
2612 0x0000015a,
2613 0x00000166,
2614 0x00000196,
2615 0x000001a5,
2616 0x000001a8,
2617 0x000001ac,
2618 0x000001b0,
2619 0x000001b4,
2620 0x000001b8,
2621 0x000001cf,
2622 0x000001de,
2623 0x000001e8,
2624 0x000001ea,
2625 0x000001ee,
2626 0x000001f9,
2627 0x000001fb,
2628 0x0000021b,
2629 0x0000021d,
2630 0x0000021f,
2631 0x00000221,
2632 0x00000223,
2633 0x00000225,
2634 0x00000229,
2635 0x0000022d,
2636 0x0000022f,
2637 0x00000233,
2638 0x00000235,
2639 0x00000239,
2640 0x0000023b,
2641 };
2642
2643 struct {
2644 u32 offset;
2645 void *address;
2646 } EXTERNAL_PATCHES[] = {
2647 };
2648
2649 u32 INSTRUCTIONS = 297;
2650 u32 PATCHES = 79;
2651 u32 EXTERNAL_PATCHES_LEN = 0;