00001 /*++ 00002 00003 Copyright (c) 1992-1994 Microsoft Corporation 00004 Copyright (c) 1994 IBM Corporation 00005 00006 Module Name: 00007 00008 flushtb.c 00009 00010 Abstract: 00011 00012 This module implements machine dependent functions to flush the 00013 translation buffer and synchronize PIDs in an MP system. 00014 00015 Author: 00016 00017 David N. Cutler (davec) 13-May-1989 00018 00019 Modified for PowerPC by Mark Mergen ([email protected]) 25-Aug-1994 00020 00021 Environment: 00022 00023 Kernel mode only. 00024 00025 Revision History: 00026 00027 00028 --*/ 00029 00030 #include "ki.h" 00031 00032 VOID 00033 KeFlushEntireTb ( 00034 IN BOOLEAN Invalid, 00035 IN BOOLEAN AllProcessors 00036 ) 00037 00038 /*++ 00039 00040 Routine Description: 00041 00042 This function flushes the entire translation buffer (TB) on all 00043 processors that are currently running threads which are children 00044 of the current process or flushes the entire translation buffer 00045 on all processors in the host configuration. 00046 00047 N.B. The entire translation buffer on all processors in the host 00048 configuration is always flushed since PowerPC TB is tagged by 00049 VSID and translations are held across context switch boundaries. 00050 00051 Arguments: 00052 00053 Invalid - Supplies a boolean value that specifies the reason for 00054 flushing the translation buffer. 00055 00056 AllProcessors - Supplies a boolean value that determines which 00057 translation buffers are to be flushed. 00058 00059 Return Value: 00060 00061 None. 00062 00063 --*/ 00064 00065 { 00066 00067 KIRQL OldIrql; 00068 00069 ASSERT(KeGetCurrentIrql() <= SYNCH_LEVEL); 00070 00071 #if !defined(NT_UP) 00072 00073 // 00074 // Raise IRQL to synchronization level to avoid a possible context switch. 00075 // 00076 00077 OldIrql = KeRaiseIrqlToSynchLevel(); 00078 00079 IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushEntireTb); 00080 00081 #endif 00082 00083 // 00084 // Flush TB on current processor. 00085 // PowerPC hardware broadcasts if MP. 00086 // 00087 00088 KeFlushCurrentTb(); 00089 00090 #if !defined(NT_UP) 00091 00092 // 00093 // Lower IRQL to previous level. 00094 // 00095 00096 KeLowerIrql(OldIrql); 00097 00098 #endif 00099 00100 return; 00101 } 00102 00103 VOID 00104 KeFlushMultipleTb ( 00105 IN ULONG Number, 00106 IN PVOID *Virtual, 00107 IN BOOLEAN Invalid, 00108 IN BOOLEAN AllProcessors, 00109 IN PHARDWARE_PTE *PtePointer OPTIONAL, 00110 IN HARDWARE_PTE PteValue 00111 ) 00112 00113 /*++ 00114 00115 Routine Description: 00116 00117 This function flushes multiple entries from the translation buffer 00118 on all processors that are currently running threads which are 00119 children of the current process or flushes multiple entries from 00120 the translation buffer on all processors in the host configuration. 00121 00122 N.B. The specified translation entries on all processors in the host 00123 configuration are always flushed since PowerPC TB is tagged by 00124 VSID and translations are held across context switch boundaries. 00125 00126 Arguments: 00127 00128 Number - Supplies the number of TB entries to flush. 00129 00130 Virtual - Supplies a pointer to an array of virtual addresses that 00131 are within the pages whose translation buffer entries are to be 00132 flushed. 00133 00134 Invalid - Supplies a boolean value that specifies the reason for 00135 flushing the translation buffer. 00136 00137 AllProcessors - Supplies a boolean value that determines which 00138 translation buffers are to be flushed. 00139 00140 PtePointer - Supplies an optional pointer to an array of pointers to 00141 page table entries that receive the specified page table entry 00142 value. 00143 00144 PteValue - Supplies the the new page table entry value. 00145 00146 Return Value: 00147 00148 None. 00149 00150 --*/ 00151 00152 { 00153 00154 ULONG Index; 00155 00156 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); 00157 00158 // 00159 // If a page table entry address array is specified, then set the 00160 // specified page table entries to the specific value. 00161 // 00162 00163 if (ARGUMENT_PRESENT(PtePointer)) { 00164 for (Index = 0; Index < Number; Index += 1) { 00165 *PtePointer[Index] = PteValue; 00166 } 00167 } 00168 00169 #if !defined(NT_UP) 00170 00171 IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushSingleTb); 00172 00173 #endif 00174 00175 // 00176 // Flush the specified entries from the TB on the current processor. 00177 // PowerPC hardware broadcasts if MP. 00178 // 00179 00180 for (Index = 0; Index < Number; Index += 1) { 00181 KiFlushSingleTb(Invalid, Virtual[Index]); 00182 } 00183 00184 return; 00185 } 00186 00187 HARDWARE_PTE 00188 KeFlushSingleTb ( 00189 IN PVOID Virtual, 00190 IN BOOLEAN Invalid, 00191 IN BOOLEAN AllProcessors, 00192 IN PHARDWARE_PTE PtePointer, 00193 IN HARDWARE_PTE PteValue 00194 ) 00195 00196 /*++ 00197 00198 Routine Description: 00199 00200 This function flushes a single entry from the translation buffer 00201 on all processors that are currently running threads which are 00202 children of the current process or flushes a single entry from 00203 the translation buffer on all processors in the host configuration. 00204 00205 N.B. The specified translation entry on all processors in the host 00206 configuration is always flushed since PowerPC TB is tagged by 00207 VSID and translations are held across context switch boundaries. 00208 00209 Arguments: 00210 00211 Virtual - Supplies a virtual address that is within the page whose 00212 translation buffer entry is to be flushed. 00213 00214 Invalid - Supplies a boolean value that specifies the reason for 00215 flushing the translation buffer. 00216 00217 AllProcessors - Supplies a boolean value that determines which 00218 translation buffers are to be flushed. 00219 00220 PtePointer - Supplies a pointer to the page table entry which 00221 receives the specified value. 00222 00223 PteValue - Supplies the the new page table entry value. 00224 00225 Return Value: 00226 00227 The previous contents of the specified page table entry is returned 00228 as the function value. 00229 00230 --*/ 00231 00232 { 00233 00234 HARDWARE_PTE OldPte; 00235 00236 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); 00237 00238 // 00239 // Collect call data. 00240 // 00241 00242 #if defined(_COLLECT_FLUSH_SINGLE_CALLDATA_) 00243 00244 RECORD_CALL_DATA(&KiFlushSingleCallData); 00245 00246 #endif 00247 00248 // 00249 // Capture the previous contents of the page table entry and set the 00250 // page table entry to the new value. 00251 // 00252 00253 OldPte = *PtePointer; 00254 *PtePointer = PteValue; 00255 00256 #if !defined(NT_UP) 00257 00258 IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushSingleTb); 00259 00260 #endif 00261 00262 // 00263 // Flush the specified entry from the TB on the current processor. 00264 // PowerPC hardware broadcasts if MP. 00265 // 00266 00267 KiFlushSingleTb(Invalid, Virtual); 00268 00269 // 00270 // Return the previous page table entry value. 00271 // 00272 00273 return OldPte; 00274 }