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

initia64.c File Reference

#include "mi.h"

Go to the source code of this file.

Defines

#define MiGetKSegPteAddress(Va)   ((PMMPTE)__thash((ULONG_PTR)(Va)))
#define _x1mb   (1024*1024)
#define _x1mbnp   ((1024*1024) >> PAGE_SHIFT)
#define _x4mb   (1024*1024*4)
#define _x4mbnp   ((1024*1024*4) >> PAGE_SHIFT)
#define _x16mb   (1024*1024*16)
#define _x16mbnp   ((1024*1024*16) >> PAGE_SHIFT)
#define _x32mb   (1024*1024*32)
#define _x32mbnp   ((1024*1024*32) >> PAGE_SHIFT)
#define _x64mb   (1024*1024*64)
#define _x64mbnp   ((1024*1024*64) >> PAGE_SHIFT)
#define _x256mb   (1024*1024*256)
#define _x256mbnp   ((1024*1024*256) >> PAGE_SHIFT)
#define _x512mb   (1024*1024*512)
#define _x512mbnp   ((1024*1024*512) >> PAGE_SHIFT)
#define _x4gb   (0x100000000UI64)
#define _x4gbnp   (0x100000000UI64 >> PAGE_SHIFT)
#define ADD_HIGH_MEMORY   0

Functions

