ReactOS 0.4.17-dev-966-gf06eace
apicsmp.c File Reference
#include <hal.h>
#include "apicp.h"
#include <smp.h>
#include <debug.h>
Include dependency graph for apicsmp.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

FORCEINLINE VOID ApicRequestGlobalInterrupt (_In_ UCHAR DestinationProcessor, _In_ UCHAR Vector, _In_ APIC_MT MessageType, _In_ APIC_TGM TriggerMode, _In_ APIC_DSH DestinationShortHand)
 
VOID ApicStartApplicationProcessor (_In_ ULONG NTProcessorNumber, _In_ PHYSICAL_ADDRESS StartupLoc)
 
VOID NTAPI HalpBroadcastIpiSpecifyVector (_In_ UCHAR Vector, _In_ BOOLEAN IncludeSelf)
 Broadcasts an IPI with a specified vector to all processors.
 
VOID NTAPI HalRequestIpiSpecifyVector (_In_ KAFFINITY TargetSet, _In_ UCHAR Vector)
 Requests an IPI with a specified vector on the specified processors.
 
VOID NTAPI HalpRequestIpi (_In_ KAFFINITY TargetSet)
 Requests an IPI interrupt on the specified processors.
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file apicsmp.c.

Function Documentation

◆ ApicRequestGlobalInterrupt()

FORCEINLINE VOID ApicRequestGlobalInterrupt ( _In_ UCHAR  DestinationProcessor,
_In_ UCHAR  Vector,
_In_ APIC_MT  MessageType,
_In_ APIC_TGM  TriggerMode,
_In_ APIC_DSH  DestinationShortHand 
)
Parameters
Vector- Specifies the interrupt vector to be delivered.
MessageType- Specifies the message type sent to the CPU core interrupt handler. This can be one of the following values: APIC_MT_Fixed - Delivers an interrupt to the target local APIC specified in Destination field. APIC_MT_LowestPriority - Delivers an interrupt to the local APIC executing at the lowest priority of all local APICs. APIC_MT_SMI - Delivers an SMI interrupt to target local APIC(s). APIC_MT_RemoteRead - Delivers a read request to read an APIC register in the target local APIC specified in Destination field. APIC_MT_NMI - Delivers a non-maskable interrupt to the target local APIC specified in the Destination field. Vector is ignored. APIC_MT_INIT - Delivers an INIT request to the target local APIC(s) specified in the Destination field. TriggerMode must be APIC_TGM_Edge, Vector must be 0. APIC_MT_Startup - Delivers a start-up request (SIPI) to the target local APIC(s) specified in Destination field. Vector specifies the startup address. APIC_MT_ExtInt - Delivers an external interrupt to the target local APIC specified in Destination field.
TriggerMode- The trigger mode of the interrupt. Can be: APIC_TGM_Edge - The interrupt is edge triggered. APIC_TGM_Level - The interrupt is level triggered.
DestinationShortHand- Specifies where to send the interrupt. APIC_DSH_Destination APIC_DSH_Self APIC_DSH_AllIncludingSelf APIC_DSH_AllExcludingSelf
See also
"AMD64 Architecture Programmer's Manual Volume 2 System Programming" Chapter 16 "Advanced Programmable Interrupt Controller (APIC)" 16.5 "Interprocessor Interrupts (IPI)"

Definition at line 60 of file apicsmp.c.

