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 }
}