ReactOS 0.4.17-dev-1190-g4c812f4
apic.c File Reference
#include <hal.h>
#include "apicp.h"
#include <smp.h>
#include <debug.h>
Include dependency graph for apic.c:

Go to the source code of this file.

Classes

struct  _HALP_IOAPIC_UNIT
 

Macros

#define NDEBUG
 
#define APIC_LAZY_IRQL
 
#define ApicRaiseIrql   ApicSetIrql
 

Typedefs

typedef struct _HALP_IOAPIC_UNIT HALP_IOAPIC_UNIT
 
typedef struct _HALP_IOAPIC_UNIT * PHALP_IOAPIC_UNIT
 

Functions

FORCEINLINE ULONG IOApicRead (_In_ ULONG_PTR Base, _In_ UCHAR Register)
 
FORCEINLINE VOID IOApicWrite (_In_ ULONG_PTR Base, _In_ UCHAR Register, _In_ ULONG Value)
 
FORCEINLINE BOOLEAN HalpFindIoApicInput (_In_ ULONG Input, _Out_ PHALP_IOAPIC_UNIT *Unit)
 Finds the I/O APIC that serves an input.
 
FORCEINLINE VOID ApicWriteIORedirectionEntry (_In_ ULONG Input, _In_ IOAPIC_REDIRECTION_REGISTER ReDirReg)
 Programs a redirection entry and records it in the shadow table.
 
FORCEINLINE IOAPIC_REDIRECTION_REGISTER ApicReadIORedirectionEntry (_In_ ULONG Input)
 Returns a redirection entry from the shadow table, without accessing the I/O APIC.
 
FORCEINLINE VOID ApicRequestSelfInterrupt (IN UCHAR Vector, UCHAR TriggerMode)
 
FORCEINLINE VOID ApicSendEOI (void)
 
FORCEINLINE KIRQL ApicGetProcessorIrql (VOID)
 
FORCEINLINE KIRQL ApicGetCurrentIrql (VOID)
 
FORCEINLINE VOID ApicSetIrql (KIRQL Irql)
 
FORCEINLINE VOID ApicLowerIrql (KIRQL Irql)
 
UCHAR FASTCALL HalpIrqToVector (_In_ UCHAR Irq)
 
KIRQL FASTCALL HalpVectorToIrql (UCHAR Vector)
 
UCHAR FASTCALL HalpVectorToIrq (UCHAR Vector)
 
VOID NTAPI HalpSendEOI (VOID)
 
VOID NTAPI ApicInitializeLocalApic (_In_ ULONG Cpu)
 
UCHAR NTAPI HalpAllocateSystemInterrupt (_In_ UCHAR Irq, _In_ UCHAR Vector)
 
ULONG NTAPI HalpGetRootInterruptVector (_In_ ULONG BusInterruptLevel, _In_ ULONG BusInterruptVector, _Out_ PKIRQL OutIrql, _Out_ PKAFFINITY OutAffinity)
 
static VOID NTAPI HalpMapIoApic (_In_ ULONG PhysicalBase, _In_ ULONG InputBase)
 Maps an I/O APIC and adds it to the units in use.
 
VOID NTAPI ApicInitializeIOApic (VOID)
 
VOID NTAPI HalpInitializePICs (_In_ BOOLEAN EnableInterrupts)
 
VOID DECLSPEC_NORETURN FASTCALL HalpApcInterruptHandler (IN PKTRAP_FRAME TrapFrame)
 
VOID DECLSPEC_NORETURN FASTCALL HalpDispatchInterruptHandler (IN PKTRAP_FRAME TrapFrame)
 
VOID FASTCALL HalRequestSoftwareInterrupt (IN KIRQL Irql)
 
VOID FASTCALL HalClearSoftwareInterrupt (IN KIRQL Irql)
 
static NTSTATUS NTAPI HalpQueryVectorInput (_In_ ULONG Vector, _Out_ PULONG Input, _Out_ PKINTERRUPT_POLARITY Polarity)
 Asks the ACPI driver for the input of a vector it allocated.
 
static KINTERRUPT_POLARITY NTAPI HalpGetInputPolarity (_In_ ULONG Input, _In_ KINTERRUPT_MODE Mode, _In_ KINTERRUPT_POLARITY Reported)
 Picks the polarity to program for an input.
 
BOOLEAN NTAPI HalEnableSystemInterrupt (_In_ ULONG Vector, _In_ KIRQL Irql, _In_ KINTERRUPT_MODE InterruptMode)
 
VOID NTAPI HalDisableSystemInterrupt (_In_ ULONG Vector, _In_ KIRQL Irql)
 
BOOLEAN NTAPI HalBeginSystemInterrupt (_In_ KIRQL Irql, _In_ ULONG Vector, _Out_ PKIRQL OldIrql)
 
