ReactOS 0.4.15-dev-8231-g29a56f3
pic.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS HAL
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * PURPOSE: HAL PIC Management and Control Code
5 * PROGRAMMERS: ReactOS Portable Systems Group
6 */
7
8/* INCLUDES *******************************************************************/
9
10#include <hal.h>
11
12#define NDEBUG
13#include <debug.h>
14
15VOID
18 IN PKTRAP_FRAME TrapFrame);
19
20/* GLOBALS ********************************************************************/
21
22#ifndef _MINIHAL_
23/*
24 * This table basically keeps track of level vs edge triggered interrupts.
25 * Windows has 250+ entries, but it seems stupid to replicate that since the PIC
26 * can't actually have that many.
27 *
28 * When a level interrupt is registered, the respective pointer in this table is
29 * modified to point to a dimiss routine for level interrupts instead.
30 *
31 * The other thing this table does is special case IRQ7, IRQ13 and IRQ15:
32 *
33 * - If an IRQ line is deasserted before it is acknowledged due to a noise spike
34 * generated by an expansion device (since the IRQ line is low during the 1st
35 * acknowledge bus cycle), the i8259 will keep the line low for at least 100ns
36 * When the spike passes, a pull-up resistor will return the IRQ line to high.
37 * Since the PIC requires the input be high until the first acknowledge, the
38 * i8259 knows that this was a spurious interrupt, and on the second interrupt
39 * acknowledge cycle, it reports this to the CPU. Since no valid interrupt has
40 * actually happened Intel hardcoded the chip to report IRQ7 on the master PIC
41 * and IRQ15 on the slave PIC (IR7 either way).
42 *
43 * "ISA System Architecture", 3rd Edition, states that these cases should be
44 * handled by reading the respective Interrupt Service Request (ISR) bits from
45 * the affected PIC, and validate whether or not IR7 is set. If it isn't, then
46 * the interrupt is spurious and should be ignored.
47 *
48 * Note that for a spurious IRQ15, we DO have to send an EOI to the master for
49 * IRQ2 since the line was asserted by the slave when it received the spurious
50 * IRQ15!
51 *
52 * - When the 80287/80387 math co-processor generates an FPU/NPX trap, this is
53 * connected to IRQ13, so we have to clear the busy latch on the NPX port.
54 */
56{
65#if defined(SARCH_PC98)
66 HalpDismissIrq08,
67#else
69#endif
74#if defined(SARCH_PC98)
76#else
78#endif
81};
82
83/*
84 * These are the level IRQ dismissal functions that get copied in the table
85 * above if the given IRQ is actually level triggered.
86 */
88{
97#if defined(SARCH_PC98)
98 HalpDismissIrq08Level,
99#else
101#endif
106#if defined(SARCH_PC98)
108#else
110#endif
113};
114
115/* This table contains the static x86 PIC mapping between IRQLs and IRQs */
116extern ULONG KiI8259MaskTable[32];
117
118/* This table indicates which IRQs, if pending, can preempt a given IRQL level */
119extern ULONG FindHigherIrqlMask[32];
120
121/* Denotes minimum required IRQL before we can process pending SW interrupts */
123{
124 PASSIVE_LEVEL, /* IRR 0 */
125 PASSIVE_LEVEL, /* IRR 1 */
126 APC_LEVEL, /* IRR 2 */
127 APC_LEVEL, /* IRR 3 */
128 DISPATCH_LEVEL, /* IRR 4 */
129 DISPATCH_LEVEL, /* IRR 5 */
130 DISPATCH_LEVEL, /* IRR 6 */
131 DISPATCH_LEVEL /* IRR 7 */
132};
133
134#if defined(__GNUC__)
135
136#define HalpDelayedHardwareInterrupt(x) \
137 VOID __cdecl HalpHardwareInterrupt##x(VOID); \
138 VOID \
139 __cdecl \
140 HalpHardwareInterrupt##x(VOID) \
141 { \
142 asm volatile ("int $%c0\n"::"i"(PRIMARY_VECTOR_BASE + x)); \
143 }
144
145#elif defined(_MSC_VER)
146
147#define HalpDelayedHardwareInterrupt(x) \
148 VOID __cdecl HalpHardwareInterrupt##x(VOID); \
149 VOID \
150 __cdecl \
151 HalpHardwareInterrupt##x(VOID) \
152 { \
153 __asm \
154 { \
155 int PRIMARY_VECTOR_BASE + x \
156 } \
157 }
158
159#else
160#error Unsupported compiler
161#endif
162
163/* Pending/delayed hardware interrupt handlers */
180
181/* Handlers for pending interrupts */
183{
188 HalpHardwareInterrupt0,
189 HalpHardwareInterrupt1,
190 HalpHardwareInterrupt2,
191 HalpHardwareInterrupt3,
192 HalpHardwareInterrupt4,
193 HalpHardwareInterrupt5,
194 HalpHardwareInterrupt6,
195 HalpHardwareInterrupt7,
196 HalpHardwareInterrupt8,
197 HalpHardwareInterrupt9,
198 HalpHardwareInterrupt10,
199 HalpHardwareInterrupt11,
200 HalpHardwareInterrupt12,
201 HalpHardwareInterrupt13,
202 HalpHardwareInterrupt14,
203 HalpHardwareInterrupt15
204};
205
206/* Handlers for pending software interrupts when we already have a trap frame*/
208{
212};
213
215
216/* FUNCTIONS ******************************************************************/
217
218VOID
219NTAPI
221{
222 ULONG EFlags;
223 EISA_ELCR Elcr;
224 ULONG i, j;
225 BOOLEAN ElcrFound;
226
227 /* Save EFlags and disable interrupts */
228 EFlags = __readeflags();
229 _disable();
230
231 /* Initialize and mask the PIC */
233
234 /* Read EISA Edge/Level Register for master and slave */
236
237#if defined(SARCH_PC98)
238 /* Force defaults when ELCR is not supported */
239 if (Elcr.Bits == 0xFFFF)
240 {
241 Elcr.Master.Irq0Level = 0;
242 Elcr.Master.Irq1Level = 0;
243 Elcr.Master.Irq7Level = 0;
244 Elcr.Slave.Irq8Level = 0;
245 }
246 ElcrFound = TRUE;
247#else
248 /* IRQs 0, 1, 2, 8, and 13 are system-reserved and must be edge */
249 ElcrFound = (!(Elcr.Master.Irq0Level) && !(Elcr.Master.Irq1Level) && !(Elcr.Master.Irq2Level) &&
250 !(Elcr.Slave.Irq8Level) && !(Elcr.Slave.Irq13Level));
251#endif
252
253 if (ElcrFound)
254 {
255 /* ELCR is as it's supposed to be, save it */
256 HalpEisaELCR = Elcr.Bits;
257
258 /* Scan for level interrupts */
259 for (i = 1, j = 0; j < 16; i <<= 1, j++)
260 {
261 if (HalpEisaELCR & i)
262 {
263 /* Switch handler to level */
265
266 /* Switch dismiss to level */
268 }
269 }
270 }
271
272 /* Report cascade IRQ usage */
276 HIGH_LEVEL);
277
278 /* Restore interrupt state */
280 __writeeflags(EFlags);
281}
282
283UCHAR
286{
287 return (PRIMARY_VECTOR_BASE + Irq);
288}
289
290UCHAR
293{
294 return (Vector - PRIMARY_VECTOR_BASE);
295}
296
297KIRQL
300{
302}
303
304/* IRQL MANAGEMENT ************************************************************/
305
306/*
307 * @implemented
308 */
309KIRQL
310NTAPI
312{
313 /* Return the IRQL */
314 return KeGetPcr()->Irql;
315}
316
317/*
318 * @implemented
319 */
320KIRQL
321NTAPI
323{
324 PKPCR Pcr = KeGetPcr();
325 KIRQL CurrentIrql;
326
327 /* Save and update IRQL */
328 CurrentIrql = Pcr->Irql;
329 Pcr->Irql = DISPATCH_LEVEL;
330
331#if DBG
332 /* Validate correct raise */
333 if (CurrentIrql > DISPATCH_LEVEL) KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
334#endif
335
336 /* Return the previous value */
337 return CurrentIrql;
338}
339
340/*
341 * @implemented
342 */
343KIRQL
344NTAPI
346{
347 PKPCR Pcr = KeGetPcr();
348 KIRQL CurrentIrql;
349
350 /* Save and update IRQL */
351 CurrentIrql = Pcr->Irql;
352 Pcr->Irql = SYNCH_LEVEL;
353
354#if DBG
355 /* Validate correct raise */
356 if (CurrentIrql > SYNCH_LEVEL)
357 {
358 /* Crash system */
359 KeBugCheckEx(IRQL_NOT_GREATER_OR_EQUAL,
360 CurrentIrql,
362 0,
363 1);
364 }
365#endif
366
367 /* Return the previous value */
368 return CurrentIrql;
369}
370
371/*
372 * @implemented
373 */
374KIRQL
377{
378 PKPCR Pcr = KeGetPcr();
379 KIRQL CurrentIrql;
380
381 /* Read current IRQL */
382 CurrentIrql = Pcr->Irql;
383
384#if DBG
385 /* Validate correct raise */
386 if (CurrentIrql > NewIrql)
387 {
388 /* Crash system */
389 Pcr->Irql = PASSIVE_LEVEL;
390 KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
391 }
392#endif
393
394 /* Set new IRQL */
395 Pcr->Irql = NewIrql;
396
397 /* Return old IRQL */
398 return CurrentIrql;
399}
400
401
402/*
403 * @implemented
404 */
405VOID
408{
409 ULONG EFlags;
410 ULONG PendingIrql, PendingIrqlMask;
411 PKPCR Pcr = KeGetPcr();
413
414#if DBG
415 /* Validate correct lower */
416 if (OldIrql > Pcr->Irql)
417 {
418 /* Crash system */
419 Pcr->Irql = HIGH_LEVEL;
420 KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
421 }
422#endif
423
424 /* Save EFlags and disable interrupts */
425 EFlags = __readeflags();
426 _disable();
427
428 /* Set old IRQL */
429 Pcr->Irql = OldIrql;
430
431 /* Check for pending software interrupts and compare with current IRQL */
432 PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
433 if (PendingIrqlMask)
434 {
435 /* Check if pending IRQL affects hardware state */
436 BitScanReverse(&PendingIrql, PendingIrqlMask);
437 if (PendingIrql > DISPATCH_LEVEL)
438 {
439 /* Set new PIC mask */
440 Mask.Both = Pcr->IDR & 0xFFFF;
443
444 /* Clear IRR bit */
445 Pcr->IRR ^= (1 << PendingIrql);
446 }
447
448 /* Now handle pending interrupt */
449 SWInterruptHandlerTable[PendingIrql]();
450 }
451
452 /* Restore interrupt state */
453 __writeeflags(EFlags);
454}
455
456/* SOFTWARE INTERRUPTS ********************************************************/
457
458/*
459 * @implemented
460 */
461VOID
464{
465 ULONG EFlags;
466 PKPCR Pcr = KeGetPcr();
467 KIRQL PendingIrql;
468
469 /* Save EFlags and disable interrupts */
470 EFlags = __readeflags();
471 _disable();
472
473 /* Mask out the requested bit */
474 Pcr->IRR |= (1 << Irql);
475
476 /* Check for pending software interrupts and compare with current IRQL */
477 PendingIrql = SWInterruptLookUpTable[Pcr->IRR & 3];
478 if (PendingIrql > Pcr->Irql) SWInterruptHandlerTable[PendingIrql]();
479
480 /* Restore interrupt state */
481 __writeeflags(EFlags);
482}
483
484/*
485 * @implemented
486 */
487VOID
490{
491 /* Mask out the requested bit */
492 KeGetPcr()->IRR &= ~(1 << Irql);
493}
494
498 IN PKTRAP_FRAME TrapFrame)
499{
500 ULONG PendingIrql, PendingIrqlMask, PendingIrqMask;
501 PKPCR Pcr = KeGetPcr();
503
504 UNREFERENCED_PARAMETER(TrapFrame);
505
506 /* Set old IRQL */
507 Pcr->Irql = OldIrql;
508
509 /* Loop checking for pending interrupts */
510 while (TRUE)
511 {
512 /* Check for pending software interrupts and compare with current IRQL */
513 PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
514 if (!PendingIrqlMask) return NULL;
515
516 /* Check for in-service delayed interrupt */
517 if (Pcr->IrrActive & 0xFFFFFFF0) return NULL;
518
519 /* Check if pending IRQL affects hardware state */
520 BitScanReverse(&PendingIrql, PendingIrqlMask);
521 if (PendingIrql > DISPATCH_LEVEL)
522 {
523 /* Set new PIC mask */
524 Mask.Both = Pcr->IDR & 0xFFFF;
527
528 /* Set active bit otherwise, and clear it from IRR */
529 PendingIrqMask = (1 << PendingIrql);
530 Pcr->IrrActive |= PendingIrqMask;
531 Pcr->IRR ^= PendingIrqMask;
532
533 /* Handle delayed hardware interrupt */
534 SWInterruptHandlerTable[PendingIrql]();
535
536 /* Handling complete */
537 Pcr->IrrActive ^= PendingIrqMask;
538 }
539 else
540 {
541 /* No need to loop checking for hardware interrupts */
542 return SWInterruptHandlerTable2[PendingIrql];
543 }
544 }
545
546 return NULL;
547}
548
549/* EDGE INTERRUPT DISMISSAL FUNCTIONS *****************************************/
550
554 IN ULONG Irq,
556{
558 KIRQL CurrentIrql;
559 I8259_OCW2 Ocw2;
560 PKPCR Pcr = KeGetPcr();
561
562 /* First save current IRQL and compare it to the requested one */
563 CurrentIrql = Pcr->Irql;
564
565 /* Check if this interrupt is really allowed to happen */
566 if (Irql > CurrentIrql)
567 {
568 /* Set the new IRQL and return the current one */
569 Pcr->Irql = Irql;
570 *OldIrql = CurrentIrql;
571
572 /* Prepare OCW2 for EOI */
573 Ocw2.Bits = 0;
574 Ocw2.EoiMode = SpecificEoi;
575
576 /* Check which PIC needs the EOI */
577 if (Irq >= 8)
578 {
579#if defined(SARCH_PC98)
580 I8259_OCW3 Ocw3;
582
583 /* Send the EOI for the IRQ */
584 __outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
585
586 /* Request the ISR */
587 Ocw3.Bits = 0;
588 Ocw3.Sbo = 1;
589 Ocw3.ReadRequest = ReadIsr;
591
592 /* Read the ISR */
594
595 /* Check if the interrupt serviced was the only one from the slave PIC */
596 if (Isr.Bits == 0)
597 {
598 /* If ISR is empty, send the EOI for cascade IRQ on the master PIC */
600 }
601#else
602 /* Send the EOI for the IRQ */
603 __outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
604
605 /* Send the EOI for cascade IRQ on the master PIC */
607#endif
608 }
609 else
610 {
611 /* Send the EOI for the IRQ */
612 __outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | (Irq & 0xFF));
613 }
614
615 /* Enable interrupts and return success */
616 _enable();
617 return TRUE;
618 }
619
620 /* Update the IRR so that we deliver this interrupt when the IRQL is proper */
621 Pcr->IRR |= (1 << (Irq + 4));
622
623 /* Set new PIC mask to real IRQL level, since the optimization is lost now */
624 Mask.Both = (KiI8259MaskTable[CurrentIrql] | Pcr->IDR) & 0xFFFF;
627
628 /* Now lie and say this was spurious */
629 return FALSE;
630}
631
633NTAPI
635 IN ULONG Irq,
637{
638 /* Run the inline code */
639 return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
640}
641
643NTAPI
645 IN ULONG Irq,
647{
648 I8259_OCW3 Ocw3;
649 I8259_OCW2 Ocw2;
651
652 /* Request the ISR */
653 Ocw3.Bits = 0;
654 Ocw3.Sbo = 1; /* This encodes an OCW3 vs. an OCW2 */
655 Ocw3.ReadRequest = ReadIsr;
657
658 /* Read the ISR */
660
661 /* Is IRQ15 really active (this is IR7) */
662 if (Isr.Irq7 == FALSE)
663 {
664 /* It isn't, so we have to EOI cascade IRQ */
665 Ocw2.Bits = 0;
666 Ocw2.EoiMode = SpecificEoi;
668
669 /* And now fail since this was spurious */
670 return FALSE;
671 }
672
673 /* Do normal interrupt dismiss */
674 return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
675}
676
678NTAPI
680 IN ULONG Irq,
682{
683 /* Clear the FPU busy latch */
684 __outbyte(0xF0, 0);
685
686 /* Do normal interrupt dismiss */
687 return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
688}
689
690#if defined(SARCH_PC98)
692NTAPI
693HalpDismissIrq08(
695 _In_ ULONG Irq,
697{
698 /* Clear the FPU busy latch */
700
701 /* Do normal interrupt dismiss */
702 return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
703}
704#endif
705
707NTAPI
709 IN ULONG Irq,
711{
712 I8259_OCW3 Ocw3;
714
715 /* Request the ISR */
716 Ocw3.Bits = 0;
717 Ocw3.Sbo = 1;
718 Ocw3.ReadRequest = ReadIsr;
720
721 /* Read the ISR */
723
724 /* Is IRQ 7 really active? If it isn't, this is spurious so fail */
725 if (Isr.Irq7 == FALSE) return FALSE;
726
727 /* Do normal interrupt dismiss */
728 return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
729}
730
731/* LEVEL INTERRUPT DISMISSAL FUNCTIONS ****************************************/
732
736 IN ULONG Irq,
738{
740 KIRQL CurrentIrql;
741 I8259_OCW2 Ocw2;
742 PKPCR Pcr = KeGetPcr();
743
744 /* Update the PIC */
745 Mask.Both = (KiI8259MaskTable[Irql] | Pcr->IDR) & 0xFFFF;
748
749 /* Update the IRR so that we clear this interrupt when the IRQL is proper */
750 Pcr->IRR |= (1 << (Irq + 4));
751
752 /* Save current IRQL */
753 CurrentIrql = Pcr->Irql;
754
755 /* Prepare OCW2 for EOI */
756 Ocw2.Bits = 0;
757 Ocw2.EoiMode = SpecificEoi;
758
759 /* Check which PIC needs the EOI */
760 if (Irq >= 8)
761 {
762#if defined(SARCH_PC98)
763 I8259_OCW3 Ocw3;
765
766 /* Send the EOI for the IRQ */
767 __outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
768
769 /* Request the ISR */
770 Ocw3.Bits = 0;
771 Ocw3.Sbo = 1;
772 Ocw3.ReadRequest = ReadIsr;
774
775 /* Read the ISR */
777
778 /* Check if the interrupt serviced was the only one from the slave PIC */
779 if (Isr.Bits == 0)
780 {
781 /* If ISR is empty, send the EOI for cascade IRQ on the master PIC */
783 }
784#else
785 /* Send the EOI for the IRQ */
786 __outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
787
788 /* Send the EOI for cascade IRQ on the master PIC */
790#endif
791 }
792 else
793 {
794 /* Send the EOI for the IRQ */
795 __outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | (Irq & 0xFF));
796 }
797
798 /* Check if this interrupt should be allowed to happen */
799 if (Irql > CurrentIrql)
800 {
801 /* Set the new IRQL and return the current one */
802 Pcr->Irql = Irql;
803 *OldIrql = CurrentIrql;
804
805 /* Enable interrupts and return success */
806 _enable();
807 return TRUE;
808 }
809
810 /* Now lie and say this was spurious */
811 return FALSE;
812}
813
815NTAPI
817 IN ULONG Irq,
819{
820 /* Run the inline code */
821 return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
822}
823
825NTAPI
827 IN ULONG Irq,
829{
830 I8259_OCW3 Ocw3;
831 I8259_OCW2 Ocw2;
833
834 /* Request the ISR */
835 Ocw3.Bits = 0;
836 Ocw3.Sbo = 1; /* This encodes an OCW3 vs. an OCW2 */
837 Ocw3.ReadRequest = ReadIsr;
839
840 /* Read the ISR */
842
843 /* Is IRQ15 really active (this is IR7) */
844 if (Isr.Irq7 == FALSE)
845 {
846 /* It isn't, so we have to EOI cascade IRQ */
847 Ocw2.Bits = 0;
848 Ocw2.EoiMode = SpecificEoi;
850
851 /* And now fail since this was spurious */
852 return FALSE;
853 }
854
855 /* Do normal interrupt dismiss */
856 return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
857}
858
860NTAPI
862 IN ULONG Irq,
864{
865 /* Clear the FPU busy latch */
866 __outbyte(0xF0, 0);
867
868 /* Do normal interrupt dismiss */
869 return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
870}
871
872#if defined(SARCH_PC98)
874NTAPI
875HalpDismissIrq08Level(
877 _In_ ULONG Irq,
879{
880 /* Clear the FPU busy latch */
882
883 /* Do normal interrupt dismiss */
884 return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
885}
886#endif
887
889NTAPI
891 IN ULONG Irq,
893{
894 I8259_OCW3 Ocw3;
896
897 /* Request the ISR */
898 Ocw3.Bits = 0;
899 Ocw3.Sbo = 1;
900 Ocw3.ReadRequest = ReadIsr;
902
903 /* Read the ISR */
905
906 /* Is IRQ 7 really active? If it isn't, this is spurious so fail */
907 if (Isr.Irq7 == FALSE) return FALSE;
908
909 /* Do normal interrupt dismiss */
910 return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
911}
912
916{
917 PKPCR Pcr = KeGetPcr();
918 ULONG PendingIrqlMask, PendingIrql;
919
920 /* Check for pending software interrupts and compare with current IRQL */
921 PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[Pcr->Irql];
922 if (PendingIrqlMask)
923 {
924 /* Check for in-service delayed interrupt */
925 if (Pcr->IrrActive & 0xFFFFFFF0) return NULL;
926
927 /* Check if pending IRQL affects hardware state */
928 BitScanReverse(&PendingIrql, PendingIrqlMask);
929
930 /* Clear IRR bit */
931 Pcr->IRR ^= (1 << PendingIrql);
932
933 /* Now handle pending interrupt */
934 return SWInterruptHandlerTable[PendingIrql];
935 }
936
937 return NULL;
938}
939
940/* SYSTEM INTERRUPTS **********************************************************/
941
942/*
943 * @implemented
944 */
946NTAPI
948 IN KIRQL Irql,
950{
951 ULONG Irq;
952 PKPCR Pcr = KeGetPcr();
953 PIC_MASK PicMask;
954
955 /* Validate the IRQ */
957 if (Irq >= CLOCK2_LEVEL) return FALSE;
958
959 /* Check for level interrupt */
961 {
962 /* Switch handler to level */
964
965 /* Switch dismiss to level */
967 }
968
969 /* Disable interrupts */
970 _disable();
971
972 /* Update software IDR */
973 Pcr->IDR &= ~(1 << Irq);
974
975 /* Set new PIC mask */
976 PicMask.Both = (KiI8259MaskTable[Pcr->Irql] | Pcr->IDR) & 0xFFFF;
979
980 /* Enable interrupts and exit */
981 _enable();
982 return TRUE;
983}
984
985/*
986 * @implemented
987 */
988VOID
989NTAPI
991 IN KIRQL Irql)
992{
993 ULONG IrqMask;
994 PIC_MASK PicMask;
995
996 /* Compute new combined IRQ mask */
997 IrqMask = 1 << (Vector - PRIMARY_VECTOR_BASE);
998
999 /* Disable interrupts */
1000 _disable();
1001
1002 /* Update software IDR */
1003 KeGetPcr()->IDR |= IrqMask;
1004
1005 /* Read current interrupt mask */
1006 PicMask.Master = __inbyte(PIC1_DATA_PORT);
1007 PicMask.Slave = __inbyte(PIC2_DATA_PORT);
1008
1009 /* Add the new disabled interrupt */
1010 PicMask.Both |= IrqMask;
1011
1012 /* Write new interrupt mask */
1014 __outbyte(PIC2_DATA_PORT, PicMask.Slave);
1015
1016 /* Bring interrupts back */
1017 _enable();
1018}
1019
1020/*
1021 * @implemented
1022 */
1023BOOLEAN
1024NTAPI
1026 IN ULONG Vector,
1028{
1029 ULONG Irq;
1030
1031 /* Get the IRQ and call the proper routine to handle it */
1033 return HalpSpecialDismissTable[Irq](Irql, Irq, OldIrql);
1034}
1035
1036/*
1037 * @implemented
1038 */
1042 IN PKTRAP_FRAME TrapFrame)
1043{
1044 ULONG PendingIrql, PendingIrqlMask, PendingIrqMask;
1045 PKPCR Pcr = KeGetPcr();
1046 PIC_MASK Mask;
1047
1048 /* Set old IRQL */
1049 Pcr->Irql = OldIrql;
1050
1051 /* Check for pending software interrupts and compare with current IRQL */
1052 PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
1053 if (PendingIrqlMask)
1054 {
1055 /* Check for in-service delayed interrupt */
1056 if (Pcr->IrrActive & 0xFFFFFFF0) return NULL;
1057
1058 /* Loop checking for pending interrupts */
1059 while (TRUE)
1060 {
1061 /* Check if pending IRQL affects hardware state */
1062 BitScanReverse(&PendingIrql, PendingIrqlMask);
1063 if (PendingIrql > DISPATCH_LEVEL)
1064 {
1065 /* Set new PIC mask */
1066 Mask.Both = Pcr->IDR & 0xFFFF;
1067 __outbyte(PIC1_DATA_PORT, Mask.Master);
1069
1070 /* Now check if this specific interrupt is already in-service */
1071 PendingIrqMask = (1 << PendingIrql);
1072 if (Pcr->IrrActive & PendingIrqMask) return NULL;
1073
1074 /* Set active bit otherwise, and clear it from IRR */
1075 Pcr->IrrActive |= PendingIrqMask;
1076 Pcr->IRR ^= PendingIrqMask;
1077
1078 /* Handle delayed hardware interrupt */
1079 SWInterruptHandlerTable[PendingIrql]();
1080
1081 /* Handling complete */
1082 Pcr->IrrActive ^= PendingIrqMask;
1083
1084 /* Check if there's still interrupts pending */
1085 PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[Pcr->Irql];
1086 if (!PendingIrqlMask) break;
1087 }
1088 else
1089 {
1090 /* Now handle pending software interrupt */
1091 return SWInterruptHandlerTable2[PendingIrql];
1092 }
1093 }
1094 }
1095
1096 return NULL;
1097}
1098
1099/* SOFTWARE INTERRUPT TRAPS ***************************************************/
1100
1103VOID
1105{
1106 KIRQL CurrentIrql;
1107 PKPCR Pcr = KeGetPcr();
1108
1109 /* Save the current IRQL and update it */
1110 CurrentIrql = Pcr->Irql;
1111 Pcr->Irql = APC_LEVEL;
1112
1113 /* Remove DPC from IRR */
1114 Pcr->IRR &= ~(1 << APC_LEVEL);
1115
1116 /* Enable interrupts and call the kernel's APC interrupt handler */
1117 _enable();
1118 KiDeliverApc(((KiUserTrap(TrapFrame)) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) ?
1120 NULL,
1121 TrapFrame);
1122
1123 /* Disable interrupts and end the interrupt */
1124 _disable();
1125 HalpEndSoftwareInterrupt(CurrentIrql, TrapFrame);
1126
1127 /* Exit the interrupt */
1128 KiEoiHelper(TrapFrame);
1129}
1130
1132VOID
1135{
1136 /* Do the work */
1137 _HalpApcInterruptHandler(TrapFrame);
1138}
1139
1141VOID
1144{
1145 /* Set up a fake INT Stack */
1146 TrapFrame->EFlags = __readeflags();
1147 TrapFrame->SegCs = KGDT_R0_CODE;
1148 TrapFrame->Eip = TrapFrame->Eax;
1149
1150 /* Build the trap frame */
1151 KiEnterInterruptTrap(TrapFrame);
1152
1153 /* Do the work */
1154 _HalpApcInterruptHandler(TrapFrame);
1155}
1156
1158KIRQL
1160{
1161 KIRQL CurrentIrql;
1162 PKPCR Pcr = KeGetPcr();
1163
1164 /* Save the current IRQL and update it */
1165 CurrentIrql = Pcr->Irql;
1166 Pcr->Irql = DISPATCH_LEVEL;
1167
1168 /* Remove DPC from IRR */
1169 Pcr->IRR &= ~(1 << DISPATCH_LEVEL);
1170
1171 /* Enable interrupts and call the kernel's DPC interrupt handler */
1172 _enable();
1174 _disable();
1175
1176 /* Return IRQL */
1177 return CurrentIrql;
1178}
1179
1181VOID
1184{
1185 KIRQL CurrentIrql;
1186
1187 /* Do the work */
1188 CurrentIrql = _HalpDispatchInterruptHandler();
1189
1190 /* End the interrupt */
1191 HalpEndSoftwareInterrupt(CurrentIrql, TrapFrame);
1192
1193 /* Exit the interrupt */
1194 KiEoiHelper(TrapFrame);
1195}
1196
1198__cdecl
1200{
1201 ULONG PendingIrqlMask, PendingIrql;
1202 KIRQL OldIrql;
1203 PIC_MASK Mask;
1204 PKPCR Pcr = KeGetPcr();
1205
1206 /* Do the work */
1208
1209 /* Restore IRQL */
1210 Pcr->Irql = OldIrql;
1211
1212 /* Check for pending software interrupts and compare with current IRQL */
1213 PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
1214 if (PendingIrqlMask)
1215 {
1216 /* Check if pending IRQL affects hardware state */
1217 BitScanReverse(&PendingIrql, PendingIrqlMask);
1218 if (PendingIrql > DISPATCH_LEVEL)
1219 {
1220 /* Set new PIC mask */
1221 Mask.Both = Pcr->IDR & 0xFFFF;
1222 __outbyte(PIC1_DATA_PORT, Mask.Master);
1224
1225 /* Clear IRR bit */
1226 Pcr->IRR ^= (1 << PendingIrql);
1227 }
1228
1229 /* Now handle pending interrupt */
1230 return SWInterruptHandlerTable[PendingIrql];
1231 }
1232
1233 return NULL;
1234}
1235
1236ULONG
1237NTAPI
1240 OUT PKIRQL Irql,
1242{
1243 UCHAR SystemVector;
1244
1245 /* Validate the IRQ */
1246 if (BusInterruptLevel > 23)
1247 {
1248 /* Invalid vector */
1249 DPRINT1("IRQ %lx is too high!\n", BusInterruptLevel);
1250 return 0;
1251 }
1252
1253 /* Get the system vector */
1254 SystemVector = HalpIrqToVector((UCHAR)BusInterruptLevel);
1255
1256 /* Return the IRQL and affinity */
1257 *Irql = HalpVectorToIrql(SystemVector);
1260
1261 /* Return the vector */
1262 return SystemVector;
1263}
1264
1265#else /* _MINIHAL_ */
1266
1267KIRQL
1268NTAPI
1270{
1271 return PASSIVE_LEVEL;
1272}
1273
1274VOID
1278{
1279}
1280
1281KIRQL
1285{
1286 return NewIrql;
1287}
1288
1289#endif /* !_MINIHAL_ */
unsigned char BOOLEAN
#define EFLAGS_INTERRUPT_MASK
Definition: SystemCall.c:11
#define __cdecl
Definition: accygwin.h:79
VOID NTAPI KiDispatchInterrupt(VOID)
Definition: thrdini.c:305
#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 CLOCK2_LEVEL
Definition: env_spec_w32.h:700
#define SYNCH_LEVEL
Definition: env_spec_w32.h:704
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PROFILE_LEVEL
Definition: env_spec_w32.h:698
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
#define APC_LEVEL
Definition: env_spec_w32.h:695
#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
static BOOLEAN NTAPI Isr(PKINTERRUPT Interrupt, PVOID ServiceContext)
Definition: floppy.c:581
unsigned int Mask
Definition: fpcontrol.c:82
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
BOOLEAN NTAPI HalBeginSystemInterrupt(IN KIRQL Irql, IN ULONG Vector, OUT PKIRQL OldIrql)
Definition: pic.c:321
BOOLEAN NTAPI HalEnableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql, IN KINTERRUPT_MODE InterruptMode)
Definition: pic.c:295
VOID NTAPI HalDisableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql)
Definition: pic.c:309
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:271
VOID FASTCALL KfLowerIrql(IN KIRQL NewIrql)
Definition: pic.c:232
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: pic.c:187
VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:282
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: pic.c:156
KAFFINITY HalpDefaultInterruptAffinity
Definition: processor.c:18
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
PHAL_DISMISS_INTERRUPT HalpSpecialDismissLevelTable[16]
Definition: pic.c:87
BOOLEAN NTAPI HalpDismissIrq13(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:679
BOOLEAN NTAPI HalpDismissIrq13Level(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:861
PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY FASTCALL HalpEndSoftwareInterrupt2(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:497
BOOLEAN NTAPI HalpDismissIrqLevel(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:816
DECLSPEC_NORETURN VOID FASTCALL HalpDispatchInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:1183
PHAL_SW_INTERRUPT_HANDLER __cdecl HalpDispatchInterrupt2(VOID)
Definition: pic.c:1199
BOOLEAN NTAPI HalpDismissIrq07(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:708
HalpDelayedHardwareInterrupt(0)
FORCEINLINE BOOLEAN _HalpDismissIrqGeneric(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:553
FORCEINLINE KIRQL _HalpDispatchInterruptHandler(VOID)
Definition: pic.c:1159
ULONG KiI8259MaskTable[32]
Definition: irql.c:15
ULONG NTAPI HalpGetRootInterruptVector(IN ULONG BusInterruptLevel, IN ULONG BusInterruptVector, OUT PKIRQL Irql, OUT PKAFFINITY Affinity)
Definition: pic.c:1238
UCHAR FASTCALL HalpIrqToVector(UCHAR Irq)
Definition: pic.c:285
BOOLEAN NTAPI HalpDismissIrq15Level(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:826
KIRQL FASTCALL HalpVectorToIrql(UCHAR Vector)
Definition: pic.c:299
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts)
Definition: pic.c:220
ULONG FindHigherIrqlMask[32]
Definition: irql.c:70
PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY SWInterruptHandlerTable2[3]
Definition: pic.c:207
PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY FASTCALL HalEndSystemInterrupt2(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:1041
VOID NTAPI HalpEndSoftwareInterrupt(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
PHAL_SW_INTERRUPT_HANDLER SWInterruptHandlerTable[20]
Definition: pic.c:182
BOOLEAN NTAPI HalpDismissIrq15(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:644
UCHAR FASTCALL HalpVectorToIrq(UCHAR Vector)
Definition: pic.c:292
FORCEINLINE BOOLEAN _HalpDismissIrqLevel(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:735
BOOLEAN NTAPI HalpDismissIrqGeneric(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:634
LONG HalpEisaELCR
Definition: pic.c:214
PHAL_DISMISS_INTERRUPT HalpSpecialDismissTable[16]
Definition: pic.c:55
BOOLEAN NTAPI HalpDismissIrq07Level(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:890
DECLSPEC_NORETURN VOID FASTCALL HalpApcInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:1134
FORCEINLINE DECLSPEC_NORETURN VOID _HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:1104
PHAL_SW_INTERRUPT_HANDLER __cdecl HalpHardwareInterruptLevel2(VOID)
Definition: pic.c:915
DECLSPEC_NORETURN VOID FASTCALL HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:1143
KIRQL SWInterruptLookUpTable[8]
Definition: pic.c:122
#define PRIMARY_VECTOR_BASE
Definition: halp.h:16
#define IDT_INTERNAL
Definition: halp.h:21
#define PIC_CASCADE_IRQ
Definition: halhw.h:156
#define EISA_ELCR_SLAVE
Definition: halhw.h:334
@ SpecificEoi
Definition: halhw.h:213
#define EISA_ELCR_MASTER
Definition: halhw.h:333
@ ReadIsr
Definition: halhw.h:205
VOID __cdecl HalpDispatchInterrupt(VOID)
BOOLEAN(NTAPI * PHAL_DISMISS_INTERRUPT)(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: halp.h:78
VOID(FASTCALL * PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY)(IN PKTRAP_FRAME TrapFrame)
Definition: halp.h:46
VOID(__cdecl * PHAL_SW_INTERRUPT_HANDLER)(VOID)
Definition: halp.h:40
VOID __cdecl HalpApcInterrupt(VOID)
VOID __cdecl HalpHardwareInterruptLevel(VOID)
#define BitScanReverse
Definition: interlocked.h:6
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
PPC_QUAL unsigned char __inbyte(const unsigned long Port)
Definition: intrin_ppc.h:539
PPC_QUAL void __outbyte(unsigned long const Port, const unsigned char Data)
Definition: intrin_ppc.h:605
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1669
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1674
#define PIC1_DATA_PORT
Definition: machpc.c:54
#define PIC2_DATA_PORT
Definition: machpc.c:56
#define PIC2_CONTROL_PORT
Definition: machpc.c:55
#define PIC1_CONTROL_PORT
Definition: machpc.c:53
#define ASSERT(a)
Definition: mode.c:44
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
#define EFLAGS_V86_MASK
Definition: ketypes.h:193
#define KeGetPcr()
Definition: ketypes.h:81
#define KGDT_R0_CODE
Definition: ketypes.h:123
#define FASTCALL
Definition: nt_native.h:50
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
FORCEINLINE BOOLEAN KiUserTrap(IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:364
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
VOID KiUnexpectedInterrupt(VOID)
Definition: interrupt.c:51
long LONG
Definition: pedump.c:60
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
@ LevelSensitive
Definition: miniport.h:80
enum _KINTERRUPT_MODE KINTERRUPT_MODE
#define CPU_IO_o_FPU_BUSY_LATCH
Definition: cpu.h:17
_Requires_lock_held_ SpinLock _Releases_lock_ SpinLock _In_ _IRQL_restores_ KIRQL NewIrql
Definition: ke.h:114
Definition: ke.h:294
ULONG IDR
Definition: ke.h:23
ULONG IRR
Definition: ke.h:22
ULONG IrrActive
Definition: ke.h:50
KIRQL Irql
Definition: ke.h:311
FORCEINLINE VOID KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:368
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
struct _EISA_ELCR::@1526::@1529 Slave
USHORT Bits
Definition: halhw.h:363
struct _EISA_ELCR::@1526::@1528 Master
UCHAR EoiMode
Definition: halhw.h:290
UCHAR Bits
Definition: halhw.h:292
UCHAR Sbo
Definition: halhw.h:301
UCHAR ReadRequest
Definition: halhw.h:299
UCHAR Bits
Definition: halhw.h:306
UCHAR Slave
Definition: halhw.h:371
USHORT Both
Definition: halhw.h:373
UCHAR Master
Definition: halhw.h:370
#define FORCEINLINE
Definition: wdftypes.h:67
_In_ ULONG _In_ ULONG BusInterruptLevel
Definition: halfuncs.h:171
_In_ ULONG _In_ ULONG _In_ ULONG BusInterruptVector
Definition: halfuncs.h:172
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:174
_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
unsigned char UCHAR
Definition: xmlstorage.h:181