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
HalpInitializeInterrupts(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
HalGetInterruptSource(VOID)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
KeGetCurrentIrql(VOID)122 KeGetCurrentIrql(VOID)
123 {
124 /* Return the IRQL */
125 return KeGetPcr()->Irql;
126 }
127
128 /*
129 * @implemented
130 */
131 KIRQL
132 NTAPI
KeRaiseIrqlToDpcLevel(VOID)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
KeRaiseIrqlToSynchLevel(VOID)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
KfRaiseIrql(IN KIRQL NewIrql)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
KfLowerIrql(IN KIRQL NewIrql)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
HalRequestSoftwareInterrupt(IN KIRQL Irql)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
HalClearSoftwareInterrupt(IN KIRQL Irql)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
HalEnableSystemInterrupt(IN ULONG Vector,IN KIRQL Irql,IN KINTERRUPT_MODE InterruptMode)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
HalDisableSystemInterrupt(IN ULONG Vector,IN KIRQL Irql)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
HalBeginSystemInterrupt(IN KIRQL Irql,IN ULONG Vector,OUT PKIRQL OldIrql)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
HalEndSystemInterrupt(IN KIRQL OldIrql,IN PKTRAP_FRAME TrapFrame)335 HalEndSystemInterrupt(IN KIRQL OldIrql,
336 IN PKTRAP_FRAME TrapFrame)
337 {
338 UNIMPLEMENTED;
339 while (TRUE);
340 }
341
342 /* EOF */
343