mirror of
https://github.com/reactos/reactos.git
synced 2025-08-09 07:53:00 +00:00
[HAL] Implement IPI support functions
This commit is contained in:
parent
4bccb6e6c9
commit
40b6b1dab3
7 changed files with 270 additions and 11 deletions
|
@ -106,14 +106,6 @@ ApicRequestGlobalInterrupt(
|
|||
|
||||
/* SMP SUPPORT FUNCTIONS ******************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpRequestIpi(_In_ KAFFINITY TargetProcessors)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
VOID
|
||||
ApicStartApplicationProcessor(
|
||||
_In_ ULONG NTProcessorNumber,
|
||||
|
@ -138,3 +130,172 @@ ApicStartApplicationProcessor(
|
|||
ApicRequestGlobalInterrupt(HalpProcessorIdentity[NTProcessorNumber].LapicId, (StartupLoc.LowPart) >> 12,
|
||||
APIC_MT_Startup, APIC_TGM_Edge, APIC_DSH_Destination);
|
||||
}
|
||||
|
||||
/* HAL IPI FUNCTIONS **********************************************************/
|
||||
|
||||
/*!
|
||||
* \brief Broadcasts an IPI with a specified vector to all processors.
|
||||
*
|
||||
* \param Vector - Specifies the interrupt vector to be delivered.
|
||||
* \param IncludeSelf - Specifies whether to include the current processor.
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
HalpBroadcastIpiSpecifyVector(
|
||||
_In_ UCHAR Vector,
|
||||
_In_ BOOLEAN IncludeSelf)
|
||||
{
|
||||
APIC_DSH DestinationShortHand = IncludeSelf ?
|
||||
APIC_DSH_AllIncludingSelf : APIC_DSH_AllExcludingSelf;
|
||||
|
||||
/* Request the interrupt targeted at all processors */
|
||||
ApicRequestGlobalInterrupt(0, // Ignored
|
||||
Vector,
|
||||
APIC_MT_Fixed,
|
||||
APIC_TGM_Edge,
|
||||
DestinationShortHand);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Requests an IPI with a specified vector on the specified processors.
|
||||
*
|
||||
* \param TargetSet - Specifies the set of processors to send the IPI to.
|
||||
* \param Vector - Specifies the interrupt vector to be delivered.
|
||||
*
|
||||
* \remarks This function is exported on Windows 10.
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
HalRequestIpiSpecifyVector(
|
||||
_In_ KAFFINITY TargetSet,
|
||||
_In_ UCHAR Vector)
|
||||
{
|
||||
KAFFINITY ActiveProcessors = KeQueryActiveProcessors();
|
||||
KAFFINITY RemainingSet, SetMember;
|
||||
ULONG ProcessorIndex;
|
||||
ULONG LApicId;
|
||||
|
||||
/* Sanitize the target set */
|
||||
TargetSet &= ActiveProcessors;
|
||||
|
||||
/* Check if all processors are requested */
|
||||
if (TargetSet == ActiveProcessors)
|
||||
{
|
||||
/* Send an IPI to all processors, including this processor */
|
||||
HalpBroadcastIpiSpecifyVector(Vector, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if all processors except the current one are requested */
|
||||
if (TargetSet == (ActiveProcessors & ~KeGetCurrentPrcb()->SetMember))
|
||||
{
|
||||
/* Send an IPI to all processors, excluding this processor */
|
||||
HalpBroadcastIpiSpecifyVector(Vector, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Loop while we have more processors */
|
||||
RemainingSet = TargetSet;
|
||||
while (RemainingSet != 0)
|
||||
{
|
||||
NT_VERIFY(BitScanForwardAffinity(&ProcessorIndex, RemainingSet) != 0);
|
||||
ASSERT(ProcessorIndex < KeNumberProcessors);
|
||||
SetMember = AFFINITY_MASK(ProcessorIndex);
|
||||
RemainingSet &= ~SetMember;
|
||||
|
||||
/* Send the interrupt to the target processor */
|
||||
LApicId = HalpProcessorIdentity[ProcessorIndex].LapicId;
|
||||
ApicRequestGlobalInterrupt(LApicId,
|
||||
Vector,
|
||||
APIC_MT_Fixed,
|
||||
APIC_TGM_Edge,
|
||||
APIC_DSH_Destination);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Requests an IPI interrupt on the specified processors.
|
||||
*
|
||||
* \param TargetSet - Specifies the set of processors to send the IPI to.
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
HalpRequestIpi(
|
||||
_In_ KAFFINITY TargetSet)
|
||||
{
|
||||
/* Request the IPI vector */
|
||||
HalRequestIpiSpecifyVector(TargetSet, APIC_IPI_VECTOR);
|
||||
}
|
||||
|
||||
#ifdef _M_AMD64
|
||||
|
||||
/*!
|
||||
* \brief Requests a software interrupt on the specified processors.
|
||||
*
|
||||
* \param TargetSet - Specifies the set of processors to send the IPI to.
|
||||
* \param Irql - Specifies the IRQL of the software interrupt.
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
HalpSendSoftwareInterrupt(
|
||||
_In_ KAFFINITY TargetSet,
|
||||
_In_ KIRQL Irql)
|
||||
{
|
||||
UCHAR Vector;
|
||||
|
||||
/* Get the vector for the requested IRQL */
|
||||
if (Irql == APC_LEVEL)
|
||||
{
|
||||
Vector = APC_VECTOR;
|
||||
}
|
||||
else if (Irql == DISPATCH_LEVEL)
|
||||
{
|
||||
Vector = DISPATCH_VECTOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Request the IPI with the specified vector */
|
||||
HalRequestIpiSpecifyVector(TargetSet, Vector);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Requests an NMI interrupt on the specified processors.
|
||||
*
|
||||
* \param TargetSet - Specifies the set of processors to send the IPI to.
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
HalpSendNMI(
|
||||
_In_ KAFFINITY TargetSet)
|
||||
{
|
||||
KAFFINITY RemainingSet, SetMember;
|
||||
ULONG ProcessorIndex;
|
||||
ULONG LApicId;
|
||||
|
||||
/* Make sure we do not send an NMI to ourselves */
|
||||
ASSERT((TargetSet & ~KeGetCurrentPrcb()->SetMember) == 0);
|
||||
|
||||
/* Loop while we have more processors */
|
||||
RemainingSet = TargetSet;
|
||||
while (RemainingSet != 0)
|
||||
{
|
||||
NT_VERIFY(BitScanForwardAffinity(&ProcessorIndex, RemainingSet) != 0);
|
||||
ASSERT(ProcessorIndex < KeNumberProcessors);
|
||||
SetMember = AFFINITY_MASK(ProcessorIndex);
|
||||
RemainingSet &= ~SetMember;
|
||||
|
||||
/* Send and NMI to the target processor */
|
||||
LApicId = HalpProcessorIdentity[ProcessorIndex].LapicId;
|
||||
ApicRequestGlobalInterrupt(LApicId,
|
||||
0,
|
||||
APIC_MT_NMI,
|
||||
APIC_TGM_Edge,
|
||||
APIC_DSH_Destination);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _M_AMD64
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue