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

initppc.c File Reference

#include "mi.h"

Go to the source code of this file.

Defines

#define _16MB   ((16*1024*1024)/PAGE_SIZE)

Functions

VOID MiInitMachineDependent (IN PLOADER_PARAMETER_BLOCK LoaderBlock)


Define Documentation

#define _16MB   ((16*1024*1024)/PAGE_SIZE)
 

Definition at line 32 of file initppc.c.


Function Documentation

VOID MiInitMachineDependent IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 36 of file initppc.c.

References _16MB, _1MB, ActiveAndValid, ASSERT, BadPageList, _MEMORY_ALLOCATION_DESCRIPTOR::BasePage, _MMPFNLIST::Blink, Buffer, c, CHAR, DISPATCH_LEVEL, ExAllocatePoolWithTag, FALSE, FIRST_MAPPING_PTE, _MMPFNLIST::Flink, _MMCOLOR_TABLES::Flink, FreePageList, HYPER_SPACE, InbvDisplayString(), InitializePool(), KeBugCheck(), KeBugCheckEx(), KeFlushSingleTb(), KeInitializeSpinLock(), KeLowerIrql(), KeRaiseIrql(), KeSweepDcache(), KSEG0_BASE, LAST_MAPPING_PTE, _MEMORY_ALLOCATION_DESCRIPTOR::ListEntry, _MMPFNLIST::ListName, LoaderBad, LoaderFirmwareTemporary, LoaderFree, LoaderLoadedProgram, LoaderOsloaderHeap, LoaderOsloaderStack, LOCK_PFN, _MMSUPPORT::MaximumWorkingSetSize, _MEMORY_ALLOCATION_DESCRIPTOR::MemoryType, MI_CONVERT_PHYSICAL_TO_PFN, MI_GET_COLOR_FROM_SECONDARY, MI_GET_PAGE_COLOR_FROM_PTE, MI_IS_PHYSICAL_ADDRESS, MI_PFN_ELEMENT, MI_SESSION_SPACE_END, MI_SET_PFN_DELETED, MiGetPdeAddress, MiGetPteAddress, MiGetVirtualAddressMappedByPte, MiHydra, MiInitializeNonPagedPool(), MiInitializeSystemPtes(), MiInsertPageInList(), _MMSUPPORT::MinimumWorkingSetSize, MiRemoveAnyPage(), MiRequestedSystemPtes, MiReserveSystemPtes(), MM_COLOR_MASK, 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_SECONDARY_COLORS_DEFAULT, MM_SECONDARY_COLORS_MAX, MM_SECONDARY_COLORS_MIN, MM_SUBSECTION_MAP, MM_SYSTEM_SPACE_END, MM_SYSTEM_SPACE_START, MMCOLOR_TABLES, MmDefaultMaximumNonPagedPool, MmDynamicPfn, MmExpandedNonPagedPoolInBytes, MmFirstReservedMappingPte, MmFreePagesByColor, MmFreePagesByPrimaryColor, MmHiberPages, MmHighestPhysicalPage, MmHighestPossiblePhysicalPage, MmInitializeProcessAddressSpace(), MmIsAddressValid(), MmLastReservedMappingPte, MmLowestPhysicalPage, MmMaxAdditionNonPagedPoolPerMb, MmMaximumNonPagedPoolInBytes, MmMinAdditionNonPagedPoolPerMb, MmMinimumNonPagedPoolSize, MmNonPagedMustSucceed, MmNonPagedPoolEnd, MmNonPagedPoolExpansionStart, MmNonPagedPoolStart, MmNonPagedSystemStart, MmNumberOfPhysicalPages, MmNumberOfSystemPtes, MmPageAlignedPoolBase, MmPageLocationList, MMPFN, MmPfnDatabase, MmPfnLock, MmSecondaryColorMask, MmSecondaryColors, MmSessionBase, MmSizeOfNonPagedMustSucceed, MmSizeOfNonPagedPoolInBytes, MmSubsectionBase, MmSubsectionTopPage, MmSystemProcessWorkingSetMax, MmSystemProcessWorkingSetMin, MmSystemSpaceLock, MmWorkingSetList, MMWSL, MmWsle, NON_PAGED_SYSTEM_END, NonPagedPool, NonPagedPoolExpansion, NonPagedPoolMustSucceed, NULL, NUMBER_OF_MAPPING_PTES, PAGE_ALIGN, PAGE_DIRECTORY_MASK, PAGE_SHIFT, PAGE_SIZE, _MEMORY_ALLOCATION_DESCRIPTOR::PageCount, PDE_PER_PAGE, PsGetCurrentProcess, PTE_PER_PAGE, PTE_SHIFT, _MMPFN::PteAddress, _MMPFN::PteFrame, RtlCompareMemoryUlong(), sprintf(), StandbyPageList, SystemPteSpace, TRUE, _MMPTE::u, _MMPFN::u2, _MMPFN::u3, UNLOCK_PFN, ValidKernelPte, _EPROCESS::Vm, WORKING_SET_LIST, _EPROCESS::WorkingSetPage, ZeroedPageList, and ZeroKernelPte.

