Reactos
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
19ULONG 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
55UCHAR 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
92VOID
93HalpInitializeInterrupts(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 */
107ULONG
108HalGetInterruptSource(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 */
120KIRQL
121NTAPI
122KeGetCurrentIrql(VOID)
123{
124 /* Return the IRQL */
125 return KeGetPcr()->Irql;
126}
127
128/*
129 * @implemented
130 */
131KIRQL
132NTAPI
133KeRaiseIrqlToDpcLevel(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 */
154KIRQL
155NTAPI
156KeRaiseIrqlToSynchLevel(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 */
185KIRQL
186FASTCALL
187KfRaiseIrql(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 */
230VOID
231FASTCALL
232KfLowerIrql(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 */
269VOID
270FASTCALL
271HalRequestSoftwareInterrupt(IN KIRQL Irql)
272{
273 /* Force a software interrupt */
274 WRITE_REGISTER_ULONG(VIC_SOFT_INT, 1 << Irql);
275}
276
277/*
278 * @implemented
279 */
280VOID
281FASTCALL
282HalClearSoftwareInterrupt(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 */
293BOOLEAN
294NTAPI
295HalEnableSystemInterrupt(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 */
307VOID
308NTAPI
309HalDisableSystemInterrupt(IN ULONG Vector,
310 IN KIRQL Irql)
311{
312 UNIMPLEMENTED;
313 while (TRUE);
314}
315
316/*
317 * @implemented
318 */
319BOOLEAN
320NTAPI
321HalBeginSystemInterrupt(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 */
333VOID
334NTAPI
335HalEndSystemInterrupt(IN KIRQL OldIrql,
336 IN PKTRAP_FRAME TrapFrame)
337{
338 UNIMPLEMENTED;
339 while (TRUE);
340}
341
342/* EOF */