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