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