Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

flush.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1990 Microsoft Corporation 00004 00005 Module Name: 00006 00007 flush.c 00008 00009 Abstract: 00010 00011 This module implements i386 machine dependent kernel functions to flush 00012 the data and instruction caches and to stall processor execution. 00013 00014 Author: 00015 00016 David N. Cutler (davec) 26-Apr-1990 00017 00018 Environment: 00019 00020 Kernel mode only. 00021 00022 Revision History: 00023 00024 --*/ 00025 00026 #include "ki.h" 00027 00028 00029 // 00030 // Prototypes 00031 // 00032 00033 VOID 00034 KeInvalidateAllCachesTarget ( 00035 IN PKIPI_CONTEXT SignalDone, 00036 IN PVOID Parameter1, 00037 IN PVOID Parameter2, 00038 IN PVOID Parameter3 00039 ); 00040 00041 extern ULONG KeI386CpuType; 00042 00043 // i386 and i486 have transparent caches, so these routines are nooped 00044 // out in macros in i386.h. 00045 00046 #if 0 00047 00048 VOID 00049 KeSweepDcache ( 00050 IN BOOLEAN AllProcessors 00051 ) 00052 00053 /*++ 00054 00055 Routine Description: 00056 00057 This function flushes the data cache on all processors that are currently 00058 running threads which are children of the current process or flushes the 00059 data cache on all processors in the host configuration. 00060 00061 Arguments: 00062 00063 AllProcessors - Supplies a boolean value that determines which data 00064 caches are flushed. 00065 00066 Return Value: 00067 00068 None. 00069 00070 --*/ 00071 00072 { 00073 00074 HalSweepDcache(); 00075 return; 00076 } 00077 00078 VOID 00079 KeSweepIcache ( 00080 IN BOOLEAN AllProcessors 00081 ) 00082 00083 /*++ 00084 00085 Routine Description: 00086 00087 This function flushes the instruction cache on all processors that are 00088 currently running threads which are children of the current process or 00089 flushes the instruction cache on all processors in the host configuration. 00090 00091 Arguments: 00092 00093 AllProcessors - Supplies a boolean value that determines which instruction 00094 caches are flushed. 00095 00096 Return Value: 00097 00098 None. 00099 00100 --*/ 00101 00102 { 00103 00104 HalSweepIcache(); 00105 00106 #if defined(R4000) 00107 00108 HalSweepDcache(); 00109 00110 #endif 00111 00112 return; 00113 } 00114 00115 VOID 00116 KeSweepIcacheRange ( 00117 IN BOOLEAN AllProcessors, 00118 IN PVOID BaseAddress, 00119 IN ULONG Length 00120 ) 00121 00122 /*++ 00123 00124 Routine Description: 00125 00126 This function flushes the an range of virtual addresses from the primary 00127 instruction cache on all processors that are currently running threads 00128 which are children of the current process or flushes the range of virtual 00129 addresses from the primary instruction cache on all processors in the host 00130 configuration. 00131 00132 Arguments: 00133 00134 AllProcessors - Supplies a boolean value that determines which instruction 00135 caches are flushed. 00136 00137 BaseAddress - Supplies a pointer to the base of the range that is flushed. 00138 00139 Length - Supplies the length of the range that is flushed if the base 00140 address is specified. 00141 00142 Return Value: 00143 00144 None. 00145 00146 --*/ 00147 00148 { 00149 00150 ULONG Offset; 00151 00152 // 00153 // If the length of the range is greater than the size of the primary 00154 // instruction cache, then set the length of the flush to the size of 00155 // the primary instruction cache and set the ase address of zero. 00156 // 00157 // N.B. It is assumed that the size of the primary instruction and 00158 // data caches are the same. 00159 // 00160 00161 if (Length > PCR->FirstLevelIcacheSize) { 00162 BaseAddress = (PVOID)0; 00163 Length = PCR->FirstLevelIcacheSize; 00164 } 00165 00166 // 00167 // Flush the specified range of virtual addresses from the primary 00168 // instruction cache. 00169 // 00170 00171 Offset = (ULONG)BaseAddress & PCR->DcacheAlignment; 00172 Length = (Offset + Length + PCR->DcacheAlignment) & ~PCR->DcacheAlignment; 00173 BaseAddress = (PVOID)((ULONG)BaseAddress & ~PCR->DcacheAlignment); 00174 HalSweepIcacheRange(BaseAddress, Length); 00175 00176 #if defined(R4000) 00177 00178 HalSweepDcacheRange(BaseAddress, Length); 00179 00180 #endif 00181 00182 return; 00183 } 00184 #endif 00185 00186 BOOLEAN 00187 KeInvalidateAllCaches ( 00188 IN BOOLEAN AllProcessors 00189 ) 00190 /*++ 00191 00192 Routine Description: 00193 00194 This function writes back and invalidates the cache on all processors 00195 that are currently running threads which are children of the current 00196 process or on all processors in the host configuration. 00197 00198 Arguments: 00199 00200 AllProcessors - Supplies a boolean value that determines which data 00201 caches are flushed. 00202 00203 Return Value: 00204 00205 TRUE if the invalidation was done, FALSE otherwise. 00206 00207 --*/ 00208 { 00209 PKPRCB Prcb; 00210 PKPROCESS Process; 00211 KIRQL OldIrql; 00212 KAFFINITY TargetProcessors; 00213 00214 // 00215 // Support for wbinvd on Pentium based platforms is vendor dependent. 00216 // Check for family first and support on Pentium Pro based platforms 00217 // onward. 00218 // 00219 00220 if (KeI386CpuType < 6 ) { 00221 return FALSE; 00222 } 00223 00224 #ifndef NT_UP 00225 // 00226 // Compute target set of processors. 00227 // 00228 00229 KiLockContextSwap(&OldIrql); 00230 Prcb = KeGetCurrentPrcb(); 00231 if (AllProcessors) { 00232 TargetProcessors = KeActiveProcessors; 00233 } else { 00234 Process = Prcb->CurrentThread->ApcState.Process; 00235 TargetProcessors = Process->ActiveProcessors; 00236 } 00237 00238 TargetProcessors &= ~Prcb->SetMember; 00239 00240 // 00241 // If any target processors are specified, then send writeback 00242 // invalidate packet to the target set of processors. 00243 // 00244 00245 if (TargetProcessors != 0) { 00246 KiIpiSendSynchronousPacket(Prcb, 00247 TargetProcessors, 00248 KeInvalidateAllCachesTarget, 00249 (PVOID)&Prcb->ReverseStall, 00250 NULL, 00251 NULL); 00252 00253 KiIpiStallOnPacketTargets(TargetProcessors); 00254 } 00255 00256 // 00257 // All target processors have written back and invalidated caches and 00258 // are waiting to proceed. Write back invalidate current cache and 00259 // then continue the execution of target processors. 00260 // 00261 #endif 00262 _asm { 00263 ; 00264 ; wbinvd 00265 ; 00266 00267 _emit 0Fh 00268 _emit 09h 00269 } 00270 00271 #ifndef NT_UP 00272 // 00273 // Wait until all target processors have finished and completed packet. 00274 // 00275 00276 if (TargetProcessors != 0) { 00277 Prcb->ReverseStall += 1; 00278 } 00279 00280 // 00281 // Release the context swap lock. 00282 // 00283 00284 KiUnlockContextSwap(OldIrql); 00285 00286 #endif 00287 00288 return TRUE; 00289 } 00290 00291 VOID 00292 KeInvalidateAllCachesTarget ( 00293 IN PKIPI_CONTEXT SignalDone, 00294 IN PVOID Proceed, 00295 IN PVOID Parameter2, 00296 IN PVOID Parameter3 00297 ) 00298 /*++ 00299 00300 Routine Description: 00301 00302 This is the target function for writing back and invalidating the cache. 00303 00304 Arguments: 00305 00306 SignalDone - Supplies a pointer to a variable that is cleared when the 00307 requested operation has been performed. 00308 00309 Proceed - pointer to flag to syncronize with 00310 00311 Return Value: 00312 00313 None. 00314 00315 --*/ 00316 { 00317 // 00318 // Write back invalidate current cache 00319 // 00320 00321 _asm { 00322 ; 00323 ; wbinvd 00324 ; 00325 00326 _emit 0Fh 00327 _emit 09h 00328 00329 } 00330 00331 KiIpiSignalPacketDoneAndStall (SignalDone, Proceed); 00332 }

Generated on Sat May 15 19:40:02 2004 for test by doxygen 1.3.7