Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninit.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: BSD - See COPYING.ARM in the top level directory 00004 * FILE: ntoskrnl/mm/ARM3/i386/init.c 00005 * PURPOSE: ARM Memory Manager Initialization for x86 00006 * PROGRAMMERS: ReactOS Portable Systems Group 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 #define MODULE_INVOLVED_IN_ARM3 00016 #include "../../ARM3/miarm.h" 00017 00018 /* GLOBALS ********************************************************************/ 00019 00020 /* Template PTE and PDE for a kernel page */ 00021 MMPTE ValidKernelPde = {{PTE_VALID|PTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}}; 00022 MMPTE ValidKernelPte = {{PTE_VALID|PTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}}; 00023 00024 /* Template PDE for a demand-zero page */ 00025 MMPDE DemandZeroPde = {{MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS}}; 00026 MMPTE DemandZeroPte = {{MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS}}; 00027 00028 /* Template PTE for prototype page */ 00029 MMPTE PrototypePte = {{(MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS) | 00030 PTE_PROTOTYPE | (MI_PTE_LOOKUP_NEEDED << PAGE_SHIFT)}}; 00031 00032 /* Template PTE for decommited page */ 00033 MMPTE MmDecommittedPte = {{MM_DECOMMIT << MM_PTE_SOFTWARE_PROTECTION_BITS}}; 00034 00035 /* PRIVATE FUNCTIONS **********************************************************/ 00036 00037 VOID 00038 NTAPI 00039 INIT_FUNCTION 00040 MiInitializeSessionSpaceLayout() 00041 { 00042 // 00043 // Set the size of session view, pool, and image 00044 // 00045 MmSessionSize = MI_SESSION_SIZE; 00046 MmSessionViewSize = MI_SESSION_VIEW_SIZE; 00047 MmSessionPoolSize = MI_SESSION_POOL_SIZE; 00048 MmSessionImageSize = MI_SESSION_IMAGE_SIZE; 00049 00050 // 00051 // Set the size of system view 00052 // 00053 MmSystemViewSize = MI_SYSTEM_VIEW_SIZE; 00054 00055 // 00056 // This is where it all ends 00057 // 00058 MiSessionImageEnd = (PVOID)PTE_BASE; 00059 00060 // 00061 // This is where we will load Win32k.sys and the video driver 00062 // 00063 MiSessionImageStart = (PVOID)((ULONG_PTR)MiSessionImageEnd - 00064 MmSessionImageSize); 00065 00066 // 00067 // So the view starts right below the session working set (itself below 00068 // the image area) 00069 // 00070 MiSessionViewStart = (PVOID)((ULONG_PTR)MiSessionImageEnd - 00071 MmSessionImageSize - 00072 MI_SESSION_WORKING_SET_SIZE - 00073 MmSessionViewSize); 00074 00075 // 00076 // Session pool follows 00077 // 00078 MiSessionPoolEnd = MiSessionViewStart; 00079 MiSessionPoolStart = (PVOID)((ULONG_PTR)MiSessionPoolEnd - 00080 MmSessionPoolSize); 00081 00082 // 00083 // And it all begins here 00084 // 00085 MmSessionBase = MiSessionPoolStart; 00086 00087 // 00088 // Sanity check that our math is correct 00089 // 00090 ASSERT((ULONG_PTR)MmSessionBase + MmSessionSize == PTE_BASE); 00091 00092 // 00093 // Session space ends wherever image session space ends 00094 // 00095 MiSessionSpaceEnd = MiSessionImageEnd; 00096 00097 // 00098 // System view space ends at session space, so now that we know where 00099 // this is, we can compute the base address of system view space itself. 00100 // 00101 MiSystemViewStart = (PVOID)((ULONG_PTR)MmSessionBase - 00102 MmSystemViewSize); 00103 00104 /* Compute the PTE addresses for all the addresses we carved out */ 00105 MiSessionImagePteStart = MiAddressToPte(MiSessionImageStart); 00106 MiSessionImagePteEnd = MiAddressToPte(MiSessionImageEnd); 00107 MiSessionBasePte = MiAddressToPte(MmSessionBase); 00108 MiSessionLastPte = MiAddressToPte(MiSessionSpaceEnd); 00109 } 00110 00111 VOID 00112 NTAPI 00113 INIT_FUNCTION 00114 MiComputeNonPagedPoolVa(IN ULONG FreePages) 00115 { 00116 IN PFN_NUMBER PoolPages; 00117 00118 /* Check if this is a machine with less than 256MB of RAM, and no overide */ 00119 if ((MmNumberOfPhysicalPages <= MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING) && 00120 !(MmSizeOfNonPagedPoolInBytes)) 00121 { 00122 /* Force the non paged pool to be 2MB so we can reduce RAM usage */ 00123 MmSizeOfNonPagedPoolInBytes = 2 * _1MB; 00124 } 00125 00126 /* Hyperspace ends here */ 00127 MmHyperSpaceEnd = (PVOID)((ULONG_PTR)MmSystemCacheWorkingSetList - 1); 00128 00129 /* Check if the user gave a ridicuously large nonpaged pool RAM size */ 00130 if ((MmSizeOfNonPagedPoolInBytes >> PAGE_SHIFT) > (FreePages * 7 / 8)) 00131 { 00132 /* More than 7/8ths of RAM was dedicated to nonpaged pool, ignore! */ 00133 MmSizeOfNonPagedPoolInBytes = 0; 00134 } 00135 00136 /* Check if no registry setting was set, or if the setting was too low */ 00137 if (MmSizeOfNonPagedPoolInBytes < MmMinimumNonPagedPoolSize) 00138 { 00139 /* Start with the minimum (256 KB) and add 32 KB for each MB above 4 */ 00140 MmSizeOfNonPagedPoolInBytes = MmMinimumNonPagedPoolSize; 00141 MmSizeOfNonPagedPoolInBytes += (FreePages - 1024) / 256 * MmMinAdditionNonPagedPoolPerMb; 00142 } 00143 00144 /* Check if the registy setting or our dynamic calculation was too high */ 00145 if (MmSizeOfNonPagedPoolInBytes > MI_MAX_INIT_NONPAGED_POOL_SIZE) 00146 { 00147 /* Set it to the maximum */ 00148 MmSizeOfNonPagedPoolInBytes = MI_MAX_INIT_NONPAGED_POOL_SIZE; 00149 } 00150 00151 /* Check if a percentage cap was set through the registry */ 00152 if (MmMaximumNonPagedPoolPercent) UNIMPLEMENTED; 00153 00154 /* Page-align the nonpaged pool size */ 00155 MmSizeOfNonPagedPoolInBytes &= ~(PAGE_SIZE - 1); 00156 00157 /* Now, check if there was a registry size for the maximum size */ 00158 if (!MmMaximumNonPagedPoolInBytes) 00159 { 00160 /* Start with the default (1MB) */ 00161 MmMaximumNonPagedPoolInBytes = MmDefaultMaximumNonPagedPool; 00162 00163 /* Add space for PFN database */ 00164 MmMaximumNonPagedPoolInBytes += (ULONG) 00165 PAGE_ALIGN((MmHighestPhysicalPage + 1) * sizeof(MMPFN)); 00166 00167 /* Check if the machine has more than 512MB of free RAM */ 00168 if (FreePages >= 0x1F000) 00169 { 00170 /* Add 200KB for each MB above 4 */ 00171 MmMaximumNonPagedPoolInBytes += (FreePages - 1024) / 256 * 00172 (MmMaxAdditionNonPagedPoolPerMb / 2); 00173 if (MmMaximumNonPagedPoolInBytes < MI_MAX_NONPAGED_POOL_SIZE) 00174 { 00175 /* Make it at least 128MB since this machine has a lot of RAM */ 00176 MmMaximumNonPagedPoolInBytes = MI_MAX_NONPAGED_POOL_SIZE; 00177 } 00178 } 00179 else 00180 { 00181 /* Add 400KB for each MB above 4 */ 00182 MmMaximumNonPagedPoolInBytes += (FreePages - 1024) / 256 * 00183 MmMaxAdditionNonPagedPoolPerMb; 00184 } 00185 } 00186 00187 /* Make sure there's at least 16 pages + the PFN available for expansion */ 00188 PoolPages = MmSizeOfNonPagedPoolInBytes + (PAGE_SIZE * 16) + 00189 ((ULONG)PAGE_ALIGN(MmHighestPhysicalPage + 1) * sizeof(MMPFN)); 00190 if (MmMaximumNonPagedPoolInBytes < PoolPages) 00191 { 00192 /* The maximum should be at least high enough to cover all the above */ 00193 MmMaximumNonPagedPoolInBytes = PoolPages; 00194 } 00195 00196 /* Systems with 2GB of kernel address space get double the size */ 00197 PoolPages = MI_MAX_NONPAGED_POOL_SIZE * 2; 00198 00199 /* On the other hand, make sure that PFN + nonpaged pool doesn't get too big */ 00200 if (MmMaximumNonPagedPoolInBytes > PoolPages) 00201 { 00202 /* Trim it down to the maximum architectural limit (256MB) */ 00203 MmMaximumNonPagedPoolInBytes = PoolPages; 00204 } 00205 00206 /* Check if this is a system with > 128MB of non paged pool */ 00207 if (MmMaximumNonPagedPoolInBytes > MI_MAX_NONPAGED_POOL_SIZE) 00208 { 00209 /* Check if the initial size is less than the extra 128MB boost */ 00210 if (MmSizeOfNonPagedPoolInBytes < (MmMaximumNonPagedPoolInBytes - 00211 MI_MAX_NONPAGED_POOL_SIZE)) 00212 { 00213 /* FIXME: Should check if the initial pool can be expanded */ 00214 00215 /* Assume no expansion possible, check ift he maximum is too large */ 00216 if (MmMaximumNonPagedPoolInBytes > (MmSizeOfNonPagedPoolInBytes + 00217 MI_MAX_NONPAGED_POOL_SIZE)) 00218 { 00219 /* Set it to the initial value plus the boost */ 00220 MmMaximumNonPagedPoolInBytes = MmSizeOfNonPagedPoolInBytes + 00221 MI_MAX_NONPAGED_POOL_SIZE; 00222 } 00223 } 00224 } 00225 } 00226 00227 NTSTATUS 00228 NTAPI 00229 INIT_FUNCTION 00230 MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 00231 { 00232 PFN_NUMBER PageFrameIndex; 00233 PMMPTE StartPde, EndPde, PointerPte, LastPte; 00234 MMPTE TempPde, TempPte; 00235 PVOID NonPagedPoolExpansionVa; 00236 KIRQL OldIrql; 00237 PMMPFN Pfn1; 00238 ULONG Flags; 00239 00240 /* Check for global bit */ 00241 #if 0 00242 if (KeFeatureBits & KF_GLOBAL_PAGE) 00243 { 00244 /* Set it on the template PTE and PDE */ 00245 ValidKernelPte.u.Hard.Global = TRUE; 00246 ValidKernelPde.u.Hard.Global = TRUE; 00247 } 00248 #endif 00249 /* Now templates are ready */ 00250 TempPte = ValidKernelPte; 00251 TempPde = ValidKernelPde; 00252 00253 // 00254 // Set CR3 for the system process 00255 // 00256 PointerPte = MiAddressToPde(PDE_BASE); 00257 PageFrameIndex = PFN_FROM_PTE(PointerPte) << PAGE_SHIFT; 00258 PsGetCurrentProcess()->Pcb.DirectoryTableBase[0] = PageFrameIndex; 00259 00260 // 00261 // Blow away user-mode 00262 // 00263 StartPde = MiAddressToPde(0); 00264 EndPde = MiAddressToPde(KSEG0_BASE); 00265 RtlZeroMemory(StartPde, (EndPde - StartPde) * sizeof(MMPTE)); 00266 00267 /* Compute non paged pool limits and size */ 00268 MiComputeNonPagedPoolVa(MiNumberOfFreePages); 00269 00270 // 00271 // Now calculate the nonpaged pool expansion VA region 00272 // 00273 MmNonPagedPoolStart = (PVOID)((ULONG_PTR)MmNonPagedPoolEnd - 00274 MmMaximumNonPagedPoolInBytes + 00275 MmSizeOfNonPagedPoolInBytes); 00276 MmNonPagedPoolStart = (PVOID)PAGE_ALIGN(MmNonPagedPoolStart); 00277 NonPagedPoolExpansionVa = MmNonPagedPoolStart; 00278 DPRINT("NP Pool has been tuned to: %d bytes and %d bytes\n", 00279 MmSizeOfNonPagedPoolInBytes, MmMaximumNonPagedPoolInBytes); 00280 00281 // 00282 // Now calculate the nonpaged system VA region, which includes the 00283 // nonpaged pool expansion (above) and the system PTEs. Note that it is 00284 // then aligned to a PDE boundary (4MB). 00285 // 00286 MiNonPagedSystemSize = (MmNumberOfSystemPtes + 1) * PAGE_SIZE; 00287 MmNonPagedSystemStart = (PVOID)((ULONG_PTR)MmNonPagedPoolStart - 00288 MiNonPagedSystemSize); 00289 MmNonPagedSystemStart = (PVOID)((ULONG_PTR)MmNonPagedSystemStart & 00290 ~(PDE_MAPPED_VA - 1)); 00291 00292 // 00293 // Don't let it go below the minimum 00294 // 00295 if (MmNonPagedSystemStart < (PVOID)0xEB000000) 00296 { 00297 // 00298 // This is a hard-coded limit in the Windows NT address space 00299 // 00300 MmNonPagedSystemStart = (PVOID)0xEB000000; 00301 00302 // 00303 // Reduce the amount of system PTEs to reach this point 00304 // 00305 MmNumberOfSystemPtes = ((ULONG_PTR)MmNonPagedPoolStart - 00306 (ULONG_PTR)MmNonPagedSystemStart) >> 00307 PAGE_SHIFT; 00308 MmNumberOfSystemPtes--; 00309 ASSERT(MmNumberOfSystemPtes > 1000); 00310 } 00311 00312 // 00313 // Check if we are in a situation where the size of the paged pool 00314 // is so large that it overflows into nonpaged pool 00315 // 00316 if (MmSizeOfPagedPoolInBytes > 00317 ((ULONG_PTR)MmNonPagedSystemStart - (ULONG_PTR)MmPagedPoolStart)) 00318 { 00319 // 00320 // We need some recalculations here 00321 // 00322 DPRINT1("Paged pool is too big!\n"); 00323 } 00324 00325 // 00326 // Normally, the PFN database should start after the loader images. 00327 // This is already the case in ReactOS, but for now we want to co-exist 00328 // with the old memory manager, so we'll create a "Shadow PFN Database" 00329 // instead, and arbitrarly start it at 0xB0000000. 00330 // 00331 MmPfnDatabase = (PVOID)0xB0000000; 00332 ASSERT(((ULONG_PTR)MmPfnDatabase & (PDE_MAPPED_VA - 1)) == 0); 00333 00334 // 00335 // Non paged pool comes after the PFN database 00336 // 00337 MmNonPagedPoolStart = (PVOID)((ULONG_PTR)MmPfnDatabase + 00338 (MxPfnAllocation << PAGE_SHIFT)); 00339 00340 // 00341 // Now we actually need to get these many physical pages. Nonpaged pool 00342 // is actually also physically contiguous (but not the expansion) 00343 // 00344 PageFrameIndex = MxGetNextPage(MxPfnAllocation + 00345 (MmSizeOfNonPagedPoolInBytes >> PAGE_SHIFT)); 00346 ASSERT(PageFrameIndex != 0); 00347 DPRINT("PFN DB PA PFN begins at: %lx\n", PageFrameIndex); 00348 DPRINT("NP PA PFN begins at: %lx\n", PageFrameIndex + MxPfnAllocation); 00349 00350 /* Convert nonpaged pool size from bytes to pages */ 00351 MmMaximumNonPagedPoolInPages = MmMaximumNonPagedPoolInBytes >> PAGE_SHIFT; 00352 00353 // 00354 // Now we need some pages to create the page tables for the NP system VA 00355 // which includes system PTEs and expansion NP 00356 // 00357 StartPde = MiAddressToPde(MmNonPagedSystemStart); 00358 EndPde = MiAddressToPde((PVOID)((ULONG_PTR)MmNonPagedPoolEnd - 1)); 00359 while (StartPde <= EndPde) 00360 { 00361 // 00362 // Get a page 00363 // 00364 TempPde.u.Hard.PageFrameNumber = MxGetNextPage(1); 00365 MI_WRITE_VALID_PTE(StartPde, TempPde); 00366 00367 // 00368 // Zero out the page table 00369 // 00370 PointerPte = MiPteToAddress(StartPde); 00371 RtlZeroMemory(PointerPte, PAGE_SIZE); 00372 00373 // 00374 // Next 00375 // 00376 StartPde++; 00377 } 00378 00379 // 00380 // Now we need pages for the page tables which will map initial NP 00381 // 00382 StartPde = MiAddressToPde(MmPfnDatabase); 00383 EndPde = MiAddressToPde((PVOID)((ULONG_PTR)MmNonPagedPoolStart + 00384 MmSizeOfNonPagedPoolInBytes - 1)); 00385 while (StartPde <= EndPde) 00386 { 00387 // 00388 // Get a page 00389 // 00390 TempPde.u.Hard.PageFrameNumber = MxGetNextPage(1); 00391 MI_WRITE_VALID_PTE(StartPde, TempPde); 00392 00393 // 00394 // Zero out the page table 00395 // 00396 PointerPte = MiPteToAddress(StartPde); 00397 RtlZeroMemory(PointerPte, PAGE_SIZE); 00398 00399 // 00400 // Next 00401 // 00402 StartPde++; 00403 } 00404 00405 // 00406 // Now remember where the expansion starts 00407 // 00408 MmNonPagedPoolExpansionStart = NonPagedPoolExpansionVa; 00409 00410 // 00411 // Last step is to actually map the nonpaged pool 00412 // 00413 PointerPte = MiAddressToPte(MmNonPagedPoolStart); 00414 LastPte = MiAddressToPte((PVOID)((ULONG_PTR)MmNonPagedPoolStart + 00415 MmSizeOfNonPagedPoolInBytes - 1)); 00416 while (PointerPte <= LastPte) 00417 { 00418 // 00419 // Use one of our contigous pages 00420 // 00421 TempPte.u.Hard.PageFrameNumber = PageFrameIndex++; 00422 MI_WRITE_VALID_PTE(PointerPte++, TempPte); 00423 } 00424 00425 // 00426 // Sanity check: make sure we have properly defined the system PTE space 00427 // 00428 ASSERT(MiAddressToPte(MmNonPagedSystemStart) < 00429 MiAddressToPte(MmNonPagedPoolExpansionStart)); 00430 00431 /* Now go ahead and initialize the nonpaged pool */ 00432 MiInitializeNonPagedPool(); 00433 MiInitializeNonPagedPoolThresholds(); 00434 00435 /* Map the PFN database pages */ 00436 MiMapPfnDatabase(LoaderBlock); 00437 00438 /* Initialize the color tables */ 00439 MiInitializeColorTables(); 00440 00441 /* Build the PFN Database */ 00442 MiInitializePfnDatabase(LoaderBlock); 00443 MmInitializeBalancer(MmAvailablePages, 0); 00444 00445 // 00446 // Reset the descriptor back so we can create the correct memory blocks 00447 // 00448 *MxFreeDescriptor = MxOldFreeDescriptor; 00449 00450 // 00451 // Initialize the nonpaged pool 00452 // 00453 InitializePool(NonPagedPool, 0); 00454 00455 // 00456 // We PDE-aligned the nonpaged system start VA, so haul some extra PTEs! 00457 // 00458 PointerPte = MiAddressToPte(MmNonPagedSystemStart); 00459 MmNumberOfSystemPtes = MiAddressToPte(MmNonPagedPoolExpansionStart) - 00460 PointerPte; 00461 MmNumberOfSystemPtes--; 00462 DPRINT("Final System PTE count: %d (%d bytes)\n", 00463 MmNumberOfSystemPtes, MmNumberOfSystemPtes * PAGE_SIZE); 00464 00465 // 00466 // Create the system PTE space 00467 // 00468 MiInitializeSystemPtes(PointerPte, MmNumberOfSystemPtes, SystemPteSpace); 00469 00470 /* Get the PDE For hyperspace */ 00471 StartPde = MiAddressToPde(HYPER_SPACE); 00472 00473 /* Lock PFN database */ 00474 OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); 00475 00476 /* Allocate a page for hyperspace and create it */ 00477 MI_SET_USAGE(MI_USAGE_PAGE_TABLE); 00478 MI_SET_PROCESS2("Kernel"); 00479 PageFrameIndex = MiRemoveAnyPage(0); 00480 TempPde.u.Hard.PageFrameNumber = PageFrameIndex; 00481 TempPde.u.Hard.Global = FALSE; // Hyperspace is local! 00482 MI_WRITE_VALID_PTE(StartPde, TempPde); 00483 00484 /* Flush the TLB */ 00485 KeFlushCurrentTb(); 00486 00487 /* Release the lock */ 00488 KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); 00489 00490 // 00491 // Zero out the page table now 00492 // 00493 PointerPte = MiAddressToPte(HYPER_SPACE); 00494 RtlZeroMemory(PointerPte, PAGE_SIZE); 00495 00496 // 00497 // Setup the mapping PTEs 00498 // 00499 MmFirstReservedMappingPte = MiAddressToPte(MI_MAPPING_RANGE_START); 00500 MmLastReservedMappingPte = MiAddressToPte(MI_MAPPING_RANGE_END); 00501 MmFirstReservedMappingPte->u.Hard.PageFrameNumber = MI_HYPERSPACE_PTES; 00502 00503 /* Set the working set address */ 00504 MmWorkingSetList = (PVOID)MI_WORKING_SET_LIST; 00505 00506 // 00507 // Reserve system PTEs for zeroing PTEs and clear them 00508 // 00509 MiFirstReservedZeroingPte = MiReserveSystemPtes(MI_ZERO_PTES, 00510 SystemPteSpace); 00511 RtlZeroMemory(MiFirstReservedZeroingPte, MI_ZERO_PTES * sizeof(MMPTE)); 00512 00513 // 00514 // Set the counter to maximum to boot with 00515 // 00516 MiFirstReservedZeroingPte->u.Hard.PageFrameNumber = MI_ZERO_PTES - 1; 00517 00518 /* Lock PFN database */ 00519 OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); 00520 00521 /* Reset the ref/share count so that MmInitializeProcessAddressSpace works */ 00522 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(MiAddressToPde(PDE_BASE))); 00523 Pfn1->u2.ShareCount = 0; 00524 Pfn1->u3.e2.ReferenceCount = 0; 00525 00526 /* Get a page for the working set list */ 00527 MI_SET_USAGE(MI_USAGE_PAGE_TABLE); 00528 MI_SET_PROCESS2("Kernel WS List"); 00529 PageFrameIndex = MiRemoveAnyPage(0); 00530 TempPte.u.Hard.PageFrameNumber = PageFrameIndex; 00531 00532 /* Map the working set list */ 00533 PointerPte = MiAddressToPte(MmWorkingSetList); 00534 MI_WRITE_VALID_PTE(PointerPte, TempPte); 00535 00536 /* Zero it out, and save the frame index */ 00537 RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE); 00538 PsGetCurrentProcess()->WorkingSetPage = PageFrameIndex; 00539 00540 /* Check for Pentium LOCK errata */ 00541 if (KiI386PentiumLockErrataPresent) 00542 { 00543 /* Mark the 1st IDT page as Write-Through to prevent a lockup 00544 on a F00F instruction. 00545 See http://www.rcollins.org/Errata/Dec97/F00FBug.html */ 00546 PointerPte = MiAddressToPte(KeGetPcr()->IDT); 00547 PointerPte->u.Hard.WriteThrough = 1; 00548 } 00549 00550 /* Release the lock */ 00551 KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); 00552 00553 /* Initialize the bogus address space */ 00554 Flags = 0; 00555 MmInitializeProcessAddressSpace(PsGetCurrentProcess(), NULL, NULL, &Flags, NULL); 00556 00557 /* Make sure the color lists are valid */ 00558 ASSERT(MmFreePagesByColor[0] < (PMMCOLOR_TABLES)PTE_BASE); 00559 StartPde = MiAddressToPde(MmFreePagesByColor[0]); 00560 ASSERT(StartPde->u.Hard.Valid == 1); 00561 PointerPte = MiAddressToPte(MmFreePagesByColor[0]); 00562 ASSERT(PointerPte->u.Hard.Valid == 1); 00563 LastPte = MiAddressToPte((ULONG_PTR)&MmFreePagesByColor[1][MmSecondaryColors] - 1); 00564 ASSERT(LastPte->u.Hard.Valid == 1); 00565 00566 /* Loop the color list PTEs */ 00567 while (PointerPte <= LastPte) 00568 { 00569 /* Get the PFN entry */ 00570 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte)); 00571 if (!Pfn1->u3.e2.ReferenceCount) 00572 { 00573 /* Fill it out */ 00574 Pfn1->u4.PteFrame = PFN_FROM_PTE(StartPde); 00575 Pfn1->PteAddress = PointerPte; 00576 Pfn1->u2.ShareCount++; 00577 Pfn1->u3.e2.ReferenceCount = 1; 00578 Pfn1->u3.e1.PageLocation = ActiveAndValid; 00579 Pfn1->u3.e1.CacheAttribute = MiCached; 00580 } 00581 00582 /* Keep going */ 00583 PointerPte++; 00584 } 00585 00586 /* All done */ 00587 return STATUS_SUCCESS; 00588 } 00589 00590 /* EOF */ Generated on Sat May 26 2012 04:22:07 for ReactOS by
1.7.6.1
|