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