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