ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

init.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.