; ; File: HALc96Init.a ; ; Contains: initialization routines ; ; Written by: Paul Wolf ; ; Copyright: © 1992-1994 by Apple Computer, Inc., All rights reserved. ; ; Change History (most recent first): ; ; 1/25/94 DCB Initialize our null deferred task which we use to make sure that ; jDisptch gets called in order to run our own DT Manager ; 12/19/93 DCB Clear our deferred task flags field before using it. ; 11/22/93 pdw Rolling in from . ; 11/8/93 pdw Fixed the bug that Craig reported but I didn't understand until ; now. ; 10/29/93 pdw Added initialization of dmaAlignMask from dmaAlignmentSize. ; 11/19/93 chp Beautify some conditional code that sometimes needs to branch ; around TNT code. ; 11/17/93 KW changed forSTP601 to forSTP601v1 ; 9/29/93 chp Add Grand Central DMA sub-transfer routine initialization. ; 11/9/93 KW for the CygnusX1 ROM, use SlowRead96 instead of FastRead_96_BIOS ; until we get our new BTU chip ; 10/29/93 DCB Initializing our Deferred Task queue element which is used in ; the pseudo-DMA data transfer routines to lower the interrupt ; level. ; 10/28/93 pdw Rearranged some vectors, fixed up the forPDMProto stuff again. ; 10/14/93 pdw roll-in. ; 10/12/93 pdw Changed a .s to a .w to fix another build problem. ; 10/12/93 pdw Added support for Synchronous data transfers, rewrote State ; Machine, message handling etc. ; 10/6/93 pdw Fixed forPDMProto stuff. ; 10/4/93 RC Put forPDMProto around AMIC3/2 special code ; 9/17/93 pdw Removed exception for Cold Fusion in PRAM check for disabling ; DMA read. ; 9/12/93 pdw Got rid of vector for HALtransfer since the routine is gone. ; 9/9/93 pdw Lots of little changes. Name changes, temporary cache_bug ; stuff. ; 7/20/93 pdw Changed DMA-disabling/enabling PRAM interpretation. Now it ; defaults to (in zero case) the fastest, safe means. For EVT3s ; this means DMA for all others (including Cold Fusion), this ; means pseudo-DMA. ; 7/17/93 pdw Lots of little things. ; 7/8/93 pdw Replaced slow DMA routines with SlowRead96 until I fix the ; residual length problems with the DMA routines. ; 6/29/93 pdw Massive checkins: Change asynchronicity mechanism to CallMachine ; stack switching mechanism. Adding support for Cold Fusion. ; Rearranging HW/SW Init code. Some code optimizations. ; 5/25/93 DCB Rollin from Ludwig. (The next item below) ; 5/21/93 PW Adding PRAM selectable Initiator ID stuff. ; 5/5/93 PW Converted names to meanies-friendly names. Updated with latest ; from Ludwig stuff. ; 4/8/93 DCB Added Initialization code for Wombat class machines. ; 5/1/93 PW Put IF RECORD_ON around the initial RecordEvent call. ; 4/30/93 DCB Getting rid of Info HalAction vector. It is getting its own ; entry point into the HAL to prevent deadlocks. ; 4/30/93 PW Added some extra fields in jump table for future use. ; 4/14/93 DCB Added jump table vector for SetParity ; 3/29/93 PW Added PDM test code to turn on real DMA reads and/or real DMA ; writes if certain PRAM bits are set. ; 3/26/93 PW Added code to initialize new DMA vectors. ; 3/23/93 DCB Removed a reference to the old SCSI Globals which aren't ; supported anymore. ; 3/23/93 PW Removing RejectMsg stuff. ; 3/20/93 PW Unknown changes. ; 2/17/93 PW For PDM: replaces Fast with Slow routines since they have ; trouble with DREQ. ; 1/31/93 PW Update from the latest of Ludwig. Also changes required for PDM ; (will update Ludwig with these as needed myself). ; 1/27/93 PW Added dispatch tables for InitDataPointer and DoData routines. ; 10/30/92 DCB Added Setup and Teardown routines to support Direct DMA into a ; user buffer ; 10/8/92 PW Got rid of unused third Read and Write transfer routine vectors. ; 8/30/92 PW Added kAssertATN to dispatch list. ; 8/20/92 DCB Fixed SCSI Bus Reset ; 7/27/92 PW Virtually initial check-in. ; ;========================================================================== BLANKS ON ; assembler accepts spaces & tabs in operand field PRINT OFF ; do not send subsequent lines to the listing file ; don't print includes CACHEBUG EQU 0 ;₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯₯ LOAD 'StandardEqu.d' INCLUDE 'HardwarePrivateEqu.a' INCLUDE 'UniversalEqu.a' ; for TestFor INCLUDE 'DeferredTaskEqu.a' INCLUDE 'Debug.a' ; for NAME macro INCLUDE 'SCSI.a' INCLUDE 'SCSIEqu53c96.a' INCLUDE 'HALc96equ.a' INCLUDE 'ACAM.a' INCLUDE 'XPTEqu.a' PRINT ON ; do send subsequent lines to the listing files CASE OBJECT HALc96Init PROC EXPORT ; EXPORT Initc96Asm ; From SCSIMgr96.a --- IMPORT CyclePhase ; IMPORT DoSCSIMsgIn ; From SCSIMgrHW96.a --- IMPORT BusErrHandler96, Install_ISR IMPORT DoInitiate IMPORT DoBitBucket IMPORT DoDataIn IMPORT DoDataOut IMPORT DoAcceptMsg IMPORT DoMsgOut IMPORT DoStatus IMPORT DoComplete IMPORT DoSaveDataPointer IMPORT DoModifyDataPointer IMPORT DoRestorePointers IMPORT GetReconnectInfo IMPORT GetSelectInfo IMPORT DoSelect IMPORT DoCommand IMPORT DoHalInfo IMPORT DoReset IMPORT DoAssertATN IMPORT SlowRead96 IMPORT SlowWrite96 IMPORT FastRead96 IMPORT FastWrite96 IMPORT TeardownIO ; DCB IMPORT SetParity ; DCB IMPORT InitDataTIB IMPORT InitDataBuffer IMPORT InitDataSG IMPORT DoDataTIB IMPORT DoDataBuffer IMPORT DoDataSG IMPORT StartPSC, StopPSCRead, StopPSCWrite, Wt4PSCComplete IMPORT StartAMIC, StopAMICRead, StopAMICWrite, Wt4AMICComplete IMPORT StartGC, StopGCRead, StopGCWrite, Wt4GCComplete IMPORT FastRead_96_BIOS,FastWrite_96_BIOS IMPORT DataIn_DMA, DataIn_DMA1x1, DataOut_DMA IMPORT SetupIOPSC, TeardownIOPSC IMPORT SetupIOAMIC, TeardownIOAMIC IMPORT SetupIOGC, TeardownIOGC IMPORT SetupIONoDMA, TeardownIONoDMA IMPORT AutoMsgIn, HandleSelected IMPORT Wt4SelectComplete IMPORT HandleBusInt IMPORT RecordEvent IMPORT DataDTask,ci_jDisptch_Vers,ci_jDisptch IMPORT oldjDisptch WITH HALc96GlobalRecord ;------------------------------------------------------------- ; Macro DispatchVector &ROMAddress IF forC96Init OR forROM THEN ; dc.l &ROMAddress-Initc96Asm ELSE dcImportResident &ROMAddress ENDIF EndM OffsetTbl96 ;ΡΡΡ Externals (Entry points) DispatchVector DoInitiate DispatchVector DoBitBucket DispatchVector DoDataIn DispatchVector DoDataOut DispatchVector DoAcceptMsg DispatchVector unusedVector DispatchVector unusedVector DispatchVector DoMsgOut DispatchVector DoStatus DispatchVector DoComplete DispatchVector DoSaveDataPointer DispatchVector DoModifyDataPointer DispatchVector DoRestorePointers DispatchVector GetReconnectInfo DispatchVector GetSelectInfo DispatchVector DoSelect DispatchVector unusedVector DispatchVector DoCommand DispatchVector SetParity ; DCB DispatchVector HandleSelected DispatchVector SetupIONoDMA DispatchVector DoReset DispatchVector DoAssertATN ; pdw DispatchVector TeardownIONoDMA DispatchVector unusedVector ; unused for now DispatchVector unusedVector ; unused for now DispatchVector unusedVector ; unused for now DispatchVector unusedVector ; unused for now DispatchVector unusedVector ; unused for now DispatchVector unusedVector ; unused for now DispatchVector unusedVector ; unused for now DispatchVector unusedVector ; unused for now ;ΡΡΡ Internals (Non-entry points) ; Init Data Pointer routines DispatchVector InitDataBuffer DispatchVector InitDataTIB DispatchVector InitDataSG DispatchVector unusedVector ; Data routines DispatchVector DoDataBuffer DispatchVector DoDataTIB DispatchVector DoDataSG DispatchVector unusedVector ; Xfer routines DispatchVector DataIn_DMA DispatchVector DataIn_DMA DispatchVector DataOut_DMA ; pdw DispatchVector DataOut_DMA ; pdw DispatchVector unusedVector DispatchVector CyclePhase DispatchVector BusErrHandler96 DispatchVector unusedVector DispatchVector unusedVector ; jvStartDMA - fill it in below DispatchVector unusedVector ; jvStopReadDMA - fill it in below DispatchVector unusedVector ; jvStopWriteDMA - fill it in below DispatchVector unusedVector ; jvWt4DMAComplete - fill it in below DispatchVector AutoMsgIn ; DispatchVector Wt4SelectComplete ; DispatchVector HandleBusInt ; DispatchVector unusedVector ; unused DispatchVector unusedVector ; DispatchVector unusedVector ; DispatchVector unusedVector ; DispatchVector unusedVector ; DispatchVector unusedVector ; DispatchVector unusedVector ; DispatchVector unusedVector ; DispatchVector unusedVector ; tblEntries equ (*-OffsetTbl96)/4 ;========================================================================== unusedVector DebugStr 'HAL unusedVector' rts ;------------------------------------------------------------- ; ; Initialization code for the SCSI Manager 5394/5396 Initc96Asm link a6, #0 movem.l intrRegs, -(sp) ; save all registers, for convenience movea.l 8(a6), A5 ; get ptr to HAL globals move.l baseRegAddr(A5), A3 ; load A3 with base addr of 53c96 ;ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ ; ; Set up jump table - go through DispatchVectors above and copy them into the HALglobals ; IF (numSelectors<>tblEntries) THEN xxx TABLES DO NOT MATCH ENDIF moveq.l #numSelectors-1, d1 ; loop count IF forC96Init OR forROM THEN ; if not a linked patch, make addrs relative lea.l Initc96Asm, a1 ; get start of SCSI Mgr code move.l a1, d0 ; remember base address ELSE moveq.l #0, D0 ; if linked patch, make addrs absolute ENDIF lea OffsetTbl96, a1 ; address of offset table lea G_JmpTbl(A5), a0 ; point to base of jump table @MakeJmpTbl move.l (a1)+, d2 ; get the next offset beq.s @skipEntry ; if zero, skip this entry add.l d0, d2 ; compute the address move.l d2, (a0) ; install it in the jump table @skipEntry adda.l #4, a0 dbra d1, @MakeJmpTbl ; loop for all vectors ;ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ ; ; Replace standard vectors (just loaded) with those for specific hardware ; IF forPDMProto THEN bset #doRealDMARead, dmaFlags(A5) bset #doRealDMAWrite, dmaFlags(A5) ENDIF tst.b HBAhasDMA(A5) ; does HBA have real DMA? beq.w @hasNoDMA ; no-> install psuedo-DMA routines @hasDMA move.b dmaAlignmentSize(A5), D0 ; 8 or 16 (or whatever) ext.w D0 ext.l D0 subq.l #1, D0 move.l D0, dmaAlignMask(A5) cmp.b #dmaTypePSC, dmaType(A5) ; is it a PSC-type DMA? beq.s @hasPSC ; -> yes cmp.b #dmaTypeAMIC, dmaType(A5) ; is it an AMIC-type DMA? beq.s @hasAMIC ; -> yes cmp.b #dmaTypeGC, dmaType(A5) ; is it a Grand Central-type DMA? beq.w @hasGC DebugStr 'Bad hwDesc - dmaType unknown' ; ; CYCLONE ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ ; @hasPSC lea StartPSC, A0 move.l A0, jvStartDMA(A5) lea StopPSCRead, A0 move.l A0, jvStopReadDMA(A5) lea StopPSCWrite, A0 move.l A0, jvStopWriteDMA(A5) lea Wt4PSCComplete, A0 move.l A0, jvWt4DMAComplete(A5) lea SetupIOPSC, A0 move.l A0, jvSetupIO(A5) lea TeardownIOPSC, A0 move.l A0, jvTeardownIO(A5) bra.w @endDMAstuff ; ; PDM ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ ; @hasAMIC ; first do DMA sub-transfer routines lea StartAMIC, A0 move.l A0, jvStartDMA(A5) lea StopAMICRead, A0 move.l A0, jvStopReadDMA(A5) lea StopAMICWrite, A0 move.l A0, jvStopWriteDMA(A5) lea Wt4AMICComplete, A0 move.l A0, jvWt4DMAComplete(A5) lea SetupIOAMIC, A0 move.l A0, jvSetupIO(A5) lea TeardownIOAMIC, A0 move.l A0, jvTeardownIO(A5) lea SlowRead96, A0 ; LET'S FIGURE OUT WHAT'S WRONG WITH LITTLE DMAs!!! move.l A0, jvReadSlow(A5) IF forPDMProto THEN IMPORT DoWeHaveAMIC3B bsr DoWeHaveAMIC3B ; If we donΥt have AMIC3B then beq.s @hasNoDMA ; use pseudo-DMA routines. ENDIF bra.w @endDMAstuff ; ; TNT ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ ; @hasGC lea StartGC, A0 move.l A0, jvStartDMA(A5) lea StopGCRead, A0 move.l A0, jvStopReadDMA(A5) lea StopGCWrite, A0 move.l A0, jvStopWriteDMA(A5) lea Wt4GCComplete, A0 move.l A0, jvWt4DMAComplete(A5) lea SetupIOGC, A0 move.l A0, jvSetupIO(A5) lea TeardownIOGC, A0 move.l A0, jvTeardownIO(A5) bra.s @endDMAstuff ; ; QUADRAs and CENTRISes ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ ; @hasNoDMA lea FastRead96, A0 ; assume FastRead96 move.l A0, jvReadFast(A5) ; put this into transfer routine vector lea FastWrite96, A0 ; assume FastWrite96 move.l A0, jvWriteFast(A5) ; put this into transfer routine vector lea SlowRead96, A0 ; always SlowRead96 move.l A0, jvReadSlow(A5) lea SlowWrite96, A0 ; always SlowWrite96 move.l A0, jvWriteSlow(A5) cmp.b #pdmaTypeBIOS, dmaType(a5) ; Is this a BIOS equipped Machine? bne.s @endDMAstuff ; if not -> assumptions correct IF forSTP601v1 THEN lea SlowRead96, A0 ; ₯₯₯₯ if so, replace routines with BIOS versions ELSE lea FastRead_96_BIOS, A0 ; if so, replace routines with BIOS versions ENDIF move.l A0, jvReadFast(A5) lea FastWrite_96_BIOS, A0 move.l A0, jvWriteFast(A5) @endDMAstuff ;ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ ; ; Configure rCF3NormalVal and rCF3DMAVal according to our hardware ; move.b #mCF3_SaveResidual, rCF3NormalVal(A5) ; assume NOT T8 move.b #mCF3_SaveResidual, rCF3DMAVal(A5) ; assume NOT T8 tst.b usesThreshold8(A5) ; is T8 used for DMA? beq.s @endThresholdStuff ; no -> skip this all move.b #mCF3_SaveResidual + mCF3_Threshold8 + mCF3_AltDMAMode, rCF3DMAVal(A5) ; do not assert DREQ on residual byte at end of xfer ; enable alternate DMA mode ; enable threshold 8 mode tst.b HBAhasPseudoDMA(A5) ; does HBA have pseudo DMA? bne.s @endThresholdStuff ; -> if so, switch back and forth move.b rCF3DMAVal(A5), rCF3NormalVal(A5) ; if not, always use T8 @endThresholdStuff move.b rCF3NormalVal(A5), rCF3(A3) ; configure for normal operation ;ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ ; ; Assorted stuff ; bsr Install_ISR WITH DeferredTask WITH SCSIGlobalsRec ; Setup the real deferred task lea dataDT(a5),a0 ; our deferred task record lea DataDTask,a1 ; the deferred task clr.l qLink(a0) ; reserved on entry move.w #dtQType, qType(a0) ; The queue type move.l a1, dtAddr(a0) ; fill in PB move.l a5, dtParm(a0) ; Save globals do DT can restore a5 clr.l dtReserved(a0) ; reserved clr.w dtFlags(a0) ; reserved ; Setup the dummy deferred task lea dataDT_Null(a5),a0 ; our deferred task record lea @bogusDefer,a1 ; the deferred task (!) clr.l qLink(a0) ; reserved on entry move.w #dtQType, qType(a0) ; The queue type move.l a1, dtAddr(a0) ; fill in PB move.l a5, dtParm(a0) ; parameter is our globals clr.l dtReserved(a0) ; reserved clr.w dtFlags(a0) ; reserved move.l SCSIGlobals, A0 ; move.l ci_jDisptch_Vers, D0 ; our version number cmp.l ci_jDisptchVers(A0), D0 ; already installed? beq.b @alreadyInstalled ; yep move.l D0, ci_jDisptchVers(A0) ; remember our version number move.l jDisptch, oldjDisptch(A0) ; remember the old routine clr.w privDTQFlags(A0) ; clear out the qFlags field clr.l privDTQHead(A0) ; and the qHead clr.l privDTQTail(A0) ; and the qTail lea ci_jDisptch, A1 ; get our patch move.l A1, jDisptch ; and install it in the jVector @alreadyInstalled clr.b dataDTFlags(a5) ; clear our flags field move.b #SCSIPhase.kBusFreePhase, currentPhase(A5) IF RECORD_ON THEN pea $00000000 pea '====' bsr RecordEvent addq.l #8, sp ENDIF movem.l (sp)+, intrRegs ; restore registers unlk A6 rts @bogusDefer rts NAME 'Initc96Asm' ENDWITH ENDWITH ENDWITH ENDP END