VOID NTAPI HalEndSystemInterrupt (IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
 
KIRQL NTAPI KeGetCurrentIrql (VOID)
 
VOID FASTCALL KfLowerIrql (IN KIRQL OldIrql)
 
KIRQL FASTCALL KfRaiseIrql (IN KIRQL NewIrql)
 
KIRQL NTAPI KeRaiseIrqlToDpcLevel (VOID)
 
KIRQL NTAPI KeRaiseIrqlToSynchLevel (VOID)
 

Variables

ULONG ApicVersion
 
UCHAR HalpVectorToIndex [256]
 
UCHAR HalpGsivToVector [256]
 
HALP_APIC_INFO_TABLE HalpApicInfoTable
 
HALP_IOAPIC_UNIT HalpIoApics [HALP_MAX_IOAPICS]
 
ULONG HalpIoApicCount
 
ULONG HalpMaxGsi
 
IOAPIC_REDIRECTION_REGISTER HalpIoApicShadow [HALP_MAX_INPUTS]
 
const UCHAR HalpIRQLtoTPR [32]
 
const KIRQL HalVectorToIRQL [16]
 

Macro Definition Documentation

◆ APIC_LAZY_IRQL

#define APIC_LAZY_IRQL

Definition at line 23 of file apic.c.

◆ ApicRaiseIrql

#define ApicRaiseIrql   ApicSetIrql

Definition at line 319 of file apic.c.

◆ NDEBUG

#define NDEBUG

Definition at line 19 of file apic.c.

Typedef Documentation

◆ HALP_IOAPIC_UNIT

◆ PHALP_IOAPIC_UNIT

Function Documentation

◆ ApicGetCurrentIrql()

FORCEINLINE KIRQL ApicGetCurrentIrql ( VOID  )

Definition at line 293 of file apic.c.

294{
295#ifdef _M_AMD64
296 return (KIRQL)__readcr8();
297#elif defined(APIC_LAZY_IRQL)
298 /* Return the field in the PCR */
300#else
301 /* Read the TPR and convert it to an IRQL */
302 return TprToIrql(ApicRead(APIC_TPR));
303#endif
304}
FORCEINLINE ULONG ApicRead(APIC_REGISTER Register)
Definition: apicp.h:337
#define TprToIrql(Tpr)
Definition: apicp.h:57
@ APIC_TPR
Definition: apicp.h:89
_Out_ PKIRQL Irql
Definition: csq.h:179
UCHAR KIRQL
Definition: env_spec_w32.h:591
PPC_QUAL unsigned char __readfsbyte(const unsigned long Offset)
Definition: intrin_ppc.h:360
Definition: ke.h:294
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255

Referenced by HalBeginSystemInterrupt(), HalpApcInterruptHandler(), HalpDispatchInterruptHandler(), KeGetCurrentIrql(), KfLowerIrql(), and KfRaiseIrql().

◆ ApicGetProcessorIrql()

FORCEINLINE KIRQL ApicGetProcessorIrql ( VOID  )

Definition at line 285 of file apic.c.

286{
287 /* Read the TPR and convert it to an IRQL */
288 return TprToIrql(ApicRead(APIC_PPR));
289}
@ APIC_PPR
Definition: apicp.h:91

Referenced by HalpApcInterruptHandler(), and HalpDispatchInterruptHandler().

◆ ApicInitializeIOApic()

VOID NTAPI ApicInitializeIOApic ( VOID  )

Definition at line 632 of file apic.c.

633{
635 IOAPIC_REDIRECTION_REGISTER ReDirReg, Current;
638
639 /* Use the I/O APICs from the MADT, or the default one without it */
641 {
643 {
646 }
647 }
648 if (HalpIoApicCount == 0)
649 {
651 }
652
653 /* Setup a redirection entry */
654 ReDirReg.LongLong = 0;
655 ReDirReg.Vector = APIC_FREE_VECTOR;
656 ReDirReg.MessageType = APIC_MT_Fixed;
658 ReDirReg.TriggerMode = APIC_TGM_Edge;
659 ReDirReg.Mask = 1;
660 ReDirReg.Destination = ApicRead(APIC_ID) >> 24;
661
662 /* Initialize all entries of all I/O APICs */
664 {
665 for (Input = Unit->InputBase; Input < Unit->InputBase + Unit->InputCount; Input++)
666 {
667 /* Entries the firmware routes to SMI stay as they are */
668 Register = (UCHAR)(IOAPIC_REDTBL + 2 * (Input - Unit->InputBase));
669 Current.Long0 = IOApicRead(Unit->Base, Register);
670 if (Current.MessageType == APIC_MT_SMI)
671 {
672 Current.Long1 = IOApicRead(Unit->Base, Register + 1);
673 HalpIoApicShadow[Input] = Current;
674 continue;
675 }
676
678 }
679 }
680
681 /* Init the vector and input tables */
682 for (Vector = 0; Vector <= 255; Vector++)
683 {
686 }
687
688 /* Enable the timer interrupt (but keep it masked) */
689 ReDirReg.Vector = APIC_CLOCK_VECTOR;
690 ReDirReg.MessageType = APIC_MT_Fixed;
692 ReDirReg.TriggerMode = APIC_TGM_Level;
693 ReDirReg.Mask = 1;
694 ReDirReg.Destination = ApicRead(APIC_ID) >> 24;
696}
static VOID NTAPI HalpMapIoApic(_In_ ULONG PhysicalBase, _In_ ULONG InputBase)
Maps an I/O APIC and adds it to the units in use.
Definition: apic.c:587
UCHAR HalpVectorToIndex[256]
Definition: apic.c:31
FORCEINLINE VOID ApicWriteIORedirectionEntry(_In_ ULONG Input, _In_ IOAPIC_REDIRECTION_REGISTER ReDirReg)
Programs a redirection entry and records it in the shadow table.
Definition: apic.c:187
ULONG HalpIoApicCount
Definition: apic.c:45
HALP_APIC_INFO_TABLE HalpApicInfoTable
Definition: misc.c:19
IOAPIC_REDIRECTION_REGISTER HalpIoApicShadow[HALP_MAX_INPUTS]
Definition: apic.c:56
UCHAR HalpGsivToVector[256]
Definition: apic.c:32
HALP_IOAPIC_UNIT HalpIoApics[HALP_MAX_IOAPICS]
Definition: apic.c:44
FORCEINLINE ULONG IOApicRead(_In_ ULONG_PTR Base, _In_ UCHAR Register)
Definition: apic.c:122
@ APIC_DM_Physical
Definition: apicp.h:152
#define APIC_CLOCK_VECTOR
Definition: apicp.h:45
#define APIC_FREE_VECTOR
Definition: apicp.h:61
@ APIC_MT_Fixed
Definition: apicp.h:132
@ APIC_MT_SMI
Definition: apicp.h:134
#define IOAPIC_REDTBL
Definition: apicp.h:309
#define APIC_CLOCK_INDEX
Definition: apicp.h:123
@ APIC_ID
Definition: apicp.h:87
@ APIC_TGM_Level
Definition: apicp.h:146
@ APIC_TGM_Edge
Definition: apicp.h:145
#define IOAPIC_PHYS_BASE
Definition: apicp.h:122
Unit
Definition: gdiplusenums.h:26
@ Input
Definition: arc.h:93
#define HALP_APIC_INFO_TABLE_IOAPIC_NUMBER
Definition: smp.h:23
ULONG IoApicPA[HALP_APIC_INFO_TABLE_IOAPIC_NUMBER]
Definition: smp.h:32
ULONG IoApicIrqBase[HALP_APIC_INFO_TABLE_IOAPIC_NUMBER]
Definition: smp.h:33
unsigned char UCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by HalpInitializePICs().

◆ ApicInitializeLocalApic()

VOID NTAPI ApicInitializeLocalApic ( _In_ ULONG  Cpu)

Definition at line 374 of file apic.c.

376{
377 APIC_BASE_ADDRESS_REGISTER BaseRegister;
379 APIC_VERSION_REGISTER VersionRegister;
380 APIC_EXTENDED_FEATURE_REGISTER FeatureRegister;
381 LVT_REGISTER LvtEntry;
382 ULONG Index;
383
384 /* Enable the APIC if it wasn't yet */
385 BaseRegister.LongLong = __readmsr(MSR_APIC_BASE);
386 BaseRegister.Enable = 1;
387 BaseRegister.BootStrapCPUCore = (Cpu == 0);
388 __writemsr(MSR_APIC_BASE, BaseRegister.LongLong);
389
390 /* Set spurious vector and SoftwareEnable to 1 */
391 SpIntRegister.Long = ApicRead(APIC_SIVR);
392 SpIntRegister.Vector = APIC_SPURIOUS_VECTOR;
393 SpIntRegister.SoftwareEnable = 1;
394 SpIntRegister.FocusCPUCoreChecking = 0;
395 ApicWrite(APIC_SIVR, SpIntRegister.Long);
396
397 /* Read the version and save it globally */
398 if (Cpu == 0) ApicVersion = ApicRead(APIC_VER);
399
400 /* Set the mode to flat (max 8 CPUs supported!) */
402
403 /* Set logical apic ID */
404 ApicWrite(APIC_LDR, ApicLogicalId(Cpu) << 24);
405
406 /* Set the spurious ISR */
408
409 /* Create a template LVT */
410 LvtEntry.Long = 0;
411 LvtEntry.Vector = APIC_FREE_VECTOR;
412 LvtEntry.MessageType = APIC_MT_Fixed;
413 LvtEntry.DeliveryStatus = 0;
414 LvtEntry.RemoteIRR = 0;
415 LvtEntry.TriggerMode = APIC_TGM_Edge;
416 LvtEntry.Mask = 1;
417 LvtEntry.TimerMode = 0;
418
419 /* Initialize and mask LVTs. Accessing one this APIC lacks is an illegal register error */
420 VersionRegister.Long = ApicRead(APIC_VER);
421 ApicWrite(APIC_TMRLVTR, LvtEntry.Long);
422
423 /* The performance counter LVT came with 5 LVT entries, the thermal LVT with 6 */
424 if (VersionRegister.MaxLVT >= 4)
425 {
426 ApicWrite(APIC_PCLVTR, LvtEntry.Long);
427 }
428 if (VersionRegister.MaxLVT >= 5)
429 {
430 ApicWrite(APIC_THRMLVTR, LvtEntry.Long);
431 }
432
433 /* AMD extended LVTs reset unmasked */
434 if (VersionRegister.ExtRegSpacePresent)
435 {
436 FeatureRegister.Long = ApicRead(APIC_EAFR);
437 for (Index = 0; Index < min(FeatureRegister.ExtLvtCount, 4); Index++)
438 {
439 ApicWrite((APIC_REGISTER)(APIC_EXT0LVTR + Index * 0x10), LvtEntry.Long);
440 }
441 }
442
443 /* LINT0 */
444 LvtEntry.Vector = APIC_SPURIOUS_VECTOR;
445 LvtEntry.MessageType = APIC_MT_ExtInt;
446 ApicWrite(APIC_LINT0, LvtEntry.Long);
447
448 /* Enable LINT1 (NMI) */
449 LvtEntry.Mask = 0;
450 LvtEntry.Vector = APIC_NMI_VECTOR;
451 LvtEntry.MessageType = APIC_MT_NMI;
452 LvtEntry.TriggerMode = APIC_TGM_Level;
453 ApicWrite(APIC_LINT1, LvtEntry.Long);
454
455 /* Clear any error from the writes above */
457
458 /* Enable error LVTR */
460 LvtEntry.Vector = APIC_ERROR_VECTOR;
461 LvtEntry.MessageType = APIC_MT_Fixed;
462 ApicWrite(APIC_ERRLVTR, LvtEntry.Long);
463
464 /* Set the IRQL from the PCR */
466#ifdef APIC_LAZY_IRQL
467 /* Save the new hard IRQL in the IRR field */
468 KeGetPcr()->IRR = KeGetPcr()->Irql;
469#endif
470}
ULONG ApicVersion
Definition: apic.c:28
FORCEINLINE VOID ApicSetIrql(KIRQL Irql)
Definition: apic.c:308
#define MSR_APIC_BASE
Definition: apicp.h:121
@ APIC_DF_Flat
Definition: apicp.h:168
#define APIC_NMI_VECTOR
Definition: apicp.h:53
@ APIC_MT_NMI
Definition: apicp.h:136
@ APIC_MT_ExtInt
Definition: apicp.h:139
#define APIC_SPURIOUS_VECTOR
Definition: apicp.h:41
#define APIC_ERROR_VECTOR
Definition: apicp.h:49
enum _APIC_REGISTER APIC_REGISTER
#define ApicLogicalId(Cpu)
Definition: apicp.h:124
VOID __cdecl ApicSpuriousService(VOID)
VOID __cdecl ApicErrorService(VOID)
FORCEINLINE VOID ApicWrite(APIC_REGISTER Register, ULONG Value)
Definition: apicp.h:344
@ APIC_LINT1
Definition: apicp.h:107
@ APIC_VER
Definition: apicp.h:88
@ APIC_LDR
Definition: apicp.h:94
@ APIC_ESR
Definition: apicp.h:100
@ APIC_ERRLVTR
Definition: apicp.h:108
@ APIC_PCLVTR
Definition: apicp.h:105
@ APIC_EAFR
Definition: apicp.h:112
@ APIC_THRMLVTR
Definition: apicp.h:104
@ APIC_TMRLVTR
Definition: apicp.h:103
@ APIC_DFR
Definition: apicp.h:95
@ APIC_LINT0
Definition: apicp.h:106
@ APIC_SIVR
Definition: apicp.h:96
@ APIC_EXT0LVTR
Definition: apicp.h:115
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
#define min(a, b)
Definition: monoChain.cc:55
#define KeGetPcr()
Definition: ketypes.h:81
FORCEINLINE VOID KeRegisterInterruptHandler(IN ULONG Vector, IN PVOID Handler)
Definition: ke.h:311
UINT32 ExtRegSpacePresent
Definition: apicp.h:229
UINT32 RemoteIRR
Definition: apicp.h:293
UINT32 MessageType
Definition: apicp.h:289
UINT32 TimerMode
Definition: apicp.h:296
UINT32 Long
Definition: apicp.h:285
UINT32 Vector
Definition: apicp.h:288
UINT32 Mask
Definition: apicp.h:295
UINT32 TriggerMode
Definition: apicp.h:294
UINT32 DeliveryStatus
Definition: apicp.h:291

◆ ApicLowerIrql()

FORCEINLINE VOID ApicLowerIrql ( KIRQL  Irql)

Definition at line 324 of file apic.c.

325{
327
328 /* Is the new Irql lower than set in the TPR? */
329 if (Irql < KeGetPcr()->IRR)
330 {
331 /* Save the new hard IRQL in the IRR field */
332 KeGetPcr()->IRR = Irql;
333
334 /* Need to lower it back */
336 }
337}
#define IrqlToTpr(Irql)
Definition: apicp.h:55
PPC_QUAL void __writefsbyte(const unsigned long Offset, const unsigned char Data)
Definition: intrin_ppc.h:342

Referenced by HalEndSystemInterrupt(), HalpApcInterruptHandler(), HalpDispatchInterruptHandler(), and KfLowerIrql().

◆ ApicReadIORedirectionEntry()

FORCEINLINE IOAPIC_REDIRECTION_REGISTER ApicReadIORedirectionEntry ( _In_ ULONG  Input)

Returns a redirection entry from the shadow table, without accessing the I/O APIC.

Definition at line 216 of file apic.c.

218{
220 return HalpIoApicShadow[Input];
221}
ULONG HalpMaxGsi
Definition: apic.c:48
#define ASSERT(a)
Definition: mode.c:44

Referenced by HalBeginSystemInterrupt(), HalDisableSystemInterrupt(), and HalEnableSystemInterrupt().

◆ ApicRequestSelfInterrupt()

FORCEINLINE VOID ApicRequestSelfInterrupt ( IN UCHAR  Vector,
UCHAR  TriggerMode 
)

Definition at line 225 of file apic.c.

226{
227 ULONG Flags;
230
231 /*
232 * The IRR registers are spaced 16 bytes apart and hold 32 status bits each.
233 * Pre-compute the register and bit that match our vector.
234 */
235 ULONG VectorHigh = Vector / 32;
236 ULONG VectorLow = Vector % 32;
237 ULONG Irr = APIC_IRR + 0x10 * VectorHigh;
238 ULONG IrrBit = 1UL << VectorLow;
239
240 /* Setup the command register */
241 Icr.LongLong = 0;
242 Icr.Vector = Vector;
244 Icr.TriggerMode = TriggerMode;
246
247 /* Disable interrupts so that we can change IRR without being interrupted */
249 _disable();
250
251 /* Wait for the APIC to be idle */
252 do
253 {
254 IcrStatus.Long0 = ApicRead(APIC_ICR0);
255 } while (IcrStatus.DeliveryStatus);
256
257 /* Write high dword first, then low dword to send the interrupt */
260
261 /* Wait until we see the interrupt request.
262 * It will stay in requested state until we re-enable interrupts.
263 */
264 while (!(ApicRead(Irr) & IrrBit))
265 {
267 }
268
269 /* Finally, restore the original interrupt state */
271 {
272 _enable();
273 }
274}
#define EFLAGS_INTERRUPT_MASK
@ APIC_DSH_Self
Definition: apicp.h:160
@ APIC_ICR0
Definition: apicp.h:101
@ APIC_IRR
Definition: apicp.h:99
@ APIC_ICR1
Definition: apicp.h:102
_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
#define YieldProcessor
Definition: ke.h:48

Referenced by HalBeginSystemInterrupt(), and HalRequestSoftwareInterrupt().

◆ ApicSendEOI()

FORCEINLINE VOID ApicSendEOI ( void  )

◆ ApicSetIrql()

FORCEINLINE VOID ApicSetIrql ( KIRQL  Irql)

Definition at line 308 of file apic.c.

309{
310#ifdef _M_AMD64
311 __writecr8(Irql);
312#elif defined(APIC_LAZY_IRQL)
314#else
315 /* Convert IRQL and write the TPR */
317#endif
318}

Referenced by ApicInitializeLocalApic().

◆ ApicWriteIORedirectionEntry()

FORCEINLINE VOID ApicWriteIORedirectionEntry ( _In_ ULONG  Input,
_In_ IOAPIC_REDIRECTION_REGISTER  ReDirReg 
)

Programs a redirection entry and records it in the shadow table.

Remarks
Callers serialize through the dispatcher lock or run before other processors are started, since IOREGSEL and IOWIN are shared.

Definition at line 187 of file apic.c.

190{
193
195 {
196 ASSERT(FALSE);
197 return;
198 }
199
200 HalpIoApicShadow[Input] = ReDirReg;
201
202 /* The destination has to be in place before the low half unmasks the
203 entry, so that an asserted input cannot reach a stale processor */
204 Register = (UCHAR)(IOAPIC_REDTBL + 2 * (Input - Unit->InputBase));
205 IOApicWrite(Unit->Base, Register + 1, ReDirReg.Long1);
206 IOApicWrite(Unit->Base, Register, ReDirReg.Long0);
207}
FORCEINLINE VOID IOApicWrite(_In_ ULONG_PTR Base, _In_ UCHAR Register, _In_ ULONG Value)
Definition: apic.c:133
FORCEINLINE BOOLEAN HalpFindIoApicInput(_In_ ULONG Input, _Out_ PHALP_IOAPIC_UNIT *Unit)
Finds the I/O APIC that serves an input.
Definition: apic.c:158
#define FALSE
Definition: types.h:117

Referenced by ApicInitializeIOApic(), HalDisableSystemInterrupt(), HalEnableSystemInterrupt(), and HalpAllocateSystemInterrupt().

◆ HalBeginSystemInterrupt()

BOOLEAN NTAPI HalBeginSystemInterrupt ( _In_ KIRQL  Irql,
_In_ ULONG  Vector,
_Out_ PKIRQL  OldIrql 
)

Definition at line 1057 of file apic.c.

1061{
1062 KIRQL CurrentIrql;
1063
1064 /* Get the current IRQL */
1065 CurrentIrql = ApicGetCurrentIrql();
1066
1067#ifdef APIC_LAZY_IRQL
1068 /* Check if this interrupt is allowed */
1069 if (CurrentIrql >= Irql)
1070 {
1072 UCHAR Index;
1073
1074 /* It is not, set the real Irql in the TPR! */
1075 ApicWrite(APIC_TPR, IrqlToTpr(CurrentIrql));
1076
1077 /* Save the new hard IRQL in the IRR field */
1078 KeGetPcr()->IRR = CurrentIrql;
1079
1080 /* End this interrupt */
1081 ApicSendEOI();
1082
1083 /* Get the irq for this vector */
1085
1086 /* Check if it's valid */
1087 if (Index < HalpMaxGsi)
1088 {
1089 /* Read the I/O redirection entry */
1091
1092 /* Re-request the interrupt to be handled later */
1094 }
1095 else
1096 {
1097 /* This should be a reserved or message-signaled vector! */
1099
1100 /* Re-request the interrupt to be handled later */
1102 }
1103
1104 /* Pretend it was a spurious interrupt */
1105 return FALSE;
1106 }
1107#endif
1108 /* Save the current IRQL */
1109 *OldIrql = CurrentIrql;
1110
1111 /* Set the new IRQL */
1113
1114 /* Turn on interrupts */
1115 _enable();
1116
1117 /* Success */
1118 return TRUE;
1119}
#define ApicRaiseIrql
Definition: apic.c:319
FORCEINLINE VOID ApicRequestSelfInterrupt(IN UCHAR Vector, UCHAR TriggerMode)
Definition: apic.c:225
FORCEINLINE VOID ApicSendEOI(void)
Definition: apic.c:278
FORCEINLINE IOAPIC_REDIRECTION_REGISTER ApicReadIORedirectionEntry(_In_ ULONG Input)
Returns a redirection entry from the shadow table, without accessing the I/O APIC.
Definition: apic.c:216
FORCEINLINE KIRQL ApicGetCurrentIrql(VOID)
Definition: apic.c:293
#define APIC_MSI_VECTOR
Definition: apicp.h:63
#define APIC_RESERVED_VECTOR
Definition: apicp.h:62
#define TRUE
Definition: types.h:120
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by HalpApcInterruptHandler(), HalpDispatchInterruptHandler(), and MpsTimerHandler().

◆ HalClearSoftwareInterrupt()

VOID FASTCALL HalClearSoftwareInterrupt ( IN KIRQL  Irql)

Definition at line 855 of file apic.c.

857{
858 /* Nothing to do */
859}

◆ HalDisableSystemInterrupt()

VOID NTAPI HalDisableSystemInterrupt ( _In_ ULONG  Vector,
_In_ KIRQL  Irql 
)

Definition at line 1034 of file apic.c.

1037{
1039 UCHAR Index;
1042
1044
1045 /* Message-signaled and reserved vectors have no entry to mask */
1046 if (Index >= HalpMaxGsi)
1047 return;
1048
1049 /* Mask the redirection entry */
1051 ReDirReg.Mask = 1;
1053}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define HIGH_LEVEL
Definition: env_spec_w32.h:703

◆ HalEnableSystemInterrupt()

BOOLEAN NTAPI HalEnableSystemInterrupt ( _In_ ULONG  Vector,
_In_ KIRQL  Irql,
_In_ KINTERRUPT_MODE  InterruptMode 
)

Definition at line 953 of file apic.c.

957{
959 KINTERRUPT_POLARITY Polarity;
961 ULONG Input;
962 UCHAR Index;
964 ASSERT((IrqlToTpr(Irql) & 0xF0) == (Vector & 0xF0));
965
966 /* Get the irq for this vector */
968
969 /* Message-signaled interrupts have no input to unmask */
970 if (Index == APIC_MSI_VECTOR)
971 {
972 return TRUE;
973 }
974
975 /* The ACPI driver allocates vectors itself when it arbitrates interrupts */
976 Polarity = InterruptPolarityUnknown;
977 if (Index == APIC_FREE_VECTOR)
978 {
979 Status = HalpQueryVectorInput(Vector, &Input, &Polarity);
981 {
983 return TRUE;
984 }
985
986 /* Don't take over an input that belongs to another vector */
988 {
989 DPRINT1("No free input for vector 0x%lx, status 0x%lx\n", Vector, Status);
990 return FALSE;
991 }
992
994 Index = (UCHAR)Input;
995 }
996
997 /* Check if its valid */
998 if (Index >= HalpMaxGsi)
999 {
1000 /* Interrupt is not in use */
1001 return FALSE;
1002 }
1003
1004 /* Read the redirection entry */
1006
1007 /* Check if the interrupt is already enabled */
1008 if (ReDirReg.Mask == FALSE)
1009 {
1010 /* If the vector matches, there is nothing more to do,
1011 otherwise something is wrong. */
1012 return (ReDirReg.Vector == Vector);
1013 }
1014
1015 /* Set up the redirection entry */
1016 ReDirReg.Vector = Vector;
1017 ReDirReg.MessageType = APIC_MT_Fixed;
1019 ReDirReg.Destination = ApicRead(APIC_ID) >> 24;
1020 ReDirReg.TriggerMode = (InterruptMode == LevelSensitive) ?
1022 ReDirReg.Polarity =
1024 ReDirReg.Mask = FALSE;
1025
1026 /* Write back the entry */
1028
1029 return TRUE;
1030}
static NTSTATUS NTAPI HalpQueryVectorInput(_In_ ULONG Vector, _Out_ PULONG Input, _Out_ PKINTERRUPT_POLARITY Polarity)
Asks the ACPI driver for the input of a vector it allocated.
Definition: apic.c:884
UCHAR NTAPI HalpAllocateSystemInterrupt(_In_ UCHAR Irq, _In_ UCHAR Vector)
Definition: apic.c:474
static KINTERRUPT_POLARITY NTAPI HalpGetInputPolarity(_In_ ULONG Input, _In_ KINTERRUPT_MODE Mode, _In_ KINTERRUPT_POLARITY Reported)
Picks the polarity to program for an input.
Definition: apic.c:928
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:24
@ LevelSensitive
Definition: miniport.h:80
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:806
@ InterruptActiveLow
Definition: ketypes.h:435
@ InterruptPolarityUnknown
Definition: ketypes.h:433
enum _KINTERRUPT_POLARITY KINTERRUPT_POLARITY

◆ HalEndSystemInterrupt()

VOID NTAPI HalEndSystemInterrupt ( IN KIRQL  OldIrql,
IN PKTRAP_FRAME  TrapFrame 
)

Definition at line 1123 of file apic.c.

1126{
1127 /* Send an EOI */
1128 ApicSendEOI();
1129
1130 /* Restore the old IRQL */
1132}
FORCEINLINE VOID ApicLowerIrql(KIRQL Irql)
Definition: apic.c:324

Referenced by MpsTimerHandler().

◆ HalpAllocateSystemInterrupt()

UCHAR NTAPI HalpAllocateSystemInterrupt ( _In_ UCHAR  Irq,
_In_ UCHAR  Vector 
)

Definition at line 474 of file apic.c.

477{
479
480 ASSERT(Irq < HalpMaxGsi);
482
483 /* Setup a redirection entry */
484 ReDirReg.Vector = Vector;
487 ReDirReg.DeliveryStatus = 0;
488 ReDirReg.Polarity = 0;
489 ReDirReg.RemoteIRR = 0;
490 ReDirReg.TriggerMode = APIC_TGM_Edge;
491 ReDirReg.Mask = 1;
492 ReDirReg.Reserved = 0;
493 ReDirReg.Destination = ApicRead(APIC_ID) >> 24;
494
495 /* Initialize entry */
496 ApicWriteIORedirectionEntry(Irq, ReDirReg);
497
498 /* Record the allocation in both tables */
501
502 return Vector;
503}
@ APIC_DM_Logical
Definition: apicp.h:153
@ APIC_MT_LowestPriority
Definition: apicp.h:133

Referenced by HalEnableSystemInterrupt(), and HalpGetRootInterruptVector().

◆ HalpApcInterruptHandler()

VOID DECLSPEC_NORETURN FASTCALL HalpApcInterruptHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 753 of file apic.c.

754{
755 KPROCESSOR_MODE ProcessorMode;
758
759 /* Enter trap */
760 KiEnterInterruptTrap(TrapFrame);
761
762#ifdef APIC_LAZY_IRQL
764 {
765 /* "Spurious" interrupt, exit the interrupt */
766 KiEoiHelper(TrapFrame);
767 }
768#else
769 /* Save the old IRQL */
772#endif
773
774 /* Raise to APC_LEVEL */
776
777 /* End the interrupt */
778 ApicSendEOI();
779
780 /* Kernel or user APC? */
781 if (KiUserTrap(TrapFrame)) ProcessorMode = UserMode;
782 else if (TrapFrame->EFlags & EFLAGS_V86_MASK) ProcessorMode = UserMode;
783 else ProcessorMode = KernelMode;
784
785 /* Enable interrupts and call the kernel's APC interrupt handler */
786 _enable();
787 KiDeliverApc(ProcessorMode, NULL, TrapFrame);
788
789 /* Disable interrupts */
790 _disable();
791
792 /* Restore the old IRQL */
794
795 /* Exit the interrupt */
796 KiEoiHelper(TrapFrame);
797}
BOOLEAN NTAPI HalBeginSystemInterrupt(_In_ KIRQL Irql, _In_ ULONG Vector, _Out_ PKIRQL OldIrql)
Definition: apic.c:1057
FORCEINLINE KIRQL ApicGetProcessorIrql(VOID)
Definition: apic.c:285
#define APC_VECTOR
Definition: apicp.h:42
#define NULL
Definition: types.h:112
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define EFLAGS_V86_MASK
Definition: ketypes.h:207
#define KernelMode
Definition: asm.h:38
#define UserMode
Definition: asm.h:39
FORCEINLINE BOOLEAN KiUserTrap(IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:377
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
VOID NTAPI KiDeliverApc(IN KPROCESSOR_MODE DeliveryMode, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
Definition: apc.c:302
FORCEINLINE VOID KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:368
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7

◆ HalpDispatchInterruptHandler()

VOID DECLSPEC_NORETURN FASTCALL HalpDispatchInterruptHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 802 of file apic.c.

803{
806
807 /* Enter trap */
808 KiEnterInterruptTrap(TrapFrame);
809
810#ifdef APIC_LAZY_IRQL
812 {
813 /* "Spurious" interrupt, exit the interrupt */
814 KiEoiHelper(TrapFrame);
815 }
816#else
817 /* Get the current IRQL */
820#endif
821
822 /* Raise to DISPATCH_LEVEL */
824
825 /* End the interrupt */
826 ApicSendEOI();
827
828 /* Enable interrupts and call the kernel's DPC interrupt handler */
829 _enable();
831 _disable();
832
833 /* Restore the old IRQL */
835
836 /* Exit the interrupt */
837 KiEoiHelper(TrapFrame);
838}
#define DISPATCH_VECTOR
Definition: apicp.h:43
VOID NTAPI KiDispatchInterrupt(VOID)
Definition: thrdini.c:305
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696

◆ HalpFindIoApicInput()

FORCEINLINE BOOLEAN HalpFindIoApicInput ( _In_ ULONG  Input,
_Out_ PHALP_IOAPIC_UNIT *  Unit 
)

Finds the I/O APIC that serves an input.

Parameters
[in]InputThe global system interrupt to look up.
[out]UnitReceives the I/O APIC serving the input.
Returns
TRUE if an I/O APIC serves the input, FALSE otherwise.

Definition at line 158 of file apic.c.

161{
162 ULONG Index;
163
164 for (Index = 0; Index < HalpIoApicCount; Index++)
165 {
166 if ((Input >= HalpIoApics[Index].InputBase) &&
167 (Input - HalpIoApics[Index].InputBase < HalpIoApics[Index].InputCount))
168 {
170 return TRUE;
171 }
172 }
173
174 return FALSE;
175}

Referenced by ApicWriteIORedirectionEntry(), HalpGetRootInterruptVector(), and HalpQueryVectorInput().

◆ HalpGetInputPolarity()

static KINTERRUPT_POLARITY NTAPI HalpGetInputPolarity ( _In_ ULONG  Input,
_In_ KINTERRUPT_MODE  Mode,
_In_ KINTERRUPT_POLARITY  Reported 
)
static

Picks the polarity to program for an input.

Parameters
[in]InputThe global system interrupt being enabled.
[in]ModeThe trigger mode of the input.
[in]ReportedThe polarity reported by the ACPI driver, or InterruptPolarityUnknown.
Returns
The reported polarity, else the one of an MADT interrupt source override targeting the input, else the default of the trigger mode.

Definition at line 928 of file apic.c.

932{
933 ULONG Irq;
934
935 if (Reported != InterruptPolarityUnknown)
936 return Reported;
937
938 for (Irq = 0; Irq < HALP_ISA_IRQ_COUNT; Irq++)
939 {
942 {
944 }
945 }
946
947 /* PCI lines are level and active low, ISA lines are edge and active high */
949}
_In_ ULONG Mode
Definition: hubbusif.h:303
#define HALP_ISA_IRQ_COUNT
Definition: smp.h:24
ULONG IsaIrqGsi[HALP_ISA_IRQ_COUNT]
Definition: smp.h:34
KINTERRUPT_POLARITY IsaIrqPolarity[HALP_ISA_IRQ_COUNT]
Definition: smp.h:35
@ InterruptActiveHigh
Definition: ketypes.h:434

Referenced by HalEnableSystemInterrupt().

◆ HalpGetRootInterruptVector()

ULONG NTAPI HalpGetRootInterruptVector ( _In_ ULONG  BusInterruptLevel,
_In_ ULONG  BusInterruptVector,
_Out_ PKIRQL  OutIrql,
_Out_ PKAFFINITY  OutAffinity 
)

Definition at line 507 of file apic.c.

512{
515 KIRQL Irql;
516
517 /* Resources that already hold a system vector are translated here too, so stay quiet */
519 {
520 DPRINT("No I/O APIC serves input %lu\n", BusInterruptLevel);
521 *OutAffinity = 0;
522 *OutIrql = 0;
523 return 0;
524 }
525
526 /* Get the vector currently registered */
528
529 /* Check if it's used */
531 {
532 /* Calculate IRQL */
534 *OutIrql = HalpVectorToIrql(Vector);
535 }
536 else
537 {
539
540 /* Outer loop to find alternative slots, when all IRQLs are in use */
541 for (Offset = 0; Offset < 15; Offset++)
542 {
543 /* Loop allowed IRQL range */
544 for (Irql = CLOCK_LEVEL - 1; Irql >= CMCI_LEVEL; Irql--)
545 {
546 /* Calculate the vactor */
548
549 /* Check if the vector is free */
551 {
552 /* Found one, allocate the interrupt */
554 *OutIrql = Irql;
555 goto Exit;
556 }
557 }
558 }
559
560 DPRINT1("Failed to get an interrupt vector for IRQ %lu\n", BusInterruptLevel);
561 *OutAffinity = 0;
562 *OutIrql = 0;
563 return 0;
564 }
565
566Exit:
567
568 *OutAffinity = HalpDefaultInterruptAffinity;
570
571 return Vector;
572}
UCHAR FASTCALL HalpIrqToVector(_In_ UCHAR Irq)
Definition: apic.c:344
KIRQL FASTCALL HalpVectorToIrql(UCHAR Vector)
Definition: apic.c:353
UCHAR FASTCALL HalpVectorToIrq(UCHAR Vector)
Definition: apic.c:360
KAFFINITY HalpDefaultInterruptAffinity
Definition: processor.c:18
#define CMCI_LEVEL
Definition: ketypes.h:15
#define CLOCK_LEVEL
Definition: ketypes.h:16
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define DPRINT
Definition: sndvol32.h:73
static void Exit(void)
Definition: sock.c:1330
_In_ ULONG _In_ ULONG BusInterruptLevel
Definition: halfuncs.h:171
#define NT_ASSERT
Definition: rtlfuncs.h:3334

Referenced by HalGetInterruptVector(), and HalpGetSystemInterruptVector().

◆ HalpInitializePICs()

VOID NTAPI HalpInitializePICs ( _In_ BOOLEAN  EnableInterrupts)

Definition at line 700 of file apic.c.

702{
703 ULONG_PTR EFlags;
704
705 /* Save EFlags and disable interrupts */
706 EFlags = __readeflags();
707 _disable();
708
709 /* Initialize and mask the PIC */
711
712 /* Initialize the I/O APIC */
714
715 /* Manually reserve some vectors */
722
723 /* Local APIC sources, all above the device vector range */
728
729 /* Set interrupt handlers in the IDT */
732#ifndef _M_AMD64
735#endif
736
737 /* Register the vectors for APC and dispatch interrupts */
740
741 /* Restore interrupt state */
743 __writeeflags(EFlags);
744}
VOID NTAPI ApicInitializeIOApic(VOID)
Definition: apic.c:632
#define CLOCK_IPI_VECTOR
Definition: apicp.h:47
#define APIC_IPI_VECTOR
Definition: apicp.h:48
#define APIC_PROFILE_VECTOR
Definition: apicp.h:51
static NTSTATUS EnableInterrupts(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR FlagsToDisable, IN UCHAR FlagsToEnable)
Definition: pnp.c:380
VOID HalpClockInterrupt(VOID)
Definition: timer.c:30
VOID NTAPI HalpRegisterVector(IN UCHAR Flags, IN ULONG BusVector, IN ULONG SystemVector, IN KIRQL Irql)
Definition: usage.c:34
VOID NTAPI HalpInitializeLegacyPICs(VOID)
Definition: pic.c:18
#define IDT_INTERNAL
Definition: halp.h:21
VOID __cdecl HalpDispatchInterrupt(VOID)
VOID __cdecl HalpApcInterrupt(VOID)
VOID __cdecl HalpClockIpi(VOID)
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1701
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by HalInitSystem().

◆ HalpIrqToVector()

UCHAR FASTCALL HalpIrqToVector ( _In_ UCHAR  Irq)

Definition at line 344 of file apic.c.

346{
347 /* Firmware can leave a vector in an entry, so use the allocation table */
348 return HalpGsivToVector[Irq];
349}

Referenced by HalpGetRootInterruptVector().

◆ HalpMapIoApic()

static VOID NTAPI HalpMapIoApic ( _In_ ULONG  PhysicalBase,
_In_ ULONG  InputBase 
)
static

Maps an I/O APIC and adds it to the units in use.

Parameters
[in]PhysicalBasePhysical address of the I/O APIC registers.
[in]InputBaseGlobal system interrupt of the first redirection entry.

Definition at line 587 of file apic.c.

590{
592 PHARDWARE_PTE Pte;
594
595 if ((HalpIoApicCount == HALP_MAX_IOAPICS) || (InputBase >= HALP_MAX_INPUTS))
596 {
597 DPRINT1("I/O APIC at 0x%lx with input base %lu ignored\n", PhysicalBase, InputBase);
598 return;
599 }
600
601 /* Each I/O APIC takes the next page from IOAPIC_BASE */
604 Pte = HalAddressToPte(Unit->Base);
605 Pte->PageFrameNumber = PhysicalBase / PAGE_SIZE;
606 Pte->Valid = 1;
607 Pte->Write = 1;
608 Pte->Owner = 1;
609 Pte->CacheDisable = 1;
610 Pte->Global = 1;
612 Unit->Base += BYTE_OFFSET(PhysicalBase);
613
614 /* Nothing decodes the address when all bits read back set */
616 if (Version == 0xFFFFFFFF)
617 {
618 DPRINT1("No I/O APIC responds at 0x%lx\n", PhysicalBase);
619 return;
620 }
621
622 /* Bits 23:16 hold the index of the last redirection entry, the register index caps the count */
623 Unit->InputBase = InputBase;
624 Unit->InputCount = min(((Version >> 16) & 0xFF) + 1, HALP_IOAPIC_MAX_ENTRIES);
625 Unit->InputCount = min(Unit->InputCount, HALP_MAX_INPUTS - InputBase);
626 HalpMaxGsi = max(HalpMaxGsi, InputBase + Unit->InputCount);
628}
#define HALP_MAX_IOAPICS
Definition: apicp.h:67
#define IOAPIC_BASE
Definition: apicp.h:38
#define IOAPIC_VER
Definition: apicp.h:307
#define HALP_MAX_INPUTS
Definition: apicp.h:66
#define HALP_IOAPIC_MAX_ENTRIES
Definition: apicp.h:68
#define ULONG_PTR
Definition: config.h:101
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define HalAddressToPte(x)
Definition: halp.h:187
#define _ReadWriteBarrier()
Definition: intrin_arm.h:36
ULONG_PTR Base
Definition: apic.c:38
ULONG64 Owner
Definition: mmtypes.h:68
ULONG64 PageFrameNumber
Definition: mmtypes.h:78
ULONG64 Write
Definition: mmtypes.h:67
ULONG64 Valid
Definition: mmtypes.h:66
ULONG64 CacheDisable
Definition: mmtypes.h:70
ULONG64 Global
Definition: mmtypes.h:74
#define max(a, b)
Definition: svc.c:63
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469
#define BYTE_OFFSET(Va)

Referenced by ApicInitializeIOApic().

◆ HalpQueryVectorInput()

static NTSTATUS NTAPI HalpQueryVectorInput ( _In_ ULONG  Vector,
_Out_ PULONG  Input,
_Out_ PKINTERRUPT_POLARITY  Polarity 
)
static

Asks the ACPI driver for the input of a vector it allocated.

Parameters
[in]VectorThe interrupt vector to look up.
[out]InputReceives the global system interrupt of the vector.
[out]PolarityReceives the polarity reported for the input.
Returns
STATUS_SUCCESS when an I/O APIC serves the input, STATUS_INVALID_PARAMETER for a message-signaled vector, or another error status otherwise.

Definition at line 884 of file apic.c.

888{
891
892 *Input = 0;
893 *Polarity = InterruptPolarityUnknown;
894
896 return STATUS_NOT_FOUND;
897
900 {
901 DPRINT1("No I/O APIC serves input %lu of vector 0x%lx\n", *Input, Vector);
902 return STATUS_NOT_FOUND;
903 }
904
905 return Status;
906}
#define HalGetVectorInputOverride
Definition: halfuncs.h:62
#define STATUS_NOT_FOUND
Definition: shellext.h:72

Referenced by HalEnableSystemInterrupt().

◆ HalpSendEOI()

VOID NTAPI HalpSendEOI ( VOID  )

Definition at line 367 of file apic.c.

368{
369 ApicSendEOI();
370}

◆ HalpVectorToIrq()

UCHAR FASTCALL HalpVectorToIrq ( UCHAR  Vector)

Definition at line 360 of file apic.c.

361{
363}

Referenced by HalpGetRootInterruptVector().

◆ HalpVectorToIrql()

KIRQL FASTCALL HalpVectorToIrql ( UCHAR  Vector)

Definition at line 353 of file apic.c.

354{
355 return TprToIrql(Vector);
356}

Referenced by HalpGetRootInterruptVector().

◆ HalRequestSoftwareInterrupt()

VOID FASTCALL HalRequestSoftwareInterrupt ( IN KIRQL  Irql)

Definition at line 847 of file apic.c.

848{
849 /* Convert irql to vector and request an interrupt */
851}
#define IrqlToSoftVector(Irql)
Definition: apicp.h:56

◆ IOApicRead()

FORCEINLINE ULONG IOApicRead ( _In_ ULONG_PTR  Base,
_In_ UCHAR  Register 
)

Definition at line 122 of file apic.c.

125{
126 /* Select the register, then do the read */
129}
#define IOAPIC_IOWIN
Definition: apicp.h:303
#define IOAPIC_IOREGSEL
Definition: apicp.h:302
#define WRITE_REGISTER_ULONG(r, v)
Definition: arm.h:11
#define READ_REGISTER_ULONG(r)
Definition: arm.h:10
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2486
uint32_t * PULONG
Definition: typedefs.h:59

Referenced by ApicInitializeIOApic(), and HalpMapIoApic().

◆ IOApicWrite()

FORCEINLINE VOID IOApicWrite ( _In_ ULONG_PTR  Base,
_In_ UCHAR  Register,
_In_ ULONG  Value 
)

Definition at line 133 of file apic.c.

137{
138 /* Select the register, then do the write */
141}
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by ApicWriteIORedirectionEntry().

◆ KeGetCurrentIrql()

KIRQL NTAPI KeGetCurrentIrql ( VOID  )

Definition at line 1140 of file apic.c.

1141{
1142 /* Read the current TPR and convert it to an IRQL */
1143 return ApicGetCurrentIrql();
1144}

◆ KeRaiseIrqlToDpcLevel()

KIRQL NTAPI KeRaiseIrqlToDpcLevel ( VOID  )

Definition at line 1189 of file apic.c.

1190{
1192}
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: apic.c:1165

◆ KeRaiseIrqlToSynchLevel()

KIRQL NTAPI KeRaiseIrqlToSynchLevel ( VOID  )

Definition at line 1196 of file apic.c.

1197{
1198 return KfRaiseIrql(SYNCH_LEVEL);
1199}
#define SYNCH_LEVEL
Definition: env_spec_w32.h:704

◆ KfLowerIrql()

VOID FASTCALL KfLowerIrql ( IN KIRQL  OldIrql)

Definition at line 1148 of file apic.c.

1150{
1151#if DBG
1152 /* Validate correct lower */
1154 {
1155 /* Crash system */
1156 KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
1157 }
1158#endif
1159 /* Set the new IRQL */
1161}
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1434

◆ KfRaiseIrql()

KIRQL FASTCALL KfRaiseIrql ( IN KIRQL  NewIrql)

Definition at line 1165 of file apic.c.

1167{
1168 KIRQL OldIrql;
1169
1170 /* Read the current IRQL */
1172#if DBG
1173 /* Validate correct raise */
1174 if (OldIrql > NewIrql)
1175 {
1176 /* Crash system */
1177 KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
1178 }
1179#endif
1180 /* Convert the new IRQL to a TPR value and write the register */
1182
1183 /* Return old IRQL */
1184 return OldIrql;
1185}
_Requires_lock_held_ SpinLock _Releases_lock_ SpinLock _In_ _IRQL_restores_ KIRQL NewIrql
Definition: ke.h:114

Referenced by KeRaiseIrqlToDpcLevel(), and KeRaiseIrqlToSynchLevel().

Variable Documentation

◆ ApicVersion

ULONG ApicVersion

Definition at line 28 of file apic.c.

Referenced by ApicInitializeLocalApic(), and ApicStartApplicationProcessor().

◆ HalpApicInfoTable

HALP_APIC_INFO_TABLE HalpApicInfoTable
extern

Definition at line 19 of file misc.c.

Referenced by ApicInitializeIOApic(), and HalpGetInputPolarity().

◆ HalpGsivToVector

◆ HalpIoApicCount

ULONG HalpIoApicCount

Definition at line 45 of file apic.c.

Referenced by ApicInitializeIOApic(), HalpFindIoApicInput(), and HalpMapIoApic().

◆ HalpIoApics

Definition at line 44 of file apic.c.

Referenced by ApicInitializeIOApic(), HalpFindIoApicInput(), and HalpMapIoApic().

◆ HalpIoApicShadow

◆ HalpIRQLtoTPR

const UCHAR HalpIRQLtoTPR[32]

Definition at line 60 of file apic.c.

◆ HalpMaxGsi

◆ HalpVectorToIndex

◆ HalVectorToIRQL

const KIRQL HalVectorToIRQL[16]
Initial value:
=
{
0,
0xff,
0xff,
1,
2,
4,
5,
6,
7,
8,
9,
10,
27,
28,
29,
31,
}

Definition at line 97 of file apic.c.