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.
323 lines
6.0 KiB
323 lines
6.0 KiB
/*++
|
|
|
|
Copyright (c) 1991-1993 Microsoft Corporation
|
|
|
|
Copyright (c) 1994 MOTOROLA, INC. All Rights Reserved. This file
|
|
contains copyrighted material. Use of this file is restricted
|
|
by the provisions of a Motorola Software License Agreement.
|
|
|
|
Module Name:
|
|
|
|
pxmpint.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the HAL enable/disable system interrupt, and
|
|
request interprocessor interrupt routines for a Power PC.
|
|
|
|
|
|
Author:
|
|
|
|
David N. Cutler (davec) 6-May-1991
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History:
|
|
|
|
Jim Wooldridge
|
|
|
|
Removed internal interrupt support
|
|
Changed irql mapping
|
|
Removed internal bus support
|
|
Removed EISA, added PCI, PCMCIA, and ISA bus support
|
|
|
|
Steve Johns
|
|
Changed to support Timer 1 as profile interrupt
|
|
Added HalAcknowledgeIpi
|
|
|
|
Peter Johnston
|
|
Added support for MPIC interrupt controller
|
|
|
|
Chris Karamatas
|
|
Fixed Hal(Dis/En)ableSystemInterrupt function
|
|
|
|
Jake Oshins
|
|
Renamed to pxmpint.c from pxsysint.c
|
|
|
|
--*/
|
|
|
|
#include "halp.h"
|
|
#include "pxmp.h"
|
|
#include "pxmpic2.h"
|
|
|
|
#if _MSC_VER >= 1000
|
|
|
|
//
|
|
// VC++ doesn't have the same intrinsics as MCL.
|
|
//
|
|
// Although the MSR is not strictly a SPR, the compiler recognizes
|
|
// all ones (~0) as being the MSR and emits the appropriate code.
|
|
//
|
|
|
|
#define __builtin_set_msr(x) __sregister_set(_PPC_MSR_,x)
|
|
|
|
#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.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
KIRQL OldIrql;
|
|
|
|
//
|
|
// Raise IRQL to the highest level and acquire device enable spinlock.
|
|
//
|
|
|
|
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
|
KiAcquireSpinLock(&HalpSystemInterruptLock);
|
|
|
|
if (Vector >= DEVICE_VECTORS ) {
|
|
if ( Vector < DEVICE_VECTORS + MPIC_BASE_VECTOR ) {
|
|
|
|
HalpDisableSioInterrupt(Vector);
|
|
|
|
} else if ( Vector <= DEVICE_VECTORS + MPIC_MAX_VECTOR ) {
|
|
|
|
HalpDisableMpicInterrupt(Vector);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Release the device enable spin lock 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;
|
|
KINTERRUPT_MODE TranslatedInterruptMode;
|
|
|
|
//
|
|
// Raise IRQL to the highest level and acquire device enable spinlock.
|
|
//
|
|
|
|
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
|
KiAcquireSpinLock(&HalpSystemInterruptLock);
|
|
|
|
if ( Vector >= DEVICE_VECTORS ) {
|
|
if ( Vector < DEVICE_VECTORS + MPIC_BASE_VECTOR ) {
|
|
|
|
//
|
|
// It's an 8259 vector.
|
|
//
|
|
// Get translated interrupt mode
|
|
//
|
|
|
|
|
|
TranslatedInterruptMode = HalpGetInterruptMode(Vector,
|
|
Irql,
|
|
InterruptMode);
|
|
|
|
|
|
HalpEnableSioInterrupt(Vector, TranslatedInterruptMode);
|
|
|
|
} else if ( Vector <= DEVICE_VECTORS + MPIC_MAX_VECTOR ) {
|
|
|
|
HalpEnableMpicInterrupt(Vector);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Release the device enable spin lock 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.
|
|
|
|
Arguments:
|
|
|
|
Mask - Supplies the set of processors that are sent an interprocessor
|
|
interrupt.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
#if defined(_MP_PPC_)
|
|
|
|
extern ULONG Mpic2IpiBugFix;
|
|
extern ULONG HalpPhysicalIpiMask[];
|
|
ULONG BugFix = Mpic2IpiBugFix;
|
|
ULONG PhysicalMask = 0;
|
|
PULONG PhysicalIpiMask = HalpPhysicalIpiMask;
|
|
ULONG OldMsr = __builtin_get_msr();
|
|
|
|
//
|
|
// Request an interprocessor interrupt on each of the specified target
|
|
// processors.
|
|
//
|
|
|
|
__builtin_set_msr(OldMsr & 0xffff7fff); // Disable Interrupts
|
|
|
|
//
|
|
// Mask is a mask of logical CPUs. Convert it to a mask of
|
|
// Physical CPUs so the IPI requests will be distributed
|
|
// properly.
|
|
//
|
|
|
|
do {
|
|
if ( Mask & 1 ) {
|
|
PhysicalMask |= *PhysicalIpiMask;
|
|
}
|
|
PhysicalIpiMask++;
|
|
Mask >>= 1;
|
|
} while ( Mask );
|
|
|
|
//
|
|
// Send the IPI interrupt(s).
|
|
//
|
|
|
|
HALPCR->MpicProcessorBase->Ipi[0 ^ BugFix].SelectProcessor = PhysicalMask;
|
|
|
|
__builtin_set_msr(OldMsr); // Restore previous interrupt
|
|
// setting.
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
BOOLEAN
|
|
HalAcknowledgeIpi (VOID)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine aknowledges an interprocessor interrupt on a set of
|
|
processors.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
TRUE if the IPI is valid; otherwise FALSE is returned.
|
|
|
|
--*/
|
|
|
|
{
|
|
return (TRUE);
|
|
}
|
|
|
|
BOOLEAN
|
|
HalpHandleIpi(
|
|
IN PVOID Unused0,
|
|
IN PVOID Unused1,
|
|
IN PVOID TrapFrame
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is entered as the result of an Inter-Processor Interrupt
|
|
being received by this processor. It passes the request onto the
|
|
kernel.
|
|
|
|
Arguments:
|
|
|
|
Unused0 - Not used.
|
|
Unused1 - Not used.
|
|
TrapFrame - Volatile context at time interrupt occured.
|
|
|
|
Return Value:
|
|
|
|
Returns TRUE (this routine always succeeds).
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
#if defined(_MP_PPC_)
|
|
|
|
KeIpiInterrupt(TrapFrame);
|
|
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|