ReactOS 0.4.16-dev-1063-gd722e70
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 * https://www.codeproject.com/KB/system/soviet_kernel_hack.aspx
9 * http://bbs.unixmap.net/thread-2022-1-1.html (DEAD_LINK)
10 * https://codemachine.com/articles/interrupt_dispatching.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
31const 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
68const 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
95{
96 /* Select the register, then do the read */
97 ASSERT(Register <= 0x3F);
100}
101
103VOID
105{
106 /* Select the register, then do the write */
107 ASSERT(Register <= 0x3F);
110}
111
113VOID
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
138VOID
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.LongLong = 0;
156 Icr.Vector = Vector;
158 Icr.TriggerMode = TriggerMode;
160
161 /* Disable interrupts so that we can change IRR without being interrupted */
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 high dword first, then low dword to send the interrupt */
174
175 /* Wait until we see the interrupt request.
176 * It will stay in requested state until we re-enable interrupts.
177 */
178 while (!(ApicRead(Irr) & IrrBit))
179 {
181 }
182
183 /* Finally, restore the original interrupt state */
185 {
186 _enable();
187 }
188}
189
191VOID
193{
195}
196
198KIRQL
200{
201 /* Read the TPR and convert it to an IRQL */
202 return TprToIrql(ApicRead(APIC_PPR));
203}
204
206KIRQL
208{
209#ifdef _M_AMD64
210 return (KIRQL)__readcr8();
211#elif defined(APIC_LAZY_IRQL)
212 /* Return the field in the PCR */
214#else
215 /* Read the TPR and convert it to an IRQL */
216 return TprToIrql(ApicRead(APIC_TPR));
217#endif
218}
219
221VOID
223{
224#ifdef _M_AMD64
225 __writecr8(Irql);
226#elif defined(APIC_LAZY_IRQL)
228#else
229 /* Convert IRQL and write the TPR */
231#endif
232}
233#define ApicRaiseIrql ApicSetIrql
234
235#ifdef APIC_LAZY_IRQL
237VOID
239{
241
242 /* Is the new Irql lower than set in the TPR? */
243 if (Irql < KeGetPcr()->IRR)
244 {
245 /* Save the new hard IRQL in the IRR field */
246 KeGetPcr()->IRR = Irql;
247
248 /* Need to lower it back */
250 }
251}
252#else
253#define ApicLowerIrql ApicSetIrql
254#endif
255
256UCHAR
259{
261
262 /* Read low dword of the redirection entry */
263 ReDirReg.Long0 = IOApicRead(IOAPIC_REDTBL + 2 * Irq);
264
265 /* Return the vector */
266 return (UCHAR)ReDirReg.Vector;
267}
268
269KIRQL
272{
273 return TprToIrql(Vector);
274}
275
276UCHAR
279{
281}
282
283VOID
284NTAPI
286{
287 ApicSendEOI();
288}
289
290VOID
291NTAPI
293{
294 APIC_BASE_ADDRESS_REGISTER BaseRegister;
296 LVT_REGISTER LvtEntry;
297
298 /* Enable the APIC if it wasn't yet */
299 BaseRegister.LongLong = __readmsr(MSR_APIC_BASE);
300 BaseRegister.Enable = 1;
301 BaseRegister.BootStrapCPUCore = (Cpu == 0);
302 __writemsr(MSR_APIC_BASE, BaseRegister.LongLong);
303
304 /* Set spurious vector and SoftwareEnable to 1 */
305 SpIntRegister.Long = ApicRead(APIC_SIVR);
306 SpIntRegister.Vector = APIC_SPURIOUS_VECTOR;
307 SpIntRegister.SoftwareEnable = 1;
308 SpIntRegister.FocusCPUCoreChecking = 0;
309 ApicWrite(APIC_SIVR, SpIntRegister.Long);
310
311 /* Read the version and save it globally */
312 if (Cpu == 0) ApicVersion = ApicRead(APIC_VER);
313
314 /* Set the mode to flat (max 8 CPUs supported!) */
316
317 /* Set logical apic ID */
318 ApicWrite(APIC_LDR, ApicLogicalId(Cpu) << 24);
319
320 /* Set the spurious ISR */
322
323 /* Create a template LVT */
324 LvtEntry.Long = 0;
325 LvtEntry.Vector = APIC_FREE_VECTOR;
326 LvtEntry.MessageType = APIC_MT_Fixed;
327 LvtEntry.DeliveryStatus = 0;
328 LvtEntry.RemoteIRR = 0;
329 LvtEntry.TriggerMode = APIC_TGM_Edge;
330 LvtEntry.Mask = 1;
331 LvtEntry.TimerMode = 0;
332
333 /* Initialize and mask LVTs */
334 ApicWrite(APIC_TMRLVTR, LvtEntry.Long);
335 ApicWrite(APIC_THRMLVTR, LvtEntry.Long);
336 ApicWrite(APIC_PCLVTR, LvtEntry.Long);
337 ApicWrite(APIC_EXT0LVTR, LvtEntry.Long);
338 ApicWrite(APIC_EXT1LVTR, LvtEntry.Long);
339 ApicWrite(APIC_EXT2LVTR, LvtEntry.Long);
340 ApicWrite(APIC_EXT3LVTR, LvtEntry.Long);
341
342 /* LINT0 */
343 LvtEntry.Vector = APIC_SPURIOUS_VECTOR;
344 LvtEntry.MessageType = APIC_MT_ExtInt;
345 ApicWrite(APIC_LINT0, LvtEntry.Long);
346
347 /* Enable LINT1 (NMI) */
348 LvtEntry.Mask = 0;
349 LvtEntry.Vector = APIC_NMI_VECTOR;
350 LvtEntry.MessageType = APIC_MT_NMI;
351 LvtEntry.TriggerMode = APIC_TGM_Level;
352 ApicWrite(APIC_LINT1, LvtEntry.Long);
353
354 /* Enable error LVTR */
355 LvtEntry.Vector = APIC_ERROR_VECTOR;
356 LvtEntry.MessageType = APIC_MT_Fixed;
357 ApicWrite(APIC_ERRLVTR, LvtEntry.Long);
358
359 /* Set the IRQL from the PCR */
361#ifdef APIC_LAZY_IRQL
362 /* Save the new hard IRQL in the IRR field */
363 KeGetPcr()->IRR = KeGetPcr()->Irql;
364#endif
365}
366
367UCHAR
368NTAPI
370 _In_ UCHAR Irq,
372{
374
375 ASSERT(Irq < APIC_MAX_IRQ);
377
378 /* Setup a redirection entry */
379 ReDirReg.Vector = Vector;
382 ReDirReg.DeliveryStatus = 0;
383 ReDirReg.Polarity = 0;
384 ReDirReg.RemoteIRR = 0;
385 ReDirReg.TriggerMode = APIC_TGM_Edge;
386 ReDirReg.Mask = 1;
387 ReDirReg.Reserved = 0;
388 ReDirReg.Destination = ApicRead(APIC_ID) >> 24;
389
390 /* Initialize entry */
391 ApicWriteIORedirectionEntry(Irq, ReDirReg);
392
393 /* Save irq in the table */
395
396 return Vector;
397}
398
399ULONG
400NTAPI
404 _Out_ PKIRQL OutIrql,
405 _Out_ PKAFFINITY OutAffinity)
406{
408 KIRQL Irql;
409
410 /* Get the vector currently registered */
412
413 /* Check if it's used */
415 {
416 /* Calculate IRQL */
418 *OutIrql = HalpVectorToIrql(Vector);
419 }
420 else
421 {
423
424 /* Outer loop to find alternative slots, when all IRQLs are in use */
425 for (Offset = 0; Offset < 15; Offset++)
426 {
427 /* Loop allowed IRQL range */
428 for (Irql = CLOCK_LEVEL - 1; Irql >= CMCI_LEVEL; Irql--)
429 {
430 /* Calculate the vactor */
432
433 /* Check if the vector is free */
435 {
436 /* Found one, allocate the interrupt */
438 *OutIrql = Irql;
439 goto Exit;
440 }
441 }
442 }
443
444 DPRINT1("Failed to get an interrupt vector for IRQ %lu\n", BusInterruptLevel);
445 *OutAffinity = 0;
446 *OutIrql = 0;
447 return 0;
448 }
449
450Exit:
451
452 *OutAffinity = HalpDefaultInterruptAffinity;
454
455 return Vector;
456}
457
458VOID
459NTAPI
461{
462 PHARDWARE_PTE Pte;
464 UCHAR Index;
466
467 /* Map the I/O Apic page */
470 Pte->Valid = 1;
471 Pte->Write = 1;
472 Pte->Owner = 1;
473 Pte->CacheDisable = 1;
474 Pte->Global = 1;
476
477 /* Setup a redirection entry */
478 ReDirReg.Vector = APIC_FREE_VECTOR;
479 ReDirReg.MessageType = APIC_MT_Fixed;
481 ReDirReg.DeliveryStatus = 0;
482 ReDirReg.Polarity = 0;
483 ReDirReg.RemoteIRR = 0;
484 ReDirReg.TriggerMode = APIC_TGM_Edge;
485 ReDirReg.Mask = 1;
486 ReDirReg.Reserved = 0;
487 ReDirReg.Destination = ApicRead(APIC_ID) >> 24;
488
489 /* Loop all table entries */
490 for (Index = 0; Index < APIC_MAX_IRQ; Index++)
491 {
492 /* Initialize entry */
494 }
495
496 /* Init the vactor to index table */
497 for (Vector = 0; Vector <= 255; Vector++)
498 {
500 }
501
502 /* Enable the timer interrupt (but keep it masked) */
503 ReDirReg.Vector = APIC_CLOCK_VECTOR;
504 ReDirReg.MessageType = APIC_MT_Fixed;
506 ReDirReg.TriggerMode = APIC_TGM_Level;
507 ReDirReg.Mask = 1;
508 ReDirReg.Destination = ApicRead(APIC_ID) >> 24;
510}
511
512VOID
513NTAPI
515{
516 ULONG_PTR EFlags;
517
518 /* Save EFlags and disable interrupts */
519 EFlags = __readeflags();
520 _disable();
521
522 /* Initialize and mask the PIC */
524
525 /* Initialize the I/O APIC */
527
528 /* Manually reserve some vectors */
534
535 /* Set interrupt handlers in the IDT */
538#ifndef _M_AMD64
541#endif
542
543 /* Register the vectors for APC and dispatch interrupts */
546
547 /* Restore interrupt state */
549 __writeeflags(EFlags);
550}
551
552
553/* SOFTWARE INTERRUPT TRAPS ***************************************************/
554
555#ifndef _M_AMD64
556VOID
560{
561 KPROCESSOR_MODE ProcessorMode;
564
565 /* Enter trap */
566 KiEnterInterruptTrap(TrapFrame);
567
568#ifdef APIC_LAZY_IRQL
570 {
571 /* "Spurious" interrupt, exit the interrupt */
572 KiEoiHelper(TrapFrame);
573 }
574#else
575 /* Save the old IRQL */
578#endif
579
580 /* Raise to APC_LEVEL */
582
583 /* End the interrupt */
584 ApicSendEOI();
585
586 /* Kernel or user APC? */
587 if (KiUserTrap(TrapFrame)) ProcessorMode = UserMode;
588 else if (TrapFrame->EFlags & EFLAGS_V86_MASK) ProcessorMode = UserMode;
589 else ProcessorMode = KernelMode;
590
591 /* Enable interrupts and call the kernel's APC interrupt handler */
592 _enable();
593 KiDeliverApc(ProcessorMode, NULL, TrapFrame);
594
595 /* Disable interrupts */
596 _disable();
597
598 /* Restore the old IRQL */
600
601 /* Exit the interrupt */
602 KiEoiHelper(TrapFrame);
603}
604
605VOID
609{
612
613 /* Enter trap */
614 KiEnterInterruptTrap(TrapFrame);
615
616#ifdef APIC_LAZY_IRQL
618 {
619 /* "Spurious" interrupt, exit the interrupt */
620 KiEoiHelper(TrapFrame);
621 }
622#else
623 /* Get the current IRQL */
626#endif
627
628 /* Raise to DISPATCH_LEVEL */
630
631 /* End the interrupt */
632 ApicSendEOI();
633
634 /* Enable interrupts and call the kernel's DPC interrupt handler */
635 _enable();
637 _disable();
638
639 /* Restore the old IRQL */
641
642 /* Exit the interrupt */
643 KiEoiHelper(TrapFrame);
644}
645#endif
646
647
648/* SOFTWARE INTERRUPTS ********************************************************/
649
650
651VOID
654{
655 /* Convert irql to vector and request an interrupt */
657}
658
659VOID
662 IN KIRQL Irql)
663{
664 /* Nothing to do */
665}
666
667
668/* SYSTEM INTERRUPTS **********************************************************/
669
671NTAPI
674 IN KIRQL Irql,
676{
678 UCHAR Index;
680 ASSERT((IrqlToTpr(Irql) & 0xF0) == (Vector & 0xF0));
681
682 /* Get the irq for this vector */
684
685 /* Check if its valid */
686 if (Index == APIC_FREE_VECTOR)
687 {
688 /* Interrupt is not in use */
689 return FALSE;
690 }
691
692 /* Read the redirection entry */
694
695 /* Check if the interrupt is already enabled */
696 if (ReDirReg.Mask == FALSE)
697 {
698 /* If the vector matches, there is nothing more to do,
699 otherwise something is wrong. */
700 return (ReDirReg.Vector == Vector);
701 }
702
703 /* Set up the redirection entry */
704 ReDirReg.Vector = Vector;
705 ReDirReg.MessageType = APIC_MT_Fixed;
707 ReDirReg.Destination = ApicRead(APIC_ID) >> 24;
710 ReDirReg.Mask = FALSE;
711
712 /* Write back the entry */
714
715 return TRUE;
716}
717
718VOID
719NTAPI
722 IN KIRQL Irql)
723{
725 UCHAR Index;
728
730
731 /* Read lower dword of redirection entry */
732 ReDirReg.Long0 = IOApicRead(IOAPIC_REDTBL + 2 * Index);
733
734 /* Mask it */
735 ReDirReg.Mask = 1;
736
737 /* Write back lower dword */
738 IOApicWrite(IOAPIC_REDTBL + 2 * Index, ReDirReg.Long0);
739}
740
742NTAPI
744 IN KIRQL Irql,
747{
748 KIRQL CurrentIrql;
749
750 /* Get the current IRQL */
751 CurrentIrql = ApicGetCurrentIrql();
752
753#ifdef APIC_LAZY_IRQL
754 /* Check if this interrupt is allowed */
755 if (CurrentIrql >= Irql)
756 {
758 UCHAR Index;
759
760 /* It is not, set the real Irql in the TPR! */
761 ApicWrite(APIC_TPR, IrqlToTpr(CurrentIrql));
762
763 /* Save the new hard IRQL in the IRR field */
764 KeGetPcr()->IRR = CurrentIrql;
765
766 /* End this interrupt */
767 ApicSendEOI();
768
769 /* Get the irq for this vector */
771
772 /* Check if it's valid */
773 if (Index < APIC_MAX_IRQ)
774 {
775 /* Read the I/O redirection entry */
777
778 /* Re-request the interrupt to be handled later */
780 }
781 else
782 {
783 /* This should be a reserved vector! */
785
786 /* Re-request the interrupt to be handled later */
788 }
789
790 /* Pretend it was a spurious interrupt */
791 return FALSE;
792 }
793#endif
794 /* Save the current IRQL */
795 *OldIrql = CurrentIrql;
796
797 /* Set the new IRQL */
799
800 /* Turn on interrupts */
801 _enable();
802
803 /* Success */
804 return TRUE;
805}
806
807VOID
808NTAPI
811 IN PKTRAP_FRAME TrapFrame)
812{
813 /* Send an EOI */
814 ApicSendEOI();
815
816 /* Restore the old IRQL */
818}
819
820
821/* IRQL MANAGEMENT ************************************************************/
822
823#ifndef _M_AMD64
824KIRQL
825NTAPI
827{
828 /* Read the current TPR and convert it to an IRQL */
829 return ApicGetCurrentIrql();
830}
831
832VOID
836{
837#if DBG
838 /* Validate correct lower */
840 {
841 /* Crash system */
842 KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
843 }
844#endif
845 /* Set the new IRQL */
847}
848
849KIRQL
853{
855
856 /* Read the current IRQL */
858#if DBG
859 /* Validate correct raise */
860 if (OldIrql > NewIrql)
861 {
862 /* Crash system */
863 KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
864 }
865#endif
866 /* Convert the new IRQL to a TPR value and write the register */
868
869 /* Return old IRQL */
870 return OldIrql;
871}
872
873KIRQL
874NTAPI
876{
878}
879
880KIRQL
881NTAPI
883{
884 return KfRaiseIrql(SYNCH_LEVEL);
885}
886
887#endif /* !_M_AMD64 */
888
unsigned char BOOLEAN
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define EFLAGS_INTERRUPT_MASK
Definition: SystemCall.c:11
VOID DECLSPEC_NORETURN FASTCALL HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:559
const KIRQL HalVectorToIRQL[16]
Definition: apic.c:69
VOID NTAPI ApicInitializeLocalApic(ULONG Cpu)
Definition: apic.c:292
VOID FASTCALL KfLowerIrql(IN KIRQL OldIrql)
Definition: apic.c:834
ULONG ApicVersion
Definition: apic.c:27
VOID NTAPI HalEndSystemInterrupt(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:809
#define ApicRaiseIrql
Definition: apic.c:233
UCHAR FASTCALL HalpIrqToVector(UCHAR Irq)
Definition: apic.c:258
UCHAR HalpVectorToIndex[256]
Definition: apic.c:28
FORCEINLINE VOID ApicSetIrql(KIRQL Irql)
Definition: apic.c:222
KIRQL FASTCALL HalpVectorToIrql(UCHAR Vector)
Definition: apic.c:271
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts)
Definition: apic.c:514
VOID NTAPI ApicInitializeIOApic(VOID)
Definition: apic.c:460
UCHAR NTAPI HalpAllocateSystemInterrupt(_In_ UCHAR Irq, _In_ UCHAR Vector)
Definition: apic.c:369
FORCEINLINE VOID IOApicWrite(UCHAR Register, ULONG Value)
Definition: apic.c:104
FORCEINLINE VOID ApicLowerIrql(KIRQL Irql)
Definition: apic.c:238
FORCEINLINE VOID ApicRequestSelfInterrupt(IN UCHAR Vector, UCHAR TriggerMode)
Definition: apic.c:139
FORCEINLINE VOID ApicWriteIORedirectionEntry(UCHAR Index, IOAPIC_REDIRECTION_REGISTER ReDirReg)
Definition: apic.c:114
VOID DECLSPEC_NORETURN FASTCALL HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:608
UCHAR FASTCALL HalpVectorToIrq(UCHAR Vector)
Definition: apic.c:278
BOOLEAN NTAPI HalBeginSystemInterrupt(IN KIRQL Irql, IN ULONG Vector, OUT PKIRQL OldIrql)
Definition: apic.c:743
FORCEINLINE VOID ApicSendEOI(void)
Definition: apic.c:192
BOOLEAN NTAPI HalEnableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql, IN KINTERRUPT_MODE InterruptMode)
Definition: apic.c:672
VOID NTAPI HalDisableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql)
Definition: apic.c:720
FORCEINLINE KIRQL ApicGetProcessorIrql(VOID)
Definition: apic.c:199
ULONG NTAPI HalpGetRootInterruptVector(_In_ ULONG BusInterruptLevel, _In_ ULONG BusInterruptVector, _Out_ PKIRQL OutIrql, _Out_ PKAFFINITY OutAffinity)
Definition: apic.c:401
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: apic.c:653
VOID NTAPI HalpSendEOI(VOID)
Definition: apic.c:285
FORCEINLINE IOAPIC_REDIRECTION_REGISTER ApicReadIORedirectionEntry(UCHAR Index)
Definition: apic.c:125
FORCEINLINE ULONG IOApicRead(UCHAR Register)
Definition: apic.c:94
const UCHAR HalpIRQLtoTPR[32]
Definition: apic.c:32
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: apic.c:851
VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Irql)
Definition: apic.c:661
FORCEINLINE KIRQL ApicGetCurrentIrql(VOID)
Definition: apic.c:207
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: apic.c:882
#define MSR_APIC_BASE
Definition: apicp.h:116
#define CLOCK_IPI_VECTOR
Definition: apicp.h:47
@ APIC_DF_Flat
Definition: apicp.h:163
#define APIC_NMI_VECTOR
Definition: apicp.h:53
@ APIC_DM_Logical
Definition: apicp.h:148
@ APIC_DM_Physical
Definition: apicp.h:147
#define APC_VECTOR
Definition: apicp.h:42
@ APIC_DSH_Self
Definition: apicp.h:155
#define IOAPIC_BASE
Definition: apicp.h:38
#define APIC_CLOCK_VECTOR
Definition: apicp.h:45
#define APIC_MAX_IRQ
Definition: apicp.h:61
#define APIC_FREE_VECTOR
Definition: apicp.h:62
@ APIC_MT_LowestPriority
Definition: apicp.h:128
@ APIC_MT_Fixed
Definition: apicp.h:127
@ APIC_MT_NMI
Definition: apicp.h:131
@ APIC_MT_ExtInt
Definition: apicp.h:134
#define APIC_SPURIOUS_VECTOR
Definition: apicp.h:41
#define APIC_ERROR_VECTOR
Definition: apicp.h:49
#define IOAPIC_REDTBL
Definition: apicp.h:290
#define ApicLogicalId(Cpu)
Definition: apicp.h:119
VOID __cdecl ApicSpuriousService(VOID)
#define DISPATCH_VECTOR
Definition: apicp.h:43
FORCEINLINE ULONG ApicRead(APIC_REGISTER Register)
Definition: apicp.h:318
#define APIC_CLOCK_INDEX
Definition: apicp.h:118
#define IrqlToTpr(Irql)
Definition: apicp.h:55
#define APIC_RESERVED_VECTOR
Definition: apicp.h:63
FORCEINLINE VOID ApicWrite(APIC_REGISTER Register, ULONG Value)
Definition: apicp.h:325
#define IOAPIC_IOWIN
Definition: apicp.h:284
#define TprToIrql(Tpr)
Definition: apicp.h:57
@ APIC_LINT1
Definition: apicp.h:102
@ APIC_PPR
Definition: apicp.h:86
@ APIC_ICR0
Definition: apicp.h:96
@ APIC_EXT3LVTR
Definition: apicp.h:113
@ APIC_TPR
Definition: apicp.h:84
@ APIC_EXT1LVTR
Definition: apicp.h:111
@ APIC_VER
Definition: apicp.h:83
@ APIC_LDR
Definition: apicp.h:89
@ APIC_ERRLVTR
Definition: apicp.h:103
@ APIC_IRR
Definition: apicp.h:94
@ APIC_PCLVTR
Definition: apicp.h:100
@ APIC_ICR1
Definition: apicp.h:97
@ APIC_EXT2LVTR
Definition: apicp.h:112
@ APIC_THRMLVTR
Definition: apicp.h:99
@ APIC_TMRLVTR
Definition: apicp.h:98
@ APIC_EOI
Definition: apicp.h:87
@ APIC_ID
Definition: apicp.h:82
@ APIC_DFR
Definition: apicp.h:90
@ APIC_LINT0
Definition: apicp.h:101
@ APIC_SIVR
Definition: apicp.h:91
@ APIC_EXT0LVTR
Definition: apicp.h:110
#define IOAPIC_IOREGSEL
Definition: apicp.h:283
#define IrqlToSoftVector(Irql)
Definition: apicp.h:56
@ APIC_TGM_Level
Definition: apicp.h:141
@ APIC_TGM_Edge
Definition: apicp.h:140
#define IOAPIC_PHYS_BASE
Definition: apicp.h:117
VOID NTAPI KiDispatchInterrupt(VOID)
Definition: thrdini.c:305
#define WRITE_REGISTER_ULONG(r, v)
Definition: arm.h:27
#define READ_REGISTER_ULONG(r)
Definition: arm.h:26
#define DPRINT1
Definition: precomp.h:8
KAFFINITY * PKAFFINITY
Definition: basetsd.h:195
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1434
_Out_ PKIRQL Irql
Definition: csq.h:179
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static NTSTATUS EnableInterrupts(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR FlagsToDisable, IN UCHAR FlagsToEnable)
Definition: pnp.c:380
#define SYNCH_LEVEL
Definition: env_spec_w32.h:704
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment KeRaiseIrqlToDpcLevel
Definition: CrNtStubs.h:68
KAFFINITY HalpDefaultInterruptAffinity
Definition: processor.c:18
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)
#define HalAddressToPte(x)
Definition: halp.h:177
VOID __cdecl HalpApcInterrupt(VOID)
VOID __cdecl HalpClockIpi(VOID)
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
#define _ReadWriteBarrier()
Definition: intrin_arm.h:36
PPC_QUAL unsigned char __readfsbyte(const unsigned long Offset)
Definition: intrin_ppc.h:360
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
PPC_QUAL void __writefsbyte(const unsigned long Offset, const unsigned char Data)
Definition: intrin_ppc.h:342
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1683
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1688
#define ASSERT(a)
Definition: mode.c:44
#define EFLAGS_V86_MASK
Definition: ketypes.h:197
#define CMCI_LEVEL
Definition: ketypes.h:15
#define CLOCK_LEVEL
Definition: ketypes.h:16
#define KernelMode
Definition: asm.h:38
#define UserMode
Definition: asm.h:39
#define KeGetPcr()
Definition: ketypes.h:81
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define FASTCALL
Definition: nt_native.h:50
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
FORCEINLINE BOOLEAN KiUserTrap(IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:367
FORCEINLINE VOID KeRegisterInterruptHandler(IN ULONG Vector, IN PVOID Handler)
Definition: ke.h:301
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
@ LevelSensitive
Definition: miniport.h:80
enum _KINTERRUPT_MODE KINTERRUPT_MODE
#define YieldProcessor
Definition: ke.h:48
_Requires_lock_held_ SpinLock _Releases_lock_ SpinLock _In_ _IRQL_restores_ KIRQL NewIrql
Definition: ke.h:114
static void Exit(void)
Definition: sock.c:1330
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
Definition: ke.h:294
FORCEINLINE VOID KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:368
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
UINT32 RemoteIRR
Definition: apicp.h:274
UINT32 MessageType
Definition: apicp.h:270
UINT32 TimerMode
Definition: apicp.h:277
UINT32 Long
Definition: apicp.h:266
UINT32 Vector
Definition: apicp.h:269
UINT32 Mask
Definition: apicp.h:276
UINT32 TriggerMode
Definition: apicp.h:275
UINT32 DeliveryStatus
Definition: apicp.h:272
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define FORCEINLINE
Definition: wdftypes.h:67
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_ ULONG _In_ ULONG BusInterruptLevel
Definition: halfuncs.h:171
_In_ ULONG _In_ ULONG _In_ ULONG BusInterruptVector
Definition: halfuncs.h:172
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:806
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define NT_ASSERT
Definition: rtlfuncs.h:3327
unsigned char UCHAR
Definition: xmlstorage.h:181