diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/nthals/halsable/alpha/lyintsup.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/ntos/nthals/halsable/alpha/lyintsup.c')
-rw-r--r-- | private/ntos/nthals/halsable/alpha/lyintsup.c | 517 |
1 files changed, 517 insertions, 0 deletions
diff --git a/private/ntos/nthals/halsable/alpha/lyintsup.c b/private/ntos/nthals/halsable/alpha/lyintsup.c new file mode 100644 index 000000000..b9f6486dc --- /dev/null +++ b/private/ntos/nthals/halsable/alpha/lyintsup.c @@ -0,0 +1,517 @@ +/*++ + +Copyright (c) 1995 Digital Equipment Corporation + +Module Name: + + lyintsup.c + +Abstract: + + This module provides interrupt support for the Lynx family + Standard I/O board. + +Author: + + Dave Richards 31-May-1995 + +Revision History: + +--*/ + +#include "halp.h" +#include "t2.h" +#include "icic.h" +#include "xiintsup.h" + +// +// Define the context structure for use by interrupt service routines. +// + +typedef BOOLEAN (*PSECOND_LEVEL_DISPATCH)( + PKINTERRUPT InterruptObject + ); + +// +// Cached copies of the corresponding ICIC registers. +// + +ICIC_ELCR_REGISTER LynxIcIcElcrRegister; +ICIC_MASK_REGISTER LynxIcIcMaskRegister; + + +ULONG +HalpGetLynxSioInterruptVector( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity + ) +{ + *Irql = DEVICE_LEVEL; + *Affinity = HAL_CPU0_MASK; + + switch( BusInterruptLevel ){ + + case EisaInterruptLevel3: + return( LynxEisaIrq3Vector ); + + case EisaInterruptLevel4: + return( LynxEisaIrq4Vector ); + + case EisaInterruptLevel5: + return( LynxEisaIrq5Vector ); + + case EisaInterruptLevel6: + return( LynxEisaIrq6Vector ); + + case EisaInterruptLevel7: + return( LynxEisaIrq7Vector ); + + case EisaInterruptLevel9: + return( LynxEisaIrq9Vector ); + + case EisaInterruptLevel10: + return( LynxEisaIrq10Vector ); + + case EisaInterruptLevel11: + return( LynxEisaIrq11Vector ); + + case EisaInterruptLevel12: + return( LynxEisaIrq12Vector ); + + case EisaInterruptLevel14: + return( LynxEisaIrq14Vector ); + + case EisaInterruptLevel15: + return( LynxEisaIrq15Vector ); + + // + // Handle Vectors for the Internal bus devices. + // + + case LynxMouseVector: + case LynxKeyboardVector: + case LynxFloppyVector: + case LynxSerialPort1Vector: + case LynxParallelPortVector: + case LynxSerialPort0Vector: + case LynxI2cVector: + + // + // Handle Vectors for PCI devices. + // + + case LynxScsi0Vector: + case LynxScsi1Vector: + case LynxPciSlot0AVector: + case LynxPciSlot0BVector: + case LynxPciSlot0CVector: + case LynxPciSlot0DVector: + case LynxPciSlot1AVector: + case LynxPciSlot1BVector: + case LynxPciSlot1CVector: + case LynxPciSlot1DVector: + case LynxPciSlot2AVector: + case LynxPciSlot2BVector: + case LynxPciSlot2CVector: + case LynxPciSlot2DVector: + case LynxPciSlot3AVector: + case LynxPciSlot3BVector: + case LynxPciSlot3CVector: + case LynxPciSlot3DVector: + case LynxPciSlot4AVector: + case LynxPciSlot4BVector: + case LynxPciSlot4CVector: + case LynxPciSlot4DVector: + case LynxPciSlot5AVector: + case LynxPciSlot5BVector: + case LynxPciSlot5CVector: + case LynxPciSlot5DVector: + case LynxPciSlot6AVector: + case LynxPciSlot6BVector: + case LynxPciSlot6CVector: + case LynxPciSlot6DVector: + case LynxPciSlot7AVector: + case LynxPciSlot7BVector: + case LynxPciSlot7CVector: + case LynxPciSlot7DVector: + + return( BusInterruptLevel ); + + default: + +#if defined(XIO_PASS1) || defined(XIO_PASS2) + + return HalpGetXioInterruptVector( + BusHandler, + RootHandler, + BusInterruptLevel, + BusInterruptVector, + Irql, + Affinity + ); + +#else + + *Irql = 0; + *Affinity = 0; + return 0; + +#endif + + } +} + + +BOOLEAN +HalpInitializeLynxSioInterrupts( + VOID + ) + +/*++ + +Routine Description: + + This routine initializes the ICIC on the Standard I/O module. + +Arguments: + + None. + +Return Value: + + TRUE. + +--*/ + +{ + T2_ICE Ice; + ICIC_EISA_REGISTER LynxIcIcEisaRegister; + + // + // Initialize the interface between the T3/T4 and the ICIC. + // + + Ice.all = 0; + Ice.EisaFlushAddress = 0x542; + Ice.IcEnable = 1; + Ice.HalfSpeedEnable = 0; + + WRITE_T2_REGISTER( &((PT2_CSRS)(T2_CSRS_QVA))->Ice, + Ice.all ); + + // + // Initialize the ICIC Mask Register. + // + + LynxIcIcMaskRegister = (ULONGLONG)-1; + + WRITE_ICIC_REGISTER( T2_CSRS_QVA, IcIcMaskRegister, + LynxIcIcMaskRegister ); + + // + // Initialize the ICIC Edge/Level Control Register. + // + + LynxIcIcElcrRegister = + ((ICIC_ELCR_REGISTER)1 << (LynxScsi0Vector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxScsi1Vector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot4AVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot4BVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot4CVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot4DVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot5AVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot5BVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot5CVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot5DVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot6AVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot6BVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot6CVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot6DVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot7AVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot7BVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot7CVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot7DVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot7DVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot0AVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot0BVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot0CVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot0DVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot1AVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot1BVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot1CVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot1DVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot2AVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot2BVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot2CVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot2DVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot3AVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot3BVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot3CVector - LynxBaseVector)) | + ((ICIC_ELCR_REGISTER)1 << (LynxPciSlot3DVector - LynxBaseVector)); + + WRITE_ICIC_REGISTER( T2_CSRS_QVA, IcIcElcrRegister, + LynxIcIcElcrRegister ); + + // + // Initialize the ICIC EISA Register. + // + + LynxIcIcEisaRegister = + (1 << (LynxEisaIrq3Vector - LynxBaseVector)) | + (1 << (LynxEisaIrq4Vector - LynxBaseVector)) | + (1 << (LynxEisaIrq5Vector - LynxBaseVector)) | + (1 << (LynxEisaIrq6Vector - LynxBaseVector)) | + (1 << (LynxEisaIrq7Vector - LynxBaseVector)) | + (1 << (LynxEisaIrq9Vector - LynxBaseVector)) | + (1 << (LynxEisaIrq10Vector - LynxBaseVector)) | + (1 << (LynxEisaIrq11Vector - LynxBaseVector)) | + (1 << (LynxEisaIrq12Vector - LynxBaseVector)) | + (1 << (LynxEisaIrq14Vector - LynxBaseVector)) | + (1 << (LynxEisaIrq15Vector - LynxBaseVector)); + + WRITE_ICIC_REGISTER( T2_CSRS_QVA, IcIcEisaRegister, + LynxIcIcEisaRegister ); + + // + // Initialize the ICIC Mode Register. + // + + WRITE_ICIC_REGISTER( T2_CSRS_QVA, IcIcModeRegister, (ULONGLONG)0 ); + + return TRUE; +} + +BOOLEAN +HalpLynxSioDispatch( + VOID + ) + +/*++ + +Routine Description: + + This routine dispatches interrupts received by the Standard I/O + ICIC. + +Arguments: + + None. + +Return Value: + + A boolean value indicating whether the interrupt was handled by + the FLIH/SLIH. + +--*/ + +{ + T2_VAR Var; + PULONG DispatchCode; + PKINTERRUPT InterruptObject; + BOOLEAN ReturnValue; + + // + // Get the interrupt vector. + // + + Var.all = READ_T2_REGISTER( &((PT2_CSRS)(T2_CSRS_QVA))->Var ); + + // + // If this is a passive release, ignore the interrupt. + // + + if( Var.PassiveRelease == 1 ){ + + return(TRUE); + + } + + // + // Dispatch to the secondary interrupt service routine. + // + + DispatchCode = (PULONG)PCR->InterruptRoutine[LynxBaseVector + Var.Vector]; + InterruptObject = CONTAINING_RECORD(DispatchCode, + KINTERRUPT, + DispatchCode); + + ReturnValue = ((PSECOND_LEVEL_DISPATCH)InterruptObject->DispatchAddress)(InterruptObject); + + // + // Send an SEOI. + // + + WRITE_T2_REGISTER( &((PT2_CSRS)(T2_CSRS_QVA))->Var, Var.Vector ); + + return(ReturnValue); +} + +VOID +HalpDisableLynxSioInterrupt( + IN ULONG Vector + ) + +/*++ + +Routine Description: + + This routine disables interrupts associated with the Standard I/O + ICIC. + +Arguments: + + Vector - The vector of the interrupt to disable. + +Return Value: + + None. + +--*/ + +{ + ULONGLONG IrqMask; + + if( (Vector >= LynxBaseVector) && + (Vector <= LynxPciSlot3DVector) ){ + + // + // Compute the IRQ mask. + // + + IrqMask = (ICIC_MASK_REGISTER)1 << (Vector - LynxBaseVector); + + // + // Mask the interrupt. + // + + LynxIcIcMaskRegister |= IrqMask; + + // + // Update the ICIC Mask Register. + // + + WRITE_ICIC_REGISTER( T2_CSRS_QVA, IcIcMaskRegister, + LynxIcIcMaskRegister ); + + } else { + +#if defined(XIO_PASS1) || defined(XIO_PASS2) + + HalpDisableXioInterrupt( Vector ); + +#endif + + } +} + +BOOLEAN +HalpEnableLynxSioInterrupt( + IN ULONG Vector, + IN KINTERRUPT_MODE InterruptMode + ) + +/*++ + +Routine Description: + + This routine enables interrupts associated with the Standard I/O + ICIC. + +Arguments: + + Vector - The vector of the interrupt to enable. + + InterruptMode - An indication of whether the interrupt should + be edge-triggered/level-sensitive. + +Return Value: + + None. + +--*/ + +{ + ULONGLONG IrqMask; + + if( (Vector >= LynxBaseVector) && + (Vector <= LynxPciSlot3DVector) ){ + + // + // Compute the IRQ mask. + // + + IrqMask = (ICIC_MASK_REGISTER)1 << (Vector - LynxBaseVector); + + // + // For EISA interrupts InterruptMode indicates whether the interrupt + // is level sensitive (active low) or edge-triggered (low-to-high). + // We use this information to update the Edge/Level Control Register + // bit for this IRQ. + // + + switch( Vector ){ + + case LynxEisaIrq3Vector: + case LynxEisaIrq4Vector: + case LynxEisaIrq5Vector: + case LynxEisaIrq6Vector: + case LynxEisaIrq7Vector: + case LynxEisaIrq9Vector: + case LynxEisaIrq10Vector: + case LynxEisaIrq11Vector: + case LynxEisaIrq12Vector: + case LynxEisaIrq14Vector: + case LynxEisaIrq15Vector: + + // + // Set/Clear the ELCR bit (as appropriate). + // + + if( InterruptMode == LevelSensitive ){ + LynxIcIcElcrRegister |= IrqMask; + } else { + LynxIcIcElcrRegister &= ~IrqMask; + } + + // + // Update the ICIC Edge/Level Control Register. + // + + WRITE_ICIC_REGISTER( T2_CSRS_QVA, IcIcElcrRegister, + LynxIcIcElcrRegister ); + + break; + + } + + // + // Un-mask the interrupt. + // + + LynxIcIcMaskRegister &= ~IrqMask; + + // + // Update the ICIC Mask Register. + // + + WRITE_ICIC_REGISTER( T2_CSRS_QVA, IcIcMaskRegister, + LynxIcIcMaskRegister ); + + return TRUE; + + } else { + +#if defined(XIO_PASS1) || defined(XIO_PASS2) + + return HalpEnableXioInterrupt( Vector, InterruptMode ); + +#endif + + } + + return FALSE; +} |