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

hypermap.c File Reference

#include "mi.h"

Go to the source code of this file.

Functions

PVOID MiMapPageInHyperSpace (IN PFN_NUMBER PageFrameIndex, IN PKIRQL OldIrql)
PVOID MiMapImageHeaderInHyperSpace (IN PFN_NUMBER PageFrameIndex)
VOID MiUnmapImageHeaderInHyperSpace (VOID)
PVOID MiMapPageToZeroInHyperSpace (IN PFN_NUMBER PageFrameIndex)


Function Documentation

PVOID MiMapImageHeaderInHyperSpace IN PFN_NUMBER  PageFrameIndex  ) 
 

Definition at line 149 of file ia64/hypermap.c.

References ASSERT, DbgPrint, Executive, FALSE, IMAGE_MAPPING_PTE, KeBugCheck(), KernelMode, KeWaitForSingleObject(), LOCK_PFN, MiGetPteAddress, MiGetVirtualAddressMappedByPte, MmImageMappingPteEvent, MmWorkingSetList, NULL, _MMPTE::u, UNLOCK_PFN, UNLOCK_PFN_AND_THEN_WAIT, ValidPtePte, and _MMWSL::WaitingForImageMapping.

00155 : 00156 00157 This procedure maps the specified physical page into the 00158 PTE within hyper space reserved explicitly for image page 00159 header mapping. By reserving an explicit PTE for mapping 00160 the PTE, page faults can occur while the PTE is mapped within 00161 hyperspace and no other hyperspace maps will affect this PTE. 00162 00163 Note that if another thread attempts to map an image at the 00164 same time, it will be forced into a wait state until the 00165 header is "unmapped". 00166 00167 Arguments: 00168 00169 PageFrameIndex - Supplies the physical page number to map. 00170 00171 Return Value: 00172 00173 Returns the virtual address where the specified physical page was 00174 mapped. 00175 00176 Environment: 00177 00178 Kernel mode. 00179 00180 --*/ 00181 00182 { 00183 MMPTE TempPte; 00184 PMMPTE PointerPte; 00185 KIRQL OldIrql; 00186 00187 #if DBG 00188 if (PageFrameIndex == 0) { 00189 DbgPrint("attempt to map physical page 0 in hyper space\n"); 00190 KeBugCheck (MEMORY_MANAGEMENT); 00191 } 00192 #endif //DBG 00193 00194 #if HYPERMAP 00195 00196 PointerPte = MiGetPteAddress (IMAGE_MAPPING_PTE); 00197 00198 LOCK_PFN (OldIrql); 00199 00200 while (PointerPte->u.Long != 0) { 00201 00202 // 00203 // If there is no event specified, set one up. 00204 // 00205 00206 if (MmWorkingSetList->WaitingForImageMapping == (PKEVENT)NULL) { 00207 00208 // 00209 // Set the global event into the field and wait for it. 00210 // 00211 00212 MmWorkingSetList->WaitingForImageMapping = &MmImageMappingPteEvent; 00213 } 00214 00215 // 00216 // Release the PFN lock and wait on the event in an 00217 // atomic operation. 00218 // 00219 00220 UNLOCK_PFN_AND_THEN_WAIT(OldIrql); 00221 00222 KeWaitForSingleObject(MmWorkingSetList->WaitingForImageMapping, 00223 Executive, 00224 KernelMode, 00225 FALSE, 00226 (PLARGE_INTEGER)NULL); 00227 00228 LOCK_PFN (OldIrql); 00229 } 00230 00231 ASSERT (PointerPte->u.Long == 0); 00232 00233 TempPte = ValidPtePte; 00234 TempPte.u.Hard.PageFrameNumber = PageFrameIndex; 00235 00236 *PointerPte = TempPte; 00237 00238 UNLOCK_PFN (OldIrql); 00239 00240 return (PVOID)MiGetVirtualAddressMappedByPte (PointerPte); 00241 00242 #else 00243 00244 return KSEG_ADDRESS(PageFrameIndex); 00245 00246 #endif 00247 }

PVOID MiMapPageInHyperSpace IN PFN_NUMBER  PageFrameIndex,
IN PKIRQL  OldIrql
 

Definition at line 26 of file ia64/hypermap.c.

References ASSERT, DbgPrint, FALSE, KeBugCheck(), KeFlushEntireTb(), KSEG0_BASE, LOCK_HYPERSPACE, MI_MAKING_MULTIPLE_PTES_INVALID, MiGetVirtualAddressMappedByPte, MmFirstReservedMappingPte, MmKseg2Frame, NUMBER_OF_MAPPING_PTES, PAGE_SHIFT, TRUE, _MMPTE::u, and ValidPtePte.

00033 : 00034 00035 This procedure maps the specified physical page into hyper space 00036 and returns the virtual address which maps the page. 00037 00038 ************************************ 00039 * * 00040 * Returns with a spin lock held!!! * 00041 * * 00042 ************************************ 00043 00044 Arguments: 00045 00046 PageFrameIndex - Supplies the physical page number to map. 00047 00048 00049 Return Value: 00050 00051 Returns the address where the requested page was mapped. 00052 00053 RETURNS WITH THE HYPERSPACE SPIN LOCK HELD!!!! 00054 00055 The routine MiUnmapHyperSpaceMap MUST be called to release the lock!!!! 00056 00057 Environment: 00058 00059 Kernel mode. 00060 00061 --*/ 00062 00063 { 00064 00065 MMPTE TempPte; 00066 PMMPTE PointerPte; 00067 PFN_NUMBER offset; 00068 00069 #if DBG 00070 if (PageFrameIndex == 0) { 00071 DbgPrint("attempt to map physical page 0 in hyper space\n"); 00072 KeBugCheck (MEMORY_MANAGEMENT); 00073 } 00074 #endif //DBG 00075 00076 LOCK_HYPERSPACE(OldIrql); 00077 00078 #if HYPERMAP 00079 00080 if( PageFrameIndex < MmKseg2Frame){ 00081 return (PVOID)(KSEG0_BASE + (PageFrameIndex << PAGE_SHIFT)); 00082 } 00083 00084 PointerPte = MmFirstReservedMappingPte; 00085 if (PointerPte->u.Hard.Valid == 1) { 00086 00087 // 00088 // All the reserved PTEs have been used, make 00089 // them all invalid. 00090 // 00091 00092 MI_MAKING_MULTIPLE_PTES_INVALID (FALSE); 00093 00094 RtlZeroMemory (MmFirstReservedMappingPte, 00095 (NUMBER_OF_MAPPING_PTES + 1) * sizeof(MMPTE)); 00096 00097 // 00098 // Use the page frame number field of the first PTE as an 00099 // offset into the available mapping PTEs. 00100 // 00101 00102 PointerPte->u.Hard.PageFrameNumber = NUMBER_OF_MAPPING_PTES; 00103 00104 // 00105 // Flush entire TB only on this processor. 00106 // 00107 00108 KeFlushEntireTb (TRUE, FALSE); 00109 } 00110 00111 // 00112 // Get offset to first free PTE. 00113 // 00114 00115 offset = (PFN_NUMBER)PointerPte->u.Hard.PageFrameNumber; 00116 00117 // 00118 // Change offset for next time through. 00119 // 00120 00121 PointerPte->u.Hard.PageFrameNumber = offset - 1; 00122 00123 // 00124 // Point to free entry and make it valid. 00125 // 00126 00127 PointerPte += offset; 00128 ASSERT (PointerPte->u.Hard.Valid == 0); 00129 00130 00131 TempPte = ValidPtePte; 00132 TempPte.u.Hard.PageFrameNumber = PageFrameIndex; 00133 *PointerPte = TempPte; 00134 00135 // 00136 // Return the VA that map the page. 00137 // 00138 00139 return MiGetVirtualAddressMappedByPte (PointerPte); 00140 00141 #else 00142 00143 return KSEG_ADDRESS(PageFrameIndex); 00144 00145 #endif 00146 }

PVOID MiMapPageToZeroInHyperSpace IN PFN_NUMBER  PageFrameIndex  ) 
 

Definition at line 320 of file ia64/hypermap.c.

References DbgPrint, FALSE, KeBugCheck(), KeFlushSingleTb(), KSEG0_BASE, MiGetPteAddress, MiGetVirtualAddressMappedByPte, MM_PFN_LOCK_ASSERT, MmKseg2Frame, PAGE_SHIFT, TRUE, _MMPTE::u, ValidPtePte, and ZEROING_PAGE_PTE.

00326 : 00327 00328 This procedure maps the specified physical page into hyper space 00329 and returns the virtual address which maps the page. 00330 00331 NOTE: it maps it into the same location reserved for zeroing operations. 00332 This is only to be used by the zeroing page thread. 00333 00334 Arguments: 00335 00336 PageFrameIndex - Supplies the physical page number to map. 00337 00338 Return Value: 00339 00340 Returns the virtual address where the specified physical page was 00341 mapped. 00342 00343 Environment: 00344 00345 Must be holding the PFN lock. 00346 00347 --*/ 00348 00349 { 00350 MMPTE TempPte; 00351 PMMPTE PointerPte; 00352 PVOID MappedAddress; 00353 00354 #if DBG 00355 if (PageFrameIndex == 0) { 00356 DbgPrint("attempt to map physical page 0 in hyper space\n"); 00357 KeBugCheck (MEMORY_MANAGEMENT); 00358 } 00359 #endif 00360 00361 MM_PFN_LOCK_ASSERT(); 00362 00363 #if HYPERMAP 00364 00365 if( PageFrameIndex < MmKseg2Frame){ 00366 return (PVOID)(KSEG0_BASE + (PageFrameIndex << PAGE_SHIFT)); 00367 } 00368 00369 PointerPte = MiGetPteAddress (ZEROING_PAGE_PTE); 00370 00371 MappedAddress = MiGetVirtualAddressMappedByPte (PointerPte); 00372 00373 TempPte.u.Long = 0; 00374 00375 KeFlushSingleTb (MappedAddress, TRUE, FALSE, 00376 (PHARDWARE_PTE)PointerPte, TempPte.u.Flush); 00377 00378 TempPte = ValidPtePte; 00379 TempPte.u.Hard.PageFrameNumber = PageFrameIndex; 00380 00381 *PointerPte = TempPte; 00382 00383 return MappedAddress; 00384 00385 #else 00386 00387 return KSEG_ADDRESS(PageFrameIndex); 00388 00389 #endif 00390 } }

VOID MiUnmapImageHeaderInHyperSpace VOID   ) 
 

Definition at line 250 of file ia64/hypermap.c.

References ASSERT, Event(), FALSE, IMAGE_MAPPING_PTE, KeFlushSingleTb(), KePulseEvent(), LOCK_PFN, MiGetPteAddress, MmWorkingSetList, NULL, TRUE, _MMPTE::u, UNLOCK_PFN, and _MMWSL::WaitingForImageMapping.

00256 : 00257 00258 This procedure unmaps the PTE reserved for mapping the image 00259 header, flushes the TB, and, if the WaitingForImageMapping field 00260 is not NULL, sets the specified event. 00261 00262 Arguments: 00263 00264 None. 00265 00266 Return Value: 00267 00268 None. 00269 00270 Environment: 00271 00272 Kernel mode. 00273 00274 --*/ 00275 00276 { 00277 #if HYPERMAP 00278 00279 MMPTE TempPte; 00280 PMMPTE PointerPte; 00281 KIRQL OldIrql; 00282 PKEVENT Event; 00283 00284 PointerPte = MiGetPteAddress (IMAGE_MAPPING_PTE); 00285 00286 TempPte.u.Long = 0; 00287 00288 LOCK_PFN (OldIrql); 00289 00290 // 00291 // Capture the current state of the event field and clear it out. 00292 // 00293 00294 Event = MmWorkingSetList->WaitingForImageMapping; 00295 00296 MmWorkingSetList->WaitingForImageMapping = (PKEVENT)NULL; 00297 00298 ASSERT (PointerPte->u.Long != 0); 00299 00300 KeFlushSingleTb (IMAGE_MAPPING_PTE, TRUE, FALSE, 00301 (PHARDWARE_PTE)PointerPte, TempPte.u.Flush); 00302 00303 UNLOCK_PFN (OldIrql); 00304 00305 if (Event != (PKEVENT)NULL) { 00306 00307 // 00308 // If there was an event specified, set the event. 00309 // 00310 00311 KePulseEvent (Event, 0, FALSE); 00312 } 00313 00314 #endif 00315 00316 return; 00317 }


Generated on Sat May 15 19:44:06 2004 for test by doxygen 1.3.7