ReactOS  0.4.15-dev-341-g17c5fb8
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  * FILE: hal/halx86/up/pic.c
5  * PURPOSE: HAL PIC Management and Control Code
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <hal.h>
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 {
73 };
74 
75 /*
76  * These are the level IRQ dismissal functions that get copied in the table
77  * above if the given IRQ is actually level triggered.
78  */
80 {
97 };
98 
99 /* This table contains the static x86 PIC mapping between IRQLs and IRQs */
101 {
102  /*
103  * It Device IRQLs only start at 4 or higher, so these are just software
104  * IRQLs that don't really change anything on the hardware
105  */
106  0b00000000000000000000000000000000, /* IRQL 0 */
107  0b00000000000000000000000000000000, /* IRQL 1 */
108  0b00000000000000000000000000000000, /* IRQL 2 */
109  0b00000000000000000000000000000000, /* IRQL 3 */
110 
111  /*
112  * These next IRQLs are actually useless from the PIC perspective, because
113  * with only 2 PICs, the mask you can send them is only 8 bits each, for 16
114  * bits total, so these IRQLs are masking off a phantom PIC.
115  */
116  0b11111111100000000000000000000000, /* IRQL 4 */
117  0b11111111110000000000000000000000, /* IRQL 5 */
118  0b11111111111000000000000000000000, /* IRQL 6 */
119  0b11111111111100000000000000000000, /* IRQL 7 */
120  0b11111111111110000000000000000000, /* IRQL 8 */
121  0b11111111111111000000000000000000, /* IRQL 9 */
122  0b11111111111111100000000000000000, /* IRQL 10 */
123  0b11111111111111110000000000000000, /* IRQL 11 */
124 
125  /*
126  * Okay, now we're finally starting to mask off IRQs on the slave PIC, from
127  * IRQ15 to IRQ8. This means the higher-level IRQs get less priority in the
128  * IRQL sense.
129  */
130  0b11111111111111111000000000000000, /* IRQL 12 */
131  0b11111111111111111100000000000000, /* IRQL 13 */
132  0b11111111111111111110000000000000, /* IRQL 14 */
133  0b11111111111111111111000000000000, /* IRQL 15 */
134  0b11111111111111111111100000000000, /* IRQL 16 */
135  0b11111111111111111111110000000000, /* IRQL 17 */
136  0b11111111111111111111111000000000, /* IRQL 18 */
137  0b11111111111111111111111000000000, /* IRQL 19 */
138 
139  /*
140  * Now we mask off the IRQs on the master. Notice the 0 "droplet"? You might
141  * have also seen that IRQL 18 and 19 are essentially equal as far as the
142  * PIC is concerned. That bit is actually IRQ8, which happens to be the RTC.
143  * The RTC will keep firing as long as we don't reach PROFILE_LEVEL which
144  * actually kills it. The RTC clock (unlike the system clock) is used by the
145  * profiling APIs in the HAL, so that explains the logic.
146  */
147  0b11111111111111111111111010000000, /* IRQL 20 */
148  0b11111111111111111111111011000000, /* IRQL 21 */
149  0b11111111111111111111111011100000, /* IRQL 22 */
150  0b11111111111111111111111011110000, /* IRQL 23 */
151  0b11111111111111111111111011111000, /* IRQL 24 */
152  0b11111111111111111111111011111000, /* IRQL 25 */
153  0b11111111111111111111111011111010, /* IRQL 26 */
154  0b11111111111111111111111111111010, /* IRQL 27 */
155 
156  /*
157  * IRQL 24 and 25 are actually identical, so IRQL 28 is actually the last
158  * IRQL to modify a bit on the master PIC. It happens to modify the very
159  * last of the IRQs, IRQ0, which corresponds to the system clock interval
160  * timer that keeps track of time (the Windows heartbeat). We only want to
161  * turn this off at a high-enough IRQL, which is why IRQLs 24 and 25 are the
162  * same to give this guy a chance to come up higher. Note that IRQL 28 is
163  * called CLOCK2_LEVEL, which explains the usage we just explained.
164  */
165  0b11111111111111111111111111111011, /* IRQL 28 */
166 
167  /*
168  * We have finished off with the PIC so there's nothing left to mask at the
169  * level of these IRQLs, making them only logical IRQLs on x86 machines.
170  * Note that we have another 0 "droplet" you might've caught since IRQL 26.
171  * In this case, it's the 2nd bit that never gets turned off, which is IRQ2,
172  * the cascade IRQ that we use to bridge the slave PIC with the master PIC.
173  * We never want to turn it off, so no matter the IRQL, it will be set to 0.
174  */
175  0b11111111111111111111111111111011, /* IRQL 29 */
176  0b11111111111111111111111111111011, /* IRQL 30 */
177  0b11111111111111111111111111111011 /* IRQL 31 */
178 };
179 
180 /* This table indicates which IRQs, if pending, can preempt a given IRQL level */
182 {
183  /*
184  * Software IRQLs, at these levels all hardware interrupts can preempt.
185  * Each higher IRQL simply enables which software IRQL can preempt the
186  * current level.
187  */
188  0b11111111111111111111111111111110, /* IRQL 0 */
189  0b11111111111111111111111111111100, /* IRQL 1 */
190  0b11111111111111111111111111111000, /* IRQL 2 */
191 
192  /*
193  * IRQL3 means only hardware IRQLs can now preempt. These last 4 zeros will
194  * then continue throughout the rest of the list, trickling down.
195  */
196  0b11111111111111111111111111110000, /* IRQL 3 */
197 
198  /*
199  * Just like in the previous list, these masks don't really mean anything
200  * since we've only got two PICs with 16 possible IRQs total
201  */
202  0b00000111111111111111111111110000, /* IRQL 4 */
203  0b00000011111111111111111111110000, /* IRQL 5 */
204  0b00000001111111111111111111110000, /* IRQL 6 */
205  0b00000000111111111111111111110000, /* IRQL 7 */
206  0b00000000011111111111111111110000, /* IRQL 8 */
207  0b00000000001111111111111111110000, /* IRQL 9 */
208  0b00000000000111111111111111110000, /* IRQL 10 */
209 
210  /*
211  * Now we start progressivly limiting which slave PIC interrupts have the
212  * right to preempt us at each level.
213  */
214  0b00000000000011111111111111110000, /* IRQL 11 */
215  0b00000000000001111111111111110000, /* IRQL 12 */
216  0b00000000000000111111111111110000, /* IRQL 13 */
217  0b00000000000000011111111111110000, /* IRQL 14 */
218  0b00000000000000001111111111110000, /* IRQL 15 */
219  0b00000000000000000111111111110000, /* IRQL 16 */
220  0b00000000000000000011111111110000, /* IRQL 17 */
221  0b00000000000000000001111111110000, /* IRQL 18 */
222  0b00000000000000000001111111110000, /* IRQL 19 */
223 
224  /*
225  * Also recall from the earlier table that IRQL 18/19 are treated the same
226  * in order to spread the masks better thoughout the 32 IRQLs and to reflect
227  * the fact that some bits will always stay on until much higher IRQLs since
228  * they are system-critical. One such example is the 1 bit that you start to
229  * see trickling down here. This is IRQ8, the RTC timer used for profiling,
230  * so it will always preempt until we reach PROFILE_LEVEL.
231  */
232  0b00000000000000000001011111110000, /* IRQL 20 */
233  0b00000000000000000001001111110000, /* IRQL 21 */
234  0b00000000000000000001000111110000, /* IRQL 22 */
235  0b00000000000000000001000011110000, /* IRQL 23 */
236  0b00000000000000000001000001110000, /* IRQL 24 */
237  0b00000000000000000001000000110000, /* IRQL 25 */
238  0b00000000000000000001000000010000, /* IRQL 26 */
239 
240  /* At this point, only the clock (IRQ0) can still preempt... */
241  0b00000000000000000000000000010000, /* IRQL 27 */
242 
243  /* And any higher than that there's no relation with hardware PICs anymore */
244  0b00000000000000000000000000000000, /* IRQL 28 */
245  0b00000000000000000000000000000000, /* IRQL 29 */
246  0b00000000000000000000000000000000, /* IRQL 30 */
247  0b00000000000000000000000000000000 /* IRQL 31 */
248 };
249 
250 /* Denotes minimum required IRQL before we can process pending SW interrupts */
252 {
253  PASSIVE_LEVEL, /* IRR 0 */
254  PASSIVE_LEVEL, /* IRR 1 */
255  APC_LEVEL, /* IRR 2 */
256  APC_LEVEL, /* IRR 3 */
257  DISPATCH_LEVEL, /* IRR 4 */
258  DISPATCH_LEVEL, /* IRR 5 */
259  DISPATCH_LEVEL, /* IRR 6 */
260  DISPATCH_LEVEL /* IRR 7 */
261 };
262 
263 #if defined(__GNUC__)
264 
265 #define HalpDelayedHardwareInterrupt(x) \
266  VOID __cdecl HalpHardwareInterrupt##x(VOID); \
267  VOID \
268  __cdecl \
269  HalpHardwareInterrupt##x(VOID) \
270  { \
271  asm volatile ("int $%c0\n"::"i"(PRIMARY_VECTOR_BASE + x)); \
272  }
273 
274 #elif defined(_MSC_VER)
275 
276 #define HalpDelayedHardwareInterrupt(x) \
277  VOID __cdecl HalpHardwareInterrupt##x(VOID); \
278  VOID \
279  __cdecl \
280  HalpHardwareInterrupt##x(VOID) \
281  { \
282  __asm \
283  { \
284  int PRIMARY_VECTOR_BASE + x \
285  } \
286  }
287 
288 #else
289 #error Unsupported compiler
290 #endif
291 
292 /* Pending/delayed hardware interrupt handlers */
309 
310 /* Handlers for pending interrupts */
312 {
317  HalpHardwareInterrupt0,
318  HalpHardwareInterrupt1,
319  HalpHardwareInterrupt2,
320  HalpHardwareInterrupt3,
321  HalpHardwareInterrupt4,
322  HalpHardwareInterrupt5,
323  HalpHardwareInterrupt6,
324  HalpHardwareInterrupt7,
325  HalpHardwareInterrupt8,
326  HalpHardwareInterrupt9,
327  HalpHardwareInterrupt10,
328  HalpHardwareInterrupt11,
329  HalpHardwareInterrupt12,
330  HalpHardwareInterrupt13,
331  HalpHardwareInterrupt14,
332  HalpHardwareInterrupt15
333 };
334 
335 /* Handlers for pending software interrupts when we already have a trap frame*/
337 {
341 };
342 
344 
345 /* FUNCTIONS ******************************************************************/
346 
347 VOID
348 NTAPI
350 {
351  ULONG EFlags;
352  EISA_ELCR Elcr;
353  ULONG i, j;
354 
355  /* Save EFlags and disable interrupts */
356  EFlags = __readeflags();
357  _disable();
358 
359  /* Initialize and mask the PIC */
361 
362  /* Read EISA Edge/Level Register for master and slave */
364 
365  /* IRQs 0, 1, 2, 8, and 13 are system-reserved and must be edge */
366  if (!(Elcr.Master.Irq0Level) && !(Elcr.Master.Irq1Level) && !(Elcr.Master.Irq2Level) &&
367  !(Elcr.Slave.Irq8Level) && !(Elcr.Slave.Irq13Level))
368  {
369  /* ELCR is as it's supposed to be, save it */
370  HalpEisaELCR = Elcr.Bits;
371 
372  /* Scan for level interrupts */
373  for (i = 1, j = 0; j < 16; i <<= 1, j++)
374  {
375  if (HalpEisaELCR & i)
376  {
377  /* Switch handler to level */
379 
380  /* Switch dismiss to level */
382  }
383  }
384  }
385 
386  /* Register IRQ 2 */
390  HIGH_LEVEL);
391 
392  /* Restore interrupt state */
394  __writeeflags(EFlags);
395 }
396 
397 UCHAR
398 FASTCALL
400 {
401  return (PRIMARY_VECTOR_BASE + Irq);
402 }
403 
404 UCHAR
405 FASTCALL
407 {
408  return (Vector - PRIMARY_VECTOR_BASE);
409 }
410 
411 KIRQL
412 FASTCALL
414 {
416 }
417 
418 /* IRQL MANAGEMENT ************************************************************/
419 
420 /*
421  * @implemented
422  */
423 KIRQL
424 NTAPI
426 {
427  /* Return the IRQL */
428  return KeGetPcr()->Irql;
429 }
430 
431 /*
432  * @implemented
433  */
434 KIRQL
435 NTAPI
437 {
438  PKPCR Pcr = KeGetPcr();
439  KIRQL CurrentIrql;
440 
441  /* Save and update IRQL */
442  CurrentIrql = Pcr->Irql;
443  Pcr->Irql = DISPATCH_LEVEL;
444 
445 #if DBG
446  /* Validate correct raise */
447  if (CurrentIrql > DISPATCH_LEVEL) KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
448 #endif
449 
450  /* Return the previous value */
451  return CurrentIrql;
452 }
453 
454 /*
455  * @implemented
456  */
457 KIRQL
458 NTAPI
460 {
461  PKPCR Pcr = KeGetPcr();
462  KIRQL CurrentIrql;
463 
464  /* Save and update IRQL */
465  CurrentIrql = Pcr->Irql;
466  Pcr->Irql = SYNCH_LEVEL;
467 
468 #if DBG
469  /* Validate correct raise */
470  if (CurrentIrql > SYNCH_LEVEL)
471  {
472  /* Crash system */
473  KeBugCheckEx(IRQL_NOT_GREATER_OR_EQUAL,
474  CurrentIrql,
475  SYNCH_LEVEL,
476  0,
477  1);
478  }
479 #endif
480 
481  /* Return the previous value */
482  return CurrentIrql;
483 }
484 
485 /*
486  * @implemented
487  */
488 KIRQL
489 FASTCALL
491 {
492  PKPCR Pcr = KeGetPcr();
493  KIRQL CurrentIrql;
494 
495  /* Read current IRQL */
496  CurrentIrql = Pcr->Irql;
497 
498 #if DBG
499  /* Validate correct raise */
500  if (CurrentIrql > NewIrql)
501  {
502  /* Crash system */
503  Pcr->Irql = PASSIVE_LEVEL;
504  KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
505  }
506 #endif
507 
508  /* Set new IRQL */
509  Pcr->Irql = NewIrql;
510 
511  /* Return old IRQL */
512  return CurrentIrql;
513 }
514 
515 
516 /*
517  * @implemented
518  */
519 VOID
520 FASTCALL
522 {
523  ULONG EFlags;
524  ULONG PendingIrql, PendingIrqlMask;
525  PKPCR Pcr = KeGetPcr();
526  PIC_MASK Mask;
527 
528 #if DBG
529  /* Validate correct lower */
530  if (OldIrql > Pcr->Irql)
531  {
532  /* Crash system */
533  Pcr->Irql = HIGH_LEVEL;
534  KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
535  }
536 #endif
537 
538  /* Save EFlags and disable interrupts */
539  EFlags = __readeflags();
540  _disable();
541 
542  /* Set old IRQL */
543  Pcr->Irql = OldIrql;
544 
545  /* Check for pending software interrupts and compare with current IRQL */
546  PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
547  if (PendingIrqlMask)
548  {
549  /* Check if pending IRQL affects hardware state */
550  BitScanReverse(&PendingIrql, PendingIrqlMask);
551  if (PendingIrql > DISPATCH_LEVEL)
552  {
553  /* Set new PIC mask */
554  Mask.Both = Pcr->IDR & 0xFFFF;
555  __outbyte(PIC1_DATA_PORT, Mask.Master);
556  __outbyte(PIC2_DATA_PORT, Mask.Slave);
557 
558  /* Clear IRR bit */
559  Pcr->IRR ^= (1 << PendingIrql);
560  }
561 
562  /* Now handle pending interrupt */
563  SWInterruptHandlerTable[PendingIrql]();
564  }
565 
566  /* Restore interrupt state */
567  __writeeflags(EFlags);
568 }
569 
570 /* SOFTWARE INTERRUPTS ********************************************************/
571 
572 /*
573  * @implemented
574  */
575 VOID
576 FASTCALL
578 {
579  ULONG EFlags;
580  PKPCR Pcr = KeGetPcr();
581  KIRQL PendingIrql;
582 
583  /* Save EFlags and disable interrupts */
584  EFlags = __readeflags();
585  _disable();
586 
587  /* Mask out the requested bit */
588  Pcr->IRR |= (1 << Irql);
589 
590  /* Check for pending software interrupts and compare with current IRQL */
591  PendingIrql = SWInterruptLookUpTable[Pcr->IRR & 3];
592  if (PendingIrql > Pcr->Irql) SWInterruptHandlerTable[PendingIrql]();
593 
594  /* Restore interrupt state */
595  __writeeflags(EFlags);
596 }
597 
598 /*
599  * @implemented
600  */
601 VOID
602 FASTCALL
604 {
605  /* Mask out the requested bit */
606  KeGetPcr()->IRR &= ~(1 << Irql);
607 }
608 
610 FASTCALL
612  IN PKTRAP_FRAME TrapFrame)
613 {
614  ULONG PendingIrql, PendingIrqlMask, PendingIrqMask;
615  PKPCR Pcr = KeGetPcr();
616  PIC_MASK Mask;
617 
618  UNREFERENCED_PARAMETER(TrapFrame);
619 
620  /* Set old IRQL */
621  Pcr->Irql = OldIrql;
622 
623  /* Loop checking for pending interrupts */
624  while (TRUE)
625  {
626  /* Check for pending software interrupts and compare with current IRQL */
627  PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
628  if (!PendingIrqlMask) return NULL;
629 
630  /* Check for in-service delayed interrupt */
631  if (Pcr->IrrActive & 0xFFFFFFF0) return NULL;
632 
633  /* Check if pending IRQL affects hardware state */
634  BitScanReverse(&PendingIrql, PendingIrqlMask);
635  if (PendingIrql > DISPATCH_LEVEL)
636  {
637  /* Set new PIC mask */
638  Mask.Both = Pcr->IDR & 0xFFFF;
639  __outbyte(PIC1_DATA_PORT, Mask.Master);
640  __outbyte(PIC2_DATA_PORT, Mask.Slave);
641 
642  /* Set active bit otherwise, and clear it from IRR */
643  PendingIrqMask = (1 << PendingIrql);
644  Pcr->IrrActive |= PendingIrqMask;
645  Pcr->IRR ^= PendingIrqMask;
646 
647  /* Handle delayed hardware interrupt */
648  SWInterruptHandlerTable[PendingIrql]();
649 
650  /* Handling complete */
651  Pcr->IrrActive ^= PendingIrqMask;
652  }
653  else
654  {
655  /* No need to loop checking for hardware interrupts */
656  return SWInterruptHandlerTable2[PendingIrql];
657  }
658  }
659 
660  return NULL;
661 }
662 
663 /* EDGE INTERRUPT DISMISSAL FUNCTIONS *****************************************/
664 
666 BOOLEAN
668  IN ULONG Irq,
670 {
671  PIC_MASK Mask;
672  KIRQL CurrentIrql;
673  I8259_OCW2 Ocw2;
674  PKPCR Pcr = KeGetPcr();
675 
676  /* First save current IRQL and compare it to the requested one */
677  CurrentIrql = Pcr->Irql;
678 
679  /* Check if this interrupt is really allowed to happen */
680  if (Irql > CurrentIrql)
681  {
682  /* Set the new IRQL and return the current one */
683  Pcr->Irql = Irql;
684  *OldIrql = CurrentIrql;
685 
686  /* Prepare OCW2 for EOI */
687  Ocw2.Bits = 0;
688  Ocw2.EoiMode = SpecificEoi;
689 
690  /* Check which PIC needs the EOI */
691  if (Irq >= 8)
692  {
693  /* Send the EOI for the IRQ */
694  __outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
695 
696  /* Send the EOI for IRQ2 on the master because this was cascaded */
697  __outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | 2);
698  }
699  else
700  {
701  /* Send the EOI for the IRQ */
702  __outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | (Irq &0xFF));
703  }
704 
705  /* Enable interrupts and return success */
706  _enable();
707  return TRUE;
708  }
709 
710  /* Update the IRR so that we deliver this interrupt when the IRQL is proper */
711  Pcr->IRR |= (1 << (Irq + 4));
712 
713  /* Set new PIC mask to real IRQL level, since the optimization is lost now */
714  Mask.Both = (KiI8259MaskTable[CurrentIrql] | Pcr->IDR) & 0xFFFF;
715  __outbyte(PIC1_DATA_PORT, Mask.Master);
716  __outbyte(PIC2_DATA_PORT, Mask.Slave);
717 
718  /* Now lie and say this was spurious */
719  return FALSE;
720 }
721 
722 BOOLEAN
723 NTAPI
725  IN ULONG Irq,
727 {
728  /* Run the inline code */
729  return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
730 }
731 
732 BOOLEAN
733 NTAPI
735  IN ULONG Irq,
737 {
738  I8259_OCW3 Ocw3;
739  I8259_OCW2 Ocw2;
740  I8259_ISR Isr;
741 
742  /* Request the ISR */
743  Ocw3.Bits = 0;
744  Ocw3.Sbo = 1; /* This encodes an OCW3 vs. an OCW2 */
745  Ocw3.ReadRequest = ReadIsr;
747 
748  /* Read the ISR */
750 
751  /* Is IRQ15 really active (this is IR7) */
752  if (Isr.Irq7 == FALSE)
753  {
754  /* It isn't, so we have to EOI IRQ2 because this was cascaded */
755  Ocw2.Bits = 0;
756  Ocw2.EoiMode = SpecificEoi;
757  __outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | 2);
758 
759  /* And now fail since this was spurious */
760  return FALSE;
761  }
762 
763  /* Do normal interrupt dismiss */
764  return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
765 }
766 
767 
768 BOOLEAN
769 NTAPI
771  IN ULONG Irq,
773 {
774  /* Clear the FPU busy latch */
775  __outbyte(0xF0, 0);
776 
777  /* Do normal interrupt dismiss */
778  return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
779 }
780 
781 BOOLEAN
782 NTAPI
784  IN ULONG Irq,
786 {
787  I8259_OCW3 Ocw3;
788  I8259_ISR Isr;
789 
790  /* Request the ISR */
791  Ocw3.Bits = 0;
792  Ocw3.Sbo = 1;
793  Ocw3.ReadRequest = ReadIsr;
795 
796  /* Read the ISR */
798 
799  /* Is IRQ 7 really active? If it isn't, this is spurious so fail */
800  if (Isr.Irq7 == FALSE) return FALSE;
801 
802  /* Do normal interrupt dismiss */
803  return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
804 }
805 
806 /* LEVEL INTERRUPT DISMISSAL FUNCTIONS ****************************************/
807 
809 BOOLEAN
811  IN ULONG Irq,
813 {
814  PIC_MASK Mask;
815  KIRQL CurrentIrql;
816  I8259_OCW2 Ocw2;
817  PKPCR Pcr = KeGetPcr();
818 
819  /* Update the PIC */
820  Mask.Both = (KiI8259MaskTable[Irql] | Pcr->IDR) & 0xFFFF;
821  __outbyte(PIC1_DATA_PORT, Mask.Master);
822  __outbyte(PIC2_DATA_PORT, Mask.Slave);
823 
824  /* Update the IRR so that we clear this interrupt when the IRQL is proper */
825  Pcr->IRR |= (1 << (Irq + 4));
826 
827  /* Save current IRQL */
828  CurrentIrql = Pcr->Irql;
829 
830  /* Prepare OCW2 for EOI */
831  Ocw2.Bits = 0;
832  Ocw2.EoiMode = SpecificEoi;
833 
834  /* Check which PIC needs the EOI */
835  if (Irq >= 8)
836  {
837  /* Send the EOI for the IRQ */
838  __outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
839 
840  /* Send the EOI for IRQ2 on the master because this was cascaded */
841  __outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | 2);
842  }
843  else
844  {
845  /* Send the EOI for the IRQ */
846  __outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | (Irq & 0xFF));
847  }
848 
849  /* Check if this interrupt should be allowed to happen */
850  if (Irql > CurrentIrql)
851  {
852  /* Set the new IRQL and return the current one */
853  Pcr->Irql = Irql;
854  *OldIrql = CurrentIrql;
855 
856  /* Enable interrupts and return success */
857  _enable();
858  return TRUE;
859  }
860 
861  /* Now lie and say this was spurious */
862  return FALSE;
863 }
864 
865 BOOLEAN
866 NTAPI
868  IN ULONG Irq,
870 {
871  /* Run the inline code */
872  return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
873 }
874 
875 BOOLEAN
876 NTAPI
878  IN ULONG Irq,
880 {
881  I8259_OCW3 Ocw3;
882  I8259_OCW2 Ocw2;
883  I8259_ISR Isr;
884 
885  /* Request the ISR */
886  Ocw3.Bits = 0;
887  Ocw3.Sbo = 1; /* This encodes an OCW3 vs. an OCW2 */
888  Ocw3.ReadRequest = ReadIsr;
890 
891  /* Read the ISR */
893 
894  /* Is IRQ15 really active (this is IR7) */
895  if (Isr.Irq7 == FALSE)
896  {
897  /* It isn't, so we have to EOI IRQ2 because this was cascaded */
898  Ocw2.Bits = 0;
899  Ocw2.EoiMode = SpecificEoi;
900  __outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | 2);
901 
902  /* And now fail since this was spurious */
903  return FALSE;
904  }
905 
906  /* Do normal interrupt dismiss */
907  return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
908 }
909 
910 BOOLEAN
911 NTAPI
913  IN ULONG Irq,
915 {
916  /* Clear the FPU busy latch */
917  __outbyte(0xF0, 0);
918 
919  /* Do normal interrupt dismiss */
920  return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
921 }
922 
923 BOOLEAN
924 NTAPI
926  IN ULONG Irq,
928 {
929  I8259_OCW3 Ocw3;
930  I8259_ISR Isr;
931 
932  /* Request the ISR */
933  Ocw3.Bits = 0;
934  Ocw3.Sbo = 1;
935  Ocw3.ReadRequest = ReadIsr;
937 
938  /* Read the ISR */
940 
941  /* Is IRQ 7 really active? If it isn't, this is spurious so fail */
942  if (Isr.Irq7 == FALSE) return FALSE;
943 
944  /* Do normal interrupt dismiss */
945  return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
946 }
947 
949 __cdecl
951 {
952  PKPCR Pcr = KeGetPcr();
953  ULONG PendingIrqlMask, PendingIrql;
954 
955  /* Check for pending software interrupts and compare with current IRQL */
956  PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[Pcr->Irql];
957  if (PendingIrqlMask)
958  {
959  /* Check for in-service delayed interrupt */
960  if (Pcr->IrrActive & 0xFFFFFFF0) return NULL;
961 
962  /* Check if pending IRQL affects hardware state */
963  BitScanReverse(&PendingIrql, PendingIrqlMask);
964 
965  /* Clear IRR bit */
966  Pcr->IRR ^= (1 << PendingIrql);
967 
968  /* Now handle pending interrupt */
969  return SWInterruptHandlerTable[PendingIrql];
970  }
971 
972  return NULL;
973 }
974 
975 /* SYSTEM INTERRUPTS **********************************************************/
976 
977 /*
978  * @implemented
979  */
980 BOOLEAN
981 NTAPI
983  IN KIRQL Irql,
985 {
986  ULONG Irq;
987  PKPCR Pcr = KeGetPcr();
988  PIC_MASK PicMask;
989 
990  /* Validate the IRQ */
991  Irq = Vector - PRIMARY_VECTOR_BASE;
992  if (Irq >= CLOCK2_LEVEL) return FALSE;
993 
994  /* Check for level interrupt */
996  {
997  /* Switch handler to level */
999 
1000  /* Switch dismiss to level */
1002  }
1003 
1004  /* Disable interrupts */
1005  _disable();
1006 
1007  /* Update software IDR */
1008  Pcr->IDR &= ~(1 << Irq);
1009 
1010  /* Set new PIC mask */
1011  PicMask.Both = (KiI8259MaskTable[Pcr->Irql] | Pcr->IDR) & 0xFFFF;
1012  __outbyte(PIC1_DATA_PORT, PicMask.Master);
1013  __outbyte(PIC2_DATA_PORT, PicMask.Slave);
1014 
1015  /* Enable interrupts and exit */
1016  _enable();
1017  return TRUE;
1018 }
1019 
1020 /*
1021  * @implemented
1022  */
1023 VOID
1024 NTAPI
1026  IN KIRQL Irql)
1027 {
1028  ULONG IrqMask;
1029  PIC_MASK PicMask;
1030 
1031  /* Compute new combined IRQ mask */
1032  IrqMask = 1 << (Vector - PRIMARY_VECTOR_BASE);
1033 
1034  /* Disable interrupts */
1035  _disable();
1036 
1037  /* Update software IDR */
1038  KeGetPcr()->IDR |= IrqMask;
1039 
1040  /* Read current interrupt mask */
1041  PicMask.Master = __inbyte(PIC1_DATA_PORT);
1042  PicMask.Slave = __inbyte(PIC2_DATA_PORT);
1043 
1044  /* Add the new disabled interrupt */
1045  PicMask.Both |= IrqMask;
1046 
1047  /* Write new interrupt mask */
1048  __outbyte(PIC1_DATA_PORT, PicMask.Master);
1049  __outbyte(PIC2_DATA_PORT, PicMask.Slave);
1050 
1051  /* Bring interrupts back */
1052  _enable();
1053 }
1054 
1055 /*
1056  * @implemented
1057  */
1058 BOOLEAN
1059 NTAPI
1061  IN ULONG Vector,
1062  OUT PKIRQL OldIrql)
1063 {
1064  ULONG Irq;
1065 
1066  /* Get the IRQ and call the proper routine to handle it */
1067  Irq = Vector - PRIMARY_VECTOR_BASE;
1068  return HalpSpecialDismissTable[Irq](Irql, Irq, OldIrql);
1069 }
1070 
1071 /*
1072  * @implemented
1073  */
1075 FASTCALL
1077  IN PKTRAP_FRAME TrapFrame)
1078 {
1079  ULONG PendingIrql, PendingIrqlMask, PendingIrqMask;
1080  PKPCR Pcr = KeGetPcr();
1081  PIC_MASK Mask;
1082 
1083  /* Set old IRQL */
1084  Pcr->Irql = OldIrql;
1085 
1086  /* Check for pending software interrupts and compare with current IRQL */
1087  PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
1088  if (PendingIrqlMask)
1089  {
1090  /* Check for in-service delayed interrupt */
1091  if (Pcr->IrrActive & 0xFFFFFFF0) return NULL;
1092 
1093  /* Loop checking for pending interrupts */
1094  while (TRUE)
1095  {
1096  /* Check if pending IRQL affects hardware state */
1097  BitScanReverse(&PendingIrql, PendingIrqlMask);
1098  if (PendingIrql > DISPATCH_LEVEL)
1099  {
1100  /* Set new PIC mask */
1101  Mask.Both = Pcr->IDR & 0xFFFF;
1102  __outbyte(PIC1_DATA_PORT, Mask.Master);
1103  __outbyte(PIC2_DATA_PORT, Mask.Slave);
1104 
1105  /* Now check if this specific interrupt is already in-service */
1106  PendingIrqMask = (1 << PendingIrql);
1107  if (Pcr->IrrActive & PendingIrqMask) return NULL;
1108 
1109  /* Set active bit otherwise, and clear it from IRR */
1110  Pcr->IrrActive |= PendingIrqMask;
1111  Pcr->IRR ^= PendingIrqMask;
1112 
1113  /* Handle delayed hardware interrupt */
1114  SWInterruptHandlerTable[PendingIrql]();
1115 
1116  /* Handling complete */
1117  Pcr->IrrActive ^= PendingIrqMask;
1118 
1119  /* Check if there's still interrupts pending */
1120  PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[Pcr->Irql];
1121  if (!PendingIrqlMask) break;
1122  }
1123  else
1124  {
1125  /* Now handle pending software interrupt */
1126  return SWInterruptHandlerTable2[PendingIrql];
1127  }
1128  }
1129  }
1130 
1131  return NULL;
1132 }
1133 
1134 /* SOFTWARE INTERRUPT TRAPS ***************************************************/
1135 
1138 VOID
1140 {
1141  KIRQL CurrentIrql;
1142  PKPCR Pcr = KeGetPcr();
1143 
1144  /* Save the current IRQL and update it */
1145  CurrentIrql = Pcr->Irql;
1146  Pcr->Irql = APC_LEVEL;
1147 
1148  /* Remove DPC from IRR */
1149  Pcr->IRR &= ~(1 << APC_LEVEL);
1150 
1151  /* Enable interrupts and call the kernel's APC interrupt handler */
1152  _enable();
1153  KiDeliverApc(((KiUserTrap(TrapFrame)) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) ?
1154  UserMode : KernelMode,
1155  NULL,
1156  TrapFrame);
1157 
1158  /* Disable interrupts and end the interrupt */
1159  _disable();
1160  HalpEndSoftwareInterrupt(CurrentIrql, TrapFrame);
1161 
1162  /* Exit the interrupt */
1163  KiEoiHelper(TrapFrame);
1164 }
1165 
1167 VOID
1168 FASTCALL
1170 {
1171  /* Do the work */
1172  _HalpApcInterruptHandler(TrapFrame);
1173 }
1174 
1176 VOID
1177 FASTCALL
1179 {
1180  /* Set up a fake INT Stack */
1181  TrapFrame->EFlags = __readeflags();
1182  TrapFrame->SegCs = KGDT_R0_CODE;
1183  TrapFrame->Eip = TrapFrame->Eax;
1184 
1185  /* Build the trap frame */
1186  KiEnterInterruptTrap(TrapFrame);
1187 
1188  /* Do the work */
1189  _HalpApcInterruptHandler(TrapFrame);
1190 }
1191 
1193 KIRQL
1195 {
1196  KIRQL CurrentIrql;
1197  PKPCR Pcr = KeGetPcr();
1198 
1199  /* Save the current IRQL and update it */
1200  CurrentIrql = Pcr->Irql;
1201  Pcr->Irql = DISPATCH_LEVEL;
1202 
1203  /* Remove DPC from IRR */
1204  Pcr->IRR &= ~(1 << DISPATCH_LEVEL);
1205 
1206  /* Enable interrupts and call the kernel's DPC interrupt handler */
1207  _enable();
1209  _disable();
1210 
1211  /* Return IRQL */
1212  return CurrentIrql;
1213 }
1214 
1216 VOID
1217 FASTCALL
1219 {
1220  KIRQL CurrentIrql;
1221 
1222  /* Do the work */
1223  CurrentIrql = _HalpDispatchInterruptHandler();
1224 
1225  /* End the interrupt */
1226  HalpEndSoftwareInterrupt(CurrentIrql, TrapFrame);
1227 
1228  /* Exit the interrupt */
1229  KiEoiHelper(TrapFrame);
1230 }
1231 
1233 __cdecl
1235 {
1236  ULONG PendingIrqlMask, PendingIrql;
1237  KIRQL OldIrql;
1238  PIC_MASK Mask;
1239  PKPCR Pcr = KeGetPcr();
1240 
1241  /* Do the work */
1243 
1244  /* Restore IRQL */
1245  Pcr->Irql = OldIrql;
1246 
1247  /* Check for pending software interrupts and compare with current IRQL */
1248  PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
1249  if (PendingIrqlMask)
1250  {
1251  /* Check if pending IRQL affects hardware state */
1252  BitScanReverse(&PendingIrql, PendingIrqlMask);
1253  if (PendingIrql > DISPATCH_LEVEL)
1254  {
1255  /* Set new PIC mask */
1256  Mask.Both = Pcr->IDR & 0xFFFF;
1257  __outbyte(PIC1_DATA_PORT, Mask.Master);
1258  __outbyte(PIC2_DATA_PORT, Mask.Slave);
1259 
1260  /* Clear IRR bit */
1261  Pcr->IRR ^= (1 << PendingIrql);
1262  }
1263 
1264  /* Now handle pending interrupt */
1265  return SWInterruptHandlerTable[PendingIrql];
1266  }
1267 
1268  return NULL;
1269 }
1270 
1271 #else
1272 
1273 KIRQL
1274 NTAPI
1276 {
1277  return PASSIVE_LEVEL;
1278 }
1279 
1280 VOID
1281 FASTCALL
1282 KfLowerIrql(
1283  IN KIRQL OldIrql)
1284 {
1285 }
1286 
1287 KIRQL
1288 FASTCALL
1289 KfRaiseIrql(
1290  IN KIRQL NewIrql)
1291 {
1292  return NewIrql;
1293 }
1294 
1295 #endif
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:343
#define TRUE
Definition: types.h:120
_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:783
USHORT Bits
Definition: halhw.h:362
#define __cdecl
Definition: accygwin.h:79
#define EISA_ELCR_MASTER
Definition: halhw.h:332
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
DECLSPEC_NORETURN VOID FASTCALL HalpDispatchInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:1218
UCHAR EoiMode
Definition: halhw.h:286
DECLSPEC_NORETURN VOID FASTCALL HalpApcInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:1169
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:79
#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:950
BOOLEAN NTAPI HalBeginSystemInterrupt(IN KIRQL Irql, IN ULONG Vector, OUT PKIRQL OldIrql)
Definition: pic.c:321
ULONG FindHigherIrqlMask[32]
Definition: pic.c:181
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:1178
#define KeGetPcr()
Definition: ke.h:25
FORCEINLINE BOOLEAN _HalpDismissIrqLevel(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:810
#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:724
FORCEINLINE BOOLEAN _HalpDismissIrqGeneric(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:667
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:1555
UCHAR ReadRequest
Definition: halhw.h:295
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
long LONG
Definition: pedump.c:60
PHAL_SW_INTERRUPT_HANDLER SWInterruptHandlerTable[20]
Definition: pic.c:311
BOOLEAN NTAPI HalpDismissIrq15Level(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:877
VOID __cdecl HalpDispatchInterrupt(VOID)
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts)
Definition: pic.c:349
PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY FASTCALL HalpEndSoftwareInterrupt2(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:611
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:336
#define FORCEINLINE
Definition: ntbasedef.h:221
KIRQL FASTCALL HalpVectorToIrql(UCHAR Vector)
Definition: pic.c:413
ULONG IrrActive
Definition: ke.h:49
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1428
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:297
#define EISA_ELCR_SLAVE
Definition: halhw.h:333
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:251
FORCEINLINE DECLSPEC_NORETURN VOID _HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:1139
struct _EISA_ELCR::@1505::@1507 Master
Definition: irql.c:21
BOOLEAN NTAPI HalpDismissIrq13(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:770
#define CLOCK2_LEVEL
Definition: env_spec_w32.h:700
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:1550
#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:867
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
UCHAR Bits
Definition: halhw.h:288
HalpDelayedHardwareInterrupt(0)
Definition: halhw.h:201
#define SYNCH_LEVEL
Definition: env_spec_w32.h:704
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
struct _EISA_ELCR::@1505::@1508 Slave
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
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:271
FORCEINLINE KIRQL _HalpDispatchInterruptHandler(VOID)
Definition: pic.c:1194
UCHAR Bits
Definition: halhw.h:302
#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:369
PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY FASTCALL HalEndSystemInterrupt2(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:1076
PHAL_SW_INTERRUPT_HANDLER __cdecl HalpDispatchInterrupt2(VOID)
Definition: pic.c:1234
#define PROFILE_LEVEL
Definition: env_spec_w32.h:698
UCHAR FASTCALL HalpVectorToIrq(UCHAR Vector)
Definition: pic.c:406
ULONG KiI8259MaskTable[32]
Definition: pic.c:100
#define PIC1_DATA_PORT
Definition: halhw.h:151
BOOLEAN NTAPI HalpDismissIrq13Level(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql)
Definition: pic.c:912
#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:399
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:925
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:107
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:734
#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