Referenced by MmInitSystem().

00042 : 00043 00044 This routine performs the necessary operations to enable virtual 00045 memory. This includes building the page directory page, building 00046 page table pages to map the code section, the data section, the' 00047 stack section and the trap handler. 00048 00049 It also initializes the PFN database and populates the free list. 00050 00051 00052 Arguments: 00053 00054 None. 00055 00056 Return Value: 00057 00058 None. 00059 00060 Environment: 00061 00062 Kernel mode. 00063 00064 --*/ 00065 00066 { 00067 00068 ULONG i, j; 00069 ULONG HighPage; 00070 ULONG PdePageNumber; 00071 ULONG PdePage; 00072 ULONG PageFrameIndex; 00073 ULONG NextPhysicalPage; 00074 ULONG PfnAllocation; 00075 ULONG NumberOfPages; 00076 ULONG MaxPool; 00077 KIRQL OldIrql; 00078 PEPROCESS CurrentProcess; 00079 ULONG DirBase; 00080 ULONG MostFreePage = 0; 00081 ULONG MostFreeLowMem = 0; 00082 PLIST_ENTRY NextMd; 00083 PMEMORY_ALLOCATION_DESCRIPTOR FreeDescriptor = NULL; 00084 PMEMORY_ALLOCATION_DESCRIPTOR FreeDescriptorLowMem = NULL; 00085 PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor; 00086 MMPTE TempPte; 00087 PMMPTE PointerPde; 00088 PMMPTE PointerPte; 00089 PMMPTE LastPte; 00090 PMMPTE Pde; 00091 PMMPTE StartPde; 00092 PMMPTE EndPde; 00093 PMMPFN Pfn1; 00094 PMMPFN Pfn2; 00095 ULONG va; 00096 00097 PointerPte = MiGetPdeAddress (PDE_BASE); 00098 00099 // N.B. this will cause first HPT miss fault, DSI in real0.s should fix it! 00100 PdePageNumber = PointerPte->u.Hard.PageFrameNumber; 00101 00102 DirBase = PdePageNumber << PAGE_SHIFT; 00103 00104 PsGetCurrentProcess()->Pcb.DirectoryTableBase[0] = DirBase; 00105 00106 KeSweepDcache (FALSE); 00107 00108 // 00109 // Get the lower bound of the free physical memory and the 00110 // number of physical pages by walking the memory descriptor lists. 00111 // 00112 00113 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink; 00114 00115 while (NextMd != &LoaderBlock->MemoryDescriptorListHead) { 00116 00117 MemoryDescriptor = CONTAINING_RECORD(NextMd, 00118 MEMORY_ALLOCATION_DESCRIPTOR, 00119 ListEntry); 00120 00121 HighPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount - 1; 00122 MmNumberOfPhysicalPages += MemoryDescriptor->PageCount; 00123 00124 if (MemoryDescriptor->BasePage < MmLowestPhysicalPage) { 00125 MmLowestPhysicalPage = MemoryDescriptor->BasePage; 00126 } 00127 00128 if (HighPage > MmHighestPhysicalPage) { 00129 MmHighestPhysicalPage = HighPage; 00130 } 00131 00132 // 00133 // Locate the largest free block and the largest free block below 16MB. 00134 // 00135 00136 if ((MemoryDescriptor->MemoryType == LoaderFree) || 00137 (MemoryDescriptor->MemoryType == LoaderLoadedProgram) || 00138 (MemoryDescriptor->MemoryType == LoaderFirmwareTemporary) || 00139 (MemoryDescriptor->MemoryType == LoaderOsloaderStack)) { 00140 00141 if ((MemoryDescriptor->BasePage < _16MB) && 00142 (MostFreeLowMem < MemoryDescriptor->PageCount) && 00143 (MostFreeLowMem < ((ULONG)_16MB - MemoryDescriptor->BasePage))) { 00144 00145 MostFreeLowMem = (ULONG)_16MB - MemoryDescriptor->BasePage; 00146 if (MemoryDescriptor->PageCount < MostFreeLowMem) { 00147 MostFreeLowMem = MemoryDescriptor->PageCount; 00148 } 00149 FreeDescriptorLowMem = MemoryDescriptor; 00150 00151 } else if (MemoryDescriptor->PageCount > MostFreePage) { 00152 00153 MostFreePage = MemoryDescriptor->PageCount; 00154 FreeDescriptor = MemoryDescriptor; 00155 } 00156 } 00157 00158 NextMd = MemoryDescriptor->ListEntry.Flink; 00159 } 00160 00161 // 00162 // This printout must be updated when the HAL goes to unicode 00163 // 00164 00165 if (MmNumberOfPhysicalPages < 1024) { 00166 KeBugCheckEx (INSTALL_MORE_MEMORY, 00167 MmNumberOfPhysicalPages, 00168 MmLowestPhysicalPage, 00169 MmHighestPhysicalPage, 00170 0); 00171 } 00172 00173 // 00174 // Build non-paged pool using the physical pages following the 00175 // data page in which to build the pool from. Non-page pool grows 00176 // from the high range of the virtual address space and expands 00177 // downward. 00178 // 00179 // At this time non-paged pool is constructed so virtual addresses 00180 // are also physically contiguous. 00181 // 00182 00183 if ((MmSizeOfNonPagedPoolInBytes >> PAGE_SHIFT) > 00184 (7 * (MmNumberOfPhysicalPages << 3))) { 00185 00186 // 00187 // More than 7/8 of memory allocated to nonpagedpool, reset to 0. 00188 // 00189 00190 MmSizeOfNonPagedPoolInBytes = 0; 00191 } 00192 00193 if (MmSizeOfNonPagedPoolInBytes < MmMinimumNonPagedPoolSize) { 00194 00195 // 00196 // Calculate the size of nonpaged pool. 00197 // Use the minimum size, then for every MB about 4mb add extra 00198 // pages. 00199 // 00200 00201 MmSizeOfNonPagedPoolInBytes = MmMinimumNonPagedPoolSize; 00202 00203 MmSizeOfNonPagedPoolInBytes += 00204 ((MmNumberOfPhysicalPages - 1024)/256) * 00205 MmMinAdditionNonPagedPoolPerMb; 00206 } 00207 00208 if (MmSizeOfNonPagedPoolInBytes > MM_MAX_INITIAL_NONPAGED_POOL) { 00209 MmSizeOfNonPagedPoolInBytes = MM_MAX_INITIAL_NONPAGED_POOL; 00210 } 00211 00212 // 00213 // Align to page size boundary. 00214 // 00215 00216 MmSizeOfNonPagedPoolInBytes &= ~(PAGE_SIZE - 1); 00217 00218 // 00219 // Calculate the maximum size of pool. 00220 // 00221 00222 if (MmMaximumNonPagedPoolInBytes == 0) { 00223 00224 // 00225 // Calculate the size of nonpaged pool. If 4mb of less use 00226 // the minimum size, then for every MB about 4mb add extra 00227 // pages. 00228 // 00229 00230 MmMaximumNonPagedPoolInBytes = MmDefaultMaximumNonPagedPool; 00231 00232 // 00233 // Make sure enough expansion for pfn database exists. 00234 // 00235 00236 MmMaximumNonPagedPoolInBytes += (ULONG)PAGE_ALIGN ( 00237 MmHighestPhysicalPage * sizeof(MMPFN)); 00238 00239 MmMaximumNonPagedPoolInBytes += 00240 ((MmNumberOfPhysicalPages - 1024)/256) * 00241 MmMaxAdditionNonPagedPoolPerMb; 00242 } 00243 00244 MaxPool = MmSizeOfNonPagedPoolInBytes + PAGE_SIZE * 16 + 00245 (ULONG)PAGE_ALIGN ( 00246 MmHighestPhysicalPage * sizeof(MMPFN)); 00247 00248 if (MmMaximumNonPagedPoolInBytes < MaxPool) { 00249 MmMaximumNonPagedPoolInBytes = MaxPool; 00250 } 00251 00252 if (MmMaximumNonPagedPoolInBytes > MM_MAX_ADDITIONAL_NONPAGED_POOL) { 00253 MmMaximumNonPagedPoolInBytes = MM_MAX_ADDITIONAL_NONPAGED_POOL; 00254 } 00255 00256 MmNonPagedPoolStart = (PVOID)((ULONG)MmNonPagedPoolEnd 00257 - (MmMaximumNonPagedPoolInBytes - 1)); 00258 00259 MmNonPagedPoolStart = (PVOID)PAGE_ALIGN(MmNonPagedPoolStart); 00260 00261 // 00262 // Calculate the starting PDE for the system PTE pool which is 00263 // right below the nonpaged pool. 00264 // 00265 00266 MmNonPagedSystemStart = (PVOID)(((ULONG)MmNonPagedPoolStart - 00267 ((MmNumberOfSystemPtes + 1) * PAGE_SIZE)) & 00268 (~PAGE_DIRECTORY_MASK)); 00269 00270 if (MmNonPagedSystemStart < MM_LOWEST_NONPAGED_SYSTEM_START) { 00271 MmNonPagedSystemStart = MM_LOWEST_NONPAGED_SYSTEM_START; 00272 MmNumberOfSystemPtes = (((ULONG)MmNonPagedPoolStart - 00273 (ULONG)MmNonPagedSystemStart) >> PAGE_SHIFT)-1; 00274 ASSERT (MmNumberOfSystemPtes > 1000); 00275 } 00276 00277 StartPde = MiGetPdeAddress (MmNonPagedSystemStart); 00278 00279 EndPde = MiGetPdeAddress((PVOID)((PCHAR)MmNonPagedPoolEnd - 1)); 00280 00281 ASSERT ((ULONG)(EndPde - StartPde) < FreeDescriptorLowMem->PageCount); 00282 00283 // 00284 // Start building the nonpaged pool with the largest free chunk of memory 00285 // below 16MB. 00286 // 00287 00288 NextPhysicalPage = FreeDescriptorLowMem->BasePage; 00289 NumberOfPages = FreeDescriptorLowMem->PageCount; 00290 TempPte = ValidKernelPte; 00291 00292 while (StartPde <= EndPde) { 00293 if (StartPde->u.Hard.Valid == 0) { 00294 00295 // 00296 // Map in a page directory page. 00297 // 00298 00299 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 00300 NextPhysicalPage += 1; 00301 NumberOfPages -= 1; 00302 *StartPde = TempPte; 00303 00304 } 00305 StartPde += 1; 00306 } 00307 00308 ASSERT(NumberOfPages > 0); 00309 00310 // 00311 // Zero the PTEs before nonpaged pool. 00312 // 00313 00314 StartPde = MiGetPteAddress(MmNonPagedSystemStart); 00315 PointerPte = MiGetPteAddress(MmNonPagedPoolStart); 00316 00317 RtlZeroMemory (StartPde, ((ULONG)PointerPte - (ULONG)StartPde)); 00318 00319 // 00320 // Fill in the PTEs for non-paged pool. 00321 // 00322 00323 LastPte = MiGetPteAddress((ULONG)MmNonPagedPoolStart + 00324 MmSizeOfNonPagedPoolInBytes - 1); 00325 while (PointerPte <= LastPte) { 00326 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 00327 NextPhysicalPage += 1; 00328 NumberOfPages -= 1; 00329 if (NumberOfPages == 0) { 00330 ASSERT (NextPhysicalPage != (FreeDescriptor->BasePage + 00331 FreeDescriptor->PageCount)); 00332 NextPhysicalPage = FreeDescriptor->BasePage; 00333 NumberOfPages = FreeDescriptor->PageCount; 00334 } 00335 *PointerPte = TempPte; 00336 PointerPte++; 00337 } 00338 00339 // 00340 // Zero the remaining PTEs (if any). 00341 // 00342 00343 while (((ULONG)PointerPte & (PAGE_SIZE - 1)) != 0) { 00344 *PointerPte = ZeroKernelPte; 00345 PointerPte++; 00346 } 00347 00348 MmPageAlignedPoolBase[NonPagedPool] = MmNonPagedPoolStart; 00349 00350 // 00351 // Non-paged pages now exist, build the pool structures. 00352 // 00353 00354 MmNonPagedPoolExpansionStart = (PVOID)((PCHAR)MmNonPagedPoolStart + 00355 MmSizeOfNonPagedPoolInBytes); 00356 MiInitializeNonPagedPool (MmNonPagedPoolStart); 00357 00358 // 00359 // Before Non-paged pool can be used, the PFN database must 00360 // be built. This is due to the fact that the start and end of 00361 // allocation bits for nonpaged pool are maintained in the 00362 // PFN elements for the corresponding pages. 00363 // 00364 00365 // 00366 // Calculate the number of pages required from page zero to 00367 // the highest page. 00368 // 00369 // Get the number of secondary colors and add the arrary for tracking 00370 // secondary colors to the end of the PFN database. 00371 // 00372 00373 // 00374 // Get secondary color value from registry. 00375 // 00376 00377 if (MmSecondaryColors == 0) { 00378 MmSecondaryColors = PCR->SecondLevelDcacheSize; 00379 } 00380 00381 MmSecondaryColors = MmSecondaryColors >> PAGE_SHIFT; 00382 00383 // 00384 // Make sure value is power of two and within limits. 00385 // 00386 00387 if (((MmSecondaryColors & (MmSecondaryColors -1)) != 0) || 00388 (MmSecondaryColors < MM_SECONDARY_COLORS_MIN) || 00389 (MmSecondaryColors > MM_SECONDARY_COLORS_MAX)) { 00390 MmSecondaryColors = MM_SECONDARY_COLORS_DEFAULT; 00391 } 00392 00393 MmSecondaryColorMask = (MmSecondaryColors - 1) & ~MM_COLOR_MASK; 00394 00395 PfnAllocation = 1 + ((((MmHighestPhysicalPage + 1) * sizeof(MMPFN)) + 00396 (MmSecondaryColors * sizeof(MMCOLOR_TABLES)*2)) 00397 >> PAGE_SHIFT); 00398 00399 // 00400 // Calculate the start of the Pfn Database (it starts a physical 00401 // page zero, even if the Lowest physical page is not zero). 00402 // 00403 00404 PointerPte = MiReserveSystemPtes (PfnAllocation, 00405 NonPagedPoolExpansion, 00406 0, 00407 0, 00408 TRUE); 00409 00410 MmPfnDatabase = (PMMPFN)(MiGetVirtualAddressMappedByPte (PointerPte)); 00411 00412 // 00413 // Go through the memory descriptors and for each physical page 00414 // make the PFN database has a valid PTE to map it. This allows 00415 // machines with sparse physical memory to have a minimal PFN 00416 // database. 00417 // 00418 00419 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink; 00420 00421 while (NextMd != &LoaderBlock->MemoryDescriptorListHead) { 00422 00423 MemoryDescriptor = CONTAINING_RECORD(NextMd, 00424 MEMORY_ALLOCATION_DESCRIPTOR, 00425 ListEntry); 00426 00427 PointerPte = MiGetPteAddress (MI_PFN_ELEMENT( 00428 MemoryDescriptor->BasePage)); 00429 00430 LastPte = MiGetPteAddress (((PCHAR)(MI_PFN_ELEMENT( 00431 MemoryDescriptor->BasePage + 00432 MemoryDescriptor->PageCount))) - 1); 00433 00434 while (PointerPte <= LastPte) { 00435 if (PointerPte->u.Hard.Valid == 0) { 00436 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 00437 NextPhysicalPage += 1; 00438 NumberOfPages -= 1; 00439 if (NumberOfPages == 0) { 00440 ASSERT (NextPhysicalPage != (FreeDescriptor->BasePage + 00441 FreeDescriptor->PageCount)); 00442 NextPhysicalPage = FreeDescriptor->BasePage; 00443 NumberOfPages = FreeDescriptor->PageCount; 00444 } 00445 *PointerPte = TempPte; 00446 RtlZeroMemory (MiGetVirtualAddressMappedByPte (PointerPte), 00447 PAGE_SIZE); 00448 } 00449 PointerPte++; 00450 } 00451 NextMd = MemoryDescriptor->ListEntry.Flink; 00452 } 00453 00454 MmFreePagesByColor[0] = (PMMCOLOR_TABLES) 00455 &MmPfnDatabase[MmHighestPhysicalPage + 1]; 00456 00457 MmFreePagesByColor[1] = &MmFreePagesByColor[0][MmSecondaryColors]; 00458 00459 // 00460 // Make sure the PTEs are mapped. 00461 // 00462 00463 00464 if (!MI_IS_PHYSICAL_ADDRESS(MmFreePagesByColor[0])) { 00465 PointerPte = MiGetPteAddress (&MmFreePagesByColor[0][0]); 00466 00467 LastPte = MiGetPteAddress ( 00468 (PVOID)((PCHAR)&MmFreePagesByColor[1][MmSecondaryColors] - 1)); 00469 00470 while (PointerPte <= LastPte) { 00471 if (PointerPte->u.Hard.Valid == 0) { 00472 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage; 00473 NextPhysicalPage += 1; 00474 *PointerPte = TempPte; 00475 RtlZeroMemory (MiGetVirtualAddressMappedByPte (PointerPte), 00476 PAGE_SIZE); 00477 } 00478 PointerPte++; 00479 } 00480 } 00481 00482 for (i = 0; i < MmSecondaryColors; i++) { 00483 MmFreePagesByColor[ZeroedPageList][i].Flink = MM_EMPTY_LIST; 00484 MmFreePagesByColor[FreePageList][i].Flink = MM_EMPTY_LIST; 00485 } 00486 00487 #if MM_MAXIMUM_NUMBER_OF_COLORS > 1 00488 for (i = 0; i < MM_MAXIMUM_NUMBER_OF_COLORS; i++) { 00489 MmFreePagesByPrimaryColor[ZeroedPageList][i].ListName = ZeroedPageList; 00490 MmFreePagesByPrimaryColor[FreePageList][i].ListName = FreePageList; 00491 MmFreePagesByPrimaryColor[ZeroedPageList][i].Flink = MM_EMPTY_LIST; 00492 MmFreePagesByPrimaryColor[FreePageList][i].Flink = MM_EMPTY_LIST; 00493 MmFreePagesByPrimaryColor[ZeroedPageList][i].Blink = MM_EMPTY_LIST; 00494 MmFreePagesByPrimaryColor[FreePageList][i].Blink = MM_EMPTY_LIST; 00495 } 00496 #endif 00497 00498 // 00499 // Go through the page table entries and for any page which is 00500 // valid, update the corresponding PFN database element. 00501 // 00502 00503 Pde = MiGetPdeAddress (NULL); 00504 PointerPde = MiGetPdeAddress (PTE_BASE); 00505 va = 0; 00506 00507 for (i = 0; i < PDE_PER_PAGE; i++) { 00508 if (Pde->u.Hard.Valid == 1) { 00509 00510 PdePage = Pde->u.Hard.PageFrameNumber; 00511 Pfn1 = MI_PFN_ELEMENT(PdePage); 00512 Pfn1->PteFrame = PointerPde->u.Hard.PageFrameNumber; 00513 Pfn1->PteAddress = Pde; 00514 Pfn1->u2.ShareCount += 1; 00515 Pfn1->u3.e2.ReferenceCount = 1; 00516 Pfn1->u3.e1.PageLocation = ActiveAndValid; 00517 Pfn1->u3.e1.PageColor = MI_GET_COLOR_FROM_SECONDARY( 00518 MI_GET_PAGE_COLOR_FROM_PTE (Pde)); 00519 00520 PointerPte = MiGetPteAddress (va); 00521 00522 for (j = 0 ; j < PTE_PER_PAGE; j++) { 00523 if (PointerPte->u.Hard.Valid == 1) { 00524 00525 Pfn1->u2.ShareCount += 1; 00526 00527 PageFrameIndex = PointerPte->u.Hard.PageFrameNumber; 00528 00529 if (PageFrameIndex <= MmHighestPhysicalPage) { 00530 00531 Pfn2 = MI_PFN_ELEMENT(PageFrameIndex); 00532 00533 if (MmIsAddressValid(Pfn2) && 00534 MmIsAddressValid((PUCHAR)(Pfn2+1)-1)) { 00535 00536 Pfn2->PteFrame = PdePage; 00537 Pfn2->PteAddress = PointerPte; 00538 Pfn2->u2.ShareCount += 1; 00539 Pfn2->u3.e2.ReferenceCount = 1; 00540 Pfn2->u3.e1.PageLocation = ActiveAndValid; 00541 Pfn2->u3.e1.PageColor = MI_GET_COLOR_FROM_SECONDARY( 00542 MI_GET_PAGE_COLOR_FROM_PTE ( 00543 PointerPte)); 00544 } 00545 } 00546 } 00547 va += PAGE_SIZE; 00548 PointerPte++; 00549 } 00550 } else { 00551 va += (ULONG)PDE_PER_PAGE * (ULONG)PAGE_SIZE; 00552 } 00553 Pde++; 00554 } 00555 00556 // 00557 // If page zero is still unused, mark it as in use. This is 00558 // temporary as we want to find bugs where a physical page 00559 // is specified as zero. 00560 // 00561 00562 Pfn1 = &MmPfnDatabase[MmLowestPhysicalPage]; 00563 if (Pfn1->u3.e2.ReferenceCount == 0) { 00564 00565 // 00566 // Make the reference count non-zero and point it into a 00567 // page directory. 00568 // 00569 00570 Pde = MiGetPdeAddress (0xb0000000); 00571 PdePage = Pde->u.Hard.PageFrameNumber; 00572 Pfn1->PteFrame = PdePageNumber; 00573 Pfn1->PteAddress = Pde; 00574 Pfn1->u2.ShareCount += 1; 00575 Pfn1->u3.e2.ReferenceCount = 1; 00576 Pfn1->u3.e1.PageLocation = ActiveAndValid; 00577 Pfn1->u3.e1.PageColor = MI_GET_COLOR_FROM_SECONDARY( 00578 MI_GET_PAGE_COLOR_FROM_PTE (Pde)); 00579 } 00580 00581 // end of temporary set to physical page zero. 00582 00583 // 00584 // 00585 // Walk through the memory descriptors and add pages to the 00586 // free list in the PFN database. 00587 // 00588 00589 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink; 00590 00591 while (NextMd != &LoaderBlock->MemoryDescriptorListHead) { 00592 00593 MemoryDescriptor = CONTAINING_RECORD(NextMd, 00594 MEMORY_ALLOCATION_DESCRIPTOR, 00595 ListEntry); 00596 00597 i = MemoryDescriptor->PageCount; 00598 NextPhysicalPage = MemoryDescriptor->BasePage; 00599 00600 switch (MemoryDescriptor->MemoryType) { 00601 case LoaderBad: 00602 while (i != 0) { 00603 MiInsertPageInList (MmPageLocationList[BadPageList], 00604 NextPhysicalPage); 00605 i -= 1; 00606 NextPhysicalPage += 1; 00607 } 00608 break; 00609 00610 case LoaderFree: 00611 case LoaderLoadedProgram: 00612 case LoaderFirmwareTemporary: 00613 case LoaderOsloaderStack: 00614 00615 Pfn1 = MI_PFN_ELEMENT (NextPhysicalPage); 00616 while (i != 0) { 00617 if (Pfn1->u3.e2.ReferenceCount == 0) { 00618 00619 // 00620 // Set the PTE address to the phyiscal page for 00621 // virtual address alignment checking. 00622 // 00623 00624 Pfn1->PteAddress = 00625 (PMMPTE)(NextPhysicalPage << PTE_SHIFT); 00626 00627 Pfn1->u3.e1.PageColor = MI_GET_COLOR_FROM_SECONDARY( 00628 MI_GET_PAGE_COLOR_FROM_PTE ( 00629 Pfn1->PteAddress)); 00630 MiInsertPageInList (MmPageLocationList[FreePageList], 00631 NextPhysicalPage); 00632 } 00633 Pfn1++; 00634 i -= 1; 00635 NextPhysicalPage += 1; 00636 } 00637 break; 00638 00639 default: 00640 00641 PointerPte = MiGetPteAddress (KSEG0_BASE + 00642 (NextPhysicalPage << PAGE_SHIFT)); 00643 Pfn1 = MI_PFN_ELEMENT (NextPhysicalPage); 00644 while (i != 0) { 00645 00646 // 00647 // Set page as in use. 00648 // 00649 00650 if (Pfn1->u3.e2.ReferenceCount == 0) { 00651 Pfn1->PteFrame = PdePageNumber; 00652 Pfn1->PteAddress = PointerPte; 00653 Pfn1->u2.ShareCount += 1; 00654 Pfn1->u3.e2.ReferenceCount = 1; 00655 Pfn1->u3.e1.PageLocation = ActiveAndValid; 00656 Pfn1->u3.e1.PageColor = MI_GET_COLOR_FROM_SECONDARY( 00657 MI_GET_PAGE_COLOR_FROM_PTE ( 00658 PointerPte)); 00659 } 00660 Pfn1++; 00661 i -= 1; 00662 NextPhysicalPage += 1; 00663 PointerPte += 1; 00664 } 00665 00666 break; 00667 } 00668 00669 NextMd = MemoryDescriptor->ListEntry.Flink; 00670 } 00671 00672 // 00673 // Indicate that the PFN database is allocated in NonPaged pool. 00674 // 00675 00676 Pfn1 = MI_PFN_ELEMENT(MiGetPteAddress(&MmPfnDatabase[MmLowestPhysicalPage])->u.Hard.PageFrameNumber); 00677 Pfn1->u3.e1.StartOfAllocation = 1; 00678 Pfn1 = MI_PFN_ELEMENT(MiGetPteAddress(&MmPfnDatabase[MmHighestPhysicalPage])->u.Hard.PageFrameNumber); 00679 Pfn1->u3.e1.EndOfAllocation = 1; 00680 00681 // 00682 // Indicate that nonpaged pool must succeed is allocated in 00683 // nonpaged pool. 00684 // 00685 00686 i = MmSizeOfNonPagedMustSucceed; 00687 Pfn1 = MI_PFN_ELEMENT(MiGetPteAddress(MmNonPagedMustSucceed)->u.Hard.PageFrameNumber); 00688 00689 while ((LONG)i > 0) { 00690 Pfn1->u3.e1.StartOfAllocation = 1; 00691 Pfn1->u3.e1.EndOfAllocation = 1; 00692 i -= PAGE_SIZE; 00693 Pfn1 += 1; 00694 } 00695 00696 KeInitializeSpinLock (&MmSystemSpaceLock); 00697 KeInitializeSpinLock (&MmPfnLock); 00698 00699 // 00700 // Initialize the nonpaged available PTEs for mapping I/O space 00701 // and kernel stacks. 00702 // 00703 00704 PointerPte = MiGetPteAddress (MmNonPagedSystemStart); 00705 00706 PointerPte = (PMMPTE)PAGE_ALIGN (PointerPte); 00707 00708 MmNumberOfSystemPtes = MiGetPteAddress(MmNonPagedPoolStart) - PointerPte - 1; 00709 00710 MiInitializeSystemPtes (PointerPte, MmNumberOfSystemPtes, SystemPteSpace); 00711 00712 // 00713 // Initialize the nonpaged pool. 00714 // 00715 00716 InitializePool(NonPagedPool,0); 00717 00718 // 00719 // Initialize memory management structures for this process. 00720 // 00721 00722 // 00723 // Build working set list. System initialization has created 00724 // a PTE for hyperspace. 00725 // 00726 // Note, we can't remove a zeroed page as hyper space does not 00727 // exist and we map non-zeroed pages into hyper space to zero. 00728 // 00729 00730 PointerPte = MiGetPdeAddress(HYPER_SPACE); 00731 00732 ASSERT (PointerPte->u.Hard.Valid == 1); 00733 PointerPte->u.Hard.Write = 1; 00734 PageFrameIndex = PointerPte->u.Hard.PageFrameNumber; 00735 00736 // 00737 // Point to the page table page we just created and zero it. 00738 // 00739 00740 PointerPte = MiGetPteAddress(HYPER_SPACE); 00741 RtlZeroMemory ((PVOID)PointerPte, PAGE_SIZE); 00742 00743 // 00744 // Hyper space now exists, set the necessary variables. 00745 // 00746 00747 MmFirstReservedMappingPte = MiGetPteAddress (FIRST_MAPPING_PTE); 00748 MmLastReservedMappingPte = MiGetPteAddress (LAST_MAPPING_PTE); 00749 00750 MmWorkingSetList = WORKING_SET_LIST; 00751 MmWsle = (PMMWSLE)((PUCHAR)WORKING_SET_LIST + sizeof(MMWSL)); 00752 00753 // 00754 // Initialize this process's memory management structures including 00755 // the working set list. 00756 // 00757 00758 // 00759 // The pfn element for the page directory has already been initialized, 00760 // zero the reference count and the share count so they won't be 00761 // wrong. 00762 // 00763 00764 Pfn1 = MI_PFN_ELEMENT (PdePageNumber); 00765 Pfn1->u2.ShareCount = 0; 00766 Pfn1->u3.e2.ReferenceCount = 0; 00767 Pfn1->u3.e1.PageColor = 0; 00768 00769 // 00770 // The pfn element for the PDE which maps hyperspace has already 00771 // been initialized, zero the reference count and the share count 00772 // so they won't be wrong. 00773 // 00774 00775 Pfn1 = MI_PFN_ELEMENT (PageFrameIndex); 00776 Pfn1->u2.ShareCount = 0; 00777 Pfn1->u3.e2.ReferenceCount = 0; 00778 Pfn1->u3.e1.PageColor = 1; 00779 00780 00781 CurrentProcess = PsGetCurrentProcess (); 00782 00783 // 00784 // Get a page for the working set list and map it into the Page 00785 // directory at the page after hyperspace. 00786 // 00787 00788 PointerPte = MiGetPteAddress (HYPER_SPACE); 00789 PageFrameIndex = MiRemoveAnyPage (MI_GET_PAGE_COLOR_FROM_PTE(PointerPte)); 00790 CurrentProcess->WorkingSetPage = PageFrameIndex; 00791 00792 TempPte.u.Hard.PageFrameNumber = PageFrameIndex; 00793 PointerPde = MiGetPdeAddress (HYPER_SPACE) + 1; 00794 00795 *PointerPde = TempPte; 00796 00797 PointerPte = MiGetVirtualAddressMappedByPte (PointerPde); 00798 00799 RtlZeroMemory ((PVOID)PointerPte, PAGE_SIZE); 00800 00801 TempPte = *PointerPde; 00802 TempPte.u.Hard.Valid = 0; 00803 00804 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); 00805 KeFlushSingleTb (PointerPte, 00806 TRUE, 00807 FALSE, 00808 (PHARDWARE_PTE)PointerPde, 00809 TempPte.u.Hard); 00810 00811 KeLowerIrql(OldIrql); 00812 00813 CurrentProcess->Vm.MaximumWorkingSetSize = MmSystemProcessWorkingSetMax; 00814 CurrentProcess->Vm.MinimumWorkingSetSize = MmSystemProcessWorkingSetMin; 00815 00816 MmInitializeProcessAddressSpace (CurrentProcess, 00817 (PEPROCESS)NULL, 00818 (PVOID)NULL); 00819 00820 *PointerPde = ZeroKernelPte; 00821 00822 // 00823 // Check to see if moving the secondary page structures to the end 00824 // of the PFN database is a waste of memory. And if so, copy it 00825 // to paged pool. 00826 // 00827 // If the PFN datbase ends on a page aligned boundary and the 00828 // size of the two arrays is less than a page, free the page 00829 // and allocate nonpagedpool for this. 00830 // 00831 00832 if ((((ULONG)MmFreePagesByColor[0] & (PAGE_SIZE - 1)) == 0) && 00833 ((MmSecondaryColors * 2 * sizeof(MMCOLOR_TABLES)) < PAGE_SIZE)) { 00834 00835 PMMCOLOR_TABLES c; 00836 00837 c = MmFreePagesByColor[0]; 00838 00839 MmFreePagesByColor[0] = ExAllocatePoolWithTag (NonPagedPoolMustSucceed, 00840 MmSecondaryColors * 2 * sizeof(MMCOLOR_TABLES), 00841 ' mM'); 00842 00843 MmFreePagesByColor[1] = &MmFreePagesByColor[0][MmSecondaryColors]; 00844 00845 RtlMoveMemory (MmFreePagesByColor[0], 00846 c, 00847 MmSecondaryColors * 2 * sizeof(MMCOLOR_TABLES)); 00848 00849 // 00850 // Free the page. 00851 // 00852 00853 if (!MI_IS_PHYSICAL_ADDRESS(c)) { 00854 PointerPte = MiGetPteAddress(c); 00855 PageFrameIndex = PointerPte->u.Hard.PageFrameNumber; 00856 *PointerPte = ZeroKernelPte; 00857 } else { 00858 PageFrameIndex = MI_CONVERT_PHYSICAL_TO_PFN (c); 00859 } 00860 00861 Pfn1 = MI_PFN_ELEMENT (PageFrameIndex); 00862 ASSERT ((Pfn1->u3.e2.ReferenceCount <= 1) && (Pfn1->u2.ShareCount <= 1)); 00863 Pfn1->u2.ShareCount = 0; 00864 Pfn1->u3.e2.ReferenceCount = 0; 00865 MI_SET_PFN_DELETED (Pfn1); 00866 #if DBG 00867 Pfn1->u3.e1.PageLocation = StandbyPageList; 00868 #endif //DBG 00869 MiInsertPageInList (MmPageLocationList[FreePageList], PageFrameIndex); 00870 } 00871 00872 return; 00873 }


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