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 ULONG PageFrameIndex, IN PKIRQL OldIrql)
PVOID MiMapImageHeaderInHyperSpace (IN ULONG PageFrameIndex)
VOID MiUnmapImageHeaderInHyperSpace (VOID)
PVOID MiMapPageToZeroInHyperSpace (IN ULONG PageFrameIndex)


Function Documentation

PVOID MiMapImageHeaderInHyperSpace IN ULONG  PageFrameIndex  ) 
 

Definition at line 153 of file alpha/hypermap.c.

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

00159 : 00160 00161 The physical address of the specified page is returned. 00162 00163 Arguments: 00164 00165 PageFrameIndex - Supplies the physical page number to map. 00166 00167 Return Value: 00168 00169 Returns the virtual address where the specified physical page was 00170 mapped. 00171 00172 Environment: 00173 00174 Kernel mode. 00175 00176 --*/ 00177 00178 { 00179 MMPTE TempPte; 00180 PMMPTE PointerPte; 00181 KIRQL OldIrql; 00182 00183 #if DBG 00184 00185 if (PageFrameIndex == 0) { 00186 DbgPrint("attempt to map physical page 0 in hyper space\n"); 00187 KeBugCheck (MEMORY_MANAGEMENT); 00188 } 00189 00190 #endif //DBG 00191 00192 PointerPte = MiGetPteAddress (IMAGE_MAPPING_PTE); 00193 00194 LOCK_PFN (OldIrql); 00195 00196 while (PointerPte->u.Long != 0) { 00197 00198 // 00199 // If there is no event specified, set one up. 00200 // 00201 00202 if (MmWorkingSetList->WaitingForImageMapping == (PKEVENT)NULL) { 00203 00204 // 00205 // Set the global event into the field and wait for it. 00206 // 00207 00208 MmWorkingSetList->WaitingForImageMapping = &MmImageMappingPteEvent; 00209 } 00210 00211 // 00212 // Release the PFN lock and wait on the event in an 00213 // atomic operation. 00214 // 00215 00216 KeEnterCriticalRegion(); 00217 UNLOCK_PFN_AND_THEN_WAIT(OldIrql); 00218 00219 KeWaitForSingleObject(MmWorkingSetList->WaitingForImageMapping, 00220 Executive, 00221 KernelMode, 00222 FALSE, 00223 (PLARGE_INTEGER)NULL); 00224 KeLeaveCriticalRegion(); 00225 00226 LOCK_PFN (OldIrql); 00227 } 00228 00229 ASSERT (PointerPte->u.Long == 0); 00230 00231 TempPte = ValidPtePte; 00232 TempPte.u.Hard.PageFrameNumber = PageFrameIndex; 00233 00234 *PointerPte = TempPte; 00235 00236 UNLOCK_PFN (OldIrql); 00237 00238 return (PVOID)MiGetVirtualAddressMappedByPte (PointerPte); 00239 }

PVOID MiMapPageInHyperSpace IN ULONG  PageFrameIndex,
IN PKIRQL  OldIrql
 

Definition at line 35 of file alpha/hypermap.c.

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

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

PVOID MiMapPageToZeroInHyperSpace IN ULONG  PageFrameIndex  ) 
 

Definition at line 313 of file alpha/hypermap.c.

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

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

VOID MiUnmapImageHeaderInHyperSpace VOID   ) 
 

Definition at line 243 of file alpha/hypermap.c.

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


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