mirror of https://github.com/lianthony/NT4.0
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.
380 lines
9.5 KiB
380 lines
9.5 KiB
#pragma comment(exestr, "$Header: /usr4/winnt/SOURCES/ddk351/src/hal/halsni4x/mips/RCS/jxsysint.c,v 1.1 1995/05/19 11:20:52 flo Exp $")
|
|
/*++
|
|
|
|
Copyright (c) 1993-94 Siemens Nixdorf Informationssysteme AG
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
jxsysint.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the HAL enable/disable system interrupt, and
|
|
request interprocessor interrupt routines for a MIPS R3000 or R4000
|
|
SNI system.
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
--*/
|
|
|
|
#include "halp.h"
|
|
|
|
|
|
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);
|
|
KiAcquireSpinLock(&HalpSystemInterruptLock);
|
|
|
|
|
|
//
|
|
// If the vector number is within the range of the onboard interrupts, then
|
|
// disable the onboard interrrupt.
|
|
// This may be an Isa (Desktop) or Isa/Eisa (Minitower) Interrupt
|
|
//
|
|
|
|
if (Vector >= ONBOARD_VECTORS &&
|
|
Vector <= MAXIMUM_ONBOARD_VECTOR &&
|
|
Irql == EISA_DEVICE_LEVEL) {
|
|
HalpDisableOnboardInterrupt(Vector);
|
|
}
|
|
|
|
|
|
//
|
|
// If the vector number is within the range of the EISA interrupts, then
|
|
// disable the EISA interrrupt on the Eisa Backplane (Eisa Extension).
|
|
//
|
|
|
|
else if (Vector >= EISA_VECTORS &&
|
|
Vector <= MAXIMUM_EISA_VECTOR &&
|
|
Irql == EISA_DEVICE_LEVEL) {
|
|
|
|
HalpDisableEisaInterrupt(Vector);
|
|
}
|
|
|
|
//
|
|
// Lower IRQL to the previous level.
|
|
//
|
|
|
|
KiReleaseSpinLock(&HalpSystemInterruptLock);
|
|
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
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
KIRQL OldIrql;
|
|
|
|
//
|
|
// Raise IRQL to the highest level.
|
|
//
|
|
|
|
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
|
KiAcquireSpinLock(&HalpSystemInterruptLock);
|
|
|
|
//
|
|
// If the vector number is within the range of the onboard interrupts, then
|
|
// enable the onboard interrrupt and set the Level/Edge register to latched,
|
|
// because the onboard Opti 499 (Desktop)is a real Isa Controler and cannot share interrupts.
|
|
// even the i82350 Chipset on the Minitower cannot share interrupts (why ?)
|
|
//
|
|
|
|
if (Vector >= ONBOARD_VECTORS &&
|
|
Vector <= MAXIMUM_ONBOARD_VECTOR &&
|
|
Irql == EISA_DEVICE_LEVEL) {
|
|
|
|
if (HalpIsRM200)
|
|
//
|
|
// the RM200 has an Opti 499 Chip, which is an "real" Isa Chipset
|
|
// so we cannot support Level sensitive Interrupts ...
|
|
//
|
|
|
|
HalpEnableOnboardInterrupt( Vector, Latched);
|
|
else
|
|
HalpEnableOnboardInterrupt( Vector, InterruptMode);
|
|
}
|
|
|
|
//
|
|
// If the vector number is within the range of the EISA interrupts, then
|
|
// enable the EISA interrrupt in the Eisa Backplane (Eisa Extension) and set the Level/Edge register.
|
|
//
|
|
|
|
else if (Vector >= EISA_VECTORS &&
|
|
Vector <= MAXIMUM_EISA_VECTOR &&
|
|
Irql == EISA_DEVICE_LEVEL) {
|
|
HalpEnableEisaInterrupt( Vector, InterruptMode);
|
|
}
|
|
|
|
//
|
|
// Lower IRQL to the previous level.
|
|
//
|
|
|
|
KiReleaseSpinLock(&HalpSystemInterruptLock);
|
|
KeLowerIrql(OldIrql);
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
ULONG
|
|
HalGetInterruptVector(
|
|
IN INTERFACE_TYPE InterfaceType,
|
|
IN ULONG BusNumber,
|
|
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.
|
|
|
|
Arguments:
|
|
|
|
InterfaceType - Supplies the type of bus which the vector is for.
|
|
|
|
BusNumber - Supplies the bus number for the device.
|
|
|
|
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.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
|
|
*Affinity = 1;
|
|
|
|
//
|
|
// If this is for the internal bus then just return the passed parameter.
|
|
//
|
|
|
|
if (InterfaceType == Internal) {
|
|
|
|
if (BusInterruptVector >= ONBOARD_VECTORS &&
|
|
BusInterruptVector <= MAXIMUM_ONBOARD_VECTOR ) {
|
|
|
|
//
|
|
// this is one of the onboard components of the PC core
|
|
// (floppy, serial, parallel, mouse etc.)
|
|
// they should be configured in the Firmware tree with an Offset of
|
|
// ONBOARD_VECTORS (e.g. 0x10 to make them different to the real onboard components
|
|
// like scsi or ethernet) and with an Irql of EISA_DEVICE_LEVEL (actually 4)
|
|
// we need Firmware release 1.04 or later ...
|
|
//
|
|
|
|
//
|
|
// Bus interrupt vector 2 of Onboard PC core interrupts is actually mapped to
|
|
// vector 9 in the Isa/Eisa hardware.
|
|
//
|
|
|
|
if (BusInterruptVector == ONBOARD_VECTORS + 2) {
|
|
BusInterruptVector = ONBOARD_VECTORS + 9;
|
|
}
|
|
|
|
//
|
|
// The IRQL level is always equal to the EISA level.
|
|
//
|
|
|
|
*Irql = EISA_DEVICE_LEVEL;
|
|
|
|
return(BusInterruptVector);
|
|
}
|
|
|
|
//
|
|
// these are the "real" Onboard components (scsi and Ethernet)
|
|
// Return the passed parameters.
|
|
//
|
|
|
|
*Irql = (KIRQL) BusInterruptLevel;
|
|
|
|
//
|
|
// this is the special case of the onboard Ethernet Controller
|
|
// At CPU Modules with an R4400 PC this goes directly to corresponding
|
|
// Cause Register Bit IP7 (bad bad ..)
|
|
// on MUltiPro machines this IP7 is used for IPI Interrupts so we have to
|
|
// manipulate this.
|
|
//
|
|
|
|
if (BusInterruptVector == NET_DEFAULT_VECTOR){
|
|
|
|
extern BOOLEAN HalpProcPc;
|
|
//
|
|
// the RM200 and all SC machines have a central Device Interrupt
|
|
// which is software managed by this HAL ...
|
|
// leave al other cases as they are ...
|
|
//
|
|
|
|
if ( ((HalpProcPc == FALSE) && (HalpProcessorId != ORIONSC)) || (HalpMainBoard==M8036)) {
|
|
|
|
if (HalpProcessorId == MPAGENT) {
|
|
|
|
BusInterruptVector = NET_LEVEL;
|
|
*Irql = (KIRQL) NETMULTI_LEVEL;
|
|
*Affinity = 1 << HalpNetProcessor; // proc 1 if started
|
|
|
|
} else {
|
|
|
|
BusInterruptVector = NET_LEVEL;
|
|
|
|
//
|
|
// Irql is equal to the most common Device Interrupt Level
|
|
// (currently 4)
|
|
//
|
|
|
|
*Irql = (KIRQL) SCSIEISA_LEVEL;
|
|
}
|
|
|
|
}
|
|
|
|
return ( BusInterruptVector);
|
|
}
|
|
|
|
//
|
|
// this is another special case of the EIP Interrupt for RM400 Tower
|
|
// we have an agreement with the EIP developer
|
|
// we meet each other on InterruptVector 15, so we limit the Irql to Device Level
|
|
//
|
|
|
|
if ( (HalpMainBoard==M8032) && (BusInterruptVector == EIP_VECTOR) ){
|
|
|
|
//
|
|
// Irql is equal to the most common Device Interrupt Level
|
|
// (currently 4)
|
|
//
|
|
|
|
if (HalpProcessorId == MPAGENT) *Irql = (KIRQL) INT3_LEVEL; else *Irql = (KIRQL) SCSIEISA_LEVEL;
|
|
|
|
}
|
|
|
|
return(BusInterruptVector);
|
|
}
|
|
|
|
if (InterfaceType != Isa && InterfaceType != Eisa) {
|
|
|
|
//
|
|
// Not on this system return nothing.
|
|
//
|
|
|
|
*Affinity = 0;
|
|
*Irql = 0;
|
|
return(0);
|
|
}
|
|
|
|
//
|
|
// Isa/Eisa Interrupts which are not configured in the Firmware
|
|
// (boards should be located in the Expansion Slots ...)
|
|
// The IRQL level is always equal to the EISA level.
|
|
// WARNING: some driver call HalGetInterruptVector
|
|
// with the BusInterruptLevel == BusInterruptVector
|
|
// but some call it with different values.
|
|
// In this part of the source tree we match the Jazz reference
|
|
// sources (see Internal handling; which is different)
|
|
//
|
|
|
|
*Irql = EISA_DEVICE_LEVEL;
|
|
|
|
//
|
|
// Bus interrupt 2 is actually mapped to bus interrupt 9 in the Isa/Eisa
|
|
// hardware.
|
|
//
|
|
|
|
if (BusInterruptLevel == 2) {
|
|
BusInterruptLevel = 9;
|
|
}
|
|
|
|
//
|
|
// The vector is equal to the specified bus level plus the ONBOARD/EISA_VECTORS.
|
|
// in any case the interrupt vector for Isa or Eisa card has to be on the
|
|
// Backplane, so if an Eisa Extension is installed this is an Eisa Interrupt
|
|
//
|
|
|
|
if (HalpEisaExtensionInstalled ) {
|
|
return( BusInterruptLevel + EISA_VECTORS);
|
|
} else
|
|
|
|
//
|
|
// if there is no Eisa Extension installed
|
|
// all Isa/Eisa Interrupts should be handled by the onboard PC core
|
|
//
|
|
|
|
return(BusInterruptLevel + ONBOARD_VECTORS);
|
|
|
|
}
|