455 lines
10 KiB
C
455 lines
10 KiB
C
#ident "@(#) NEC jxsysint.c 1.13 94/11/08 16:20:09"
|
|
/*++
|
|
|
|
Copyright (c) 1991-1994 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
jxsysint.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the HAL enable/disable system interrupt, and
|
|
request interprocessor interrupt routines for R98
|
|
|
|
--*/
|
|
|
|
/*
|
|
* Original source: Build Number 1.612
|
|
*
|
|
* Modify for R98(MIPS/R4400)
|
|
*
|
|
***********************************************************************
|
|
*
|
|
* M001 94.03/25-5/31 T.Samezima
|
|
*
|
|
* Change Interrupt control
|
|
* Irql level
|
|
*
|
|
* Add Correspond to PCIBus
|
|
* Exchange mask data
|
|
* define table of ipi interrupt request
|
|
*
|
|
* Del #ifdef DUO
|
|
*
|
|
***********************************************************************
|
|
*
|
|
* S002 94.06/02 T.Samezima
|
|
*
|
|
* Add HalGetInterruptVector
|
|
*
|
|
***********************************************************************
|
|
*
|
|
* S003 94,6/10 T.Samezima
|
|
*
|
|
* Del Compile err
|
|
*
|
|
***********************************************************************
|
|
*
|
|
* S004 94,7/5 T.Samezima
|
|
*
|
|
* Chg Mask value
|
|
* Maximun EISA vecter
|
|
*
|
|
***********************************************************************
|
|
*
|
|
* S005 94,7/8 T.Samezima
|
|
*
|
|
* Chg Maximun EISA vecter
|
|
*
|
|
***********************************************************************
|
|
*
|
|
* S006 94,7/21 T.Samezima
|
|
*
|
|
* Chg Fixd to PCI
|
|
*
|
|
*
|
|
***********************************************************************
|
|
*
|
|
* S007 94,8/22 T.Samezima on SNES
|
|
*
|
|
* Chg Designate member
|
|
*
|
|
***********************************************************************
|
|
*
|
|
* K001 94/09/26 N.Kugimoto
|
|
* Mov Move Source code to r98busdat.c
|
|
***********************************************************************
|
|
*
|
|
* S008 94/09/30 T.Samezima
|
|
*
|
|
* Bug Miss define of PCI Interrupt vector.
|
|
*
|
|
* S009 94/11/08 T.Samezima
|
|
* Bug Miss define of IpiRequestMask.
|
|
*
|
|
*
|
|
*/
|
|
|
|
#include "halp.h"
|
|
|
|
/* Start M001 */
|
|
//
|
|
// Define Ipi Interrupt Reqest value table.
|
|
//
|
|
/* Start S003 */
|
|
ULONG HalpIpiIntRequestMask[] = {
|
|
IntIR_REQUEST_IPI | (0x00 << IntIR_CPU3_BIT) , // 0000 -> 0000
|
|
IntIR_REQUEST_IPI | (0x08 << IntIR_CPU3_BIT) , // 0001 -> 1000
|
|
IntIR_REQUEST_IPI | (0x04 << IntIR_CPU3_BIT) , // 0010 -> 0100
|
|
IntIR_REQUEST_IPI | (0x0c << IntIR_CPU3_BIT) , // 0011 -> 1100
|
|
IntIR_REQUEST_IPI | (0x02 << IntIR_CPU3_BIT) , // 0100 -> 0010
|
|
IntIR_REQUEST_IPI | (0x0a << IntIR_CPU3_BIT) , // 0101 -> 1010
|
|
IntIR_REQUEST_IPI | (0x06 << IntIR_CPU3_BIT) , // 0110 -> 0110
|
|
IntIR_REQUEST_IPI | (0x0e << IntIR_CPU3_BIT) , // 0111 -> 1110
|
|
IntIR_REQUEST_IPI | (0x01 << IntIR_CPU3_BIT) , // 1000 -> 0001
|
|
IntIR_REQUEST_IPI | (0x09 << IntIR_CPU3_BIT) , // 1001 -> 1001
|
|
IntIR_REQUEST_IPI | (0x05 << IntIR_CPU3_BIT) , // 1010 -> 0101
|
|
IntIR_REQUEST_IPI | (0x0d << IntIR_CPU3_BIT) , // 1011 -> 1101
|
|
IntIR_REQUEST_IPI | (0x03 << IntIR_CPU3_BIT) , // 1100 -> 0011 // S009
|
|
IntIR_REQUEST_IPI | (0x0b << IntIR_CPU3_BIT) , // 1101 -> 1011
|
|
IntIR_REQUEST_IPI | (0x07 << IntIR_CPU3_BIT) , // 1110 -> 0111
|
|
IntIR_REQUEST_IPI | (0x0f << IntIR_CPU3_BIT) // 1111 -> 1111
|
|
};
|
|
/* End S003 */
|
|
/* End M001 */
|
|
|
|
|
|
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 and acquire device enable spinlock.
|
|
//
|
|
|
|
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
|
KiAcquireSpinLock(&HalpSystemInterruptLock);
|
|
|
|
//
|
|
// If the vector number is within the range of builtin devices, then
|
|
// disable the builtin device interrupt.
|
|
//
|
|
|
|
if ((Vector >= (DEVICE_VECTORS + 1)) && (Vector <= MAXIMUM_BUILTIN_VECTOR)) {
|
|
HalpBuiltinInterruptEnable &= ~(1 << (Vector - DEVICE_VECTORS - 1));
|
|
/* Start M001 */
|
|
WRITE_REGISTER_ULONG( &( LR_CONTROL2 )->iREN,
|
|
HalpBuiltinInterruptEnable);
|
|
/* End M001 */
|
|
}
|
|
|
|
//
|
|
// If the vector number is within the range of the EISA interrupts, then
|
|
// disable the EISA interrrupt.
|
|
//
|
|
|
|
/* Start M001 */
|
|
/* Start S003 */
|
|
if (Vector >= EISA_VECTORS &&
|
|
Vector <= MAXIMUM_EISA_VECTORS && // S004
|
|
Irql == INT1_LEVEL) {
|
|
HalpDisableEisaInterrupt(Vector);
|
|
}
|
|
/* End S003 */
|
|
|
|
//
|
|
// If the vector number is within the range of the PCI interrupts, then
|
|
// disable the PCI interrrupt.
|
|
//
|
|
|
|
/* Start S006 */
|
|
if (Vector == PCI_DEVICE_VECTOR && Irql == INT1_LEVEL) {
|
|
HalpDisablePciInterrupt(Vector);
|
|
}
|
|
/* End S006 */
|
|
/* End M001 */
|
|
|
|
//
|
|
// Release the device enable spin loc and 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 and acquire device enable spinlock.
|
|
//
|
|
|
|
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
|
KiAcquireSpinLock(&HalpSystemInterruptLock);
|
|
|
|
//
|
|
// If the vector number is within the range of builtin devices, then
|
|
// enable the builtin device interrupt.
|
|
//
|
|
|
|
if ((Vector >= (DEVICE_VECTORS + 1)) && (Vector <= MAXIMUM_BUILTIN_VECTOR)) {
|
|
HalpBuiltinInterruptEnable |= (1 << (Vector - DEVICE_VECTORS - 1));
|
|
/* Start M001 */
|
|
WRITE_REGISTER_ULONG( &( LR_CONTROL2 )->iREN,
|
|
HalpBuiltinInterruptEnable);
|
|
/* End M001 */
|
|
}
|
|
|
|
//
|
|
// If the vector number is within the range of the EISA interrupts, then
|
|
// enable the EISA interrrupt and set the Level/Edge register.
|
|
//
|
|
|
|
/* Start M001 */
|
|
/* Start S003 */
|
|
if (Vector >= EISA_VECTORS &&
|
|
Vector <= MAXIMUM_EISA_VECTORS && // S005
|
|
Irql == INT1_LEVEL) {
|
|
HalpEnableEisaInterrupt( Vector, InterruptMode);
|
|
}
|
|
/* End S003 */
|
|
|
|
//
|
|
// If the vector number is within the range of the PCI interrupts, then
|
|
// disable the PCI interrrupt.
|
|
//
|
|
|
|
/* Start S006 */
|
|
if (Vector == PCI_DEVICE_VECTOR && Irql == INT1_LEVEL) {
|
|
HalpEnablePciInterrupt(Vector);
|
|
}
|
|
/* End S006 */
|
|
/* End M001 */
|
|
|
|
//
|
|
// Release the device enable spin loc and lower IRQL to the previous level.
|
|
//
|
|
|
|
KiReleaseSpinLock(&HalpSystemInterruptLock);
|
|
KeLowerIrql(OldIrql);
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
HalRequestIpi (
|
|
IN ULONG Mask
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine requests an interprocessor interrupt on a set of processors.
|
|
|
|
N.B. This routine must ensure that the interrupt is posted at the target
|
|
processor(s) before returning.
|
|
|
|
Arguments:
|
|
|
|
Mask - Supplies the set of processors that are sent an interprocessor
|
|
interrupt.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
/* Start M001 */
|
|
ULONG buffer;
|
|
/* End M001 */
|
|
|
|
//
|
|
// Request an interprocessor interrupt on each of the specified target
|
|
// processors.
|
|
//
|
|
|
|
/* Start M001 */
|
|
buffer = HalpIpiIntRequestMask[(Mask & 0xf)] | // S004
|
|
( (((PCR->Prcb)->Number) & 0x3) << IntIR_CODE_BIT );
|
|
WRITE_REGISTER_ULONG( &( PMC_CONTROL1 )->IntIR.Long, buffer); // S007
|
|
/* End M001 */
|
|
|
|
return;
|
|
}
|
|
|
|
#if 0 //K001
|
|
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.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
//
|
|
// N.B. On Jazz systems which are single processor systems, all interrupts
|
|
// go to processor 0. On Duo systems both processors could handle
|
|
// interrupts, but the hardware does not arbitrate and distribute
|
|
// interrupts, and therefore, both processors would get all interrupts.
|
|
//
|
|
|
|
*Affinity = 1;
|
|
|
|
//
|
|
// If this is for the internal bus then just return the passed parameter.
|
|
//
|
|
|
|
if (InterfaceType == Internal) {
|
|
|
|
//
|
|
// Return the passed parameters.
|
|
//
|
|
|
|
*Irql = (KIRQL)BusInterruptLevel;
|
|
/* Start S002 */
|
|
return(BusInterruptVector + DEVICE_VECTORS);
|
|
/* End S002 */
|
|
}
|
|
|
|
/* Start S002 */
|
|
//
|
|
// If this is for the pci bus then just return the passed parameter.
|
|
//
|
|
|
|
if (InterfaceType == PCIBus) {
|
|
|
|
//
|
|
// Return the passed parameters.
|
|
//
|
|
|
|
*Irql = INT1_LEVEL;
|
|
return(PCI_DEVICE_VECTOR); // S008
|
|
}
|
|
/* End S002 */
|
|
|
|
if (InterfaceType != Isa && InterfaceType != Eisa) {
|
|
|
|
//
|
|
// Not on this system return nothing.
|
|
//
|
|
|
|
*Affinity = 0;
|
|
*Irql = 0;
|
|
return(0);
|
|
|
|
}
|
|
|
|
//
|
|
// Jazz and Duo only have one I/O bus which is an EISA, so the bus
|
|
// number and the bus interrupt vector are unused.
|
|
//
|
|
// The IRQL level is always equal to the EISA level.
|
|
//
|
|
|
|
/* Start S001 */
|
|
*Irql = INT1_LEVEL;
|
|
/* End S001 */
|
|
|
|
//
|
|
// Bus interrupt level 2 is actually mapped to bus level 9 in the Eisa
|
|
// hardware.
|
|
//
|
|
|
|
if (BusInterruptLevel == 2) {
|
|
BusInterruptLevel = 9;
|
|
}
|
|
|
|
//
|
|
// The vector is equal to the specified bus level plus the EISA_VECTOR.
|
|
//
|
|
|
|
return(BusInterruptLevel + EISA_VECTORS);
|
|
}
|
|
|
|
#endif
|