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

hypermap.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 Copyright (c) 1992 Digital Equipment Corporation 00005 00006 Module Name: 00007 00008 hypermap.c 00009 00010 Abstract: 00011 00012 This module contains the routines which map physical pages into 00013 reserved PTEs within hyper space for AXP64 systems. 00014 00015 Author: 00016 00017 Lou Perazzoli (loup) 5-Apr-1989 00018 Joe Notarangelo 23-Apr-1992 ALPHA version from MIPS version 00019 00020 Revision History: 00021 00022 Chao Chen 21-Aug-1995 Fixed accessing pages above 1 gig problem through 00023 hyperspace. 00024 00025 --*/ 00026 00027 #include "mi.h" 00028 00029 PVOID 00030 MiMapPageInHyperSpace ( 00031 IN PFN_NUMBER PageFrameIndex, 00032 IN PKIRQL OldIrql 00033 ) 00034 00035 /*++ 00036 00037 Routine Description: 00038 00039 This routine returns the physical address of the page. 00040 00041 ************************************ 00042 * * 00043 * Returns with a spin lock held!!! * 00044 * * 00045 ************************************ 00046 00047 Arguments: 00048 00049 PageFrameIndex - Supplies the physical page number to map. 00050 00051 Return Value: 00052 00053 Returns the address where the requested page was mapped. 00054 00055 RETURNS WITH THE HYPERSPACE SPIN LOCK HELD!!!! 00056 00057 The routine MiUnmapHyperSpaceMap MUST be called to release the lock!!!! 00058 00059 Environment: 00060 00061 kernel mode. 00062 00063 --*/ 00064 00065 { 00066 00067 // 00068 // On AXP64 systems all pages can be mapped physically using the 43-bit 00069 // super page address range. 00070 // 00071 00072 ASSERT(PageFrameIndex != 0); 00073 00074 LOCK_HYPERSPACE(OldIrql); 00075 00076 return KSEG_ADDRESS(PageFrameIndex); 00077 } 00078 00079 PVOID 00080 MiMapImageHeaderInHyperSpace ( 00081 IN PFN_NUMBER PageFrameIndex 00082 ) 00083 00084 /*++ 00085 00086 Routine Description: 00087 00088 The physical address of the specified page is returned. 00089 00090 Arguments: 00091 00092 PageFrameIndex - Supplies the physical page number to map. 00093 00094 Return Value: 00095 00096 Returns the virtual address where the specified physical page was 00097 mapped. 00098 00099 Environment: 00100 00101 Kernel mode. 00102 00103 --*/ 00104 00105 { 00106 MMPTE TempPte; 00107 PMMPTE PointerPte; 00108 KIRQL OldIrql; 00109 00110 #if DBG 00111 00112 if (PageFrameIndex == 0) { 00113 DbgPrint("attempt to map physical page 0 in hyper space\n"); 00114 KeBugCheck (MEMORY_MANAGEMENT); 00115 } 00116 00117 #endif //DBG 00118 00119 PointerPte = MiGetPteAddress (IMAGE_MAPPING_PTE); 00120 00121 LOCK_PFN(OldIrql); 00122 00123 while (PointerPte->u.Long != 0) { 00124 00125 // 00126 // If there is no event specified, set one up. 00127 // 00128 00129 if (MmWorkingSetList->WaitingForImageMapping == (PKEVENT)NULL) { 00130 00131 // 00132 // Set the global event into the field and wait for it. 00133 // 00134 00135 MmWorkingSetList->WaitingForImageMapping = &MmImageMappingPteEvent; 00136 } 00137 00138 // 00139 // Release the PFN lock and wait on the event in an 00140 // atomic operation. 00141 // 00142 00143 KeEnterCriticalRegion(); 00144 00145 UNLOCK_PFN_AND_THEN_WAIT(OldIrql); 00146 00147 KeWaitForSingleObject(MmWorkingSetList->WaitingForImageMapping, 00148 Executive, 00149 KernelMode, 00150 FALSE, 00151 (PLARGE_INTEGER)NULL); 00152 00153 KeLeaveCriticalRegion(); 00154 00155 LOCK_PFN (OldIrql); 00156 } 00157 00158 ASSERT (PointerPte->u.Long == 0); 00159 00160 TempPte = ValidPtePte; 00161 TempPte.u.Hard.PageFrameNumber = PageFrameIndex; 00162 00163 *PointerPte = TempPte; 00164 00165 UNLOCK_PFN (OldIrql); 00166 00167 return (PVOID)MiGetVirtualAddressMappedByPte (PointerPte); 00168 } 00169 00170 VOID 00171 MiUnmapImageHeaderInHyperSpace ( 00172 VOID 00173 ) 00174 00175 /*++ 00176 00177 Routine Description: 00178 00179 This procedure unmaps the PTE reserved for mapping the image 00180 header, flushes the TB, and, if the WaitingForImageMapping field 00181 is not NULL, sets the specified event. 00182 00183 On ALPHA, no action is required as the super-page address of the page 00184 was used. 00185 00186 Arguments: 00187 00188 None. 00189 00190 Return Value: 00191 00192 None. 00193 00194 Environment: 00195 00196 Kernel mode. 00197 00198 --*/ 00199 00200 { 00201 00202 MMPTE TempPte; 00203 PMMPTE PointerPte; 00204 KIRQL OldIrql; 00205 PKEVENT Event; 00206 00207 PointerPte = MiGetPteAddress(IMAGE_MAPPING_PTE); 00208 00209 TempPte.u.Long = 0; 00210 00211 LOCK_PFN (OldIrql); 00212 00213 // 00214 // Capture the current state of the event field and clear it out. 00215 // 00216 00217 Event = MmWorkingSetList->WaitingForImageMapping; 00218 00219 MmWorkingSetList->WaitingForImageMapping = (PKEVENT)NULL; 00220 00221 ASSERT (PointerPte->u.Long != 0); 00222 00223 KeFlushSingleTb (IMAGE_MAPPING_PTE, TRUE, FALSE, 00224 (PHARDWARE_PTE)PointerPte, TempPte.u.Hard); 00225 00226 UNLOCK_PFN (OldIrql); 00227 00228 if (Event != (PKEVENT)NULL) { 00229 00230 // 00231 // If there was an event specified, set the event. 00232 // 00233 00234 KePulseEvent (Event, 0, FALSE); 00235 } 00236 00237 return; 00238 } 00239 00240 PVOID 00241 MiMapPageToZeroInHyperSpace ( 00242 IN PFN_NUMBER PageFrameIndex 00243 ) 00244 00245 /*++ 00246 00247 Routine Description: 00248 00249 This procedure maps the specified page frame into the 43-bit super 00250 page address range. 00251 00252 Arguments: 00253 00254 PageFrameIndex - Supplies the page frame to map. 00255 00256 Return Value: 00257 00258 The 43-bit super address of the respective page is returned as the 00259 function value. 00260 00261 --*/ 00262 00263 { 00264 00265 // 00266 // On AXP64 systems all pages can be mapped physically using the 43-bit 00267 // super page address range. 00268 // 00269 00270 ASSERT(PageFrameIndex != 0); 00271 00272 MM_PFN_LOCK_ASSERT(); 00273 00274 return KSEG_ADDRESS(PageFrameIndex); 00275 }

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