ReactOS  0.4.13-dev-464-g6b95727
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: 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  */
11 
12 /* INCLUDES *******************************************************************/
13 
14 #include <hal.h>
15 #define NDEBUG
16 #include <debug.h>
17 
18 #include "apic.h"
19 void __cdecl HackEoi(void);
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  *(volatile UCHAR *)(IOAPIC_BASE + IOAPIC_IOREGSEL) = Register;
98  return *(volatile ULONG *)(IOAPIC_BASE + IOAPIC_IOWIN);
99 }
100 
102 VOID
104 {
105  /* Select the register, then do the write */
106  *(volatile UCHAR *)(IOAPIC_BASE + IOAPIC_IOREGSEL) = Register;
107  *(volatile ULONG *)(IOAPIC_BASE + IOAPIC_IOWIN) = Value;
108 }
109 
111 VOID
113  UCHAR Index,
115 {
116  IOApicWrite(IOAPIC_REDTBL + 2 * Index, ReDirReg.Long0);
117  IOApicWrite(IOAPIC_REDTBL + 2 * Index + 1, ReDirReg.Long1);
118 }
119 
123  UCHAR Index)
124 {
126 
127  ReDirReg.Long0 = IOApicRead(IOAPIC_REDTBL + 2 * Index);
128  ReDirReg.Long1 = IOApicRead(IOAPIC_REDTBL + 2 * Index + 1);
129 
130  return ReDirReg;
131 }
132 
134 VOID
136 {
137  APIC_COMMAND_REGISTER CommandRegister;
138 
139  /* Setup the command register */
140  CommandRegister.Long0 = 0;
141  CommandRegister.Vector = Vector;
142  CommandRegister.MessageType = APIC_MT_Fixed;
143  CommandRegister.TriggerMode = TriggerMode;
144  CommandRegister.DestinationShortHand = APIC_DSH_Self;
145 
146  /* Write the low dword to send the interrupt */
147  ApicWrite(APIC_ICR0, CommandRegister.Long0);
148 }
149 
151 VOID
153 {
154  //ApicWrite(APIC_EOI, 0);
155  HackEoi();
156 }
157 
159 KIRQL
161 {
162  /* Read the TPR and convert it to an IRQL */
163  return TprToIrql(ApicRead(APIC_PPR));
164 }
165 
167 KIRQL
169 {
170 #ifdef _M_AMD64
171  return (KIRQL)__readcr8();
172 #elif defined(APIC_LAZY_IRQL)
173  // HACK: some magic to Sync VBox's APIC registers
175 
176  /* Return the field in the PCR */
178 #else
179  // HACK: some magic to Sync VBox's APIC registers
181 
182  /* Read the TPR and convert it to an IRQL */
183  return TprToIrql(ApicRead(APIC_TPR));
184 #endif
185 }
186 
188 VOID
190 {
191 #ifdef _M_AMD64
192  __writecr8(Irql);
193 #elif defined(APIC_LAZY_IRQL)
195 #else
196  /* Convert IRQL and write the TPR */
198 #endif
199 }
200 #define ApicRaiseIrql ApicSetIrql
201 
202 #ifdef APIC_LAZY_IRQL
204 VOID
206 {
208 
209  /* Is the new Irql lower than set in the TPR? */
210  if (Irql < KeGetPcr()->IRR)
211  {
212  /* Save the new hard IRQL in the IRR field */
213  KeGetPcr()->IRR = Irql;
214 
215  /* Need to lower it back */
217  }
218 }
219 #else
220 #define ApicLowerIrql ApicSetIrql
221 #endif
222 
223 UCHAR
224 FASTCALL
226 {
228 
229  /* Read low dword of the redirection entry */
230  ReDirReg.Long0 = IOApicRead(IOAPIC_REDTBL + 2 * Irq);
231 
232  /* Return the vector */
233  return (UCHAR)ReDirReg.Vector;
234 }
235 
236 KIRQL
237 FASTCALL
239 {
240  return TprToIrql(Vector);
241 }
242 
243 UCHAR
244 FASTCALL
246 {
247  return HalpVectorToIndex[Vector];
248 }
249 
250 VOID
251 NTAPI
253 {
254  ApicSendEOI();
255 }
256 
257 VOID
258 NTAPI
260 {
261  APIC_BASE_ADRESS_REGISTER BaseRegister;
262  APIC_SPURIOUS_INERRUPT_REGISTER SpIntRegister;
263  LVT_REGISTER LvtEntry;
264 
265  /* Enable the APIC if it wasn't yet */
266  BaseRegister.Long = __readmsr(MSR_APIC_BASE);
267  BaseRegister.Enable = 1;
268  BaseRegister.BootStrapCPUCore = (Cpu == 0);
269  __writemsr(MSR_APIC_BASE, BaseRegister.Long);
270 
271  /* Set spurious vector and SoftwareEnable to 1 */
272  SpIntRegister.Long = ApicRead(APIC_SIVR);
273  SpIntRegister.Vector = APIC_SPURIOUS_VECTOR;
274  SpIntRegister.SoftwareEnable = 1;
275  SpIntRegister.FocusCPUCoreChecking = 0;
276  ApicWrite(APIC_SIVR, SpIntRegister.Long);
277 
278  /* Read the version and save it globally */
279  if (Cpu == 0) ApicVersion = ApicRead(APIC_VER);
280 
281  /* Set the mode to flat (max 8 CPUs supported!) */
283 
284  /* Set logical apic ID */
285  ApicWrite(APIC_LDR, ApicLogicalId(Cpu) << 24);
286 
287  /* Set the spurious ISR */
289 
290  /* Create a template LVT */
291  LvtEntry.Long = 0;
292  LvtEntry.Vector = 0xFF;
293  LvtEntry.MessageType = APIC_MT_Fixed;
294  LvtEntry.DeliveryStatus = 0;
295  LvtEntry.RemoteIRR = 0;
296  LvtEntry.TriggerMode = APIC_TGM_Edge;
297  LvtEntry.Mask = 1;
298  LvtEntry.TimerMode = 0;
299 
300  /* Initialize and mask LVTs */
301  ApicWrite(APIC_TMRLVTR, LvtEntry.Long);
302  ApicWrite(APIC_THRMLVTR, LvtEntry.Long);
303  ApicWrite(APIC_PCLVTR, LvtEntry.Long);
304  ApicWrite(APIC_EXT0LVTR, LvtEntry.Long);
305  ApicWrite(APIC_EXT1LVTR, LvtEntry.Long);
306  ApicWrite(APIC_EXT2LVTR, LvtEntry.Long);
307  ApicWrite(APIC_EXT3LVTR, LvtEntry.Long);
308 
309  /* LINT0 */
310  LvtEntry.Vector = APIC_SPURIOUS_VECTOR;
311  LvtEntry.MessageType = APIC_MT_ExtInt;
312  ApicWrite(APIC_LINT0, LvtEntry.Long);
313 
314  /* Enable LINT1 (NMI) */
315  LvtEntry.Mask = 0;
316  LvtEntry.Vector = APIC_NMI_VECTOR;
317  LvtEntry.MessageType = APIC_MT_NMI;
318  LvtEntry.TriggerMode = APIC_TGM_Level;
319  ApicWrite(APIC_LINT1, LvtEntry.Long);
320 
321  /* Enable error LVTR */
322  LvtEntry.Vector = APIC_ERROR_VECTOR;
323  LvtEntry.MessageType = APIC_MT_Fixed;
324  ApicWrite(APIC_ERRLVTR, LvtEntry.Long);
325 
326  /* Set the IRQL from the PCR */
328 #ifdef APIC_LAZY_IRQL
329  /* Save the new hard IRQL in the IRR field */
330  KeGetPcr()->IRR = KeGetPcr()->Irql;
331 #endif
332 }
333 
334 UCHAR
335 NTAPI
337  IN UCHAR Irq,
338  IN KIRQL Irql)
339 {
341  IN UCHAR Vector;
342 
343  /* Start with lowest vector */
344  Vector = IrqlToTpr(Irql) & 0xF0;
345 
346  /* Find an empty vector */
347  while (HalpVectorToIndex[Vector] != 0xFF)
348  {
349  Vector++;
350 
351  /* Check if we went over the edge */
352  if (TprToIrql(Vector) > Irql)
353  {
354  /* Nothing free, return failure */
355  return 0;
356  }
357  }
358 
359  /* Save irq in the table */
360  HalpVectorToIndex[Vector] = Irq;
361 
362  /* Setup a redirection entry */
363  ReDirReg.Vector = Vector;
365  ReDirReg.DestinationMode = APIC_DM_Logical;
366  ReDirReg.DeliveryStatus = 0;
367  ReDirReg.Polarity = 0;
368  ReDirReg.RemoteIRR = 0;
369  ReDirReg.TriggerMode = APIC_TGM_Edge;
370  ReDirReg.Mask = 1;
371  ReDirReg.Reserved = 0;
372  ReDirReg.Destination = 0;
373 
374  /* Initialize entry */
375  IOApicWrite(IOAPIC_REDTBL + 2 * Irq, ReDirReg.Long0);
376  IOApicWrite(IOAPIC_REDTBL + 2 * Irq + 1, ReDirReg.Long1);
377 
378  return Vector;
379 }
380 
381 VOID
382 NTAPI
384 {
385  PHARDWARE_PTE Pte;
387  UCHAR Index;
388  ULONG Vector;
389 
390  /* Map the I/O Apic page */
393  Pte->Valid = 1;
394  Pte->Write = 1;
395  Pte->Owner = 1;
396  Pte->CacheDisable = 1;
397  Pte->Global = 1;
399 
400  /* Setup a redirection entry */
401  ReDirReg.Vector = 0xFF;
402  ReDirReg.DeliveryMode = APIC_MT_Fixed;
404  ReDirReg.DeliveryStatus = 0;
405  ReDirReg.Polarity = 0;
406  ReDirReg.RemoteIRR = 0;
407  ReDirReg.TriggerMode = APIC_TGM_Edge;
408  ReDirReg.Mask = 1;
409  ReDirReg.Reserved = 0;
410  ReDirReg.Destination = 0;
411 
412  /* Loop all table entries */
413  for (Index = 0; Index < 24; Index++)
414  {
415  /* Initialize entry */
416  IOApicWrite(IOAPIC_REDTBL + 2 * Index, ReDirReg.Long0);
417  IOApicWrite(IOAPIC_REDTBL + 2 * Index + 1, ReDirReg.Long1);
418  }
419 
420  /* Init the vactor to index table */
421  for (Vector = 0; Vector <= 255; Vector++)
422  {
423  HalpVectorToIndex[Vector] = 0xFF;
424  }
425 
426  // HACK: Allocate all IRQs, should rather do that on demand
427  for (Index = 0; Index <= 15; Index++)
428  {
429  /* Map the IRQs to IRQLs like with the PIC */
431  }
432 
433  /* Enable the timer interrupt */
434  ReDirReg.Vector = APIC_CLOCK_VECTOR;
435  ReDirReg.DeliveryMode = APIC_MT_Fixed;
437  ReDirReg.TriggerMode = APIC_TGM_Edge;
438  ReDirReg.Mask = 0;
439  ReDirReg.Destination = ApicRead(APIC_ID);
441 }
442 
443 VOID
444 NTAPI
446 {
447  ULONG_PTR EFlags;
448 
449  /* Save EFlags and disable interrupts */
450  EFlags = __readeflags();
451  _disable();
452 
453  /* Initialize and mask the PIC */
455 
456  /* Initialize the I/O APIC */
458 
459  /* Manually reserve some vectors */
463 
464  /* Set interrupt handlers in the IDT */
466 #ifndef _M_AMD64
469 #endif
470 
471  /* Register the vectors for APC and dispatch interrupts */
474 
475  /* Restore interrupt state */
477  __writeeflags(EFlags);
478 }
479 
480 
481 /* SOFTWARE INTERRUPT TRAPS ***************************************************/
482 
483 #ifndef _M_AMD64
484 VOID
486 FASTCALL
488 {
489  KPROCESSOR_MODE ProcessorMode;
490  KIRQL OldIrql;
492 
493  /* Enter trap */
494  KiEnterInterruptTrap(TrapFrame);
495 
496 #ifdef APIC_LAZY_IRQL
498  {
499  /* "Spurious" interrupt, exit the interrupt */
500  KiEoiHelper(TrapFrame);
501  }
502 #else
503  /* Save the old IRQL */
506 #endif
507 
508  /* Raise to APC_LEVEL */
510 
511  /* End the interrupt */
512  ApicSendEOI();
513 
514  /* Kernel or user APC? */
515  if (KiUserTrap(TrapFrame)) ProcessorMode = UserMode;
516  else if (TrapFrame->EFlags & EFLAGS_V86_MASK) ProcessorMode = UserMode;
517  else ProcessorMode = KernelMode;
518 
519  /* Enable interrupts and call the kernel's APC interrupt handler */
520  _enable();
521  KiDeliverApc(ProcessorMode, NULL, TrapFrame);
522 
523  /* Disable interrupts */
524  _disable();
525 
526  /* Restore the old IRQL */
528 
529  /* Exit the interrupt */
530  KiEoiHelper(TrapFrame);
531 }
532 
533 VOID
535 FASTCALL
537 {
538  KIRQL OldIrql;
540 
541  /* Enter trap */
542  KiEnterInterruptTrap(TrapFrame);
543 
544 #ifdef APIC_LAZY_IRQL
546  {
547  /* "Spurious" interrupt, exit the interrupt */
548  KiEoiHelper(TrapFrame);
549  }
550 #else
551  /* Get the current IRQL */
554 #endif
555 
556  /* Raise to DISPATCH_LEVEL */
558 
559  /* End the interrupt */
560  ApicSendEOI();
561 
562  /* Enable interrupts and call the kernel's DPC interrupt handler */
563  _enable();
565  _disable();
566 
567  /* Restore the old IRQL */
569 
570  /* Exit the interrupt */
571  KiEoiHelper(TrapFrame);
572 }
573 #endif
574 
575 
576 /* SOFTWARE INTERRUPTS ********************************************************/
577 
578 
579 VOID
580 FASTCALL
582 {
583  /* Convert irql to vector and request an interrupt */
585 }
586 
587 VOID
588 FASTCALL
590  IN KIRQL Irql)
591 {
592  /* Nothing to do */
593 }
594 
595 
596 /* SYSTEM INTERRUPTS **********************************************************/
597 
598 BOOLEAN
599 NTAPI
601  IN ULONG Vector,
602  IN KIRQL Irql,
604 {
606  PKPRCB Prcb = KeGetCurrentPrcb();
607  UCHAR Index;
608  ASSERT(Irql <= HIGH_LEVEL);
609  ASSERT((IrqlToTpr(Irql) & 0xF0) == (Vector & 0xF0));
610 
611  /* Get the irq for this vector */
613 
614  /* Check if its valid */
615  if (Index == 0xff)
616  {
617  /* Interrupt is not in use */
618  return FALSE;
619  }
620 
621  /* Read the redirection entry */
622  ReDirReg = ApicReadIORedirectionEntry(Index);
623 
624  /* Check if the interrupt was unused */
625  if (ReDirReg.Vector != Vector)
626  {
627  ReDirReg.Vector = Vector;
629  ReDirReg.DestinationMode = APIC_DM_Logical;
630  ReDirReg.Destination = 0;
631  }
632 
633  /* Check if the destination is logical */
634  if (ReDirReg.DestinationMode == APIC_DM_Logical)
635  {
636  /* Set the bit for this cpu */
637  ReDirReg.Destination |= ApicLogicalId(Prcb->Number);
638  }
639 
640  /* Set the trigger mode */
641  ReDirReg.TriggerMode = 1 - InterruptMode;
642 
643  /* Now unmask it */
644  ReDirReg.Mask = FALSE;
645 
646  /* Write back the entry */
648 
649  return TRUE;
650 }
651 
652 VOID
653 NTAPI
655  IN ULONG Vector,
656  IN KIRQL Irql)
657 {
659  UCHAR Index;
660  ASSERT(Irql <= HIGH_LEVEL);
662 
664 
665  /* Read lower dword of redirection entry */
666  ReDirReg.Long0 = IOApicRead(IOAPIC_REDTBL + 2 * Index);
667 
668  /* Mask it */
669  ReDirReg.Mask = 1;
670 
671  /* Write back lower dword */
672  IOApicWrite(IOAPIC_REDTBL + 2 * Irql, ReDirReg.Long0);
673 }
674 
675 #ifndef _M_AMD64
676 BOOLEAN
677 NTAPI
679  IN KIRQL Irql,
680  IN ULONG Vector,
682 {
683  KIRQL CurrentIrql;
684 
685  /* Get the current IRQL */
686  CurrentIrql = ApicGetCurrentIrql();
687 
688 #ifdef APIC_LAZY_IRQL
689  /* Check if this interrupt is allowed */
690  if (CurrentIrql >= Irql)
691  {
693  UCHAR Index;
694 
695  /* It is not, set the real Irql in the TPR! */
696  ApicWrite(APIC_TPR, IrqlToTpr(CurrentIrql));
697 
698  /* Save the new hard IRQL in the IRR field */
699  KeGetPcr()->IRR = CurrentIrql;
700 
701  /* End this interrupt */
702  ApicSendEOI();
703 
704  /* Get the irq for this vector */
706 
707  /* Check if its valid */
708  if (Index != 0xff)
709  {
710  /* Read the I/O redirection entry */
711  RedirReg = ApicReadIORedirectionEntry(Index);
712 
713  /* Re-request the interrupt to be handled later */
715  }
716  else
717  {
718  /* Re-request the interrupt to be handled later */
720  }
721 
722  /* Pretend it was a spurious interrupt */
723  return FALSE;
724  }
725 #endif
726  /* Save the current IRQL */
727  *OldIrql = CurrentIrql;
728 
729  /* Set the new IRQL */
731 
732  /* Turn on interrupts */
733  _enable();
734 
735  /* Success */
736  return TRUE;
737 }
738 
739 VOID
740 NTAPI
742  IN KIRQL OldIrql,
743  IN PKTRAP_FRAME TrapFrame)
744 {
745  /* Send an EOI */
746  ApicSendEOI();
747 
748  /* Restore the old IRQL */
750 }
751 
752 
753 /* IRQL MANAGEMENT ************************************************************/
754 
755 KIRQL
756 NTAPI
758 {
759  /* Read the current TPR and convert it to an IRQL */
760  return ApicGetCurrentIrql();
761 }
762 
763 VOID
764 FASTCALL
766  IN KIRQL OldIrql)
767 {
768 #if DBG
769  /* Validate correct lower */
770  if (OldIrql > ApicGetCurrentIrql())
771  {
772  /* Crash system */
773  KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
774  }
775 #endif
776  /* Set the new IRQL */
778 }
779 
780 KIRQL
781 FASTCALL
783  IN KIRQL NewIrql)
784 {
785  KIRQL OldIrql;
786 
787  /* Read the current IRQL */
789 #if DBG
790  /* Validate correct raise */
791  if (OldIrql > NewIrql)
792  {
793  /* Crash system */
794  KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
795  }
796 #endif
797  /* Convert the new IRQL to a TPR value and write the register */
799 
800  /* Return old IRQL */
801  return OldIrql;
802 }
803 
804 KIRQL
805 NTAPI
807 {
808  return KfRaiseIrql(DISPATCH_LEVEL);
809 }
810 
811 KIRQL
812 NTAPI
814 {
815  return KfRaiseIrql(SYNCH_LEVEL);
816 }
817 
818 #endif /* !_M_AMD64 */
819 
ULONG64 Valid
Definition: mmtypes.h:66
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
#define APIC_LDR
Definition: apic.h:16
UCHAR FASTCALL HalpVectorToIrq(UCHAR Vector)
Definition: apic.c:245
#define IN
Definition: typedefs.h:38
#define TprToIrql(Tpr)
Definition: apic.h:38
static NTSTATUS EnableInterrupts(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR FlagsToDisable, IN UCHAR FlagsToEnable)
Definition: pnp.c:380
#define TRUE
Definition: types.h:120
ULONG Long
Definition: apic.h:209
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:798
__INTRIN_INLINE unsigned long __readcr8(void)
Definition: intrin_x86.h:1721
ULONGLONG DestinationMode
Definition: apic.h:252
#define _ReadWriteBarrier()
Definition: intrin_arm.h:36
ULONGLONG TriggerMode
Definition: apic.h:199
#define __cdecl
Definition: accygwin.h:79
#define APIC_ID
Definition: apic.h:10
ULONG64 Global
Definition: mmtypes.h:74
ULONG64 Owner
Definition: mmtypes.h:68
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:252
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
#define HalAddressToPte(x)
Definition: halp.h:523
ULONG TriggerMode
Definition: apic.h:218
ULONG Vector
Definition: apic.h:212
const UCHAR HalpIRQLtoTPR[32]
Definition: apic.c:32
Definition: ke.h:280
FORCEINLINE KIRQL ApicGetProcessorIrql(VOID)
Definition: apic.c:160
FORCEINLINE IOAPIC_REDIRECTION_REGISTER ApicReadIORedirectionEntry(UCHAR Index)
Definition: apic.c:122
ULONG ApicVersion
Definition: apic.c:27
ULONG RemoteIRR
Definition: apic.h:217
#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
__INTRIN_INLINE void __writecr8(unsigned int Data)
Definition: intrin_x86.h:1686
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
#define ApicLogicalId(Cpu)
Definition: apic.h:45
#define KeGetPcr()
Definition: ke.h:25
#define EFLAGS_V86_MASK
Definition: ketypes.h:129
FORCEINLINE KIRQL ApicGetCurrentIrql(VOID)
Definition: apic.c:168
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define APIC_TPR
Definition: apic.h:12
ULONGLONG DeliveryStatus
Definition: apic.h:253
FORCEINLINE VOID ApicWriteIORedirectionEntry(UCHAR Index, IOAPIC_REDIRECTION_REGISTER ReDirReg)
Definition: apic.c:112
UCHAR KIRQL
Definition: env_spec_w32.h:591
UCHAR FASTCALL HalpIrqToVector(UCHAR Irq)
Definition: apic.c:225
VOID FASTCALL KfLowerIrql(IN KIRQL OldIrql)
Definition: apic.c:765
#define APIC_ICR0
Definition: apic.h:23
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1555
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
BOOLEAN NTAPI HalEnableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql, IN KINTERRUPT_MODE InterruptMode)
Definition: apic.c:600
VOID __cdecl HalpDispatchInterrupt(VOID)
VOID NTAPI ApicInitializeIOApic(VOID)
Definition: apic.c:383
KIRQL FASTCALL HalpVectorToIrql(UCHAR Vector)
Definition: apic.c:238
unsigned char BOOLEAN
#define ApicRaiseIrql
Definition: apic.c:200
smooth NULL
Definition: ftsmooth.c:416
enum _KINTERRUPT_MODE KINTERRUPT_MODE
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
VOID __cdecl ApicSpuriousService(VOID)
#define FORCEINLINE
Definition: ntbasedef.h:221
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1465
KIRQL NTAPI KeGetCurrentIrql(VOID)
Definition: apic.c:757
FORCEINLINE VOID IOApicWrite(UCHAR Register, ULONG Value)
Definition: apic.c:103
UCHAR HalpVectorToIndex[256]
Definition: apic.c:28
#define APIC_DFR
Definition: apic.h:17
#define DISPATCH_VECTOR
Definition: apic.h:27
ULONGLONG DestinationShortHand
Definition: apic.h:201
ULONGLONG Vector
Definition: apic.h:193
VOID NTAPI HalDisableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql)
Definition: apic.c:654
FORCEINLINE VOID ApicLowerIrql(KIRQL Irql)
Definition: apic.c:205
#define APIC_ERROR_VECTOR
Definition: apic.h:32
FORCEINLINE VOID ApicWrite(ULONG Offset, ULONG Value)
Definition: apic.h:272
#define APIC_EXT1LVTR
Definition: apic.h:77
PPC_QUAL unsigned char __readfsbyte(const unsigned long Offset)
Definition: intrin_ppc.h:360
#define APIC_PCLVTR
Definition: apic.h:66
static const UCHAR Index[8]
Definition: usbohci.c:18
PPC_QUAL void __writefsbyte(const unsigned long Offset, const unsigned char Data)
Definition: intrin_ppc.h:342
ULONG MessageType
Definition: apic.h:213
#define APIC_LINT1
Definition: apic.h:29
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
ULONG Mask
Definition: apic.h:219
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
#define APIC_SPURIOUS_VECTOR
Definition: apic.h:25
ULONG64 PageFrameNumber
Definition: mmtypes.h:78
#define IDT_INTERNAL
Definition: halp.h:21
VOID __cdecl HalpApcInterrupt(VOID)
#define APIC_ERRLVTR
Definition: apic.h:69
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1550
VOID NTAPI KiDispatchInterrupt(VOID)
Definition: thrdini.c:295
ULONG DeliveryStatus
Definition: apic.h:215
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
#define MSR_APIC_BASE
Definition: apic.h:41
VOID DECLSPEC_NORETURN FASTCALL HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:487
VOID HalpClockInterrupt(VOID)
Definition: timer.c:30
ULONG TimerMode
Definition: apic.h:220
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:242
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
const KIRQL HalVectorToIRQL[16]
Definition: apic.c:69
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: apic.c:581
#define APIC_PPR
Definition: apic.h:14
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: apic.c:813
#define APIC_VER
Definition: apic.h:11
FORCEINLINE VOID KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:369
UCHAR NTAPI HalpAllocateSystemInterrupt(IN UCHAR Irq, IN KIRQL Irql)
Definition: apic.c:336
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
ULONGLONG MessageType
Definition: apic.h:194
#define APIC_EXT3LVTR
Definition: apic.h:79
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG Vector
Definition: iofuncs.h:798
#define APIC_THRMLVTR
Definition: apic.h:65
#define IrqlToSoftVector(Irql)
Definition: apic.h:37
ULONG64 BootStrapCPUCore
Definition: apic.h:138
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define IrqlToTpr(Irql)
Definition: apic.h:36
FORCEINLINE VOID ApicSetIrql(KIRQL Irql)
Definition: apic.c:189
VOID DECLSPEC_NORETURN FASTCALL HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:536
FORCEINLINE ULONG IOApicRead(UCHAR Register)
Definition: apic.c:94
#define APIC_CLOCK_INDEX
Definition: apic.h:43
#define IOAPIC_BASE
Definition: apic.h:23
ULONG64 Write
Definition: mmtypes.h:67
#define APIC_EXT2LVTR
Definition: apic.h:78
#define OUT
Definition: typedefs.h:39
#define APIC_SIVR
Definition: apic.h:18
USHORT Number
Definition: ketypes.h:559
void __cdecl _disable(void)
Definition: intrin_arm.h:365
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID ApicSendEOI(void)
Definition: apic.c:152
KIRQL NTAPI KeRaiseIrqlToDpcLevel(VOID)
Definition: apic.c:806
#define APIC_LINT0
Definition: apic.h:28
#define IOAPIC_PHYS_BASE
Definition: apic.h:42
VOID NTAPI ApicInitializeLocalApic(ULONG Cpu)
Definition: apic.c:259
FORCEINLINE VOID ApicRequestInterrupt(IN UCHAR Vector, UCHAR TriggerMode)
Definition: apic.c:135
#define APIC_NMI_VECTOR
Definition: apic.h:35
VOID NTAPI KiDeliverApc(IN KPROCESSOR_MODE DeliveryMode, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
Definition: apc.c:302
VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Irql)
Definition: apic.c:589
void __cdecl HackEoi(void)
#define APC_LEVEL
Definition: env_spec_w32.h:695
FORCEINLINE ULONG ApicRead(ULONG Offset)
Definition: apic.h:265
#define APIC_EXT0LVTR
Definition: apic.h:76
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts)
Definition: apic.c:445
#define APIC_CLOCK_VECTOR
Definition: apic.h:29
BOOLEAN FORCEINLINE KiUserTrap(IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:305
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: apic.c:782
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:678
#define APC_VECTOR
Definition: apic.h:26
VOID NTAPI HalEndSystemInterrupt(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:741
#define EFLAGS_INTERRUPT_MASK
Definition: ketypes.h:126
#define APIC_TMRLVTR
Definition: apic.h:64