66{
69
70 /* Disable interrupts so that we can change IRR without being interrupted */
72 _disable();
73
74 /* Wait for the APIC to be idle */
75 do
76 {
78 } while (Icr.DeliveryStatus);
79
80 /* Setup the command register */
81 Icr.LongLong = 0;
82 Icr.Vector = Vector;
83 Icr.MessageType = MessageType;
85 Icr.DeliveryStatus = 0;
86 Icr.Level = 0;
87 Icr.TriggerMode = TriggerMode;
88 Icr.RemoteReadStatus = 0;
89 Icr.DestinationShortHand = DestinationShortHand;
90 Icr.Destination = DestinationProcessor;
91
92 /* Write the low dword last to send the interrupt */
95
96 /* Finally, restore the original interrupt state */
98 {
99 _enable();
100 }
101}
#define EFLAGS_INTERRUPT_MASK
@ APIC_DM_Physical
Definition: apicp.h:147
FORCEINLINE ULONG ApicRead(APIC_REGISTER Register)
Definition: apicp.h:318
FORCEINLINE VOID ApicWrite(APIC_REGISTER Register, ULONG Value)
Definition: apicp.h:325
@ APIC_ICR0
Definition: apicp.h:96
@ APIC_ICR1
Definition: apicp.h:97
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
Definition: dispmprt.h:245
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1706
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
uint32_t ULONG
Definition: typedefs.h:59

Referenced by ApicStartApplicationProcessor(), HalpBroadcastIpiSpecifyVector(), and HalRequestIpiSpecifyVector().

◆ ApicStartApplicationProcessor()

VOID ApicStartApplicationProcessor ( _In_ ULONG  NTProcessorNumber,
_In_ PHYSICAL_ADDRESS  StartupLoc 
)

Definition at line 107 of file apicsmp.c.

