Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmpsirql.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * FILE: hal/halx86/mp/mpsirql.c 00005 * PURPOSE: Implements IRQLs for multiprocessor systems 00006 * PROGRAMMERS: David Welch (welch@cwcom.net) 00007 * Casper S. Hornstrup (chorns@users.sourceforge.net) 00008 * UPDATE HISTORY: 00009 * 12/04/2001 CSH Created 00010 */ 00011 00012 /* INCLUDES *****************************************************************/ 00013 00014 #include <hal.h> 00015 #define NDEBUG 00016 #include <debug.h> 00017 00018 /* GLOBALS ******************************************************************/ 00019 00020 00021 /* FUNCTIONS ****************************************************************/ 00022 00023 #undef KeGetCurrentIrql 00024 KIRQL NTAPI KeGetCurrentIrql (VOID) 00025 /* 00026 * PURPOSE: Returns the current irq level 00027 * RETURNS: The current irq level 00028 */ 00029 { 00030 KIRQL irql; 00031 ULONG Flags; 00032 00033 Flags = __readeflags(); 00034 _disable(); 00035 00036 irql = __readfsbyte(FIELD_OFFSET(KPCR, Irql)); 00037 if (irql > HIGH_LEVEL) 00038 { 00039 DPRINT1 ("CurrentIrql %x\n", irql); 00040 ASSERT(FALSE); 00041 } 00042 if (Flags & EFLAGS_INTERRUPT_MASK) 00043 { 00044 _enable(); 00045 } 00046 return irql; 00047 } 00048 00049 00050 #undef KeSetCurrentIrql 00051 VOID KeSetCurrentIrql (KIRQL NewIrql) 00052 /* 00053 * PURPOSE: Sets the current irq level without taking any action 00054 */ 00055 { 00056 ULONG Flags; 00057 if (NewIrql > HIGH_LEVEL) 00058 { 00059 DPRINT1 ("NewIrql %x\n", NewIrql); 00060 ASSERT(FALSE); 00061 } 00062 Flags = __readeflags(); 00063 _disable(); 00064 __writefsbyte(FIELD_OFFSET(KPCR, Irql), NewIrql); 00065 if (Flags & EFLAGS_INTERRUPT_MASK) 00066 { 00067 _enable(); 00068 } 00069 } 00070 00071 VOID 00072 HalpLowerIrql(KIRQL NewIrql, BOOLEAN FromHalEndSystemInterrupt) 00073 { 00074 ULONG Flags; 00075 UCHAR DpcRequested; 00076 if (NewIrql >= DISPATCH_LEVEL) 00077 { 00078 KeSetCurrentIrql (NewIrql); 00079 APICWrite(APIC_TPR, IRQL2TPR (NewIrql) & APIC_TPR_PRI); 00080 return; 00081 } 00082 Flags = __readeflags(); 00083 if (KeGetCurrentIrql() > APC_LEVEL) 00084 { 00085 KeSetCurrentIrql (DISPATCH_LEVEL); 00086 APICWrite(APIC_TPR, IRQL2TPR (DISPATCH_LEVEL) & APIC_TPR_PRI); 00087 DpcRequested = __readfsbyte(FIELD_OFFSET(KIPCR, HalReserved[HAL_DPC_REQUEST])); 00088 if (FromHalEndSystemInterrupt || DpcRequested) 00089 { 00090 __writefsbyte(FIELD_OFFSET(KIPCR, HalReserved[HAL_DPC_REQUEST]), 0); 00091 _enable(); 00092 KiDispatchInterrupt(); 00093 if (!(Flags & EFLAGS_INTERRUPT_MASK)) 00094 { 00095 _disable(); 00096 } 00097 } 00098 KeSetCurrentIrql (APC_LEVEL); 00099 } 00100 if (NewIrql == APC_LEVEL) 00101 { 00102 return; 00103 } 00104 if (KeGetCurrentThread () != NULL && 00105 KeGetCurrentThread ()->ApcState.KernelApcPending) 00106 { 00107 _enable(); 00108 KiDeliverApc(KernelMode, NULL, NULL); 00109 if (!(Flags & EFLAGS_INTERRUPT_MASK)) 00110 { 00111 _disable(); 00112 } 00113 } 00114 KeSetCurrentIrql (PASSIVE_LEVEL); 00115 } 00116 00117 00118 /********************************************************************** 00119 * NAME EXPORTED 00120 * KfLowerIrql 00121 * 00122 * DESCRIPTION 00123 * Restores the irq level on the current processor 00124 * 00125 * ARGUMENTS 00126 * NewIrql = Irql to lower to 00127 * 00128 * RETURN VALUE 00129 * None 00130 * 00131 * NOTES 00132 * Uses fastcall convention 00133 */ 00134 VOID FASTCALL 00135 KfLowerIrql (KIRQL NewIrql) 00136 { 00137 KIRQL oldIrql = KeGetCurrentIrql(); 00138 if (NewIrql > oldIrql) 00139 { 00140 DPRINT1 ("NewIrql %x CurrentIrql %x\n", NewIrql, oldIrql); 00141 ASSERT(FALSE); 00142 } 00143 HalpLowerIrql (NewIrql, FALSE); 00144 } 00145 00146 00147 /********************************************************************** 00148 * NAME EXPORTED 00149 * KfRaiseIrql 00150 * 00151 * DESCRIPTION 00152 * Raises the hardware priority (irql) 00153 * 00154 * ARGUMENTS 00155 * NewIrql = Irql to raise to 00156 * 00157 * RETURN VALUE 00158 * previous irq level 00159 * 00160 * NOTES 00161 * Uses fastcall convention 00162 */ 00163 00164 KIRQL FASTCALL 00165 KfRaiseIrql (KIRQL NewIrql) 00166 { 00167 KIRQL OldIrql; 00168 ULONG Flags; 00169 00170 Flags = __readeflags(); 00171 _disable(); 00172 00173 OldIrql = KeGetCurrentIrql (); 00174 00175 if (NewIrql < OldIrql) 00176 { 00177 DPRINT1 ("CurrentIrql %x NewIrql %x\n", KeGetCurrentIrql (), NewIrql); 00178 ASSERT(FALSE); 00179 } 00180 00181 00182 if (NewIrql > DISPATCH_LEVEL) 00183 { 00184 APICWrite (APIC_TPR, IRQL2TPR(NewIrql) & APIC_TPR_PRI); 00185 } 00186 KeSetCurrentIrql (NewIrql); 00187 if (Flags & EFLAGS_INTERRUPT_MASK) 00188 { 00189 _enable(); 00190 } 00191 00192 return OldIrql; 00193 } 00194 00195 /********************************************************************** 00196 * NAME EXPORTED 00197 * KeRaiseIrqlToDpcLevel 00198 * 00199 * DESCRIPTION 00200 * Raises the hardware priority (irql) to DISPATCH level 00201 * 00202 * ARGUMENTS 00203 * None 00204 * 00205 * RETURN VALUE 00206 * Previous irq level 00207 * 00208 * NOTES 00209 * Calls KfRaiseIrql 00210 */ 00211 00212 KIRQL NTAPI 00213 KeRaiseIrqlToDpcLevel (VOID) 00214 { 00215 return KfRaiseIrql (DISPATCH_LEVEL); 00216 } 00217 00218 00219 /********************************************************************** 00220 * NAME EXPORTED 00221 * KeRaiseIrqlToSynchLevel 00222 * 00223 * DESCRIPTION 00224 * Raises the hardware priority (irql) to CLOCK2 level 00225 * 00226 * ARGUMENTS 00227 * None 00228 * 00229 * RETURN VALUE 00230 * Previous irq level 00231 * 00232 * NOTES 00233 * Calls KfRaiseIrql 00234 */ 00235 00236 KIRQL NTAPI 00237 KeRaiseIrqlToSynchLevel (VOID) 00238 { 00239 return KfRaiseIrql (CLOCK2_LEVEL); 00240 } 00241 00242 00243 BOOLEAN NTAPI 00244 HalBeginSystemInterrupt (KIRQL Irql, 00245 ULONG Vector, 00246 PKIRQL OldIrql) 00247 { 00248 ULONG Flags; 00249 DPRINT("Vector (0x%X) Irql (0x%X)\n", Vector, Irql); 00250 00251 if (KeGetCurrentIrql () >= Irql) 00252 { 00253 DPRINT1("current irql %d, new irql %d\n", KeGetCurrentIrql(), Irql); 00254 ASSERT(FALSE); 00255 } 00256 00257 Flags = __readeflags(); 00258 if (Flags & EFLAGS_INTERRUPT_MASK) 00259 { 00260 DPRINT1("HalBeginSystemInterrupt was called with interrupt's enabled\n"); 00261 ASSERT(FALSE); 00262 } 00263 APICWrite (APIC_TPR, IRQL2TPR (Irql) & APIC_TPR_PRI); 00264 *OldIrql = KeGetCurrentIrql (); 00265 KeSetCurrentIrql (Irql); 00266 return(TRUE); 00267 } 00268 00269 00270 VOID NTAPI 00271 HalEndSystemInterrupt (KIRQL Irql, 00272 IN PKTRAP_FRAME TrapFrame) 00273 /* 00274 * FUNCTION: Finish a system interrupt and restore the specified irq level. 00275 */ 00276 { 00277 ULONG Flags; 00278 Flags = __readeflags(); 00279 00280 if (Flags & EFLAGS_INTERRUPT_MASK) 00281 { 00282 DPRINT1("HalEndSystemInterrupt was called with interrupt's enabled\n"); 00283 ASSERT(FALSE); 00284 } 00285 APICSendEOI(); 00286 HalpLowerIrql (Irql, TRUE); 00287 } 00288 00289 VOID 00290 NTAPI 00291 HalDisableSystemInterrupt(ULONG Vector, 00292 KIRQL Irql) 00293 { 00294 ULONG irq; 00295 00296 DPRINT ("Vector (0x%X)\n", Vector); 00297 00298 if (Vector < FIRST_DEVICE_VECTOR || 00299 Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) 00300 { 00301 DPRINT1("Not a device interrupt, vector=%x\n", Vector); 00302 ASSERT(FALSE); 00303 return; 00304 } 00305 00306 irq = VECTOR2IRQ (Vector); 00307 IOAPICMaskIrq (irq); 00308 00309 return; 00310 } 00311 00312 00313 BOOLEAN NTAPI 00314 HalEnableSystemInterrupt (ULONG Vector, 00315 KIRQL Irql, 00316 KINTERRUPT_MODE InterruptMode) 00317 { 00318 ULONG irq; 00319 00320 if (Vector < FIRST_DEVICE_VECTOR || 00321 Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) 00322 { 00323 DPRINT("Not a device interrupt\n"); 00324 return FALSE; 00325 } 00326 00327 /* FIXME: We must check if the requested and the assigned interrupt mode is the same */ 00328 00329 irq = VECTOR2IRQ (Vector); 00330 IOAPICUnmaskIrq (irq); 00331 00332 return TRUE; 00333 } 00334 00335 VOID FASTCALL 00336 HalRequestSoftwareInterrupt(IN KIRQL Request) 00337 { 00338 switch (Request) 00339 { 00340 case APC_LEVEL: 00341 __writefsbyte(FIELD_OFFSET(KIPCR, HalReserved[HAL_APC_REQUEST]), 1); 00342 break; 00343 00344 case DISPATCH_LEVEL: 00345 __writefsbyte(FIELD_OFFSET(KIPCR, HalReserved[HAL_DPC_REQUEST]), 1); 00346 break; 00347 00348 default: 00349 ASSERT(FALSE); 00350 } 00351 } 00352 00353 VOID FASTCALL 00354 HalClearSoftwareInterrupt( 00355 IN KIRQL Request) 00356 { 00357 UNIMPLEMENTED; 00358 } Generated on Sun May 27 2012 04:28:45 for ReactOS by
1.7.6.1
|