xref: /reactos/hal/halx86/pic/irql.c (revision bbabe248)
1 /*
2  * PROJECT:         ReactOS Hardware Abstraction Layer
3  * LICENSE:         BSD - See COPYING.ARM in the top level directory
4  * PURPOSE:         IRQL mapping
5  * PROGRAMMERS:     ReactOS Portable Systems Group
6  */
7 
8 /* INCLUDES *******************************************************************/
9 
10 #include <hal.h>
11 
12 /* GLOBALS ********************************************************************/
13 
14 /* This table contains the static x86 PIC mapping between IRQLs and IRQs */
15 ULONG KiI8259MaskTable[32] =
16 {
17     /*
18      * It Device IRQLs only start at 4 or higher, so these are just software
19      * IRQLs that don't really change anything on the hardware
20      */
21     0b00000000000000000000000000000000, /* IRQL 0 */
22     0b00000000000000000000000000000000, /* IRQL 1 */
23     0b00000000000000000000000000000000, /* IRQL 2 */
24     0b00000000000000000000000000000000, /* IRQL 3 */
25 
26     /*
27      * These next IRQLs are actually useless from the PIC perspective, because
28      * with only 2 PICs, the mask you can send them is only 8 bits each, for 16
29      * bits total, so these IRQLs are masking off a phantom PIC.
30      */
31     0b11111111100000000000000000000000, /* IRQL 4 */
32     0b11111111110000000000000000000000, /* IRQL 5 */
33     0b11111111111000000000000000000000, /* IRQL 6 */
34     0b11111111111100000000000000000000, /* IRQL 7 */
35     0b11111111111110000000000000000000, /* IRQL 8 */
36     0b11111111111111000000000000000000, /* IRQL 9 */
37     0b11111111111111100000000000000000, /* IRQL 10 */
38     0b11111111111111110000000000000000, /* IRQL 11 */
39 
40     /*
41      * Okay, now we're finally starting to mask off IRQs on the slave PIC, from
42      * IRQ15 to IRQ8. This means the higher-level IRQs get less priority in the
43      * IRQL sense.
44      */
45     0b11111111111111111000000000000000, /* IRQL 12 */
46     0b11111111111111111100000000000000, /* IRQL 13 */
47     0b11111111111111111110000000000000, /* IRQL 14 */
48     0b11111111111111111111000000000000, /* IRQL 15 */
49     0b11111111111111111111100000000000, /* IRQL 16 */
50     0b11111111111111111111110000000000, /* IRQL 17 */
51     0b11111111111111111111111000000000, /* IRQL 18 */
52     0b11111111111111111111111000000000, /* IRQL 19 */
53 
54     /*
55      * Now we mask off the IRQs on the master. Notice the 0 "droplet"? You might
56      * have also seen that IRQL 18 and 19 are essentially equal as far as the
57      * PIC is concerned. That bit is actually IRQ8, which happens to be the RTC.
58      * The RTC will keep firing as long as we don't reach PROFILE_LEVEL which
59      * actually kills it. The RTC clock (unlike the system clock) is used by the
60      * profiling APIs in the HAL, so that explains the logic.
61      */
62     0b11111111111111111111111010000000, /* IRQL 20 */
63     0b11111111111111111111111011000000, /* IRQL 21 */
64     0b11111111111111111111111011100000, /* IRQL 22 */
65     0b11111111111111111111111011110000, /* IRQL 23 */
66     0b11111111111111111111111011111000, /* IRQL 24 */
67     0b11111111111111111111111011111000, /* IRQL 25 */
68     0b11111111111111111111111011111010, /* IRQL 26 */
69     0b11111111111111111111111111111010, /* IRQL 27 */
70 
71     /*
72      * IRQL 24 and 25 are actually identical, so IRQL 28 is actually the last
73      * IRQL to modify a bit on the master PIC. It happens to modify the very
74      * last of the IRQs, IRQ0, which corresponds to the system clock interval
75      * timer that keeps track of time (the Windows heartbeat). We only want to
76      * turn this off at a high-enough IRQL, which is why IRQLs 24 and 25 are the
77      * same to give this guy a chance to come up higher. Note that IRQL 28 is
78      * called CLOCK2_LEVEL, which explains the usage we just explained.
79      */
80     0b11111111111111111111111111111011, /* IRQL 28 */
81 
82     /*
83      * We have finished off with the PIC so there's nothing left to mask at the
84      * level of these IRQLs, making them only logical IRQLs on x86 machines.
85      * Note that we have another 0 "droplet" you might've caught since IRQL 26.
86      * In this case, it's the 2nd bit that never gets turned off, which is IRQ2,
87      * the cascade IRQ that we use to bridge the slave PIC with the master PIC.
88      * We never want to turn it off, so no matter the IRQL, it will be set to 0.
89      */
90     0b11111111111111111111111111111011, /* IRQL 29 */
91     0b11111111111111111111111111111011, /* IRQL 30 */
92     0b11111111111111111111111111111011  /* IRQL 31 */
93 };
94 
95 /* This table indicates which IRQs, if pending, can preempt a given IRQL level */
96 ULONG FindHigherIrqlMask[32] =
97 {
98     /*
99      * Software IRQLs, at these levels all hardware interrupts can preempt.
100      * Each higher IRQL simply enables which software IRQL can preempt the
101      * current level.
102      */
103     0b11111111111111111111111111111110, /* IRQL 0 */
104     0b11111111111111111111111111111100, /* IRQL 1 */
105     0b11111111111111111111111111111000, /* IRQL 2 */
106 
107     /*
108      * IRQL3 means only hardware IRQLs can now preempt. These last 4 zeros will
109      * then continue throughout the rest of the list, trickling down.
110      */
111     0b11111111111111111111111111110000, /* IRQL 3 */
112 
113     /*
114      * Just like in the previous list, these masks don't really mean anything
115      * since we've only got two PICs with 16 possible IRQs total
116      */
117     0b00000111111111111111111111110000, /* IRQL 4 */
118     0b00000011111111111111111111110000, /* IRQL 5 */
119     0b00000001111111111111111111110000, /* IRQL 6 */
120     0b00000000111111111111111111110000, /* IRQL 7 */
121     0b00000000011111111111111111110000, /* IRQL 8 */
122     0b00000000001111111111111111110000, /* IRQL 9 */
123     0b00000000000111111111111111110000, /* IRQL 10 */
124 
125     /*
126      * Now we start progressivly limiting which slave PIC interrupts have the
127      * right to preempt us at each level.
128      */
129     0b00000000000011111111111111110000, /* IRQL 11 */
130     0b00000000000001111111111111110000, /* IRQL 12 */
131     0b00000000000000111111111111110000, /* IRQL 13 */
132     0b00000000000000011111111111110000, /* IRQL 14 */
133     0b00000000000000001111111111110000, /* IRQL 15 */
134     0b00000000000000000111111111110000, /* IRQL 16 */
135     0b00000000000000000011111111110000, /* IRQL 17 */
136     0b00000000000000000001111111110000, /* IRQL 18 */
137     0b00000000000000000001111111110000, /* IRQL 19 */
138 
139     /*
140      * Also recall from the earlier table that IRQL 18/19 are treated the same
141      * in order to spread the masks better thoughout the 32 IRQLs and to reflect
142      * the fact that some bits will always stay on until much higher IRQLs since
143      * they are system-critical. One such example is the 1 bit that you start to
144      * see trickling down here. This is IRQ8, the RTC timer used for profiling,
145      * so it will always preempt until we reach PROFILE_LEVEL.
146      */
147     0b00000000000000000001011111110000, /* IRQL 20 */
148     0b00000000000000000001001111110000, /* IRQL 21 */
149     0b00000000000000000001000111110000, /* IRQL 22 */
150     0b00000000000000000001000011110000, /* IRQL 23 */
151     0b00000000000000000001000001110000, /* IRQL 24 */
152     0b00000000000000000001000000110000, /* IRQL 25 */
153     0b00000000000000000001000000010000, /* IRQL 26 */
154 
155     /* At this point, only the clock (IRQ0) can still preempt... */
156     0b00000000000000000000000000010000, /* IRQL 27 */
157 
158     /* And any higher than that there's no relation with hardware PICs anymore */
159     0b00000000000000000000000000000000, /* IRQL 28 */
160     0b00000000000000000000000000000000, /* IRQL 29 */
161     0b00000000000000000000000000000000, /* IRQL 30 */
162     0b00000000000000000000000000000000  /* IRQL 31 */
163 };
164