Annotation of kernel/bsd/dev/ppc/drvSymbios8xx/Sym8xxScript.ss, revision 1.1.1.1

1.1       root        1: 
                      2: ;   Copyright: 1997, 1998 by Apple Computer, Inc., all rights reserved.
                      3: ;
                      4: ;   File Ownership:
                      5: ;
                      6: ;       DRI:            Mike Johnson
                      7: ;
                      8: ;       Other Contact:  Russ Berkoff
                      9: ;
                     10: ;       Technology:     SCSI
                     11: ;
                     12: ;   Writers:
                     13: ;
                     14: ;       (MLJ)   Mike Johnson
                     15: ;       (RRA)   Rick Auricchio
                     16: 
                     17: 
                     18: ;       NCR Errata Listing 125 Item 1 : Clear the SCNTL0 start bit
                     19: ;       when jump to reselect during select (try_reselect)
                     20: ;
                     21: ;       NCR Errata Listing 117 Item 4 : Bad parity if odd bytes during
                     22: ;       wide transfer. Only for DATA OUT in Initiator mode.
                     23: ;       (Confirm by Manfred Eierle 3rd June 93 not during DATA IN)
                     24: 
                     25:     ARCH     825A                ;specifically for 825a and 875 (new instructions)
                     26: 
                     27: 
                     28:         ;*****************************************************************
                     29:         ;
                     30:         ;   Phase codes - These values represent which action is being handled
                     31:         ;
                     32:         ;*****************************************************************
                     33: 
                     34:     ABSOLUTE kphase_DATA_OUT                = 0x00
                     35:     ABSOLUTE kphase_DATA_IN                 = 0x01
                     36:     ABSOLUTE kphase_COMMAND                 = 0x02
                     37:     ABSOLUTE kphase_STATUS                  = 0x03
                     38:     ABSOLUTE kphase_MSG_OUT                 = 0x06
                     39:     ABSOLUTE kphase_MSG_IN                  = 0x07
                     40:     ABSOLUTE kphase_SELECT                  = 0x08
                     41:     ABSOLUTE kphase_RESELECT                = 0x09
                     42:     ABSOLUTE kphase_ABORT_CURRENT           = 0x0A
                     43:     ABSOLUTE kphase_ABORT_MAILBOX           = 0x0B
                     44:     ABSOLUTE kphase_CMD_COMPLETE            = 0x0C
                     45:     ABSOLUTE kphase_DISCONNECT              = 0x0D
                     46:     ABSOLUTE kphase_saveDataPointer         = 0x0E  ; ??? driver work to be done
                     47:     ABSOLUTE kphase_restoreDataPointer      = 0x0F  ; ??? driver work to be done
                     48: 
                     49: 
                     50:         ;*****************************************************************
                     51:         ;   interrupt codes
                     52:         ;*****************************************************************
                     53: 
                     54:     ABSOLUTE unknown_phase              = 0x00  ; A spurious phase on SCSI Bus
                     55:     ABSOLUTE status_error               = 0x01  ; IO completes, but with status error
                     56:     ABSOLUTE unexpected_msg             = 0x02  ; An 'unknown' message is in ld_message var
                     57:     ABSOLUTE unexpected_ext_msg         = 0x03  ; An 'unknown' extended message in ld_message
                     58:     ABSOLUTE wide_32_not_supported      = 0x04  ; The device wants 32 bits data phase
                     59:     ABSOLUTE no_msgin_after_reselect    = 0x05  ; No message-in after reselection
                     60:     ABSOLUTE reqack_too_large           = 0x06  ; The device answer ReqAck offset is greater than 8
                     61:     ABSOLUTE unknown_reselect           = 0x07  ; The valid bit in SFBR reg not set
                     62:     ABSOLUTE unallocated_nexus          = 0x08  ; nexus index -> 0xFFFFFFFF
                     63:     ABSOLUTE abort_mailbox              = 0x09  ; Abort/BDR mailbox completed
                     64:     ABSOLUTE abort_current              = 0x0A  ; Abort/BDR current op completed
                     65:     ABSOLUTE unknown_message_out        = 0x0B  ; Unknown phase before message out
                     66:     ABSOLUTE unknown_msg_reject         = 0x0C  ; Unknown message reject
                     67:     ABSOLUTE negotiateSDTR              = 0x0D  ; Sync negotiation rx'd
                     68:     ABSOLUTE negotiateWDTR              = 0x0E  ; Wide negotiation rx'd
                     69:     ABSOLUTE sglist_complete            = 0x0F  ; SGList complete
                     70: 
                     71: 
                     72:         ;*****************************************************************
                     73:         ;
                     74:         ; Data structure for T/L/Q Nexus:
                     75:         ;
                     76:         ;*****************************************************************
                     77: 
                     78:     ABSOLUTE TLQ_SCSI_ID    =  0    ;  4 SCSI ID et al for SELECT instruction
                     79:     ABSOLUTE TLQ_xferAdr    =  4    ;  4 Physical address of CHMOV instructions
                     80:     ABSOLUTE TLQ_MSGOp      =  8    ;  8 Byte count, data adr   -> TLQ_MSGO
                     81:     ABSOLUTE TLQ_CDBp       = 16    ;  8 Byte count, data adr   -> TLQ_CDB
                     82:     ABSOLUTE TLQ_CDP        = 24    ;  4 Current Data Pointer
                     83:     ABSOLUTE TLQ_SDP        = 28    ;  4 Saved   Data Pointer
                     84:     ABSOLUTE TLQ_index      = 32    ;  1 index into nexus array
                     85:     ABSOLUTE TLQ_xferStarted= 33    ;  1 transfer started flag
                     86:     ABSOLUTE TLQ_IWR        = 34    ;  1 flag to Ignore Wide Residue
                     87:     ABSOLUTE TLQ_pad        = 35    ;  1 pad byte
                     88: 
                     89: 
                     90:         ;*****************************************************************
                     91:         ;
                     92:         ; ENTRY declarations - Declare entry points for driver
                     93:         ;
                     94:         ;*****************************************************************
                     95: 
                     96:     ENTRY   select_phase
                     97:     ENTRY   phase_handler
                     98:     ENTRY   issueMessageOut         ; for negotiation and Reject messages
                     99:     ENTRY   issueAbort_BDR          ; to immediately Abort or Bus-Device-Reset
                    100:     ENTRY   clearACK                ; MsgIn done - clr ACK, jump to phase handler
                    101: 
                    102: 
                    103:         ;*****************************************************************
                    104:         ;
                    105:         ; Define local data structure at start of SCRIPTS.
                    106:         ; This structure is allocated by the following nops.
                    107:         ;
                    108:         ;*****************************************************************
                    109:         ;
                    110: 
                    111:     RELATIVE local_data     \
                    112:         ld_AbortCode                = 4{??}\    ; 1 byte code to Abort or BDR
                    113:         ld_zeroes                   = 4{??}\    ; 4 bytes of 0 to clear registers
                    114:         ld_status                   = 4{??}\    ; Status byte from target
                    115:         ld_counter                  = 4{??}\    ; index into mailbox array
                    116:            ld_AbortBdr_mailbox      = 4{??}\    ; Abort/BusDeviceReset mailbox
                    117:            ld_IOdone_mailbox        = 4{??}\    ; [ nexus 0 0 semaphore ]
                    118:            ld_sched_mlbx_base_adr   = 4{??}\    ; base addr of mailbox array
                    119:            ld_mailboxp              = 4{??}\    ; address of current mailbox
                    120:         ld_scsi_id                  = 4{??}\    ; ptr to current mailbox
                    121:         ld_nexus_array_base         = 4{??}\    ; base address of Nexus pointers
                    122:         ld_nexus_index              = 4{??}\    ; index to Nexus pointer
                    123:         ld_nexus                    = 4{??}\    ; address of Nexus
                    124:            ld_phase_flag            = 4{??}\    ; for debugging
                    125:            ld_device_table_base_adr = 4{??}\    ; device configuration table
                    126:            ld_scratch               = 4{??}\    ; scratch memory
                    127:            ld_unused                = 4{??}\    ; unused
                    128:         ld_message                  = 4{??}\    ; buffer for MsgIn bytes
                    129:         ld_message4                 = 4{??}\    ; buffer continuation
                    130:         ld_pad                      = 4{??}\    ; padding
                    131:         ld_size                     = 4{??}     ; size of this structure
                    132: 
                    133: 
                    134: PROC BSC_SCRIPT:
                    135: 
                    136:         ; *** These NOPs must be at address 0.                          ***
                    137:         ; *** This is reserved space for the structure "local_data".    ***
                    138:         ; *** The driver inits this area to zero.                       ***
                    139: 
                    140:     nop 0       ; ld_AbortCode,             ld_zeroes
                    141:     nop 0       ; ld_status,                ld_counter
                    142: 
                    143:     nop 0       ; ld_AbortBdr_mailbox,      ld_IOdone_mailbox
                    144:     nop 0       ; ld_sched_mlbx_base_adr,   ld_mailboxp
                    145: 
                    146:     nop 0       ; ld_scsi_id,               ld_nexus_array_base
                    147:     nop 0       ; ld_nexus_index,           ld_nexus
                    148: 
                    149:     nop 0       ; ld_phase_flag,            ld_device_table_base_adr
                    150:     nop 0       ; ld_scratch,               ld_unused
                    151: 
                    152:     nop 0       ; ld_message,               ld_message4
                    153:     nop ld_size ; ld_pad,                   ld_size     (Use ld_size or lose it)
                    154: 
                    155:     nop sglist_complete     ; use sglist_complete or lose it from gen'd output file
                    156: 
                    157:     ;****************************************************************************
                    158:     ;
                    159:     ; findNexusFromIndex - load DSA with pointer to Nexus given a Nexus index:
                    160:     ;
                    161:     ;****************************************************************************
                    162: 
                    163: findNexusFromIndex:
                    164: 
                    165:     load SCRATCHA0, 4, ld_nexus_index       ; load index and leading zeroes
                    166:     clear CARRY
                    167:     move SCRATCHA0 SHL 0 to SCRATCHA0       ; double the index
                    168:     move SCRATCHA1 SHL 0 to SCRATCHA1
                    169:     move SCRATCHA0 SHL 0 to SCRATCHA0       ; double again
                    170:     move SCRATCHA1 SHL 0 to SCRATCHA1       ; A0 now has index to 4-byte address
                    171:     store SCRATCHA0, 4, patchArrayOffset+4  ; *** patch the code
                    172:     
                    173:     load DSA0, 4, ld_nexus_array_base       ; load base address of array of Nexus pointers
                    174: patchArrayOffset:
                    175:     load DSA0, 4, DSAREL( 0 )               ; *** patched offset. Load pointer.
                    176: 
                    177:     move DSA0 to SFBR                       ; Ensure pointer is not 0xFFFFFFFF
                    178:     int unallocated_nexus, if 0xFF          ; Interrupt if NFG
                    179: 
                    180:     store DSA0, 4, ld_nexus                 ; Store the Nexus pointer
                    181:     return                                  ; end findNexusFromIndex
                    182: 
                    183: 
                    184:     ;****************************************************************************
                    185:     ;
                    186:     ; initContext - Initialize the registers for Sync and Wide using
                    187:     ;   values stored in the device configuration table.
                    188:     ;   Return with values in SCRATCHB for Select code.
                    189:     ;
                    190:     ;****************************************************************************
                    191: 
                    192: initContext:
                    193: 
                    194:     load SCRATCHB0, 4, ld_scsi_id                   ; load 4-bit SCSI ID and zeroes
                    195:     clear CARRY
                    196:     move SCRATCHB0 SHL SCRATCHB0                    ; * 2
                    197:     move SCRATCHB0 SHL SCRATCHB0                    ; * 2 -> UInt32 index
                    198:     store SCRATCHB0, 4, patchGetDevConfigOffset+4   ; *** Patch load  code
                    199: 
                    200:     load DSA0, 4, ld_device_table_base_adr          ; load base physical addr of tables
                    201: 
                    202: patchGetDevConfigOffset:
                    203:     load  SCRATCHB0, 4, DSAREL( 0 )                 ; *** Patched table offset ***
                    204: 
                    205:         ; SCRATCHB0 = 0
                    206:         ; SCRATCHB1 = TP,MO (SXFER bits7-5 bits3-0)
                    207:         ; SCRATCHB2 = 0 (position for SCSI ID)
                    208:         ; SCRATCHB3 = SCCF,EWS (SCNTL3 bits6-4 bit 3)
                    209: 
                    210:     move SCRATCHB1 to SFBR                          ; init SXFER from B1
                    211:     move SFBR to SXFER
                    212:                                                     ; Init SCNTL3 from B3
                    213:     move SCRATCHB3 to SFBR
                    214:     move SFBR to SCNTL3
                    215:     return                                          ; return with SCRATCHB intact.
                    216: 
                    217: 
                    218:     ;*****************************************************************
                    219:     ;
                    220:     ; Select_phase:
                    221:     ;       Clear the SIGP bit.
                    222:     ;       Check if any Abort/BusDeviceReset request waiting.
                    223:     ;       Nexus is found in the list of 256 mailboxes.
                    224:     ;       If current mailbox is empty, jump to reselect_phase.
                    225:     ;       SCRIPTS tries to select device.
                    226:     ;       If select fails due to reselect, jump to reselect_phase
                    227:     ;       Select Timeout handled by driver.
                    228:     ;       If select succeeds, clear the mailbox entry
                    229:     ;       and increment the mailbox counter.
                    230:     ;       Jump to the phase_handler (hopefully for MSG_OUT)
                    231:     ;
                    232:     ;*****************************************************************
                    233: 
                    234: select_phase:
                    235: 
                    236:     move CTEST2 | 0x00 to CTEST2           ; Clear SIGP bit from ISTAT reg
                    237: 
                    238:         ; Check abort mailbox:
                    239: 
                    240:     load SCRATCHA0, 4, ld_AbortBdr_mailbox ; Get AbortBdr mailbox
                    241:         ; The Identify byte in byte 0 is also the semaphore
                    242:         ; A0 = Identify byte (0xC0 + LUN  N.B. Disconnect allowed)
                    243:         ; A1 = Tag, if any
                    244:         ; A2 = SCSI ID
                    245:         ; A3 = Abort code   Abort=0x06; Abort Tag=0D; Bus Device Reset=0x0C
                    246:     move SCRATCHA0 to SFBR                  ; test the semaphore/Identify
                    247:     jump rel( AbortMailbox ), if not 0      ; jump if aborting
                    248: 
                    249: 
                    250:         ; Get the next IO nexus in the mailboxes circular list.
                    251:         ; Calculate current mailbox address as so:
                    252:         ;   counter byte index * 4  to get mailbox index
                    253:         ;   add base physical address of mailboxes giving current mailbox address
                    254: 
                    255:     load SCRATCHA0, 4, ld_counter           ; get 1-byte mailbox counter & 0s
                    256:     clear CARRY
                    257:     move SCRATCHA0 SHL 0 to SCRATCHA0       ; double it
                    258:     move SCRATCHA1 SHL 0 to SCRATCHA1
                    259:     move SCRATCHA0 SHL 0 to SCRATCHA0       ; double it again
                    260:     move SCRATCHA1 SHL 0 to SCRATCHA1       ; now have a UInt32 index
                    261:     store SCRATCHA0, 4, fetchMailbox+4      ; *** patch the load  DSA instruction
                    262:     store SCRATCHA0, 4, clear_mailbox+4     ; *** patch the store DSA instruction
                    263: 
                    264:     load DSA0, 4, ld_sched_mlbx_base_adr    ; load base physical address of mailboxes
                    265: 
                    266: fetchMailbox:
                    267:     load  DSA0, 4, DSAREL( 0 )              ; *** Patched offset. Load Nexus address
                    268:     store DSA0, 4, ld_nexus                 ; save pointer to current Nexus
                    269:     load SCRATCHA0, 4, ld_nexus             ; copy to A0
                    270: 
                    271:     move SCRATCHA0 to SFBR                  ; if non-zero, have implicit semaphore
                    272:     move SCRATCHA1 | SFBR to SFBR
                    273:     move SCRATCHA2 | SFBR to SFBR
                    274:     move SCRATCHA3 | SFBR to SFBR
                    275:     jump rel( reselect_phase ), if 0        ; go to reselect_phase if empty
                    276: 
                    277:         ;*****************************************************************
                    278:         ;
                    279:         ; Something in mailbox: we have work to do
                    280:         ;
                    281:         ;*****************************************************************
                    282: 
                    283:     move kphase_SELECT to SCRATCHB0             ; set phase indicator
                    284:     store SCRATCHB0, 1, ld_phase_flag
                    285: 
                    286:     load  SCRATCHB0, 4, ld_zeroes               ; clr the invalid-nexus-index flag
                    287:     load  SCRATCHB0, 1, DSAREL( TLQ_index )     ; get index byte from nexus
                    288:     store SCRATCHB0, 4, ld_nexus_index          ; save it in local data
                    289: 
                    290:     load DSA0, 4, ld_nexus                      ; restore DSA register
                    291:     load SCRATCHB2, 1, DSAREL( TLQ_SCSI_ID+2 )  ; get Target's SCSI ID
                    292:     move SCRATCHB2 to SFBR
                    293:     move SFBR to SCRATCHB0                      ; position it
                    294:     store SCRATCHB0, 1, ld_scsi_id              ; save it
                    295:     call rel( initContext )                     ; setup Sync/Wide regs in SCRATCHB
                    296:     load DSA0, 4, ld_nexus                      ; restore DSA register
                    297:     store SCRATCHB1, 1, DSAREL( TLQ_SCSI_ID+1 ) ; SXFER
                    298:     store SCRATCHB3, 1, DSAREL( TLQ_SCSI_ID+3 ) ; SCNTL3
                    299: 
                    300:         ;********************** select the device ********************************
                    301:     SELECT ATN from TLQ_SCSI_ID, rel( try_reselect )    ; ************************
                    302:         ;*************************************************************************
                    303: 
                    304:         ; looking good - clear the mailbox:
                    305: 
                    306:     load SCRATCHA0, 4, ld_zeroes            ; zero out scratch register A
                    307:     load DSA0, 4, ld_sched_mlbx_base_adr    ; load base physical address of mailboxes
                    308: clear_mailbox:
                    309:     store SCRATCHA0, 4, DSAREL( 0 )         ; *** Patched offset. Zero the mailbox
                    310: 
                    311:         ; Update the index to the mailbox circular list:
                    312:     load SCRATCHB0, 1, ld_counter           ; get counter (mailbox index)
                    313:     move SCRATCHB0 + 1 to SCRATCHB0         ; add 1
                    314:     store SCRATCHB0, 1, ld_counter  ; put it back
                    315: ;   *** FALL THROUGH TO phase_handler ***
                    316: 
                    317: 
                    318:     ;*****************************************************************
                    319:     ;
                    320:     ;   Phase_handler
                    321:     ;       The phase handler script is a dispatcher function of SCSI phase
                    322:     ;
                    323:     ;*****************************************************************
                    324: 
                    325: phase_handler:
                    326:     load DSA0, 4, ld_nexus                          ; reload DSA
                    327:     jump rel( command_phase ),        when CMD      ; wait for REQ
                    328:     jump rel( data_out_phase ),       if DATA_OUT   ; already latched REQ signal
                    329:     jump rel( message_out_phase ),    if MSG_OUT
                    330:     jump rel( data_in_phase ),        if DATA_IN
                    331:     jump rel( status_phase ),         if STATUS
                    332:     jump rel( message_in_phase ),     if MSG_IN
                    333:     int     unknown_phase
                    334: 
                    335: 
                    336:     ;*****************************************************************
                    337:     ;
                    338:     ; Message-Out phase
                    339:     ;
                    340:     ;*****************************************************************
                    341: 
                    342: message_out_phase:
                    343:     move kphase_MSG_OUT to SCRATCHB0                ; Set phase indicator
                    344:     store SCRATCHB0, 1, ld_phase_flag
                    345: 
                    346:     move from TLQ_MSGOp, when MSG_OUT               ; put out the message(s)
                    347:     jump rel( phase_handler )
                    348: 
                    349: 
                    350:         ; issueMessageOut - Driver entry point for Sync/Wide negotiation and
                    351:         ; to issue message Reject:
                    352: 
                    353: issueMessageOut:
                    354:     set     ATN                                     ; tell Target we have something to say
                    355:     clear   ACK
                    356:     jump rel( message_out_phase ),  when MSG_OUT    ; wait for REQ. Jump if msg-out phase.
                    357:     jump rel( phase_handler ),      if not MSG_IN   ; jump if weird phase
                    358:     move 1, ld_scratch+1,           when   MSG_IN   ; dump the msg byte
                    359:     clear ACK                                       ; accept Target's last msg-in byte
                    360:     jump rel( issueMessageOut )
                    361: 
                    362: 
                    363:     ;*****************************************************************
                    364:     ;
                    365:     ;   Command phase
                    366:     ;
                    367:     ;*****************************************************************
                    368: 
                    369: command_phase:
                    370:     move kphase_COMMAND to SCRATCHB0    ; Set phase indicator
                    371:     store SCRATCHB0, 1, ld_phase_flag
                    372: 
                    373:     clear ATN                           ; In case we missed the sending nego
                    374:     move FROM TLQ_CDBp, when CMD        ; issue the CDB
                    375:     jump rel( phase_handler )
                    376: 
                    377: 
                    378:     ;*****************************************************************
                    379:     ;
                    380:     ; Data_out_phase
                    381:     ;
                    382:     ;*****************************************************************
                    383: 
                    384: data_out_phase:
                    385:     move kphase_DATA_OUT to SCRATCHB0       ; Set phase indicator
                    386:     store SCRATCHB0, 1, ld_phase_flag
                    387: 
                    388:     call rel( driverXfer )                  ; call driver-built CHMOV instructions
                    389:     jump rel( phase_handler )               ; if all data xfer'd, get next phase
                    390: 
                    391: driverXfer:                                 ; get here from data-in code also
                    392:     load  SCRATCHA0, 4, DSAREL( TLQ_xferAdr )
                    393:     store SCRATCHA0, 4, doItPatch+4         ; *** patch the JUMP address
                    394:     move 0xFF to SCRATCHA1
                    395:     store SCRATCHA1, 1, DSAREL( TLQ_xferStarted )
                    396: 
                    397: doItPatch:
                    398:     jump 0x0333                             ; *** patched address
                    399: 
                    400: 
                    401: 
                    402:     ;*****************************************************************
                    403:     ;
                    404:     ; Data_in_phase
                    405:     ;   875 sets ATN if bad parity detected.
                    406:     ;   Use of CHMOV instructions assures that we properly handle
                    407:     ;   a leftover wide byte in the SWIDE or SODL register, depending
                    408:     ;   on the data direction. This can happen in either of two conditions:
                    409:     ;     1. The Target disconnects at an odd boundary. This is
                    410:     ;       extremely unlikely with disk devices.
                    411:     ;     2. The client passes either an odd buffer address or
                    412:     ;       an odd transfer count. When the Target disconnects (at
                    413:     ;       an even boundary, we end up with the extra wide
                    414:     ;       byte in SWIDE or SODL. MacOS does this with VM on.
                    415:     ;
                    416:     ;*****************************************************************
                    417: 
                    418: data_in_phase:
                    419:     move kphase_DATA_IN to SCRATCHB0        ; Set phase indicator
                    420:     store SCRATCHB0, 1, ld_phase_flag
                    421: 
                    422:     call rel( driverXfer )                  ; call driver-built CHMOV instructions
                    423: 
                    424:     ; The driver gets interrupted if a phase mismatch occurs as when
                    425:     ; the Target goes MSG-IN with a Disconnect.
                    426:     ; The driver codes either a RETURN if the Scatter/Gather list is complete or
                    427:     ; an INT if more Scatter/Gather elements need to be generated.
                    428:     ; On the Macintosh, client programs expect extra incoming data to be dumped.
                    429:     ; For example, during boot the ROM reads 512 bytes from a 2K-byte-sector CD.
                    430: 
                    431: bucket_loop:
                    432:     jump rel( phase_handler ), when not DATA_IN ; wait for phase, exit if changed
                    433:     CHMOV 1, ld_status, when DATA_IN            ; eat a byte
                    434:     jump rel( bucket_loop );                    ; keep dumping bytes
                    435: 
                    436: 
                    437:     ;*****************************************************************
                    438:     ;
                    439:     ; Status phase
                    440:     ;
                    441:     ;*****************************************************************
                    442: 
                    443: status_phase:
                    444:     move kphase_STATUS to SCRATCHB0             ; Set phase indicator
                    445:     store SCRATCHB0, 1, ld_phase_flag
                    446: 
                    447:     move 1, ld_status, when STATUS              ; Read Status byte from bus
                    448:     jump rel( phase_handler )
                    449: 
                    450: 
                    451:     ;*****************************************************************
                    452:     ;
                    453:     ; Message-In phase
                    454:     ;
                    455:     ;*****************************************************************
                    456: 
                    457: message_in_phase:
                    458:     move kphase_MSG_IN to SCRATCHB0             ; Set phase indicator
                    459:     store SCRATCHB0, 1, ld_phase_flag
                    460: 
                    461:     move 1, ld_message, when MSG_IN             ; Read byte from bus
                    462: 
                    463:     jump rel( cmdComplete ),        if 0x00     ; Command Complete
                    464:     jump rel( saveDataPointer ),    if 0x02     ; Save Data Pointer
                    465:     jump rel( disconnect_msg ),     if 0x04     ; Disconnect
                    466:     jump rel( ignoreWideResidue ),  if 0x23     ; Ignore Wide Residue
                    467:     jump rel( restoreDataPointer ), if 0x03     ; Restore Data Pointer
                    468:     jump rel( extended_msg ),       if 0x01     ; Extended message
                    469:     jump rel( msg_reject ),         if 0x07     ; Message Reject
                    470:         ; Identify,                 if 0x80-FF  ; Identify + LUN
                    471:         ; simple_queue_tag,         if 0x20     ; Simple Queue Tag
                    472:         ; initiate_recovery,        if 0x0F     ; Initiate Recovery
                    473:         ; linked_cde_complete,      if 0x0A/0x0B
                    474:     int unexpected_msg                          ; unknown
                    475: 
                    476: msg_reject:
                    477:     int  unknown_msg_reject
                    478: 
                    479: clearACK:                                       ; ENTRY point to end negotiation
                    480:     clear ACK
                    481:     jump rel( phase_handler )
                    482: 
                    483: 
                    484: 
                    485:     ;*****************************************************************
                    486:     ;
                    487:     ; Ignore Wide Residue
                    488:     ;
                    489:     ;*****************************************************************
                    490: 
                    491: ignoreWideResidue:      ; this is a two byte message so snag the 2nd byte here
                    492:     clear ACK
                    493:     move 1, ld_message+1, when MSG_IN       ; save residue count
                    494:     move SFBR to SCRATCHB2                  ; byte is still in SFBR. Position it.
                    495:     store SCRATCHB2, 1, DSAREL( TLQ_IWR )   ; Store residue count in Nexus for driver.
                    496:     clear ACK
                    497:     jump rel( phase_handler )
                    498: 
                    499: 
                    500:     ;*****************************************************************
                    501:     ;
                    502:     ; Extended message
                    503:     ;       Accept Wide and Synchronous Data Transfer messages
                    504:     ;
                    505:     ;*****************************************************************
                    506: 
                    507: extended_msg:
                    508:     clear ACK
                    509:     move 1, ld_message+1, when MSG_IN       ; read msg length byte from bus
                    510:     clear ACK
                    511:     move 1, ld_message+2, when MSG_IN       ; read ext msg code from bus
                    512:     clear ACK
                    513:         ; extended_identify,   IF 0x02
                    514:         ; modify_data_pointer, if 0x00
                    515:     jump rel( sdtr ),   if 0x01             ; jump if SDTR, sync negotiation msg
                    516:     jump rel( wdtr ),   if 0x03             ; jump if WDTR, wide negotiation msg
                    517:     int unexpected_ext_msg                  ; let driver deal with unknown
                    518: 
                    519: 
                    520:     ;*****************************************************************
                    521:     ;
                    522:     ; Command complete
                    523:     ;       The Command-Complete message is sent to indicate that the
                    524:     ;       IO operation has completed and valid status has been sent.
                    525:     ;       The Target should then disconnect.
                    526:     ;       SCRIPTS must spin until the IOdone mailbox is empty.
                    527:     ;       Then it sets the IOdone mailbox with the current Nexus.
                    528:     ;       The status message is analyzed.
                    529:     ;       If status is good, INTF the driver and jump to select_phase.
                    530:     ;       If status is NG, save it in the NEXUS and INT the driver.
                    531:     ;
                    532:     ;*****************************************************************
                    533: 
                    534: cmdComplete:
                    535:     move kphase_CMD_COMPLETE to SCRATCHB0       ; Set phase indicator
                    536:     store SCRATCHB0, 1, ld_phase_flag
                    537: 
                    538:     move SCNTL2 & 0X7F to SCNTL2                ; Clr SDU: SCSI Disconnect Unexpected
                    539:     clear ACK
                    540:     WAIT DISCONNECT
                    541: 
                    542: testMbxLp:                                      ; loop until IOdone mailbox empty
                    543:     load SCRATCHA0, 4, ld_IOdone_mailbox
                    544:     move SCRATCHA3 to SFBR                      ; A3 = semaphore
                    545:     jump rel( testMbxLp ), if not 0
                    546: 
                    547:         ; Fill in the IOdone mailbox with the following:
                    548:         ;   A0 = index to Nexus
                    549:         ;   A1 = Status
                    550:         ;   A2 = 0
                    551:         ;   A3 = semaphore (FF = set)
                    552:     load SCRATCHA0, 1, ld_nexus_index       ; A0 = index to Nexus
                    553:     load SCRATCHB0, 1, ld_status
                    554:     move SCRATCHB0 to SFBR
                    555:     move SFBR to SCRATCHA1                  ; A1 = Status
                    556:     move 0x00 to SCRATCHA2                  ; A2 = 0
                    557:     move 0xFF to SCRATCHA3                  ; A3 = semaphore IOdone mailbox
                    558:     store SCRATCHA0, 4, ld_IOdone_mailbox
                    559: 
                    560:     move SCRATCHA1 to SFBR                  ; Test the Status of this IO
                    561:         ; SFBR = status msg
                    562:         ; Test status - If good, Interrupt on the fly and jump to select phase
                    563:     intfly 0xFF, if 0 and mask 0xC1         ; mask off reserved bits
                    564:     jump rel( select_phase ), if 0 and mask 0xC1
                    565:     int     status_error                    ; Status err. Interrupt driver & stop
                    566: 
                    567: 
                    568:     ;*****************************************************************
                    569:     ;
                    570:     ; Disconnect
                    571:     ;       The 8xx Accepts the disconnection and jumps to the select_phase
                    572:     ;       to check for another IO
                    573:     ;
                    574:     ;*****************************************************************
                    575: 
                    576: disconnect_msg:
                    577:     load SCRATCHB0, 1, ld_phase_flag
                    578:     move SCRATCHB0 to SFBR
                    579:         ; If we got here from reselect just bailout since ld_nexus is
                    580:         ; not setup and the code using it is not needed anyway (no data xfer)
                    581:     jump rel( bailout ), if kphase_RESELECT
                    582: 
                    583:     move kphase_DISCONNECT to SCRATCHB0
                    584:     store SCRATCHB0, 1, ld_phase_flag
                    585: 
                    586: bailout:
                    587:     move 0xFF to SCRATCHB3                  ; invalidate nexus index for driver
                    588:     store SCRATCHB3, 1, ld_nexus_index+3
                    589:     move SCNTL2 & 0x7F to SCNTL2            ; Clr SDU: SCSI Disconnect Unexpected
                    590:     clear ACK
                    591:     WAIT DISCONNECT                         ; wait for bus-free
                    592:     jump rel( select_phase )                ; go see if more to do
                    593: 
                    594: 
                    595:     ;******************************************************************
                    596:     ;
                    597:     ; ??? mlj - saveDataPointer and restoreDataPointer are incorrect.
                    598:     ; ??? They basically do nothing.
                    599:     ; Save Data Pointer
                    600:     ;
                    601:     ;*****************************************************************
                    602: 
                    603: saveDataPointer:
                    604:     move kphase_saveDataPointer to SCRATCHB0
                    605:     store SCRATCHB0, 1, ld_phase_flag
                    606:     clear ACK
                    607:     jump rel( phase_handler )
                    608: 
                    609: 
                    610:     ;******************************************************************
                    611:     ;
                    612:     ; ??? mlj - saveDataPointer and restoreDataPointer are incorrect.
                    613:     ; ??? They basically do nothing.
                    614:     ; Restore Data Pointer
                    615:     ;       The local values still blocks, still bytes and data address
                    616:     ;       must be loaded from the corresponding NEXUS data set.
                    617:     ;       This message should followed an IDE (parity error)
                    618:     ;
                    619:     ;*****************************************************************
                    620: 
                    621: restoreDataPointer:
                    622:     move kphase_restoreDataPointer to SCRATCHB0
                    623:     store SCRATCHB0, 1, ld_phase_flag
                    624:     clear ACK
                    625:     jump rel( phase_handler )
                    626: 
                    627: 
                    628:     ;*****************************************************************
                    629:     ;
                    630:     ; Synchronous data transfer request or response
                    631:     ;
                    632:     ;*****************************************************************
                    633: sdtr:
                    634:     move 2, ld_message+3, when MSG_IN       ; Read period & offset from bus
                    635:     int negotiateSDTR
                    636: 
                    637: 
                    638:     ;***************************************************************************
                    639:     ;
                    640:     ; Wide Data Transfer request or response
                    641:     ;
                    642:     ;***************************************************************************
                    643: wdtr:
                    644:     move 1, ld_message+3, when MSG_IN       ; get Transfer Width Exponent fm bus
                    645:     int  negotiateWDTR
                    646: 
                    647: 
                    648:     ;*****************************************************************
                    649:     ;
                    650:     ; Reselect phase
                    651:     ;       The chip waits here either for a Reselection from a Target or
                    652:     ;       a SIGP from the driver indicating something in the mailbox.
                    653:     ;       If reselected, the script uses the Nexus value which is either
                    654:     ;       a Tag or a SCSI ID/LUN combo to lookup the Nexus.
                    655:     ;       Then init the SXFER and SCNTL3 registers from the device config table.
                    656:     ;
                    657:     ;*****************************************************************
                    658: 
                    659: try_reselect:                               ; Select failed - probably reselecting
                    660:                                             ; Cf NCR Errata Listing 117 Item 1:
                    661:     move SCNTL0 & 0xDF to SCNTL0            ; clr Start bit
                    662:     move CTEST2 | 0x00 to CTEST2            ; Clear SIGP bit from ISTAT reg
                    663: 
                    664: reselect_phase:
                    665:     move kphase_RESELECT to SCRATCHB0       ; Set phase indicator
                    666:     store SCRATCHB0, 1, ld_phase_flag
                    667: 
                    668:     move 0xFF to SCRATCHB3                  ; invalidate nexus index for driver
                    669:     store SCRATCHB3, 1, ld_nexus_index+3
                    670: 
                    671:         ; wait here for reselect from a Target
                    672:         ; or SIGP from the driver
                    673: 
                    674:     WAIT RESELECT REL( select_phase )       ; jump if SIGP
                    675: 
                    676:         ; Reselected:
                    677: 
                    678:     move SSID to SFBR                       ; SSID = [ Valxxx Scsi_id ]
                    679:     int unknown_reselect, if 0 and mask 0x7F; Interrupt if VAL bit not set
                    680:     move SFBR & 0x0F to SCRATCHB0           ; B0 = Target ID
                    681:     store SCRATCHB0, 1, ld_scsi_id          ; save it
                    682: 
                    683:     call rel( initContext )                 ; setup sync regs here
                    684: 
                    685:     int no_msgin_after_reselect, when not MSG_IN
                    686: 
                    687:     move 1, ld_message, when MSG_IN         ; Read Identify byte from bus
                    688: 
                    689:         ; if another REQ is asserted, a SimpleQueueTag message should be next
                    690: 
                    691:     clear ACK                               ; notify Target: msg byte rx'd
                    692:     jump rel( getNextMsg ), when MSG_IN     ; jump if SimpleQueueTag coming
                    693: 
                    694:         ; untagged operation:
                    695: 
                    696:     move SFBR & 0x07 to SCRATCHA0           ; isolate LUN from Identify byte
                    697: 
                    698:     load SCRATCHB0, 1, ld_scsi_id           ; B0 = Target ID
                    699:     clear CARRY
                    700:     move SCRATCHB0 SHL SFBR                 ; shift left #1
                    701:     move SFBR SHL SCRATCHB0                 ; shift left #2
                    702:     move SCRATCHB0 SHL SFBR                 ; shift left #3
                    703:     move SCRATCHA0 | SFBR to SCRATCHA0      ; form Nexus index = 0b0TTTTLLL
                    704: 
                    705:     store SCRATCHA0, 1, ld_nexus_index      ; store as index to Nexus
                    706:     jump rel( haveNexusIndex )
                    707: 
                    708:         ; should be tagged operation:
                    709: 
                    710: getNextMsg:
                    711:     move 1, ld_message,  when MSG_IN        ; read message byte from bus
                    712:     jump rel( disconnect_msg ), if 0x04     ; if Disconnect, oh well.
                    713:     clear ACK
                    714:     jump rel( phase_handler ), if not 0x20; Branch if not Queue tag code
                    715:         ; get the Queue Tag and save as the nexus index
                    716:     move 1, ld_nexus_index, when MSG_IN     ; Nexus index <- Tag from bus
                    717:     clear ACK                               ; acknowledge it
                    718: 
                    719: haveNexusIndex:
                    720:     move 0x00 to SCRATCHB3                  ; clear invalid-nexus-index flag
                    721:     store SCRATCHB3, 1, ld_nexus_index+3 
                    722:     call rel( findNexusFromIndex )          ; set DSA <- Nexus pointer
                    723:     jump rel( phase_handler )               ; start handling phases.
                    724: 
                    725: 
                    726:         ;*****************************************************************
                    727:         ;
                    728:         ; AbortMailbox - Abort (or BusDeviceReset) the mailbox entry.
                    729:         ; This is a queued operation - not an immediate
                    730:         ; operation as is issueAbort_BDR.
                    731:         ;   The Abort message clears all IO processes for the
                    732:         ;   selecting Initiator on the specified LUN.
                    733:         ;
                    734:         ;   The Bus Device Reset message clears all IO processes for
                    735:         ;   all Initiators on all LUNs of selected Target.
                    736:         ;   It forces a hard reset condition to the selected SCSI device.
                    737:         ;
                    738:         ;   A0 = Identify byte (0xC0 + LUN  N.B. Disconnect allowed)
                    739:         ;   A1 = Tag, if any
                    740:         ;   A2 = SCSI ID
                    741:         ;   A3 = Abort code Abort=0x06; Abort Tag=0D; Bus Device Reset=0x0C
                    742:         ;
                    743:         ;   Mailbox not cleared by SCRIPTS so that driver can find SCSI ID when done
                    744:         ;   N.B.: Device is Async and Narrow after BDR!!!
                    745:         ;   Driver must set the device config table values accordingly.
                    746:         ;*****************************************************************
                    747: 
                    748: AbortMailbox:
                    749:     move kphase_ABORT_MAILBOX to SCRATCHB0      ; Set phase code
                    750:     store SCRATCHB0, 1, ld_phase_flag
                    751:         
                    752:     move 0xFF to SCRATCHB3                      ; invalidate nexus index for driver
                    753:     store SCRATCHB3, 1, ld_nexus_index+3
                    754: 
                    755:     load  SCRATCHB0, 4, ld_zeroes               ; clear  Scratch B
                    756:     load  SCRATCHB2, 1, ld_AbortBdr_mailbox+2   ; get SCSI ID
                    757:     store SCRATCHB0, 4, AbortSelect+4           ; *** Patch the Select/ATN instruction
                    758: 
                    759: AbortSelect:
                    760:     SELECT ATN 0, REL( try_reselect )           ; *** Patched SCSI ID
                    761: 
                    762:     move SCRATCHA1 to SFBR                      ; check for Tag
                    763:     jump rel( taggedAbort ) if not 0x00         ; jump if tagged abort
                    764: 
                    765:         ; untagged Abort or BusDeviceReset:
                    766: 
                    767:     move SCRATCHA3 to SFBR                      ; position the abort code
                    768:     move SFBR to SCRATCHA1
                    769:     store SCRATCHA0, 2, ld_scratch              ; Store Identify and Abort msgs
                    770:     move 0x00 to SCNTL2                         ; Clr SDU SCSI Disconnect Unexpected
                    771:     move 2, ld_scratch , when MSG_OUT           ; emit Identify and Abort messages
                    772:     WAIT DISCONNECT
                    773:     int abort_mailbox
                    774: 
                    775:         ; AbortTag:
                    776: 
                    777: taggedAbort:
                    778:     move SCRATCHA1 to SFBR                      ; position the Tag
                    779:     move SFBR to SCRATCHA2
                    780:     move 0x20 to SCRATCHA1                      ; gen SimpleQueueTag code
                    781:     store SCRATCHA0, 4, ld_scratch              ; store Identify, SQT, Tag, AbortTag
                    782:     move 0x00 to SCNTL2                         ; Clr SDU SCSI Disconnect Unexpected
                    783:     move 4, ld_scratch, when MSG_OUT            ; emit all 4 bytes
                    784:     WAIT DISCONNECT
                    785:     int abort_mailbox
                    786: 
                    787: 
                    788:         ;*****************************************************************
                    789:         ;
                    790:         ; issueAbort_BDR - Abort (or BusDeviceReset) the current operation.
                    791:         ; This is an immediate operation - not a queued operation
                    792:         ; as is AbortMailbox.
                    793:         ;   The Abort message clears all IO processes for the
                    794:         ;   selecting Initiator on the specified LUN.
                    795:         ;
                    796:         ;   The Bus Device Reset message clears all IO processes for
                    797:         ;   all Initiators on all LUNs of selected Target.
                    798:         ;   It forces a hard reset condition to the selected SCSI device.
                    799:         ;
                    800:         ;*****************************************************************
                    801: 
                    802: issueAbort_BDR:
                    803:     move kphase_ABORT_CURRENT to SCRATCHB0      ; Set phase code
                    804:     store SCRATCHB0, 1, ld_phase_flag
                    805: 
                    806:     move ISTAT & 0x08 to SFBR                   ; see if Target connected to bus
                    807:     int abort_current, if 0                     ; interrupt driver if not connected
                    808: 
                    809:     SET ATN                                     ; get Target's attention
                    810:     load DSA0, 4, ld_nexus                      ; load pointer to Nexus
                    811: 
                    812: bucketLoop:
                    813:     clear ACK
                    814:     jump rel( sendAbortBDR ),   when MSG_OUT    ; wait for REQ. Jump if OK.
                    815: 
                    816:     jump rel( BucketInStatus ), if STATUS       ; bit bucket in
                    817:     jump rel( BucketInMsg ),    if MSG_IN       ; bit bucket in
                    818:     jump rel( BucketInData ),   if DATA_IN      ; bit bucket in
                    819: 
                    820:     move 0xAD to SCRATCHA0
                    821:     jump rel( BucketOutData ),  if DATA_OUT     ; bit bucket out
                    822:     jump rel( BucketOutCmd ),   if CMD          ; bit bucket out
                    823:     int unknown_phase                           ; back to driver for harsher measures
                    824: 
                    825: 
                    826: BucketInStatus:
                    827:     move 1, ld_scratch, when STATUS             ; eat the Status byte
                    828:     jump rel( bucketLoop );                     ; keep bit-bucketing bytes
                    829: 
                    830: BucketInMsg:
                    831:     move 1, ld_scratch, when MSG_IN             ; eat a message byte
                    832:     jump rel( bucketLoop );                     ; keep bit-bucketing bytes
                    833: 
                    834: BucketInData:
                    835:     move 1, ld_scratch, when DATA_IN            ; eat a data byte
                    836:     jump rel( bucketLoop );                     ; keep bit-bucketing bytes
                    837: 
                    838: BucketOutData:
                    839:     move SCRATCHA0 xor 0x73 to SCRATCHA0        ; gen 0xDEAD ...
                    840:     store SCRATCHA0, 1, ld_scratch
                    841:     move 1, ld_scratch, when DATA_OUT           ; pad a byte out
                    842:     jump rel( bucketLoop );                     ; keep bit-bucketing bytes
                    843: 
                    844: BucketOutCmd:
                    845:     move 0x00 to SCRATCHA0                      ; load Null, TestUnitReady, whatever
                    846:     store SCRATCHA0, 1, ld_scratch
                    847:     move 1, ld_scratch, when CMD                ; pad a byte out
                    848:     jump rel( bucketLoop );                     ; keep bit-bucketing bytes
                    849: 
                    850: 
                    851: sendAbortBDR:
                    852:     move 0x00 to SCNTL2                         ; Clr SDU SCSI Disconnect Unexpected
                    853:     move  1, ld_AbortCode, when MSG_OUT         ; Send Abort(06) or BDR(0C) message
                    854:     load  SCRATCHA0, 4, ld_zeroes               ; load 0's
                    855:     store SCRATCHA0, 4, ld_AbortCode            ; clear the Abort code
                    856:     WAIT DISCONNECT
                    857:     int abort_current                           ; went BusFree - tell Driver

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.