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
9 /* INCLUDES *******************************************************************/
15 #undef KeGetCurrentIrql
17 /* GLOBALS ********************************************************************/
19 ULONG HalpIrqlTable
[HIGH_LEVEL
+ 1] =
21 0xFFFFFFFF, // IRQL 0 PASSIVE_LEVEL
22 0xFFFFFFFD, // IRQL 1 APC_LEVEL
23 0xFFFFFFF9, // IRQL 2 DISPATCH_LEVEL
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
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
55 UCHAR HalpMaskTable
[HIGH_LEVEL
+ 1] =
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
90 /* FUNCTIONS ******************************************************************/
93 HalpInitializeInterrupts(VOID
)
95 PKIPCR Pcr
= (PKIPCR
)KeGetPcr();
97 /* Fill out the IRQL mappings */
98 RtlCopyMemory(Pcr
->IrqlTable
, HalpIrqlTable
, sizeof(Pcr
->IrqlTable
));
99 RtlCopyMemory(Pcr
->IrqlMask
, HalpMaskTable
, sizeof(Pcr
->IrqlMask
));
102 /* IRQL MANAGEMENT ************************************************************/
108 HalGetInterruptSource(VOID
)
110 ULONG InterruptStatus
;
112 /* Get the interrupt status, and return the highest bit set */
113 InterruptStatus
= READ_REGISTER_ULONG(VIC_INT_STATUS
);
114 return 31 - _clz(InterruptStatus
);
122 KeGetCurrentIrql(VOID
)
124 /* Return the IRQL */
125 return KeGetPcr()->Irql
;
133 KeRaiseIrqlToDpcLevel(VOID
)
135 PKPCR Pcr
= KeGetPcr();
138 /* Save and update IRQL */
139 CurrentIrql
= Pcr
->Irql
;
140 Pcr
->Irql
= DISPATCH_LEVEL
;
143 /* Validate correct raise */
144 if (CurrentIrql
> DISPATCH_LEVEL
) KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL
);
147 /* Return the previous value */
156 KeRaiseIrqlToSynchLevel(VOID
)
158 PKPCR Pcr
= KeGetPcr();
161 /* Save and update IRQL */
162 CurrentIrql
= Pcr
->Irql
;
163 Pcr
->Irql
= SYNCH_LEVEL
;
166 /* Validate correct raise */
167 if (CurrentIrql
> SYNCH_LEVEL
)
170 KeBugCheckEx(IRQL_NOT_GREATER_OR_EQUAL
,
178 /* Return the previous value */
187 KfRaiseIrql(IN KIRQL NewIrql
)
189 ARM_STATUS_REGISTER Flags
;
190 PKIPCR Pcr
= (PKIPCR
)KeGetPcr();
194 /* Disable interrupts */
195 Flags
= KeArmStatusRegisterGet();
198 /* Read current IRQL */
199 CurrentIrql
= Pcr
->Irql
;
202 /* Validate correct raise */
203 if (CurrentIrql
> NewIrql
)
206 Pcr
->Irql
= PASSIVE_LEVEL
;
207 KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL
);
210 /* Clear interrupts associated to the old IRQL */
211 WRITE_REGISTER_ULONG(VIC_INT_CLEAR
, 0xFFFFFFFF);
213 /* Set the new interrupt mask */
214 InterruptMask
= Pcr
->IrqlTable
[NewIrql
];
215 WRITE_REGISTER_ULONG(VIC_INT_ENABLE
, InterruptMask
);
220 /* Restore interrupt state */
221 if (!Flags
.IrqDisable
) _enable();
223 /* Return old IRQL */
232 KfLowerIrql(IN KIRQL NewIrql
)
234 ARM_STATUS_REGISTER Flags
;
235 PKIPCR Pcr
= (PKIPCR
)KeGetPcr();
238 /* Disableinterrupts */
239 Flags
= KeArmStatusRegisterGet();
243 /* Validate correct lower */
244 if (OldIrql
> Pcr
->Irql
)
247 Pcr
->Irql
= HIGH_LEVEL
;
248 KeBugCheck(IRQL_NOT_LESS_OR_EQUAL
);
252 /* Clear interrupts associated to the old IRQL */
253 WRITE_REGISTER_ULONG(VIC_INT_CLEAR
, 0xFFFFFFFF);
255 /* Set the new interrupt mask */
256 InterruptMask
= Pcr
->IrqlTable
[NewIrql
];
257 WRITE_REGISTER_ULONG(VIC_INT_ENABLE
, InterruptMask
);
259 /* Save the new IRQL and restore interrupt state */
261 if (!Flags
.IrqDisable
) _enable();
264 /* SOFTWARE INTERRUPTS ********************************************************/
271 HalRequestSoftwareInterrupt(IN KIRQL Irql
)
273 /* Force a software interrupt */
274 WRITE_REGISTER_ULONG(VIC_SOFT_INT
, 1 << Irql
);
282 HalClearSoftwareInterrupt(IN KIRQL Irql
)
284 /* Clear software interrupt */
285 WRITE_REGISTER_ULONG(VIC_SOFT_INT_CLEAR
, 1 << Irql
);
288 /* SYSTEM INTERRUPTS **********************************************************/
295 HalEnableSystemInterrupt(IN UCHAR Vector
,
297 IN KINTERRUPT_MODE InterruptMode
)
309 HalDisableSystemInterrupt(IN UCHAR Vector
,
321 HalBeginSystemInterrupt(IN KIRQL Irql
,
335 HalEndSystemInterrupt(IN KIRQL OldIrql
,
336 IN PKTRAP_FRAME TrapFrame
)