1 u32 SCRIPT[] = {
2 /*
3 ; NCR 53c810 driver, main script
4 ; Sponsored by
5 ; iX Multiuser Multitasking Magazine
6 ; hm@ix.de
7 ;
8 ; Copyright 1993, Drew Eckhardt
9 ; Visionary Computing
10 ; (Unix and Linux consulting and custom programming)
11 ; drew@Colorado.EDU
12 ; +1 (303) 786-7975
13 ;
14 ; TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
15 ;
16 ; PRE-ALPHA
17 ;
18 ; For more information, please consult
19 ;
20 ; NCR 53C810
21 ; PCI-SCSI I/O Processor
22 ; Data Manual
23 ;
24 ; NCR 53C710
25 ; SCSI I/O Processor
26 ; Programmers Guide
27 ;
28 ; NCR Microelectronics
29 ; 1635 Aeroplaza Drive
30 ; Colorado Springs, CO 80916
31 ; 1+ (719) 578-3400
32 ;
33 ; Toll free literature number
34 ; +1 (800) 334-5454
35 ;
36 ; IMPORTANT : This code is self modifying due to the limitations of
37 ; the NCR53c7,8xx series chips. Persons debugging this code with
38 ; the remote debugger should take this into account, and NOT set
39 ; breakpoints in modified instructions.
40 ;
41 ;
42 ; Design:
43 ; The NCR53c7x0 family of SCSI chips are busmasters with an onboard
44 ; microcontroller using a simple instruction set.
45 ;
46 ; So, to minimize the effects of interrupt latency, and to maximize
47 ; throughput, this driver offloads the practical maximum amount
48 ; of processing to the SCSI chip while still maintaining a common
49 ; structure.
50 ;
51 ; Where tradeoffs were needed between efficiency on the older
52 ; chips and the newer NCR53c800 series, the NCR53c800 series
53 ; was chosen.
54 ;
55 ; While the NCR53c700 and NCR53c700-66 lacked the facilities to fully
56 ; automate SCSI transfers without host processor intervention, this
57 ; isn't the case with the NCR53c710 and newer chips which allow
58 ;
59 ; - reads and writes to the internal registers from within the SCSI
60 ; scripts, allowing the SCSI SCRIPTS(tm) code to save processor
61 ; state so that multiple threads of execution are possible, and also
62 ; provide an ALU for loop control, etc.
63 ;
64 ; - table indirect addressing for some instructions. This allows
65 ; pointers to be located relative to the DSA ((Data Structure
66 ; Address) register.
67 ;
68 ; These features make it possible to implement a mailbox style interface,
69 ; where the same piece of code is run to handle I/O for multiple threads
70 ; at once minimizing our need to relocate code. Since the NCR53c700/
71 ; NCR53c800 series have a unique combination of features, making a
72 ; a standard ingoing/outgoing mailbox system, costly, I've modified it.
73 ;
74 ; - Commands are stored in a linked list, rather than placed in
75 ; arbitrary mailboxes. This simplifies the amount of processing
76 ; that must be done by the NCR53c810.
77 ;
78 ; - Mailboxes are a mixture of code and data. This lets us greatly
79 ; simplify the NCR53c810 code and do things that would otherwise
80 ; not be possible.
81
82 ;
83 ; Note : the DSA structures must be aligned on 32 bit boundaries,
84 ; since the source and destination of MOVE MEMORY instructions
85 ; must share the same alignment and this is the alignment of the
86 ; NCR registers.
87 ;
88
89 ABSOLUTE dsa_temp_jump_resume = 0 ; Patch to dsa_jump_resume
90 ; in current dsa
91 ABSOLUTE dsa_temp_lun = 0 ; Patch to lun for current dsa
92 ABSOLUTE dsa_temp_dsa_next = 0 ; Patch to dsa next for current dsa
93 ABSOLUTE dsa_temp_sync = 0 ; Patch to address of per-target
94 ; sync routine
95 ABSOLUTE dsa_temp_target = 0 ; Patch to id for current dsa
96
97
98
99 ENTRY dsa_code_template
100 dsa_code_template:
101
102 ; Define DSA structure used for mailboxes
103
104 ; wrong_dsa loads the DSA register with the value of the dsa_next
105 ; field.
106 ;
107 wrong_dsa:
108 ; Patch the MOVE MEMORY INSTRUCTION such that
109 ; the destination address is that of the OLD next
110 ; pointer.
111 MOVE MEMORY 4, dsa_temp_dsa_next, reselected_ok + 8
112
113 at 0x00000000 : */ 0xc0000004,0x00000000,0x00000660,
114 /*
115
116 MOVE dmode_memory_to_ncr TO DMODE
117
118 at 0x00000003 : */ 0x78380000,0x00000000,
119 /*
120 MOVE MEMORY 4, dsa_temp_dsa_next, addr_scratch
121
122 at 0x00000005 : */ 0xc0000004,0x00000000,0x00000000,
123 /*
124 MOVE dmode_memory_to_memory TO DMODE
125
126 at 0x00000008 : */ 0x78380000,0x00000000,
127 /*
128 CALL scratch_to_dsa
129
130 at 0x0000000a : */ 0x88080000,0x00000830,
131 /*
132 JUMP reselected_check_next
133
134 at 0x0000000c : */ 0x80080000,0x000005ac,
135 /*
136
137 ABSOLUTE dsa_check_reselect = 0
138 ; dsa_check_reselect determines whether or not the current target and
139 ; lun match the current DSA
140 ENTRY dsa_code_check_reselect
141 dsa_code_check_reselect:
142 MOVE SSID TO SFBR ; SSID contains 3 bit target ID
143
144 at 0x0000000e : */ 0x720a0000,0x00000000,
145 /*
146 JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 7
147
148 at 0x00000010 : */ 0x80840700,0x00ffffb8,
149 /*
150 MOVE dmode_memory_to_ncr TO DMODE
151
152 at 0x00000012 : */ 0x78380000,0x00000000,
153 /*
154 MOVE MEMORY 1, reselected_identify, addr_sfbr
155
156 at 0x00000014 : */ 0xc0000001,0x00000000,0x00000000,
157 /*
158 JUMP REL (wrong_dsa), IF NOT dsa_temp_lun, AND MASK 7
159
160 at 0x00000017 : */ 0x80840700,0x00ffff9c,
161 /*
162 MOVE dmode_memory_to_memory TO DMODE
163
164 at 0x00000019 : */ 0x78380000,0x00000000,
165 /*
166 ; Patch the MOVE MEMORY INSTRUCTION such that
167 ; the source address is that of this dsas
168 ; next pointer.
169 MOVE MEMORY 4, dsa_temp_dsa_next, reselected_ok + 4
170
171 at 0x0000001b : */ 0xc0000004,0x00000000,0x0000065c,
172 /*
173 CALL reselected_ok
174
175 at 0x0000001e : */ 0x88080000,0x00000658,
176 /*
177 CALL dsa_temp_sync
178
179 at 0x00000020 : */ 0x88080000,0x00000000,
180 /*
181 ENTRY dsa_jump_resume
182 dsa_jump_resume:
183 JUMP 0 ; Jump to resume address
184
185 at 0x00000022 : */ 0x80080000,0x00000000,
186 /*
187 ENTRY dsa_zero
188 dsa_zero:
189 MOVE dmode_ncr_to_memory TO DMODE ; 8
190
191 at 0x00000024 : */ 0x78380000,0x00000000,
192 /*
193 MOVE MEMORY 4, addr_temp, dsa_temp_jump_resume ; 16
194
195 at 0x00000026 : */ 0xc0000004,0x00000000,0x00000000,
196 /*
197 MOVE dmode_memory_to_memory TO DMODE ; 28
198
199 at 0x00000029 : */ 0x78380000,0x00000000,
200 /*
201 JUMP dsa_schedule ; 36
202
203 at 0x0000002b : */ 0x80080000,0x000000b4,
204 /*
205 ENTRY dsa_code_template_end
206 dsa_code_template_end:
207
208 ; Perform sanity check for dsa_fields_start == dsa_code_template_end -
209 ; dsa_zero, puke.
210
211 ABSOLUTE dsa_fields_start = 36 ; Sanity marker
212 ; pad 12
213 ABSOLUTE dsa_next = 48 ; len 4 Next DSA
214 ; del 4 Previous DSA address
215 ABSOLUTE dsa_cmnd = 56 ; len 4 Scsi_Cmnd * for this thread.
216 ABSOLUTE dsa_select = 60 ; len 4 Device ID, Period, Offset for
217 ; table indirect select
218 ABSOLUTE dsa_msgout = 64 ; len 8 table indirect move parameter for
219 ; select message
220 ABSOLUTE dsa_cmdout = 72 ; len 8 table indirect move parameter for
221 ; command
222 ABSOLUTE dsa_dataout = 80 ; len 4 code pointer for dataout
223 ABSOLUTE dsa_datain = 84 ; len 4 code pointer for datain
224 ABSOLUTE dsa_msgin = 88 ; len 8 table indirect move for msgin
225 ABSOLUTE dsa_status = 96 ; len 8 table indirect move for status byte
226 ABSOLUTE dsa_msgout_other = 104 ; len 8 table indirect for normal message out
227 ; (Synchronous transfer negotiation, etc).
228 ABSOLUTE dsa_end = 112
229
230 ; Linked lists of DSA structures
231 ABSOLUTE issue_dsa_head = 0 ; Linked list of DSAs to issue
232 ABSOLUTE reconnect_dsa_head = 0 ; Link list of DSAs which can reconnect
233
234 ; These select the source and destination of a MOVE MEMORY instruction
235 ABSOLUTE dmode_memory_to_memory = 0x0
236 ABSOLUTE dmode_memory_to_ncr = 0x0
237 ABSOLUTE dmode_ncr_to_memory = 0x0
238 ABSOLUTE dmode_ncr_to_ncr = 0x0
239
240 ABSOLUTE addr_scratch = 0x0
241 ABSOLUTE addr_sfbr = 0x0
242 ABSOLUTE addr_temp = 0x0
243
244
245 ; Interrupts -
246 ; MSB indicates type
247 ; 0 handle error condition
248 ; 1 handle message
249 ; 2 handle normal condition
250 ; 3 debugging interrupt
251 ; 4 testing interrupt
252 ; Next byte indicates specific error
253
254 ; XXX not yet implemented, I'm not sure if I want to -
255 ; Next byte indicates the routine the error occurred in
256 ; The LSB indicates the specific place the error occurred
257
258 ABSOLUTE int_err_unexpected_phase = 0x00000000 ; Unexpected phase encountered
259 ABSOLUTE int_err_selected = 0x00010000 ; SELECTED (nee RESELECTED)
260 ABSOLUTE int_err_unexpected_reselect = 0x00020000
261 ABSOLUTE int_err_check_condition = 0x00030000
262 ABSOLUTE int_err_no_phase = 0x00040000
263 ABSOLUTE int_msg_wdtr = 0x01000000 ; WDTR message received
264 ABSOLUTE int_msg_sdtr = 0x01010000 ; SDTR received
265 ABSOLUTE int_msg_1 = 0x01020000 ; single byte special message
266 ; received
267
268 ABSOLUTE int_norm_select_complete = 0x02000000 ; Select complete, reprogram
269 ; registers.
270 ABSOLUTE int_norm_reselect_complete = 0x02010000 ; Nexus established
271 ABSOLUTE int_norm_command_complete = 0x02020000 ; Command complete
272 ABSOLUTE int_norm_disconnected = 0x02030000 ; Disconnected
273 ABSOLUTE int_norm_aborted =0x02040000 ; Aborted *dsa
274 ABSOLUTE int_norm_reset = 0x02050000 ; Generated BUS reset.
275 ABSOLUTE int_debug_break = 0x03000000 ; Break point
276 ABSOLUTE int_debug_scheduled = 0x03010000 ; new I/O scheduled
277 ABSOLUTE int_debug_idle = 0x03020000 ; scheduler is idle
278 ABSOLUTE int_debug_dsa_loaded = 0x03030000 ; dsa reloaded
279 ABSOLUTE int_debug_reselected = 0x03040000 ; NCR reselected
280 ABSOLUTE int_debug_head = 0x03050000 ; issue head overwritten
281
282 ABSOLUTE int_test_1 = 0x04000000 ; Test 1 complete
283 ABSOLUTE int_test_2 = 0x04010000 ; Test 2 complete
284 ABSOLUTE int_test_3 = 0x04020000 ; Test 3 complete
285
286 ABSOLUTE NCR53c7xx_msg_abort = 0 ; Pointer to abort message
287 ABSOLUTE NCR53c7xx_msg_reject = 0 ; Pointer to reject message
288 ABSOLUTE NCR53c7xx_zero = 0 ; long with zero in it, use for source
289 ABSOLUTE NCR53c7xx_sink = 0 ; long to dump worthless data in
290
291 ; Pointer to final bytes of multi-byte messages
292 ABSOLUTE msg_buf = 0
293
294 ; Pointer to holding area for reselection information
295 ABSOLUTE reselected_identify = 0
296 ABSOLUTE reselected_tag = 0
297
298 ; Request sense command pointer, it's a 6 byte command, should
299 ; be constant for all commands since we always want 16 bytes of
300 ; sense and we don't need to change any fields as we did under
301 ; SCSI-I when we actually cared about the LUN field.
302 ;EXTERNAL NCR53c7xx_sense ; Request sense command
303
304
305 ; dsa_schedule
306 ; PURPOSE : after a DISCONNECT message has been received, and pointers
307 ; saved, insert the current DSA structure at the head of the
308 ; disconnected queue and fall through to the scheduler.
309 ;
310 ; CALLS : OK
311 ;
312 ; INPUTS : dsa - current DSA structure, reconnect_dsa_head - list
313 ; of disconnected commands
314 ;
315 ; MODIFIES : SCRATCH, reconnect_dsa_head
316 ;
317 ; EXITS : always passes control to schedule
318
319 ENTRY dsa_schedule
320 dsa_schedule:
321
322 ;
323 ; Calculate the address of the next pointer within the DSA
324 ; structure of the command that is currently disconnecting
325 ;
326 CALL dsa_to_scratch
327
328 at 0x0000002d : */ 0x88080000,0x000007e8,
329 /*
330 ; XXX - we need to deal with the NCR53c710, which lacks an add with
331 ; carry instruction, by moving around the DSA alignment to avoid
332 ; carry in situations like this.
333 MOVE SCRATCH0 + dsa_next TO SCRATCH0
334
335 at 0x0000002f : */ 0x7e343000,0x00000000,
336 /*
337 MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
338
339 at 0x00000031 : */ 0x7f350000,0x00000000,
340 /*
341 MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
342
343 at 0x00000033 : */ 0x7f360000,0x00000000,
344 /*
345 MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
346
347 at 0x00000035 : */ 0x7f370000,0x00000000,
348 /*
349
350 ; Point the next field of this DSA structure at the current disconnected
351 ; list
352 MOVE dmode_ncr_to_memory TO DMODE
353
354 at 0x00000037 : */ 0x78380000,0x00000000,
355 /*
356 MOVE MEMORY 4, addr_scratch, dsa_schedule_insert + 8
357
358 at 0x00000039 : */ 0xc0000004,0x00000000,0x00000100,
359 /*
360 MOVE dmode_memory_to_memory TO DMODE
361
362 at 0x0000003c : */ 0x78380000,0x00000000,
363 /*
364 dsa_schedule_insert:
365 MOVE MEMORY 4, reconnect_dsa_head, 0
366
367 at 0x0000003e : */ 0xc0000004,0x00000000,0x00000000,
368 /*
369
370 ; And update the head pointer.
371 CALL dsa_to_scratch
372
373 at 0x00000041 : */ 0x88080000,0x000007e8,
374 /*
375 MOVE dmode_ncr_to_memory TO DMODE
376
377 at 0x00000043 : */ 0x78380000,0x00000000,
378 /*
379 MOVE MEMORY 4, addr_scratch, reconnect_dsa_head
380
381 at 0x00000045 : */ 0xc0000004,0x00000000,0x00000000,
382 /*
383 MOVE dmode_memory_to_memory TO DMODE
384
385 at 0x00000048 : */ 0x78380000,0x00000000,
386 /*
387 WAIT DISCONNECT
388
389 at 0x0000004a : */ 0x48000000,0x00000000,
390 /*
391
392 ; schedule
393 ; PURPOSE : schedule a new I/O once the bus is free by putting the
394 ; address of the next DSA structure in the DSA register.
395 ;
396 ; INPUTS : issue_dsa_head - list of new commands
397 ;
398 ; CALLS : OK
399 ;
400 ; MODIFIES : SCRATCH, DSA
401 ;
402 ; EXITS : if the issue_dsa_head pointer is non-NULL, control
403 ; is passed to select. Otherwise, control is passed to
404 ; wait_reselect.
405
406
407 ENTRY schedule
408 schedule:
409 ; Point DSA at the current head of the issue queue.
410 MOVE dmode_memory_to_ncr TO DMODE
411
412 at 0x0000004c : */ 0x78380000,0x00000000,
413 /*
414 MOVE MEMORY 4, issue_dsa_head, addr_scratch
415
416 at 0x0000004e : */ 0xc0000004,0x00000000,0x00000000,
417 /*
418 MOVE dmode_memory_to_memory TO DMODE
419
420 at 0x00000051 : */ 0x78380000,0x00000000,
421 /*
422
423 CALL scratch_to_dsa
424
425 at 0x00000053 : */ 0x88080000,0x00000830,
426 /*
427
428
429
430
431 ; Check for a null pointer.
432 MOVE DSA0 TO SFBR
433
434 at 0x00000055 : */ 0x72100000,0x00000000,
435 /*
436 JUMP select, IF NOT 0
437
438 at 0x00000057 : */ 0x80040000,0x00000194,
439 /*
440 MOVE DSA1 TO SFBR
441
442 at 0x00000059 : */ 0x72110000,0x00000000,
443 /*
444 JUMP select, IF NOT 0
445
446 at 0x0000005b : */ 0x80040000,0x00000194,
447 /*
448 MOVE DSA2 TO SFBR
449
450 at 0x0000005d : */ 0x72120000,0x00000000,
451 /*
452 JUMP select, IF NOT 0
453
454 at 0x0000005f : */ 0x80040000,0x00000194,
455 /*
456 MOVE DSA3 TO SFBR
457
458 at 0x00000061 : */ 0x72130000,0x00000000,
459 /*
460 JUMP wait_reselect, IF 0
461
462 at 0x00000063 : */ 0x800c0000,0x00000560,
463 /*
464
465
466
467
468
469 ;
470 ; select
471 ;
472 ; PURPOSE : establish a nexus for the SCSI command referenced by DSA.
473 ; On success, the current DSA structure is removed from the issue
474 ; queue. Usually, this is entered as a fall-through from schedule,
475 ; although the contingent allegiance handling code will write
476 ; the select entry address to the DSP to restart a command as a
477 ; REQUEST SENSE. A message is sent (usually IDENTIFY, although
478 ; additional SDTR or WDTR messages may be sent). COMMAND OUT
479 ; is handled.
480 ;
481 ; INPUTS : DSA - SCSI command, issue_dsa_head
482 ;
483 ; CALLS : OK
484 ;
485 ; MODIFIES : SCRATCH, issue_dsa_head
486 ;
487 ; EXITS : on reselection or selection, go to select_failed
488 ; otherwise, fall through to data_transfer. If a MSG_IN
489 ; phase occurs before
490 ;
491
492 ENTRY select
493 select:
494
495
496
497
498 CLEAR TARGET
499
500 at 0x00000065 : */ 0x60000200,0x00000000,
501 /*
502
503 ; XXX
504 ;
505 ; In effect, SELECTION operations are backgrounded, with execution
506 ; continuing until code which waits for REQ or a fatal interrupt is
507 ; encountered.
508 ;
509 ; So, for more performance, we could overlap the code which removes
510 ; the command from the NCRs issue queue with the selection, but
511 ; at this point I don't want to deal with the error recovery.
512 ;
513
514
515 SELECT ATN FROM dsa_select, select_failed
516
517 at 0x00000067 : */ 0x4300003c,0x000006a4,
518 /*
519 JUMP select_msgout, WHEN MSG_OUT
520
521 at 0x00000069 : */ 0x860b0000,0x000001ac,
522 /*
523 ENTRY select_msgout
524 select_msgout:
525 MOVE FROM dsa_msgout, WHEN MSG_OUT
526
527 at 0x0000006b : */ 0x1e000000,0x00000040,
528 /*
529
530
531
532
533
534
535
536
537
538 ; Calculate address of dsa_next field
539
540 CALL dsa_to_scratch
541
542 at 0x0000006d : */ 0x88080000,0x000007e8,
543 /*
544
545 MOVE SCRATCH0 + dsa_next TO SCRATCH0
546
547 at 0x0000006f : */ 0x7e343000,0x00000000,
548 /*
549 MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
550
551 at 0x00000071 : */ 0x7f350000,0x00000000,
552 /*
553 MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
554
555 at 0x00000073 : */ 0x7f360000,0x00000000,
556 /*
557 MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
558
559 at 0x00000075 : */ 0x7f370000,0x00000000,
560 /*
561
562 ; Patch memory to memory move
563 move dmode_ncr_to_memory TO DMODE
564
565 at 0x00000077 : */ 0x78380000,0x00000000,
566 /*
567 MOVE MEMORY 4, addr_scratch, issue_remove + 4
568
569 at 0x00000079 : */ 0xc0000004,0x00000000,0x000001fc,
570 /*
571
572
573 ; And rewrite the issue_dsa_head pointer.
574 MOVE dmode_memory_to_memory TO DMODE
575
576 at 0x0000007c : */ 0x78380000,0x00000000,
577 /*
578 issue_remove:
579 ; The actual UPDATE of the issue_dsa_head variable is
580 ; atomic, with all of the setup code being irrelevant to
581 ; whether the updated value being the old or new contents of
582 ; dsa_next field.
583 ;
584 ; To insure synchronization, the host system merely needs to
585 ; do a XCHG instruction with interrupts disabled on the
586 ; issue_dsa_head memory address.
587 ;
588 ; The net effect will be that the XCHG instruction will return
589 ; either a non-NULL value, indicating that the NCR chip will not
590 ; go into the idle loop when this command DISCONNECTS, or a NULL
591 ; value indicating that the NCR wrote first and that the Linux
592 ; code must rewrite the issue_dsa_head pointer and set SIG_P.
593 ;
594
595
596 MOVE MEMORY 4, 0, issue_dsa_head
597
598 at 0x0000007e : */ 0xc0000004,0x00000000,0x00000000,
599 /*
600
601
602
603
604
605 ; After a successful selection, we should get either a CMD phase or
606 ; some transfer request negotiation message.
607
608 JUMP cmdout, WHEN CMD
609
610 at 0x00000081 : */ 0x820b0000,0x00000224,
611 /*
612 INT int_err_unexpected_phase, WHEN NOT MSG_IN
613
614 at 0x00000083 : */ 0x9f030000,0x00000000,
615 /*
616
617 select_msg_in:
618 CALL msg_in, WHEN MSG_IN
619
620 at 0x00000085 : */ 0x8f0b0000,0x00000354,
621 /*
622 JUMP select_msg_in, WHEN MSG_IN
623
624 at 0x00000087 : */ 0x870b0000,0x00000214,
625 /*
626
627 cmdout:
628 INT int_err_unexpected_phase, WHEN NOT CMD
629
630 at 0x00000089 : */ 0x9a030000,0x00000000,
631 /*
632
633
634
635 ENTRY cmdout_cmdout
636 cmdout_cmdout:
637
638 MOVE FROM dsa_cmdout, WHEN CMD
639
640 at 0x0000008b : */ 0x1a000000,0x00000048,
641 /*
642
643
644
645
646 ;
647 ; data_transfer
648 ; other_transfer
649 ;
650 ; PURPOSE : handle the main data transfer for a SCSI command in
651 ; two parts. In the first part, data_transfer, DATA_IN
652 ; and DATA_OUT phases are allowed, with the user provided
653 ; code (usually dynamically generated based on the scatter/gather
654 ; list associated with a SCSI command) called to handle these
655 ; phases.
656 ;
657 ; On completion, the user code passes control to other_transfer
658 ; which causes DATA_IN and DATA_OUT to result in unexpected_phase
659 ; interrupts so that data overruns may be trapped.
660 ;
661 ; INPUTS : DSA - SCSI command
662 ;
663 ; CALLS : OK
664 ;
665 ; MODIFIES : SCRATCH
666 ;
667 ; EXITS : if STATUS IN is detected, signifying command completion,
668 ; the NCR jumps to command_complete. If MSG IN occurs, a
669 ; CALL is made to msg_in. Otherwise, other_transfer runs in
670 ; an infinite loop.
671 ;
672
673 data_transfer:
674 INT int_err_unexpected_phase, WHEN CMD
675
676 at 0x0000008d : */ 0x9a0b0000,0x00000000,
677 /*
678 CALL msg_in, WHEN MSG_IN
679
680 at 0x0000008f : */ 0x8f0b0000,0x00000354,
681 /*
682 INT int_err_unexpected_phase, WHEN MSG_OUT
683
684 at 0x00000091 : */ 0x9e0b0000,0x00000000,
685 /*
686 JUMP do_dataout, WHEN DATA_OUT
687
688 at 0x00000093 : */ 0x800b0000,0x0000026c,
689 /*
690 JUMP do_datain, WHEN DATA_IN
691
692 at 0x00000095 : */ 0x810b0000,0x000002c4,
693 /*
694 JUMP command_complete, WHEN STATUS
695
696 at 0x00000097 : */ 0x830b0000,0x00000508,
697 /*
698 JUMP data_transfer
699
700 at 0x00000099 : */ 0x80080000,0x00000234,
701 /*
702
703 ;
704 ; On NCR53c700 and NCR53c700-66 chips, do_dataout/do_datain are fixed up
705 ; whenever the nexus changes so it can point to the correct routine for
706 ; that command.
707 ;
708
709
710 ; Nasty jump to dsa->dataout
711 do_dataout:
712 CALL dsa_to_scratch
713
714 at 0x0000009b : */ 0x88080000,0x000007e8,
715 /*
716 MOVE SCRATCH0 + dsa_dataout TO SCRATCH0
717
718 at 0x0000009d : */ 0x7e345000,0x00000000,
719 /*
720 MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
721
722 at 0x0000009f : */ 0x7f350000,0x00000000,
723 /*
724 MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
725
726 at 0x000000a1 : */ 0x7f360000,0x00000000,
727 /*
728 MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
729
730 at 0x000000a3 : */ 0x7f370000,0x00000000,
731 /*
732 MOVE dmode_ncr_to_memory TO DMODE
733
734 at 0x000000a5 : */ 0x78380000,0x00000000,
735 /*
736 MOVE MEMORY 4, addr_scratch, dataout_to_jump + 4
737
738 at 0x000000a7 : */ 0xc0000004,0x00000000,0x000002b4,
739 /*
740 MOVE dmode_memory_to_memory TO DMODE
741
742 at 0x000000aa : */ 0x78380000,0x00000000,
743 /*
744 dataout_to_jump:
745 MOVE MEMORY 4, 0, dataout_jump + 4
746
747 at 0x000000ac : */ 0xc0000004,0x00000000,0x000002c0,
748 /*
749 dataout_jump:
750 JUMP 0
751
752 at 0x000000af : */ 0x80080000,0x00000000,
753 /*
754
755 ; Nasty jump to dsa->dsain
756 do_datain:
757 CALL dsa_to_scratch
758
759 at 0x000000b1 : */ 0x88080000,0x000007e8,
760 /*
761 MOVE SCRATCH0 + dsa_datain TO SCRATCH0
762
763 at 0x000000b3 : */ 0x7e345400,0x00000000,
764 /*
765 MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
766
767 at 0x000000b5 : */ 0x7f350000,0x00000000,
768 /*
769 MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
770
771 at 0x000000b7 : */ 0x7f360000,0x00000000,
772 /*
773 MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
774
775 at 0x000000b9 : */ 0x7f370000,0x00000000,
776 /*
777 MOVE dmode_ncr_to_memory TO DMODE
778
779 at 0x000000bb : */ 0x78380000,0x00000000,
780 /*
781 MOVE MEMORY 4, addr_scratch, datain_to_jump + 4
782
783 at 0x000000bd : */ 0xc0000004,0x00000000,0x0000030c,
784 /*
785 MOVE dmode_memory_to_memory TO DMODE
786
787 at 0x000000c0 : */ 0x78380000,0x00000000,
788 /*
789 datain_to_jump:
790 MOVE MEMORY 4, 0, datain_jump + 4
791
792 at 0x000000c2 : */ 0xc0000004,0x00000000,0x00000318,
793 /*
794 datain_jump:
795 JUMP 0
796
797 at 0x000000c5 : */ 0x80080000,0x00000000,
798 /*
799
800
801 ;
802 ; other_transfer is exported because it is referenced by dynamically
803 ; generated code.
804 ;
805 ENTRY other_transfer
806 other_transfer:
807
808
809
810 INT int_err_unexpected_phase, WHEN CMD
811
812 at 0x000000c7 : */ 0x9a0b0000,0x00000000,
813 /*
814 CALL msg_in, WHEN MSG_IN
815
816 at 0x000000c9 : */ 0x8f0b0000,0x00000354,
817 /*
818 INT int_err_unexpected_phase, WHEN MSG_OUT
819
820 at 0x000000cb : */ 0x9e0b0000,0x00000000,
821 /*
822 INT int_err_unexpected_phase, WHEN DATA_OUT
823
824 at 0x000000cd : */ 0x980b0000,0x00000000,
825 /*
826 INT int_err_unexpected_phase, WHEN DATA_IN
827
828 at 0x000000cf : */ 0x990b0000,0x00000000,
829 /*
830 JUMP command_complete, WHEN STATUS
831
832 at 0x000000d1 : */ 0x830b0000,0x00000508,
833 /*
834 JUMP other_transfer
835
836 at 0x000000d3 : */ 0x80080000,0x0000031c,
837 /*
838
839 ;
840 ; msg_in
841 ; munge_msg
842 ;
843 ; PURPOSE : process messages from a target. msg_in is called when the
844 ; caller hasn't read the first byte of the message. munge_message
845 ; is called when the caller has read the first byte of the message,
846 ; and left it in SFBR.
847 ;
848 ; Various int_* interrupts are generated when the host system
849 ; needs to intervene, as is the case with SDTR, WDTR, and
850 ; INITIATE RECOVERY messages.
851 ;
852 ; When the host system handles one of these interrupts,
853 ; it can respond by reentering at reject_message,
854 ; which rejects the message and returns control to
855 ; the caller of msg_in or munge_msg, accept_message
856 ; which clears ACK and returns control, or reply_message
857 ; which sends the message pointed to by the DSA
858 ; msgout_other table indirect field.
859 ;
860 ; DISCONNECT messages are handled by moving the command
861 ; to the reconnect_dsa_queue.
862 ;
863 ; SAVE DATA POINTER and RESTORE DATA POINTERS are currently
864 ; treated as NOPS.
865 ;
866 ; INPUTS : DSA - SCSI COMMAND, SFBR - first byte of message (munge_msg
867 ; only)
868 ;
869 ; CALLS : NO. The TEMP register isn't backed up to allow nested calls.
870 ;
871 ; MODIFIES : SCRATCH, DSA on DISCONNECT
872 ;
873 ; EXITS : On receipt of SAVE DATA POINTER, RESTORE POINTERS,
874 ; and normal return from message handlers running under
875 ; Linux, control is returned to the caller. Receipt
876 ; of DISCONNECT messages pass control to dsa_schedule.
877 ;
878 ENTRY msg_in
879 msg_in:
880 MOVE 1, msg_buf, WHEN MSG_IN
881
882 at 0x000000d5 : */ 0x0f000001,0x00000000,
883 /*
884
885 munge_msg:
886 JUMP munge_extended, IF 0x01 ; EXTENDED MESSAGE
887
888 at 0x000000d7 : */ 0x800c0001,0x00000428,
889 /*
890 JUMP munge_2, IF 0x20, AND MASK 0xdf ; two byte message
891
892 at 0x000000d9 : */ 0x800cdf20,0x0000039c,
893 /*
894 ;
895 ; I've seen a handful of broken SCSI devices which fail to issue
896 ; a SAVE POINTERS message before disconnecting in the middle of
897 ; a transfer, assuming that the DATA POINTER will be implicitly
898 ; restored. So, we treat the SAVE DATA POINTER message as a NOP.
899 ;
900 ; I've also seen SCSI devices which don't issue a RESTORE DATA
901 ; POINTER message and assume that thats implicit.
902 ;
903 JUMP accept_message, IF 0x02 ; SAVE DATA POINTER
904
905 at 0x000000db : */ 0x800c0002,0x000004d8,
906 /*
907 JUMP accept_message, IF 0x03 ; RESTORE POINTERS
908
909 at 0x000000dd : */ 0x800c0003,0x000004d8,
910 /*
911 JUMP munge_disconnect, IF 0x04 ; DISCONNECT
912
913 at 0x000000df : */ 0x800c0004,0x000003b4,
914 /*
915 INT int_msg_1, IF 0x07 ; MESSAGE REJECT
916
917 at 0x000000e1 : */ 0x980c0007,0x01020000,
918 /*
919 INT int_msg_1, IF 0x0f ; INITIATE RECOVERY
920
921 at 0x000000e3 : */ 0x980c000f,0x01020000,
922 /*
923 JUMP reject_message
924
925 at 0x000000e5 : */ 0x80080000,0x000004b8,
926 /*
927
928 munge_2:
929 JUMP reject_message
930
931 at 0x000000e7 : */ 0x80080000,0x000004b8,
932 /*
933
934 munge_save_data_pointer:
935 CLEAR ACK
936
937 at 0x000000e9 : */ 0x60000040,0x00000000,
938 /*
939 RETURN
940
941 at 0x000000eb : */ 0x90080000,0x00000000,
942 /*
943
944 munge_disconnect:
945 MOVE SCNTL2 & 0x7f TO SCNTL2
946
947 at 0x000000ed : */ 0x7c027f00,0x00000000,
948 /*
949 CLEAR ACK
950
951 at 0x000000ef : */ 0x60000040,0x00000000,
952 /*
953
954
955 ; Pass control to the DSA routine. Note that we can not call
956 ; dsa_to_scratch here because that would clobber temp, which
957 ; we must preserve.
958 MOVE DSA0 TO SFBR
959
960 at 0x000000f1 : */ 0x72100000,0x00000000,
961 /*
962 MOVE SFBR TO SCRATCH0
963
964 at 0x000000f3 : */ 0x6a340000,0x00000000,
965 /*
966 MOVE DSA1 TO SFBR
967
968 at 0x000000f5 : */ 0x72110000,0x00000000,
969 /*
970 MOVE SFBR TO SCRATCH1
971
972 at 0x000000f7 : */ 0x6a350000,0x00000000,
973 /*
974 MOVE DSA2 TO SFBR
975
976 at 0x000000f9 : */ 0x72120000,0x00000000,
977 /*
978 MOVE SFBR TO SCRATCH2
979
980 at 0x000000fb : */ 0x6a360000,0x00000000,
981 /*
982 MOVE DSA3 TO SFBR
983
984 at 0x000000fd : */ 0x72130000,0x00000000,
985 /*
986 MOVE SFBR TO SCRATCH3
987
988 at 0x000000ff : */ 0x6a370000,0x00000000,
989 /*
990
991 MOVE dmode_ncr_to_memory TO DMODE
992
993 at 0x00000101 : */ 0x78380000,0x00000000,
994 /*
995 MOVE MEMORY 4, addr_scratch, jump_to_dsa + 4
996
997 at 0x00000103 : */ 0xc0000004,0x00000000,0x00000424,
998 /*
999 MOVE dmode_memory_to_memory TO DMODE
1000
1001 at 0x00000106 : */ 0x78380000,0x00000000,
1002 /*
1003 jump_to_dsa:
1004 JUMP 0
1005
1006 at 0x00000108 : */ 0x80080000,0x00000000,
1007 /*
1008
1009
1010
1011
1012
1013 munge_extended:
1014 CLEAR ACK
1015
1016 at 0x0000010a : */ 0x60000040,0x00000000,
1017 /*
1018 INT int_err_unexpected_phase, WHEN NOT MSG_IN
1019
1020 at 0x0000010c : */ 0x9f030000,0x00000000,
1021 /*
1022 MOVE 1, msg_buf + 1, WHEN MSG_IN
1023
1024 at 0x0000010e : */ 0x0f000001,0x00000001,
1025 /*
1026 JUMP munge_extended_2, IF 0x02
1027
1028 at 0x00000110 : */ 0x800c0002,0x00000458,
1029 /*
1030 JUMP munge_extended_3, IF 0x03
1031
1032 at 0x00000112 : */ 0x800c0003,0x00000488,
1033 /*
1034 JUMP reject_message
1035
1036 at 0x00000114 : */ 0x80080000,0x000004b8,
1037 /*
1038
1039 munge_extended_2:
1040 CLEAR ACK
1041
1042 at 0x00000116 : */ 0x60000040,0x00000000,
1043 /*
1044 MOVE 1, msg_buf + 2, WHEN MSG_IN
1045
1046 at 0x00000118 : */ 0x0f000001,0x00000002,
1047 /*
1048 JUMP reject_message, IF NOT 0x02 ; Must be WDTR
1049
1050 at 0x0000011a : */ 0x80040002,0x000004b8,
1051 /*
1052 CLEAR ACK
1053
1054 at 0x0000011c : */ 0x60000040,0x00000000,
1055 /*
1056 MOVE 1, msg_buf + 3, WHEN MSG_IN
1057
1058 at 0x0000011e : */ 0x0f000001,0x00000003,
1059 /*
1060 INT int_msg_wdtr
1061
1062 at 0x00000120 : */ 0x98080000,0x01000000,
1063 /*
1064
1065 munge_extended_3:
1066 CLEAR ACK
1067
1068 at 0x00000122 : */ 0x60000040,0x00000000,
1069 /*
1070 MOVE 1, msg_buf + 2, WHEN MSG_IN
1071
1072 at 0x00000124 : */ 0x0f000001,0x00000002,
1073 /*
1074 JUMP reject_message, IF NOT 0x01 ; Must be SDTR
1075
1076 at 0x00000126 : */ 0x80040001,0x000004b8,
1077 /*
1078 CLEAR ACK
1079
1080 at 0x00000128 : */ 0x60000040,0x00000000,
1081 /*
1082 MOVE 2, msg_buf + 3, WHEN MSG_IN
1083
1084 at 0x0000012a : */ 0x0f000002,0x00000003,
1085 /*
1086 INT int_msg_sdtr
1087
1088 at 0x0000012c : */ 0x98080000,0x01010000,
1089 /*
1090
1091 ENTRY reject_message
1092 reject_message:
1093 SET ATN
1094
1095 at 0x0000012e : */ 0x58000008,0x00000000,
1096 /*
1097 CLEAR ACK
1098
1099 at 0x00000130 : */ 0x60000040,0x00000000,
1100 /*
1101 MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT
1102
1103 at 0x00000132 : */ 0x0e000001,0x00000000,
1104 /*
1105 RETURN
1106
1107 at 0x00000134 : */ 0x90080000,0x00000000,
1108 /*
1109
1110 ENTRY accept_message
1111 accept_message:
1112 CLEAR ACK
1113
1114 at 0x00000136 : */ 0x60000040,0x00000000,
1115 /*
1116 RETURN
1117
1118 at 0x00000138 : */ 0x90080000,0x00000000,
1119 /*
1120
1121 ENTRY respond_message
1122 msg_respond:
1123 SET ATN
1124
1125 at 0x0000013a : */ 0x58000008,0x00000000,
1126 /*
1127 CLEAR ACK
1128
1129 at 0x0000013c : */ 0x60000040,0x00000000,
1130 /*
1131 MOVE FROM dsa_msgout_other, WHEN MSG_OUT
1132
1133 at 0x0000013e : */ 0x1e000000,0x00000068,
1134 /*
1135 RETURN
1136
1137 at 0x00000140 : */ 0x90080000,0x00000000,
1138 /*
1139
1140 ;
1141 ; command_complete
1142 ;
1143 ; PURPOSE : handle command termination when STATUS IN is detected by reading
1144 ; a status byte followed by a command termination message.
1145 ;
1146 ; Normal termination results in an INTFLY instruction, and
1147 ; the host system can pick out which command terminated by
1148 ; examining the MESSAGE and STATUS buffers of all currently
1149 ; executing commands;
1150 ;
1151 ; Abnormal (CHECK_CONDITION) termination results in an
1152 ; int_err_check_condition interrupt so that a REQUEST SENSE
1153 ; command can be issued out-of-order so that no other command
1154 ; clears the contingent allegiance condition.
1155 ;
1156 ;
1157 ; INPUTS : DSA - command
1158 ;
1159 ; CALLS : OK
1160 ;
1161 ; EXITS : On successful termination, control is passed to schedule.
1162 ; On abnormal termination, the user will usually modify the
1163 ; DSA fields and corresponding buffers and return control
1164 ; to select.
1165 ;
1166
1167 ENTRY command_complete
1168 command_complete:
1169 MOVE FROM dsa_status, WHEN STATUS
1170
1171 at 0x00000142 : */ 0x1b000000,0x00000060,
1172 /*
1173
1174 MOVE SFBR TO SCRATCH0 ; Save status
1175
1176 at 0x00000144 : */ 0x6a340000,0x00000000,
1177 /*
1178
1179 ENTRY command_complete_msgin
1180 command_complete_msgin:
1181 MOVE FROM dsa_msgin, WHEN MSG_IN
1182
1183 at 0x00000146 : */ 0x1f000000,0x00000058,
1184 /*
1185 ; Indicate that we should be expecting a disconnect
1186 MOVE SCNTL2 & 0x7f TO SCNTL2
1187
1188 at 0x00000148 : */ 0x7c027f00,0x00000000,
1189 /*
1190 CLEAR ACK
1191
1192 at 0x0000014a : */ 0x60000040,0x00000000,
1193 /*
1194
1195 MOVE SCRATCH0 TO SFBR
1196
1197 at 0x0000014c : */ 0x72340000,0x00000000,
1198 /*
1199
1200 ;
1201 ; The SCSI specification states that when a UNIT ATTENTION condition
1202 ; is pending, as indicated by a CHECK CONDITION status message,
1203 ; the target shall revert to asynchronous transfers. Since
1204 ; synchronous transfers parameters are maintained on a per INITIATOR/TARGET
1205 ; basis, and returning control to our scheduler could work on a command
1206 ; running on another lun on that target using the old parameters, we must
1207 ; interrupt the host processor to get them changed, or change them ourselves.
1208 ;
1209 ; Once SCSI-II tagged queueing is implemented, things will be even more
1210 ; hairy, since contingent allegiance conditions exist on a per-target/lun
1211 ; basis, and issuing a new command with a different tag would clear it.
1212 ; In these cases, we must interrupt the host processor to get a request
1213 ; added to the HEAD of the queue with the request sense command, or we
1214 ; must automatically issue the request sense command.
1215
1216
1217
1218
1219 INTFLY
1220
1221 at 0x0000014e : */ 0x98180000,0x00000000,
1222 /*
1223
1224 WAIT DISCONNECT
1225
1226 at 0x00000150 : */ 0x48000000,0x00000000,
1227 /*
1228
1229 JUMP schedule
1230
1231 at 0x00000152 : */ 0x80080000,0x00000130,
1232 /*
1233 command_failed:
1234 WAIT DISCONNECT
1235
1236 at 0x00000154 : */ 0x48000000,0x00000000,
1237 /*
1238 INT int_err_check_condition
1239
1240 at 0x00000156 : */ 0x98080000,0x00030000,
1241 /*
1242
1243
1244
1245
1246 ;
1247 ; wait_reselect
1248 ;
1249 ; PURPOSE : This is essentially the idle routine, where control lands
1250 ; when there are no new processes to schedule. wait_reselect
1251 ; waits for reselection, selection, and new commands.
1252 ;
1253 ; When a successful reselection occurs, with the aid
1254 ; of fixed up code in each DSA, wait_reselect walks the
1255 ; reconnect_dsa_queue, asking each dsa if the target ID
1256 ; and LUN match its.
1257 ;
1258 ; If a match is found, a call is made back to reselected_ok,
1259 ; which through the miracles of self modifying code, extracts
1260 ; the found DSA from the reconnect_dsa_queue and then
1261 ; returns control to the DSAs thread of execution.
1262 ;
1263 ; INPUTS : NONE
1264 ;
1265 ; CALLS : OK
1266 ;
1267 ; MODIFIES : DSA,
1268 ;
1269 ; EXITS : On successful reselection, control is returned to the
1270 ; DSA which called reselected_ok. If the WAIT RESELECT
1271 ; was interrupted by a new commands arrival signaled by
1272 ; SIG_P, control is passed to schedule. If the NCR is
1273 ; selected, the host system is interrupted with an
1274 ; int_err_selected which is usually responded to by
1275 ; setting DSP to the target_abort address.
1276
1277 wait_reselect:
1278
1279
1280
1281 WAIT RESELECT wait_reselect_failed
1282
1283 at 0x00000158 : */ 0x50000000,0x0000067c,
1284 /*
1285
1286 reselected:
1287 ; Read all data needed to reestablish the nexus -
1288 MOVE 1, reselected_identify, WHEN MSG_IN
1289
1290 at 0x0000015a : */ 0x0f000001,0x00000000,
1291 /*
1292
1293 ; Well add a jump to here after some how determining that
1294 ; tagged queueing isn't in use on this device.
1295 reselected_notag:
1296 MOVE MEMORY 1, NCR53c7xx_zero, reselected_tag
1297
1298 at 0x0000015c : */ 0xc0000001,0x00000000,0x00000000,
1299 /*
1300
1301
1302
1303
1304
1305 ; Point DSA at the current head of the disconnected queue.
1306 MOVE dmode_memory_to_ncr TO DMODE
1307
1308 at 0x0000015f : */ 0x78380000,0x00000000,
1309 /*
1310 MOVE MEMORY 4, reconnect_dsa_head, addr_scratch
1311
1312 at 0x00000161 : */ 0xc0000004,0x00000000,0x00000000,
1313 /*
1314 MOVE dmode_memory_to_memory TO DMODE
1315
1316 at 0x00000164 : */ 0x78380000,0x00000000,
1317 /*
1318 CALL scratch_to_dsa
1319
1320 at 0x00000166 : */ 0x88080000,0x00000830,
1321 /*
1322
1323 ; Fix the update-next pointer so that the reconnect_dsa_head
1324 ; pointer is the one that will be updated if this DSA is a hit
1325 ; and we remove it from the queue.
1326
1327 MOVE MEMORY 4, reconnect_dsa_head, reselected_ok + 8
1328
1329 at 0x00000168 : */ 0xc0000004,0x00000000,0x00000660,
1330 /*
1331
1332 ENTRY reselected_check_next
1333 reselected_check_next:
1334 ; Check for a NULL pointer.
1335 MOVE DSA0 TO SFBR
1336
1337 at 0x0000016b : */ 0x72100000,0x00000000,
1338 /*
1339 JUMP reselected_not_end, IF NOT 0
1340
1341 at 0x0000016d : */ 0x80040000,0x000005f4,
1342 /*
1343 MOVE DSA1 TO SFBR
1344
1345 at 0x0000016f : */ 0x72110000,0x00000000,
1346 /*
1347 JUMP reselected_not_end, IF NOT 0
1348
1349 at 0x00000171 : */ 0x80040000,0x000005f4,
1350 /*
1351 MOVE DSA2 TO SFBR
1352
1353 at 0x00000173 : */ 0x72120000,0x00000000,
1354 /*
1355 JUMP reselected_not_end, IF NOT 0
1356
1357 at 0x00000175 : */ 0x80040000,0x000005f4,
1358 /*
1359 MOVE DSA3 TO SFBR
1360
1361 at 0x00000177 : */ 0x72130000,0x00000000,
1362 /*
1363 JUMP reselected_not_end, IF NOT 0
1364
1365 at 0x00000179 : */ 0x80040000,0x000005f4,
1366 /*
1367 INT int_err_unexpected_reselect
1368
1369 at 0x0000017b : */ 0x98080000,0x00020000,
1370 /*
1371
1372 reselected_not_end:
1373 MOVE DSA0 TO SFBR
1374
1375 at 0x0000017d : */ 0x72100000,0x00000000,
1376 /*
1377 ;
1378 ; XXX the ALU is only eight bits wide, and the assembler
1379 ; wont do the dirt work for us. As long as dsa_check_reselect
1380 ; is negative, we need to sign extend with 1 bits to the full
1381 ; 32 bit width of the address.
1382 ;
1383 ; A potential work around would be to have a known alignment
1384 ; of the DSA structure such that the base address plus
1385 ; dsa_check_reselect doesn't require carrying from bytes
1386 ; higher than the LSB.
1387 ;
1388
1389 MOVE SFBR + dsa_check_reselect TO SCRATCH0
1390
1391 at 0x0000017f : */ 0x6e340000,0x00000000,
1392 /*
1393 MOVE DSA1 TO SFBR
1394
1395 at 0x00000181 : */ 0x72110000,0x00000000,
1396 /*
1397 MOVE SFBR + 0xff TO SCRATCH1 WITH CARRY
1398
1399 at 0x00000183 : */ 0x6f35ff00,0x00000000,
1400 /*
1401 MOVE DSA2 TO SFBR
1402
1403 at 0x00000185 : */ 0x72120000,0x00000000,
1404 /*
1405 MOVE SFBR + 0xff TO SCRATCH2 WITH CARRY
1406
1407 at 0x00000187 : */ 0x6f36ff00,0x00000000,
1408 /*
1409 MOVE DSA3 TO SFBR
1410
1411 at 0x00000189 : */ 0x72130000,0x00000000,
1412 /*
1413 MOVE SFBR + 0xff TO SCRATCH3 WITH CARRY
1414
1415 at 0x0000018b : */ 0x6f37ff00,0x00000000,
1416 /*
1417
1418 MOVE dmode_ncr_to_memory TO DMODE
1419
1420 at 0x0000018d : */ 0x78380000,0x00000000,
1421 /*
1422 MOVE MEMORY 4, addr_scratch, reselected_check + 4
1423
1424 at 0x0000018f : */ 0xc0000004,0x00000000,0x00000654,
1425 /*
1426 MOVE dmode_memory_to_memory TO DMODE
1427
1428 at 0x00000192 : */ 0x78380000,0x00000000,
1429 /*
1430 reselected_check:
1431 JUMP 0
1432
1433 at 0x00000194 : */ 0x80080000,0x00000000,
1434 /*
1435
1436
1437 ;
1438 ;
1439 reselected_ok:
1440 MOVE MEMORY 4, 0, 0 ; Patched : first word
1441
1442 at 0x00000196 : */ 0xc0000004,0x00000000,0x00000000,
1443 /*
1444 ; is this successful
1445 ; dsa_next
1446 ; Second word is
1447 ; unsuccessful dsa_next
1448 CLEAR ACK ; Accept last message
1449
1450 at 0x00000199 : */ 0x60000040,0x00000000,
1451 /*
1452 RETURN ; Return control to where
1453
1454 at 0x0000019b : */ 0x90080000,0x00000000,
1455 /*
1456
1457
1458
1459
1460 selected:
1461 INT int_err_selected;
1462
1463 at 0x0000019d : */ 0x98080000,0x00010000,
1464 /*
1465
1466 ;
1467 ; A select or reselect failure can be caused by one of two conditions :
1468 ; 1. SIG_P was set. This will be the case if the user has written
1469 ; a new value to a previously NULL head of the issue queue.
1470 ;
1471 ; 2. The NCR53c810 was selected or reselected by another device.
1472 ;
1473
1474 wait_reselect_failed:
1475 ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
1476 MOVE CTEST2 & 0x40 TO SFBR
1477
1478 at 0x0000019f : */ 0x741a4000,0x00000000,
1479 /*
1480 JUMP schedule, IF 0x40
1481
1482 at 0x000001a1 : */ 0x800c0040,0x00000130,
1483 /*
1484 MOVE SIST0 & 0x20 TO SFBR
1485
1486 at 0x000001a3 : */ 0x74422000,0x00000000,
1487 /*
1488 JUMP selected, IF 0x20
1489
1490 at 0x000001a5 : */ 0x800c0020,0x00000674,
1491 /*
1492 ; FIXME : Something bogus happened, and we shouldn't fail silently.
1493 JUMP schedule
1494
1495 at 0x000001a7 : */ 0x80080000,0x00000130,
1496 /*
1497
1498 select_failed:
1499 ; If SIGP is set, the user just gave us another command, and
1500 ; we should restart or return to the scheduler.
1501 ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
1502 MOVE CTEST2 & 0x40 TO SFBR
1503
1504 at 0x000001a9 : */ 0x741a4000,0x00000000,
1505 /*
1506 JUMP select, IF 0x40
1507
1508 at 0x000001ab : */ 0x800c0040,0x00000194,
1509 /*
1510 ; Otherwise, mask the selected and reselected bits off SIST0
1511 MOVE SIST0 & 0x30 TO SFBR
1512
1513 at 0x000001ad : */ 0x74423000,0x00000000,
1514 /*
1515 JUMP selected, IF 0x20
1516
1517 at 0x000001af : */ 0x800c0020,0x00000674,
1518 /*
1519 JUMP reselected, IF 0x10
1520
1521 at 0x000001b1 : */ 0x800c0010,0x00000568,
1522 /*
1523 ; FIXME : Something bogus happened, and we shouldn't fail silently.
1524 JUMP schedule
1525
1526 at 0x000001b3 : */ 0x80080000,0x00000130,
1527 /*
1528
1529 ;
1530 ; test_1
1531 ; test_2
1532 ;
1533 ; PURPOSE : run some verification tests on the NCR. test_1
1534 ; copies test_src to test_dest and interrupts the host
1535 ; processor, testing for cache coherency and interrupt
1536 ; problems in the processes.
1537 ;
1538 ; test_2 runs a command with offsets relative to the
1539 ; DSA on entry, and is useful for miscellaneous experimentation.
1540 ;
1541
1542 ; Verify that interrupts are working correctly and that we don't
1543 ; have a cache invalidation problem.
1544
1545 ABSOLUTE test_src = 0, test_dest = 0
1546 ENTRY test_1
1547 test_1:
1548 MOVE MEMORY 4, test_src, test_dest
1549
1550 at 0x000001b5 : */ 0xc0000004,0x00000000,0x00000000,
1551 /*
1552 INT int_test_1
1553
1554 at 0x000001b8 : */ 0x98080000,0x04000000,
1555 /*
1556
1557 ;
1558 ; Run arbitrary commands, with test code establishing a DSA
1559 ;
1560
1561 ENTRY test_2
1562 test_2:
1563 CLEAR TARGET
1564
1565 at 0x000001ba : */ 0x60000200,0x00000000,
1566 /*
1567 SELECT ATN FROM 0, test_2_fail
1568
1569 at 0x000001bc : */ 0x43000000,0x00000740,
1570 /*
1571 JUMP test_2_msgout, WHEN MSG_OUT
1572
1573 at 0x000001be : */ 0x860b0000,0x00000700,
1574 /*
1575 ENTRY test_2_msgout
1576 test_2_msgout:
1577 MOVE FROM 8, WHEN MSG_OUT
1578
1579 at 0x000001c0 : */ 0x1e000000,0x00000008,
1580 /*
1581 MOVE FROM 16, WHEN CMD
1582
1583 at 0x000001c2 : */ 0x1a000000,0x00000010,
1584 /*
1585 MOVE FROM 24, WHEN DATA_IN
1586
1587 at 0x000001c4 : */ 0x19000000,0x00000018,
1588 /*
1589 MOVE FROM 32, WHEN STATUS
1590
1591 at 0x000001c6 : */ 0x1b000000,0x00000020,
1592 /*
1593 MOVE FROM 40, WHEN MSG_IN
1594
1595 at 0x000001c8 : */ 0x1f000000,0x00000028,
1596 /*
1597 MOVE SCNTL2 & 0x7f TO SCNTL2
1598
1599 at 0x000001ca : */ 0x7c027f00,0x00000000,
1600 /*
1601 CLEAR ACK
1602
1603 at 0x000001cc : */ 0x60000040,0x00000000,
1604 /*
1605 WAIT DISCONNECT
1606
1607 at 0x000001ce : */ 0x48000000,0x00000000,
1608 /*
1609 test_2_fail:
1610 INT int_test_2
1611
1612 at 0x000001d0 : */ 0x98080000,0x04010000,
1613 /*
1614
1615 ENTRY debug_break
1616 debug_break:
1617 INT int_debug_break
1618
1619 at 0x000001d2 : */ 0x98080000,0x03000000,
1620 /*
1621
1622 ;
1623 ; initiator_abort
1624 ; target_abort
1625 ;
1626 ; PURPOSE : Abort the currently established nexus from with initiator
1627 ; or target mode.
1628 ;
1629 ;
1630
1631 ENTRY target_abort
1632 target_abort:
1633 SET TARGET
1634
1635 at 0x000001d4 : */ 0x58000200,0x00000000,
1636 /*
1637 DISCONNECT
1638
1639 at 0x000001d6 : */ 0x48000000,0x00000000,
1640 /*
1641 CLEAR TARGET
1642
1643 at 0x000001d8 : */ 0x60000200,0x00000000,
1644 /*
1645 JUMP schedule
1646
1647 at 0x000001da : */ 0x80080000,0x00000130,
1648 /*
1649
1650 ENTRY initiator_abort
1651 initiator_abort:
1652 SET ATN
1653
1654 at 0x000001dc : */ 0x58000008,0x00000000,
1655 /*
1656 ; In order to abort the currently established nexus, we
1657 ; need to source/sink up to one byte of data in any SCSI phase,
1658 ; since the phase cannot change until REQ transitions
1659 ; false->true
1660 JUMP no_eat_cmd, WHEN NOT CMD
1661
1662 at 0x000001de : */ 0x82030000,0x00000788,
1663 /*
1664 MOVE 1, NCR53c7xx_zero, WHEN CMD
1665
1666 at 0x000001e0 : */ 0x0a000001,0x00000000,
1667 /*
1668 no_eat_cmd:
1669 JUMP no_eat_msg, WHEN NOT MSG_IN
1670
1671 at 0x000001e2 : */ 0x87030000,0x00000798,
1672 /*
1673 MOVE 1, NCR53c7xx_sink, WHEN MSG_IN
1674
1675 at 0x000001e4 : */ 0x0f000001,0x00000000,
1676 /*
1677 no_eat_msg:
1678 JUMP no_eat_data, WHEN NOT DATA_IN
1679
1680 at 0x000001e6 : */ 0x81030000,0x000007a8,
1681 /*
1682 MOVE 1, NCR53c7xx_sink, WHEN DATA_IN
1683
1684 at 0x000001e8 : */ 0x09000001,0x00000000,
1685 /*
1686 no_eat_data:
1687 JUMP no_eat_status, WHEN NOT STATUS
1688
1689 at 0x000001ea : */ 0x83030000,0x000007b8,
1690 /*
1691 MOVE 1, NCR53c7xx_sink, WHEN STATUS
1692
1693 at 0x000001ec : */ 0x0b000001,0x00000000,
1694 /*
1695 no_eat_status:
1696 JUMP no_source_data, WHEN NOT DATA_OUT
1697
1698 at 0x000001ee : */ 0x80030000,0x000007c8,
1699 /*
1700 MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT
1701
1702 at 0x000001f0 : */ 0x08000001,0x00000000,
1703 /*
1704 no_source_data:
1705 ;
1706 ; If DSP points here, and a phase mismatch is encountered, we need to
1707 ; do a bus reset.
1708 ;
1709
1710 MOVE SCNTL2 & 0x7f TO SCNTL2
1711
1712 at 0x000001f2 : */ 0x7c027f00,0x00000000,
1713 /*
1714 MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
1715
1716 at 0x000001f4 : */ 0x0e000001,0x00000000,
1717 /*
1718 WAIT DISCONNECT
1719
1720 at 0x000001f6 : */ 0x48000000,0x00000000,
1721 /*
1722 INT int_norm_aborted
1723
1724 at 0x000001f8 : */ 0x98080000,0x02040000,
1725 /*
1726
1727 ;
1728 ; dsa_to_scratch
1729 ; scratch_to_dsa
1730 ;
1731 ; PURPOSE :
1732 ; The NCR chips cannot do a move memory instruction with the DSA register
1733 ; as the source or destination. So, we provide a couple of subroutines
1734 ; that let us switch between the DSA register and scratch register.
1735 ;
1736 ; Memory moves to/from the DSPS register also don't work, but we
1737 ; don't use them.
1738 ;
1739 ;
1740
1741
1742 dsa_to_scratch:
1743 MOVE DSA0 TO SFBR
1744
1745 at 0x000001fa : */ 0x72100000,0x00000000,
1746 /*
1747 MOVE SFBR TO SCRATCH0
1748
1749 at 0x000001fc : */ 0x6a340000,0x00000000,
1750 /*
1751 MOVE DSA1 TO SFBR
1752
1753 at 0x000001fe : */ 0x72110000,0x00000000,
1754 /*
1755 MOVE SFBR TO SCRATCH1
1756
1757 at 0x00000200 : */ 0x6a350000,0x00000000,
1758 /*
1759 MOVE DSA2 TO SFBR
1760
1761 at 0x00000202 : */ 0x72120000,0x00000000,
1762 /*
1763 MOVE SFBR TO SCRATCH2
1764
1765 at 0x00000204 : */ 0x6a360000,0x00000000,
1766 /*
1767 MOVE DSA3 TO SFBR
1768
1769 at 0x00000206 : */ 0x72130000,0x00000000,
1770 /*
1771 MOVE SFBR TO SCRATCH3
1772
1773 at 0x00000208 : */ 0x6a370000,0x00000000,
1774 /*
1775 RETURN
1776
1777 at 0x0000020a : */ 0x90080000,0x00000000,
1778 /*
1779
1780 scratch_to_dsa:
1781 MOVE SCRATCH0 TO SFBR
1782
1783 at 0x0000020c : */ 0x72340000,0x00000000,
1784 /*
1785 MOVE SFBR TO DSA0
1786
1787 at 0x0000020e : */ 0x6a100000,0x00000000,
1788 /*
1789 MOVE SCRATCH1 TO SFBR
1790
1791 at 0x00000210 : */ 0x72350000,0x00000000,
1792 /*
1793 MOVE SFBR TO DSA1
1794
1795 at 0x00000212 : */ 0x6a110000,0x00000000,
1796 /*
1797 MOVE SCRATCH2 TO SFBR
1798
1799 at 0x00000214 : */ 0x72360000,0x00000000,
1800 /*
1801 MOVE SFBR TO DSA2
1802
1803 at 0x00000216 : */ 0x6a120000,0x00000000,
1804 /*
1805 MOVE SCRATCH3 TO SFBR
1806
1807 at 0x00000218 : */ 0x72370000,0x00000000,
1808 /*
1809 MOVE SFBR TO DSA3
1810
1811 at 0x0000021a : */ 0x6a130000,0x00000000,
1812 /*
1813 RETURN
1814
1815 at 0x0000021c : */ 0x90080000,0x00000000,
1816 };
1817
1818 #define A_NCR53c7xx_msg_abort 0x00000000
1819 u32 A_NCR53c7xx_msg_abort_used[] = {
1820 0x000001f5,
1821 };
1822
1823 #define A_NCR53c7xx_msg_reject 0x00000000
1824 u32 A_NCR53c7xx_msg_reject_used[] = {
1825 0x00000133,
1826 };
1827
1828 #define A_NCR53c7xx_sink 0x00000000
1829 u32 A_NCR53c7xx_sink_used[] = {
1830 0x000001e5,
1831 0x000001e9,
1832 0x000001ed,
1833 };
1834
1835 #define A_NCR53c7xx_zero 0x00000000
1836 u32 A_NCR53c7xx_zero_used[] = {
1837 0x0000015d,
1838 0x000001e1,
1839 0x000001f1,
1840 };
1841
1842 #define A_addr_scratch 0x00000000
1843 u32 A_addr_scratch_used[] = {
1844 0x00000007,
1845 0x0000003a,
1846 0x00000046,
1847 0x00000050,
1848 0x0000007a,
1849 0x000000a8,
1850 0x000000be,
1851 0x00000104,
1852 0x00000163,
1853 0x00000190,
1854 };
1855
1856 #define A_addr_sfbr 0x00000000
1857 u32 A_addr_sfbr_used[] = {
1858 0x00000016,
1859 };
1860
1861 #define A_addr_temp 0x00000000
1862 u32 A_addr_temp_used[] = {
1863 0x00000027,
1864 };
1865
1866 #define A_dmode_memory_to_memory 0x00000000
1867 u32 A_dmode_memory_to_memory_used[] = {
1868 0x00000008,
1869 0x00000019,
1870 0x00000029,
1871 0x0000003c,
1872 0x00000048,
1873 0x00000051,
1874 0x0000007c,
1875 0x000000aa,
1876 0x000000c0,
1877 0x00000106,
1878 0x00000164,
1879 0x00000192,
1880 };
1881
1882 #define A_dmode_memory_to_ncr 0x00000000
1883 u32 A_dmode_memory_to_ncr_used[] = {
1884 0x00000003,
1885 0x00000012,
1886 0x0000004c,
1887 0x0000015f,
1888 };
1889
1890 #define A_dmode_ncr_to_memory 0x00000000
1891 u32 A_dmode_ncr_to_memory_used[] = {
1892 0x00000024,
1893 0x00000037,
1894 0x00000043,
1895 0x00000077,
1896 0x000000a5,
1897 0x000000bb,
1898 0x00000101,
1899 0x0000018d,
1900 };
1901
1902 #define A_dmode_ncr_to_ncr 0x00000000
1903 u32 A_dmode_ncr_to_ncr_used[] = {
1904 };
1905
1906 #define A_dsa_check_reselect 0x00000000
1907 u32 A_dsa_check_reselect_used[] = {
1908 0x0000017f,
1909 };
1910
1911 #define A_dsa_cmdout 0x00000048
1912 u32 A_dsa_cmdout_used[] = {
1913 0x0000008c,
1914 };
1915
1916 #define A_dsa_cmnd 0x00000038
1917 u32 A_dsa_cmnd_used[] = {
1918 };
1919
1920 #define A_dsa_datain 0x00000054
1921 u32 A_dsa_datain_used[] = {
1922 0x000000b3,
1923 };
1924
1925 #define A_dsa_dataout 0x00000050
1926 u32 A_dsa_dataout_used[] = {
1927 0x0000009d,
1928 };
1929
1930 #define A_dsa_end 0x00000070
1931 u32 A_dsa_end_used[] = {
1932 };
1933
1934 #define A_dsa_fields_start 0x00000024
1935 u32 A_dsa_fields_start_used[] = {
1936 };
1937
1938 #define A_dsa_msgin 0x00000058
1939 u32 A_dsa_msgin_used[] = {
1940 0x00000147,
1941 };
1942
1943 #define A_dsa_msgout 0x00000040
1944 u32 A_dsa_msgout_used[] = {
1945 0x0000006c,
1946 };
1947
1948 #define A_dsa_msgout_other 0x00000068
1949 u32 A_dsa_msgout_other_used[] = {
1950 0x0000013f,
1951 };
1952
1953 #define A_dsa_next 0x00000030
1954 u32 A_dsa_next_used[] = {
1955 0x0000002f,
1956 0x0000006f,
1957 };
1958
1959 #define A_dsa_select 0x0000003c
1960 u32 A_dsa_select_used[] = {
1961 0x00000067,
1962 };
1963
1964 #define A_dsa_status 0x00000060
1965 u32 A_dsa_status_used[] = {
1966 0x00000143,
1967 };
1968
1969 #define A_dsa_temp_dsa_next 0x00000000
1970 u32 A_dsa_temp_dsa_next_used[] = {
1971 0x00000001,
1972 0x00000006,
1973 0x0000001c,
1974 };
1975
1976 #define A_dsa_temp_jump_resume 0x00000000
1977 u32 A_dsa_temp_jump_resume_used[] = {
1978 0x00000028,
1979 };
1980
1981 #define A_dsa_temp_lun 0x00000000
1982 u32 A_dsa_temp_lun_used[] = {
1983 0x00000017,
1984 };
1985
1986 #define A_dsa_temp_sync 0x00000000
1987 u32 A_dsa_temp_sync_used[] = {
1988 0x00000021,
1989 };
1990
1991 #define A_dsa_temp_target 0x00000000
1992 u32 A_dsa_temp_target_used[] = {
1993 0x00000010,
1994 };
1995
1996 #define A_int_debug_break 0x03000000
1997 u32 A_int_debug_break_used[] = {
1998 0x000001d3,
1999 };
2000
2001 #define A_int_debug_dsa_loaded 0x03030000
2002 u32 A_int_debug_dsa_loaded_used[] = {
2003 };
2004
2005 #define A_int_debug_head 0x03050000
2006 u32 A_int_debug_head_used[] = {
2007 };
2008
2009 #define A_int_debug_idle 0x03020000
2010 u32 A_int_debug_idle_used[] = {
2011 };
2012
2013 #define A_int_debug_reselected 0x03040000
2014 u32 A_int_debug_reselected_used[] = {
2015 };
2016
2017 #define A_int_debug_scheduled 0x03010000
2018 u32 A_int_debug_scheduled_used[] = {
2019 };
2020
2021 #define A_int_err_check_condition 0x00030000
2022 u32 A_int_err_check_condition_used[] = {
2023 0x00000157,
2024 };
2025
2026 #define A_int_err_no_phase 0x00040000
2027 u32 A_int_err_no_phase_used[] = {
2028 };
2029
2030 #define A_int_err_selected 0x00010000
2031 u32 A_int_err_selected_used[] = {
2032 0x0000019e,
2033 };
2034
2035 #define A_int_err_unexpected_phase 0x00000000
2036 u32 A_int_err_unexpected_phase_used[] = {
2037 0x00000084,
2038 0x0000008a,
2039 0x0000008e,
2040 0x00000092,
2041 0x000000c8,
2042 0x000000cc,
2043 0x000000ce,
2044 0x000000d0,
2045 0x0000010d,
2046 };
2047
2048 #define A_int_err_unexpected_reselect 0x00020000
2049 u32 A_int_err_unexpected_reselect_used[] = {
2050 0x0000017c,
2051 };
2052
2053 #define A_int_msg_1 0x01020000
2054 u32 A_int_msg_1_used[] = {
2055 0x000000e2,
2056 0x000000e4,
2057 };
2058
2059 #define A_int_msg_sdtr 0x01010000
2060 u32 A_int_msg_sdtr_used[] = {
2061 0x0000012d,
2062 };
2063
2064 #define A_int_msg_wdtr 0x01000000
2065 u32 A_int_msg_wdtr_used[] = {
2066 0x00000121,
2067 };
2068
2069 #define A_int_norm_aborted 0x02040000
2070 u32 A_int_norm_aborted_used[] = {
2071 0x000001f9,
2072 };
2073
2074 #define A_int_norm_command_complete 0x02020000
2075 u32 A_int_norm_command_complete_used[] = {
2076 };
2077
2078 #define A_int_norm_disconnected 0x02030000
2079 u32 A_int_norm_disconnected_used[] = {
2080 };
2081
2082 #define A_int_norm_reselect_complete 0x02010000
2083 u32 A_int_norm_reselect_complete_used[] = {
2084 };
2085
2086 #define A_int_norm_reset 0x02050000
2087 u32 A_int_norm_reset_used[] = {
2088 };
2089
2090 #define A_int_norm_select_complete 0x02000000
2091 u32 A_int_norm_select_complete_used[] = {
2092 };
2093
2094 #define A_int_test_1 0x04000000
2095 u32 A_int_test_1_used[] = {
2096 0x000001b9,
2097 };
2098
2099 #define A_int_test_2 0x04010000
2100 u32 A_int_test_2_used[] = {
2101 0x000001d1,
2102 };
2103
2104 #define A_int_test_3 0x04020000
2105 u32 A_int_test_3_used[] = {
2106 };
2107
2108 #define A_issue_dsa_head 0x00000000
2109 u32 A_issue_dsa_head_used[] = {
2110 0x0000004f,
2111 0x00000080,
2112 };
2113
2114 #define A_msg_buf 0x00000000
2115 u32 A_msg_buf_used[] = {
2116 0x000000d6,
2117 0x0000010f,
2118 0x00000119,
2119 0x0000011f,
2120 0x00000125,
2121 0x0000012b,
2122 };
2123
2124 #define A_reconnect_dsa_head 0x00000000
2125 u32 A_reconnect_dsa_head_used[] = {
2126 0x0000003f,
2127 0x00000047,
2128 0x00000162,
2129 0x00000169,
2130 };
2131
2132 #define A_reselected_identify 0x00000000
2133 u32 A_reselected_identify_used[] = {
2134 0x00000015,
2135 0x0000015b,
2136 };
2137
2138 #define A_reselected_tag 0x00000000
2139 u32 A_reselected_tag_used[] = {
2140 0x0000015e,
2141 };
2142
2143 #define A_test_dest 0x00000000
2144 u32 A_test_dest_used[] = {
2145 0x000001b7,
2146 };
2147
2148 #define A_test_src 0x00000000
2149 u32 A_test_src_used[] = {
2150 0x000001b6,
2151 };
2152
2153 #define Ent_accept_message 0x000004d8
2154 #define Ent_cmdout_cmdout 0x0000022c
2155 #define Ent_command_complete 0x00000508
2156 #define Ent_command_complete_msgin 0x00000518
2157 #define Ent_debug_break 0x00000748
2158 #define Ent_dsa_code_check_reselect 0x00000038
2159 #define Ent_dsa_code_template 0x00000000
2160 #define Ent_dsa_code_template_end 0x000000b4
2161 #define Ent_dsa_jump_resume 0x00000088
2162 #define Ent_dsa_schedule 0x000000b4
2163 #define Ent_dsa_zero 0x00000090
2164 #define Ent_initiator_abort 0x00000770
2165 #define Ent_msg_in 0x00000354
2166 #define Ent_other_transfer 0x0000031c
2167 #define Ent_reject_message 0x000004b8
2168 #define Ent_reselected_check_next 0x000005ac
2169 #define Ent_respond_message 0x00000000
2170 #define Ent_schedule 0x00000130
2171 #define Ent_select 0x00000194
2172 #define Ent_select_msgout 0x000001ac
2173 #define Ent_target_abort 0x00000750
2174 #define Ent_test_1 0x000006d4
2175 #define Ent_test_2 0x000006e8
2176 #define Ent_test_2_msgout 0x00000700
2177 u32 LABELPATCHES[] = {
2178 0x00000002,
2179 0x0000000b,
2180 0x0000000d,
2181 0x0000001d,
2182 0x0000001f,
2183 0x0000002c,
2184 0x0000002e,
2185 0x0000003b,
2186 0x00000042,
2187 0x00000054,
2188 0x00000058,
2189 0x0000005c,
2190 0x00000060,
2191 0x00000064,
2192 0x00000068,
2193 0x0000006a,
2194 0x0000006e,
2195 0x0000007b,
2196 0x00000082,
2197 0x00000086,
2198 0x00000088,
2199 0x00000090,
2200 0x00000094,
2201 0x00000096,
2202 0x00000098,
2203 0x0000009a,
2204 0x0000009c,
2205 0x000000a9,
2206 0x000000ae,
2207 0x000000b2,
2208 0x000000bf,
2209 0x000000c4,
2210 0x000000ca,
2211 0x000000d2,
2212 0x000000d4,
2213 0x000000d8,
2214 0x000000da,
2215 0x000000dc,
2216 0x000000de,
2217 0x000000e0,
2218 0x000000e6,
2219 0x000000e8,
2220 0x00000105,
2221 0x00000111,
2222 0x00000113,
2223 0x00000115,
2224 0x0000011b,
2225 0x00000127,
2226 0x00000153,
2227 0x00000159,
2228 0x00000167,
2229 0x0000016a,
2230 0x0000016e,
2231 0x00000172,
2232 0x00000176,
2233 0x0000017a,
2234 0x00000191,
2235 0x000001a2,
2236 0x000001a6,
2237 0x000001a8,
2238 0x000001ac,
2239 0x000001b0,
2240 0x000001b2,
2241 0x000001b4,
2242 0x000001bd,
2243 0x000001bf,
2244 0x000001db,
2245 0x000001df,
2246 0x000001e3,
2247 0x000001e7,
2248 0x000001eb,
2249 0x000001ef,
2250 };
2251
2252 struct {
2253 u32 offset;
2254 void *address;
2255 } EXTERNAL_PATCHES[] = {
2256 };
2257
2258 u32 INSTRUCTIONS = 260;
2259 u32 PATCHES = 72;
2260 u32 EXTERNAL_PATCHES_LEN = 0;