summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halsable/alpha/lyintsup.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/nthals/halsable/alpha/lyintsup.c
downloadNT4.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.c517
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;
+}