VOID KeInitializeVhpt (IN PVOID Virtual, IN ULONG Size)
VOID KeFillLargePdePinned (IN PMMPTE Pte, IN PVOID Virtual)
VOID MiConvertToSuperPages (PVOID StartVirtual, PVOID EndVirtual, SIZE_T PageSize, ULONG PageShift)
VOID MiConvertBackToStandardPages (IN PVOID StartVirtual, IN PVOID EndVirtual)
VOID MiBuildPageTableForDrivers (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID MiBuildPageTableForLoaderMemory (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID MiRemoveLoaderSuperPages (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID MiMakeKernelPagesPermanent (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID MiCheckMemoryDescriptorList (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
PFN_NUMBER MiGetNextPhysicalPage (VOID)
BOOLEAN MiEnsureAvailablePagesInFreeDescriptor (IN PFN_NUMBER Pages, IN PFN_NUMBER MaxPage)
VOID MiInitMachineDependent (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
PVOID MiGetKSegAddress (PFN_NUMBER FrameNumber)
VOID MiConvertToSuperPages (IN PVOID StartVirtual, IN PVOID EndVirtual, IN SIZE_T PageSize, IN ULONG PageShift)
VOID MiSweepCacheMachineDependent (IN PVOID VirtualAddress, IN SIZE_T Size, IN MEMORY_CACHING_TYPE CacheType)
PVOID MiConvertToLoaderVirtual (IN PFN_NUMBER Page, IN PLOADER_PARAMETER_BLOCK LoaderBlock)

Variables

ULONG_PTR MmKseg3VhptBase
ULONG MmKseg3VhptPs
PFN_NUMBER MmSystemParentTablePage
MMPTE MiSystemSelfMappedPte
MMPTE MiUserSelfMappedPte
PVOID MiKseg0Start = 0
PVOID MiKseg0End = 0
BOOLEAN MiKseg0Mapping = TRUE
BOOLEAN MiPrintMemoryDescriptors = FALSE
PFN_NUMBER MiNtoskrnlPhysicalBase
ULONG_PTR MiNtoskrnlVirtualBase
ULONG MiNtoskrnlPageShift
PFN_NUMBER MiWasteStart = 0
PFN_NUMBER MiWasteEnd = 0
PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor
PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorLargest = NULL
PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorLowMem = NULL
PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorNonPaged = NULL
PFN_NUMBER MiNextPhysicalPage
PFN_NUMBER MiNumberOfPages
PFN_NUMBER MiOldFreeDescriptorBase
PFN_NUMBER MiOldFreeDescriptorCount
ULONG MiImplVirtualMsb = 50


Define Documentation

#define _x16mb   (1024*1024*16)
 

Definition at line 102 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

#define _x16mbnp   ((1024*1024*16) >> PAGE_SHIFT)
 

Definition at line 103 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

#define _x1mb   (1024*1024)
 

Definition at line 98 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

#define _x1mbnp   ((1024*1024) >> PAGE_SHIFT)
 

Definition at line 99 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

#define _x256mb   (1024*1024*256)
 

Definition at line 108 of file mm/ia64/initia64.c.

#define _x256mbnp   ((1024*1024*256) >> PAGE_SHIFT)
 

Definition at line 109 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

#define _x32mb   (1024*1024*32)
 

Definition at line 104 of file mm/ia64/initia64.c.

#define _x32mbnp   ((1024*1024*32) >> PAGE_SHIFT)
 

Definition at line 105 of file mm/ia64/initia64.c.

#define _x4gb   (0x100000000UI64)
 

Definition at line 112 of file mm/ia64/initia64.c.

#define _x4gbnp   (0x100000000UI64 >> PAGE_SHIFT)
 

Definition at line 113 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

#define _x4mb   (1024*1024*4)
 

Definition at line 100 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

#define _x4mbnp   ((1024*1024*4) >> PAGE_SHIFT)
 

Definition at line 101 of file mm/ia64/initia64.c.

#define _x512mb   (1024*1024*512)
 

Definition at line 110 of file mm/ia64/initia64.c.

#define _x512mbnp   ((1024*1024*512) >> PAGE_SHIFT)
 

Definition at line 111 of file mm/ia64/initia64.c.

#define _x64mb   (1024*1024*64)
 

Definition at line 106 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

#define _x64mbnp   ((1024*1024*64) >> PAGE_SHIFT)
 

Definition at line 107 of file mm/ia64/initia64.c.

#define ADD_HIGH_MEMORY   0
 

Definition at line 115 of file mm/ia64/initia64.c.

#define MiGetKSegPteAddress Va   )     ((PMMPTE)__thash((ULONG_PTR)(Va)))
 

Definition at line 96 of file mm/ia64/initia64.c.

Referenced by MiGetKSegAddress(), and MiInitMachineDependent().


Function Documentation

VOID KeFillLargePdePinned IN PMMPTE  Pte,
IN PVOID  Virtual
 

VOID KeInitializeVhpt IN PVOID  Virtual,
IN ULONG  Size
 

Referenced by MiInitMachineDependent().

VOID MiBuildPageTableForDrivers IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 2091 of file mm/ia64/initia64.c.

References ASSERT, FALSE, MI_CONVERT_PHYSICAL_TO_PFN, MI_WRITE_VALID_PTE, MiGetNextPhysicalPage(), MiGetPdeAddress, MiGetPteAddress, MiIsPteOnPdeBoundary, MiIsPteOnPpeBoundary, MM_PTE_EXECUTE, PAGE_SHIFT, PAGE_SIZE, ROUND_TO_PAGES, TRUE, _MMPTE::u, and ValidKernelPte.

02096 : 02097 02098 This function builds page ables for loader loaded drivers. 02099 02100 Arguments: 02101 02102 LoaderBlock - Supplies the address of the loader block. 02103 02104 Return Value: 02105 02106 None. 02107 02108 --*/ 02109 { 02110 PMMPTE StartPte; 02111 PMMPTE EndPte; 02112 PMMPTE StartPde; 02113 PMMPTE StartPpe; 02114 MMPTE TempPte; 02115 ULONG First; 02116 ULONG_PTR i; 02117 PLIST_ENTRY NextEntry; 02118 ULONG NumberOfLoaderPtes; 02119 PFN_NUMBER NextPhysicalPage; 02120 PVOID Va; 02121 PLDR_DATA_TABLE_ENTRY DataTableEntry; 02122 02123 TempPte = ValidKernelPte; 02124 TempPte.u.Long |= MM_PTE_EXECUTE; 02125 02126 i = 0; 02127 NextEntry = LoaderBlock->LoadOrderListHead.Flink; 02128 02129 for ( ; NextEntry != &LoaderBlock->LoadOrderListHead; NextEntry = NextEntry->Flink) { 02130 02131 // 02132 // As it is mapped through the translation registers, skip the kernel. 02133 // 02134 02135 i += 1; 02136 if (i <= 1) { 02137 continue; 02138 } 02139 02140 DataTableEntry = CONTAINING_RECORD(NextEntry, 02141 LDR_DATA_TABLE_ENTRY, 02142 InLoadOrderLinks); 02143 02144 NumberOfLoaderPtes = (ULONG)((ROUND_TO_PAGES(DataTableEntry->SizeOfImage)) >> PAGE_SHIFT); 02145 02146 Va = DataTableEntry->DllBase; 02147 StartPte = MiGetPteAddress(Va); 02148 EndPte = StartPte + NumberOfLoaderPtes; 02149 02150 First = TRUE; 02151 02152 while (StartPte <= EndPte) { 02153 02154 if (First == TRUE || MiIsPteOnPpeBoundary(StartPte)) { 02155 StartPpe = MiGetPdeAddress(StartPte); 02156 if (StartPpe->u.Hard.Valid == 0) { 02157 ASSERT (StartPpe->u.Long == 0); 02158 NextPhysicalPage = MiGetNextPhysicalPage(); 02159 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE); 02160 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 02161 MI_WRITE_VALID_PTE(StartPpe, TempPte); 02162 } 02163 } 02164 02165 if ((First == TRUE) || MiIsPteOnPdeBoundary(StartPte)) { 02166 First = FALSE; 02167 StartPde = MiGetPteAddress(StartPte); 02168 if (StartPde->u.Hard.Valid == 0) { 02169 NextPhysicalPage = MiGetNextPhysicalPage(); 02170 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE); 02171 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 02172 MI_WRITE_VALID_PTE(StartPde, TempPte); 02173 } 02174 } 02175 02176 TempPte.u.Hard.PageFrameNumber = MI_CONVERT_PHYSICAL_TO_PFN(Va); 02177 MI_WRITE_VALID_PTE (StartPte, TempPte); 02178 StartPte += 1; 02179 Va = (PVOID)((ULONG_PTR)Va + PAGE_SIZE); 02180 } 02181 } 02182 }

VOID MiBuildPageTableForLoaderMemory IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 2229 of file mm/ia64/initia64.c.

References ASSERT, _MEMORY_ALLOCATION_DESCRIPTOR::BasePage, FALSE, LoaderBootDriver, LoaderHalCode, LoaderMemoryData, LoaderNlsData, LoaderOsloaderHeap, LoaderRegistryData, LoaderStartupDpcStack, LoaderStartupKernelStack, LoaderStartupPanicStack, LoaderStartupPdrPage, LoaderSystemCode, _MEMORY_ALLOCATION_DESCRIPTOR::MemoryType, MI_WRITE_VALID_PTE, MiConvertToLoaderVirtual(), MiGetNextPhysicalPage(), MiGetPdeAddress, MiGetPteAddress, MiIsPteOnPdeBoundary, MiIsPteOnPpeBoundary, PAGE_SIZE, _MEMORY_ALLOCATION_DESCRIPTOR::PageCount, TRUE, _MMPTE::u, and ValidKernelPte.

Referenced by MiInitMachineDependent().

02234 : 02235 02236 This function builds page ables for loader loaded drivers and loader 02237 allocated memory. 02238 02239 Arguments: 02240 02241 LoaderBlock - Supplies the address of the loader block. 02242 02243 Return Value: 02244 02245 None. 02246 02247 --*/ 02248 { 02249 PMMPTE StartPte; 02250 PMMPTE EndPte; 02251 PMMPTE StartPde; 02252 PMMPTE StartPpe; 02253 MMPTE TempPte; 02254 ULONG First; 02255 PLIST_ENTRY NextEntry; 02256 PFN_NUMBER NextPhysicalPage; 02257 PVOID Va; 02258 PFN_NUMBER PfnNumber; 02259 PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor; 02260 02261 TempPte = ValidKernelPte; 02262 NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink; 02263 02264 for ( ; NextEntry != &LoaderBlock->MemoryDescriptorListHead; NextEntry = NextEntry->Flink) { 02265 02266 MemoryDescriptor = CONTAINING_RECORD(NextEntry, 02267 MEMORY_ALLOCATION_DESCRIPTOR, 02268 ListEntry); 02269 02270 if ((MemoryDescriptor->MemoryType == LoaderOsloaderHeap) || 02271 (MemoryDescriptor->MemoryType == LoaderRegistryData) || 02272 (MemoryDescriptor->MemoryType == LoaderNlsData) || 02273 (MemoryDescriptor->MemoryType == LoaderStartupDpcStack) || 02274 (MemoryDescriptor->MemoryType == LoaderStartupKernelStack) || 02275 (MemoryDescriptor->MemoryType == LoaderStartupPanicStack) || 02276 (MemoryDescriptor->MemoryType == LoaderStartupPdrPage) || 02277 (MemoryDescriptor->MemoryType == LoaderMemoryData)) { 02278 02279 TempPte.u.Hard.Execute = 0; 02280 02281 } else if ((MemoryDescriptor->MemoryType == LoaderSystemCode) || 02282 (MemoryDescriptor->MemoryType == LoaderHalCode) || 02283 (MemoryDescriptor->MemoryType == LoaderBootDriver) || 02284 (MemoryDescriptor->MemoryType == LoaderStartupDpcStack)) { 02285 02286 TempPte.u.Hard.Execute = 1; 02287 02288 } else { 02289 02290 continue; 02291 02292 } 02293 02294 PfnNumber = MemoryDescriptor->BasePage; 02295 Va = MiConvertToLoaderVirtual(MemoryDescriptor->BasePage, LoaderBlock); 02296 02297 StartPte = MiGetPteAddress(Va); 02298 EndPte = StartPte + MemoryDescriptor->PageCount; 02299 02300 First = TRUE; 02301 02302 while (StartPte <= EndPte) { 02303 02304 if (First == TRUE || MiIsPteOnPpeBoundary(StartPte)) { 02305 StartPpe = MiGetPdeAddress(StartPte); 02306 if (StartPpe->u.Hard.Valid == 0) { 02307 ASSERT (StartPpe->u.Long == 0); 02308 NextPhysicalPage = MiGetNextPhysicalPage(); 02309 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE); 02310 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 02311 MI_WRITE_VALID_PTE(StartPpe, TempPte); 02312 } 02313 } 02314 02315 if ((First == TRUE) || MiIsPteOnPdeBoundary(StartPte)) { 02316 First = FALSE; 02317 StartPde = MiGetPteAddress(StartPte); 02318 if (StartPde->u.Hard.Valid == 0) { 02319 NextPhysicalPage = MiGetNextPhysicalPage(); 02320 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE); 02321 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 02322 MI_WRITE_VALID_PTE(StartPde, TempPte); 02323 } 02324 } 02325 02326 TempPte.u.Hard.PageFrameNumber = PfnNumber; 02327 MI_WRITE_VALID_PTE (StartPte, TempPte); 02328 StartPte += 1; 02329 PfnNumber += 1; 02330 Va = (PVOID)((ULONG_PTR)Va + PAGE_SIZE); 02331 } 02332 } 02333 }

VOID MiCheckMemoryDescriptorList IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 2394 of file mm/ia64/initia64.c.

References _MEMORY_ALLOCATION_DESCRIPTOR::BasePage, DbgPrint, LoaderFirmwareTemporary, LoaderSpecialMemory, LoaderSystemBlock, _MEMORY_ALLOCATION_DESCRIPTOR::MemoryType, MiNtoskrnlPageShift, MiNtoskrnlPhysicalBase, MiPrintMemoryDescriptors, NULL, PAGE_SHIFT, and _MEMORY_ALLOCATION_DESCRIPTOR::PageCount.

Referenced by MiInitMachineDependent().

02397 { 02398 PFN_NUMBER KernelStart; 02399 PFN_NUMBER KernelEnd; 02400 ULONG_PTR PageSize; 02401 PLIST_ENTRY NextEntry; 02402 PLIST_ENTRY PreviousEntry; 02403 PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor; 02404 PMEMORY_ALLOCATION_DESCRIPTOR PreviousMemoryDescriptor; 02405 02406 02407 KernelStart = MiNtoskrnlPhysicalBase >> PAGE_SHIFT; 02408 PageSize = (ULONG_PTR)1 << MiNtoskrnlPageShift; 02409 KernelEnd = KernelStart + (PageSize >> PAGE_SHIFT); 02410 02411 PreviousMemoryDescriptor = NULL; 02412 PreviousEntry = NULL; 02413 02414 NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink; 02415 02416 for ( ; NextEntry != &LoaderBlock->MemoryDescriptorListHead; NextEntry = NextEntry->Flink) { 02417 02418 MemoryDescriptor = CONTAINING_RECORD(NextEntry, 02419 MEMORY_ALLOCATION_DESCRIPTOR, 02420 ListEntry); 02421 02422 #if DBG 02423 if (MiPrintMemoryDescriptors) { 02424 DbgPrint("MemoryType = %x\n", MemoryDescriptor->MemoryType); 02425 DbgPrint("BasePage = %p\n", (PFN_NUMBER)MemoryDescriptor->BasePage << PAGE_SHIFT); 02426 DbgPrint("PageCount = %x\n\n", MemoryDescriptor->PageCount << PAGE_SHIFT); 02427 } 02428 #endif 02429 if ((MemoryDescriptor->BasePage >= KernelStart) && 02430 (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount <= KernelEnd)) { 02431 02432 if (MemoryDescriptor->MemoryType == LoaderSystemBlock) { 02433 02434 MemoryDescriptor->MemoryType = LoaderFirmwareTemporary; 02435 02436 } else if (MemoryDescriptor->MemoryType == LoaderSpecialMemory) { 02437 02438 MemoryDescriptor->MemoryType = LoaderFirmwareTemporary; 02439 02440 } 02441 } 02442 02443 02444 if ((PreviousMemoryDescriptor != NULL) && 02445 (MemoryDescriptor->MemoryType == PreviousMemoryDescriptor->MemoryType) && 02446 (MemoryDescriptor->BasePage == 02447 (PreviousMemoryDescriptor->BasePage + PreviousMemoryDescriptor->PageCount))) { 02448 02449 PreviousMemoryDescriptor->PageCount += MemoryDescriptor->PageCount; 02450 PreviousEntry->Flink = NextEntry->Flink; 02451 02452 } else { 02453 02454 PreviousMemoryDescriptor = MemoryDescriptor; 02455 PreviousEntry = NextEntry; 02456 02457 } 02458 02459 } 02460 02461 }

VOID MiConvertBackToStandardPages IN PVOID  StartVirtual,
IN PVOID  EndVirtual
 

Definition at line 1995 of file mm/ia64/initia64.c.

References MI_WRITE_VALID_PTE, MiGetPteAddress, PAGE_ALIGN, PAGE_SIZE, and _MMPTE::u.

02001 : 02002 02003 This function disables the use of the super pages. 02004 02005 Arguments: 02006 02007 StartVirtual - the start address of the region of pages to disable super pages. 02008 super pages. 02009 02010 EndVirtual - the end address of the region of pages to disable super pages. 02011 02012 Return Value: 02013 02014 None. 02015 02016 --*/ 02017 { 02018 ULONG_PTR VirtualAddress; 02019 ULONG_PTR i; 02020 ULONG_PTR NumberOfPte; 02021 PMMPTE StartPte; 02022 MMPTE TempPte; 02023 02024 VirtualAddress = (ULONG_PTR) PAGE_ALIGN(StartVirtual); 02025 02026 StartPte = MiGetPteAddress(VirtualAddress); 02027 02028 while (VirtualAddress <= (ULONG_PTR)EndVirtual) { 02029 02030 TempPte = *StartPte; 02031 TempPte.u.Large.PageSize = 0; 02032 TempPte.u.Large.PageSize = 0; 02033 TempPte.u.Hard.Valid = 1; 02034 MI_WRITE_VALID_PTE (StartPte, TempPte); 02035 02036 StartPte += 1; 02037 VirtualAddress += PAGE_SIZE; 02038 } 02039 }

PVOID MiConvertToLoaderVirtual IN PFN_NUMBER  Page,
IN PLOADER_PARAMETER_BLOCK  LoaderBlock
 

Definition at line 2185 of file mm/ia64/initia64.c.

References KeBugCheckEx(), and PAGE_SHIFT.

Referenced by MiBuildPageTableForLoaderMemory().

02189 { 02190 ULONG_PTR PageAddress = Page << PAGE_SHIFT; 02191 PTR_INFO ItrInfo = &LoaderBlock->u.Ia64.ItrInfo[0]; 02192 02193 02194 if ((PageAddress >= ItrInfo[ITR_KERNEL_INDEX].PhysicalAddress) && 02195 (PageAddress <= ItrInfo[ITR_KERNEL_INDEX].PhysicalAddress + 02196 ((ULONG_PTR)1 << ItrInfo[ITR_KERNEL_INDEX].PageSize))) { 02197 02198 return (PVOID)(ItrInfo[ITR_KERNEL_INDEX].VirtualAddress + 02199 (PageAddress - ItrInfo[ITR_KERNEL_INDEX].PhysicalAddress)); 02200 02201 } else if ((PageAddress >= ItrInfo[ITR_DRIVER0_INDEX].PhysicalAddress) && 02202 (PageAddress <= ItrInfo[ITR_DRIVER0_INDEX].PhysicalAddress + 02203 ((ULONG_PTR)1 << ItrInfo[ITR_DRIVER0_INDEX].PageSize))) { 02204 02205 return (PVOID)(ItrInfo[ITR_DRIVER0_INDEX].VirtualAddress + 02206 (PageAddress - ItrInfo[ITR_DRIVER0_INDEX].PhysicalAddress)); 02207 02208 } else if ((PageAddress >= ItrInfo[ITR_DRIVER1_INDEX].PhysicalAddress) && 02209 (PageAddress <= ItrInfo[ITR_DRIVER1_INDEX].PhysicalAddress + 02210 ((ULONG_PTR)1 << ItrInfo[ITR_DRIVER1_INDEX].PageSize))) { 02211 02212 return (PVOID)(ItrInfo[ITR_DRIVER1_INDEX].VirtualAddress + 02213 (PageAddress - ItrInfo[ITR_DRIVER1_INDEX].PhysicalAddress)); 02214 02215 } else { 02216 02217 KeBugCheckEx (MEMORY_MANAGEMENT, 02218 0x01010101, 02219 PageAddress, 02220 (ULONG_PTR)&ItrInfo[0], 02221 (ULONG_PTR)LoaderBlock); 02222 02223 return 0; 02224 } 02225 }

VOID MiConvertToSuperPages IN PVOID  StartVirtual,
IN PVOID  EndVirtual,
IN SIZE_T  PageSize,
IN ULONG  PageShift
 

Definition at line 1921 of file mm/ia64/initia64.c.

References MiGetPteAddress, PAGE_ALIGN, PAGE_SHIFT, PAGE_SIZE, and _MMPTE::u.

Referenced by MiInitMachineDependent().

01929 : 01930 01931 This function makes contiguous non-paged memory use super pages rather than 01932 using page tables. 01933 01934 Arguments: 01935 01936 StartVirtual - the start address of the region of pages to be mapped by 01937 super pages. 01938 01939 EndVirtual - the end address of the region of pages to be mapped by super 01940 pages. 01941 01942 Page Size - the page size to be used by the super page. 01943 01944 Page Shift - the page shift count to be used by the super page. 01945 01946 Return Value: 01947 01948 None. 01949 01950 --*/ 01951 { 01952 ULONG_PTR VirtualAddress; 01953 ULONG_PTR i; 01954 ULONG_PTR NumberOfPte; 01955 PMMPTE StartPte; 01956 01957 VirtualAddress = (ULONG_PTR) PAGE_ALIGN(StartVirtual); 01958 i = VirtualAddress & (PageSize - 1); 01959 01960 if (i != 0) { 01961 01962 VirtualAddress = (VirtualAddress + PageSize - 1) & ~(PageSize - 1); 01963 01964 } 01965 01966 StartPte = MiGetPteAddress(VirtualAddress); 01967 NumberOfPte = PageSize >> PAGE_SHIFT; 01968 01969 i = 0; 01970 01971 while (VirtualAddress <= (ULONG_PTR)EndVirtual) { 01972 01973 if (i == NumberOfPte) { 01974 01975 StartPte -= NumberOfPte; 01976 01977 for (i = 0; i < NumberOfPte; i++) { 01978 01979 StartPte->u.Hard.Valid = 0; 01980 StartPte->u.Large.LargePage = 1; 01981 StartPte->u.Large.PageSize = PageShift; 01982 StartPte += 1; 01983 } 01984 01985 i = 0; 01986 } 01987 01988 i += 1; 01989 StartPte += 1; 01990 VirtualAddress += PAGE_SIZE; 01991 } 01992 }

VOID MiConvertToSuperPages PVOID  StartVirtual,
PVOID  EndVirtual,
SIZE_T  PageSize,
ULONG  PageShift
 

BOOLEAN MiEnsureAvailablePagesInFreeDescriptor IN PFN_NUMBER  Pages,
IN PFN_NUMBER  MaxPage
 

Definition at line 225 of file mm/ia64/initia64.c.

References _MEMORY_ALLOCATION_DESCRIPTOR::BasePage, FALSE, KeBugCheckEx(), MiFreeDescriptor, MiFreeDescriptorLargest, MiFreeDescriptorLowMem, MiFreeDescriptorNonPaged, MiNextPhysicalPage, MiNumberOfPages, MiOldFreeDescriptorBase, MiOldFreeDescriptorCount, MmHighestPhysicalPage, MmLowestPhysicalPage, MmNumberOfPhysicalPages, _MEMORY_ALLOCATION_DESCRIPTOR::PageCount, and TRUE.

Referenced by MiInitMachineDependent().

00229 { 00230 if ((MiNumberOfPages < Pages) && 00231 (MiFreeDescriptor == MiFreeDescriptorNonPaged)) { 00232 00233 MiFreeDescriptor->BasePage = (ULONG)MiNextPhysicalPage; 00234 MiFreeDescriptor->PageCount = (PFN_COUNT)MiNumberOfPages; 00235 00236 if (MiFreeDescriptor != MiFreeDescriptorLowMem) { 00237 00238 MiOldFreeDescriptorCount = MiFreeDescriptorLowMem->PageCount; 00239 MiOldFreeDescriptorBase = MiFreeDescriptorLowMem->BasePage; 00240 00241 MiFreeDescriptor = MiFreeDescriptorLowMem; 00242 MiNumberOfPages = MiFreeDescriptorLowMem->PageCount; 00243 MiNextPhysicalPage = MiFreeDescriptorLowMem->BasePage; 00244 00245 } else if (MiFreeDescriptor != MiFreeDescriptorLargest) { 00246 00247 MiOldFreeDescriptorCount = MiFreeDescriptorLargest->PageCount; 00248 MiOldFreeDescriptorBase = MiFreeDescriptorLargest->BasePage; 00249 00250 MiFreeDescriptor = MiFreeDescriptorLargest; 00251 MiNumberOfPages = MiFreeDescriptorLargest->PageCount; 00252 MiNextPhysicalPage = MiFreeDescriptorLargest->BasePage; 00253 00254 } else { 00255 00256 KeBugCheckEx(INSTALL_MORE_MEMORY, 00257 MmNumberOfPhysicalPages, 00258 MmLowestPhysicalPage, 00259 MmHighestPhysicalPage, 00260 1); 00261 } 00262 } 00263 00264 if (MaxPage < (MiFreeDescriptor->BasePage + Pages)) { 00265 00266 return FALSE; 00267 00268 } else { 00269 00270 return TRUE; 00271 00272 } 00273 }

PVOID MiGetKSegAddress PFN_NUMBER  FrameNumber  ) 
 

Definition at line 1871 of file mm/ia64/initia64.c.

References ASSERT, MI_WRITE_VALID_PTE, MiGetKSegPteAddress, MmHighestPhysicalPage, PAGE_SHIFT, _MMPTE::u, ValidKernelPte, and Virtual.

01876 : 01877 01878 This function returns the KSEG3 address which maps the given physical page. 01879 01880 Arguments: 01881 01882 FrameNumber - Supplies the physical page number to get the KSEG3 address for 01883 01884 Return Value: 01885 01886 Virtual address mapped in KSEG3 space 01887 01888 TBS 01889 01890 --*/ 01891 { 01892 PVOID Virtual; 01893 PMMPTE PointerPte; 01894 MMPTE TempPte; 01895 01896 ASSERT (FrameNumber <= MmHighestPhysicalPage); 01897 01898 Virtual = ((PVOID)(KSEG3_BASE | ((ULONG_PTR)(FrameNumber) << PAGE_SHIFT))); 01899 01900 #if defined(KSEG_VHPT) 01901 PointerPte = MiGetKSegPteAddress (Virtual); 01902 01903 if (PointerPte->u.Long == 0) { 01904 01905 // 01906 // if the VHPT entry for the KSEG3 address is still zero, build it here. 01907 // 01908 01909 TempPte = ValidKernelPte; 01910 TempPte.u.Hard.PageFrameNumber = FrameNumber; 01911 MI_WRITE_VALID_PTE(PointerPte, TempPte); 01912 01913 __mf(); 01914 } 01915 #endif 01916 01917 return (Virtual); 01918 }

PFN_NUMBER MiGetNextPhysicalPage VOID   ) 
 

Definition at line 139 of file mm/ia64/initia64.c.

References _MEMORY_ALLOCATION_DESCRIPTOR::BasePage, KeBugCheckEx(), MiFreeDescriptor, MiFreeDescriptorLargest, MiFreeDescriptorLowMem, MiFreeDescriptorNonPaged, MiNextPhysicalPage, MiNumberOfPages, MiOldFreeDescriptorBase, MiOldFreeDescriptorCount, MmHighestPhysicalPage, MmLowestPhysicalPage, MmNumberOfPhysicalPages, and _MEMORY_ALLOCATION_DESCRIPTOR::PageCount.

Referenced by MiBuildPageTableForDrivers(), MiBuildPageTableForLoaderMemory(), and MiInitMachineDependent().

00145 : 00146 00147 This function returns the next physical page number from either the 00148 largest low memory descritor or the largest free descriptor. If there 00149 are no physical pages left, then a bugcheck is executed since the 00150 system cannot be initialized. 00151 00152 Arguments: 00153 00154 LoaderBlock - Supplies the address of the loader block. 00155 00156 Return Value: 00157 00158 None. 00159 00160 Environment: 00161 00162 Kernel mode. 00163 00164 --*/ 00165 00166 { 00167 00168 // 00169 // If there are free pages left in the current descriptor, then 00170 // return the next physical page. Otherwise, attempt to switch 00171 // descriptors. 00172 // 00173 00174 if (MiNumberOfPages != 0) { 00175 MiNumberOfPages -= 1; 00176 return MiNextPhysicalPage++; 00177 00178 } else { 00179 00180 // 00181 // If the current descriptor is not the largest free descriptor, 00182 // then switch to the largest free descriptor. Otherwise, bugcheck. 00183 // 00184 00185 if (MiFreeDescriptor == MiFreeDescriptorLargest) { 00186 00187 KeBugCheckEx(INSTALL_MORE_MEMORY, 00188 MmNumberOfPhysicalPages, 00189 MmLowestPhysicalPage, 00190 MmHighestPhysicalPage, 00191 0); 00192 00193 return 0; 00194 00195 } else if (MiFreeDescriptor == MiFreeDescriptorLowMem) { 00196 00197 MiOldFreeDescriptorCount = MiFreeDescriptorLargest->PageCount; 00198 MiOldFreeDescriptorBase = MiFreeDescriptorLargest->BasePage; 00199 00200 MiFreeDescriptor = MiFreeDescriptorLargest; 00201 MiNumberOfPages = MiFreeDescriptorLargest->PageCount - 1; 00202 MiNextPhysicalPage = MiFreeDescriptorLargest->BasePage; 00203 00204 MiFreeDescriptorLowMem->PageCount = 0; 00205 00206 return MiNextPhysicalPage++; 00207 00208 } else { 00209 00210 MiOldFreeDescriptorCount = MiFreeDescriptorLowMem->PageCount; 00211 MiOldFreeDescriptorBase = MiFreeDescriptorLowMem->BasePage; 00212 00213 MiFreeDescriptor = MiFreeDescriptorLowMem; 00214 MiNumberOfPages = MiFreeDescriptorLowMem->PageCount - 1; 00215 MiNextPhysicalPage = MiFreeDescriptorLowMem->BasePage; 00216 00217 MiFreeDescriptorNonPaged->PageCount = 0; 00218 00219 return MiNextPhysicalPage++; 00220 } 00221 } 00222 }

VOID MiInitMachineDependent IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 277 of file mm/ia64/initia64.c.

References _x16mb, _x16mbnp, _x1mb, _x1mbnp, _x256mb, _x256mbnp, _x4gbnp, _x4mb, _x64mb, ActiveAndValid, ASSERT, BadPageList, _MEMORY_ALLOCATION_DESCRIPTOR::BasePage, _MMPFNLIST::Blink, BYTES_TO_PAGES, c, DbgPrint, ExAllocatePoolWithTag, FALSE, FIRST_MAPPING_PTE, _MMPFNLIST::Flink, _MMCOLOR_TABLES::Flink, FreePageList, HYPER_SPACE, HYPER_SPACE_END, InitializationPhase, INITIALIZE_DIRECTORY_TABLE_BASE, InitializePool(), KeBugCheckEx(), KeFlushCurrentTb(), KeInitializeSpinLock(), KeInitializeVhpt(), KSEG0_ADDRESS, KSEG0_BASE, LAST_MAPPING_PTE, _MEMORY_ALLOCATION_DESCRIPTOR::ListEntry, _MMPFNLIST::ListName, LoaderBad, LoaderFirmwareTemporary, LoaderFree, LoaderLoadedProgram, LoaderOsloaderStack, _MMSUPPORT::MaximumWorkingSetSize, _MEMORY_ALLOCATION_DESCRIPTOR::MemoryType, MI_CONVERT_PHYSICAL_TO_PFN, MI_GET_COLOR_FROM_SECONDARY, MI_GET_PAGE_COLOR_FROM_PTE, MI_GET_PAGE_FRAME_FROM_PTE, MI_IS_PHYSICAL_ADDRESS, MI_PFN_ELEMENT, MI_SET_PFN_DELETED, MI_WRITE_INVALID_PTE, MI_WRITE_VALID_PTE, MiBuildPageTableForLoaderMemory(), MiCheckMemoryDescriptorList(), MiConvertToSuperPages(), MiDecrementReferenceCount(), MiEnsureAvailablePagesInFreeDescriptor(), MiFreeDescriptor, MiFreeDescriptorLargest, MiFreeDescriptorLowMem, MiFreeDescriptorNonPaged, MiGetKSegPteAddress, MiGetNextPhysicalPage(), MiGetPdeAddress, MiGetPpeAddress, MiGetPteAddress, MiGetVirtualAddressMappedByPte, MiImplVirtualMsb, MiInitializeNonPagedPool(), MiInitializeSystemPtes(), MiInsertPageInList(), MiIsPteOnPdeBoundary, MiIsPteOnPpeBoundary, MiKseg0End, MiKseg0Mapping, MiKseg0Start, MiMakeKernelPagesPermanent(), MiNextPhysicalPage, _MMSUPPORT::MinimumWorkingSetSize, MiNtoskrnlPageShift, MiNtoskrnlPhysicalBase, MiNtoskrnlVirtualBase, MiNumberOfPages, MiOldFreeDescriptorBase, MiOldFreeDescriptorCount, MiPrintMemoryDescriptors, MiRemoveAnyPage(), MiRemoveLoaderSuperPages(), MiSystemSelfMappedPte, MiUserSelfMappedPte, MiWasteEnd, MiWasteStart, MM_CRASH_DUMP_VA, MM_DEBUG_VA, MM_EMPTY_LIST, MM_LOWEST_NONPAGED_SYSTEM_START, MM_MAX_ADDITIONAL_NONPAGED_POOL, MM_MAX_INITIAL_NONPAGED_POOL, MM_MAXIMUM_NUMBER_OF_COLORS, MM_PAGES_IN_KSEG0, MM_PFN_DATABASE_START, MM_PTE_16MB_PAGE, MM_PTE_1MB_PAGE, MM_PTE_256MB_PAGE, MM_PTE_4MB_PAGE, MM_PTE_64MB_PAGE, MM_SECONDARY_COLORS_DEFAULT, MM_SECONDARY_COLORS_MAX, MM_SECONDARY_COLORS_MIN, MM_SYSTEM_SPACE_END, MMCOLOR_TABLES, MmCrashDumpPte, MmDebugPte, MmDefaultMaximumNonPagedPool, MmFirstReservedMappingPte, MmFreePagesByColor, MmFreePagesByPrimaryColor, MmHighestPhysicalPage, MmHighestPossiblePhysicalPage, MmInitializeProcessAddressSpace(), MmKseg3VhptBase, MmKseg3VhptPs, MmLastReservedMappingPte, MmLowestPhysicalPage, MmMaxAdditionNonPagedPoolPerMb, MmMaximumNonPagedPoolInBytes, MmMinAdditionNonPagedPoolPerMb, MmMinimumNonPagedPoolSize, MmNonPagedMustSucceed, MmNonPagedPoolEnd, MmNonPagedPoolExpansionStart, MmNonPagedPoolStart, MmNonPagedSystemStart, MmNumberOfPhysicalPages, MmNumberOfSystemPtes, MmPageAlignedPoolBase, MmPageLocationList, MmPfnDatabase, MmPfnLock, MmSecondaryColorMask, MmSecondaryColors, MmSizeOfNonPagedMustSucceed, MmSizeOfNonPagedPoolInBytes, MmSubsectionBase, MmSubsectionTopPage, MmSystemParentTablePage, MmSystemProcessWorkingSetMax, MmSystemProcessWorkingSetMin, MmSystemSpaceLock, MmWorkingSetList, MmWsle, NonPagedPool, NonPagedPoolMustSucceed, NULL, PAGE_ALIGN, PAGE_DIRECTORY2_MASK, PAGE_SHIFT, PAGE_SIZE, _MEMORY_ALLOCATION_DESCRIPTOR::PageCount, PDE_KTBASE, PsGetCurrentProcess, PTE_PER_PAGE, PTE_SHIFT, _MMPFN::PteAddress, _MMPFN::PteFrame, RtlCompareMemoryUlong(), StandbyPageList, SystemPteSpace, TRUE, _MMPTE::u, _MMPFN::u2, _MMPFN::u3, ValidKernelPte, ValidPdePde, _EPROCESS::Vm, WORKING_SET_LIST, _EPROCESS::WorkingSetPage, X64K, ZeroedPageList, and ZeroKernelPte.

00283 : 00284 00285 This routine performs the necessary operations to enable virtual 00286 memory. This includes building the page directory page, building 00287 page table pages to map the code section, the data section, the' 00288 stack section and the trap handler. 00289 00290 It also initializes the PFN database and populates the free list. 00291 00292 00293 Arguments: 00294 00295 LoaderBlock - Supplies a pointer to the firmware setup loader block. 00296 00297 Return Value: 00298 00299 None. 00300 00301 Environment: 00302 00303 Kernel mode. 00304 00305 --*/ 00306 00307 { 00308 PMMPFN BasePfn; 00309 PMMPFN BottomPfn; 00310 PMMPFN TopPfn; 00311 SIZE_T Range; 00312 PFN_NUMBER i; 00313 ULONG j; 00314 PFN_NUMBER PdePageNumber; 00315 PFN_NUMBER PdePage; 00316 PFN_NUMBER PageFrameIndex; 00317 PFN_NUMBER NextPhysicalPage; 00318 SPFN_NUMBER PfnAllocation; 00319 SPFN_NUMBER NumberOfPages; 00320 SIZE_T MaxPool; 00321 PEPROCESS CurrentProcess; 00322 PFN_NUMBER MostFreePage = 0; 00323 PFN_NUMBER MostFreeLowMem = 0; 00324 PFN_NUMBER MostFreeNonPaged = 0; 00325 PLIST_ENTRY NextMd; 00326 PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor; 00327 MMPTE TempPte; 00328 PMMPTE PointerPde; 00329 PMMPTE PointerPte; 00330 PMMPTE StartPte; 00331 PMMPTE LastPte; 00332 PMMPTE EndPte; 00333 PMMPTE Pde; 00334 PMMPTE StartPde; 00335 PMMPTE StartPpe; 00336 PMMPTE EndPde; 00337 PMMPTE FirstPpe; 00338 PMMPFN Pfn1; 00339 PMMPFN Pfn2; 00340 ULONG First; 00341 KIRQL OldIrql; 00342 ULONG_PTR va; 00343 SIZE_T Kseg0Size = 0; 00344 PVOID NonPagedPoolStartVirtual; 00345 ULONG i1; 00346 ULONG i2; 00347 PFN_NUMBER PhysicalPages; 00348 ULONG_PTR HighestPageAddress; 00349 ULONG_PTR Kseg3VhptSize; 00350 PFN_NUMBER Kseg3VhptPn; 00351 ULONG_PTR size; 00352 ULONG_PTR PageSize; 00353 PFN_NUMBER KernelStart; 00354 PFN_NUMBER KernelEnd; 00355 00356 if (InitializationPhase == 1) { 00357 00358 MiMakeKernelPagesPermanent(LoaderBlock); 00359 00360 return; 00361 00362 } 00363 00364 // 00365 // Initialize the kernel mapping info 00366 // 00367 00368 MiNtoskrnlPhysicalBase = LoaderBlock->u.Ia64.ItrInfo[ITR_KERNEL_INDEX].PhysicalAddress; 00369 MiNtoskrnlVirtualBase = LoaderBlock->u.Ia64.ItrInfo[ITR_KERNEL_INDEX].VirtualAddress; 00370 MiNtoskrnlPageShift = LoaderBlock->u.Ia64.ItrInfo[ITR_KERNEL_INDEX].PageSize; 00371 00372 KernelStart = MiNtoskrnlPhysicalBase >> PAGE_SHIFT; 00373 PageSize = (ULONG_PTR)1 << MiNtoskrnlPageShift; 00374 KernelEnd = KernelStart + (PageSize >> PAGE_SHIFT); 00375 00376 // 00377 // Initialize MmDebugPte and MmCrashDumpPte 00378 // 00379 00380 MmDebugPte = MiGetPteAddress(MM_DEBUG_VA); 00381 00382 MmCrashDumpPte = MiGetPteAddress(MM_CRASH_DUMP_VA); 00383 00384 // 00385 // Set TempPte to ValidKernelPte for the future use 00386 // 00387 00388 TempPte = ValidKernelPte; 00389 00390 // 00391 // Check the memory descriptor list from NT loader 00392 // 00393 00394 MiCheckMemoryDescriptorList(LoaderBlock); 00395 00396 00397 // 00398 // Get the lower bound of the free physical memory and the 00399 // number of physical pages by walking the memory descriptor lists. 00400 // 00401 00402 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink; 00403 00404 #if ADD_HIGH_MEMORY 00405 LoaderBlock->MemoryDescriptorListHead.Flink = &MiHighMemoryDescriptor.ListEntry; 00406 MiHighMemoryDescriptor.ListEntry.Flink = NextMd; 00407 MiHighMemoryDescriptor.MemoryType = 5; 00408 MiHighMemoryDescriptor.BasePage = 0x80000; 00409 MiHighMemoryDescriptor.PageCount = 0x20000; 00410 NextMd = &MiHighMemoryDescriptor.ListEntry; 00411 #endif 00412 00413 while (NextMd != &LoaderBlock->MemoryDescriptorListHead) { 00414 00415 MemoryDescriptor = CONTAINING_RECORD(NextMd, 00416 MEMORY_ALLOCATION_DESCRIPTOR, 00417 ListEntry); 00418 00419 // 00420 // This check results in /BURNMEMORY chunks not being counted. 00421 // 00422 00423 if (MemoryDescriptor->MemoryType != LoaderBad) { 00424 MmNumberOfPhysicalPages += MemoryDescriptor->PageCount; 00425 } 00426 00427 if (MemoryDescriptor->BasePage < MmLowestPhysicalPage) { 00428 MmLowestPhysicalPage = MemoryDescriptor->BasePage; 00429 } 00430 if ((MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) > 00431 MmHighestPhysicalPage) { 00432 MmHighestPhysicalPage = 00433 MemoryDescriptor->BasePage + MemoryDescriptor->PageCount -1; 00434 } 00435 00436 // 00437 // We assume at this stage (Gambit Port) that the minimum memory requirement 00438 // for the iA EM is 32mb. There will be no memory hole right below the 16m 00439 // boundary on EM machines unlike some x86 of PC platforms. 00440 // 00441 00442 if ((MemoryDescriptor->MemoryType == LoaderFree) || 00443 (MemoryDescriptor->MemoryType == LoaderLoadedProgram) || 00444 (MemoryDescriptor->MemoryType == LoaderFirmwareTemporary) || 00445 (MemoryDescriptor->MemoryType == LoaderOsloaderStack)) { 00446 00447 if (MemoryDescriptor->PageCount > MostFreePage) { 00448 MostFreePage = MemoryDescriptor->PageCount; 00449 MiFreeDescriptorLargest = MemoryDescriptor; 00450 } 00451 00452 if (MemoryDescriptor->BasePage < _x256mbnp) { 00453 00454 // 00455 // This memory descriptor is below 16mb. 00456 // 00457 00458 if ((MostFreeLowMem < MemoryDescriptor->PageCount) && 00459 (MostFreeLowMem < _x256mbnp - MemoryDescriptor->BasePage)) { 00460 00461 MostFreeLowMem = _x256mbnp - MemoryDescriptor->BasePage; 00462 if (MemoryDescriptor->PageCount < MostFreeLowMem) { 00463 MostFreeLowMem = MemoryDescriptor->PageCount; 00464 } 00465 00466 MiFreeDescriptorLowMem = MemoryDescriptor; 00467 } 00468 } 00469 00470 if ((MemoryDescriptor->BasePage >= KernelStart) && 00471 (MemoryDescriptor->PageCount > MostFreeNonPaged)) { 00472 00473 MostFreeNonPaged = MemoryDescriptor->PageCount; 00474 MiFreeDescriptorNonPaged = MemoryDescriptor; 00475 00476 } 00477 00478 } 00479 00480 #if DBG 00481 if (MiPrintMemoryDescriptors) { 00482 DbgPrint("MemoryType = %x\n", MemoryDescriptor->MemoryType); 00483 DbgPrint("BasePage = %p\n", (PFN_NUMBER)MemoryDescriptor->BasePage << PAGE_SHIFT); 00484 DbgPrint("PageCount = %x\n\n", MemoryDescriptor->PageCount << PAGE_SHIFT); 00485 } 00486 #endif 00487 00488 NextMd = MemoryDescriptor->ListEntry.Flink; 00489 } 00490 00491 MmHighestPossiblePhysicalPage = MmHighestPhysicalPage; 00492 00493 // 00494 // If the number of physical pages is less than 16mb, then 00495 // bugcheck. There is not enough memory to run the system. 00496 // 00497 00498 if (MmNumberOfPhysicalPages < _x16mbnp) { 00499 KeBugCheckEx (INSTALL_MORE_MEMORY, 00500 MmNumberOfPhysicalPages, 00501 MmLowestPhysicalPage, 00502 MmHighestPhysicalPage, 00503 2); 00504 } 00505 00506 // 00507 // initialize the next page allocation variable & structures 00508 // 00509 00510 00511 if (MiFreeDescriptorNonPaged != NULL) { 00512 00513 MiFreeDescriptor = MiFreeDescriptorNonPaged; 00514 00515 } else if (MiFreeDescriptorLowMem != NULL) { 00516 00517 MiFreeDescriptor = MiFreeDescriptorLowMem; 00518 00519 } else { 00520 00521 MiFreeDescriptor = MiFreeDescriptorLargest; 00522 } 00523 00524 if (MiFreeDescriptorLowMem == NULL) { 00525 00526 MiKseg0Mapping = FALSE; 00527 00528 } 00529 00530 MiNextPhysicalPage = MiFreeDescriptor->BasePage; 00531 MiNumberOfPages = MiFreeDescriptor->PageCount; 00532 MiOldFreeDescriptorCount = MiFreeDescriptor->PageCount; 00533 MiOldFreeDescriptorBase = MiFreeDescriptor->BasePage; 00534 00535 // 00536 // Produce the size of the Kseg 0 space 00537 // 00538 00539 if (MiKseg0Mapping == TRUE) { 00540 00541 00542 MiKseg0Start = KSEG0_ADDRESS(MiNextPhysicalPage); 00543 00544 Kseg0Size = MiNextPhysicalPage + MiNumberOfPages; 00545 00546 if (Kseg0Size > MM_PAGES_IN_KSEG0) { 00547 Kseg0Size = MM_PAGES_IN_KSEG0 - (_x16mbnp * 3); 00548 } 00549 00550 Kseg0Size = Kseg0Size << PAGE_SHIFT; 00551 00552 } else { 00553 00554 MiKseg0Mapping = FALSE; 00555 Kseg0Size = 0; 00556 00557 } 00558 00559 // 00560 // Initialize VHPT registers 00561 // 00562 00563 KeInitializeVhpt ((PVOID)PTA_BASE, MiImplVirtualMsb - PAGE_SHIFT + PTE_SHIFT); 00564 00565 // 00566 // Build 1 to 1 virtual to physical mapping space 00567 // 00568 00569 #if defined(KSEG_VHPT) 00570 HighestPageAddress = ((ULONG_PTR)MmHighestPhysicalPage << PAGE_SHIFT); 00571 00572 HighestPageAddress = (HighestPageAddress + (ULONG_PTR)X64K - 1) & ~((ULONG_PTR)X64K - 1); 00573 00574 Kseg3VhptSize = HighestPageAddress >> 16 << PTE_SHIFT; 00575 00576 size = (Kseg3VhptSize-1) >> 12; // make the base page size 4KB 00577 PageSize = 12; 00578 00579 while (size != 0) { 00580 size = size >> 2; 00581 PageSize += 2; 00582 } 00583 00584 Kseg3VhptSize = (ULONG_PTR)1 << PageSize; 00585 00586 Kseg3VhptPages = (PFN_NUMBER)(Kseg3VhptSize >> PAGE_SHIFT); 00587 00588 if ((MiFreeDescriptor->BasePage & (_x16mbnp - 1)) != 0) { 00589 KeBugCheckEx (INSTALL_MORE_MEMORY, 00590 MmNumberOfPhysicalPages, 00591 MmLowestPhysicalPage, 00592 MmHighestPhysicalPage, 00593 3); 00594 } 00595 00596 MmKseg3VhptBase = MiNextPhysicalPage; 00597 MiNextPhysicalPage += Kseg3VhptPages; 00598 MiNumberOfPages -= Kseg3VhptPages; 00599 00600 if (MiNumberOfPages < 0) { 00601 00602 KeBugCheckEx(INSTALL_MORE_MEMORY, 00603 MmNumberOfPhysicalPages, 00604 MmLowestPhysicalPage, 00605 MmHighestPhysicalPage, 00606 4); 00607 } 00608 00609 #endif 00610 00611 // 00612 // Build a parent directory page table for the kernel space 00613 // 00614 00615 PdePageNumber = (PFN_NUMBER)LoaderBlock->u.Ia64.PdrPage; 00616 00617 MmSystemParentTablePage = MiGetNextPhysicalPage(); 00618 00619 RtlZeroMemory(KSEG_ADDRESS(MmSystemParentTablePage), PAGE_SIZE); 00620 00621 TempPte.u.Hard.PageFrameNumber = MmSystemParentTablePage; 00622 00623 MiSystemSelfMappedPte = TempPte; 00624 00625 KeFillFixedEntryTb((PHARDWARE_PTE)&TempPte, (PVOID)PDE_KTBASE, DTR_KTBASE_INDEX_TMP); 00626 00627 // 00628 // Install the self-mapped Ppe entry into the kernel parent directory table 00629 // 00630 00631 PointerPte = MiGetPteAddress(PDE_KTBASE); 00632 00633 MI_WRITE_VALID_PTE(PointerPte, TempPte); 00634 00635 // 00636 // Install the kernel image Ppe entry into the parent directory table 00637 // 00638 00639 PointerPte = MiGetPteAddress(PDE_KBASE); 00640 00641 TempPte.u.Hard.PageFrameNumber = PdePageNumber; 00642 00643 MI_WRITE_VALID_PTE(PointerPte, TempPte); 00644 00645 // 00646 // Build a parent directory page table for the user space 00647 // 00648 00649 NextPhysicalPage = MiGetNextPhysicalPage(); 00650 00651 RtlZeroMemory (KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE); 00652 00653 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 00654 00655 INITIALIZE_DIRECTORY_TABLE_BASE 00656 (&(PsGetCurrentProcess()->Pcb.DirectoryTableBase[0]), NextPhysicalPage); 00657 00658 MiUserSelfMappedPte = TempPte; 00659 00660 KeFillFixedEntryTb((PHARDWARE_PTE)&TempPte, (PVOID)PDE_UTBASE, DTR_UTBASE_INDEX_TMP); 00661 00662 // 00663 // Install the self-mapped entry into the user parent directory table 00664 // 00665 00666 PointerPte = MiGetPteAddress(PDE_UTBASE); 00667 00668 MI_WRITE_VALID_PTE(PointerPte, TempPte); 00669 00670 // 00671 // Build a parent directory page table for the hydra space 00672 // 00673 00674 NextPhysicalPage = MiGetNextPhysicalPage(); 00675 00676 RtlZeroMemory (KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE); 00677 00678 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 00679 00680 INITIALIZE_DIRECTORY_TABLE_BASE 00681 (&(PsGetCurrentProcess()->Pcb.SessionParentBase), NextPhysicalPage); 00682 00683 KeFillFixedEntryTb((PHARDWARE_PTE)&TempPte, (PVOID)PDE_STBASE, DTR_STBASE_INDEX); 00684 00685 // 00686 // Install the self-mapped entry into the hydra parent directory table 00687 // 00688 00689 PointerPte = MiGetPteAddress(PDE_STBASE); 00690 00691 MI_WRITE_VALID_PTE(PointerPte, TempPte); 00692 00693 // 00694 // Build Vhpt table for KSEG3 00695 // 00696 00697 #if defined(KSEG_VHPT) 00698 va = KSEG0_ADDRESS(MmKseg3VhptBase); 00699 00700 RtlZeroMemory((PVOID)va, Kseg3VhptSize); 00701 00702 TempPte.u.Hard.PageFrameNumber = MmKseg3VhptBase; 00703 00704 PointerPte = MiGetKSegPteAddress(KSEG3_BASE); 00705 00706 KeFillFixedLargeEntryTb((PHARDWARE_PTE)&TempPte, 00707 (PVOID)PointerPte, 00708 PageSize, 00709 DTR_KSEG3_INDEX); 00710 00711 MmKseg3VhptPs = PageSize; 00712 #endif 00713 00714 // 00715 // Build non-paged pool using the physical pages following the 00716 // data page in which to build the pool from. Non-page pool grows 00717 // from the high range of the virtual address space and expands 00718 // downward. 00719 // 00720 // At this time non-paged pool is constructed so virtual addresses 00721 // are also physically contiguous. 00722 // 00723 00724 if ((MmSizeOfNonPagedPoolInBytes >> PAGE_SHIFT) > 00725 (7 * (MmNumberOfPhysicalPages << 3))) { 00726 00727 // 00728 // More than 7/8 of memory allocated to nonpagedpool, reset to 0. 00729 // 00730 00731 MmSizeOfNonPagedPoolInBytes = 0; 00732 } 00733 00734 if (MmSizeOfNonPagedPoolInBytes < MmMinimumNonPagedPoolSize) { 00735 00736 // 00737 // Calculate the size of nonpaged pool. 00738 // Use the minimum size, then for every MB about 4mb add extra 00739 // pages. 00740 // 00741 00742 MmSizeOfNonPagedPoolInBytes = MmMinimumNonPagedPoolSize; 00743 00744 MmSizeOfNonPagedPoolInBytes += 00745 ((MmNumberOfPhysicalPages - _x16mbnp)/_x1mbnp) * 00746 MmMinAdditionNonPagedPoolPerMb; 00747 } 00748 00749 if (MmSizeOfNonPagedPoolInBytes > MM_MAX_INITIAL_NONPAGED_POOL) { 00750 MmSizeOfNonPagedPoolInBytes = MM_MAX_INITIAL_NONPAGED_POOL; 00751 } 00752 00753 // 00754 // Align to page size boundary. 00755 // 00756 00757 MmSizeOfNonPagedPoolInBytes &= ~(PAGE_SIZE - 1); 00758 00759 // 00760 // Calculate the maximum size of pool. 00761 // 00762 00763 if (MmMaximumNonPagedPoolInBytes == 0) { 00764 00765 // 00766 // Calculate the size of nonpaged pool. If 4mb of less use 00767 // the minimum size, then for every MB about 4mb add extra 00768 // pages. 00769 // 00770 00771 MmMaximumNonPagedPoolInBytes = MmDefaultMaximumNonPagedPool; 00772 00773 // 00774 // Make sure enough expansion for pfn database exists. 00775 // 00776 00777 MmMaximumNonPagedPoolInBytes += (MmHighestPhysicalPage * sizeof(MMPFN)) & ~(PAGE_SIZE-1); 00778 00779 MmMaximumNonPagedPoolInBytes += 00780 ((MmNumberOfPhysicalPages - _x16mbnp)/_x1mbnp) * 00781 MmMaxAdditionNonPagedPoolPerMb; 00782 00783 } 00784 00785 MaxPool = MmSizeOfNonPagedPoolInBytes + PAGE_SIZE * 16 + 00786 ((MmHighestPhysicalPage * sizeof(MMPFN)) & ~(PAGE_SIZE -1)); 00787 00788 if (MmMaximumNonPagedPoolInBytes < MaxPool) { 00789 MmMaximumNonPagedPoolInBytes = MaxPool; 00790 } 00791 00792 if (MmMaximumNonPagedPoolInBytes > MM_MAX_ADDITIONAL_NONPAGED_POOL) { 00793 MmMaximumNonPagedPoolInBytes = MM_MAX_ADDITIONAL_NONPAGED_POOL; 00794 } 00795 00796 MmNonPagedPoolStart = (PVOID)((ULONG_PTR)MmNonPagedPoolEnd 00797 - MmMaximumNonPagedPoolInBytes); 00798 00799 MmNonPagedPoolStart = (PVOID)PAGE_ALIGN(MmNonPagedPoolStart); 00800 00801 MmPageAlignedPoolBase[NonPagedPool] = MmNonPagedPoolStart; 00802 00803 // 00804 // Calculate the starting PDE for the system PTE pool which is 00805 // right below the nonpaged pool. 00806 // 00807 00808 MmNonPagedSystemStart = (PVOID)(((ULONG_PTR)MmNonPagedPoolStart - 00809 ((MmNumberOfSystemPtes + 1) * PAGE_SIZE)) & 00810 (~PAGE_DIRECTORY2_MASK)); 00811 00812 if (MmNonPagedSystemStart < MM_LOWEST_NONPAGED_SYSTEM_START) { 00813 MmNonPagedSystemStart = MM_LOWEST_NONPAGED_SYSTEM_START; 00814 MmNumberOfSystemPtes = (ULONG)(((ULONG_PTR)MmNonPagedPoolStart - 00815 (ULONG_PTR)MmNonPagedSystemStart) >> PAGE_SHIFT)-1; 00816 ASSERT (MmNumberOfSystemPtes > 1000); 00817 } 00818 00819 00820 // 00821 // Allocate a page directory and a pair of page table pages. 00822 // Map the hyper space page directory page into the top level parent 00823 // directory & the hyper space page table page into the page directory 00824 // and map an additional page that will eventually be used for the 00825 // working set list. Page tables after the first two are set up later 00826 // on during individual process working set initialization. 00827 // 00828 // The working set list page will eventually be a part of hyper space. 00829 // It is mapped into the second level page directory page so it can be 00830 // zeroed and so it will be accounted for in the PFN database. Later 00831 // the page will be unmapped, and its page frame number captured in the 00832 // system process object. 00833 // 00834 00835 TempPte = ValidPdePde; 00836 StartPde = MiGetPdeAddress(HYPER_SPACE); 00837 StartPpe = MiGetPpeAddress(HYPER_SPACE); 00838 EndPde = StartPde; 00839 First = (StartPpe->u.Hard.Valid == 0) ? TRUE : FALSE; 00840 00841 while (StartPde <= EndPde) { 00842 00843 if (First == TRUE || MiIsPteOnPdeBoundary(StartPde)) { 00844 First = FALSE; 00845 StartPpe = MiGetPteAddress(StartPde); 00846 if (StartPpe->u.Hard.Valid == 0) { 00847 ASSERT (StartPpe->u.Long == 0); 00848 NextPhysicalPage = MiGetNextPhysicalPage(); 00849 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE); 00850 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 00851 MI_WRITE_VALID_PTE(StartPpe, TempPte); 00852 } 00853 } 00854 NextPhysicalPage = MiGetNextPhysicalPage(); 00855 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE); 00856 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 00857 MI_WRITE_VALID_PTE(StartPde, TempPte); 00858 StartPde += 1; 00859 } 00860 00861 // 00862 // Allocate page directory and page table pages for 00863 // system PTEs and nonpaged pool. 00864 // 00865 00866 TempPte = ValidKernelPte; 00867 StartPde = MiGetPdeAddress(MmNonPagedSystemStart); 00868 StartPpe = MiGetPpeAddress(MmNonPagedSystemStart); 00869 EndPde = MiGetPdeAddress((ULONG_PTR)MmNonPagedPoolEnd - 1); 00870 First = (StartPpe->u.Hard.Valid == 0) ? TRUE : FALSE; 00871 00872 while (StartPde <= EndPde) { 00873 00874 if (First == TRUE || MiIsPteOnPdeBoundary(StartPde)) { 00875 First = FALSE; 00876 StartPpe = MiGetPteAddress(StartPde); 00877 if (StartPpe->u.Hard.Valid == 0) { 00878 NextPhysicalPage = MiGetNextPhysicalPage(); 00879 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE); 00880 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 00881 MI_WRITE_VALID_PTE(StartPpe, TempPte); 00882 } 00883 } 00884 00885 if (StartPde->u.Hard.Valid == 0) { 00886 NextPhysicalPage = MiGetNextPhysicalPage(); 00887 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE); 00888 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 00889 MI_WRITE_VALID_PTE(StartPde, TempPte); 00890 } 00891 StartPde += 1; 00892 } 00893 00894 NonPagedPoolStartVirtual = MmNonPagedPoolStart; 00895 00896 // MiBuildPageTableForDrivers(LoaderBlock); 00897 00898 00899 MiBuildPageTableForLoaderMemory(LoaderBlock); 00900 00901 MiRemoveLoaderSuperPages(LoaderBlock); 00902 00903 // 00904 // remove the temporary super pages for the root page table pages, 00905 // and remap again with DTR_KTBASE_INDEX and DTR_UTBASE_INDEX. 00906 // 00907 00908 KiFlushFixedDataTb(FALSE, (PVOID)PDE_KTBASE); 00909 KiFlushFixedDataTb(FALSE, (PVOID)PDE_UTBASE); 00910 KeFillFixedEntryTb((PHARDWARE_PTE)&MiSystemSelfMappedPte, (PVOID)PDE_KTBASE, DTR_KTBASE_INDEX); 00911 KeFillFixedEntryTb((PHARDWARE_PTE)&MiUserSelfMappedPte, (PVOID)PDE_UTBASE, DTR_UTBASE_INDEX); 00912 00913 if (MiKseg0Mapping == TRUE) { 00914 00915 // 00916 // Fill the PDEs for KSEG0 space 00917 // 00918 00919 StartPde = MiGetPdeAddress(MiKseg0Start); 00920 EndPde = MiGetPdeAddress((PCHAR)KSEG0_BASE + Kseg0Size); 00921 00922 while (StartPde <= EndPde) { 00923 00924 if (StartPde->u.Hard.Valid == 0) { 00925 NextPhysicalPage = MiGetNextPhysicalPage(); 00926 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE); 00927 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 00928 MI_WRITE_VALID_PTE(StartPde, TempPte); 00929 } 00930 StartPde++; 00931 } 00932 } 00933 00934 // 00935 // Initial NonPagedPool allocation priorities 00936 // 00937 // 1. allocate pages from 16mb kernel image maping space and use the 16mb super page 00938 // addresses 00939 // 2. allocate pages from low memory space ( < 256mb) and use the KSEG0 addresses 00940 // 3. allocate pages from the largest free memory descriptor list and use 00941 // MM_NON_PAGED_POOL addresses. 00942 // 00943 00944 if (MiKseg0Mapping == TRUE) { 00945 00946 // 00947 // When KiKseg0Mapping is enabled, check to see if 00948 // 00949 00950 MiKseg0Mapping = 00951 MiEnsureAvailablePagesInFreeDescriptor(BYTES_TO_PAGES(MmSizeOfNonPagedPoolInBytes), 00952 MM_PAGES_IN_KSEG0); 00953 00954 } 00955 00956 // 00957 // Fill in the PTEs to cover the initial nonpaged pool. The physical 00958 // page frames to cover this range were reserved earlier from the 00959 // largest low memory free descriptor. The initial allocation is both 00960 // physically and virtually contiguous. 00961 // 00962 00963 PointerPte = MiGetPteAddress(MmNonPagedPoolStart); 00964 LastPte = MiGetPteAddress((PCHAR)MmNonPagedPoolStart + 00965 MmSizeOfNonPagedPoolInBytes - 1); 00966 00967 while (PointerPte <= LastPte) { 00968 NextPhysicalPage = MiGetNextPhysicalPage(); 00969 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 00970 MI_WRITE_VALID_PTE(PointerPte, TempPte); 00971 PointerPte++; 00972 } 00973 00974 // 00975 // Zero the remaining PTEs (if any) for the initial nonpaged pool up to 00976 // the end of the current page table page. 00977 // 00978 00979 while (!MiIsPteOnPdeBoundary (PointerPte)) { 00980 MI_WRITE_INVALID_PTE(PointerPte, ZeroKernelPte); 00981 PointerPte += 1; 00982 } 00983 00984 // 00985 // Convert the starting nonpaged pool address to KSEG0 space 00986 // address and set the address of the initial nonpaged pool allocation. 00987 // 00988 00989 if (MiKseg0Mapping == TRUE) { 00990 00991 00992 // 00993 // No need to get page table pages for these as we can reference 00994 // them via large pages. 00995 // 00996 00997 PointerPte = MiGetPteAddress (MmNonPagedPoolStart); 00998 MmNonPagedPoolStart = KSEG0_ADDRESS(PointerPte->u.Hard.PageFrameNumber); 00999 MmSubsectionBase = KSEG0_BASE; 01000 01001 StartPte = MiGetPteAddress(MmNonPagedPoolStart); 01002 LastPte = MiGetPteAddress((PCHAR)MmNonPagedPoolStart + 01003 MmSizeOfNonPagedPoolInBytes - 1); 01004 01005 MiKseg0Start = MiGetVirtualAddressMappedByPte(StartPte); 01006 01007 while (StartPte <= LastPte) { 01008 01009 // 01010 // duplicating PTEs to map non initial non paged pool 01011 // in the KSEG0 space. 01012 // 01013 01014 MI_WRITE_VALID_PTE(StartPte, *PointerPte); 01015 StartPte++; 01016 PointerPte++; 01017 } 01018 01019 MiKseg0End = MiGetVirtualAddressMappedByPte(LastPte); 01020 01021 } else { 01022 01023 MiKseg0Mapping = FALSE; 01024 MmSubsectionBase = 0; 01025 01026 } 01027 01028 // 01029 // As only the initial non paged pool is mapped through superpages, 01030 // MmSubsectionToPage is always set to zero. 01031 // 01032 01033 MmSubsectionTopPage = 0; 01034 01035 01036 MmNonPagedPoolExpansionStart = (PVOID)((PCHAR)NonPagedPoolStartVirtual + 01037 MmSizeOfNonPagedPoolInBytes); 01038 01039 MmPageAlignedPoolBase[NonPagedPool] = MmNonPagedPoolStart; 01040 01041 01042 // 01043 // Non-paged pages now exist, build the pool structures. 01044 // 01045 01046 MiInitializeNonPagedPool (); 01047 01048 // 01049 // Before Non-paged pool can be used, the PFN database must 01050 // be built. This is due to the fact that the start and end of 01051 // allocation bits for nonpaged pool are maintained in the 01052 // PFN elements for the corresponding pages. 01053 // 01054 01055 // 01056 // Calculate the number of pages required from page zero to 01057 // the highest page. 01058 // 01059 // Get secondary color value from registry. 01060 // 01061 01062 MmSecondaryColors = MmSecondaryColors >> PAGE_SHIFT; 01063 01064 if (MmSecondaryColors == 0) { 01065 MmSecondaryColors = MM_SECONDARY_COLORS_DEFAULT; 01066 } else { 01067 01068 // 01069 // Make sure value is power of two and within limits. 01070 // 01071 01072 if (((MmSecondaryColors & (MmSecondaryColors -1)) != 0) || 01073 (MmSecondaryColors < MM_SECONDARY_COLORS_MIN) || 01074 (MmSecondaryColors > MM_SECONDARY_COLORS_MAX)) { 01075 MmSecondaryColors = MM_SECONDARY_COLORS_DEFAULT; 01076 } 01077 } 01078 01079 MmSecondaryColorMask = MmSecondaryColors - 1; 01080 01081 // 01082 // Get the number of secondary colors and add the arrary for tracking 01083 // secondary colors to the end of the PFN database. 01084 // 01085 01086 01087 PfnAllocation = 1 + ((((MmHighestPhysicalPage + 1) * sizeof(MMPFN)) + 01088 (MmSecondaryColors * sizeof(MMCOLOR_TABLES)*2)) 01089 >> PAGE_SHIFT); 01090 01091 01092 if ((MmHighestPhysicalPage < _x4gbnp) && 01093 (MiKseg0Mapping == TRUE) && 01094 (MiEnsureAvailablePagesInFreeDescriptor(PfnAllocation, 01095 MM_PAGES_IN_KSEG0))) { 01096 // 01097 // Allocate the PFN database in the superpage space 01098 // 01099 // Compute the address of the PFN by allocating the appropriate 01100 // number of pages from the end of the free descriptor. 01101 // 01102 01103 MmPfnDatabase = (PMMPFN)KSEG0_ADDRESS(MiNextPhysicalPage); 01104 01105 StartPte = MiGetPteAddress(MmPfnDatabase); 01106 LastPte = MiGetPteAddress((PCHAR)MmPfnDatabase + (PfnAllocation << PAGE_SHIFT) - 1); 01107 01108 while (StartPte <= LastPte) { 01109 TempPte.u.Hard.PageFrameNumber = MiGetNextPhysicalPage(); 01110 MI_WRITE_VALID_PTE(StartPte, TempPte); 01111 StartPte++; 01112 } 01113 01114 RtlZeroMemory(MmPfnDatabase, PfnAllocation * PAGE_SIZE); 01115 MiKseg0End = MiGetVirtualAddressMappedByPte(LastPte); 01116 01117 } else { 01118 01119 // 01120 // Calculate the start of the Pfn Database (it starts a physical 01121 // page zero, even if the Lowest physical page is not zero). 01122 // 01123 01124 MmPfnDatabase = (PMMPFN)MM_PFN_DATABASE_START; 01125 01126 // 01127 // Go through the memory descriptors and for each physical page 01128 // make the PFN database has a valid PTE to map it. This allows 01129 // machines with sparse physical memory to have a minimal PFN 01130 // database. 01131 // 01132 01133 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink; 01134 01135 while (NextMd != &LoaderBlock->MemoryDescriptorListHead) { 01136 01137 MemoryDescriptor = CONTAINING_RECORD(NextMd, 01138 MEMORY_ALLOCATION_DESCRIPTOR, 01139 ListEntry); 01140 01141 PointerPte = MiGetPteAddress (MI_PFN_ELEMENT( 01142 MemoryDescriptor->BasePage)); 01143 01144 LastPte = MiGetPteAddress (((PCHAR)(MI_PFN_ELEMENT( 01145 MemoryDescriptor->BasePage + 01146 MemoryDescriptor->PageCount))) - 1); 01147 01148 First = TRUE; 01149 01150 while (PointerPte <= LastPte) { 01151 01152 if (First == TRUE || MiIsPteOnPpeBoundary(PointerPte)) { 01153 StartPpe = MiGetPdeAddress(PointerPte); 01154 if (StartPpe->u.Hard.Valid == 0) { 01155 ASSERT (StartPpe->u.Long == 0); 01156 NextPhysicalPage = MiGetNextPhysicalPage(); 01157 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE); 01158 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 01159 MI_WRITE_VALID_PTE(StartPpe, TempPte); 01160 } 01161 } 01162 01163 if ((First == TRUE) || MiIsPteOnPdeBoundary(PointerPte)) { 01164 First = FALSE; 01165 StartPde = MiGetPteAddress(PointerPte); 01166 if (StartPde->u.Hard.Valid == 0) { 01167 NextPhysicalPage = MiGetNextPhysicalPage(); 01168 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE); 01169 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 01170 MI_WRITE_VALID_PTE(StartPde, TempPte); 01171 } 01172 } 01173 01174 if (PointerPte->u.Hard.Valid == 0) { 01175 NextPhysicalPage = MiGetNextPhysicalPage(); 01176 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE); 01177 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 01178 MI_WRITE_VALID_PTE(PointerPte, TempPte); 01179 } 01180 01181 PointerPte++; 01182 } 01183 NextMd = MemoryDescriptor->ListEntry.Flink; 01184 } 01185 } 01186 01187 if (MiKseg0Mapping == TRUE) { 01188 01189 // 01190 // Try to convert to superpages 01191 // 01192 01193 MiConvertToSuperPages(MiKseg0Start, 01194 MiKseg0End, 01195 _x1mb, 01196 MM_PTE_1MB_PAGE); 01197 01198 MiConvertToSuperPages(MiKseg0Start, 01199 MiKseg0End, 01200 _x4mb, 01201 MM_PTE_4MB_PAGE); 01202 01203 MiConvertToSuperPages(MiKseg0Start, 01204 MiKseg0End, 01205 _x16mb, 01206 MM_PTE_16MB_PAGE); 01207 01208 MiConvertToSuperPages(MiKseg0Start, 01209 MiKseg0End, 01210 _x64mb, 01211 MM_PTE_64MB_PAGE); 01212 01213 MiConvertToSuperPages(MiKseg0Start, 01214 MiKseg0End, 01215 _x256mb, 01216 MM_PTE_256MB_PAGE); 01217 01218 } 01219 01220 01221 // 01222 // Initialize support for colored pages. 01223 // 01224 01225 MmFreePagesByColor[0] = (PMMCOLOR_TABLES) 01226 &MmPfnDatabase[MmHighestPhysicalPage + 1]; 01227 01228 MmFreePagesByColor[1] = &MmFreePagesByColor[0][MmSecondaryColors]; 01229 01230 // 01231 // Make sure the PTEs are mapped. 01232 // 01233 01234 if (!MI_IS_PHYSICAL_ADDRESS(MmFreePagesByColor[0])) { 01235 PointerPte = MiGetPteAddress (&MmFreePagesByColor[0][0]); 01236 01237 LastPte = MiGetPteAddress ( 01238 (PVOID)((PCHAR)&MmFreePagesByColor[1][MmSecondaryColors] - 1)); 01239 01240 while (PointerPte <= LastPte) { 01241 if (PointerPte->u.Hard.Valid == 0) { 01242 NextPhysicalPage = MiGetNextPhysicalPage(); 01243 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE); 01244 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 01245 MI_WRITE_VALID_PTE(PointerPte, TempPte); 01246 } 01247 PointerPte++; 01248 } 01249 } 01250 01251 for (i = 0; i < MmSecondaryColors; i++) { 01252 MmFreePagesByColor[ZeroedPageList][i].Flink = MM_EMPTY_LIST; 01253 MmFreePagesByColor[FreePageList][i].Flink = MM_EMPTY_LIST; 01254 } 01255 01256 #if MM_MAXIMUM_NUMBER_OF_COLORS > 1 01257 for (i = 0; i < MM_MAXIMUM_NUMBER_OF_COLORS; i++) { 01258 MmFreePagesByPrimaryColor[ZeroedPageList][i].ListName = ZeroedPageList; 01259 MmFreePagesByPrimaryColor[FreePageList][i].ListName = FreePageList; 01260 MmFreePagesByPrimaryColor[ZeroedPageList][i].Flink = MM_EMPTY_LIST; 01261 MmFreePagesByPrimaryColor[FreePageList][i].Flink = MM_EMPTY_LIST; 01262 MmFreePagesByPrimaryColor[ZeroedPageList][i].Blink = MM_EMPTY_LIST; 01263 MmFreePagesByPrimaryColor[FreePageList][i].Blink = MM_EMPTY_LIST; 01264 } 01265 #endif 01266 01267 // 01268 // Go through the page table entries and for any page which is 01269 // valid, update the corresponding PFN database element. 01270 // 01271 01272 StartPde = MiGetPdeAddress (HYPER_SPACE); 01273 StartPpe = MiGetPpeAddress (HYPER_SPACE); 01274 EndPde = MiGetPdeAddress(HYPER_SPACE_END); 01275 First = (StartPpe->u.Hard.Valid == 0) ? TRUE : FALSE; 01276 01277 while (StartPde <= EndPde) { 01278 01279 if (First == TRUE || MiIsPteOnPdeBoundary(StartPde)) { 01280 First = FALSE; 01281 StartPpe = MiGetPteAddress(StartPde); 01282 if (StartPpe->u.Hard.Valid == 0) { 01283 StartPpe += 1; 01284 StartPde = MiGetVirtualAddressMappedByPte (StartPpe); 01285 continue; 01286 } 01287 01288 PdePage = MI_GET_PAGE_FRAME_FROM_PTE(StartPpe); 01289 01290 Pfn1 = MI_PFN_ELEMENT(PdePage); 01291 Pfn1->PteFrame = MmSystemParentTablePage; 01292 Pfn1->PteAddress = StartPde; 01293 Pfn1->u2.ShareCount += 1; 01294 Pfn1->u3.e2.ReferenceCount = 1; 01295 Pfn1->u3.e1.PageLocation = ActiveAndValid; 01296 Pfn1->u3.e1.PageColor = 01297 MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE(StartPpe)); 01298 } 01299 01300 01301 if (StartPde->u.Hard.Valid == 1) { 01302 PdePage = MI_GET_PAGE_FRAME_FROM_PTE(StartPde); 01303 Pfn1 = MI_PFN_ELEMENT(PdePage); 01304 PointerPde = MiGetPteAddress(StartPde); 01305 Pfn1->PteFrame = MI_GET_PAGE_FRAME_FROM_PTE(PointerPde); 01306 Pfn1->PteAddress = StartPde; 01307 Pfn1->u2.ShareCount += 1; 01308 Pfn1->u3.e2.ReferenceCount = 1; 01309 Pfn1->u3.e1.PageLocation = ActiveAndValid; 01310 Pfn1->u3.e1.PageColor = 01311 MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE (StartPde)); 01312 01313 PointerPte = MiGetVirtualAddressMappedByPte(StartPde); 01314 for (j = 0 ; j < PTE_PER_PAGE; j++) { 01315 if (PointerPte->u.Hard.Valid == 1) { 01316 01317 Pfn1->u2.ShareCount += 1; 01318 01319 if (PointerPte->u.Hard.PageFrameNumber <= 01320 MmHighestPhysicalPage) { 01321 Pfn2 = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber); 01322 Pfn2->PteFrame = PdePage; 01323 Pfn2->PteAddress = PointerPte; 01324 Pfn2->u2.ShareCount += 1; 01325 Pfn2->u3.e2.ReferenceCount = 1; 01326 Pfn2->u3.e1.PageLocation = ActiveAndValid; 01327 Pfn2->u3.e1.PageColor = 01328 MI_GET_COLOR_FROM_SECONDARY( 01329 MI_GET_PAGE_COLOR_FROM_PTE ( 01330 PointerPte)); 01331 } 01332 } 01333 PointerPte += 1; 01334 } 01335 } 01336 01337 StartPde++; 01338 } 01339 01340 // 01341 // do it for the kernel space 01342 // 01343 01344 StartPde = MiGetPdeAddress (KADDRESS_BASE); 01345 StartPpe = MiGetPpeAddress (KADDRESS_BASE); 01346 EndPde = MiGetPdeAddress(MM_SYSTEM_SPACE_END); 01347 First = (StartPpe->u.Hard.Valid == 0) ? TRUE : FALSE; 01348 01349 while (StartPde <= EndPde) { 01350 01351 if (First == TRUE || MiIsPteOnPdeBoundary(StartPde)) { 01352 First = FALSE; 01353 StartPpe = MiGetPteAddress(StartPde); 01354 if (StartPpe->u.Hard.Valid == 0) { 01355 StartPpe += 1; 01356 StartPde = MiGetVirtualAddressMappedByPte (StartPpe); 01357 continue; 01358 } 01359 01360 PdePage = MI_GET_PAGE_FRAME_FROM_PTE(StartPpe); 01361 01362 Pfn1 = MI_PFN_ELEMENT(PdePage); 01363 Pfn1->PteFrame = MmSystemParentTablePage; 01364 Pfn1->PteAddress = StartPde; 01365 Pfn1->u2.ShareCount += 1; 01366 Pfn1->u3.e2.ReferenceCount = 1; 01367 Pfn1->u3.e1.PageLocation = ActiveAndValid; 01368 Pfn1->u3.e1.PageColor = 01369 MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE(StartPpe)); 01370 } 01371 01372 if (StartPde->u.Hard.Valid == 1) { 01373 PdePage = MI_GET_PAGE_FRAME_FROM_PTE(StartPde); 01374 Pfn1 = MI_PFN_ELEMENT(PdePage); 01375 PointerPde = MiGetPteAddress(StartPde); 01376 Pfn1->PteFrame = MI_GET_PAGE_FRAME_FROM_PTE(PointerPde); 01377 Pfn1->PteAddress = StartPde; 01378 Pfn1->u2.ShareCount += 1; 01379 Pfn1->u3.e2.ReferenceCount = 1; 01380 Pfn1->u3.e1.PageLocation = ActiveAndValid; 01381 Pfn1->u3.e1.PageColor = 01382 MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE (StartPde)); 01383 01384 PointerPte = MiGetVirtualAddressMappedByPte(StartPde); 01385 for (j = 0 ; j < PTE_PER_PAGE; j++) { 01386 if (PointerPte->u.Hard.Valid == 1) { 01387 01388 Pfn1->u2.ShareCount += 1; 01389 01390 if (PointerPte->u.Hard.PageFrameNumber <= 01391 MmHighestPhysicalPage) { 01392 Pfn2 = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber); 01393 Pfn2->PteFrame = PdePage; 01394 Pfn2->PteAddress = PointerPte; 01395 Pfn2->u2.ShareCount += 1; 01396 Pfn2->u3.e2.ReferenceCount = 1; 01397 Pfn2->u3.e1.PageLocation = ActiveAndValid; 01398 Pfn2->u3.e1.PageColor = 01399 MI_GET_COLOR_FROM_SECONDARY( 01400 MI_GET_PAGE_COLOR_FROM_PTE ( 01401 PointerPte)); 01402 } 01403 } 01404 PointerPte += 1; 01405 } 01406 } 01407 01408 StartPde++; 01409 } 01410 01411 // 01412 // If page zero is still unused, mark it as in use. This is 01413 // temporary as we want to find bugs where a physical page 01414 // is specified as zero. 01415 // 01416 01417 Pfn1 = &MmPfnDatabase[MmLowestPhysicalPage]; 01418 if (Pfn1->u3.e2.ReferenceCount == 0) { 01419 01420 // 01421 // Make the reference count non-zero and point it into a 01422 // page directory. 01423 // 01424 01425 Pde = MiGetPdeAddress (KADDRESS_BASE + 0xb0000000); 01426 PdePage = MI_GET_PAGE_FRAME_FROM_PTE(Pde); 01427 Pfn1->PteFrame = PdePageNumber; 01428 Pfn1->PteAddress = Pde; 01429 Pfn1->u2.ShareCount += 1; 01430 Pfn1->u3.e2.ReferenceCount = 1; 01431 Pfn1->u3.e1.PageLocation = ActiveAndValid; 01432 Pfn1->u3.e1.PageColor = MI_GET_COLOR_FROM_SECONDARY( 01433 MI_GET_PAGE_COLOR_FROM_PTE (Pde)); 01434 } 01435 01436 // end of temporary set to physical page zero. 01437 01438 // 01439 // 01440 // Walk through the memory descriptors and add pages to the 01441 // free list in the PFN database. 01442 // 01443 01444 MiFreeDescriptor->PageCount -= 01445 (PFN_COUNT)(MiNextPhysicalPage - MiOldFreeDescriptorBase); 01446 01447 // 01448 // Until BasePage (arc.h) is changed to PFN_NUMBER, NextPhysicalPage 01449 // needs (ULONG) cast. 01450 // 01451 01452 MiFreeDescriptor->BasePage = (ULONG)MiNextPhysicalPage; 01453 01454 // 01455 // making unused pages inside the kernel super page mapping unusable 01456 // so that no one is going to reclaim it for uncached pages. 01457 // 01458 01459 if (MiFreeDescriptorNonPaged != NULL) { 01460 01461 if (MiFreeDescriptorNonPaged->BasePage > KernelEnd) { 01462 01463 MiWasteStart = KernelEnd; 01464 MiWasteEnd = KernelEnd; 01465 01466 01467 } else if ((MiFreeDescriptorNonPaged->BasePage + 01468 MiFreeDescriptorNonPaged->PageCount) > KernelEnd) { 01469 01470 MiWasteStart = MiFreeDescriptorNonPaged->BasePage; 01471 MiWasteEnd = KernelEnd; 01472 01473 MiFreeDescriptorNonPaged->PageCount -= 01474 (PFN_COUNT) (KernelEnd - MiFreeDescriptorNonPaged->BasePage); 01475 01476 MiFreeDescriptorNonPaged->BasePage = (ULONG) KernelEnd; 01477 01478 } else if (MiFreeDescriptorNonPaged->PageCount != 0) { 01479 01480 MiWasteStart = MiFreeDescriptorNonPaged->BasePage; 01481 MiWasteEnd = MiWasteStart + MiFreeDescriptorNonPaged->PageCount; 01482 MiFreeDescriptorNonPaged->PageCount = 0; 01483 01484 } 01485 } 01486 01487 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink; 01488 01489 while (NextMd != &LoaderBlock->MemoryDescriptorListHead) { 01490 01491 MemoryDescriptor = CONTAINING_RECORD(NextMd, 01492 MEMORY_ALLOCATION_DESCRIPTOR, 01493 ListEntry); 01494 01495 i = MemoryDescriptor->PageCount; 01496 NextPhysicalPage = MemoryDescriptor->BasePage; 01497 01498 switch (MemoryDescriptor->MemoryType) { 01499 case LoaderBad: 01500 while (i != 0) { 01501 MiInsertPageInList (MmPageLocationList[BadPageList], 01502 NextPhysicalPage); 01503 i -= 1; 01504 NextPhysicalPage += 1; 01505 } 01506 break; 01507 01508 case LoaderFree: 01509 case LoaderLoadedProgram: 01510 case LoaderFirmwareTemporary: 01511 case LoaderOsloaderStack: 01512 01513 Pfn1 = MI_PFN_ELEMENT (NextPhysicalPage); 01514 while (i != 0) { 01515 if (Pfn1->u3.e2.ReferenceCount == 0) { 01516 01517 // 01518 // Set the PTE address to the physical page for 01519 // virtual address alignment checking. 01520 // 01521 01522 Pfn1->PteAddress = KSEG_ADDRESS (NextPhysicalPage); 01523 MiInsertPageInList (MmPageLocationList[FreePageList], 01524 NextPhysicalPage); 01525 } 01526 Pfn1++; 01527 i -= 1; 01528 NextPhysicalPage += 1; 01529 } 01530 break; 01531 01532 default: 01533 01534 PointerPte = KSEG_ADDRESS(NextPhysicalPage); 01535 Pfn1 = MI_PFN_ELEMENT (NextPhysicalPage); 01536 while (i != 0) { 01537 01538 // 01539 // Set page as in use. 01540 // 01541 01542 if (Pfn1->u3.e2.ReferenceCount == 0) { 01543 Pfn1->PteFrame = PdePageNumber; 01544 Pfn1->PteAddress = PointerPte; 01545 Pfn1->u2.ShareCount += 1; 01546 Pfn1->u3.e2.ReferenceCount = 1; 01547 Pfn1->u3.e1.PageLocation = ActiveAndValid; 01548 Pfn1->u3.e1.PageColor = MI_GET_COLOR_FROM_SECONDARY( 01549 MI_GET_PAGE_COLOR_FROM_PTE ( 01550 PointerPte)); 01551 } 01552 Pfn1++; 01553 i -= 1; 01554 NextPhysicalPage += 1; 01555 PointerPte += 1; 01556 } 01557 break; 01558 } 01559 01560 NextMd = MemoryDescriptor->ListEntry.Flink; 01561 } 01562 01563 if (MI_IS_PHYSICAL_ADDRESS(MmPfnDatabase) == FALSE) { 01564 01565 // 01566 // Indicate that the PFN database is allocated in NonPaged pool. 01567 // 01568 01569 PointerPte = MiGetPteAddress (&MmPfnDatabase[MmLowestPhysicalPage]); 01570 Pfn1 = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber); 01571 Pfn1->u3.e1.StartOfAllocation = 1; 01572 01573 // 01574 // Set the end of the allocation. 01575 // 01576 01577 PointerPte = MiGetPteAddress (&MmPfnDatabase[MmHighestPhysicalPage]); 01578 Pfn1 = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber); 01579 Pfn1->u3.e1.EndOfAllocation = 1; 01580 01581 } else { 01582 // 01583 // The PFN database is allocated in the superpage space 01584 // 01585 // Mark all pfn entries for the pfn pages in use. 01586 // 01587 01588 PageFrameIndex = MI_CONVERT_PHYSICAL_TO_PFN (MmPfnDatabase); 01589 Pfn1 = MI_PFN_ELEMENT(PageFrameIndex); 01590 do { 01591 Pfn1->PteAddress = KSEG_ADDRESS(PageFrameIndex); 01592 Pfn1->u3.e1.PageColor = 0; 01593 Pfn1->u3.e2.ReferenceCount += 1; 01594 Pfn1->u3.e1.PageLocation = ActiveAndValid; 01595 PageFrameIndex += 1; 01596 Pfn1 += 1; 01597 PfnAllocation -= 1; 01598 } while (PfnAllocation != 0); 01599 01600 // 01601 // To avoid creating WB/UC/WC aliasing problem, we should not scan 01602 // and add free pages to the free list. 01603 // 01604 #if 0 01605 // Scan the PFN database backward for pages that are completely zero. 01606 // These pages are unused and can be added to the free list 01607 // 01608 01609 BottomPfn = MI_PFN_ELEMENT(MmHighestPhysicalPage); 01610 do { 01611 01612 // 01613 // Compute the address of the start of the page that is next 01614 // lower in memory and scan backwards until that page address 01615 // is reached or just crossed. 01616 // 01617 01618 if (((ULONG_PTR)BottomPfn & (PAGE_SIZE - 1)) != 0) { 01619 BasePfn = (PMMPFN)((ULONG_PTR)BottomPfn & ~(PAGE_SIZE - 1)); 01620 TopPfn = BottomPfn + 1; 01621 01622 } else { 01623 BasePfn = (PMMPFN)((ULONG_PTR)BottomPfn - PAGE_SIZE); 01624 TopPfn = BottomPfn; 01625 } 01626 01627 while (BottomPfn > BasePfn) { 01628 BottomPfn -= 1; 01629 } 01630 01631 // 01632 // If the entire range over which the PFN entries span is 01633 // completely zero and the PFN entry that maps the page is 01634 // not in the range, then add the page to the appropriate 01635 // free list. 01636 // 01637 01638 Range = (ULONG_PTR)TopPfn - (ULONG_PTR)BottomPfn; 01639 if (RtlCompareMemoryUlong((PVOID)BottomPfn, Range, 0) == Range) { 01640 01641 // 01642 // Set the PTE address to the physical page for virtual 01643 // address alignment checking. 01644 // 01645 01646 PageFrameIndex = MI_CONVERT_PHYSICAL_TO_PFN (BasePfn); 01647 Pfn1 = MI_PFN_ELEMENT(PageFrameIndex); 01648 01649 ASSERT (Pfn1->u3.e2.ReferenceCount == 1); 01650 ASSERT (Pfn1->PteAddress == KSEG_ADDRESS(PageFrameIndex)); 01651 Pfn1->u3.e2.ReferenceCount = 0; 01652 PfnAllocation += 1; 01653 Pfn1->PteAddress = (PMMPTE)((ULONG_PTR)PageFrameIndex << PTE_SHIFT); 01654 Pfn1->u3.e1.PageColor = 0; 01655 MiInsertPageInList(MmPageLocationList[FreePageList], 01656 PageFrameIndex); 01657 } 01658 01659 } while (BottomPfn > MmPfnDatabase); 01660 #endif 01661 01662 } 01663 01664 01665 // 01666 // Indicate that nonpaged pool must succeed is allocated in 01667 // nonpaged pool. 01668 // 01669 01670 if (MI_IS_PHYSICAL_ADDRESS(MmNonPagedMustSucceed)) { 01671 Pfn1 = MI_PFN_ELEMENT(MI_CONVERT_PHYSICAL_TO_PFN (MmNonPagedMustSucceed)); 01672 } else { 01673 PointerPte = MiGetPteAddress(MmNonPagedMustSucceed); 01674 Pfn1 = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber); 01675 } 01676 01677 i = MmSizeOfNonPagedMustSucceed; 01678 while ((LONG)i > 0) { 01679 Pfn1->u3.e1.StartOfAllocation = 1; 01680 Pfn1->u3.e1.EndOfAllocation = 1; 01681 i -= PAGE_SIZE; 01682 Pfn1 += 1; 01683 } 01684 01685 #if 0 01686 // 01687 // Adjust the memory descriptors to indicate that free pool has 01688 // been used for nonpaged pool creation. 01689 // 01690 01691 MiFreeDescriptor->PageCount = (ULONG)MiOldFreeDescriptorCount; 01692 01693 // 01694 // Until PagePage is defined to PFN_NUMBER, we need (ULONG) cast to 01695 // remove warning. 01696 // 01697 01698 MiFreeDescriptor->BasePage = (ULONG)MiOldFreeDescriptorBase; 01699 01700 #endif 01701 01702 // moved from above for pool hack routines... 01703 KeInitializeSpinLock (&MmSystemSpaceLock); 01704 01705 KeInitializeSpinLock (&MmPfnLock); 01706 01707 // 01708 // Initialize the nonpaged available PTEs for mapping I/O space 01709 // and kernel stacks. 01710 // 01711 01712 PointerPte = MiGetPteAddress (MmNonPagedSystemStart); 01713 ASSERT (((ULONG_PTR)PointerPte & (PAGE_SIZE - 1)) == 0); 01714 01715 MmNumberOfSystemPtes = (ULONG)(MiGetPteAddress(NonPagedPoolStartVirtual) - PointerPte - 1); 01716 01717 MiInitializeSystemPtes (PointerPte, MmNumberOfSystemPtes, SystemPteSpace); 01718 01719 // 01720 // Initialize the nonpaged pool. 01721 // 01722 01723 InitializePool(NonPagedPool,0); 01724 01725 // 01726 // Initialize memory management structures for the system process. 01727 // 01728 // Set the address of the first and last reserved PTE in hyper space. 01729 // 01730 01731 MmFirstReservedMappingPte = MiGetPteAddress (FIRST_MAPPING_PTE); 01732 MmLastReservedMappingPte = MiGetPteAddress (LAST_MAPPING_PTE); 01733 01734 MmWorkingSetList = WORKING_SET_LIST; 01735 MmWsle = (PMMWSLE)((PUCHAR)WORKING_SET_LIST + sizeof(MMWSL)); 01736 01737 // 01738 // The PFN element for the page directory parent will be initialized 01739 // a second time when the process address space is initialized. Therefore, 01740 // the share count and the reference count must be set to zero. 01741 // 01742 01743 Pfn1 = MI_PFN_ELEMENT(MI_GET_PAGE_FRAME_FROM_PTE((PMMPTE)PDE_SELFMAP)); 01744 Pfn1->u2.ShareCount = 0; 01745 Pfn1->u3.e2.ReferenceCount = 0; 01746 01747 // 01748 // The PFN element for the hyper space page directory page will be 01749 // initialized a second time when the process address space is initialized. 01750 // Therefore, the share count and the reference count must be set to zero. 01751 // 01752 01753 PointerPte = MiGetPpeAddress(HYPER_SPACE); 01754 Pfn1 = MI_PFN_ELEMENT(MI_GET_PAGE_FRAME_FROM_PTE(PointerPte)); 01755 Pfn1->u2.ShareCount = 0; 01756 Pfn1->u3.e2.ReferenceCount = 0; 01757 01758 // 01759 // The PFN elements for the hyper space page table page and working set list 01760 // page will be initialized a second time when the process address space 01761 // is initialized. Therefore, the share count and the reference must be 01762 // set to zero. 01763 // 01764 01765 StartPde = MiGetPdeAddress(HYPER_SPACE); 01766 01767 Pfn1 = MI_PFN_ELEMENT(MI_GET_PAGE_FRAME_FROM_PTE(StartPde)); 01768 Pfn1->u2.ShareCount = 0; 01769 Pfn1->u3.e2.ReferenceCount = 0; 01770 01771 // 01772 // Initialize this process's memory management structures including 01773 // the working set list. 01774 // 01775 01776 // 01777 // The pfn element for the page directory has already been initialized, 01778 // zero the reference count and the share count so they won't be 01779 // wrong. 01780 // 01781 01782 Pfn1 = MI_PFN_ELEMENT (PdePageNumber); 01783 Pfn1->u2.ShareCount = 0; 01784 Pfn1->u3.e2.ReferenceCount = 0; 01785 01786 CurrentProcess = PsGetCurrentProcess (); 01787 01788 // 01789 // Get a page for the working set list and map it into the Page 01790 // directory at the page after hyperspace. 01791 // 01792 01793 PageFrameIndex = MiRemoveAnyPage (0); 01794 01795 CurrentProcess->WorkingSetPage = PageFrameIndex; 01796 TempPte.u.Hard.PageFrameNumber = PageFrameIndex; 01797 01798 RtlZeroMemory (KSEG_ADDRESS(PageFrameIndex), PAGE_SIZE); 01799 01800 CurrentProcess->Vm.MaximumWorkingSetSize = (ULONG)MmSystemProcessWorkingSetMax; 01801 CurrentProcess->Vm.MinimumWorkingSetSize = (ULONG)MmSystemProcessWorkingSetMin; 01802 01803 MmInitializeProcessAddressSpace (CurrentProcess, 01804 (PEPROCESS)NULL, 01805 (PVOID)NULL, 01806 (PVOID)NULL); 01807 01808 01809 // *PointerPde = ZeroPte; 01810 01811 // 01812 // page after hyperspace should be reclaimed for system cache structure 01813 // 01814 01815 KeFlushCurrentTb(); 01816 01817 // 01818 // Check to see if moving the secondary page structures to the end 01819 // of the PFN database is a waste of memory. And if so, copy it 01820 // to paged pool. 01821 // 01822 // If the PFN datbase ends on a page aligned boundary and the 01823 // size of the two arrays is less than a page, free the page 01824 // and allocate nonpagedpool for this. 01825 // 01826 01827 if ((((ULONG_PTR)MmFreePagesByColor[0] & (PAGE_SIZE - 1)) == 0) && 01828 ((MmSecondaryColors * 2 * sizeof(MMCOLOR_TABLES)) < PAGE_SIZE)) { 01829 01830 PMMCOLOR_TABLES c; 01831 01832 c = MmFreePagesByColor[0]; 01833 01834 MmFreePagesByColor[0] = ExAllocatePoolWithTag (NonPagedPoolMustSucceed, 01835 MmSecondaryColors * 2 * sizeof(MMCOLOR_TABLES), 01836 ' mM'); 01837 01838 MmFreePagesByColor[1] = &MmFreePagesByColor[0][MmSecondaryColors]; 01839 01840 RtlMoveMemory (MmFreePagesByColor[0], 01841 c, 01842 MmSecondaryColors * 2 * sizeof(MMCOLOR_TABLES)); 01843 01844 // 01845 // Free the page. 01846 // 01847 01848 if (!MI_IS_PHYSICAL_ADDRESS(c)) { 01849 PointerPte = MiGetPteAddress(c); 01850 PageFrameIndex = MI_GET_PAGE_FRAME_FROM_PTE(PointerPte); 01851 MI_WRITE_INVALID_PTE(PointerPte, ZeroKernelPte); 01852 } else { 01853 PageFrameIndex = MI_CONVERT_PHYSICAL_TO_PFN (c); 01854 } 01855 01856 Pfn1 = MI_PFN_ELEMENT (PageFrameIndex); 01857 ASSERT ((Pfn1->u2.ShareCount <= 1) && (Pfn1->u3.e2.ReferenceCount <= 1)); 01858 Pfn1->u2.ShareCount = 0; 01859 Pfn1->u3.e2.ReferenceCount = 1; 01860 MI_SET_PFN_DELETED (Pfn1); 01861 #if DBG 01862 Pfn1->u3.e1.PageLocation = StandbyPageList; 01863 #endif //DBG 01864 MiDecrementReferenceCount (PageFrameIndex); 01865 } 01866 01867 return; 01868 }

VOID MiMakeKernelPagesPermanent IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 2354 of file mm/ia64/initia64.c.

References _MEMORY_ALLOCATION_DESCRIPTOR::BasePage, LoaderNlsData, LoaderOsloaderHeap, LoaderRegistryData, LoaderSpecialMemory, _MEMORY_ALLOCATION_DESCRIPTOR::MemoryType, MiNtoskrnlPageShift, MiNtoskrnlPhysicalBase, and PAGE_SHIFT.

Referenced by MiInitMachineDependent().

02357 { 02358 PFN_NUMBER KernelStart; 02359 PFN_NUMBER KernelEnd; 02360 ULONG_PTR PageSize; 02361 PLIST_ENTRY NextEntry; 02362 PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor; 02363 02364 KernelStart = MiNtoskrnlPhysicalBase >> PAGE_SHIFT; 02365 PageSize = (ULONG_PTR)1 << MiNtoskrnlPageShift; 02366 KernelEnd = KernelStart + (PageSize >> PAGE_SHIFT); 02367 02368 NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink; 02369 02370 for ( ; NextEntry != &LoaderBlock->MemoryDescriptorListHead; NextEntry = NextEntry->Flink) { 02371 02372 MemoryDescriptor = CONTAINING_RECORD(NextEntry, 02373 MEMORY_ALLOCATION_DESCRIPTOR, 02374 ListEntry); 02375 02376 if (((MemoryDescriptor->BasePage >= KernelStart) && 02377 (MemoryDescriptor->BasePage < KernelEnd)) && 02378 ((MemoryDescriptor->MemoryType == LoaderOsloaderHeap) || 02379 (MemoryDescriptor->MemoryType == LoaderRegistryData) || 02380 (MemoryDescriptor->MemoryType == LoaderNlsData))) { 02381 02382 // 02383 // prevent these pages from being reclaimed later 02384 // 02385 02386 MemoryDescriptor->MemoryType = LoaderSpecialMemory; 02387 02388 } 02389 02390 } 02391 }

VOID MiRemoveLoaderSuperPages IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 2337 of file mm/ia64/initia64.c.

References FALSE.

Referenced by MiInitMachineDependent().

02340 { 02341 02342 // 02343 // remove the super pages for the boot drivers 02344 // 02345 02346 KiFlushFixedInstTb(FALSE, LoaderBlock->u.Ia64.ItrInfo[ITR_DRIVER0_INDEX].VirtualAddress); 02347 KiFlushFixedInstTb(FALSE, LoaderBlock->u.Ia64.ItrInfo[ITR_DRIVER1_INDEX].VirtualAddress); 02348 KiFlushFixedDataTb(FALSE, LoaderBlock->u.Ia64.DtrInfo[DTR_DRIVER0_INDEX].VirtualAddress); 02349 KiFlushFixedDataTb(FALSE, LoaderBlock->u.Ia64.DtrInfo[DTR_DRIVER1_INDEX].VirtualAddress); 02350 02351 }

VOID MiSweepCacheMachineDependent IN PVOID  VirtualAddress,
IN SIZE_T  Size,
IN MEMORY_CACHING_TYPE  CacheType
 

Definition at line 2042 of file mm/ia64/initia64.c.

References COMPUTE_PAGES_SPANNED, KeSweepCacheRangeWithDrain(), MEMORY_CACHING_TYPE, MI_SET_PTE_WRITE_COMBINE, MI_WRITE_VALID_PTE, MiGetPteAddress, MmWriteCombined, PAGE_ALIGN, PAGE_SIZE, Size, and TRUE.

Referenced by MiMapLockedPagesInUserSpace(), MiMapSinglePage(), MiMapViewOfPhysicalSection(), MmAllocateNonCachedMemory(), MmMapIoSpace(), and MmMapLockedPagesSpecifyCache().

02049 : 02050 02051 This function checks and perform appropriate cache flushing operations. 02052 02053 Arguments: 02054 02055 StartVirtual - the start address of the region of pages to be examined. 02056 02057 Size - the size of the region of pages 02058 02059 Cache - the new cache type 02060 02061 Return Value: 02062 02063 None. 02064 02065 --*/ 02066 { 02067 PFN_NUMBER j; 02068 PFN_NUMBER NumberOfPages; 02069 KIRQL OldIrql; 02070 PMMPTE PointerPte; 02071 MMPTE TempPte; 02072 02073 NumberOfPages = COMPUTE_PAGES_SPANNED (VirtualAddress, Size); 02074 VirtualAddress = PAGE_ALIGN(VirtualAddress); 02075 Size = NumberOfPages * PAGE_SIZE; 02076 02077 KeSweepCacheRangeWithDrain(TRUE, VirtualAddress, (ULONG)Size); 02078 02079 if (CacheType == MmWriteCombined) { 02080 PointerPte = MiGetPteAddress(VirtualAddress); 02081 for (j = 0; j < NumberOfPages; j += 1) { 02082 TempPte = *PointerPte; 02083 MI_SET_PTE_WRITE_COMBINE (TempPte); 02084 MI_WRITE_VALID_PTE (PointerPte, TempPte); 02085 PointerPte += 1; 02086 } 02087 } 02088 }


Variable Documentation

PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor
 

Definition at line 121 of file mm/ia64/initia64.c.

Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorLargest = NULL
 

Definition at line 122 of file mm/ia64/initia64.c.

Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorLowMem = NULL
 

Definition at line 123 of file mm/ia64/initia64.c.

Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorNonPaged = NULL
 

Definition at line 124 of file mm/ia64/initia64.c.

Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

ULONG MiImplVirtualMsb = 50
 

Definition at line 135 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

PVOID MiKseg0End = 0
 

Definition at line 87 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

BOOLEAN MiKseg0Mapping = TRUE
 

Definition at line 88 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

PVOID MiKseg0Start = 0
 

Definition at line 86 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

PFN_NUMBER MiNextPhysicalPage
 

Definition at line 126 of file mm/ia64/initia64.c.

Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

ULONG MiNtoskrnlPageShift
 

Definition at line 92 of file mm/ia64/initia64.c.

Referenced by MiCheckMemoryDescriptorList(), MiInitMachineDependent(), and MiMakeKernelPagesPermanent().

PFN_NUMBER MiNtoskrnlPhysicalBase
 

Definition at line 90 of file mm/ia64/initia64.c.

Referenced by MiCheckMemoryDescriptorList(), MiInitMachineDependent(), and MiMakeKernelPagesPermanent().

ULONG_PTR MiNtoskrnlVirtualBase
 

Definition at line 91 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

PFN_NUMBER MiNumberOfPages
 

Definition at line 127 of file mm/ia64/initia64.c.

Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

PFN_NUMBER MiOldFreeDescriptorBase
 

Definition at line 128 of file mm/ia64/initia64.c.

Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

PFN_NUMBER MiOldFreeDescriptorCount
 

Definition at line 129 of file mm/ia64/initia64.c.

Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

BOOLEAN MiPrintMemoryDescriptors = FALSE
 

Definition at line 89 of file mm/ia64/initia64.c.

Referenced by MiCheckMemoryDescriptorList(), and MiInitMachineDependent().

MMPTE MiSystemSelfMappedPte
 

Definition at line 84 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

MMPTE MiUserSelfMappedPte
 

Definition at line 85 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

PFN_NUMBER MiWasteEnd = 0
 

Definition at line 94 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

PFN_NUMBER MiWasteStart = 0
 

Definition at line 93 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

ULONG_PTR MmKseg3VhptBase
 

Definition at line 80 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

ULONG MmKseg3VhptPs
 

Definition at line 81 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().

PFN_NUMBER MmSystemParentTablePage
 

Definition at line 83 of file mm/ia64/initia64.c.

Referenced by MiInitMachineDependent().


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