00033                    :
00034 
00035     This routine performs 
the necessary operations to enable 
virtual
00036     memory.  This includes building 
the page directory page, building
00037     page table pages to map 
the code section, 
the data section, 
the'
00038     stack section and 
the trap handler.
00039 
00040     It also initializes 
the PFN database and populates 
the free list.
00041 
00042 
00043 Arguments:
00044 
00045     None.
00046 
00047 Return Value:
00048 
00049     None.
00050 
00051 Environment:
00052 
00053     Kernel mode.
00054 
00055 --*/
00056 
00057 {
00058 
00059     
PMMPFN BasePfn;
00060     
PMMPFN BottomPfn;
00061     
PMMPFN TopPfn;
00062     BOOLEAN PfnInKseg0;
00063     ULONG i, j;
00064     ULONG HighPage;
00065     ULONG PagesLeft;
00066     ULONG PageNumber;
00067     ULONG PdePageNumber;
00068     ULONG PdePage;
00069     ULONG PageFrameIndex;
00070     ULONG NextPhysicalPage;
00071     ULONG PfnAllocation;
00072     ULONG MaxPool;
00073     KIRQL OldIrql;
00074     
PEPROCESS CurrentProcess;
00075     ULONG DirBase;
00076     PVOID SpinLockPage;
00077     ULONG MostFreePage = 0;
00078     PLIST_ENTRY NextMd;
00079     
PMEMORY_ALLOCATION_DESCRIPTOR FreeDescriptor;
00080     
PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
00081     
MMPTE TempPte;
00082     
PMMPTE PointerPde;
00083     
PMMPTE PointerPte;
00084     
PMMPTE LastPte;
00085     
PMMPTE CacheStackPage;
00086     
PMMPTE Pde;
00087     
PMMPTE StartPde;
00088     
PMMPTE EndPde;
00089     
PMMPFN Pfn1;
00090     
PMMPFN Pfn2;
00091     PULONG PointerLong;
00092     PVOID NonPagedPoolStartVirtual;
00093     ULONG Range;
00094 
00095     
00096     
00097     
00098 
00099     
ValidKernelPte.
u.Hard.CachePolicy = PCR->CachePolicy;
00100     
ValidUserPte.
u.Hard.CachePolicy = PCR->CachePolicy;
00101     
ValidPtePte.
u.Hard.CachePolicy = PCR->CachePolicy;
00102     
ValidPdePde.
u.Hard.CachePolicy = PCR->CachePolicy;
00103     
ValidKernelPde.
u.Hard.CachePolicy = PCR->CachePolicy ;
00104 
00105     
MmProtectToPteMask[
MM_READONLY] |= PCR->AlignedCachePolicy;
00106     
MmProtectToPteMask[
MM_EXECUTE] |= PCR->AlignedCachePolicy;
00107     
MmProtectToPteMask[
MM_EXECUTE_READ] |= PCR->AlignedCachePolicy;
00108     
MmProtectToPteMask[
MM_READWRITE] |= PCR->AlignedCachePolicy;
00109     
MmProtectToPteMask[
MM_WRITECOPY] |= PCR->AlignedCachePolicy;
00110     
MmProtectToPteMask[
MM_EXECUTE_READWRITE] |= PCR->AlignedCachePolicy;
00111     
MmProtectToPteMask[
MM_EXECUTE_WRITECOPY] |= PCR->AlignedCachePolicy;
00112 
00113     
MmProtectToPteMask[
MM_GUARD_PAGE | 
MM_READONLY] |= PCR->AlignedCachePolicy;
00114     
MmProtectToPteMask[
MM_GUARD_PAGE | 
MM_EXECUTE] |= PCR->AlignedCachePolicy;
00115     
MmProtectToPteMask[
MM_GUARD_PAGE | 
MM_EXECUTE_READ] |= PCR->AlignedCachePolicy;
00116     
MmProtectToPteMask[
MM_GUARD_PAGE | 
MM_READWRITE] |= PCR->AlignedCachePolicy;
00117     
MmProtectToPteMask[
MM_GUARD_PAGE | 
MM_WRITECOPY] |= PCR->AlignedCachePolicy;
00118     
MmProtectToPteMask[
MM_GUARD_PAGE | 
MM_EXECUTE_READWRITE] |= PCR->AlignedCachePolicy;
00119     
MmProtectToPteMask[
MM_GUARD_PAGE | 
MM_EXECUTE_WRITECOPY] |= PCR->AlignedCachePolicy;
00120 
00121     PointerPte = 
MiGetPdeAddress (PDE_BASE);
00122 
00123     PointerPte->
u.Hard.Dirty = 1;
00124     PointerPte->
u.Hard.Valid = 1;
00125     PointerPte->
u.Hard.Global = 1;
00126     PointerPte->
u.Hard.Write = 0;
00127 
00128     PdePageNumber = PointerPte->
u.Hard.PageFrameNumber;
00129 
00130     
PsGetCurrentProcess()->Pcb.DirectoryTableBase[0] = PointerPte->
u.Long;
00131 
00132     
KeSweepDcache (FALSE);
00133 
00134     
00135     
00136     
00137     
00138 
00139     NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
00140     
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
00141         MemoryDescriptor = CONTAINING_RECORD(NextMd,
00142                                              
MEMORY_ALLOCATION_DESCRIPTOR,
00143                                              ListEntry);
00144 
00145         
MmNumberOfPhysicalPages += MemoryDescriptor->
PageCount;
00146         
if (MemoryDescriptor->
BasePage < 
MmLowestPhysicalPage) {
00147             
MmLowestPhysicalPage = MemoryDescriptor->
BasePage;
00148         }
00149 
00150         
00151         
00152         
00153         
00154         
00155         
00156 
00157         HighPage = MemoryDescriptor->
BasePage + MemoryDescriptor->
PageCount - 1;
00158         
if (MemoryDescriptor->
MemoryType == 
LoaderFree) {
00159             
if ((MemoryDescriptor->
PageCount > MostFreePage) &&
00160                 (HighPage < 
MM_PAGES_IN_KSEG0)) {
00161                 MostFreePage = MemoryDescriptor->
PageCount;
00162                 FreeDescriptor = MemoryDescriptor;
00163             }
00164         }
00165 
00166         
if (HighPage > 
MmHighestPhysicalPage) {
00167             
MmHighestPhysicalPage = HighPage;
00168         }
00169 
00170         NextMd = MemoryDescriptor->
ListEntry.Flink;
00171     }
00172 
00173     
00174     
00175     
00176 
00177     
if (
MmNumberOfPhysicalPages < 1024) {
00178         
KeBugCheckEx (INSTALL_MORE_MEMORY,
00179                       MmNumberOfPhysicalPages,
00180                       MmLowestPhysicalPage,
00181                       MmHighestPhysicalPage,
00182                       0);
00183     }
00184 
00185     
00186     
00187     
00188     
00189     
00190     
00191     
00192     
00193     
00194 
00195     
if ((
MmSizeOfNonPagedPoolInBytes >> 
PAGE_SHIFT) >
00196                         (7 * (
MmNumberOfPhysicalPages << 3))) {
00197 
00198         
00199         
00200         
00201 
00202         
MmSizeOfNonPagedPoolInBytes = 0;
00203     }
00204 
00205     
if (
MmSizeOfNonPagedPoolInBytes < 
MmMinimumNonPagedPoolSize) {
00206 
00207         
00208         
00209         
00210         
00211         
00212 
00213         
MmSizeOfNonPagedPoolInBytes = 
MmMinimumNonPagedPoolSize;
00214 
00215         
MmSizeOfNonPagedPoolInBytes +=
00216                             ((
MmNumberOfPhysicalPages - 1024)/256) *
00217                             
MmMinAdditionNonPagedPoolPerMb;
00218     }
00219 
00220     
if (
MmSizeOfNonPagedPoolInBytes > 
MM_MAX_INITIAL_NONPAGED_POOL) {
00221         
MmSizeOfNonPagedPoolInBytes = 
MM_MAX_INITIAL_NONPAGED_POOL;
00222     }
00223 
00224     
00225     
00226     
00227 
00228     
MmSizeOfNonPagedPoolInBytes &= ~(
PAGE_SIZE - 1);
00229 
00230     
00231     
00232     
00233 
00234     
if (
MmMaximumNonPagedPoolInBytes == 0) {
00235 
00236         
00237         
00238         
00239         
00240         
00241 
00242         
MmMaximumNonPagedPoolInBytes = 
MmDefaultMaximumNonPagedPool;
00243 
00244         
00245         
00246         
00247 
00248         
MmMaximumNonPagedPoolInBytes += (ULONG)
PAGE_ALIGN (
00249                                       MmHighestPhysicalPage * 
sizeof(
MMPFN));
00250 
00251         
MmMaximumNonPagedPoolInBytes +=
00252                         ((
MmNumberOfPhysicalPages - 1024)/256) *
00253                         
MmMaxAdditionNonPagedPoolPerMb;
00254     }
00255 
00256     MaxPool = 
MmSizeOfNonPagedPoolInBytes + 
PAGE_SIZE * 16 +
00257                                    (ULONG)
PAGE_ALIGN (
00258                                         MmHighestPhysicalPage * 
sizeof(
MMPFN));
00259 
00260     
if (
MmMaximumNonPagedPoolInBytes < MaxPool) {
00261         
MmMaximumNonPagedPoolInBytes = MaxPool;
00262     }
00263 
00264     
if (
MmMaximumNonPagedPoolInBytes > 
MM_MAX_ADDITIONAL_NONPAGED_POOL) {
00265         
MmMaximumNonPagedPoolInBytes = 
MM_MAX_ADDITIONAL_NONPAGED_POOL;
00266     }
00267 
00268     
MmNonPagedPoolStart = (PVOID)((ULONG)
MmNonPagedPoolEnd
00269                                       - (
MmMaximumNonPagedPoolInBytes - 1));
00270 
00271     
MmNonPagedPoolStart = (PVOID)
PAGE_ALIGN(MmNonPagedPoolStart);
00272     NonPagedPoolStartVirtual = 
MmNonPagedPoolStart;
00273 
00274 
00275     
00276     
00277     
00278     
00279 
00280     
MmNonPagedSystemStart = (PVOID)(((ULONG)
MmNonPagedPoolStart -
00281                                 ((
MmNumberOfSystemPtes + 1) * 
PAGE_SIZE)) &
00282                                  (~
PAGE_DIRECTORY_MASK));
00283 
00284     
if (
MmNonPagedSystemStart < 
MM_LOWEST_NONPAGED_SYSTEM_START) {
00285         
MmNonPagedSystemStart = 
MM_LOWEST_NONPAGED_SYSTEM_START;
00286         
MmNumberOfSystemPtes = (((ULONG)
MmNonPagedPoolStart -
00287                                  (ULONG)
MmNonPagedSystemStart) >> 
PAGE_SHIFT)-1;
00288         
ASSERT (MmNumberOfSystemPtes > 1000);
00289     }
00290 
00291     
00292     
00293     
00294 
00295     StartPde = 
MiGetPdeAddress (MM_SYSTEM_SPACE_START);
00296     EndPde = 
MiGetPdeAddress (MM_SYSTEM_SPACE_END);
00297 
00298     
while (StartPde <= EndPde) {
00299         
if (StartPde->
u.Hard.Global == 0) {
00300 
00301             
00302             
00303             
00304 
00305             TempPte = *StartPde;
00306             TempPte.
u.Hard.Global = 1;
00307             *StartPde = TempPte;
00308         }
00309         StartPde += 1;
00310     }
00311 
00312     StartPde = 
MiGetPdeAddress (MmNonPagedSystemStart);
00313 
00314     EndPde = 
MiGetPdeAddress((PVOID)((PCHAR)MmNonPagedPoolEnd - 1));
00315 
00316     
ASSERT ((EndPde - StartPde) < (LONG)FreeDescriptor->
PageCount);
00317 
00318     NextPhysicalPage = FreeDescriptor->
BasePage;
00319     TempPte = 
ValidKernelPte;
00320 
00321     
while (StartPde <= EndPde) {
00322         
if (StartPde->u.Hard.Valid == 0) {
00323 
00324             
00325             
00326             
00327 
00328             TempPte.
u.Hard.PageFrameNumber = NextPhysicalPage;
00329             NextPhysicalPage += 1;
00330             *StartPde = TempPte;
00331 
00332         }
00333         StartPde += 1;
00334     }
00335 
00336     
00337     
00338     
00339 
00340     StartPde = 
MiGetPteAddress (MmNonPagedSystemStart);
00341     PointerPte = 
MiGetPteAddress(MmNonPagedPoolStart);
00342 
00343     RtlZeroMemory (StartPde, ((ULONG)PointerPte - (ULONG)StartPde));
00344 
00345     
00346     
00347     
00348 
00349     LastPte = 
MiGetPteAddress((ULONG)MmNonPagedPoolStart +
00350                                         MmSizeOfNonPagedPoolInBytes - 1);
00351     
while (PointerPte <= LastPte) {
00352         TempPte.
u.Hard.PageFrameNumber = NextPhysicalPage;
00353         NextPhysicalPage += 1;
00354         *PointerPte = TempPte;
00355         PointerPte++;
00356     }
00357 
00358     
ASSERT (NextPhysicalPage <
00359                        (FreeDescriptor->
BasePage + FreeDescriptor->
PageCount));
00360 
00361     
00362     
00363     
00364 
00365     StartPde = (
PMMPTE)((ULONG)
MiGetPteAddress (MmNonPagedPoolEnd) | (
PAGE_SIZE - 
sizeof(
MMPTE)));
00366     
while (PointerPte <= StartPde) {
00367         *PointerPte = 
ZeroKernelPte;
00368         PointerPte++;
00369     }
00370 
00371     PointerPte = 
MiGetPteAddress (MmNonPagedPoolStart);
00372     
MmNonPagedPoolStart =
00373         (PVOID)(
KSEG0_BASE | (PointerPte->
u.Hard.PageFrameNumber << 
PAGE_SHIFT));
00374 
00375     
MmPageAlignedPoolBase[
NonPagedPool] = 
MmNonPagedPoolStart;
00376 
00377     
MmSubsectionBase = (ULONG)
MmNonPagedPoolStart;
00378     
if (NextPhysicalPage < (MM_SUBSECTION_MAP >> 
PAGE_SHIFT)) {
00379         
MmSubsectionBase = 
KSEG0_BASE;
00380         
MmSubsectionTopPage = 
MM_SUBSECTION_MAP >> 
PAGE_SHIFT;
00381     }
00382 
00383     
00384     
00385     
00386 
00387     
MmNonPagedPoolExpansionStart = (PVOID)((PCHAR)NonPagedPoolStartVirtual +
00388                     
MmSizeOfNonPagedPoolInBytes);
00389     
MiInitializeNonPagedPool (NonPagedPoolStartVirtual);
00390 
00391     
00392     
00393     
00394     
00395     
00396     
00397 
00398     
00399     
00400     
00401     
00402 
00403     
00404     
00405     
00406     
00407     
00408     
00409 
00410     
if (
MmSecondaryColors == 0) {
00411         
MmSecondaryColors = PCR->SecondLevelDcacheSize;
00412     }
00413 
00414     
MmSecondaryColors = 
MmSecondaryColors >> 
PAGE_SHIFT;
00415 
00416     
00417     
00418     
00419 
00420     
if (((
MmSecondaryColors & (
MmSecondaryColors -1)) != 0) ||
00421         (
MmSecondaryColors < 
MM_SECONDARY_COLORS_MIN) ||
00422         (
MmSecondaryColors > 
MM_SECONDARY_COLORS_MAX)) {
00423         
MmSecondaryColors = 
MM_SECONDARY_COLORS_DEFAULT;
00424     }
00425 
00426     
MmSecondaryColorMask = (
MmSecondaryColors - 1) & ~
MM_COLOR_MASK;
00427 
00428     PfnAllocation = 1 + ((((
MmHighestPhysicalPage + 1) * 
sizeof(
MMPFN)) +
00429                         (
MmSecondaryColors * 
sizeof(
MMCOLOR_TABLES)*2))
00430                             >> 
PAGE_SHIFT);
00431 
00432     
00433     
00434     
00435     
00436     
00437 
00438     HighPage = FreeDescriptor->
BasePage + FreeDescriptor->
PageCount;
00439     PagesLeft = HighPage - NextPhysicalPage;
00440     
if (PagesLeft >= PfnAllocation) {
00441 
00442         
00443         
00444         
00445         
00446         
00447         
00448 
00449         PfnInKseg0 = 
TRUE;
00450         
MmPfnDatabase = (
PMMPFN)(
KSEG0_BASE |
00451                                     ((HighPage - PfnAllocation) << 
PAGE_SHIFT));
00452 
00453         RtlZeroMemory(MmPfnDatabase, PfnAllocation * PAGE_SIZE);
00454         FreeDescriptor->
PageCount -= PfnAllocation;
00455 
00456     } 
else {
00457 
00458         
00459         
00460         
00461         
00462         
00463         
00464 
00465         PfnInKseg0 = 
FALSE;
00466         PointerPte = 
MiReserveSystemPtes (PfnAllocation,
00467                                           NonPagedPoolExpansion,
00468                                           0,
00469                                           0,
00470                                           TRUE);
00471 
00472         
MmPfnDatabase = (
PMMPFN)(
MiGetVirtualAddressMappedByPte (PointerPte));
00473 
00474         
00475         
00476         
00477         
00478         
00479         
00480 
00481         NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
00482         
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
00483 
00484             MemoryDescriptor = CONTAINING_RECORD(NextMd,
00485                                                  
MEMORY_ALLOCATION_DESCRIPTOR,
00486                                                  ListEntry);
00487 
00488             PointerPte = 
MiGetPteAddress (
MI_PFN_ELEMENT(
00489                                             MemoryDescriptor->
BasePage));
00490 
00491             LastPte = 
MiGetPteAddress (((PCHAR)(
MI_PFN_ELEMENT(
00492                                             MemoryDescriptor->
BasePage +
00493                                             MemoryDescriptor->
PageCount))) - 1);
00494 
00495             
while (PointerPte <= LastPte) {
00496                 
if (PointerPte->
u.Hard.Valid == 0) {
00497                     TempPte.
u.Hard.PageFrameNumber = NextPhysicalPage;
00498                     NextPhysicalPage += 1;
00499                     *PointerPte = TempPte;
00500                     RtlZeroMemory (MiGetVirtualAddressMappedByPte (PointerPte),
00501                                    PAGE_SIZE);
00502                 }
00503                 PointerPte++;
00504             }
00505 
00506             NextMd = MemoryDescriptor->
ListEntry.Flink;
00507         }
00508     }
00509 
00510     
00511     
00512     
00513 
00514     
MmFreePagesByColor[0] = (
PMMCOLOR_TABLES)
00515                                 &
MmPfnDatabase[
MmHighestPhysicalPage + 1];
00516 
00517     
MmFreePagesByColor[1] = &
MmFreePagesByColor[0][
MmSecondaryColors];
00518 
00519     
00520     
00521     
00522 
00523     
if (!
MI_IS_PHYSICAL_ADDRESS(MmFreePagesByColor[0])) {
00524         PointerPte = 
MiGetPteAddress (&MmFreePagesByColor[0][0]);
00525 
00526         LastPte = 
MiGetPteAddress (
00527               (PVOID)((PCHAR)&MmFreePagesByColor[1][MmSecondaryColors] - 1));
00528 
00529         
while (PointerPte <= LastPte) {
00530             
if (PointerPte->
u.Hard.Valid == 0) {
00531                 TempPte.
u.Hard.PageFrameNumber = NextPhysicalPage;
00532                 NextPhysicalPage += 1;
00533                 *PointerPte = TempPte;
00534                 RtlZeroMemory (MiGetVirtualAddressMappedByPte (PointerPte),
00535                                PAGE_SIZE);
00536             }
00537             PointerPte++;
00538         }
00539     }
00540 
00541     
for (i = 0; i < 
MmSecondaryColors; i++) {
00542         
MmFreePagesByColor[
ZeroedPageList][i].
Flink = 
MM_EMPTY_LIST;
00543         
MmFreePagesByColor[
FreePageList][i].
Flink = 
MM_EMPTY_LIST;
00544     }
00545 
00546     
for (i = 0; i < 
MM_MAXIMUM_NUMBER_OF_COLORS; i++) {
00547         
MmFreePagesByPrimaryColor[
ZeroedPageList][i].
ListName = 
ZeroedPageList;
00548         
MmFreePagesByPrimaryColor[
FreePageList][i].
ListName = 
FreePageList;
00549         
MmFreePagesByPrimaryColor[
ZeroedPageList][i].
Flink = 
MM_EMPTY_LIST;
00550         
MmFreePagesByPrimaryColor[
FreePageList][i].
Flink = 
MM_EMPTY_LIST;
00551         
MmFreePagesByPrimaryColor[
ZeroedPageList][i].
Blink = 
MM_EMPTY_LIST;
00552         
MmFreePagesByPrimaryColor[
FreePageList][i].
Blink = 
MM_EMPTY_LIST;
00553     }
00554 
00555     
00556     
00557     
00558     
00559 
00560     PointerPde = 
MiGetPdeAddress (PTE_BASE);
00561 
00562     PdePage = PointerPde->
u.Hard.PageFrameNumber;
00563     Pfn1 = 
MI_PFN_ELEMENT(PdePage);
00564     Pfn1->
PteFrame = PdePage;
00565     Pfn1->
PteAddress = PointerPde;
00566     Pfn1->
u2.ShareCount += 1;
00567     Pfn1->
u3.e2.ReferenceCount = 1;
00568     Pfn1->
u3.e1.PageLocation = 
ActiveAndValid;
00569     Pfn1->
u3.e1.PageColor = 
MI_GET_PAGE_COLOR_FROM_PTE (PointerPde);
00570 
00571     
00572     
00573     
00574     
00575 
00576     Pde = 
MiGetPdeAddress ((ULONG)NonPagedPoolStartVirtual -
00577                                 ((MmNumberOfSystemPtes + 1) * PAGE_SIZE));
00578 
00579     EndPde = 
MiGetPdeAddress(MmNonPagedPoolEnd);
00580 
00581     
while (Pde <= EndPde) {
00582         
if (Pde->
u.Hard.Valid == 1) {
00583             PdePage = Pde->
u.Hard.PageFrameNumber;
00584             Pfn1 = 
MI_PFN_ELEMENT(PdePage);
00585             Pfn1->
PteFrame = PointerPde->
u.Hard.PageFrameNumber;
00586             Pfn1->
PteAddress = Pde;
00587             Pfn1->
u2.ShareCount += 1;
00588             Pfn1->
u3.e2.ReferenceCount = 1;
00589             Pfn1->
u3.e1.PageLocation = 
ActiveAndValid;
00590             Pfn1->
u3.e1.PageColor = 
MI_GET_PAGE_COLOR_FROM_PTE (Pde);
00591 
00592             PointerPte = 
MiGetVirtualAddressMappedByPte (Pde);
00593             
for (j = 0 ; j < 
PTE_PER_PAGE; j++) {
00594                 
if (PointerPte->
u.Hard.Valid == 1) {
00595 
00596                     PageFrameIndex = PointerPte->
u.Hard.PageFrameNumber;
00597                     Pfn2 = 
MI_PFN_ELEMENT(PageFrameIndex);
00598                     Pfn2->
PteFrame = PdePage;
00599                     Pfn2->
u2.ShareCount += 1;
00600                     Pfn2->
u3.e2.ReferenceCount = 1;
00601                     Pfn2->
u3.e1.PageLocation = 
ActiveAndValid;
00602                     Pfn2->
PteAddress =
00603                             (
PMMPTE)(
KSEG0_BASE | (PageFrameIndex << 
PTE_SHIFT));
00604 
00605                     Pfn2->
u3.e1.PageColor =
00606                              
MI_GET_PAGE_COLOR_FROM_PTE (Pfn2->
PteAddress);
00607                 }
00608                 PointerPte++;
00609             }
00610         }
00611         Pde++;
00612     }
00613 
00614     
00615     
00616     
00617     
00618     
00619 
00620     Pfn1 = &
MmPfnDatabase[
MmLowestPhysicalPage];
00621     
if (Pfn1->
u3.e2.ReferenceCount == 0) {
00622 
00623         
00624         
00625         
00626         
00627 
00628         Pde = 
MiGetPdeAddress (0xb0000000);
00629         PdePage = Pde->
u.Hard.PageFrameNumber;
00630         Pfn1->
PteFrame = PdePageNumber;
00631         Pfn1->
PteAddress = Pde;
00632         Pfn1->
u2.ShareCount += 1;
00633         Pfn1->
u3.e2.ReferenceCount = 1;
00634         Pfn1->
u3.e1.PageLocation = 
ActiveAndValid;
00635         Pfn1->
u3.e1.PageColor = 
MI_GET_PAGE_COLOR_FROM_PTE (Pde);
00636     }
00637 
00638     
00639 
00640 
00641     
00642     
00643     
00644     
00645     
00646 
00647     NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
00648 
00649     
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
00650 
00651         MemoryDescriptor = CONTAINING_RECORD(NextMd,
00652                                              
MEMORY_ALLOCATION_DESCRIPTOR,
00653                                              ListEntry);
00654 
00655         i = MemoryDescriptor->
PageCount;
00656         NextPhysicalPage = MemoryDescriptor->
BasePage;
00657 
00658         
switch (MemoryDescriptor->
MemoryType) {
00659             
case LoaderBad:
00660                 
while (i != 0) {
00661                     
MiInsertPageInList (MmPageLocationList[BadPageList],
00662                                         NextPhysicalPage);
00663                     i -= 1;
00664                     NextPhysicalPage += 1;
00665                 }
00666                 
break;
00667 
00668             
case LoaderFree:
00669             
case LoaderLoadedProgram:
00670             
case LoaderFirmwareTemporary:
00671             
case LoaderOsloaderStack:
00672 
00673                 Pfn1 = 
MI_PFN_ELEMENT (NextPhysicalPage);
00674                 
while (i != 0) {
00675                     
if (Pfn1->
u3.e2.ReferenceCount == 0) {
00676 
00677                         
00678                         
00679                         
00680                         
00681 
00682                         Pfn1->
PteAddress = (
PMMPTE)(NextPhysicalPage << 
PTE_SHIFT);
00683                         Pfn1->
u3.e1.PageColor = 
MI_GET_PAGE_COLOR_FROM_PTE (
00684                                                     Pfn1->
PteAddress);
00685 
00686                         
MiInsertPageInList (MmPageLocationList[FreePageList],
00687                                             NextPhysicalPage);
00688                     }
00689                     Pfn1++;
00690                     i -= 1;
00691                     NextPhysicalPage += 1;
00692                 }
00693                 
break;
00694 
00695             
default:
00696                 PointerPte = 
MiGetPteAddress(KSEG0_BASE |
00697                                             (NextPhysicalPage << PAGE_SHIFT));
00698 
00699                 Pfn1 = 
MI_PFN_ELEMENT (NextPhysicalPage);
00700                 
while (i != 0) {
00701 
00702                     
00703                     
00704                     
00705 
00706                     Pfn1->
PteFrame = PdePageNumber;
00707                     Pfn1->
PteAddress = PointerPte;
00708                     Pfn1->
u2.ShareCount += 1;
00709                     Pfn1->
u3.e2.ReferenceCount = 1;
00710                     Pfn1->
u3.e1.PageLocation = 
ActiveAndValid;
00711                     Pfn1->
u3.e1.PageColor = 
MI_GET_PAGE_COLOR_FROM_PTE (
00712                                                     PointerPte);
00713 
00714                     Pfn1++;
00715                     i -= 1;
00716                     NextPhysicalPage += 1;
00717                     PointerPte += 1;
00718                 }
00719 
00720                 
break;
00721         }
00722 
00723         NextMd = MemoryDescriptor->
ListEntry.Flink;
00724     }
00725 
00726     
00727     
00728     
00729     
00730     
00731 
00732     
if (PfnInKseg0 == 
FALSE) {
00733 
00734         
00735         
00736         
00737         
00738         
00739 
00740         Pfn1 = 
MI_PFN_ELEMENT(
MiGetPteAddress(&MmPfnDatabase[MmLowestPhysicalPage])->u.Hard.PageFrameNumber);
00741         Pfn1->
u3.e1.StartOfAllocation = 1;
00742         Pfn1 = 
MI_PFN_ELEMENT(
MiGetPteAddress(&MmPfnDatabase[MmHighestPhysicalPage])->u.Hard.PageFrameNumber);
00743         Pfn1->
u3.e1.EndOfAllocation = 1;
00744 
00745     } 
else {
00746 
00747         
00748         
00749         
00750         
00751         
00752 
00753         PageNumber = ((ULONG)
MmPfnDatabase - 
KSEG0_BASE) >> 
PAGE_SHIFT;
00754         Pfn1 = 
MI_PFN_ELEMENT(PageNumber);
00755         
do {
00756             Pfn1->
PteAddress = (
PMMPTE)(PageNumber << 
PTE_SHIFT);
00757             Pfn1->
u3.e1.PageColor = 
MI_GET_PAGE_COLOR_FROM_PTE(Pfn1->
PteAddress);
00758             Pfn1 += 1;
00759             PfnAllocation -= 1;
00760         } 
while (PfnAllocation != 0);
00761 
00762         
00763         
00764         
00765 
00766         BottomPfn = 
MI_PFN_ELEMENT(MmHighestPhysicalPage);
00767         
do {
00768 
00769             
00770             
00771             
00772             
00773             
00774 
00775             
if (((ULONG)BottomPfn & (
PAGE_SIZE - 1)) != 0) {
00776                 BasePfn = (
PMMPFN)((ULONG)BottomPfn & ~(
PAGE_SIZE - 1));
00777                 TopPfn = BottomPfn + 1;
00778 
00779             } 
else {
00780                 BasePfn = (
PMMPFN)((ULONG)BottomPfn - 
PAGE_SIZE);
00781                 TopPfn = BottomPfn;
00782             }
00783 
00784             
while (BottomPfn > BasePfn) {
00785                 BottomPfn -= 1;
00786             }
00787 
00788             
00789             
00790             
00791             
00792             
00793             
00794 
00795             Range = (ULONG)TopPfn - (ULONG)BottomPfn;
00796             
if (
RtlCompareMemoryUlong((PVOID)BottomPfn, Range, 0) == Range) {
00797 
00798                 
00799                 
00800                 
00801                 
00802 
00803                 PageNumber = ((ULONG)BasePfn - 
KSEG0_BASE) >> 
PAGE_SHIFT;
00804                 Pfn1 = 
MI_PFN_ELEMENT(PageNumber);
00805 
00806                 
ASSERT(Pfn1->
u3.e2.ReferenceCount == 0);
00807 
00808                 PfnAllocation += 1;
00809 
00810                 Pfn1->
PteAddress = (
PMMPTE)(PageNumber << 
PTE_SHIFT);
00811                 Pfn1->
u3.e1.PageColor = 
MI_GET_PAGE_COLOR_FROM_PTE(Pfn1->
PteAddress);
00812                 
MiInsertPageInList(MmPageLocationList[FreePageList],
00813                                    PageNumber);
00814             }
00815 
00816         } 
while (BottomPfn > 
MmPfnDatabase);
00817     }
00818 
00819     
00820     
00821     
00822     
00823 
00824     i = 
MmSizeOfNonPagedMustSucceed;
00825     Pfn1 = 
MI_PFN_ELEMENT(MI_CONVERT_PHYSICAL_TO_PFN (MmNonPagedMustSucceed));
00826     
while ((LONG)i > 0) {
00827         Pfn1->
u3.e1.StartOfAllocation = 1;
00828         Pfn1->
u3.e1.EndOfAllocation = 1;
00829         i -= 
PAGE_SIZE;
00830         Pfn1 += 1;
00831     }
00832 
00833     
KeInitializeSpinLock (&MmSystemSpaceLock);
00834     
KeInitializeSpinLock (&MmPfnLock);
00835 
00836     
00837     
00838     
00839     
00840 
00841     PointerPte = 
MiGetPteAddress ((ULONG)NonPagedPoolStartVirtual -
00842                                 ((MmNumberOfSystemPtes + 1) * PAGE_SIZE));
00843 
00844     PointerPte = (
PMMPTE)
PAGE_ALIGN (PointerPte);
00845     
if (PfnInKseg0) {
00846         
MmNumberOfSystemPtes = 
MiGetPteAddress(MmNonPagedPoolExpansionStart) - PointerPte - 1;
00847     } 
else {
00848         
MmNumberOfSystemPtes = 
MiGetPteAddress(NonPagedPoolStartVirtual) - PointerPte - 1;
00849     }
00850 
00851     
MiInitializeSystemPtes (PointerPte, MmNumberOfSystemPtes, SystemPteSpace);
00852 
00853     
00854     
00855     
00856 
00857     
InitializePool(NonPagedPool,0);
00858 
00859     
00860     
00861     
00862 
00863     
00864     
00865     
00866     
00867     
00868     
00869     
00870 
00871     PointerPte = 
MiGetPdeAddress(HYPER_SPACE);
00872 
00873     
ASSERT (PointerPte->
u.Hard.Valid == 1);
00874     PointerPte->
u.Hard.Global = 0;
00875     PointerPte->
u.Hard.Write = 1;
00876     PageFrameIndex = PointerPte->
u.Hard.PageFrameNumber;
00877 
00878     
00879     
00880     
00881 
00882 
00883 
00884 
00885 
00886 
00887     PointerPte = 
MiGetPteAddress(HYPER_SPACE);
00888     RtlZeroMemory ((PVOID)PointerPte, PAGE_SIZE);
00889 
00890     
00891     
00892     
00893 
00894     
MmFirstReservedMappingPte = 
MiGetPteAddress (FIRST_MAPPING_PTE);
00895     
MmLastReservedMappingPte = 
MiGetPteAddress (LAST_MAPPING_PTE);
00896 
00897     
MmWorkingSetList = 
WORKING_SET_LIST;
00898     
MmWsle = (
PMMWSLE)((PUCHAR)
WORKING_SET_LIST + 
sizeof(
MMWSL));
00899 
00900     
00901     
00902     
00903     
00904 
00905     
00906     
00907     
00908     
00909     
00910 
00911     Pfn1 = 
MI_PFN_ELEMENT (PdePageNumber);
00912     Pfn1->
u2.ShareCount = 0;
00913     Pfn1->
u3.e2.ReferenceCount = 0;
00914     Pfn1->
u3.e1.PageColor = 0;
00915 
00916     
00917     
00918     
00919     
00920     
00921 
00922     Pfn1 = 
MI_PFN_ELEMENT (PageFrameIndex);
00923     Pfn1->
u2.ShareCount = 0;
00924     Pfn1->
u3.e2.ReferenceCount = 0;
00925     Pfn1->
u3.e1.PageColor = 1;
00926 
00927 
00928     CurrentProcess = 
PsGetCurrentProcess ();
00929 
00930     
00931     
00932     
00933     
00934 
00935     PointerPte = 
MiGetPteAddress (HYPER_SPACE);
00936     PageFrameIndex = 
MiRemoveAnyPage (
MI_GET_PAGE_COLOR_FROM_PTE(PointerPte));
00937     CurrentProcess->
WorkingSetPage = PageFrameIndex;
00938 
00939     TempPte.
u.Hard.Global = 0;
00940     TempPte.
u.Hard.PageFrameNumber = PageFrameIndex;
00941     PointerPde = 
MiGetPdeAddress (HYPER_SPACE) + 1;
00942 
00943     
00944     
00945     
00946 
00947     
ASSERT ((PointerPte->
u.Long & (0xF << PTE_SHIFT)) ==
00948             (PointerPde->
u.Long & (0xF << PTE_SHIFT)));
00949 
00950     *PointerPde = TempPte;
00951 
00952     PointerPte = 
MiGetVirtualAddressMappedByPte (PointerPde);
00953 
00954     KeFillEntryTb ((PHARDWARE_PTE)PointerPde,
00955                     PointerPte,
00956                     TRUE);
00957 
00958     RtlZeroMemory ((PVOID)PointerPte, PAGE_SIZE);
00959 
00960     TempPte = *PointerPde;
00961     TempPte.
u.Hard.Valid = 0;
00962     TempPte.u.Hard.Global = 0;
00963 
00964     
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
00965     
KeFlushSingleTb (PointerPte,
00966                      TRUE,
00967                      FALSE,
00968                      (PHARDWARE_PTE)PointerPde,
00969                      TempPte.u.Hard);
00970 
00971     
KeLowerIrql(OldIrql);
00972 
00973 
#ifdef R4000
00974 
00975     
00976     
00977     
00978 
00979     i = 
NUMBER_OF_MAPPING_PTES - 
MM_COLOR_MASK;
00980     PointerPte = 
MmFirstReservedMappingPte;
00981     
while (PointerPte <= (
MmFirstReservedMappingPte + 
MM_COLOR_MASK)) {
00982         PointerPte->
u.Hard.PageFrameNumber = i;
00983         PointerPte += 1;
00984     }
00985 
00986 
#endif
00987 
00988     CurrentProcess->
Vm.
MaximumWorkingSetSize = 
MmSystemProcessWorkingSetMax;
00989     CurrentProcess->
Vm.
MinimumWorkingSetSize = 
MmSystemProcessWorkingSetMin;
00990 
00991     
MmInitializeProcessAddressSpace (CurrentProcess,
00992                                 (
PEPROCESS)NULL,
00993                                 (PVOID)NULL);
00994 
00995     *PointerPde = 
ZeroPte;
00996     
KeFlushEntireTb(TRUE, TRUE);
00997 
00998     
00999     
01000     
01001     
01002     
01003     
01004     
01005     
01006     
01007 
01008     
if ((((ULONG)
MmFreePagesByColor[0] & (
PAGE_SIZE - 1)) == 0) &&
01009        ((
MmSecondaryColors * 2 * 
sizeof(
MMCOLOR_TABLES)) < 
PAGE_SIZE)) {
01010 
01011         
PMMCOLOR_TABLES c;
01012 
01013         
c = 
MmFreePagesByColor[0];
01014 
01015         
MmFreePagesByColor[0] = 
ExAllocatePoolWithTag (NonPagedPoolMustSucceed,
01016                                MmSecondaryColors * 2 * 
sizeof(
MMCOLOR_TABLES),
01017                                '  mM');
01018 
01019         
MmFreePagesByColor[1] = &
MmFreePagesByColor[0][
MmSecondaryColors];
01020 
01021         RtlMoveMemory (MmFreePagesByColor[0],
01022                        c,
01023                        MmSecondaryColors * 2 * 
sizeof(
MMCOLOR_TABLES));
01024 
01025         
01026         
01027         
01028 
01029         
if (!
MI_IS_PHYSICAL_ADDRESS(c)) {
01030             PointerPte = 
MiGetPteAddress(c);
01031             PageFrameIndex = PointerPte->
u.Hard.PageFrameNumber;
01032             *PointerPte = 
ZeroKernelPte;
01033         } 
else {
01034             PageFrameIndex = 
MI_CONVERT_PHYSICAL_TO_PFN (c);
01035         }
01036 
01037         Pfn1 = 
MI_PFN_ELEMENT (PageFrameIndex);
01038         
ASSERT ((Pfn1->
u3.e2.ReferenceCount <= 1) && (Pfn1->
u2.ShareCount <= 1));
01039         Pfn1->
u2.ShareCount = 0;
01040         Pfn1->
u3.e2.ReferenceCount = 0;
01041         
MI_SET_PFN_DELETED (Pfn1);
01042 
#if DBG
01043 
        Pfn1->
u3.e1.PageLocation = 
StandbyPageList;
01044 
#endif //DBG
01045 
        MiInsertPageInList (MmPageLocationList[FreePageList], PageFrameIndex);
01046     }
01047     
return;
01048 }
}