1 unsigned long 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,0x00000800, 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 weather 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 EXTERNAL NCR53c7xx_msg_abort ; Pointer to abort message 287 EXTERNAL NCR53c7xx_msg_reject ; Pointer to reject message 288 EXTERNAL NCR53c7xx_zero ; long with zero in it, use for source 289 EXTERNAL NCR53c7xx_sink ; 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,0x000007b8, 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,0x000007b8, 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,0x00000800, 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,0x00000694, 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,0x000007b8, 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 ; weather 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,0x000007b8, 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,0x000007b8, 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,((unsigned long)&NCR53c7xx_msg_reject), 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,((unsigned long)&NCR53c7xx_zero),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,0x00000800, 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 selected, IF NOT 0x40 1481 1482 at 0x000001a1 : */ 0x80040040,0x00000674, 1483 /* 1484 JUMP schedule 1485 1486 at 0x000001a3 : */ 0x80080000,0x00000130, 1487 /* 1488 1489 select_failed: 1490 MOVE ISTAT & 0x20 TO SFBR 1491 1492 at 0x000001a5 : */ 0x74142000,0x00000000, 1493 /* 1494 JUMP reselected, IF NOT 0x20 1495 1496 at 0x000001a7 : */ 0x80040020,0x00000568, 1497 /* 1498 MOVE ISTAT & 0xdf TO ISTAT 1499 1500 at 0x000001a9 : */ 0x7c14df00,0x00000000, 1501 /* 1502 JUMP schedule 1503 1504 at 0x000001ab : */ 0x80080000,0x00000130, 1505 /* 1506 1507 ; 1508 ; test_1 1509 ; test_2 1510 ; 1511 ; PURPOSE : run some verification tests on the NCR. test_1 1512 ; copies test_src to test_dest and interrupts the host 1513 ; processor, testing for cache coherency and interrupt 1514 ; problems in the processes. 1515 ; 1516 ; test_2 runs a command with offsets relative to the 1517 ; DSA on entry, and is useful for miscellaneous experimentation. 1518 ; 1519 1520 ; Verify that interrupts are working correctly and that we don't 1521 ; have a cache invalidation problem. 1522 1523 ABSOLUTE test_src = 0, test_dest = 0 1524 ENTRY test_1 1525 test_1: 1526 MOVE MEMORY 4, test_src, test_dest 1527 1528 at 0x000001ad : */ 0xc0000004,0x00000000,0x00000000, 1529 /* 1530 INT int_test_1 1531 1532 at 0x000001b0 : */ 0x98080000,0x04000000, 1533 /* 1534 1535 ; 1536 ; Run arbitrary commands, with test code establishing a DSA 1537 ; 1538 1539 ENTRY test_2 1540 test_2: 1541 CLEAR TARGET 1542 1543 at 0x000001b2 : */ 0x60000200,0x00000000, 1544 /* 1545 SELECT ATN FROM 0, test_2_fail 1546 1547 at 0x000001b4 : */ 0x43000000,0x00000720, 1548 /* 1549 JUMP test_2_msgout, WHEN MSG_OUT 1550 1551 at 0x000001b6 : */ 0x860b0000,0x000006e0, 1552 /* 1553 ENTRY test_2_msgout 1554 test_2_msgout: 1555 MOVE FROM 8, WHEN MSG_OUT 1556 1557 at 0x000001b8 : */ 0x1e000000,0x00000008, 1558 /* 1559 MOVE FROM 16, WHEN CMD 1560 1561 at 0x000001ba : */ 0x1a000000,0x00000010, 1562 /* 1563 MOVE FROM 24, WHEN DATA_IN 1564 1565 at 0x000001bc : */ 0x19000000,0x00000018, 1566 /* 1567 MOVE FROM 32, WHEN STATUS 1568 1569 at 0x000001be : */ 0x1b000000,0x00000020, 1570 /* 1571 MOVE FROM 40, WHEN MSG_IN 1572 1573 at 0x000001c0 : */ 0x1f000000,0x00000028, 1574 /* 1575 MOVE SCNTL2 & 0x7f TO SCNTL2 1576 1577 at 0x000001c2 : */ 0x7c027f00,0x00000000, 1578 /* 1579 CLEAR ACK 1580 1581 at 0x000001c4 : */ 0x60000040,0x00000000, 1582 /* 1583 WAIT DISCONNECT 1584 1585 at 0x000001c6 : */ 0x48000000,0x00000000, 1586 /* 1587 test_2_fail: 1588 INT int_test_2 1589 1590 at 0x000001c8 : */ 0x98080000,0x04010000, 1591 /* 1592 1593 ENTRY debug_break 1594 debug_break: 1595 INT int_debug_break 1596 1597 at 0x000001ca : */ 0x98080000,0x03000000, 1598 /* 1599 1600 ; 1601 ; initiator_abort 1602 ; target_abort 1603 ; 1604 ; PURPOSE : Abort the currently established nexus from with initiator 1605 ; or target mode. 1606 ; 1607 ; 1608 1609 ENTRY target_abort 1610 target_abort: 1611 SET TARGET 1612 1613 at 0x000001cc : */ 0x58000200,0x00000000, 1614 /* 1615 DISCONNECT 1616 1617 at 0x000001ce : */ 0x48000000,0x00000000, 1618 /* 1619 CLEAR TARGET 1620 1621 at 0x000001d0 : */ 0x60000200,0x00000000, 1622 /* 1623 JUMP schedule 1624 1625 at 0x000001d2 : */ 0x80080000,0x00000130, 1626 /* 1627 1628 ENTRY initiator_abort 1629 initiator_abort: 1630 SET ATN 1631 1632 at 0x000001d4 : */ 0x58000008,0x00000000, 1633 /* 1634 ; In order to abort the currently established nexus, we 1635 ; need to source/sink up to one byte of data in any SCSI phase, 1636 ; since the phase cannot change until REQ transitions 1637 ; false->true 1638 JUMP no_eat_cmd, WHEN NOT CMD 1639 1640 at 0x000001d6 : */ 0x82030000,0x00000768, 1641 /* 1642 MOVE 1, NCR53c7xx_zero, WHEN CMD 1643 1644 at 0x000001d8 : */ 0x0a000001,((unsigned long)&NCR53c7xx_zero), 1645 /* 1646 no_eat_cmd: 1647 JUMP no_eat_msg, WHEN NOT MSG_IN 1648 1649 at 0x000001da : */ 0x87030000,0x00000778, 1650 /* 1651 MOVE 1, NCR53c7xx_sink, WHEN MSG_IN 1652 1653 at 0x000001dc : */ 0x0f000001,((unsigned long)&NCR53c7xx_sink), 1654 /* 1655 no_eat_msg: 1656 JUMP no_eat_data, WHEN NOT DATA_IN 1657 1658 at 0x000001de : */ 0x81030000,0x00000788, 1659 /* 1660 MOVE 1, NCR53c7xx_sink, WHEN DATA_IN 1661 1662 at 0x000001e0 : */ 0x09000001,((unsigned long)&NCR53c7xx_sink), 1663 /* 1664 no_eat_data: 1665 JUMP no_eat_status, WHEN NOT STATUS 1666 1667 at 0x000001e2 : */ 0x83030000,0x00000798, 1668 /* 1669 MOVE 1, NCR53c7xx_sink, WHEN STATUS 1670 1671 at 0x000001e4 : */ 0x0b000001,((unsigned long)&NCR53c7xx_sink), 1672 /* 1673 no_eat_status: 1674 JUMP no_source_data, WHEN NOT DATA_OUT 1675 1676 at 0x000001e6 : */ 0x80030000,0x000007a8, 1677 /* 1678 MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT 1679 1680 at 0x000001e8 : */ 0x08000001,((unsigned long)&NCR53c7xx_zero), 1681 /* 1682 no_source_data: 1683 ; 1684 ; If DSP points here, and a phase mismatch is encountered, we need to 1685 ; do a bus reset. 1686 ; 1687 MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT 1688 1689 at 0x000001ea : */ 0x0e000001,((unsigned long)&NCR53c7xx_msg_abort), 1690 /* 1691 INT int_norm_aborted 1692 1693 at 0x000001ec : */ 0x98080000,0x02040000, 1694 /* 1695 1696 ; 1697 ; dsa_to_scratch 1698 ; scratch_to_dsa 1699 ; 1700 ; PURPOSE : 1701 ; The NCR chips cannot do a move memory instruction with the DSA register 1702 ; as the source or destination. So, we provide a couple of subroutines 1703 ; that let us switch between the DSA register and scratch register. 1704 ; 1705 ; Memory moves to/from the DSPS register also don't work, but we 1706 ; don't use them. 1707 ; 1708 ; 1709 1710 1711 dsa_to_scratch: 1712 MOVE DSA0 TO SFBR 1713 1714 at 0x000001ee : */ 0x72100000,0x00000000, 1715 /* 1716 MOVE SFBR TO SCRATCH0 1717 1718 at 0x000001f0 : */ 0x6a340000,0x00000000, 1719 /* 1720 MOVE DSA1 TO SFBR 1721 1722 at 0x000001f2 : */ 0x72110000,0x00000000, 1723 /* 1724 MOVE SFBR TO SCRATCH1 1725 1726 at 0x000001f4 : */ 0x6a350000,0x00000000, 1727 /* 1728 MOVE DSA2 TO SFBR 1729 1730 at 0x000001f6 : */ 0x72120000,0x00000000, 1731 /* 1732 MOVE SFBR TO SCRATCH2 1733 1734 at 0x000001f8 : */ 0x6a360000,0x00000000, 1735 /* 1736 MOVE DSA3 TO SFBR 1737 1738 at 0x000001fa : */ 0x72130000,0x00000000, 1739 /* 1740 MOVE SFBR TO SCRATCH3 1741 1742 at 0x000001fc : */ 0x6a370000,0x00000000, 1743 /* 1744 RETURN 1745 1746 at 0x000001fe : */ 0x90080000,0x00000000, 1747 /* 1748 1749 scratch_to_dsa: 1750 MOVE SCRATCH0 TO SFBR 1751 1752 at 0x00000200 : */ 0x72340000,0x00000000, 1753 /* 1754 MOVE SFBR TO DSA0 1755 1756 at 0x00000202 : */ 0x6a100000,0x00000000, 1757 /* 1758 MOVE SCRATCH1 TO SFBR 1759 1760 at 0x00000204 : */ 0x72350000,0x00000000, 1761 /* 1762 MOVE SFBR TO DSA1 1763 1764 at 0x00000206 : */ 0x6a110000,0x00000000, 1765 /* 1766 MOVE SCRATCH2 TO SFBR 1767 1768 at 0x00000208 : */ 0x72360000,0x00000000, 1769 /* 1770 MOVE SFBR TO DSA2 1771 1772 at 0x0000020a : */ 0x6a120000,0x00000000, 1773 /* 1774 MOVE SCRATCH3 TO SFBR 1775 1776 at 0x0000020c : */ 0x72370000,0x00000000, 1777 /* 1778 MOVE SFBR TO DSA3 1779 1780 at 0x0000020e : */ 0x6a130000,0x00000000, 1781 /* 1782 RETURN 1783 1784 at 0x00000210 : */ 0x90080000,0x00000000, 1785 }; 1786 1787 #define A_addr_scratch 0x00000000 1788 unsigned long A_addr_scratch_used[] = { 1789 0x00000007, 1790 0x0000003a, 1791 0x00000046, 1792 0x00000050, 1793 0x0000007a, 1794 0x000000a8, 1795 0x000000be, 1796 0x00000104, 1797 0x00000163, 1798 0x00000190, 1799 }; 1800 1801 #define A_addr_sfbr 0x00000000 1802 unsigned long A_addr_sfbr_used[] = { 1803 0x00000016, 1804 }; 1805 1806 #define A_addr_temp 0x00000000 1807 unsigned long A_addr_temp_used[] = { 1808 0x00000027, 1809 }; 1810 1811 #define A_dmode_memory_to_memory 0x00000000 1812 unsigned long A_dmode_memory_to_memory_used[] = { 1813 0x00000008, 1814 0x00000019, 1815 0x00000029, 1816 0x0000003c, 1817 0x00000048, 1818 0x00000051, 1819 0x0000007c, 1820 0x000000aa, 1821 0x000000c0, 1822 0x00000106, 1823 0x00000164, 1824 0x00000192, 1825 }; 1826 1827 #define A_dmode_memory_to_ncr 0x00000000 1828 unsigned long A_dmode_memory_to_ncr_used[] = { 1829 0x00000003, 1830 0x00000012, 1831 0x0000004c, 1832 0x0000015f, 1833 }; 1834 1835 #define A_dmode_ncr_to_memory 0x00000000 1836 unsigned long A_dmode_ncr_to_memory_used[] = { 1837 0x00000024, 1838 0x00000037, 1839 0x00000043, 1840 0x00000077, 1841 0x000000a5, 1842 0x000000bb, 1843 0x00000101, 1844 0x0000018d, 1845 }; 1846 1847 #define A_dmode_ncr_to_ncr 0x00000000 1848 unsigned long A_dmode_ncr_to_ncr_used[] = { 1849 }; 1850 1851 #define A_dsa_check_reselect 0x00000000 1852 unsigned long A_dsa_check_reselect_used[] = { 1853 0x0000017f, 1854 }; 1855 1856 #define A_dsa_cmdout 0x00000048 1857 unsigned long A_dsa_cmdout_used[] = { 1858 0x0000008c, 1859 }; 1860 1861 #define A_dsa_cmnd 0x00000038 1862 unsigned long A_dsa_cmnd_used[] = { 1863 }; 1864 1865 #define A_dsa_datain 0x00000054 1866 unsigned long A_dsa_datain_used[] = { 1867 0x000000b3, 1868 }; 1869 1870 #define A_dsa_dataout 0x00000050 1871 unsigned long A_dsa_dataout_used[] = { 1872 0x0000009d, 1873 }; 1874 1875 #define A_dsa_end 0x00000070 1876 unsigned long A_dsa_end_used[] = { 1877 }; 1878 1879 #define A_dsa_fields_start 0x00000024 1880 unsigned long A_dsa_fields_start_used[] = { 1881 }; 1882 1883 #define A_dsa_msgin 0x00000058 1884 unsigned long A_dsa_msgin_used[] = { 1885 0x00000147, 1886 }; 1887 1888 #define A_dsa_msgout 0x00000040 1889 unsigned long A_dsa_msgout_used[] = { 1890 0x0000006c, 1891 }; 1892 1893 #define A_dsa_msgout_other 0x00000068 1894 unsigned long A_dsa_msgout_other_used[] = { 1895 0x0000013f, 1896 }; 1897 1898 #define A_dsa_next 0x00000030 1899 unsigned long A_dsa_next_used[] = { 1900 0x0000002f, 1901 0x0000006f, 1902 }; 1903 1904 #define A_dsa_select 0x0000003c 1905 unsigned long A_dsa_select_used[] = { 1906 0x00000067, 1907 }; 1908 1909 #define A_dsa_status 0x00000060 1910 unsigned long A_dsa_status_used[] = { 1911 0x00000143, 1912 }; 1913 1914 #define A_dsa_temp_dsa_next 0x00000000 1915 unsigned long A_dsa_temp_dsa_next_used[] = { 1916 0x00000001, 1917 0x00000006, 1918 0x0000001c, 1919 }; 1920 1921 #define A_dsa_temp_jump_resume 0x00000000 1922 unsigned long A_dsa_temp_jump_resume_used[] = { 1923 0x00000028, 1924 }; 1925 1926 #define A_dsa_temp_lun 0x00000000 1927 unsigned long A_dsa_temp_lun_used[] = { 1928 0x00000017, 1929 }; 1930 1931 #define A_dsa_temp_sync 0x00000000 1932 unsigned long A_dsa_temp_sync_used[] = { 1933 0x00000021, 1934 }; 1935 1936 #define A_dsa_temp_target 0x00000000 1937 unsigned long A_dsa_temp_target_used[] = { 1938 0x00000010, 1939 }; 1940 1941 #define A_int_debug_break 0x03000000 1942 unsigned long A_int_debug_break_used[] = { 1943 0x000001cb, 1944 }; 1945 1946 #define A_int_debug_dsa_loaded 0x03030000 1947 unsigned long A_int_debug_dsa_loaded_used[] = { 1948 }; 1949 1950 #define A_int_debug_head 0x03050000 1951 unsigned long A_int_debug_head_used[] = { 1952 }; 1953 1954 #define A_int_debug_idle 0x03020000 1955 unsigned long A_int_debug_idle_used[] = { 1956 }; 1957 1958 #define A_int_debug_reselected 0x03040000 1959 unsigned long A_int_debug_reselected_used[] = { 1960 }; 1961 1962 #define A_int_debug_scheduled 0x03010000 1963 unsigned long A_int_debug_scheduled_used[] = { 1964 }; 1965 1966 #define A_int_err_check_condition 0x00030000 1967 unsigned long A_int_err_check_condition_used[] = { 1968 0x00000157, 1969 }; 1970 1971 #define A_int_err_no_phase 0x00040000 1972 unsigned long A_int_err_no_phase_used[] = { 1973 }; 1974 1975 #define A_int_err_selected 0x00010000 1976 unsigned long A_int_err_selected_used[] = { 1977 0x0000019e, 1978 }; 1979 1980 #define A_int_err_unexpected_phase 0x00000000 1981 unsigned long A_int_err_unexpected_phase_used[] = { 1982 0x00000084, 1983 0x0000008a, 1984 0x0000008e, 1985 0x00000092, 1986 0x000000c8, 1987 0x000000cc, 1988 0x000000ce, 1989 0x000000d0, 1990 0x0000010d, 1991 }; 1992 1993 #define A_int_err_unexpected_reselect 0x00020000 1994 unsigned long A_int_err_unexpected_reselect_used[] = { 1995 0x0000017c, 1996 }; 1997 1998 #define A_int_msg_1 0x01020000 1999 unsigned long A_int_msg_1_used[] = { 2000 0x000000e2, 2001 0x000000e4, 2002 }; 2003 2004 #define A_int_msg_sdtr 0x01010000 2005 unsigned long A_int_msg_sdtr_used[] = { 2006 0x0000012d, 2007 }; 2008 2009 #define A_int_msg_wdtr 0x01000000 2010 unsigned long A_int_msg_wdtr_used[] = { 2011 0x00000121, 2012 }; 2013 2014 #define A_int_norm_aborted 0x02040000 2015 unsigned long A_int_norm_aborted_used[] = { 2016 0x000001ed, 2017 }; 2018 2019 #define A_int_norm_command_complete 0x02020000 2020 unsigned long A_int_norm_command_complete_used[] = { 2021 }; 2022 2023 #define A_int_norm_disconnected 0x02030000 2024 unsigned long A_int_norm_disconnected_used[] = { 2025 }; 2026 2027 #define A_int_norm_reselect_complete 0x02010000 2028 unsigned long A_int_norm_reselect_complete_used[] = { 2029 }; 2030 2031 #define A_int_norm_reset 0x02050000 2032 unsigned long A_int_norm_reset_used[] = { 2033 }; 2034 2035 #define A_int_norm_select_complete 0x02000000 2036 unsigned long A_int_norm_select_complete_used[] = { 2037 }; 2038 2039 #define A_int_test_1 0x04000000 2040 unsigned long A_int_test_1_used[] = { 2041 0x000001b1, 2042 }; 2043 2044 #define A_int_test_2 0x04010000 2045 unsigned long A_int_test_2_used[] = { 2046 0x000001c9, 2047 }; 2048 2049 #define A_int_test_3 0x04020000 2050 unsigned long A_int_test_3_used[] = { 2051 }; 2052 2053 #define A_issue_dsa_head 0x00000000 2054 unsigned long A_issue_dsa_head_used[] = { 2055 0x0000004f, 2056 0x00000080, 2057 }; 2058 2059 #define A_msg_buf 0x00000000 2060 unsigned long A_msg_buf_used[] = { 2061 0x000000d6, 2062 0x0000010f, 2063 0x00000119, 2064 0x0000011f, 2065 0x00000125, 2066 0x0000012b, 2067 }; 2068 2069 #define A_reconnect_dsa_head 0x00000000 2070 unsigned long A_reconnect_dsa_head_used[] = { 2071 0x0000003f, 2072 0x00000047, 2073 0x00000162, 2074 0x00000169, 2075 }; 2076 2077 #define A_reselected_identify 0x00000000 2078 unsigned long A_reselected_identify_used[] = { 2079 0x00000015, 2080 0x0000015b, 2081 }; 2082 2083 #define A_reselected_tag 0x00000000 2084 unsigned long A_reselected_tag_used[] = { 2085 0x0000015e, 2086 }; 2087 2088 #define A_test_dest 0x00000000 2089 unsigned long A_test_dest_used[] = { 2090 0x000001af, 2091 }; 2092 2093 #define A_test_src 0x00000000 2094 unsigned long A_test_src_used[] = { 2095 0x000001ae, 2096 }; 2097 2098 #define Ent_accept_message 0x000004d8 2099 #define Ent_cmdout_cmdout 0x0000022c 2100 #define Ent_command_complete 0x00000508 2101 #define Ent_command_complete_msgin 0x00000518 2102 #define Ent_debug_break 0x00000728 2103 #define Ent_dsa_code_check_reselect 0x00000038 2104 #define Ent_dsa_code_template 0x00000000 2105 #define Ent_dsa_code_template_end 0x000000b4 2106 #define Ent_dsa_jump_resume 0x00000088 2107 #define Ent_dsa_schedule 0x000000b4 2108 #define Ent_dsa_zero 0x00000090 2109 #define Ent_initiator_abort 0x00000750 2110 #define Ent_msg_in 0x00000354 2111 #define Ent_other_transfer 0x0000031c 2112 #define Ent_reject_message 0x000004b8 2113 #define Ent_reselected_check_next 0x000005ac 2114 #define Ent_respond_message 0x00000000 2115 #define Ent_schedule 0x00000130 2116 #define Ent_select 0x00000194 2117 #define Ent_select_msgout 0x000001ac 2118 #define Ent_target_abort 0x00000730 2119 #define Ent_test_1 0x000006b4 2120 #define Ent_test_2 0x000006c8 2121 #define Ent_test_2_msgout 0x000006e0 2122 unsigned long LABELPATCHES[] = { 2123 0x00000002, 2124 0x0000000b, 2125 0x0000000d, 2126 0x0000001d, 2127 0x0000001f, 2128 0x0000002c, 2129 0x0000002e, 2130 0x0000003b, 2131 0x00000042, 2132 0x00000054, 2133 0x00000058, 2134 0x0000005c, 2135 0x00000060, 2136 0x00000064, 2137 0x00000068, 2138 0x0000006a, 2139 0x0000006e, 2140 0x0000007b, 2141 0x00000082, 2142 0x00000086, 2143 0x00000088, 2144 0x00000090, 2145 0x00000094, 2146 0x00000096, 2147 0x00000098, 2148 0x0000009a, 2149 0x0000009c, 2150 0x000000a9, 2151 0x000000ae, 2152 0x000000b2, 2153 0x000000bf, 2154 0x000000c4, 2155 0x000000ca, 2156 0x000000d2, 2157 0x000000d4, 2158 0x000000d8, 2159 0x000000da, 2160 0x000000dc, 2161 0x000000de, 2162 0x000000e0, 2163 0x000000e6, 2164 0x000000e8, 2165 0x00000105, 2166 0x00000111, 2167 0x00000113, 2168 0x00000115, 2169 0x0000011b, 2170 0x00000127, 2171 0x00000153, 2172 0x00000159, 2173 0x00000167, 2174 0x0000016a, 2175 0x0000016e, 2176 0x00000172, 2177 0x00000176, 2178 0x0000017a, 2179 0x00000191, 2180 0x000001a2, 2181 0x000001a4, 2182 0x000001a8, 2183 0x000001ac, 2184 0x000001b5, 2185 0x000001b7, 2186 0x000001d3, 2187 0x000001d7, 2188 0x000001db, 2189 0x000001df, 2190 0x000001e3, 2191 0x000001e7, 2192 }; 2193 2194 unsigned long INSTRUCTIONS = 0x000000fe; 2195 unsigned long PATCHES = 0x00000045;