ReactOS 0.4.16-dev-340-g0540c21
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
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.Long0 = 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 the low dword to send the interrupt */
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
190VOID
192{
194}
195
197KIRQL
199{
200 /* Read the TPR and convert it to an IRQL */
201 return TprToIrql(ApicRead(APIC_PPR));
202}
203
205KIRQL
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
220VOID
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
236VOID
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
255UCHAR
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
268KIRQL
271{
272 return TprToIrql(Vector);
273}
274
275UCHAR
278{
280}
281
282VOID
283NTAPI
285{
286 ApicSendEOI();
287}
288
289VOID
290NTAPI
292{
293 APIC_BASE_ADDRESS_REGISTER BaseRegister;
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
366UCHAR
367NTAPI
369 _In_ UCHAR Irq,
371{
373
374 ASSERT(Irq < APIC_MAX_IRQ);
376
377 /* Setup a redirection entry */
378 ReDirReg.Vector = Vector;
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 */
394
395 return Vector;
396}
397
398ULONG
399NTAPI
403 _Out_ PKIRQL OutIrql,
404 _Out_ PKAFFINITY OutAffinity)
405{
407 KIRQL Irql;
408
409 /* Get the vector currently registered */
411
412 /* Check if it's used */
414 {
415 /* Calculate IRQL */
417 *OutIrql = HalpVectorToIrql(Vector);
418 }
419 else
420 {
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
449Exit:
450
451 *OutAffinity = HalpDefaultInterruptAffinity;
453
454 return Vector;
455}
456
457VOID
458NTAPI
460{
461 PHARDWARE_PTE Pte;
463 UCHAR Index;
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.MessageType = 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.MessageType = APIC_MT_Fixed;
505 ReDirReg.TriggerMode = APIC_TGM_Edge;
506 ReDirReg.Mask = 1;
507 ReDirReg.Destination = ApicRead(APIC_ID);
509}
510
511VOID
512NTAPI
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 */
533
534 /* Set interrupt handlers in the IDT */
537#ifndef _M_AMD64
540#endif
541
542 /* Register the vectors for APC and dispatch interrupts */
545
546 /* Restore interrupt state */
548 __writeeflags(EFlags);
549}
550
551
552/* SOFTWARE INTERRUPT TRAPS ***************************************************/
553
554#ifndef _M_AMD64
555VOID
559{
560 KPROCESSOR_MODE ProcessorMode;
563
564 /* Enter trap */
565 KiEnterInterruptTrap(TrapFrame);
566
567#ifdef APIC_LAZY_IRQL
569 {
570 /* "Spurious" interrupt, exit the interrupt */
571 KiEoiHelper(TrapFrame);
572 }
573#else
574 /* Save the old IRQL */
577#endif
578
579 /* Raise to APC_LEVEL */
581
582 /* End the interrupt */
583 ApicSendEOI();
584
585 /* Kernel or user APC? */
586 if (KiUserTrap(TrapFrame)) ProcessorMode = UserMode;
587 else if (TrapFrame->EFlags & EFLAGS_V86_MASK) ProcessorMode = UserMode;
588 else ProcessorMode = KernelMode;
589
590 /* Enable interrupts and call the kernel's APC interrupt handler */
591 _enable();
592 KiDeliverApc(ProcessorMode, NULL, TrapFrame);
593
594 /* Disable interrupts */
595 _disable();
596
597 /* Restore the old IRQL */
599
600 /* Exit the interrupt */
601 KiEoiHelper(TrapFrame);
602}
603
604VOID
608{
611
612 /* Enter trap */
613 KiEnterInterruptTrap(TrapFrame);
614
615#ifdef APIC_LAZY_IRQL
617 {
618 /* "Spurious" interrupt, exit the interrupt */
619 KiEoiHelper(TrapFrame);
620 }
621#else
622 /* Get the current IRQL */
625#endif
626
627 /* Raise to DISPATCH_LEVEL */
629
630 /* End the interrupt */
631 ApicSendEOI();
632
633 /* Enable interrupts and call the kernel's DPC interrupt handler */
634 _enable();
636 _disable();
637
638 /* Restore the old IRQL */
640
641 /* Exit the interrupt */
642 KiEoiHelper(TrapFrame);
643}
644#endif
645
646
647/* SOFTWARE INTERRUPTS ********************************************************/
648
649
650VOID
653{
654 /* Convert irql to vector and request an interrupt */
656}
657
658VOID
661 IN KIRQL Irql)
662{
663 /* Nothing to do */
664}
665
666
667/* SYSTEM INTERRUPTS **********************************************************/
668
670NTAPI
673 IN KIRQL Irql,
675{
677 PKPRCB Prcb = KeGetCurrentPrcb();
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 was unused */
696 if (ReDirReg.Vector != Vector)
697 {
698 ReDirReg.Vector = Vector;
701 ReDirReg.Destination = 0;
702 }
703
704 /* Check if the destination is logical */
705 if (ReDirReg.DestinationMode == APIC_DM_Logical)
706 {
707 /* Set the bit for this cpu */
708 ReDirReg.Destination |= ApicLogicalId(Prcb->Number);
709 }
710
711 /* Set the trigger mode */
712 ReDirReg.TriggerMode = 1 - InterruptMode;
713
714 /* Now unmask it */
715 ReDirReg.Mask = FALSE;
716
717 /* Write back the entry */
719
720 return TRUE;
721}
722
723VOID
724NTAPI
727 IN KIRQL Irql)
728{
730 UCHAR Index;
733
735
736 /* Read lower dword of redirection entry */
737 ReDirReg.Long0 = IOApicRead(IOAPIC_REDTBL + 2 * Index);
738
739 /* Mask it */
740 ReDirReg.Mask = 1;
741
742 /* Write back lower dword */
743 IOApicWrite(IOAPIC_REDTBL + 2 * Index, ReDirReg.Long0);
744}
745
746#ifndef _M_AMD64
748NTAPI
750 IN KIRQL Irql,
753{
754 KIRQL CurrentIrql;
755
756 /* Get the current IRQL */
757 CurrentIrql = ApicGetCurrentIrql();
758
759#ifdef APIC_LAZY_IRQL
760 /* Check if this interrupt is allowed */
761 if (CurrentIrql >= Irql)
762 {
764 UCHAR Index;
765
766 /* It is not, set the real Irql in the TPR! */
767 ApicWrite(APIC_TPR, IrqlToTpr(CurrentIrql));
768
769 /* Save the new hard IRQL in the IRR field */
770 KeGetPcr()->IRR = CurrentIrql;
771
772 /* End this interrupt */
773 ApicSendEOI();
774
775 /* Get the irq for this vector */
777
778 /* Check if it's valid */
779 if (Index < APIC_MAX_IRQ)
780 {
781 /* Read the I/O redirection entry */
783
784 /* Re-request the interrupt to be handled later */
786 }
787 else
788 {
789 /* This should be a reserved vector! */
791
792 /* Re-request the interrupt to be handled later */
794 }
795
796 /* Pretend it was a spurious interrupt */
797 return FALSE;
798 }
799#endif
800 /* Save the current IRQL */
801 *OldIrql = CurrentIrql;
802
803 /* Set the new IRQL */
805
806 /* Turn on interrupts */
807 _enable();
808
809 /* Success */
810 return TRUE;
811}
812
813VOID
814NTAPI
817 IN PKTRAP_FRAME TrapFrame)
818{
819 /* Send an EOI */
820 ApicSendEOI();
821
822 /* Restore the old IRQL */
824}
825
826
827/* IRQL MANAGEMENT ************************************************************/
828
829KIRQL
830NTAPI
832{
833 /* Read the current TPR and convert it to an IRQL */
834 return ApicGetCurrentIrql();
835}
836
837VOID
841{
842#if DBG
843 /* Validate correct lower */
845 {
846 /* Crash system */
847 KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
848 }
849#endif
850 /* Set the new IRQL */
852}
853
854KIRQL
858{
860
861 /* Read the current IRQL */
863#if DBG
864 /* Validate correct raise */
865 if (OldIrql > NewIrql)
866 {
867 /* Crash system */
868 KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
869 }
870#endif
871 /* Convert the new IRQL to a TPR value and write the register */
873
874 /* Return old IRQL */
875 return OldIrql;
876}
877
878KIRQL
879NTAPI
881{
883}
884
885KIRQL
886NTAPI
888{
889 return KfRaiseIrql(SYNCH_LEVEL);
890}
891
892#endif /* !_M_AMD64 */
893
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:558
const KIRQL HalVectorToIRQL[16]
Definition: apic.c:69
VOID NTAPI ApicInitializeLocalApic(ULONG Cpu)
Definition: apic.c:291
VOID FASTCALL KfLowerIrql(IN KIRQL OldIrql)
Definition: apic.c:839
ULONG ApicVersion
Definition: apic.c:27
VOID NTAPI HalEndSystemInterrupt(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
Definition: apic.c:815
#define ApicRaiseIrql
Definition: apic.c:232
UCHAR FASTCALL HalpIrqToVector(UCHAR Irq)
Definition: apic.c:257
UCHAR HalpVectorToIndex[256]
Definition: apic.c:28
FORCEINLINE VOID ApicSetIrql(KIRQL Irql)
Definition: apic.c:221
KIRQL FASTCALL HalpVectorToIrql(UCHAR Vector)
Definition: apic.c:270
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts)
Definition: apic.c:513
VOID NTAPI ApicInitializeIOApic(VOID)
Definition: apic.c:459
UCHAR NTAPI HalpAllocateSystemInterrupt(_In_ UCHAR Irq, _In_ UCHAR Vector)
Definition: apic.c:368
FORCEINLINE VOID IOApicWrite(UCHAR Register, ULONG Value)
Definition: apic.c:104
FORCEINLINE VOID ApicLowerIrql(KIRQL Irql)
Definition: apic.c:237
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:607
UCHAR FASTCALL HalpVectorToIrq(UCHAR Vector)
Definition: apic.c:277
BOOLEAN NTAPI HalBeginSystemInterrupt(IN KIRQL Irql, IN ULONG Vector, OUT PKIRQL OldIrql)
Definition: apic.c:749
FORCEINLINE VOID ApicSendEOI(void)
Definition: apic.c:191
BOOLEAN NTAPI HalEnableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql, IN KINTERRUPT_MODE InterruptMode)
Definition: apic.c:671
VOID NTAPI HalDisableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql)
Definition: apic.c:725
FORCEINLINE KIRQL ApicGetProcessorIrql(VOID)
Definition: apic.c:198
ULONG NTAPI HalpGetRootInterruptVector(_In_ ULONG BusInterruptLevel, _In_ ULONG BusInterruptVector, _Out_ PKIRQL OutIrql, _Out_ PKAFFINITY OutAffinity)
Definition: apic.c:400
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: apic.c:652
VOID NTAPI HalpSendEOI(VOID)
Definition: apic.c:284
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:856
VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Irql)
Definition: apic.c:660
FORCEINLINE KIRQL ApicGetCurrentIrql(VOID)
Definition: apic.c:206
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: apic.c:887
#define MSR_APIC_BASE
Definition: apicp.h:114
#define CLOCK_IPI_VECTOR
Definition: apicp.h:46
@ APIC_DF_Flat
Definition: apicp.h:161
#define APIC_NMI_VECTOR
Definition: apicp.h:52
@ APIC_DM_Logical
Definition: apicp.h:146
@ APIC_DM_Physical
Definition: apicp.h:145
#define APC_VECTOR
Definition: apicp.h:41
@ APIC_DSH_Self
Definition: apicp.h:153
#define IOAPIC_BASE
Definition: apicp.h:37
#define APIC_CLOCK_VECTOR
Definition: apicp.h:44
#define APIC_MAX_IRQ
Definition: apicp.h:59
#define APIC_FREE_VECTOR
Definition: apicp.h:60
@ APIC_MT_LowestPriority
Definition: apicp.h:126
@ APIC_MT_Fixed
Definition: apicp.h:125
@ APIC_MT_NMI
Definition: apicp.h:129
@ APIC_MT_ExtInt
Definition: apicp.h:132
#define APIC_SPURIOUS_VECTOR
Definition: apicp.h:40
#define APIC_ERROR_VECTOR
Definition: apicp.h:48
#define IOAPIC_REDTBL
Definition: apicp.h:288
#define ApicLogicalId(Cpu)
Definition: apicp.h:117
VOID __cdecl ApicSpuriousService(VOID)
#define DISPATCH_VECTOR
Definition: apicp.h:42
FORCEINLINE ULONG ApicRead(APIC_REGISTER Register)
Definition: apicp.h:316
#define APIC_CLOCK_INDEX
Definition: apicp.h:116
#define IrqlToTpr(Irql)
Definition: apicp.h:54
#define APIC_RESERVED_VECTOR
Definition: apicp.h:61
FORCEINLINE VOID ApicWrite(APIC_REGISTER Register, ULONG Value)
Definition: apicp.h:323
#define IOAPIC_IOWIN
Definition: apicp.h:282
#define TprToIrql(Tpr)
Definition: apicp.h:56
@ APIC_LINT1
Definition: apicp.h:100
@ APIC_PPR
Definition: apicp.h:84
@ APIC_ICR0
Definition: apicp.h:94
@ APIC_EXT3LVTR
Definition: apicp.h:111
@ APIC_TPR
Definition: apicp.h:82
@ APIC_EXT1LVTR
Definition: apicp.h:109
@ APIC_VER
Definition: apicp.h:81
@ APIC_LDR
Definition: apicp.h:87
@ APIC_ERRLVTR
Definition: apicp.h:101
@ APIC_IRR
Definition: apicp.h:92
@ APIC_PCLVTR
Definition: apicp.h:98
@ APIC_EXT2LVTR
Definition: apicp.h:110
@ APIC_THRMLVTR
Definition: apicp.h:97
@ APIC_TMRLVTR
Definition: apicp.h:96
@ APIC_EOI
Definition: apicp.h:85
@ APIC_ID
Definition: apicp.h:80
@ APIC_DFR
Definition: apicp.h:88
@ APIC_LINT0
Definition: apicp.h:99
@ APIC_SIVR
Definition: apicp.h:89
@ APIC_EXT0LVTR
Definition: apicp.h:108
#define IOAPIC_IOREGSEL
Definition: apicp.h:281
#define IrqlToSoftVector(Irql)
Definition: apicp.h:55
@ APIC_TGM_Level
Definition: apicp.h:139
@ APIC_TGM_Edge
Definition: apicp.h:138
#define IOAPIC_PHYS_BASE
Definition: apicp.h:115
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:1430
_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)
#define NOTHING
Definition: input_list.c:10
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:1669
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1674
#define ASSERT(a)
Definition: mode.c:44
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
#define EFLAGS_V86_MASK
Definition: ketypes.h:182
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1150
#define CMCI_LEVEL
Definition: ketypes.h:15
#define CLOCK_LEVEL
Definition: ketypes.h:16
#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:364
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
enum _KINTERRUPT_MODE KINTERRUPT_MODE
_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
USHORT Number
Definition: ketypes.h:632
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:272
UINT32 MessageType
Definition: apicp.h:268
UINT32 TimerMode
Definition: apicp.h:275
UINT32 Long
Definition: apicp.h:264
UINT32 Vector
Definition: apicp.h:267
UINT32 Mask
Definition: apicp.h:274
UINT32 TriggerMode
Definition: apicp.h:273
UINT32 DeliveryStatus
Definition: apicp.h:270
_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