110{
112
113 ASSERT(StartupLoc.HighPart == 0);
114 ASSERT((StartupLoc.QuadPart & 0xFFF) == 0);
115 ASSERT((StartupLoc.QuadPart & 0xFFF00FFF) == 0);
116
117 /* Init IPI */
118 ApicRequestGlobalInterrupt(HalpProcessorIdentity[NTProcessorNumber].LapicId, 0,
120
121 /* De-Assert Init IPI */
122 ApicRequestGlobalInterrupt(HalpProcessorIdentity[NTProcessorNumber].LapicId, 0,
124
125 /* Give the APIC time to latch INIT before the first SIPI: MPS Spec - B.4 */
127
128 /* 82489DX APICs don't support the STARTUP IPI: MPS Spec - B.4 */
130 if (ApicVersion.Version >= 0x10)
131 {
132 /* First Startup IPI */
133 ApicRequestGlobalInterrupt(HalpProcessorIdentity[NTProcessorNumber].LapicId, (StartupLoc.LowPart) >> 12,
135
136 /* Stall between SIPIs: MPS Spec - B.4 */
138
139 /* Second Startup IPI, required unconditionally by the MP Spec */
140 ApicRequestGlobalInterrupt(HalpProcessorIdentity[NTProcessorNumber].LapicId, (StartupLoc.LowPart) >> 12,
142
143 /* Give the AP time to come up before returning */
145 }
146}
ULONG ApicVersion
Definition: apic.c:27
@ APIC_DSH_Destination
Definition: apicp.h:154
@ APIC_MT_INIT
Definition: apicp.h:132
@ APIC_MT_Startup
Definition: apicp.h:133
@ APIC_VER
Definition: apicp.h:83
@ APIC_TGM_Level
Definition: apicp.h:141
@ APIC_TGM_Edge
Definition: apicp.h:140
FORCEINLINE VOID ApicRequestGlobalInterrupt(_In_ UCHAR DestinationProcessor, _In_ UCHAR Vector, _In_ APIC_MT MessageType, _In_ APIC_TGM TriggerMode, _In_ APIC_DSH DestinationShortHand)
Definition: apicsmp.c:60
PROCESSOR_IDENTITY HalpProcessorIdentity[MAXIMUM_PROCESSORS]
Definition: madt.c:24
#define ASSERT(a)
Definition: mode.c:44
#define KeStallExecutionProcessor(MicroSeconds)
Definition: precomp.h:27

Referenced by HalStartNextProcessor().

◆ HalpBroadcastIpiSpecifyVector()

VOID NTAPI HalpBroadcastIpiSpecifyVector ( _In_ UCHAR  Vector,
_In_ BOOLEAN  IncludeSelf 
)

Broadcasts an IPI with a specified vector to all processors.

Parameters
Vector- Specifies the interrupt vector to be delivered.
IncludeSelf- Specifies whether to include the current processor.

Definition at line 158 of file apicsmp.c.

161{
162 APIC_DSH DestinationShortHand = IncludeSelf ?
164
165 /* Request the interrupt targeted at all processors */
166 ApicRequestGlobalInterrupt(0, // Ignored
167 Vector,
170 DestinationShortHand);
171}
@ APIC_DSH_AllIncludingSelf
Definition: apicp.h:156
@ APIC_DSH_AllExcludingSelf
Definition: apicp.h:157
@ APIC_MT_Fixed
Definition: apicp.h:127
enum _APIC_DSH APIC_DSH

Referenced by HalpBroadcastClockIpi(), and HalRequestIpiSpecifyVector().

◆ HalpRequestIpi()

VOID NTAPI HalpRequestIpi ( _In_ KAFFINITY  TargetSet)

Requests an IPI interrupt on the specified processors.

Parameters
TargetSet- Specifies the set of processors to send the IPI to.

Definition at line 237 of file apicsmp.c.

239{
240 /* Request the IPI vector */
242}
#define APIC_IPI_VECTOR
Definition: apicp.h:48
VOID NTAPI HalRequestIpiSpecifyVector(_In_ KAFFINITY TargetSet, _In_ UCHAR Vector)
Requests an IPI with a specified vector on the specified processors.
Definition: apicsmp.c:183

Referenced by HalRequestIpi().

◆ HalRequestIpiSpecifyVector()

VOID NTAPI HalRequestIpiSpecifyVector ( _In_ KAFFINITY  TargetSet,
_In_ UCHAR  Vector 
)

Requests an IPI with a specified vector on the specified processors.

Parameters
TargetSet- Specifies the set of processors to send the IPI to.
Vector- Specifies the interrupt vector to be delivered.
Remarks
This function is exported on Windows 10.

Definition at line 183 of file apicsmp.c.

186{
187 KAFFINITY ActiveProcessors = HalpActiveProcessors;
188 KAFFINITY RemainingSet, SetMember;
189 ULONG ProcessorIndex;
190 ULONG LApicId;
191
192 /* Sanitize the target set */
193 TargetSet &= ActiveProcessors;
194
195 /* Check if all processors are requested */
196 if (TargetSet == ActiveProcessors)
197 {
198 /* Send an IPI to all processors, including this processor */
200 return;
201 }
202
203 /* Check if all processors except the current one are requested */
204 if (TargetSet == (ActiveProcessors & ~KeGetCurrentPrcb()->SetMember))
205 {
206 /* Send an IPI to all processors, excluding this processor */
208 return;
209 }
210
211 /* Loop while we have more processors */
212 RemainingSet = TargetSet;
213 while (RemainingSet != 0)
214 {
215 NT_VERIFY(BitScanForwardAffinity(&ProcessorIndex, RemainingSet) != 0);
216 ASSERT(ProcessorIndex < KeNumberProcessors);
217 SetMember = AFFINITY_MASK(ProcessorIndex);
218 RemainingSet &= ~SetMember;
219
220 /* Send the interrupt to the target processor */
221 LApicId = HalpProcessorIdentity[ProcessorIndex].LapicId;
223 Vector,
227 }
228}
VOID NTAPI HalpBroadcastIpiSpecifyVector(_In_ UCHAR Vector, _In_ BOOLEAN IncludeSelf)
Broadcasts an IPI with a specified vector to all processors.
Definition: apicsmp.c:158
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
ULONG_PTR KAFFINITY
Definition: compat.h:85
KAFFINITY HalpActiveProcessors
Definition: processor.c:17
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1197
FORCEINLINE KAFFINITY AFFINITY_MASK(ULONG Index)
Definition: kefuncs.h:39
FORCEINLINE BOOLEAN BitScanForwardAffinity(PULONG Index, KAFFINITY Mask)
Definition: kefuncs.h:45
CCHAR KeNumberProcessors
Definition: processor.c:19
ULONG LapicId
Definition: smp.h:14
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3311

Referenced by HalpRequestIpi().