ReactOS  0.4.15-dev-3207-ga415bd4
apic.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS HAL
3  * LICENSE: GNU GPL - See COPYING in the top level directory
4  * FILE: hal/halx86/apic/apic.c
5  * PURPOSE: HAL APIC Management and Control Code
6  * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
7  * REFERENCES: https://web.archive.org/web/20190407074221/http://www.joseflores.com/docs/ExploringIrql.html
8  * http://www.codeproject.com/KB/system/soviet_kernel_hack.aspx
9  * http://bbs.unixmap.net/thread-2022-1-1.html
10  * https://www.codemachine.com/article_interruptdispatching.html
11  * https://www.osronline.com/article.cfm%5Earticle=211.htm
12  */
13 
14 /* INCLUDES *******************************************************************/
15 
16 #include <hal.h>
17 #include "apicp.h"
18 #define NDEBUG
19 #include <debug.h>
20 
21 #ifndef _M_AMD64
22 #define APIC_LAZY_IRQL
23 #endif
24 
25 /* GLOBALS ********************************************************************/
26 
29 
30 #ifndef _M_AMD64
31 const UCHAR
33 {
34  0x00, /* 0 PASSIVE_LEVEL */
35  0x3d, /* 1 APC_LEVEL */
36  0x41, /* 2 DISPATCH_LEVEL */
37  0x41, /* 3 \ */
38  0x51, /* 4 \ */
39  0x61, /* 5 | */
40  0x71, /* 6 | */
41  0x81, /* 7 | */
42  0x91, /* 8 | */
43  0xa1, /* 9 | */
44  0xb1, /* 10 | */
45  0xb1, /* 11 | */
46  0xb1, /* 12 | */
47  0xb1, /* 13 | */
48  0xb1, /* 14 | */
49  0xb1, /* 15 DEVICE IRQL */
50  0xb1, /* 16 | */
51  0xb1, /* 17 | */
52  0xb1, /* 18 | */
53  0xb1, /* 19 | */
54  0xb1, /* 20 | */
55  0xb1, /* 21 | */
56  0xb1, /* 22 | */
57  0xb1, /* 23 | */
58  0xb1, /* 24 | */
59  0xb1, /* 25 / */
60  0xb1, /* 26 / */
61  0xc1, /* 27 PROFILE_LEVEL */
62  0xd1, /* 28 CLOCK2_LEVEL */
63  0xe1, /* 29 IPI_LEVEL */
64  0xef, /* 30 POWER_LEVEL */
65  0xff, /* 31 HIGH_LEVEL */
66 };
67 
68 const KIRQL
70 {
71  0, /* 00 PASSIVE_LEVEL */
72  0xff, /* 10 */
73  0xff, /* 20 */
74  1, /* 3D APC_LEVEL */
75  2, /* 41 DISPATCH_LEVEL */
76  4, /* 50 \ */
77  5, /* 60 \ */
78  6, /* 70 | */
79  7, /* 80 DEVICE IRQL */
80  8, /* 90 | */
81  9, /* A0 / */
82  10, /* B0 / */
83  27, /* C1 PROFILE_LEVEL */
84  28, /* D1 CLOCK2_LEVEL */
85  29, /* E1 IPI_LEVEL / EF POWER_LEVEL */
86  31, /* FF HIGH_LEVEL */
87 };
88 #endif
89 
90 /* PRIVATE FUNCTIONS **********************************************************/
91 
93 ULONG
94 IOApicRead(UCHAR Register)
95 {
96  /* Select the register, then do the read */
97  ASSERT(Register <= 0x3F);
100 }
101 
103 VOID
105 {
106  /* Select the register, then do the write */
107  ASSERT(Register <= 0x3F);
110 }
111 
113 VOID
115  UCHAR Index,
117 {
119  IOApicWrite(IOAPIC_REDTBL + 2 * Index, ReDirReg.Long0);
120  IOApicWrite(IOAPIC_REDTBL + 2 * Index + 1, ReDirReg.Long1);
121 }
122 
126  UCHAR Index)
127 {
129 
131  ReDirReg.Long0 = IOApicRead(IOAPIC_REDTBL + 2 * Index);
132  ReDirReg.Long1 = IOApicRead(IOAPIC_REDTBL + 2 * Index + 1);
133 
134  return ReDirReg;
135 }
136 
138 VOID
140 {
142 
143  /* Setup the command register */
144  Icr.Long0 = 0;
145  Icr.Vector = Vector;
147  Icr.TriggerMode = TriggerMode;
149 
150  /* Write the low dword to send the interrupt */
151  ApicWrite(APIC_ICR0, Icr.Long0);
152 }
153 
155 VOID
157 {
158  ApicWrite(APIC_EOI, 0);
159 }
160 
162 KIRQL
164 {
165  /* Read the TPR and convert it to an IRQL */
166  return TprToIrql(ApicRead(APIC_PPR));
167 }
168 
170 KIRQL
172 {
173 #ifdef _M_AMD64
174  return (KIRQL)__readcr8();
175 #elif defined(APIC_LAZY_IRQL)
176  /* Return the field in the PCR */
178 #else
179  /* Read the TPR and convert it to an IRQL */
180  return TprToIrql(ApicRead(APIC_TPR));
181 #endif
182 }
183 
185 VOID
187 {
188 #ifdef _M_AMD64
189  __writecr8(Irql);
190 #elif defined(APIC_LAZY_IRQL)
192 #else
193  /* Convert IRQL and write the TPR */
195 #endif
196 }
197 #define ApicRaiseIrql ApicSetIrql
198 
199 #ifdef APIC_LAZY_IRQL
201 VOID
203 {
205 
206  /* Is the new Irql lower than set in the TPR? */
207  if (Irql < KeGetPcr()->IRR)
208  {
209  /* Save the new hard IRQL in the IRR field */
210  KeGetPcr()->IRR = Irql;
211 
212  /* Need to lower it back */
214  }
215 }
216 #else
217 #define ApicLowerIrql ApicSetIrql
218 #endif
219 
220 UCHAR
221 FASTCALL
223 {
225 
226  /* Read low dword of the redirection entry */
227  ReDirReg.Long0 = IOApicRead(IOAPIC_REDTBL + 2 * Irq);
228 
229  /* Return the vector */
230  return (UCHAR)ReDirReg.Vector;
231 }
232 
233 KIRQL
234 FASTCALL
236 {
237  return TprToIrql(Vector);
238 }
239 
240 UCHAR
241 FASTCALL
243 {
244  return HalpVectorToIndex[Vector];
245 }
246 
247 VOID
248 NTAPI
250 {
251  ApicSendEOI();
252 }
253 
254 VOID
255 NTAPI
257 {
258  APIC_BASE_ADRESS_REGISTER BaseRegister;
259  APIC_SPURIOUS_INERRUPT_REGISTER SpIntRegister;
260  LVT_REGISTER LvtEntry;
261 
262  /* Enable the APIC if it wasn't yet */
263  BaseRegister.LongLong = __readmsr(MSR_APIC_BASE);
264  BaseRegister.Enable = 1;
265  BaseRegister.BootStrapCPUCore = (Cpu == 0);
266  __writemsr(MSR_APIC_BASE, BaseRegister.LongLong);
267 
268  /* Set spurious vector and SoftwareEnable to 1 */
269  SpIntRegister.Long = ApicRead(APIC_SIVR);
270  SpIntRegister.Vector = APIC_SPURIOUS_VECTOR;
271  SpIntRegister.SoftwareEnable = 1;
272  SpIntRegister.FocusCPUCoreChecking = 0;
273  ApicWrite(APIC_SIVR, SpIntRegister.Long);
274 
275  /* Read the version and save it globally */
276  if (Cpu == 0) ApicVersion = ApicRead(APIC_VER);
277 
278  /* Set the mode to flat (max 8 CPUs supported!) */
280 
281  /* Set logical apic ID */
282  ApicWrite(APIC_LDR, ApicLogicalId(Cpu) << 24);
283 
284  /* Set the spurious ISR */
286 
287  /* Create a template LVT */
288  LvtEntry.Long = 0;
289  LvtEntry.Vector = APIC_FREE_VECTOR;
290  LvtEntry.MessageType = APIC_MT_Fixed;
291  LvtEntry.DeliveryStatus = 0;
292  LvtEntry.RemoteIRR = 0;
293  LvtEntry.TriggerMode = APIC_TGM_Edge;
294  LvtEntry.Mask = 1;
295  LvtEntry.TimerMode = 0;
296 
297  /* Initialize and mask LVTs */
298  ApicWrite(APIC_TMRLVTR, LvtEntry.Long);
299  ApicWrite(APIC_THRMLVTR, LvtEntry.Long);
300  ApicWrite(APIC_PCLVTR, LvtEntry.Long);
301  ApicWrite(APIC_EXT0LVTR, LvtEntry.Long);
302  ApicWrite(APIC_EXT1LVTR, LvtEntry.Long);
303  ApicWrite(APIC_EXT2LVTR, LvtEntry.Long);
304  ApicWrite(APIC_EXT3LVTR, LvtEntry.Long);
305 
306  /* LINT0 */
307  LvtEntry.Vector = APIC_SPURIOUS_VECTOR;
308  LvtEntry.MessageType = APIC_MT_ExtInt;
309  ApicWrite(APIC_LINT0, LvtEntry.Long);
310 
311  /* Enable LINT1 (NMI) */
312  LvtEntry.Mask = 0;
313  LvtEntry.Vector = APIC_NMI_VECTOR;
314  LvtEntry.MessageType = APIC_MT_NMI;
315  LvtEntry.TriggerMode = APIC_TGM_Level;
316  ApicWrite(APIC_LINT1, LvtEntry.Long);
317 
318  /* Enable error LVTR */
319  LvtEntry.Vector = APIC_ERROR_VECTOR;
320  LvtEntry.MessageType = APIC_MT_Fixed;
321  ApicWrite(APIC_ERRLVTR, LvtEntry.Long);
322 
323  /* Set the IRQL from the PCR */
325 #ifdef APIC_LAZY_IRQL
326  /* Save the new hard IRQL in the IRR field */
327  KeGetPcr()->IRR = KeGetPcr()->Irql;
328 #endif
329 }
330 
331 UCHAR
332 NTAPI
334  _In_ UCHAR Irq,
335  _In_ UCHAR Vector)
336 {
338 
339  ASSERT(Irq < APIC_MAX_IRQ);
341 
342  /* Setup a redirection entry */
343  ReDirReg.Vector = Vector;
345  ReDirReg.DestinationMode = APIC_DM_Logical;
346  ReDirReg.DeliveryStatus = 0;
347  ReDirReg.Polarity = 0;
348  ReDirReg.RemoteIRR = 0;
349  ReDirReg.TriggerMode = APIC_TGM_Edge;
350  ReDirReg.Mask = 1;
351  ReDirReg.Reserved = 0;
352  ReDirReg.Destination = 0;
353 
354  /* Initialize entry */
355  ApicWriteIORedirectionEntry(Irq, ReDirReg);
356 
357  /* Save irq in the table */
358  HalpVectorToIndex[Vector] = Irq;
359 
360  return Vector;
361 }
362 
363 ULONG
364 NTAPI
368  _Out_ PKIRQL OutIrql,
369  _Out_ PKAFFINITY OutAffinity)
370 {
371  UCHAR Vector;
372  KIRQL Irql;
373 
374  /* Get the vector currently registered */
376 
377  /* Check if it's used */
378  if (Vector != APIC_FREE_VECTOR)
379  {
380  /* Calculate IRQL */
382  *OutIrql = HalpVectorToIrql(Vector);
383  }
384  else
385  {
386  ULONG Offset;
387 
388  /* Outer loop to find alternative slots, when all IRQLs are in use */
389  for (Offset = 0; Offset < 15; Offset++)
390  {
391  /* Loop allowed IRQL range */
392  for (Irql = CLOCK_LEVEL - 1; Irql >= CMCI_LEVEL; Irql--)
393  {
394  /* Calculate the vactor */
396 
397  /* Check if the vector is free */
399  {
400  /* Found one, allocate the interrupt */
402  *OutIrql = Irql;
403  goto Exit;
404  }
405  }
406  }
407 
408  DPRINT1("Failed to get an interrupt vector for IRQ %lu\n", BusInterruptLevel);
409  *OutAffinity = 0;
410  *OutIrql = 0;
411  return 0;
412  }
413 
414 Exit:
415 
416  *OutAffinity = HalpDefaultInterruptAffinity;
418 
419  return Vector;
420 }
421 
422 VOID
423 NTAPI
425 {
426  PHARDWARE_PTE Pte;
428  UCHAR Index;
429  ULONG Vector;
430 
431  /* Map the I/O Apic page */
434  Pte->Valid = 1;
435  Pte->Write = 1;
436  Pte->Owner = 1;
437  Pte->CacheDisable = 1;
438  Pte->Global = 1;
440 
441  /* Setup a redirection entry */
442  ReDirReg.Vector = APIC_FREE_VECTOR;
443  ReDirReg.DeliveryMode = APIC_MT_Fixed;
445  ReDirReg.DeliveryStatus = 0;
446  ReDirReg.Polarity = 0;
447  ReDirReg.RemoteIRR = 0;
448  ReDirReg.TriggerMode = APIC_TGM_Edge;
449  ReDirReg.Mask = 1;
450  ReDirReg.Reserved = 0;
451  ReDirReg.Destination = 0;
452 
453  /* Loop all table entries */
454  for (Index = 0; Index < APIC_MAX_IRQ; Index++)
455  {
456  /* Initialize entry */
458  }
459 
460  /* Init the vactor to index table */
461  for (Vector = 0; Vector <= 255; Vector++)
462  {
464  }
465 
466  /* Enable the timer interrupt (but keep it masked) */
467  ReDirReg.Vector = APIC_CLOCK_VECTOR;
468  ReDirReg.DeliveryMode = APIC_MT_Fixed;
470  ReDirReg.TriggerMode = APIC_TGM_Edge;
471  ReDirReg.Mask = 1;
472  ReDirReg.Destination = ApicRead(APIC_ID);
474 }
475 
476 VOID
477 NTAPI
479 {
480  ULONG_PTR EFlags;
481 
482  /* Save EFlags and disable interrupts */
483  EFlags = __readeflags();
484  _disable();
485 
486  /* Initialize and mask the PIC */
488 
489  /* Initialize the I/O APIC */
491 
492  /* Manually reserve some vectors */
497 
498  /* Set interrupt handlers in the IDT */
500 #ifndef _M_AMD64
503 #endif
504 
505  /* Register the vectors for APC and dispatch interrupts */
508 
509  /* Restore interrupt state */
511  __writeeflags(EFlags);
512 }
513 
514 
515 /* SOFTWARE INTERRUPT TRAPS ***************************************************/
516 
517 #ifndef _M_AMD64
518 VOID
520 FASTCALL
522 {
523  KPROCESSOR_MODE ProcessorMode;
524  KIRQL OldIrql;
526 
527  /* Enter trap */
528  KiEnterInterruptTrap(TrapFrame);
529 
530 #ifdef APIC_LAZY_IRQL
532  {
533  /* "Spurious" interrupt, exit the interrupt */
534  KiEoiHelper(TrapFrame);
535  }
536 #else
537  /* Save the old IRQL */
540 #endif
541 
542  /* Raise to APC_LEVEL */
544 
545  /* End the interrupt */
546  ApicSendEOI();
547 
548  /* Kernel or user APC? */
549  if (KiUserTrap(TrapFrame)) ProcessorMode = UserMode;
550  else if (TrapFrame->EFlags & EFLAGS_V86_MASK) ProcessorMode = UserMode;
551  else ProcessorMode = KernelMode;
552 
553  /* Enable interrupts and call the kernel's APC interrupt handler */
554  _enable();
555  KiDeliverApc(ProcessorMode, NULL, TrapFrame);
556 
557  /* Disable interrupts */
558  _disable();
559 
560  /* Restore the old IRQL */
562 
563  /* Exit the interrupt */
564  KiEoiHelper(TrapFrame);
565 }
566 
567 VOID
569 FASTCALL
571 {
572  KIRQL OldIrql;
574 
575  /* Enter trap */
576  KiEnterInterruptTrap(TrapFrame);
577 
578 #ifdef APIC_LAZY_IRQL
580  {
581  /* "Spurious" interrupt, exit the interrupt */
582  KiEoiHelper(TrapFrame);
583  }
584 #else
585  /* Get the current IRQL */
588 #endif
589 
590  /* Raise to DISPATCH_LEVEL */
592 
593  /* End the interrupt */
594  ApicSendEOI();
595 
596  /* Enable interrupts and call the kernel's DPC interrupt handler */
597  _enable();
599  _disable();
600 
601  /* Restore the old IRQL */
603 
604  /* Exit the interrupt */
605  KiEoiHelper(TrapFrame);
606 }
607 #endif
608 
609 
610 /* SOFTWARE INTERRUPTS ********************************************************/
611 
612 
613 VOID
614 FASTCALL
616 {
617  /* Convert irql to vector and request an interrupt */
619 }
620 
621 VOID
622 FASTCALL
624  IN KIRQL Irql)
625 {
626  /* Nothing to do */
627 }
628 
629 
630 /* SYSTEM INTERRUPTS **********************************************************/
631 
632 BOOLEAN
633 NTAPI
635  IN ULONG Vector,
636  IN KIRQL Irql,
638 {
640  PKPRCB Prcb = KeGetCurrentPrcb();
641  UCHAR Index;
642  ASSERT(Irql <= HIGH_LEVEL);
643  ASSERT((IrqlToTpr(Irql) & 0xF0) == (Vector & 0xF0));
644 
645  /* Get the irq for this vector */
647 
648  /* Check if its valid */
649  if (Index == APIC_FREE_VECTOR)
650  {
651  /* Interrupt is not in use */
652  return FALSE;
653  }
654 
655  /* Read the redirection entry */
656  ReDirReg = ApicReadIORedirectionEntry(Index);
657 
658  /* Check if the interrupt was unused */
659  if (ReDirReg.Vector != Vector)
660  {
661  ReDirReg.Vector = Vector;
663  ReDirReg.DestinationMode = APIC_DM_Logical;
664  ReDirReg.Destination = 0;
665  }
666 
667  /* Check if the destination is logical */
668  if (ReDirReg.DestinationMode == APIC_DM_Logical)
669  {
670  /* Set the bit for this cpu */
671  ReDirReg.Destination |= ApicLogicalId(Prcb->Number);
672  }
673 
674  /* Set the trigger mode */
675  ReDirReg.TriggerMode = 1 - InterruptMode;
676 
677  /* Now unmask it */
678  ReDirReg.Mask = FALSE;
679 
680  /* Write back the entry */
682 
683  return TRUE;
684 }
685 
686 VOID
687 NTAPI
689  IN ULONG Vector,
690  IN KIRQL Irql)
691 {
693  UCHAR Index;
694  ASSERT(Irql <= HIGH_LEVEL);
696 
698 
699  /* Read lower dword of redirection entry */
700  ReDirReg.Long0 = IOApicRead(IOAPIC_REDTBL + 2 * Index);
701 
702  /* Mask it */
703  ReDirReg.Mask = 1;
704 
705  /* Write back lower dword */
706  IOApicWrite(IOAPIC_REDTBL + 2 * Index, ReDirReg.Long0);
707 }
708 
709 #ifndef _M_AMD64
710 BOOLEAN
711 NTAPI
713  IN KIRQL Irql,
714  IN ULONG Vector,
716 {
717  KIRQL CurrentIrql;
718 
719  /* Get the current IRQL */
720  CurrentIrql = ApicGetCurrentIrql();
721 
722 #ifdef APIC_LAZY_IRQL
723  /* Check if this interrupt is allowed */
724  if (CurrentIrql >= Irql)
725  {
727  UCHAR Index;
728 
729  /* It is not, set the real Irql in the TPR! */
730  ApicWrite(APIC_TPR, IrqlToTpr(CurrentIrql));
731 
732  /* Save the new hard IRQL in the IRR field */
733  KeGetPcr()->IRR = CurrentIrql;
734 
735  /* End this interrupt */
736  ApicSendEOI();
737 
738  /* Get the irq for this vector */
740 
741  /* Check if it's valid */
742  if (Index < APIC_MAX_IRQ)
743  {
744  /* Read the I/O redirection entry */
745  RedirReg = ApicReadIORedirectionEntry(Index);
746 
747  /* Re-request the interrupt to be handled later */
749  }
750  else
751  {
752  /* This should be a reserved vector! */
754 
755  /* Re-request the interrupt to be handled later */
757  }
758 
759  /* Pretend it was a spurious interrupt */
760  return FALSE;
761  }
762 #endif
763  /* Save the current IRQL */
764  *OldIrql = CurrentIrql;
765 
766  /* Set the new IRQL */
768 
769  /* Turn on interrupts */
770  _enable();
771 
772  /* Success */
773  return TRUE;
774 }
775 
776 VOID
777 NTAPI
779  IN KIRQL OldIrql,
780  IN PKTRAP_FRAME TrapFrame)
781 {
782  /* Send an EOI */
783  ApicSendEOI();
784 
785  /* Restore the old IRQL */
787 }
788 
789 
790 /* IRQL MANAGEMENT ************************************************************/
791 
792 KIRQL
793 NTAPI
795 {
796  /* Read the current TPR and convert it to an IRQL */
797  return ApicGetCurrentIrql();
798 }
799 
800 VOID
801 FASTCALL
803  IN KIRQL OldIrql)
804 {
805 #if DBG
806  /* Validate correct lower */
807  if (OldIrql > ApicGetCurrentIrql())
808  {
809  /* Crash system */
810  KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
811  }
812 #endif
813  /* Set the new IRQL */
815 }
816 
817 KIRQL
818 FASTCALL
820  IN KIRQL NewIrql)
821 {
822  KIRQL OldIrql;
823 
824  /* Read the current IRQL */
826 #if DBG
827  /* Validate correct raise */
828  if (OldIrql > NewIrql)
829  {
830  /* Crash system */
831  KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
832  }
833 #endif
834  /* Convert the new IRQL to a TPR value and write the register */
836 
837  /* Return old IRQL */
838  return OldIrql;
839 }
840 
841 KIRQL
842 NTAPI
844 {
845  return KfRaiseIrql(DISPATCH_LEVEL);
846 }
847 
848 KIRQL
849 NTAPI
851 {
852  return KfRaiseIrql(SYNCH_LEVEL);
853 }
854 
855 #endif /* !_M_AMD64 */
856 
ULONG64 Valid
Definition: mmtypes.h:66
UCHAR FASTCALL HalpVectorToIrq(UCHAR Vector)
Definition: apic.c:242
_In_ ULONG _In_ ULONG BusInterruptLevel
Definition: halfuncs.h:170
#define IN
Definition: typedefs.h:39
static NTSTATUS EnableInterrupts(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR FlagsToDisable, IN UCHAR FlagsToEnable)
Definition: pnp.c:380
NTKERNELAPI VOID NTAPI WRITE_REGISTER_ULONG(IN PULONG Register, IN ULONG Value)
FORCEINLINE VOID ApicRequestSelfInterrupt(IN UCHAR Vector, UCHAR TriggerMode)
Definition: apic.c:139
Definition: apicp.h:80
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:800
#define _ReadWriteBarrier()
Definition: intrin_arm.h:36
KAFFINITY HalpDefaultInterruptAffinity
Definition: processor.c:18
#define _Out_
Definition: ms_sal.h:345
Definition: apicp.h:87
ULONG64 Global
Definition: mmtypes.h:74
#define TRUE
Definition: types.h:120
ULONG64 Owner
Definition: mmtypes.h:68
FORCEINLINE ULONG ApicRead(APIC_REGISTER Register)
Definition: apicp.h:321
ULONG64 CacheDisable
Definition: mmtypes.h:70
VOID NTAPI HalpRegisterVector(IN UCHAR Flags, IN ULONG BusVector, IN ULONG SystemVector, IN KIRQL Irql)
Definition: usage.c:34
void __cdecl _enable(void)
Definition: intrin_arm.h:373
VOID NTAPI HalpSendEOI(VOID)
Definition: apic.c:249
UINT32 Vector
Definition: apicp.h:266
UINT32 DeliveryStatus
Definition: apicp.h:269
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1079
#define HalAddressToPte(x)
Definition: halp.h:163
const UCHAR HalpIRQLtoTPR[32]
Definition: apic.c:32
Definition: ke.h:289
#define APIC_NMI_VECTOR
Definition: apicp.h:51
FORCEINLINE KIRQL ApicGetProcessorIrql(VOID)
Definition: apic.c:163
FORCEINLINE IOAPIC_REDIRECTION_REGISTER ApicReadIORedirectionEntry(UCHAR Index)
Definition: apic.c:125
_In_ ULONG _In_ ULONG _In_ ULONG BusInterruptVector
Definition: halfuncs.h:170
NTKERNELAPI ULONG NTAPI READ_REGISTER_ULONG(IN PULONG Register)
ULONG ApicVersion
Definition: apic.c:27
#define FASTCALL
Definition: nt_native.h:50
_Out_ PKIRQL Irql
Definition: csq.h:179
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
#define APIC_SPURIOUS_VECTOR
Definition: apicp.h:40
#define KeGetPcr()
Definition: ke.h:26
#define EFLAGS_V86_MASK
Definition: ketypes.h:132
FORCEINLINE KIRQL ApicGetCurrentIrql(VOID)
Definition: apic.c:171
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ApicLogicalId(Cpu)
Definition: apicp.h:116
#define CMCI_LEVEL
FORCEINLINE VOID ApicWriteIORedirectionEntry(UCHAR Index, IOAPIC_REDIRECTION_REGISTER ReDirReg)
Definition: apic.c:114
UCHAR KIRQL
Definition: env_spec_w32.h:591
UCHAR FASTCALL HalpIrqToVector(UCHAR Irq)
Definition: apic.c:222
#define CLOCK_LEVEL
UINT32 Long
Definition: apicp.h:263
VOID FASTCALL KfLowerIrql(IN KIRQL OldIrql)
Definition: apic.c:802
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1675
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
FORCEINLINE VOID ApicWrite(APIC_REGISTER Register, ULONG Value)
Definition: apicp.h:328
BOOLEAN NTAPI HalEnableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql, IN KINTERRUPT_MODE InterruptMode)
Definition: apic.c:634
Definition: apicp.h:83
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
VOID __cdecl HalpDispatchInterrupt(VOID)
VOID NTAPI ApicInitializeIOApic(VOID)
Definition: apic.c:424
KAFFINITY * PKAFFINITY
Definition: basetsd.h:197
KIRQL FASTCALL HalpVectorToIrql(UCHAR Vector)
Definition: apic.c:235
unsigned char BOOLEAN
UCHAR NTAPI HalpAllocateSystemInterrupt(_In_ UCHAR Irq, _In_ UCHAR Vector)
Definition: apic.c:333
#define ApicRaiseIrql
Definition: apic.c:197
Definition: apicp.h:79
enum _KINTERRUPT_MODE KINTERRUPT_MODE
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
#define _In_
Definition: ms_sal.h:308
#define APIC_CLOCK_VECTOR
Definition: apicp.h:44
KIRQL NTAPI KeGetCurrentIrql(VOID)
Definition: apic.c:794
#define IrqlToSoftVector(Irql)
Definition: apicp.h:54
FORCEINLINE VOID IOApicWrite(UCHAR Register, ULONG Value)
Definition: apic.c:104
UINT32 TimerMode
Definition: apicp.h:274
UINT32 Mask
Definition: apicp.h:273
UCHAR HalpVectorToIndex[256]
Definition: apic.c:28
KIRQL OldIrql
Definition: mm.h:1502
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define APC_VECTOR
Definition: apicp.h:41
#define ASSERT(a)
Definition: mode.c:44
#define MSR_APIC_BASE
Definition: apicp.h:113
UINT32 RemoteIRR
Definition: apicp.h:271
#define APIC_FREE_VECTOR
Definition: apicp.h:59
#define APIC_RESERVED_VECTOR
Definition: apicp.h:60
VOID NTAPI HalDisableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql)
Definition: apic.c:688
FORCEINLINE VOID ApicLowerIrql(KIRQL Irql)
Definition: apic.c:202
_In_ WDFCOLLECTION _In_ ULONG Index
static void Exit(void)
Definition: sock.c:1331
PPC_QUAL unsigned char __readfsbyte(const unsigned long Offset)
Definition: intrin_ppc.h:360
PPC_QUAL void __writefsbyte(const unsigned long Offset, const unsigned char Data)
Definition: intrin_ppc.h:342
UINT32 MessageType
Definition: apicp.h:267
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define APIC_ERROR_VECTOR
Definition: apicp.h:47
#define IOAPIC_PHYS_BASE
Definition: apicp.h:114
unsigned char UCHAR
Definition: xmlstorage.h:181
ULONG64 PageFrameNumber
Definition: mmtypes.h:78
#define IDT_INTERNAL
Definition: halp.h:21
VOID __cdecl HalpApcInterrupt(VOID)
#define IrqlToTpr(Irql)
Definition: apicp.h:53
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1670
VOID NTAPI KiDispatchInterrupt(VOID)
Definition: thrdini.c:295
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define SYNCH_LEVEL
Definition: env_spec_w32.h:704
VOID DECLSPEC_NORETURN FASTCALL HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:521
VOID HalpClockInterrupt(VOID)
Definition: timer.c:30
FORCEINLINE BOOLEAN KiUserTrap(IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:360
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
FORCEINLINE VOID KeRegisterInterruptHandler(IN ULONG Vector, IN PVOID Handler)
Definition: ke.h:297
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
const KIRQL HalVectorToIRQL[16]
Definition: apic.c:69
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: apic.c:615
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: apic.c:850
FORCEINLINE VOID KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:368
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
Definition: apicp.h:86
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG Vector
Definition: iofuncs.h:800
#define FORCEINLINE
Definition: wdftypes.h:67
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
FORCEINLINE VOID ApicSetIrql(KIRQL Irql)
Definition: apic.c:186
VOID DECLSPEC_NORETURN FASTCALL HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:570
ULONG NTAPI HalpGetRootInterruptVector(_In_ ULONG BusInterruptLevel, _In_ ULONG BusInterruptVector, _Out_ PKIRQL OutIrql, _Out_ PKAFFINITY OutAffinity)
Definition: apic.c:365
FORCEINLINE ULONG IOApicRead(UCHAR Register)
Definition: apic.c:94
#define DPRINT1
Definition: precomp.h:8
ULONG64 Write
Definition: mmtypes.h:67
#define OUT
Definition: typedefs.h:40
USHORT Number
Definition: ketypes.h:563
void __cdecl _disable(void)
Definition: intrin_arm.h:365
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID ApicSendEOI(void)
Definition: apic.c:156
#define APIC_CLOCK_INDEX
Definition: apicp.h:115
KIRQL NTAPI KeRaiseIrqlToDpcLevel(VOID)
Definition: apic.c:843
#define DISPATCH_VECTOR
Definition: apicp.h:42
#define IOAPIC_BASE
Definition: apicp.h:37
Definition: apicp.h:84
VOID __cdecl ApicSpuriousService(VOID)
VOID NTAPI ApicInitializeLocalApic(ULONG Cpu)
Definition: apic.c:256
#define APIC_MAX_IRQ
Definition: apicp.h:58
VOID NTAPI KiDeliverApc(IN KPROCESSOR_MODE DeliveryMode, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
Definition: apc.c:302
UINT32 TriggerMode
Definition: apicp.h:272
VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Irql)
Definition: apic.c:623
#define APC_LEVEL
Definition: env_spec_w32.h:695
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts)
Definition: apic.c:478
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: apic.c:819
Definition: apicp.h:81
VOID NTAPI HalpInitializeLegacyPICs(VOID)
Definition: pic.c:18
_Requires_lock_held_ SpinLock _Releases_lock_ SpinLock _In_ _IRQL_restores_ KIRQL NewIrql
Definition: ke.h:114
BOOLEAN NTAPI HalBeginSystemInterrupt(IN KIRQL Irql, IN ULONG Vector, OUT PKIRQL OldIrql)
Definition: apic.c:712
#define TprToIrql(Tpr)
Definition: apicp.h:55
VOID NTAPI HalEndSystemInterrupt(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:778
#define EFLAGS_INTERRUPT_MASK
Definition: ketypes.h:126
#define NT_ASSERT
Definition: rtlfuncs.h:3310