ReactOS  0.4.15-dev-1203-g0e5a4d5
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 
15 VOID
16 NTAPI
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 */
116 extern ULONG KiI8259MaskTable[32];
117 
118 /* This table indicates which IRQs, if pending, can preempt a given IRQL level */
119 extern 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 
218 VOID
219 NTAPI
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 
283 UCHAR
284 FASTCALL
286 {
287  return (PRIMARY_VECTOR_BASE + Irq);
288 }
289 
290 UCHAR
291 FASTCALL
293 {
294  return (Vector - PRIMARY_VECTOR_BASE);
295 }
296 
297 KIRQL
298 FASTCALL
300 {
302 }
303 
304 /* IRQL MANAGEMENT ************************************************************/
305 
306 /*
307  * @implemented
308  */
309 KIRQL
310 NTAPI
312 {
313  /* Return the IRQL */
314  return KeGetPcr()->Irql;
315 }
316 
317 /*
318  * @implemented
319  */
320 KIRQL
321 NTAPI
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  */
343 KIRQL
344 NTAPI
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,
361  SYNCH_LEVEL,
362  0,
363  1);
364  }
365 #endif
366 
367  /* Return the previous value */
368  return CurrentIrql;
369 }
370 
371 /*
372  * @implemented
373  */
374 KIRQL
375 FASTCALL
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  */
405 VOID
406 FASTCALL
408 {
409  ULONG EFlags;
410  ULONG PendingIrql, PendingIrqlMask;
411  PKPCR Pcr = KeGetPcr();
412  PIC_MASK Mask;
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;
441  __outbyte(PIC1_DATA_PORT, Mask.Master);
442  __outbyte(PIC2_DATA_PORT, Mask.Slave);
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  */
461 VOID
462 FASTCALL
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  */
487 VOID
488 FASTCALL
490 {
491  /* Mask out the requested bit */
492  KeGetPcr()->IRR &= ~(1 << Irql);
493 }
494 
496 FASTCALL
498  IN PKTRAP_FRAME TrapFrame)
499 {
500  ULONG PendingIrql, PendingIrqlMask, PendingIrqMask;
501  PKPCR Pcr = KeGetPcr();
502  PIC_MASK Mask;
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;
525  __outbyte(PIC1_DATA_PORT, Mask.Master);
526  __outbyte(PIC2_DATA_PORT, Mask.Slave);
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 
552 BOOLEAN
554  IN ULONG Irq,
556 {
557  PIC_MASK Mask;
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;
581  I8259_ISR Isr;
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;
625  __outbyte(PIC1_DATA_PORT, Mask.Master);
626  __outbyte(PIC2_DATA_PORT, Mask.Slave);
627 
628  /* Now lie and say this was spurious */
629  return FALSE;
630 }
631 
632 BOOLEAN
633 NTAPI
635  IN ULONG Irq,
637 {
638  /* Run the inline code */
639  return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
640 }
641 
642 BOOLEAN
643 NTAPI
645  IN ULONG Irq,
647 {
648  I8259_OCW3 Ocw3;
649  I8259_OCW2 Ocw2;
650  I8259_ISR Isr;
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 
677 BOOLEAN
678 NTAPI
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)
691 BOOLEAN
692 NTAPI
693 HalpDismissIrq08(
694  _In_ KIRQL Irql,
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 
706 BOOLEAN
707 NTAPI
709  IN ULONG Irq,
711 {
712  I8259_OCW3 Ocw3;
713  I8259_ISR Isr;
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 
734 BOOLEAN
736  IN ULONG Irq,
738 {
739  PIC_MASK Mask;
740  KIRQL CurrentIrql;
741  I8259_OCW2 Ocw2;
742  PKPCR Pcr = KeGetPcr();
743 
744  /* Update the PIC */
745  Mask.Both = (KiI8259MaskTable[Irql] | Pcr->IDR) & 0xFFFF;
746  __outbyte(PIC1_DATA_PORT, Mask.Master);
747  __outbyte(PIC2_DATA_PORT, Mask.Slave);
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;
764  I8259_ISR Isr;
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 
814 BOOLEAN
815 NTAPI
817  IN ULONG Irq,
819 {
820  /* Run the inline code */
821  return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
822 }
823 
824 BOOLEAN
825 NTAPI
827  IN ULONG Irq,
829 {
830  I8259_OCW3 Ocw3;
831  I8259_OCW2 Ocw2;
832  I8259_ISR Isr;
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 
859 BOOLEAN
860 NTAPI
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)
873 BOOLEAN
874 NTAPI
875 HalpDismissIrq08Level(
876  _In_ KIRQL Irql,
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 
888 BOOLEAN
889 NTAPI
891  IN ULONG Irq,
893 {
894  I8259_OCW3 Ocw3;
895  I8259_ISR Isr;
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 
914 __cdecl
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  */
945 BOOLEAN
946 NTAPI
948  IN KIRQL Irql,
950 {
951  ULONG Irq;
952  PKPCR Pcr = KeGetPcr();
953  PIC_MASK PicMask;
954 
955  /* Validate the IRQ */
956  Irq = Vector - PRIMARY_VECTOR_BASE;
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;
977  __outbyte(PIC1_DATA_PORT, PicMask.Master);
978  __outbyte(PIC2_DATA_PORT, PicMask.Slave);
979 
980  /* Enable interrupts and exit */
981  _enable();
982  return TRUE;
983 }
984 
985 /*
986  * @implemented
987  */
988 VOID
989 NTAPI
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 */
1013  __outbyte(PIC1_DATA_PORT, PicMask.Master);
1014  __outbyte(PIC2_DATA_PORT, PicMask.Slave);
1015 
1016  /* Bring interrupts back */
1017  _enable();
1018 }
1019 
1020 /*
1021  * @implemented
1022  */
1023 BOOLEAN
1024 NTAPI
1026  IN ULONG Vector,
1027  OUT PKIRQL OldIrql)
1028 {
1029  ULONG Irq;
1030 
1031  /* Get the IRQ and call the proper routine to handle it */
1032  Irq = Vector - PRIMARY_VECTOR_BASE;
1033  return HalpSpecialDismissTable[Irq](Irql, Irq, OldIrql);
1034 }
1035 
1036 /*
1037  * @implemented
1038  */
1040 FASTCALL
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);
1068  __outbyte(PIC2_DATA_PORT, Mask.Slave);
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 
1103 VOID
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)) ?
1119  UserMode : KernelMode,
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 
1132 VOID
1133 FASTCALL
1135 {
1136  /* Do the work */
1137  _HalpApcInterruptHandler(TrapFrame);
1138 }
1139 
1141 VOID
1142 FASTCALL
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 
1158 KIRQL
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 
1181 VOID
1182 FASTCALL
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);
1223  __outbyte(PIC2_DATA_PORT, Mask.Slave);
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 
1236 #else /* _MINIHAL_ */
1237 
1238 KIRQL
1239 NTAPI
1241 {
1242  return PASSIVE_LEVEL;
1243 }
1244 
1245 VOID
1246 FASTCALL
1247 KfLowerIrql(
1248  IN KIRQL OldIrql)
1249 {
1250 }
1251 
1252 KIRQL
1253 FASTCALL
1254 KfRaiseIrql(
1255  IN KIRQL NewIrql)
1256 {
1257  return NewIrql;
1258 }
1259 
1260 #endif /* !_MINIHAL_ */
KIRQL Irql
Definition: ke.h:307
#define IN
Definition: typedefs.h:39
BOOLEAN NTAPI HalEnableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql, IN KINTERRUPT_MODE InterruptMode)
Definition: pic.c:295
static NTSTATUS EnableInterrupts(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR FlagsToDisable, IN UCHAR FlagsToEnable)
Definition: pnp.c:380
LONG HalpEisaELCR
Definition: pic.c:214
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:798
BOOLEAN NTAPI HalpDismissIrq07(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:708
USHORT Bits
Definition: halhw.h:363
#define __cdecl
Definition: accygwin.h:79
#define EISA_ELCR_MASTER
Definition: halhw.h:333
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
DECLSPEC_NORETURN VOID FASTCALL HalpDispatchInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:1183
UCHAR EoiMode
Definition: halhw.h:290
DECLSPEC_NORETURN VOID FASTCALL HalpApcInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:1134
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
PHAL_DISMISS_INTERRUPT HalpSpecialDismissLevelTable[16]
Definition: pic.c:87
#define PRIMARY_VECTOR_BASE
Definition: halp.h:16
PHAL_DISMISS_INTERRUPT HalpSpecialDismissTable[16]
Definition: pic.c:55
KIRQL NTAPI KeGetCurrentIrql(VOID)
Definition: pic.c:122
ULONG IDR
Definition: ke.h:22
#define KGDT_R0_CODE
Definition: ketypes.h:75
PHAL_SW_INTERRUPT_HANDLER __cdecl HalpHardwareInterruptLevel2(VOID)
Definition: pic.c:915
BOOLEAN NTAPI HalBeginSystemInterrupt(IN KIRQL Irql, IN ULONG Vector, OUT PKIRQL OldIrql)
Definition: pic.c:321
ULONG FindHigherIrqlMask[32]
Definition: irql.c:70
PPC_QUAL void __outbyte(unsigned long const Port, const unsigned char Data)
Definition: intrin_ppc.h:605
Definition: ke.h:289
#define FASTCALL
Definition: nt_native.h:50
_Out_ PKIRQL Irql
Definition: csq.h:179
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
DECLSPEC_NORETURN VOID FASTCALL HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:1143
#define KeGetPcr()
Definition: ke.h:25
FORCEINLINE BOOLEAN _HalpDismissIrqLevel(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:735
#define EFLAGS_V86_MASK
Definition: ketypes.h:129
VOID NTAPI HalDisableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql)
Definition: pic.c:309
BOOLEAN NTAPI HalpDismissIrqGeneric(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:634
FORCEINLINE BOOLEAN _HalpDismissIrqGeneric(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:553
UCHAR KIRQL
Definition: env_spec_w32.h:591
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
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1569
UCHAR ReadRequest
Definition: halhw.h:299
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1431
long LONG
Definition: pedump.c:60
PHAL_SW_INTERRUPT_HANDLER SWInterruptHandlerTable[20]
Definition: pic.c:182
BOOLEAN NTAPI HalpDismissIrq15Level(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:826
VOID __cdecl HalpDispatchInterrupt(VOID)
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts)
Definition: pic.c:220
PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY FASTCALL HalpEndSoftwareInterrupt2(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:497
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
enum _KINTERRUPT_MODE KINTERRUPT_MODE
PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY SWInterruptHandlerTable2[3]
Definition: pic.c:207
#define FORCEINLINE
Definition: ntbasedef.h:216
#define _Out_
Definition: no_sal2.h:160
KIRQL FASTCALL HalpVectorToIrql(UCHAR Vector)
Definition: pic.c:299
ULONG IrrActive
Definition: ke.h:49
struct _EISA_ELCR::@1509::@1511 Master
#define PIC_CASCADE_IRQ
Definition: halhw.h:156
VOID(FASTCALL * PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY)(IN PKTRAP_FRAME TrapFrame)
Definition: halp.h:38
VOID KiUnexpectedInterrupt(VOID)
Definition: interrupt.c:51
UCHAR Sbo
Definition: halhw.h:301
#define EISA_ELCR_SLAVE
Definition: halhw.h:334
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
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: pic.c:187
static BOOLEAN NTAPI Isr(PKINTERRUPT Interrupt, PVOID ServiceContext)
Definition: floppy.c:581
KIRQL SWInterruptLookUpTable[8]
Definition: pic.c:122
FORCEINLINE DECLSPEC_NORETURN VOID _HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:1104
Definition: irql.c:21
BOOLEAN NTAPI HalpDismissIrq13(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:679
#define CLOCK2_LEVEL
Definition: env_spec_w32.h:700
struct _EISA_ELCR::@1509::@1512 Slave
VOID NTAPI HalpEndSoftwareInterrupt(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IDT_INTERNAL
Definition: halp.h:21
VOID __cdecl HalpApcInterrupt(VOID)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1564
#define BitScanReverse
Definition: interlocked.h:6
VOID NTAPI KiDispatchInterrupt(VOID)
Definition: thrdini.c:295
#define PIC1_CONTROL_PORT
Definition: halhw.h:150
BOOLEAN NTAPI HalpDismissIrqLevel(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:816
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
UCHAR Bits
Definition: halhw.h:292
HalpDelayedHardwareInterrupt(0)
Definition: halhw.h:205
#define SYNCH_LEVEL
Definition: env_spec_w32.h:704
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
KIRQL NTAPI KeRaiseIrqlToDpcLevel(VOID)
Definition: pic.c:133
FORCEINLINE BOOLEAN KiUserTrap(IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:305
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define _In_
Definition: no_sal2.h:158
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:271
FORCEINLINE KIRQL _HalpDispatchInterruptHandler(VOID)
Definition: pic.c:1159
UCHAR Bits
Definition: halhw.h:306
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
VOID FASTCALL KfLowerIrql(IN KIRQL NewIrql)
Definition: pic.c:232
FORCEINLINE VOID KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:368
PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY FASTCALL HalEndSystemInterrupt2(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:1041
#define CPU_IO_o_FPU_BUSY_LATCH
Definition: cpu.h:17
PHAL_SW_INTERRUPT_HANDLER __cdecl HalpDispatchInterrupt2(VOID)
Definition: pic.c:1199
#define PROFILE_LEVEL
Definition: env_spec_w32.h:698
UCHAR FASTCALL HalpVectorToIrq(UCHAR Vector)
Definition: pic.c:292
ULONG KiI8259MaskTable[32]
Definition: irql.c:15
#define PIC1_DATA_PORT
Definition: halhw.h:151
BOOLEAN NTAPI HalpDismissIrq13Level(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:861
#define PIC2_DATA_PORT
Definition: halhw.h:153
VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:282
#define OUT
Definition: typedefs.h:40
UCHAR FASTCALL HalpIrqToVector(UCHAR Irq)
Definition: pic.c:285
void __cdecl _disable(void)
Definition: intrin_arm.h:365
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN(NTAPI * PHAL_DISMISS_INTERRUPT)(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: halp.h:64
VOID __cdecl HalpHardwareInterruptLevel(VOID)
VOID NTAPI KiDeliverApc(IN KPROCESSOR_MODE DeliveryMode, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
Definition: apc.c:302
#define APC_LEVEL
Definition: env_spec_w32.h:695
ULONG IRR
Definition: ke.h:21
#define PIC2_CONTROL_PORT
Definition: halhw.h:152
BOOLEAN NTAPI HalpDismissIrq07Level(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:890
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
VOID(__cdecl * PHAL_SW_INTERRUPT_HANDLER)(VOID)
Definition: halp.h:32
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 HalpDismissIrq15(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:644
#define EFLAGS_INTERRUPT_MASK
Definition: ketypes.h:126
PPC_QUAL unsigned char __inbyte(const unsigned long Port)
Definition: intrin_ppc.h:539
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: pic.c:156