|
|
/*++
Copyright (c) 1993 Digital Equipment Corporation
Module Name:
mkinitnt.c
Abstract:
This module implements the HAL enable/disable system interrupt, and request interprocessor interrupt routines for the Mikasa system.
Author:
Joe Notarangelo 25-Oct-1993
Environment:
Kernel mode
Revision History:
James Livingston 29-Apr-1994 Adapted from Avanti module for Mikasa.
Janet Schneider (Digital) 27-July-1995 Added support for the Noritake.
--*/
#include "halp.h"
#include "mikasa.h"
#include "axp21064.h"
//
// Function prototype
//
VOID HalpDisableMikasaPciInterrupt( IN ULONG Vector );
VOID HalpDisableNoritakePciInterrupt( IN ULONG Vector );
VOID HalpEnableMikasaPciInterrupt( IN ULONG Vector, IN KINTERRUPT_MODE InterruptMode );
VOID HalpEnableNoritakePciInterrupt( IN ULONG Vector, IN KINTERRUPT_MODE InterruptMode );
VOID HalpSetMachineCheckEnables( IN BOOLEAN DisableMachineChecks, IN BOOLEAN DisableProcessorCorrectables, IN BOOLEAN DisableSystemCorrectables );
//
// Define reference to the builtin device interrupt enables.
//
extern USHORT HalpBuiltinInterruptEnable;
//
// Define reference to platform identifier
//
extern BOOLEAN HalpNoritakePlatform;
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.
--*/
{
KIRQL OldIrql;
//
// Raise IRQL to the highest level.
//
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
//
// If the vector number is within the range of the EISA interrupts, then
// disable the EISA interrrupt.
//
if (Vector >= EISA_VECTORS && Vector < MAXIMUM_EISA_VECTOR && Irql == EISA_DEVICE_LEVEL) { HalpDisableEisaInterrupt(Vector); }
//
// If the vector number is within the range of the PCI interrupts, then
// disable the PCI interrrupt.
//
if (Vector >= PCI_VECTORS && Vector < MAXIMUM_PCI_VECTOR && Irql == PCI_DEVICE_LEVEL) {
if( HalpNoritakePlatform ) {
HalpDisableNoritakePciInterrupt(Vector);
} else {
HalpDisableMikasaPciInterrupt(Vector);
}
}
//
// If the vector is a performance counter vector or one of the internal
// device vectors then disable the interrupt for the 21064.
//
switch (Vector) {
//
// Performance counter 0 interrupt (internal to 21064)
//
case PC0_VECTOR: case PC0_SECONDARY_VECTOR:
HalpDisable21064PerformanceInterrupt( PC0_VECTOR ); break;
//
// Performance counter 1 interrupt (internal to 21064)
//
case PC1_VECTOR: case PC1_SECONDARY_VECTOR:
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 ); } break;
} //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; KIRQL OldIrql;
//
// Raise IRQL to the highest level.
//
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
//
// If the vector number is within the range of the EISA interrupts, then
// enable the EISA interrrupt and set the Level/Edge register.
//
if (Vector >= EISA_VECTORS && Vector < MAXIMUM_EISA_VECTOR && Irql == EISA_DEVICE_LEVEL) { HalpEnableEisaInterrupt( Vector, InterruptMode ); Enabled = TRUE; }
//
// If the vector number is within the range of the PCI interrupts, then
// enable the PCI interrrupt.
//
if (Vector >= PCI_VECTORS && Vector < MAXIMUM_PCI_VECTOR && Irql == PCI_DEVICE_LEVEL) {
if( HalpNoritakePlatform ) {
HalpEnableNoritakePciInterrupt( Vector, InterruptMode );
} else {
HalpEnableMikasaPciInterrupt( Vector, InterruptMode );
}
Enabled = TRUE; }
//
// If the vector is a performance counter vector or one of the
// internal device vectors then perform 21064-specific enable.
//
switch (Vector) {
//
// Performance counter 0 (internal to 21064)
//
case PC0_VECTOR: case PC0_SECONDARY_VECTOR:
HalpEnable21064PerformanceInterrupt( PC0_VECTOR, Irql ); Enabled = TRUE; break;
//
// Performance counter 1 (internal to 21064)
//
case PC1_VECTOR: case PC1_SECONDARY_VECTOR:
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 ); }
Enabled = TRUE; break;
} //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 EISA and ISA are the same as the InterruptLevel, so ignore.
jwlfix - How does the above apply to PCI when it's done as in Mikasa? I've made the assumption the the same is true, but that must be checked.
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;
*Affinity = 1;
switch (InterfaceType) {
case ProcessorInternal:
//
// Handle the internal defined for the processor itself
// and used to control the performance counters in the 21064.
//
if( (Vector = HalpGet21064PerformanceVector( BusInterruptLevel, Irql)) != 0 ){
//
// Performance counter was successfully recognized.
//
*Affinity = HalpActiveProcessors; return Vector;
} else if ((Vector = HalpGet21064CorrectableVector( BusInterruptLevel, Irql)) != 0 ){ //
// Correctable error interrupt was sucessfully recognized.
//
*Affinity = 1; return Vector;
} else {
//
// Unrecognized processor interrupt.
//
*Irql = 0; *Affinity = 0; return 0;
} //end if Vector
break;
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.
//
*Irql = ISA_DEVICE_LEVEL;
return(BusInterruptLevel + ISA_VECTORS); break;
case Isa:
//
// Assumes all ISA devices coming in on same processor pin
//
*Irql = ISA_DEVICE_LEVEL;
//
// The vector is equal to the specified bus level plus ISA_VECTORS.
// N.B.: this encoding technique uses the notion of defining a
// base interrupt vector in the space defined by the constant,
// ISA_VECTORS, which may or may not differ from EISA_VECTORS or
// PCI_VECTORS.
//
return(BusInterruptLevel + ISA_VECTORS); break;
case Eisa:
//
// Assumes all EISA devices coming in on same processor pin
//
*Irql = EISA_DEVICE_LEVEL;
//
// The vector is equal to the specified bus level plus the EISA_VECTOR.
//
return(BusInterruptLevel + EISA_VECTORS); break;
case PCIBus:
//
// Assumes all PCI devices coming in on same processor pin
//
*Irql = PCI_DEVICE_LEVEL;
//
// The vector is equal to the specified bus level plus the PCI_VECTOR
//
return((BusInterruptLevel) + PCI_VECTORS);
break;
default:
//
// Not an interface supported on Mikasa systems.
//
#if defined(HALDBG)
DbgPrint("MKSYSINT: InterfaceType (%d) not supported on Mikasa\r\n", InterfaceType); #endif
*Irql = 0; *Affinity = 0; return(0); break;
} //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 Mikasa because it is a uni-processor system.
Arguments:
Mask - Supplies the set of processors that are sent an interprocessor interrupt.
Return Value:
None.
--*/
{ return; }
|