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