Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

679 lines
15 KiB

/*++
Copyright (c) 1993,1995,1996 Digital Equipment Corporation
Module Name:
lgsysint.c
Abstract:
This module implements the HAL enable/disable system interrupt, and
request interprocessor interrupt routines for the Lego system.
Author:
Joe Notarangelo 25-Oct-1993
Environment:
Kernel mode
Revision History:
Gene Morgan [Digital] 11-Oct-1995
Initial version for Lego. Adapted from Avanti and Mikasa
Gene Morgan 15-Apr-1996
Remove debugging code.
Add error logging for server management events (e.g., fan and temp)
--*/
#include "halp.h"
#include "legodef.h"
#include "axp21064.h"
extern ULONG HalpLegoPciRoutingType;
extern BOOLEAN HalpServerMgmtLoggingEnabled;
//
// External function prototypes
//
ULONG
HalpGet21064CorrectableVector(
IN ULONG BusInterruptLevel,
OUT PKIRQL Irql
);
VOID
HalpSetMachineCheckEnables(
IN BOOLEAN DisableMachineChecks,
IN BOOLEAN DisableProcessorCorrectables,
IN BOOLEAN DisableSystemCorrectables
);
//
// Local function prototypes
//
VOID
HalpDisablePciInterrupt(
IN ULONG Vector
);
VOID
HalpDisableServerMgmtInterrupt(
IN ULONG Vector
);
VOID
HalpEnablePciInterrupt(
IN ULONG Vector,
IN KINTERRUPT_MODE InterruptMode
);
VOID
HalpEnableServerMgmtInterrupt(
IN ULONG Vector,
IN KINTERRUPT_MODE InterruptMode
);
//
// Define reference to the builtin device interrupt enables.
//
extern USHORT HalpBuiltinInterruptEnable;
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE,HalpGetSystemInterruptVector)
#endif
VOID
HalDisableSystemInterrupt (
IN ULONG Vector,
IN KIRQL Irql
)
/*++
Routine Description:
This routine disables the specified system interrupt.
Arguments:
Vector - Supplies the vector of the system interrupt that is disabled.
Irql - Supplies the IRQL of the interrupting source.
Return Value:
None.
--*/
{
ULONG Irq;
KIRQL OldIrql;
//
// Raise IRQL to the highest level.
//
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
//
// If the vector number is within the range of the
// Server Management interrupts, then disable the appropriate
// interrupt.
//
if (Vector >= SERVER_MGMT_VECTORS &&
Vector < MAXIMUM_SERVER_MGMT_VECTOR &&
Irql == SERVER_MGMT_LEVEL) {
#if DBG
DbgPrint("Dm<%02x>",Vector);
#endif
HalpDisableServerMgmtInterrupt(Vector);
}
//
// If the vector number is within the range of the
// ISA interrupts, then disable the ISA interrupt.
//
else if (Vector >= ISA_DEVICE_VECTORS &&
Vector < MAXIMUM_ISA_VECTOR &&
Irql == ISA_DEVICE_LEVEL) {
#if DBG
DbgPrint("Ds<%02x>",Vector);
#endif
HalpDisableSioInterrupt(Vector);
}
//
// If the vector number is within the range of the
// PCI interrupts, then disable the PCI interrupt.
//
else if (Vector >= PCI_DEVICE_VECTORS &&
Vector < LEGO_MAXIMUM_PCI_VECTOR &&
Irql == PCI_DEVICE_LEVEL) {
#if DBG
DbgPrint("Dp<%02x>",Vector);
#endif
HalpDisablePciInterrupt(Vector);
}
//
// If the vector is a performance counter vector or one of the internal
// device vectors then disable the interrupt for the 21064.
//
else {
switch (Vector) {
//
// Performance counter 0 interrupt (internal to 21064)
//
case PC0_VECTOR:
case PC0_SECONDARY_VECTOR:
#if DBG
DbgPrint("Dc0<%02x>",Vector);
#endif
HalpDisable21064PerformanceInterrupt( PC0_VECTOR );
break;
//
// Performance counter 1 interrupt (internal to 21064)
//
case PC1_VECTOR:
case PC1_SECONDARY_VECTOR:
#if DBG
DbgPrint("Dc1<%02x>",Vector);
#endif
HalpDisable21064PerformanceInterrupt( PC1_VECTOR );
break;
case CORRECTABLE_VECTOR:
//
// Disable the correctable error interrupt.
//
{
EPIC_ECSR Ecsr;
Ecsr.all = READ_EPIC_REGISTER(
&((PEPIC_CSRS)(APECS_EPIC_BASE_QVA))->EpicControlAndStatusRegister );
Ecsr.Dcei = 0x0;
WRITE_EPIC_REGISTER(
&((PEPIC_CSRS)(APECS_EPIC_BASE_QVA))->EpicControlAndStatusRegister,
Ecsr.all );
HalpSetMachineCheckEnables( FALSE, TRUE, TRUE );
//
// Disable logging of server management errors as well
//
HalpServerMgmtLoggingEnabled = FALSE;
break;
}
#if DBG
default:
//
// unrecognized
//
DbgPrint("D?<%02x>",Vector);
#endif
} //end switch Vector
}
//
// Lower IRQL to the previous level.
//
KeLowerIrql(OldIrql);
return;
}
BOOLEAN
HalEnableSystemInterrupt (
IN ULONG Vector,
IN KIRQL Irql,
IN KINTERRUPT_MODE InterruptMode
)
/*++
Routine Description:
This routine enables the specified system interrupt.
Arguments:
Vector - Supplies the vector of the system interrupt that is enabled.
Irql - Supplies the IRQL of the interrupting source.
InterruptMode - Supplies the mode of the interrupt;
LevelSensitive or Latched.
Return Value:
TRUE if the system interrupt was enabled
--*/
{
BOOLEAN Enabled = FALSE;
ULONG Irq;
KIRQL OldIrql;
//
// Raise IRQL to the highest level.
//
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
//
// If the vector number is within the range of the
// Server Management interrupts, then enable the appropriate
// interrrupt.
//
if (Vector >= SERVER_MGMT_VECTORS &&
Vector < MAXIMUM_SERVER_MGMT_VECTOR &&
Irql == SERVER_MGMT_LEVEL) {
#if DBG
DbgPrint("Em<%02x,%02x>",Vector,InterruptMode);
#endif
HalpEnableServerMgmtInterrupt(Vector,InterruptMode);
Enabled = TRUE;
}
//
// If the vector number is within the range of the
// ISA interrupts, then enable the ISA interrupt and
// set the Level/Edge register.
//
else if (Vector >= ISA_DEVICE_VECTORS &&
Vector < MAXIMUM_ISA_VECTOR &&
Irql == ISA_DEVICE_LEVEL) {
#if DBG
DbgPrint("Es<%02x,%02x>",Vector,InterruptMode);
#endif
HalpEnableSioInterrupt( Vector, InterruptMode );
Enabled = TRUE;
}
//
// If the vector number is within the range of the
// PCI interrupts, then enable the PCI interrupt.
//
else if (Vector >= PCI_DEVICE_VECTORS &&
Vector < LEGO_MAXIMUM_PCI_VECTOR &&
Irql == PCI_DEVICE_LEVEL) {
#if DBG
DbgPrint("Ep<%02x,%02x>",Vector,InterruptMode);
#endif
HalpEnablePciInterrupt(Vector, InterruptMode);
Enabled = TRUE;
}
//
// If the vector is a performance counter vector or one of the
// internal device vectors then perform 21064-specific enable.
//
else {
switch (Vector) {
//
// Performance counter 0 (internal to 21064)
//
case PC0_VECTOR:
case PC0_SECONDARY_VECTOR:
#if DBG
DbgPrint("Ec0<%02x,%02x>",Vector,Irql);
#endif
HalpEnable21064PerformanceInterrupt( PC0_VECTOR, Irql );
Enabled = TRUE;
break;
//
// Performance counter 1 (internal to 21064)
//
case PC1_VECTOR:
case PC1_SECONDARY_VECTOR:
#if DBG
DbgPrint("Ec1<%02x,%02x>",Vector,Irql);
#endif
HalpEnable21064PerformanceInterrupt( PC1_VECTOR, Irql );
Enabled = TRUE;
break;
case CORRECTABLE_VECTOR:
//
// Enable the correctable error interrupt.
//
{
EPIC_ECSR Ecsr;
Ecsr.all = READ_EPIC_REGISTER(
&((PEPIC_CSRS)(APECS_EPIC_BASE_QVA))->EpicControlAndStatusRegister );
Ecsr.Dcei = 0x1;
WRITE_EPIC_REGISTER(
&((PEPIC_CSRS)(APECS_EPIC_BASE_QVA))->EpicControlAndStatusRegister,
Ecsr.all );
HalpSetMachineCheckEnables( FALSE, FALSE, FALSE );
//
// Will log server management errors as well
//
HalpServerMgmtLoggingEnabled = TRUE;
Enabled = TRUE;
break;
}
#if DBG
default:
//
// not enabled
//
DbgPrint("E?<%02x,%02x,%02x>",Vector,Irql,InterruptMode);
#endif
} //end switch Vector
}
//
// Lower IRQL to the previous level.
//
KeLowerIrql(OldIrql);
return Enabled;
}
ULONG
HalpGetSystemInterruptVector(
IN PBUS_HANDLER BusHandler,
IN PBUS_HANDLER RootHandler,
IN ULONG BusInterruptLevel,
IN ULONG BusInterruptVector,
OUT PKIRQL Irql,
OUT PKAFFINITY Affinity
)
/*++
Routine Description:
This function returns the system interrupt vector and IRQL level
corresponding to the specified bus interrupt level and/or vector. The
system interrupt vector and IRQL are suitable for use in a subsequent call
to KeInitializeInterrupt.
We only use InterfaceType, and BusInterruptLevel. BusInterruptVector
for ISA and ISA are the same as the InterruptLevel, so ignore.
Arguments:
BusHandler - Registered BUSHANDLER for the target configuration space
RootHandler - Registered BUSHANDLER for the orginating HalGetBusData
request.
BusInterruptLevel - Supplies the bus specific interrupt level.
BusInterruptVector - Supplies the bus specific interrupt vector.
Irql - Returns the system request priority.
Affinity - Returns the affinity for the requested vector
Return Value:
Returns the system interrupt vector corresponding to the specified device.
--*/
{
INTERFACE_TYPE InterfaceType = BusHandler->InterfaceType;
ULONG BusNumber = BusHandler->BusNumber;
ULONG Vector;
#if DBG
DbgPrint("GIV< l:%02x, v:%02x => ",
BusInterruptLevel,BusInterruptVector);
#endif
*Affinity = 1;
switch (InterfaceType) {
case ProcessorInternal:
//
// Handle the internal defined for the processor itself
// and used to control the performance counters and
// correctable errors in the 21064.
//
Vector = HalpGet21064PerformanceVector(BusInterruptLevel,Irql);
if (Vector != 0) {
#if DBG
DbgPrint("PIperf: i:%02x, v:%02x >.", Vector, *Irql);
#endif
return Vector; // Performance counter interrupt
}
Vector = HalpGet21064CorrectableVector( BusInterruptLevel,Irql);
if (Vector != 0) {
#if DBG
DbgPrint("PIcorr: i:%02x, v:%02x >.", Vector, *Irql);
#endif
return Vector; // Correctable error interrupt
}
// Check for unrecognized processor interrupt.
//
if (Vector == 0) {
*Irql = 0;
*Affinity = 0;
}
#if DBG
DbgPrint("PI: i:00, v:00 >.");
#endif
return Vector; // zero if unrecognized interrupt
case Internal:
//
// This bus type is for things connected to the processor
// in some way other than a standard bus, e.g., (E)ISA, PCI.
// Since devices on this "bus," apart from the special case of
// the processor, above, interrupt via the 82c59 cascade in the
// ESC, we assign vectors based on (E)ISA_VECTORS - see below.
// Firmware must agree on these vectors, as it puts them in
// the CDS.
//
// Assume interrupt can be mapped to Lego System Management.
// [wem] ??? check this ?
//
*Irql = SERVER_MGMT_LEVEL;
// The vector is equal to the specified bus level plus
// SERVER_MGMT_VECTORS.
//
#if DBG
DbgPrint("SM: i:%02x, v:%02x >.",
SERVER_MGMT_LEVEL,
BusInterruptLevel + SERVER_MGMT_VECTORS);
#endif
return(BusInterruptLevel + SERVER_MGMT_VECTORS);
case PCIBus:
//[wem] if interrupt accelerator is enabled, direct
// PCI interrupts via the PCI_DEVICE_VECTORS
// Otherwise, fall into the ISA case...
//
if (HalpLegoPciRoutingType == PCI_INTERRUPT_ROUTING_FULL) {
//
// All PCI devices coming in on same CPU IRQ pin
//
*Irql = PCI_DEVICE_LEVEL;
//
// The vector is equal to the specified bus level
// plus the PCI Device Vector base
//
#if DBG
DbgPrint("PCI: i:%02x, v:%02x >.",
PCI_DEVICE_LEVEL,
BusInterruptLevel + PCI_DEVICE_VECTORS);
#endif
return((BusInterruptLevel) + PCI_DEVICE_VECTORS);
#if DBG
} else {
//
// Fall into ISA interrupt handling code
//
DbgPrint("PCI*");
#endif
}
case Isa:
//
// Assumes all ISA devices coming in on same pin
//
*Irql = ISA_DEVICE_LEVEL;
//
// The vector is equal to the specified bus level plus
// the ISA_VECTOR. This is assuming that the ISA levels
// not assigned Interrupt Levels in the Beta programming
// guide are unused in the LCA system. Otherwise, need
// a different encoding scheme.
//
// Not all interrupt levels are actually supported on Beta;
// Should we make some of them illegal here?
//
#if DBG
DbgPrint("ISA: i:%02x, v:%02x >.",
ISA_DEVICE_LEVEL,
BusInterruptLevel + ISA_DEVICE_VECTORS);
#endif
return(BusInterruptLevel + ISA_DEVICE_VECTORS);
case Eisa:
//[wem] Should never occur
//
// Assumes all EISA devices coming in on same pin
//
*Irql = EISA_DEVICE_LEVEL;
//
// The vector is equal to the specified bus level plus the EISA_VECTOR.
//
return(BusInterruptLevel + EISA_VECTORS);
default:
//
// Not an interface supported on Lego systems
//
#if DBG
DbgPrint("LGSYSINT: InterfaceType (%d) not supported.\n",
InterfaceType);
#endif
#if DBG
DbgPrint("?: i:00, v:00 >.");
#endif
*Irql = 0;
*Affinity = 0;
return(0);
} //end switch(InterfaceType)
}
VOID
HalRequestIpi (
IN ULONG Mask
)
/*++
Routine Description:
This routine requests an interprocessor interrupt on a set of processors.
This routine performs no function on an Avanti because it is a
uni-processor system.
Arguments:
Mask - Supplies the set of processors that are sent an interprocessor
interrupt.
Return Value:
None.
--*/
{
return;
}