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