ReactOS  0.4.15-dev-5112-g22d8c0f
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 {
141  ULONG Flags;
144 
145  /*
146  * The IRR registers are spaced 16 bytes apart and hold 32 status bits each.
147  * Pre-compute the register and bit that match our vector.
148  */
149  ULONG VectorHigh = Vector / 32;
150  ULONG VectorLow = Vector % 32;
151  ULONG Irr = APIC_IRR + 0x10 * VectorHigh;
152  ULONG IrrBit = 1UL << VectorLow;
153 
154  /* Setup the command register */
155  Icr.Long0 = 0;
156  Icr.Vector = Vector;
158  Icr.TriggerMode = TriggerMode;
160 
161  /* Disable interrupts so that we can change IRR without being interrupted */
162  Flags = __readeflags();
163  _disable();
164 
165  /* Wait for the APIC to be idle */
166  do
167  {
168  IcrStatus.Long0 = ApicRead(APIC_ICR0);
169  } while (IcrStatus.DeliveryStatus);
170 
171  /* Write the low dword to send the interrupt */
172  ApicWrite(APIC_ICR0, Icr.Long0);
173 
174  /* Wait until we see the interrupt request.
175  * It will stay in requested state until we re-enable interrupts.
176  */
177  while (!(ApicRead(Irr) & IrrBit))
178  {
179  NOTHING;
180  }
181 
182  /* Finally, restore the original interrupt state */
184  {
185  _enable();
186  }
187 }
188 
190 VOID
192 {
193  ApicWrite(APIC_EOI, 0);
194 }
195 
197 KIRQL
199 {
200  /* Read the TPR and convert it to an IRQL */
201  return TprToIrql(ApicRead(APIC_PPR));
202 }
203 
205 KIRQL
207 {
208 #ifdef _M_AMD64
209  return (KIRQL)__readcr8();
210 #elif defined(APIC_LAZY_IRQL)
211  /* Return the field in the PCR */
213 #else
214  /* Read the TPR and convert it to an IRQL */
215  return TprToIrql(ApicRead(APIC_TPR));
216 #endif
217 }
218 
220 VOID
222 {
223 #ifdef _M_AMD64
224  __writecr8(Irql);
225 #elif defined(APIC_LAZY_IRQL)
227 #else
228  /* Convert IRQL and write the TPR */
230 #endif
231 }
232 #define ApicRaiseIrql ApicSetIrql
233 
234 #ifdef APIC_LAZY_IRQL
236 VOID
238 {
240 
241  /* Is the new Irql lower than set in the TPR? */
242  if (Irql < KeGetPcr()->IRR)
243  {
244  /* Save the new hard IRQL in the IRR field */
245  KeGetPcr()->IRR = Irql;
246 
247  /* Need to lower it back */
249  }
250 }
251 #else
252 #define ApicLowerIrql ApicSetIrql
253 #endif
254 
255 UCHAR
256 FASTCALL
258 {
260 
261  /* Read low dword of the redirection entry */
262  ReDirReg.Long0 = IOApicRead(IOAPIC_REDTBL + 2 * Irq);
263 
264  /* Return the vector */
265  return (UCHAR)ReDirReg.Vector;
266 }
267 
268 KIRQL
269 FASTCALL
271 {
272  return TprToIrql(Vector);
273 }
274 
275 UCHAR
276 FASTCALL
278 {
279  return HalpVectorToIndex[Vector];
280 }
281 
282 VOID
283 NTAPI
285 {
286  ApicSendEOI();
287 }
288 
289 VOID
290 NTAPI
292 {
293  APIC_BASE_ADRESS_REGISTER BaseRegister;
294  APIC_SPURIOUS_INERRUPT_REGISTER SpIntRegister;
295  LVT_REGISTER LvtEntry;
296 
297  /* Enable the APIC if it wasn't yet */
298  BaseRegister.LongLong = __readmsr(MSR_APIC_BASE);
299  BaseRegister.Enable = 1;
300  BaseRegister.BootStrapCPUCore = (Cpu == 0);
301  __writemsr(MSR_APIC_BASE, BaseRegister.LongLong);
302 
303  /* Set spurious vector and SoftwareEnable to 1 */
304  SpIntRegister.Long = ApicRead(APIC_SIVR);
305  SpIntRegister.Vector = APIC_SPURIOUS_VECTOR;
306  SpIntRegister.SoftwareEnable = 1;
307  SpIntRegister.FocusCPUCoreChecking = 0;
308  ApicWrite(APIC_SIVR, SpIntRegister.Long);
309 
310  /* Read the version and save it globally */
311  if (Cpu == 0) ApicVersion = ApicRead(APIC_VER);
312 
313  /* Set the mode to flat (max 8 CPUs supported!) */
315 
316  /* Set logical apic ID */
317  ApicWrite(APIC_LDR, ApicLogicalId(Cpu) << 24);
318 
319  /* Set the spurious ISR */
321 
322  /* Create a template LVT */
323  LvtEntry.Long = 0;
324  LvtEntry.Vector = APIC_FREE_VECTOR;
325  LvtEntry.MessageType = APIC_MT_Fixed;
326  LvtEntry.DeliveryStatus = 0;
327  LvtEntry.RemoteIRR = 0;
328  LvtEntry.TriggerMode = APIC_TGM_Edge;
329  LvtEntry.Mask = 1;
330  LvtEntry.TimerMode = 0;
331 
332  /* Initialize and mask LVTs */
333  ApicWrite(APIC_TMRLVTR, LvtEntry.Long);
334  ApicWrite(APIC_THRMLVTR, LvtEntry.Long);
335  ApicWrite(APIC_PCLVTR, LvtEntry.Long);
336  ApicWrite(APIC_EXT0LVTR, LvtEntry.Long);
337  ApicWrite(APIC_EXT1LVTR, LvtEntry.Long);
338  ApicWrite(APIC_EXT2LVTR, LvtEntry.Long);
339  ApicWrite(APIC_EXT3LVTR, LvtEntry.Long);
340 
341  /* LINT0 */
342  LvtEntry.Vector = APIC_SPURIOUS_VECTOR;
343  LvtEntry.MessageType = APIC_MT_ExtInt;
344  ApicWrite(APIC_LINT0, LvtEntry.Long);
345 
346  /* Enable LINT1 (NMI) */
347  LvtEntry.Mask = 0;
348  LvtEntry.Vector = APIC_NMI_VECTOR;
349  LvtEntry.MessageType = APIC_MT_NMI;
350  LvtEntry.TriggerMode = APIC_TGM_Level;
351  ApicWrite(APIC_LINT1, LvtEntry.Long);
352 
353  /* Enable error LVTR */
354  LvtEntry.Vector = APIC_ERROR_VECTOR;
355  LvtEntry.MessageType = APIC_MT_Fixed;
356  ApicWrite(APIC_ERRLVTR, LvtEntry.Long);
357 
358  /* Set the IRQL from the PCR */
360 #ifdef APIC_LAZY_IRQL
361  /* Save the new hard IRQL in the IRR field */
362  KeGetPcr()->IRR = KeGetPcr()->Irql;
363 #endif
364 }
365 
366 UCHAR
367 NTAPI
369  _In_ UCHAR Irq,
370  _In_ UCHAR Vector)
371 {
373 
374  ASSERT(Irq < APIC_MAX_IRQ);
376 
377  /* Setup a redirection entry */
378  ReDirReg.Vector = Vector;
380  ReDirReg.DestinationMode = APIC_DM_Logical;
381  ReDirReg.DeliveryStatus = 0;
382  ReDirReg.Polarity = 0;
383  ReDirReg.RemoteIRR = 0;
384  ReDirReg.TriggerMode = APIC_TGM_Edge;
385  ReDirReg.Mask = 1;
386  ReDirReg.Reserved = 0;
387  ReDirReg.Destination = 0;
388 
389  /* Initialize entry */
390  ApicWriteIORedirectionEntry(Irq, ReDirReg);
391 
392  /* Save irq in the table */
393  HalpVectorToIndex[Vector] = Irq;
394 
395  return Vector;
396 }
397 
398 ULONG
399 NTAPI
403  _Out_ PKIRQL OutIrql,
404  _Out_ PKAFFINITY OutAffinity)
405 {
406  UCHAR Vector;
407  KIRQL Irql;
408 
409  /* Get the vector currently registered */
411 
412  /* Check if it's used */
413  if (Vector != APIC_FREE_VECTOR)
414  {
415  /* Calculate IRQL */
417  *OutIrql = HalpVectorToIrql(Vector);
418  }
419  else
420  {
421  ULONG Offset;
422 
423  /* Outer loop to find alternative slots, when all IRQLs are in use */
424  for (Offset = 0; Offset < 15; Offset++)
425  {
426  /* Loop allowed IRQL range */
427  for (Irql = CLOCK_LEVEL - 1; Irql >= CMCI_LEVEL; Irql--)
428  {
429  /* Calculate the vactor */
431 
432  /* Check if the vector is free */
434  {
435  /* Found one, allocate the interrupt */
437  *OutIrql = Irql;
438  goto Exit;
439  }
440  }
441  }
442 
443  DPRINT1("Failed to get an interrupt vector for IRQ %lu\n", BusInterruptLevel);
444  *OutAffinity = 0;
445  *OutIrql = 0;
446  return 0;
447  }
448 
449 Exit:
450 
451  *OutAffinity = HalpDefaultInterruptAffinity;
453 
454  return Vector;
455 }
456 
457 VOID
458 NTAPI
460 {
461  PHARDWARE_PTE Pte;
463  UCHAR Index;
464  ULONG Vector;
465 
466  /* Map the I/O Apic page */
469  Pte->Valid = 1;
470  Pte->Write = 1;
471  Pte->Owner = 1;
472  Pte->CacheDisable = 1;
473  Pte->Global = 1;
475 
476  /* Setup a redirection entry */
477  ReDirReg.Vector = APIC_FREE_VECTOR;
478  ReDirReg.DeliveryMode = APIC_MT_Fixed;
480  ReDirReg.DeliveryStatus = 0;
481  ReDirReg.Polarity = 0;
482  ReDirReg.RemoteIRR = 0;
483  ReDirReg.TriggerMode = APIC_TGM_Edge;
484  ReDirReg.Mask = 1;
485  ReDirReg.Reserved = 0;
486  ReDirReg.Destination = 0;
487 
488  /* Loop all table entries */
489  for (Index = 0; Index < APIC_MAX_IRQ; Index++)
490  {
491  /* Initialize entry */
493  }
494 
495  /* Init the vactor to index table */
496  for (Vector = 0; Vector <= 255; Vector++)
497  {
499  }
500 
501  /* Enable the timer interrupt (but keep it masked) */
502  ReDirReg.Vector = APIC_CLOCK_VECTOR;
503  ReDirReg.DeliveryMode = APIC_MT_Fixed;
505  ReDirReg.TriggerMode = APIC_TGM_Edge;
506  ReDirReg.Mask = 1;
507  ReDirReg.Destination = ApicRead(APIC_ID);
509 }
510 
511 VOID
512 NTAPI
514 {
515  ULONG_PTR EFlags;
516 
517  /* Save EFlags and disable interrupts */
518  EFlags = __readeflags();
519  _disable();
520 
521  /* Initialize and mask the PIC */
523 
524  /* Initialize the I/O APIC */
526 
527  /* Manually reserve some vectors */
532 
533  /* Set interrupt handlers in the IDT */
535 #ifndef _M_AMD64
538 #endif
539 
540  /* Register the vectors for APC and dispatch interrupts */
543 
544  /* Restore interrupt state */
546  __writeeflags(EFlags);
547 }
548 
549 
550 /* SOFTWARE INTERRUPT TRAPS ***************************************************/
551 
552 #ifndef _M_AMD64
553 VOID
555 FASTCALL
557 {
558  KPROCESSOR_MODE ProcessorMode;
559  KIRQL OldIrql;
561 
562  /* Enter trap */
563  KiEnterInterruptTrap(TrapFrame);
564 
565 #ifdef APIC_LAZY_IRQL
567  {
568  /* "Spurious" interrupt, exit the interrupt */
569  KiEoiHelper(TrapFrame);
570  }
571 #else
572  /* Save the old IRQL */
575 #endif
576 
577  /* Raise to APC_LEVEL */
579 
580  /* End the interrupt */
581  ApicSendEOI();
582 
583  /* Kernel or user APC? */
584  if (KiUserTrap(TrapFrame)) ProcessorMode = UserMode;
585  else if (TrapFrame->EFlags & EFLAGS_V86_MASK) ProcessorMode = UserMode;
586  else ProcessorMode = KernelMode;
587 
588  /* Enable interrupts and call the kernel's APC interrupt handler */
589  _enable();
590  KiDeliverApc(ProcessorMode, NULL, TrapFrame);
591 
592  /* Disable interrupts */
593  _disable();
594 
595  /* Restore the old IRQL */
597 
598  /* Exit the interrupt */
599  KiEoiHelper(TrapFrame);
600 }
601 
602 VOID
604 FASTCALL
606 {
607  KIRQL OldIrql;
609 
610  /* Enter trap */
611  KiEnterInterruptTrap(TrapFrame);
612 
613 #ifdef APIC_LAZY_IRQL
615  {
616  /* "Spurious" interrupt, exit the interrupt */
617  KiEoiHelper(TrapFrame);
618  }
619 #else
620  /* Get the current IRQL */
623 #endif
624 
625  /* Raise to DISPATCH_LEVEL */
627 
628  /* End the interrupt */
629  ApicSendEOI();
630 
631  /* Enable interrupts and call the kernel's DPC interrupt handler */
632  _enable();
634  _disable();
635 
636  /* Restore the old IRQL */
638 
639  /* Exit the interrupt */
640  KiEoiHelper(TrapFrame);
641 }
642 #endif
643 
644 
645 /* SOFTWARE INTERRUPTS ********************************************************/
646 
647 
648 VOID
649 FASTCALL
651 {
652  /* Convert irql to vector and request an interrupt */
654 }
655 
656 VOID
657 FASTCALL
659  IN KIRQL Irql)
660 {
661  /* Nothing to do */
662 }
663 
664 
665 /* SYSTEM INTERRUPTS **********************************************************/
666 
667 BOOLEAN
668 NTAPI
670  IN ULONG Vector,
671  IN KIRQL Irql,
673 {
675  PKPRCB Prcb = KeGetCurrentPrcb();
676  UCHAR Index;
677  ASSERT(Irql <= HIGH_LEVEL);
678  ASSERT((IrqlToTpr(Irql) & 0xF0) == (Vector & 0xF0));
679 
680  /* Get the irq for this vector */
682 
683  /* Check if its valid */
684  if (Index == APIC_FREE_VECTOR)
685  {
686  /* Interrupt is not in use */
687  return FALSE;
688  }
689 
690  /* Read the redirection entry */
691  ReDirReg = ApicReadIORedirectionEntry(Index);
692 
693  /* Check if the interrupt was unused */
694  if (ReDirReg.Vector != Vector)
695  {
696  ReDirReg.Vector = Vector;
698  ReDirReg.DestinationMode = APIC_DM_Logical;
699  ReDirReg.Destination = 0;
700  }
701 
702  /* Check if the destination is logical */
703  if (ReDirReg.DestinationMode == APIC_DM_Logical)
704  {
705  /* Set the bit for this cpu */
706  ReDirReg.Destination |= ApicLogicalId(Prcb->Number);
707  }
708 
709  /* Set the trigger mode */
710  ReDirReg.TriggerMode = 1 - InterruptMode;
711 
712  /* Now unmask it */
713  ReDirReg.Mask = FALSE;
714 
715  /* Write back the entry */
717 
718  return TRUE;
719 }
720 
721 VOID
722 NTAPI
724  IN ULONG Vector,
725  IN KIRQL Irql)
726 {
728  UCHAR Index;
729  ASSERT(Irql <= HIGH_LEVEL);
731 
733 
734  /* Read lower dword of redirection entry */
735  ReDirReg.Long0 = IOApicRead(IOAPIC_REDTBL + 2 * Index);
736 
737  /* Mask it */
738  ReDirReg.Mask = 1;
739 
740  /* Write back lower dword */
741  IOApicWrite(IOAPIC_REDTBL + 2 * Index, ReDirReg.Long0);
742 }
743 
744 #ifndef _M_AMD64
745 BOOLEAN
746 NTAPI
748  IN KIRQL Irql,
749  IN ULONG Vector,
751 {
752  KIRQL CurrentIrql;
753 
754  /* Get the current IRQL */
755  CurrentIrql = ApicGetCurrentIrql();
756 
757 #ifdef APIC_LAZY_IRQL
758  /* Check if this interrupt is allowed */
759  if (CurrentIrql >= Irql)
760  {
762  UCHAR Index;
763 
764  /* It is not, set the real Irql in the TPR! */
765  ApicWrite(APIC_TPR, IrqlToTpr(CurrentIrql));
766 
767  /* Save the new hard IRQL in the IRR field */
768  KeGetPcr()->IRR = CurrentIrql;
769 
770  /* End this interrupt */
771  ApicSendEOI();
772 
773  /* Get the irq for this vector */
775 
776  /* Check if it's valid */
777  if (Index < APIC_MAX_IRQ)
778  {
779  /* Read the I/O redirection entry */
780  RedirReg = ApicReadIORedirectionEntry(Index);
781 
782  /* Re-request the interrupt to be handled later */
784  }
785  else
786  {
787  /* This should be a reserved vector! */
789 
790  /* Re-request the interrupt to be handled later */
792  }
793 
794  /* Pretend it was a spurious interrupt */
795  return FALSE;
796  }
797 #endif
798  /* Save the current IRQL */
799  *OldIrql = CurrentIrql;
800 
801  /* Set the new IRQL */
803 
804  /* Turn on interrupts */
805  _enable();
806 
807  /* Success */
808  return TRUE;
809 }
810 
811 VOID
812 NTAPI
814  IN KIRQL OldIrql,
815  IN PKTRAP_FRAME TrapFrame)
816 {
817  /* Send an EOI */
818  ApicSendEOI();
819 
820  /* Restore the old IRQL */
822 }
823 
824 
825 /* IRQL MANAGEMENT ************************************************************/
826 
827 KIRQL
828 NTAPI
830 {
831  /* Read the current TPR and convert it to an IRQL */
832  return ApicGetCurrentIrql();
833 }
834 
835 VOID
836 FASTCALL
838  IN KIRQL OldIrql)
839 {
840 #if DBG
841  /* Validate correct lower */
842  if (OldIrql > ApicGetCurrentIrql())
843  {
844  /* Crash system */
845  KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
846  }
847 #endif
848  /* Set the new IRQL */
850 }
851 
852 KIRQL
853 FASTCALL
855  IN KIRQL NewIrql)
856 {
857  KIRQL OldIrql;
858 
859  /* Read the current IRQL */
861 #if DBG
862  /* Validate correct raise */
863  if (OldIrql > NewIrql)
864  {
865  /* Crash system */
866  KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
867  }
868 #endif
869  /* Convert the new IRQL to a TPR value and write the register */
871 
872  /* Return old IRQL */
873  return OldIrql;
874 }
875 
876 KIRQL
877 NTAPI
879 {
880  return KfRaiseIrql(DISPATCH_LEVEL);
881 }
882 
883 KIRQL
884 NTAPI
886 {
887  return KfRaiseIrql(SYNCH_LEVEL);
888 }
889 
890 #endif /* !_M_AMD64 */
891 
ULONG64 Valid
Definition: mmtypes.h:66
UCHAR FASTCALL HalpVectorToIrq(UCHAR Vector)
Definition: apic.c:277
_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:315
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:284
UINT32 Vector
Definition: apicp.h:266
UINT32 DeliveryStatus
Definition: apicp.h:269
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1080
#define HalAddressToPte(x)
Definition: halp.h:163
const UCHAR HalpIRQLtoTPR[32]
Definition: apic.c:32
Definition: ke.h:289
#define IOAPIC_IOWIN
Definition: apicp.h:281
#define APIC_NMI_VECTOR
Definition: apicp.h:51
FORCEINLINE KIRQL ApicGetProcessorIrql(VOID)
Definition: apic.c:198
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:206
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ApicLogicalId(Cpu)
Definition: apicp.h:116
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:257
UINT32 Long
Definition: apicp.h:263
VOID FASTCALL KfLowerIrql(IN KIRQL OldIrql)
Definition: apic.c:837
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1666
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:322
BOOLEAN NTAPI HalEnableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql, IN KINTERRUPT_MODE InterruptMode)
Definition: apic.c:669
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:459
KAFFINITY * PKAFFINITY
Definition: basetsd.h:197
KIRQL FASTCALL HalpVectorToIrql(UCHAR Vector)
Definition: apic.c:270
unsigned char BOOLEAN
UCHAR NTAPI HalpAllocateSystemInterrupt(_In_ UCHAR Irq, _In_ UCHAR Vector)
Definition: apic.c:368
#define ApicRaiseIrql
Definition: apic.c:232
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:829
#define IrqlToSoftVector(Irql)
Definition: apicp.h:54
#define IOAPIC_IOREGSEL
Definition: apicp.h:280
#define IOAPIC_REDTBL
Definition: apicp.h:287
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
_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
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#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:723
FORCEINLINE VOID ApicLowerIrql(KIRQL Irql)
Definition: apic.c:237
_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 CLOCK_LEVEL
Definition: ketypes.h:16
#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
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1661
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 NOTHING
Definition: env_spec_w32.h:461
#define SYNCH_LEVEL
Definition: env_spec_w32.h:704
VOID DECLSPEC_NORETURN FASTCALL HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:556
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:650
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: apic.c:885
FORCEINLINE VOID KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:368
#define CMCI_LEVEL
Definition: ketypes.h:15
#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:221
VOID DECLSPEC_NORETURN FASTCALL HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:605
ULONG NTAPI HalpGetRootInterruptVector(_In_ ULONG BusInterruptLevel, _In_ ULONG BusInterruptVector, _Out_ PKIRQL OutIrql, _Out_ PKAFFINITY OutAffinity)
Definition: apic.c:400
Definition: apicp.h:91
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:564
void __cdecl _disable(void)
Definition: intrin_arm.h:365
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID ApicSendEOI(void)
Definition: apic.c:191
#define APIC_CLOCK_INDEX
Definition: apicp.h:115
KIRQL NTAPI KeRaiseIrqlToDpcLevel(VOID)
Definition: apic.c:878
#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:291
#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
#define UL
Definition: tui.h:148
VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Irql)
Definition: apic.c:658
#define APC_LEVEL
Definition: env_spec_w32.h:695
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts)
Definition: apic.c:513
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: apic.c:854
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:747
#define TprToIrql(Tpr)
Definition: apicp.h:55
VOID NTAPI HalEndSystemInterrupt(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:813
#define EFLAGS_INTERRUPT_MASK
Definition: ketypes.h:126
#define NT_ASSERT
Definition: rtlfuncs.h:3310