.IDENT 'X-01' ; ;**************************************************************************** ;* * ;* COPYRIGHT (c) 1990 BY * ;* DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS. * ;* ALL RIGHTS RESERVED. * ;* * ;* THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED * ;* ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE * ;* INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER * ;* COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY * ;* OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY * ;* TRANSFERRED. * ;* * ;* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE * ;* AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT * ;* CORPORATION. * ;* * ;* DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS * ;* SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. * ;* * ;* * ;**************************************************************************** ; ;++ ; ; FACILITY: ; ; VAX/VMS Executive, I/O Drivers ; ; ABSTRACT: ; ; This module contains the driver to map VME memory. ; ; ENVIRONMENT: ; ; Kernel Mode, Non-paged ; ; ; ;-- .SBTTL External and local symbol definitions ; External symbols $ACBDEF ; AST control block $ADPDEF ; Adapter control block $CRBDEF ; Channel request block $DCDEF ; Device types $DDBDEF ; Device data block $DEVDEF ; Device characteristics $DPTDEF ; Driver prolog table $DYNDEF ; Dynamic data structure types $EMBDEF ; EMB offsets $IDBDEF ; Interrupt data block $IO9CCDEF ; Define Calypso/CVAX memory layout $IO9RRDEF ; Define Calypso/Rigel memory layout $IO1202DEF ; Define Mariah memory layout $IO1302DEF ; Define Neptune memory layout $IODEF ; I/O function codes $IPLDEF ; Hardware IPL definitions $IRPDEF ; I/O request packet $PRDEF ; Internal processor registers $PRIDEF ; Scheduler priority increments $PTEDEF ; PTE definitions $SSDEF ; System status codes $UCBDEF ; Unit control block $VECDEF ; Interrupt vector block $XADEF ; Define device specific characteristics ; $XVIBDEF ; VME definitions ; Local symbols ; Argument list (AP) offsets for device-dependent QIO parameters P1 = 0 ; First QIO parameter P2 = 4 ; Second QIO parameter P3 = 8 ; Third QIO parameter P4 = 12 ; Fourth QIO parameter P5 = 16 ; Fifth QIO parameter P6 = 20 ; Sixth QIO parameter ; Other constants ; DATEL DVME definitions that follow the standard UCB fields $DEFINI UCB .=UCB$L_DPC+4 $DEF UCB$L_MAPDESCR,.LONG $DEF UCB$L_WDATA,.LONG UCB$K_SIZE = . $DEFEND UCB .SBTTL Device Driver Tables ; Driver prologue table DPTAB - ; DPT-creation macro END=QL_END,- ; End of driver label ADAPTER=VME,- ; Adapter type FLAGS=,- ; Allocate system page table UCBSIZE=UCB$K_SIZE,- ; UCB size NAME=QLDRIVER ; Driver name DPT_STORE INIT ; Start of load ; initialization table DPT_STORE UCB,UCB$B_FLCK,B,SPL$C_IOLOCK8 ; Device fork IPL DPT_STORE UCB,UCB$B_DIPL,B,20 ; Device interrupt IPL DPT_STORE UCB,UCB$L_DEVCHAR,L,<- ; Device characteristics DEV$M_AVL> ; Available DPT_STORE UCB,UCB$B_DEVCLASS,B,DC$_REALTIME ; Device class DPT_STORE UCB,UCB$B_DEVTYPE,B,DT$_XVIB ; Device Type DPT_STORE REINIT ; Start of reload ; initialization table DPT_STORE DDB,DDB$L_DDT,D,QL$DDT ; Address of DDT DPT_STORE CRB,CRB$L_INTD+4,D,- ; Address of interrupt QL_INTERRUPT ; service routine DPT_STORE CRB,CRB$L_INTD+VEC$L_UNITINIT,-; Unit init. D,QL_UNIT_INIT ; DPT_STORE CRB,CRB$L_INTD+VEC$L_INITIAL,-; Address of controller D,QL_CONTROL_INIT ; initialization routine DPT_STORE END ; End of initialization ; tables ; Driver dispatch table DDTAB - ; DDT-creation macro DEVNAM=QL,- ; Name of device START=QL_START,- ; Start I/O routine FUNCTB=QL_FUNCTABLE,- ; FDT address CANCEL=QL_CANCEL ; Cancel I/O routine ; ; Function dispatch table ; QL_FUNCTABLE: ; FDT for driver FUNCTAB ,- ; Valid I/O functions FUNCTAB , ; No buffered functions FUNCTAB QL_FDT_DEACCESS, FUNCTAB QL_FDT_INITIALIZE, FUNCTAB QL_FDT_PIO, ; PIO .SBTTL QL_CONTROL_INIT, Controller initialization ;++ ; QL_CONTROL_INIT, Called when driver is loaded, system is booted, or ; power failure recovery. ; ; Functional Description: ; ; Inputs: ; ; R4 = address of CSR ; R5 = address of IDB ; R6 = address of DDB ; R8 = address of CRB ; ; Outputs: ; ; ;-- QL_CONTROL_INIT:: MOVL IDB$L_UCBLST(R5),R0 ; Address of UCB MOVL R0,IDB$L_OWNER(R5) ; Make permanent owner BISW #UCB$M_ONLINE,UCB$W_STS(R0) RSB ; Done QL_UNIT_INIT: BISW #UCB$M_ONLINE,UCB$W_STS(R5) MOVZBL #SS$_NORMAL,R0 RSB .SBTTL DT_FDT_DEACCESS, FDT for Release PIO map regs. ;++ ; QL_FDT_DEACCESS FDT for DEACCESS ; ; Functional description: ; ; 1) This routine will release the current PIO mapping registers that ; have been allocated. ; ; Inputs: ; ; R3 = Address of IRP ; R4 = Address of PCB ; R5 = Address of UCB ; R6 = Address of CCB ; R8 = Address of FDT routine ; AP = Address of P1 ; ; Outputs: ; ; Queued to start IO routine ; ;-- QL_FDT_DEACCESS: JMP G^EXE$QIODRVPKT .SBTTL QL_FDT_INITIALIZE, FDT to allocate the PIO map registers. ;++ ; QL_FDT_INITIALIZE FDT for INITIALIZE ; ; Functional description: ; ; Inputs: ; ; P1 = VME address to map. ; P2 = # of bytes to map. ; P3 = VME access modes. ; R3 = Address of IRP ; R4 = Address of PCB ; R5 = Address of UCB ; R6 = Address of CCB ; R8 = Address of FDT routine ; AP = Address of P1 ; ; Outputs: ; ; Queued to start IO routine ;-- QL_FDT_INITIALIZE: MOVL P1(AP),IRP$L_IOST1(R3) ; Get the VME address. MOVL P3(AP),IRP$L_IOST2(R3) ; Get the Access modes. JMP G^EXE$QIODRVPKT .SBTTL QL_FDT_PIO, FDT to do PIO. ;++ ; QL_FDT_PIO FDT for PIO ; ; Functional description: ; ; Inputs: ; ; P1 = PCA. ; P2 = Word length. ; P3 = Write data. ; R3 = Address of IRP ; R4 = Address of PCB ; R5 = Address of UCB ; R6 = Address of CCB ; R8 = Address of FDT routine ; AP = Address of P1 ; ; Outputs: ; ; Queued to start IO routine ;-- QL_FDT_PIO: MOVL P1(AP),IRP$L_IOST1(R3) ; Get the PCA. MOVL P2(AP),IRP$L_IOST2(R3) ; Get the Data length. MOVL P3(AP),UCB$L_WDATA(R5) ; Get the Data. JMP G^EXE$QIODRVPKT .SBTTL QL_START, Start I/O routines QL_START: MOVW IRP$W_FUNC(R3),- ; Save function code & modifier UCB$W_FUNC(R5) ;+ ; Do final set up and dispatch to the routine which performs the function. ;- EXTZV #IRP$V_FCODE,#IRP$S_FCODE,- ; Extract I/O function code... IRP$W_FUNC(R3),R1 ; ...without function modifiers CMPL #IO$_WRITEPBLK,R1 ; Allocate and load PIO map registers BEQL 10$ ; Branch if allocate CMPL #IO$_DEACCESS,R1 ; Deallocate PIO map registers BEQL 20$ ; Branch if deallocate CMPL #IO$_READLBLK, R1 ; Branch if PIO write to device BEQL 30$ CMPL #IO$_WRITELBLK, R1 ; Branch if PIO read to device BNEQ 5$ BRW 40$ ; ; If we fall through then we were passed an illegal function code ; 5$: MOVZBL #SS$_ILLIOFUNC,R0 ; Specify the error type REQCOM ; ; Come here to allocate and load the PIO mapping registers. We will pass back the ; IO space PFN that corresponds to the first PIO map register allocated. This will ; allow the user to PFN map the mapped VME space into their P0 space ; 10$: PUSHL R3 MOVZBL #1,R3 ; We want 1 PIO map register. BSBW IOC$ALOVMEMAP_PIO ; Allocate a mapping register. BLBC R0,15$ ; Branch if error. MOVL (SP),R2 ; Get a pointer to the IRP MOVL IRP$L_IOST1(R2),R0 ; Get the VME address. MOVL IRP$L_IOST2(R2),R1 ; Get the Access modes. BSBW IOC$LOADVMEMAP_PIO ; Load the mapping registers. BLBC R0,15$ MOVL UCB$L_CRB(R5),R2 ; Get the CRB. MOVW CRB$L_INTD+VEC$W_MAPALT(R2),R1 ; Get the starting map reg #. MOVL CRB$L_INTD+VEC$L_ADP(R2),R2 ; Get our ADP MOVL ADP$L_CSR(R2),R1 ; Get our PCA for I/O adapter ; space BBSS #PCA$V_VME,R1,11$ ; Set VME flag 11$: MOVZBL #SS$_NORMAL,R0 ; Set success status 12$: POPL R3 ; Restore IRP REQCOM ; Return to user 15$: CLRL R0 BRB 12$ ; ; Deallocate the PIO mapping registers ; 20$: BSBW IOC$RELVMEMAP_PIO ; Release the VME PIO map regs. CLRL R1 ; Set return to not released. MOVZWL #SS$_NORMAL,R0 ; Init return to success. REQCOM ; Return to user 30$: ; PIO write PUSHR #^M MOVL IRP$L_IOST1(R3),R0 ; PCA MOVL UCB$L_WDATA(R5),R1 ; Write data MOVL IRP$L_IOST2(R3),R3 ; Data length MOVL #1, R4 ; PIO map register 1 BLBS R3, 31$ ; if set BYTE mode BBS #1,R3,32$ ; if set WORD mode BBS #2,R3,33$ ; if set LONGWORD mode BRW 34$ 31$: WRITE_CSR R1,(R0),VME=R4,- ; Do mailbox to VME space LENGTH= BYTE,- ENVIRON=SPECIFIC BRW 34$ 32$: WRITE_CSR R1,(R0),VME=R4,- ; Do mailbox to VME space LENGTH= WORD,- ENVIRON=SPECIFIC BRW 34$ 33$: WRITE_CSR R1,(R0),VME=R4,- ; Do mailbox to VME space LENGTH= LONG,- ENVIRON=SPECIFIC 34$: POPR #^M REQCOM ; return to user 40$: ; PIO read PUSHR #^M MOVL IRP$L_IOST1(R3),R0 ; PCA MOVL IRP$L_IOST2(R3),R3 ; Data length MOVL #1,R4 ; PIO map register 1 BLBS R3, 41$ ; if set BYTE mode BBS #1,R3,42$ ; if set WORD mode BBS #2,R3,43$ ; if set LONGWORD mode BRW 44$ 41$: READ_CSR (R0),R1,VME=R4,- ; Do mailbox to VME space LENGTH=BYTE,- ENVIRON=SPECIFIC BRW 44$ 42$: READ_CSR (R0),R1,VME=R4,- ; Do mailbox to VME space LENGTH=WORD,- ENVIRON=SPECIFIC BRW 44$ 43$: READ_CSR (R0),R1,VME=R4,- ; Do mailbox to VME space LENGTH=LONG,- ENVIRON=SPECIFIC 44$: POPR #^M REQCOM ; return to user .SBTTL QL_INTERRUPT, Interrupt service routine. QL_INTERRUPT: REI ; Return from interrupt .SBTTL QL_CANCEL, Cancel I/O routine QL_CANCEL: ; Cancel I/O DEVICELOCK - LOCKADDR=UCB$L_DLCK(R5),- ; Lock device access SAVIPL=-(SP),- ; Save current IPL PRESERVE=NO ; Don't preserve R0 ; Check to see if a data transfer request is in progress ; for this process on this channel JSB G^IOC$CANCELIO ; Check if transfer going BBC #UCB$V_CANCEL,- UCB$W_STS(R5),30$ ; Branch if not for this guy ; ; Release resources ; BSBW IOC$RELVMEMAP_PIO ; Release any map registers 30$: DEVICEUNLOCK - LOCKADDR=UCB$L_DLCK(R5),- ; Unlock device access NEWIPL=(SP)+,- ; Enable interrupts PRESERVE=NO RSB ; Return QL_END: ; End of driver label .END