xref: /reactos/hal/halarm/generic/pic.c (revision 1734f297)
1 /*
2  * PROJECT:         ReactOS HAL
3  * LICENSE:         BSD - See COPYING.ARM in the top level directory
4  * FILE:            hal/halarm/generic/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 #undef KeGetCurrentIrql
16 
17 /* GLOBALS ********************************************************************/
18 
19 ULONG HalpIrqlTable[HIGH_LEVEL + 1] =
20 {
21     0xFFFFFFFF, // IRQL 0 PASSIVE_LEVEL
22     0xFFFFFFFD, // IRQL 1 APC_LEVEL
23     0xFFFFFFF9, // IRQL 2 DISPATCH_LEVEL
24     0xFFFFFFD9, // IRQL 3
25     0xFFFFFF99, // IRQL 4
26     0xFFFFFF19, // IRQL 5
27     0xFFFFFE19, // IRQL 6
28     0xFFFFFC19, // IRQL 7
29     0xFFFFF819, // IRQL 8
30     0xFFFFF019, // IRQL 9
31     0xFFFFE019, // IRQL 10
32     0xFFFFC019, // IRQL 11
33     0xFFFF8019, // IRQL 12
34     0xFFFF0019, // IRQL 13
35     0xFFFE0019, // IRQL 14
36     0xFFFC0019, // IRQL 15
37     0xFFF80019, // IRQL 16
38     0xFFF00019, // IRQL 17
39     0xFFE00019, // IRQL 18
40     0xFFC00019, // IRQL 19
41     0xFF800019, // IRQL 20
42     0xFF000019, // IRQL 21
43     0xFE000019, // IRQL 22
44     0xFC000019, // IRQL 23
45     0xF0000019, // IRQL 24
46     0x80000019, // IRQL 25
47     0x19,       // IRQL 26
48     0x18,       // IRQL 27 PROFILE_LEVEL
49     0x10,       // IRQL 28 CLOCK2_LEVEL
50     0x00,       // IRQL 29 IPI_LEVEL
51     0x00,       // IRQL 30 POWER_LEVEL
52     0x00,       // IRQL 31 HIGH_LEVEL
53 };
54 
55 UCHAR HalpMaskTable[HIGH_LEVEL + 1] =
56 {
57     PROFILE_LEVEL, // INT 0 WATCHDOG
58     APC_LEVEL,     // INT 1 SOFTWARE INTERRUPT
59     DISPATCH_LEVEL,// INT 2 COMM RX
60     IPI_LEVEL,     // INT 3 COMM TX
61     CLOCK2_LEVEL,  // INT 4 TIMER 0
62     3,
63     4,
64     5,
65     6,
66     7,
67     8,
68     9,
69     10,
70     11,
71     12,
72     13,
73     14,
74     15,
75     16,
76     17,
77     18,
78     19,
79     20,
80     21,
81     22,
82     23,
83     24,
84     25,
85     26,
86     26,
87     26
88 };
89 
90 /* FUNCTIONS ******************************************************************/
91 
92 VOID
93 HalpInitializeInterrupts(VOID)
94 {
95     PKPCR Pcr = KeGetPcr();
96 
97     /* Fill out the IRQL mappings */
98     RtlCopyMemory(Pcr->IrqlTable, HalpIrqlTable, sizeof(Pcr->IrqlTable));
99     RtlCopyMemory(Pcr->IrqlMask, HalpMaskTable, sizeof(Pcr->IrqlMask));
100 }
101 
102 /* IRQL MANAGEMENT ************************************************************/
103 
104 /*
105  * @implemented
106  */
107 ULONG
108 HalGetInterruptSource(VOID)
109 {
110     ULONG InterruptStatus;
111 
112     /* Get the interrupt status, and return the highest bit set */
113     InterruptStatus = READ_REGISTER_ULONG(VIC_INT_STATUS);
114     return 31 - _clz(InterruptStatus);
115 }
116 
117 /*
118  * @implemented
119  */
120 KIRQL
121 NTAPI
122 KeGetCurrentIrql(VOID)
123 {
124     /* Return the IRQL */
125     return KeGetPcr()->Irql;
126 }
127 
128 /*
129  * @implemented
130  */
131 KIRQL
132 NTAPI
133 KeRaiseIrqlToDpcLevel(VOID)
134 {
135     PKPCR Pcr = KeGetPcr();
136     KIRQL CurrentIrql;
137 
138     /* Save and update IRQL */
139     CurrentIrql = Pcr->Irql;
140     Pcr->Irql = DISPATCH_LEVEL;
141 
142 #ifdef IRQL_DEBUG
143     /* Validate correct raise */
144     if (CurrentIrql > DISPATCH_LEVEL) KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
145 #endif
146 
147     /* Return the previous value */
148     return CurrentIrql;
149 }
150 
151 /*
152  * @implemented
153  */
154 KIRQL
155 NTAPI
156 KeRaiseIrqlToSynchLevel(VOID)
157 {
158     PKPCR Pcr = KeGetPcr();
159     KIRQL CurrentIrql;
160 
161     /* Save and update IRQL */
162     CurrentIrql = Pcr->Irql;
163     Pcr->Irql = SYNCH_LEVEL;
164 
165 #ifdef IRQL_DEBUG
166     /* Validate correct raise */
167     if (CurrentIrql > SYNCH_LEVEL)
168     {
169         /* Crash system */
170         KeBugCheckEx(IRQL_NOT_GREATER_OR_EQUAL,
171                      CurrentIrql,
172                      SYNCH_LEVEL,
173                      0,
174                      1);
175     }
176 #endif
177 
178     /* Return the previous value */
179     return CurrentIrql;
180 }
181 
182 /*
183  * @implemented
184  */
185 KIRQL
186 FASTCALL
187 KfRaiseIrql(IN KIRQL NewIrql)
188 {
189     ARM_STATUS_REGISTER Flags;
190     PKPCR Pcr = KeGetPcr();
191     KIRQL CurrentIrql;
192     ULONG InterruptMask;
193 
194     /* Disable interrupts */
195     Flags = KeArmStatusRegisterGet();
196     _disable();
197 
198     /* Read current IRQL */
199     CurrentIrql = Pcr->Irql;
200 
201 #ifdef IRQL_DEBUG
202     /* Validate correct raise */
203     if (CurrentIrql > NewIrql)
204     {
205         /* Crash system */
206         Pcr->Irql = PASSIVE_LEVEL;
207         KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
208     }
209 #endif
210     /* Clear interrupts associated to the old IRQL */
211     WRITE_REGISTER_ULONG(VIC_INT_CLEAR, 0xFFFFFFFF);
212 
213     /* Set the new interrupt mask */
214     InterruptMask = Pcr->IrqlTable[NewIrql];
215     WRITE_REGISTER_ULONG(VIC_INT_ENABLE, InterruptMask);
216 
217     /* Set new IRQL */
218     Pcr->Irql = NewIrql;
219 
220     /* Restore interrupt state */
221     if (!Flags.IrqDisable) _enable();
222 
223     /* Return old IRQL */
224     return CurrentIrql;
225 }
226 
227 /*
228  * @implemented
229  */
230 VOID
231 FASTCALL
232 KfLowerIrql(IN KIRQL NewIrql)
233 {
234     ARM_STATUS_REGISTER Flags;
235     PKPCR Pcr = KeGetPcr();
236     ULONG InterruptMask;
237 
238     /* Disableinterrupts */
239     Flags = KeArmStatusRegisterGet();
240     _disable();
241 
242 #ifdef IRQL_DEBUG
243     /* Validate correct lower */
244     if (OldIrql > Pcr->Irql)
245     {
246         /* Crash system */
247         Pcr->Irql = HIGH_LEVEL;
248         KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
249     }
250 #endif
251 
252     /* Clear interrupts associated to the old IRQL */
253     WRITE_REGISTER_ULONG(VIC_INT_CLEAR, 0xFFFFFFFF);
254 
255     /* Set the new interrupt mask */
256     InterruptMask = Pcr->IrqlTable[NewIrql];
257     WRITE_REGISTER_ULONG(VIC_INT_ENABLE, InterruptMask);
258 
259     /* Save the new IRQL and restore interrupt state */
260     Pcr->Irql = NewIrql;
261     if (!Flags.IrqDisable) _enable();
262 }
263 
264 /* SOFTWARE INTERRUPTS ********************************************************/
265 
266 /*
267  * @implemented
268  */
269 VOID
270 FASTCALL
271 HalRequestSoftwareInterrupt(IN KIRQL Irql)
272 {
273     /* Force a software interrupt */
274     WRITE_REGISTER_ULONG(VIC_SOFT_INT, 1 << Irql);
275 }
276 
277 /*
278  * @implemented
279  */
280 VOID
281 FASTCALL
282 HalClearSoftwareInterrupt(IN KIRQL Irql)
283 {
284     /* Clear software interrupt */
285     WRITE_REGISTER_ULONG(VIC_SOFT_INT_CLEAR, 1 << Irql);
286 }
287 
288 /* SYSTEM INTERRUPTS **********************************************************/
289 
290 /*
291  * @implemented
292  */
293 BOOLEAN
294 NTAPI
295 HalEnableSystemInterrupt(IN ULONG Vector,
296                          IN KIRQL Irql,
297                          IN KINTERRUPT_MODE InterruptMode)
298 {
299     UNIMPLEMENTED;
300     while (TRUE);
301     return FALSE;
302 }
303 
304 /*
305  * @implemented
306  */
307 VOID
308 NTAPI
309 HalDisableSystemInterrupt(IN ULONG Vector,
310                           IN KIRQL Irql)
311 {
312     UNIMPLEMENTED;
313     while (TRUE);
314 }
315 
316 /*
317  * @implemented
318  */
319 BOOLEAN
320 NTAPI
321 HalBeginSystemInterrupt(IN KIRQL Irql,
322                         IN ULONG Vector,
323                         OUT PKIRQL OldIrql)
324 {
325     UNIMPLEMENTED;
326     while (TRUE);
327     return FALSE;
328 }
329 
330 /*
331  * @implemented
332  */
333 VOID
334 NTAPI
335 HalEndSystemInterrupt(IN KIRQL OldIrql,
336                       IN PKTRAP_FRAME TrapFrame)
337 {
338     UNIMPLEMENTED;
339     while (TRUE);
340 }
341 
342 /* EOF */
343