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