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