NT4/private/ntos/nthals/halr98mp/mips/jxsysint.c
2020-09-30 17:12:29 +02:00

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