test: mm/ia64/initia64.c File Reference

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

# initia64.c File Reference

`#include "mi.h"`

Go to the source code of this file.

## Defines

#define | MiGetKSegPteAddress(Va) ((PMMPTE)__thash((ULONG_PTR)(Va)))
#define | _x1mb (1024*1024)
#define | _x1mbnp ((1024*1024) >> PAGE_SHIFT)
#define | _x4mb (1024*1024*4)
#define | _x4mbnp ((1024*1024*4) >> PAGE_SHIFT)
#define | _x16mb (1024*1024*16)
#define | _x16mbnp ((1024*1024*16) >> PAGE_SHIFT)
#define | _x32mb (1024*1024*32)
#define | _x32mbnp ((1024*1024*32) >> PAGE_SHIFT)
#define | _x64mb (1024*1024*64)
#define | _x64mbnp ((1024*1024*64) >> PAGE_SHIFT)
#define | _x256mb (1024*1024*256)
#define | _x256mbnp ((1024*1024*256) >> PAGE_SHIFT)
#define | _x512mb (1024*1024*512)
#define | _x512mbnp ((1024*1024*512) >> PAGE_SHIFT)
#define | _x4gb (0x100000000UI64)
#define | _x4gbnp (0x100000000UI64 >> PAGE_SHIFT)
#define | ADD_HIGH_MEMORY 0

## Functions

VOID | KeInitializeVhpt (IN PVOID Virtual, IN ULONG Size)
VOID | KeFillLargePdePinned (IN PMMPTE Pte, IN PVOID Virtual)
VOID | MiConvertToSuperPages (PVOID StartVirtual, PVOID EndVirtual, SIZE_T PageSize, ULONG PageShift)
VOID | MiConvertBackToStandardPages (IN PVOID StartVirtual, IN PVOID EndVirtual)
VOID | MiBuildPageTableForDrivers (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID | MiBuildPageTableForLoaderMemory (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID | MiRemoveLoaderSuperPages (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID | MiMakeKernelPagesPermanent (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID | MiCheckMemoryDescriptorList (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
PFN_NUMBER | MiGetNextPhysicalPage (VOID)
BOOLEAN | MiEnsureAvailablePagesInFreeDescriptor (IN PFN_NUMBER Pages, IN PFN_NUMBER MaxPage)
VOID | MiInitMachineDependent (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
PVOID | MiGetKSegAddress (PFN_NUMBER FrameNumber)
VOID | MiConvertToSuperPages (IN PVOID StartVirtual, IN PVOID EndVirtual, IN SIZE_T PageSize, IN ULONG PageShift)
VOID | MiSweepCacheMachineDependent (IN PVOID VirtualAddress, IN SIZE_T Size, IN MEMORY_CACHING_TYPE CacheType)
PVOID | MiConvertToLoaderVirtual (IN PFN_NUMBER Page, IN PLOADER_PARAMETER_BLOCK LoaderBlock)

## Variables

ULONG_PTR | MmKseg3VhptBase
ULONG | MmKseg3VhptPs
PFN_NUMBER | MmSystemParentTablePage
MMPTE | MiSystemSelfMappedPte
MMPTE | MiUserSelfMappedPte
PVOID | MiKseg0Start = 0
PVOID | MiKseg0End = 0
BOOLEAN | MiKseg0Mapping = TRUE
BOOLEAN | MiPrintMemoryDescriptors = FALSE
PFN_NUMBER | MiNtoskrnlPhysicalBase
ULONG_PTR | MiNtoskrnlVirtualBase
ULONG | MiNtoskrnlPageShift
PFN_NUMBER | MiWasteStart = 0
PFN_NUMBER | MiWasteEnd = 0
PMEMORY_ALLOCATION_DESCRIPTOR | MiFreeDescriptor
PMEMORY_ALLOCATION_DESCRIPTOR | MiFreeDescriptorLargest = NULL
PMEMORY_ALLOCATION_DESCRIPTOR | MiFreeDescriptorLowMem = NULL
PMEMORY_ALLOCATION_DESCRIPTOR | MiFreeDescriptorNonPaged = NULL
PFN_NUMBER | MiNextPhysicalPage
PFN_NUMBER | MiNumberOfPages
PFN_NUMBER | MiOldFreeDescriptorBase
PFN_NUMBER | MiOldFreeDescriptorCount
ULONG | MiImplVirtualMsb = 50

## Define Documentation

#define _x16mb (1024*1024*16)

| Definition at line 102 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

#define _x16mbnp ((1024*1024*16) >> PAGE_SHIFT)

| Definition at line 103 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

#define _x1mb (1024*1024)

| Definition at line 98 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

#define _x1mbnp ((1024*1024) >> PAGE_SHIFT)

| Definition at line 99 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

#define _x256mb (1024*1024*256)

| Definition at line 108 of file mm/ia64/initia64.c.

#define _x256mbnp ((1024*1024*256) >> PAGE_SHIFT)

| Definition at line 109 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

#define _x32mb (1024*1024*32)

| Definition at line 104 of file mm/ia64/initia64.c.

#define _x32mbnp ((1024*1024*32) >> PAGE_SHIFT)

| Definition at line 105 of file mm/ia64/initia64.c.

#define _x4gb (0x100000000UI64)

| Definition at line 112 of file mm/ia64/initia64.c.

#define _x4gbnp (0x100000000UI64 >> PAGE_SHIFT)

| Definition at line 113 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

#define _x4mb (1024*1024*4)

| Definition at line 100 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

#define _x4mbnp ((1024*1024*4) >> PAGE_SHIFT)

| Definition at line 101 of file mm/ia64/initia64.c.

#define _x512mb (1024*1024*512)

| Definition at line 110 of file mm/ia64/initia64.c.

#define _x512mbnp ((1024*1024*512) >> PAGE_SHIFT)

| Definition at line 111 of file mm/ia64/initia64.c.

#define _x64mb (1024*1024*64)

| Definition at line 106 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

#define _x64mbnp ((1024*1024*64) >> PAGE_SHIFT)

| Definition at line 107 of file mm/ia64/initia64.c.

#define ADD_HIGH_MEMORY 0

| Definition at line 115 of file mm/ia64/initia64.c.

#define MiGetKSegPteAddress | ( | Va |  | ) | ((PMMPTE)__thash((ULONG_PTR)(Va)))

| Definition at line 96 of file mm/ia64/initia64.c. Referenced by MiGetKSegAddress(), and MiInitMachineDependent().

## Function Documentation

VOID KeFillLargePdePinned | ( | IN PMMPTE | Pte,
|  | IN PVOID | Virtual
| ) |

VOID KeInitializeVhpt | ( | IN PVOID | Virtual,
|  | IN ULONG | Size
| ) |

| Referenced by MiInitMachineDependent().

VOID MiBuildPageTableForDrivers | ( | IN PLOADER_PARAMETER_BLOCK | LoaderBlock | ) |

Definition at line 2091 of file mm/ia64/initia64.c.

References ASSERT, FALSE, MI_CONVERT_PHYSICAL_TO_PFN, MI_WRITE_VALID_PTE, MiGetNextPhysicalPage(), MiGetPdeAddress, MiGetPteAddress, MiIsPteOnPdeBoundary, MiIsPteOnPpeBoundary, MM_PTE_EXECUTE, PAGE_SHIFT, PAGE_SIZE, ROUND_TO_PAGES, TRUE, _MMPTE::u, and ValidKernelPte.

    02096                    :
    02097
    02098     This function builds page ables for loader loaded drivers.
    02099
    02100 Arguments:
    02101
    02102     LoaderBlock - Supplies the address of the loader block.
    02103
    02104 Return Value:
    02105
    02106     None.
    02107
    02108 --*/
    02109 {
    02110     PMMPTE StartPte;
    02111     PMMPTE EndPte;
    02112     PMMPTE StartPde;
    02113     PMMPTE StartPpe;
    02114     MMPTE TempPte;
    02115     ULONG First;
    02116     ULONG_PTR i;
    02117     PLIST_ENTRY NextEntry;
    02118     ULONG NumberOfLoaderPtes;
    02119     PFN_NUMBER NextPhysicalPage;
    02120     PVOID Va;
    02121     PLDR_DATA_TABLE_ENTRY DataTableEntry;
    02122
    02123     TempPte = ValidKernelPte;
    02124     TempPte.u.Long |= MM_PTE_EXECUTE;
    02125
    02126     i = 0;
    02127     NextEntry = LoaderBlock->LoadOrderListHead.Flink;
    02128
    02129     for ( ; NextEntry != &LoaderBlock->LoadOrderListHead; NextEntry = NextEntry->Flink) {
    02130
    02131         //
    02132         // As it is mapped through the translation registers, skip the kernel.
    02133         //
    02134
    02135         i += 1;
    02136         if (i <= 1) {
    02137             continue;
    02138         }
    02139
    02140         DataTableEntry = CONTAINING_RECORD(NextEntry,
    02141                                            LDR_DATA_TABLE_ENTRY,
    02142                                            InLoadOrderLinks);
    02143
    02144         NumberOfLoaderPtes = (ULONG)((ROUND_TO_PAGES(DataTableEntry->SizeOfImage)) >> PAGE_SHIFT);
    02145
    02146         Va = DataTableEntry->DllBase;
    02147         StartPte = MiGetPteAddress(Va);
    02148         EndPte = StartPte + NumberOfLoaderPtes;
    02149
    02150         First = TRUE;
    02151
    02152         while (StartPte <= EndPte) {
    02153
    02154             if (First == TRUE || MiIsPteOnPpeBoundary(StartPte)) {
    02155                 StartPpe = MiGetPdeAddress(StartPte);
    02156                 if (StartPpe->u.Hard.Valid == 0) {
    02157                     ASSERT (StartPpe->u.Long == 0);
    02158                     NextPhysicalPage = MiGetNextPhysicalPage();
    02159                     RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE);
    02160                     TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    02161                     MI_WRITE_VALID_PTE(StartPpe, TempPte);
    02162                 }
    02163             }
    02164
    02165             if ((First == TRUE) || MiIsPteOnPdeBoundary(StartPte)) {
    02166                 First = FALSE;
    02167                 StartPde = MiGetPteAddress(StartPte);
    02168                 if (StartPde->u.Hard.Valid == 0) {
    02169                     NextPhysicalPage = MiGetNextPhysicalPage();
    02170                     RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE);
    02171                     TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    02172                     MI_WRITE_VALID_PTE(StartPde, TempPte);
    02173                 }
    02174             }
    02175
    02176             TempPte.u.Hard.PageFrameNumber = MI_CONVERT_PHYSICAL_TO_PFN(Va);
    02177             MI_WRITE_VALID_PTE (StartPte, TempPte);
    02178             StartPte += 1;
    02179             Va = (PVOID)((ULONG_PTR)Va + PAGE_SIZE);
    02180         }
    02181     }
    02182 }

VOID MiBuildPageTableForLoaderMemory | ( | IN PLOADER_PARAMETER_BLOCK | LoaderBlock | ) |

Definition at line 2229 of file mm/ia64/initia64.c.

References ASSERT, _MEMORY_ALLOCATION_DESCRIPTOR::BasePage, FALSE, LoaderBootDriver, LoaderHalCode, LoaderMemoryData, LoaderNlsData, LoaderOsloaderHeap, LoaderRegistryData, LoaderStartupDpcStack, LoaderStartupKernelStack, LoaderStartupPanicStack, LoaderStartupPdrPage, LoaderSystemCode, _MEMORY_ALLOCATION_DESCRIPTOR::MemoryType, MI_WRITE_VALID_PTE, MiConvertToLoaderVirtual(), MiGetNextPhysicalPage(), MiGetPdeAddress, MiGetPteAddress, MiIsPteOnPdeBoundary, MiIsPteOnPpeBoundary, PAGE_SIZE, _MEMORY_ALLOCATION_DESCRIPTOR::PageCount, TRUE, _MMPTE::u, and ValidKernelPte.

Referenced by MiInitMachineDependent().

    02234                    :
    02235
    02236     This function builds page ables for loader loaded drivers and loader
    02237     allocated memory.
    02238
    02239 Arguments:
    02240
    02241     LoaderBlock - Supplies the address of the loader block.
    02242
    02243 Return Value:
    02244
    02245     None.
    02246
    02247 --*/
    02248 {
    02249     PMMPTE StartPte;
    02250     PMMPTE EndPte;
    02251     PMMPTE StartPde;
    02252     PMMPTE StartPpe;
    02253     MMPTE TempPte;
    02254     ULONG First;
    02255     PLIST_ENTRY NextEntry;
    02256     PFN_NUMBER NextPhysicalPage;
    02257     PVOID Va;
    02258     PFN_NUMBER PfnNumber;
    02259     PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
    02260
    02261     TempPte = ValidKernelPte;
    02262     NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
    02263
    02264     for ( ; NextEntry != &LoaderBlock->MemoryDescriptorListHead; NextEntry = NextEntry->Flink) {
    02265
    02266         MemoryDescriptor = CONTAINING_RECORD(NextEntry,
    02267                                              MEMORY_ALLOCATION_DESCRIPTOR,
    02268                                              ListEntry);
    02269
    02270         if ((MemoryDescriptor->MemoryType == LoaderOsloaderHeap) ||
    02271             (MemoryDescriptor->MemoryType == LoaderRegistryData) ||
    02272             (MemoryDescriptor->MemoryType == LoaderNlsData) ||
    02273             (MemoryDescriptor->MemoryType == LoaderStartupDpcStack) ||
    02274             (MemoryDescriptor->MemoryType == LoaderStartupKernelStack) ||
    02275             (MemoryDescriptor->MemoryType == LoaderStartupPanicStack) ||
    02276             (MemoryDescriptor->MemoryType == LoaderStartupPdrPage) ||
    02277             (MemoryDescriptor->MemoryType == LoaderMemoryData)) {
    02278
    02279             TempPte.u.Hard.Execute = 0;
    02280
    02281         } else if ((MemoryDescriptor->MemoryType == LoaderSystemCode) ||
    02282                    (MemoryDescriptor->MemoryType == LoaderHalCode) ||
    02283                    (MemoryDescriptor->MemoryType == LoaderBootDriver) ||
    02284                    (MemoryDescriptor->MemoryType == LoaderStartupDpcStack)) {
    02285
    02286             TempPte.u.Hard.Execute = 1;
    02287
    02288         } else {
    02289
    02290             continue;
    02291
    02292         }
    02293
    02294         PfnNumber = MemoryDescriptor->BasePage;
    02295         Va = MiConvertToLoaderVirtual(MemoryDescriptor->BasePage, LoaderBlock);
    02296
    02297         StartPte = MiGetPteAddress(Va);
    02298         EndPte = StartPte + MemoryDescriptor->PageCount;
    02299
    02300         First = TRUE;
    02301
    02302         while (StartPte <= EndPte) {
    02303
    02304             if (First == TRUE || MiIsPteOnPpeBoundary(StartPte)) {
    02305                 StartPpe = MiGetPdeAddress(StartPte);
    02306                 if (StartPpe->u.Hard.Valid == 0) {
    02307                     ASSERT (StartPpe->u.Long == 0);
    02308                     NextPhysicalPage = MiGetNextPhysicalPage();
    02309                     RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE);
    02310                     TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    02311                     MI_WRITE_VALID_PTE(StartPpe, TempPte);
    02312                 }
    02313             }
    02314
    02315             if ((First == TRUE) || MiIsPteOnPdeBoundary(StartPte)) {
    02316                 First = FALSE;
    02317                 StartPde = MiGetPteAddress(StartPte);
    02318                 if (StartPde->u.Hard.Valid == 0) {
    02319                     NextPhysicalPage = MiGetNextPhysicalPage();
    02320                     RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE);
    02321                     TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    02322                     MI_WRITE_VALID_PTE(StartPde, TempPte);
    02323                 }
    02324             }
    02325
    02326             TempPte.u.Hard.PageFrameNumber = PfnNumber;
    02327             MI_WRITE_VALID_PTE (StartPte, TempPte);
    02328             StartPte += 1;
    02329             PfnNumber += 1;
    02330             Va = (PVOID)((ULONG_PTR)Va + PAGE_SIZE);
    02331         }
    02332     }
    02333 }

VOID MiCheckMemoryDescriptorList | ( | IN PLOADER_PARAMETER_BLOCK | LoaderBlock | ) |

Definition at line 2394 of file mm/ia64/initia64.c.

References _MEMORY_ALLOCATION_DESCRIPTOR::BasePage, DbgPrint, LoaderFirmwareTemporary, LoaderSpecialMemory, LoaderSystemBlock, _MEMORY_ALLOCATION_DESCRIPTOR::MemoryType, MiNtoskrnlPageShift, MiNtoskrnlPhysicalBase, MiPrintMemoryDescriptors, NULL, PAGE_SHIFT, and _MEMORY_ALLOCATION_DESCRIPTOR::PageCount.

Referenced by MiInitMachineDependent().

    02397 {
    02398     PFN_NUMBER KernelStart;
    02399     PFN_NUMBER KernelEnd;
    02400     ULONG_PTR PageSize;
    02401     PLIST_ENTRY NextEntry;
    02402     PLIST_ENTRY PreviousEntry;
    02403     PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
    02404     PMEMORY_ALLOCATION_DESCRIPTOR PreviousMemoryDescriptor;
    02405
    02406
    02407     KernelStart = MiNtoskrnlPhysicalBase >> PAGE_SHIFT;
    02408     PageSize = (ULONG_PTR)1 << MiNtoskrnlPageShift;
    02409     KernelEnd = KernelStart + (PageSize >> PAGE_SHIFT);
    02410
    02411     PreviousMemoryDescriptor = NULL;
    02412     PreviousEntry = NULL;
    02413
    02414     NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
    02415
    02416     for ( ; NextEntry != &LoaderBlock->MemoryDescriptorListHead; NextEntry = NextEntry->Flink) {
    02417
    02418         MemoryDescriptor = CONTAINING_RECORD(NextEntry,
    02419                                              MEMORY_ALLOCATION_DESCRIPTOR,
    02420                                              ListEntry);
    02421
    02422 #if DBG
    02423         if (MiPrintMemoryDescriptors) {
    02424             DbgPrint("MemoryType = %x\n", MemoryDescriptor->MemoryType);
    02425             DbgPrint("BasePage = %p\n", (PFN_NUMBER)MemoryDescriptor->BasePage << PAGE_SHIFT);
    02426             DbgPrint("PageCount = %x\n\n", MemoryDescriptor->PageCount << PAGE_SHIFT);
    02427         }
    02428 #endif
    02429         if ((MemoryDescriptor->BasePage >= KernelStart) &&
    02430             (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount <= KernelEnd)) {
    02431
    02432             if (MemoryDescriptor->MemoryType == LoaderSystemBlock) {
    02433
    02434                 MemoryDescriptor->MemoryType = LoaderFirmwareTemporary;
    02435
    02436             } else if (MemoryDescriptor->MemoryType == LoaderSpecialMemory) {
    02437
    02438                 MemoryDescriptor->MemoryType = LoaderFirmwareTemporary;
    02439
    02440             }
    02441         }
    02442
    02443
    02444         if ((PreviousMemoryDescriptor != NULL) &&
    02445             (MemoryDescriptor->MemoryType == PreviousMemoryDescriptor->MemoryType) &&
    02446             (MemoryDescriptor->BasePage ==
    02447              (PreviousMemoryDescriptor->BasePage + PreviousMemoryDescriptor->PageCount))) {
    02448
    02449             PreviousMemoryDescriptor->PageCount += MemoryDescriptor->PageCount;
    02450             PreviousEntry->Flink = NextEntry->Flink;
    02451
    02452         } else {
    02453
    02454             PreviousMemoryDescriptor = MemoryDescriptor;
    02455             PreviousEntry = NextEntry;
    02456
    02457         }
    02458
    02459     }
    02460
    02461 }

VOID MiConvertBackToStandardPages | ( | IN PVOID | StartVirtual,
|  | IN PVOID | EndVirtual
| ) |

Definition at line 1995 of file mm/ia64/initia64.c.

References MI_WRITE_VALID_PTE, MiGetPteAddress, PAGE_ALIGN, PAGE_SIZE, and _MMPTE::u.

    02001                    :
    02002
    02003     This function disables the use of the super pages.
    02004
    02005 Arguments:
    02006
    02007     StartVirtual - the start address of the region of pages to disable super pages.
    02008           super pages.
    02009
    02010     EndVirtual - the end address of the region of pages to disable super pages.
    02011
    02012 Return Value:
    02013
    02014     None.
    02015
    02016 --*/
    02017 {
    02018     ULONG_PTR VirtualAddress;
    02019     ULONG_PTR i;
    02020     ULONG_PTR NumberOfPte;
    02021     PMMPTE StartPte;
    02022     MMPTE TempPte;
    02023
    02024     VirtualAddress = (ULONG_PTR) PAGE_ALIGN(StartVirtual);
    02025
    02026     StartPte = MiGetPteAddress(VirtualAddress);
    02027
    02028     while (VirtualAddress <= (ULONG_PTR)EndVirtual) {
    02029
    02030         TempPte = *StartPte;
    02031         TempPte.u.Large.PageSize = 0;
    02032         TempPte.u.Large.PageSize = 0;
    02033         TempPte.u.Hard.Valid = 1;
    02034         MI_WRITE_VALID_PTE (StartPte, TempPte);
    02035
    02036         StartPte += 1;
    02037         VirtualAddress += PAGE_SIZE;
    02038     }
    02039 }

PVOID MiConvertToLoaderVirtual | ( | IN PFN_NUMBER | Page,
|  | IN PLOADER_PARAMETER_BLOCK | LoaderBlock
| ) |

Definition at line 2185 of file mm/ia64/initia64.c.

References KeBugCheckEx(), and PAGE_SHIFT.

Referenced by MiBuildPageTableForLoaderMemory().

    02189 {
    02190     ULONG_PTR PageAddress = Page << PAGE_SHIFT;
    02191     PTR_INFO ItrInfo = &LoaderBlock->u.Ia64.ItrInfo[0];
    02192
    02193
    02194     if ((PageAddress >= ItrInfo[ITR_KERNEL_INDEX].PhysicalAddress) &&
    02195         (PageAddress <= ItrInfo[ITR_KERNEL_INDEX].PhysicalAddress +
    02196          ((ULONG_PTR)1 << ItrInfo[ITR_KERNEL_INDEX].PageSize))) {
    02197
    02198         return (PVOID)(ItrInfo[ITR_KERNEL_INDEX].VirtualAddress +
    02199                        (PageAddress - ItrInfo[ITR_KERNEL_INDEX].PhysicalAddress));
    02200
    02201     } else if ((PageAddress >= ItrInfo[ITR_DRIVER0_INDEX].PhysicalAddress) &&
    02202         (PageAddress <= ItrInfo[ITR_DRIVER0_INDEX].PhysicalAddress +
    02203          ((ULONG_PTR)1 << ItrInfo[ITR_DRIVER0_INDEX].PageSize))) {
    02204
    02205         return (PVOID)(ItrInfo[ITR_DRIVER0_INDEX].VirtualAddress +
    02206                        (PageAddress - ItrInfo[ITR_DRIVER0_INDEX].PhysicalAddress));
    02207
    02208     } else if ((PageAddress >= ItrInfo[ITR_DRIVER1_INDEX].PhysicalAddress) &&
    02209         (PageAddress <= ItrInfo[ITR_DRIVER1_INDEX].PhysicalAddress +
    02210          ((ULONG_PTR)1 << ItrInfo[ITR_DRIVER1_INDEX].PageSize))) {
    02211
    02212         return (PVOID)(ItrInfo[ITR_DRIVER1_INDEX].VirtualAddress +
    02213                        (PageAddress - ItrInfo[ITR_DRIVER1_INDEX].PhysicalAddress));
    02214
    02215     } else {
    02216
    02217         KeBugCheckEx (MEMORY_MANAGEMENT,
    02218                       0x01010101,
    02219                       PageAddress,
    02220                       (ULONG_PTR)&ItrInfo[0],
    02221                       (ULONG_PTR)LoaderBlock);
    02222
    02223         return 0;
    02224     }
    02225 }

VOID MiConvertToSuperPages | ( | IN PVOID | StartVirtual,
|  | IN PVOID | EndVirtual,
|  | IN SIZE_T | PageSize,
|  | IN ULONG | PageShift
| ) |

Definition at line 1921 of file mm/ia64/initia64.c.

References MiGetPteAddress, PAGE_ALIGN, PAGE_SHIFT, PAGE_SIZE, and _MMPTE::u.

Referenced by MiInitMachineDependent().

    01929                    :
    01930
    01931     This function makes contiguous non-paged memory use super pages rather than
    01932     using page tables.
    01933
    01934 Arguments:
    01935
    01936     StartVirtual - the start address of the region of pages to be mapped by
    01937           super pages.
    01938
    01939     EndVirtual - the end address of the region of pages to be mapped by super
    01940           pages.
    01941
    01942     Page Size - the page size to be used by the super page.
    01943
    01944     Page Shift - the page shift count to be used by the super page.
    01945
    01946 Return Value:
    01947
    01948     None.
    01949
    01950 --*/
    01951 {
    01952     ULONG_PTR VirtualAddress;
    01953     ULONG_PTR i;
    01954     ULONG_PTR NumberOfPte;
    01955     PMMPTE StartPte;
    01956
    01957     VirtualAddress = (ULONG_PTR) PAGE_ALIGN(StartVirtual);
    01958     i = VirtualAddress & (PageSize - 1);
    01959
    01960     if (i != 0) {
    01961
    01962         VirtualAddress = (VirtualAddress + PageSize - 1) & ~(PageSize - 1);
    01963
    01964     }
    01965
    01966     StartPte = MiGetPteAddress(VirtualAddress);
    01967     NumberOfPte = PageSize >> PAGE_SHIFT;
    01968
    01969     i = 0;
    01970
    01971     while (VirtualAddress <= (ULONG_PTR)EndVirtual) {
    01972
    01973         if (i == NumberOfPte) {
    01974
    01975             StartPte -= NumberOfPte;
    01976
    01977             for (i = 0; i < NumberOfPte; i++) {
    01978
    01979                 StartPte->u.Hard.Valid = 0;
    01980                 StartPte->u.Large.LargePage = 1;
    01981                 StartPte->u.Large.PageSize = PageShift;
    01982                 StartPte += 1;
    01983             }
    01984
    01985             i = 0;
    01986         }
    01987
    01988         i += 1;
    01989         StartPte += 1;
    01990         VirtualAddress += PAGE_SIZE;
    01991     }
    01992 }

VOID MiConvertToSuperPages | ( | PVOID | StartVirtual,
|  | PVOID | EndVirtual,
|  | SIZE_T | PageSize,
|  | ULONG | PageShift
| ) |

BOOLEAN MiEnsureAvailablePagesInFreeDescriptor | ( | IN PFN_NUMBER | Pages,
|  | IN PFN_NUMBER | MaxPage
| ) |

Definition at line 225 of file mm/ia64/initia64.c.

References _MEMORY_ALLOCATION_DESCRIPTOR::BasePage, FALSE, KeBugCheckEx(), MiFreeDescriptor, MiFreeDescriptorLargest, MiFreeDescriptorLowMem, MiFreeDescriptorNonPaged, MiNextPhysicalPage, MiNumberOfPages, MiOldFreeDescriptorBase, MiOldFreeDescriptorCount, MmHighestPhysicalPage, MmLowestPhysicalPage, MmNumberOfPhysicalPages, _MEMORY_ALLOCATION_DESCRIPTOR::PageCount, and TRUE.

Referenced by MiInitMachineDependent().

    00229 {
    00230     if ((MiNumberOfPages < Pages) &&
    00231         (MiFreeDescriptor == MiFreeDescriptorNonPaged)) {
    00232
    00233         MiFreeDescriptor->BasePage = (ULONG)MiNextPhysicalPage;
    00234         MiFreeDescriptor->PageCount = (PFN_COUNT)MiNumberOfPages;
    00235
    00236         if (MiFreeDescriptor != MiFreeDescriptorLowMem) {
    00237
    00238             MiOldFreeDescriptorCount = MiFreeDescriptorLowMem->PageCount;
    00239             MiOldFreeDescriptorBase = MiFreeDescriptorLowMem->BasePage;
    00240
    00241             MiFreeDescriptor = MiFreeDescriptorLowMem;
    00242             MiNumberOfPages = MiFreeDescriptorLowMem->PageCount;
    00243             MiNextPhysicalPage = MiFreeDescriptorLowMem->BasePage;
    00244
    00245         } else if (MiFreeDescriptor != MiFreeDescriptorLargest) {
    00246
    00247             MiOldFreeDescriptorCount = MiFreeDescriptorLargest->PageCount;
    00248             MiOldFreeDescriptorBase = MiFreeDescriptorLargest->BasePage;
    00249
    00250             MiFreeDescriptor = MiFreeDescriptorLargest;
    00251             MiNumberOfPages = MiFreeDescriptorLargest->PageCount;
    00252             MiNextPhysicalPage = MiFreeDescriptorLargest->BasePage;
    00253
    00254         } else {
    00255
    00256             KeBugCheckEx(INSTALL_MORE_MEMORY,
    00257                          MmNumberOfPhysicalPages,
    00258                          MmLowestPhysicalPage,
    00259                          MmHighestPhysicalPage,
    00260                          1);
    00261         }
    00262     }
    00263
    00264     if (MaxPage < (MiFreeDescriptor->BasePage + Pages)) {
    00265
    00266         return FALSE;
    00267
    00268     } else {
    00269
    00270         return TRUE;
    00271
    00272     }
    00273 }

PVOID MiGetKSegAddress | ( | PFN_NUMBER | FrameNumber | ) |

Definition at line 1871 of file mm/ia64/initia64.c.

References ASSERT, MI_WRITE_VALID_PTE, MiGetKSegPteAddress, MmHighestPhysicalPage, PAGE_SHIFT, _MMPTE::u, ValidKernelPte, and Virtual.

    01876                    :
    01877
    01878     This function returns the KSEG3 address which maps the given physical page.
    01879
    01880 Arguments:
    01881
    01882    FrameNumber - Supplies the physical page number to get the KSEG3 address for
    01883
    01884 Return Value:
    01885
    01886     Virtual address mapped in KSEG3 space
    01887
    01888     TBS
    01889
    01890 --*/
    01891 {
    01892     PVOID Virtual;
    01893     PMMPTE PointerPte;
    01894     MMPTE TempPte;
    01895
    01896     ASSERT (FrameNumber <= MmHighestPhysicalPage);
    01897
    01898     Virtual = ((PVOID)(KSEG3_BASE | ((ULONG_PTR)(FrameNumber) << PAGE_SHIFT)));
    01899
    01900 #if defined(KSEG_VHPT)
    01901     PointerPte = MiGetKSegPteAddress (Virtual);
    01902
    01903     if (PointerPte->u.Long == 0) {
    01904
    01905         //
    01906         // if the VHPT entry for the KSEG3 address is still zero, build it here.
    01907         //
    01908
    01909         TempPte = ValidKernelPte;
    01910         TempPte.u.Hard.PageFrameNumber = FrameNumber;
    01911         MI_WRITE_VALID_PTE(PointerPte, TempPte);
    01912
    01913         __mf();
    01914     }
    01915 #endif
    01916
    01917     return (Virtual);
    01918 }

PFN_NUMBER MiGetNextPhysicalPage | ( | VOID |  | ) |

Definition at line 139 of file mm/ia64/initia64.c.

References _MEMORY_ALLOCATION_DESCRIPTOR::BasePage, KeBugCheckEx(), MiFreeDescriptor, MiFreeDescriptorLargest, MiFreeDescriptorLowMem, MiFreeDescriptorNonPaged, MiNextPhysicalPage, MiNumberOfPages, MiOldFreeDescriptorBase, MiOldFreeDescriptorCount, MmHighestPhysicalPage, MmLowestPhysicalPage, MmNumberOfPhysicalPages, and _MEMORY_ALLOCATION_DESCRIPTOR::PageCount.

Referenced by MiBuildPageTableForDrivers(), MiBuildPageTableForLoaderMemory(), and MiInitMachineDependent().

    00145                    :
    00146
    00147     This function returns the next physical page number from either the
    00148     largest low memory descritor or the largest free descriptor. If there
    00149     are no physical pages left, then a bugcheck is executed since the
    00150     system cannot be initialized.
    00151
    00152 Arguments:
    00153
    00154     LoaderBlock - Supplies the address of the loader block.
    00155
    00156 Return Value:
    00157
    00158     None.
    00159
    00160 Environment:
    00161
    00162     Kernel mode.
    00163
    00164 --*/
    00165
    00166 {
    00167
    00168     //
    00169     // If there are free pages left in the current descriptor, then
    00170     // return the next physical page. Otherwise, attempt to switch
    00171     // descriptors.
    00172     //
    00173
    00174     if (MiNumberOfPages != 0) {
    00175         MiNumberOfPages -= 1;
    00176         return MiNextPhysicalPage++;
    00177
    00178     } else {
    00179
    00180         //
    00181         // If the current descriptor is not the largest free descriptor,
    00182         // then switch to the largest free descriptor. Otherwise, bugcheck.
    00183         //
    00184
    00185         if (MiFreeDescriptor == MiFreeDescriptorLargest) {
    00186
    00187             KeBugCheckEx(INSTALL_MORE_MEMORY,
    00188                          MmNumberOfPhysicalPages,
    00189                          MmLowestPhysicalPage,
    00190                          MmHighestPhysicalPage,
    00191                          0);
    00192
    00193             return 0;
    00194
    00195         } else if (MiFreeDescriptor == MiFreeDescriptorLowMem) {
    00196
    00197             MiOldFreeDescriptorCount = MiFreeDescriptorLargest->PageCount;
    00198             MiOldFreeDescriptorBase = MiFreeDescriptorLargest->BasePage;
    00199
    00200             MiFreeDescriptor = MiFreeDescriptorLargest;
    00201             MiNumberOfPages = MiFreeDescriptorLargest->PageCount - 1;
    00202             MiNextPhysicalPage = MiFreeDescriptorLargest->BasePage;
    00203
    00204             MiFreeDescriptorLowMem->PageCount = 0;
    00205
    00206             return MiNextPhysicalPage++;
    00207
    00208         } else {
    00209
    00210             MiOldFreeDescriptorCount = MiFreeDescriptorLowMem->PageCount;
    00211             MiOldFreeDescriptorBase = MiFreeDescriptorLowMem->BasePage;
    00212
    00213             MiFreeDescriptor = MiFreeDescriptorLowMem;
    00214             MiNumberOfPages = MiFreeDescriptorLowMem->PageCount - 1;
    00215             MiNextPhysicalPage = MiFreeDescriptorLowMem->BasePage;
    00216
    00217             MiFreeDescriptorNonPaged->PageCount = 0;
    00218
    00219             return MiNextPhysicalPage++;
    00220         }
    00221     }
    00222 }

VOID MiInitMachineDependent | ( | IN PLOADER_PARAMETER_BLOCK | LoaderBlock | ) |

Definition at line 277 of file mm/ia64/initia64.c.

References _x16mb, _x16mbnp, _x1mb, _x1mbnp, _x256mb, _x256mbnp, _x4gbnp, _x4mb, _x64mb, ActiveAndValid, ASSERT, BadPageList, _MEMORY_ALLOCATION_DESCRIPTOR::BasePage, _MMPFNLIST::Blink, BYTES_TO_PAGES, c, DbgPrint, ExAllocatePoolWithTag, FALSE, FIRST_MAPPING_PTE, _MMPFNLIST::Flink, _MMCOLOR_TABLES::Flink, FreePageList, HYPER_SPACE, HYPER_SPACE_END, InitializationPhase, INITIALIZE_DIRECTORY_TABLE_BASE, InitializePool(), KeBugCheckEx(), KeFlushCurrentTb(), KeInitializeSpinLock(), KeInitializeVhpt(), KSEG0_ADDRESS, KSEG0_BASE, LAST_MAPPING_PTE, _MEMORY_ALLOCATION_DESCRIPTOR::ListEntry, _MMPFNLIST::ListName, LoaderBad, LoaderFirmwareTemporary, LoaderFree, LoaderLoadedProgram, LoaderOsloaderStack, _MMSUPPORT::MaximumWorkingSetSize, _MEMORY_ALLOCATION_DESCRIPTOR::MemoryType, MI_CONVERT_PHYSICAL_TO_PFN, MI_GET_COLOR_FROM_SECONDARY, MI_GET_PAGE_COLOR_FROM_PTE, MI_GET_PAGE_FRAME_FROM_PTE, MI_IS_PHYSICAL_ADDRESS, MI_PFN_ELEMENT, MI_SET_PFN_DELETED, MI_WRITE_INVALID_PTE, MI_WRITE_VALID_PTE, MiBuildPageTableForLoaderMemory(), MiCheckMemoryDescriptorList(), MiConvertToSuperPages(), MiDecrementReferenceCount(), MiEnsureAvailablePagesInFreeDescriptor(), MiFreeDescriptor, MiFreeDescriptorLargest, MiFreeDescriptorLowMem, MiFreeDescriptorNonPaged, MiGetKSegPteAddress, MiGetNextPhysicalPage(), MiGetPdeAddress, MiGetPpeAddress, MiGetPteAddress, MiGetVirtualAddressMappedByPte, MiImplVirtualMsb, MiInitializeNonPagedPool(), MiInitializeSystemPtes(), MiInsertPageInList(), MiIsPteOnPdeBoundary, MiIsPteOnPpeBoundary, MiKseg0End, MiKseg0Mapping, MiKseg0Start, MiMakeKernelPagesPermanent(), MiNextPhysicalPage, _MMSUPPORT::MinimumWorkingSetSize, MiNtoskrnlPageShift, MiNtoskrnlPhysicalBase, MiNtoskrnlVirtualBase, MiNumberOfPages, MiOldFreeDescriptorBase, MiOldFreeDescriptorCount, MiPrintMemoryDescriptors, MiRemoveAnyPage(), MiRemoveLoaderSuperPages(), MiSystemSelfMappedPte, MiUserSelfMappedPte, MiWasteEnd, MiWasteStart, MM_CRASH_DUMP_VA, MM_DEBUG_VA, MM_EMPTY_LIST, MM_LOWEST_NONPAGED_SYSTEM_START, MM_MAX_ADDITIONAL_NONPAGED_POOL, MM_MAX_INITIAL_NONPAGED_POOL, MM_MAXIMUM_NUMBER_OF_COLORS, MM_PAGES_IN_KSEG0, MM_PFN_DATABASE_START, MM_PTE_16MB_PAGE, MM_PTE_1MB_PAGE, MM_PTE_256MB_PAGE, MM_PTE_4MB_PAGE, MM_PTE_64MB_PAGE, MM_SECONDARY_COLORS_DEFAULT, MM_SECONDARY_COLORS_MAX, MM_SECONDARY_COLORS_MIN, MM_SYSTEM_SPACE_END, MMCOLOR_TABLES, MmCrashDumpPte, MmDebugPte, MmDefaultMaximumNonPagedPool, MmFirstReservedMappingPte, MmFreePagesByColor, MmFreePagesByPrimaryColor, MmHighestPhysicalPage, MmHighestPossiblePhysicalPage, MmInitializeProcessAddressSpace(), MmKseg3VhptBase, MmKseg3VhptPs, MmLastReservedMappingPte, MmLowestPhysicalPage, MmMaxAdditionNonPagedPoolPerMb, MmMaximumNonPagedPoolInBytes, MmMinAdditionNonPagedPoolPerMb, MmMinimumNonPagedPoolSize, MmNonPagedMustSucceed, MmNonPagedPoolEnd, MmNonPagedPoolExpansionStart, MmNonPagedPoolStart, MmNonPagedSystemStart, MmNumberOfPhysicalPages, MmNumberOfSystemPtes, MmPageAlignedPoolBase, MmPageLocationList, MmPfnDatabase, MmPfnLock, MmSecondaryColorMask, MmSecondaryColors, MmSizeOfNonPagedMustSucceed, MmSizeOfNonPagedPoolInBytes, MmSubsectionBase, MmSubsectionTopPage, MmSystemParentTablePage, MmSystemProcessWorkingSetMax, MmSystemProcessWorkingSetMin, MmSystemSpaceLock, MmWorkingSetList, MmWsle, NonPagedPool, NonPagedPoolMustSucceed, NULL, PAGE_ALIGN, PAGE_DIRECTORY2_MASK, PAGE_SHIFT, PAGE_SIZE, _MEMORY_ALLOCATION_DESCRIPTOR::PageCount, PDE_KTBASE, PsGetCurrentProcess, PTE_PER_PAGE, PTE_SHIFT, _MMPFN::PteAddress, _MMPFN::PteFrame, RtlCompareMemoryUlong(), StandbyPageList, SystemPteSpace, TRUE, _MMPTE::u, _MMPFN::u2, _MMPFN::u3, ValidKernelPte, ValidPdePde, _EPROCESS::Vm, WORKING_SET_LIST, _EPROCESS::WorkingSetPage, X64K, ZeroedPageList, and ZeroKernelPte.

    00283                    :
    00284
    00285     This routine performs the necessary operations to enable virtual
    00286     memory.  This includes building the page directory page, building
    00287     page table pages to map the code section, the data section, the'
    00288     stack section and the trap handler.
    00289
    00290     It also initializes the PFN database and populates the free list.
    00291
    00292
    00293 Arguments:
    00294
    00295     LoaderBlock  - Supplies a pointer to the firmware setup loader block.
    00296
    00297 Return Value:
    00298
    00299     None.
    00300
    00301 Environment:
    00302
    00303     Kernel mode.
    00304
    00305 --*/
    00306
    00307 {
    00308     PMMPFN BasePfn;
    00309     PMMPFN BottomPfn;
    00310     PMMPFN TopPfn;
    00311     SIZE_T Range;
    00312     PFN_NUMBER i;
    00313     ULONG j;
    00314     PFN_NUMBER PdePageNumber;
    00315     PFN_NUMBER PdePage;
    00316     PFN_NUMBER PageFrameIndex;
    00317     PFN_NUMBER NextPhysicalPage;
    00318     SPFN_NUMBER PfnAllocation;
    00319     SPFN_NUMBER NumberOfPages;
    00320     SIZE_T MaxPool;
    00321     PEPROCESS CurrentProcess;
    00322     PFN_NUMBER MostFreePage = 0;
    00323     PFN_NUMBER MostFreeLowMem = 0;
    00324     PFN_NUMBER MostFreeNonPaged = 0;
    00325     PLIST_ENTRY NextMd;
    00326     PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
    00327     MMPTE TempPte;
    00328     PMMPTE PointerPde;
    00329     PMMPTE PointerPte;
    00330     PMMPTE StartPte;
    00331     PMMPTE LastPte;
    00332     PMMPTE EndPte;
    00333     PMMPTE Pde;
    00334     PMMPTE StartPde;
    00335     PMMPTE StartPpe;
    00336     PMMPTE EndPde;
    00337     PMMPTE FirstPpe;
    00338     PMMPFN Pfn1;
    00339     PMMPFN Pfn2;
    00340     ULONG First;
    00341     KIRQL OldIrql;
    00342     ULONG_PTR va;
    00343     SIZE_T Kseg0Size = 0;
    00344     PVOID NonPagedPoolStartVirtual;
    00345     ULONG i1;
    00346     ULONG i2;
    00347     PFN_NUMBER PhysicalPages;
    00348     ULONG_PTR HighestPageAddress;
    00349     ULONG_PTR Kseg3VhptSize;
    00350     PFN_NUMBER Kseg3VhptPn;
    00351     ULONG_PTR size;
    00352     ULONG_PTR PageSize;
    00353     PFN_NUMBER KernelStart;
    00354     PFN_NUMBER KernelEnd;
    00355
    00356     if (InitializationPhase == 1) {
    00357
    00358         MiMakeKernelPagesPermanent(LoaderBlock);
    00359
    00360         return;
    00361
    00362     }
    00363
    00364     //
    00365     // Initialize the kernel mapping info
    00366     //
    00367
    00368     MiNtoskrnlPhysicalBase = LoaderBlock->u.Ia64.ItrInfo[ITR_KERNEL_INDEX].PhysicalAddress;
    00369     MiNtoskrnlVirtualBase = LoaderBlock->u.Ia64.ItrInfo[ITR_KERNEL_INDEX].VirtualAddress;
    00370     MiNtoskrnlPageShift = LoaderBlock->u.Ia64.ItrInfo[ITR_KERNEL_INDEX].PageSize;
    00371
    00372     KernelStart = MiNtoskrnlPhysicalBase >> PAGE_SHIFT;
    00373     PageSize = (ULONG_PTR)1 << MiNtoskrnlPageShift;
    00374     KernelEnd = KernelStart + (PageSize >> PAGE_SHIFT);
    00375
    00376     //
    00377     // Initialize MmDebugPte and MmCrashDumpPte
    00378     //
    00379
    00380     MmDebugPte = MiGetPteAddress(MM_DEBUG_VA);
    00381
    00382     MmCrashDumpPte = MiGetPteAddress(MM_CRASH_DUMP_VA);
    00383
    00384     //
    00385     // Set TempPte to ValidKernelPte for the future use
    00386     //
    00387
    00388     TempPte = ValidKernelPte;
    00389
    00390     //
    00391     // Check the memory descriptor list from NT loader
    00392     //
    00393
    00394     MiCheckMemoryDescriptorList(LoaderBlock);
    00395
    00396
    00397     //
    00398     // Get the lower bound of the free physical memory and the
    00399     // number of physical pages by walking the memory descriptor lists.
    00400     //
    00401
    00402     NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
    00403
    00404 #if ADD_HIGH_MEMORY
    00405     LoaderBlock->MemoryDescriptorListHead.Flink = &MiHighMemoryDescriptor.ListEntry;
    00406     MiHighMemoryDescriptor.ListEntry.Flink = NextMd;
    00407     MiHighMemoryDescriptor.MemoryType = 5;
    00408     MiHighMemoryDescriptor.BasePage = 0x80000;
    00409     MiHighMemoryDescriptor.PageCount = 0x20000;
    00410     NextMd = &MiHighMemoryDescriptor.ListEntry;
    00411 #endif
    00412
    00413     while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
    00414
    00415         MemoryDescriptor = CONTAINING_RECORD(NextMd,
    00416                                              MEMORY_ALLOCATION_DESCRIPTOR,
    00417                                              ListEntry);
    00418
    00419         //
    00420         // This check results in /BURNMEMORY chunks not being counted.
    00421         //
    00422
    00423         if (MemoryDescriptor->MemoryType != LoaderBad) {
    00424             MmNumberOfPhysicalPages += MemoryDescriptor->PageCount;
    00425         }
    00426
    00427         if (MemoryDescriptor->BasePage < MmLowestPhysicalPage) {
    00428             MmLowestPhysicalPage = MemoryDescriptor->BasePage;
    00429         }
    00430         if ((MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) >
    00431                                                          MmHighestPhysicalPage) {
    00432             MmHighestPhysicalPage =
    00433                     MemoryDescriptor->BasePage + MemoryDescriptor->PageCount -1;
    00434         }
    00435
    00436         //
    00437         // We assume at this stage (Gambit Port) that the minimum memory requirement
    00438         // for the iA EM is 32mb. There will be no memory hole right below the 16m
    00439         // boundary on EM machines unlike some x86 of PC platforms.
    00440         //
    00441
    00442         if ((MemoryDescriptor->MemoryType == LoaderFree) ||
    00443             (MemoryDescriptor->MemoryType == LoaderLoadedProgram) ||
    00444             (MemoryDescriptor->MemoryType == LoaderFirmwareTemporary) ||
    00445             (MemoryDescriptor->MemoryType == LoaderOsloaderStack)) {
    00446
    00447             if (MemoryDescriptor->PageCount > MostFreePage) {
    00448                 MostFreePage = MemoryDescriptor->PageCount;
    00449                 MiFreeDescriptorLargest = MemoryDescriptor;
    00450              }
    00451
    00452             if (MemoryDescriptor->BasePage < _x256mbnp) {
    00453
    00454                 //
    00455                 // This memory descriptor is below 16mb.
    00456                 //
    00457
    00458                 if ((MostFreeLowMem < MemoryDescriptor->PageCount) &&
    00459                     (MostFreeLowMem < _x256mbnp - MemoryDescriptor->BasePage)) {
    00460
    00461                     MostFreeLowMem = _x256mbnp - MemoryDescriptor->BasePage;
    00462                     if (MemoryDescriptor->PageCount < MostFreeLowMem) {
    00463                         MostFreeLowMem = MemoryDescriptor->PageCount;
    00464                     }
    00465
    00466                     MiFreeDescriptorLowMem = MemoryDescriptor;
    00467                 }
    00468             }
    00469
    00470             if ((MemoryDescriptor->BasePage >= KernelStart) &&
    00471                 (MemoryDescriptor->PageCount > MostFreeNonPaged)) {
    00472
    00473                 MostFreeNonPaged = MemoryDescriptor->PageCount;
    00474                 MiFreeDescriptorNonPaged = MemoryDescriptor;
    00475
    00476             }
    00477
    00478         }
    00479
    00480 #if DBG
    00481         if (MiPrintMemoryDescriptors) {
    00482             DbgPrint("MemoryType = %x\n", MemoryDescriptor->MemoryType);
    00483             DbgPrint("BasePage = %p\n", (PFN_NUMBER)MemoryDescriptor->BasePage << PAGE_SHIFT);
    00484             DbgPrint("PageCount = %x\n\n", MemoryDescriptor->PageCount << PAGE_SHIFT);
    00485         }
    00486 #endif
    00487
    00488         NextMd = MemoryDescriptor->ListEntry.Flink;
    00489     }
    00490
    00491     MmHighestPossiblePhysicalPage = MmHighestPhysicalPage;
    00492
    00493     //
    00494     // If the number of physical pages is less than  16mb, then
    00495     // bugcheck. There is not enough memory to run the system.
    00496     //
    00497
    00498     if (MmNumberOfPhysicalPages < _x16mbnp) {
    00499         KeBugCheckEx (INSTALL_MORE_MEMORY,
    00500                       MmNumberOfPhysicalPages,
    00501                       MmLowestPhysicalPage,
    00502                       MmHighestPhysicalPage,
    00503                       2);
    00504     }
    00505
    00506     //
    00507     // initialize the next page allocation variable & structures
    00508     //
    00509
    00510
    00511     if (MiFreeDescriptorNonPaged != NULL) {
    00512
    00513         MiFreeDescriptor = MiFreeDescriptorNonPaged;
    00514
    00515     } else if (MiFreeDescriptorLowMem != NULL) {
    00516
    00517         MiFreeDescriptor = MiFreeDescriptorLowMem;
    00518
    00519     } else {
    00520
    00521         MiFreeDescriptor = MiFreeDescriptorLargest;
    00522     }
    00523
    00524     if (MiFreeDescriptorLowMem == NULL) {
    00525
    00526         MiKseg0Mapping = FALSE;
    00527
    00528     }
    00529
    00530     MiNextPhysicalPage = MiFreeDescriptor->BasePage;
    00531     MiNumberOfPages = MiFreeDescriptor->PageCount;
    00532     MiOldFreeDescriptorCount = MiFreeDescriptor->PageCount;
    00533     MiOldFreeDescriptorBase = MiFreeDescriptor->BasePage;
    00534
    00535     //
    00536     // Produce the size of the Kseg 0 space
    00537     //
    00538
    00539     if (MiKseg0Mapping == TRUE) {
    00540
    00541
    00542         MiKseg0Start = KSEG0_ADDRESS(MiNextPhysicalPage);
    00543
    00544         Kseg0Size = MiNextPhysicalPage + MiNumberOfPages;
    00545
    00546         if (Kseg0Size > MM_PAGES_IN_KSEG0) {
    00547             Kseg0Size = MM_PAGES_IN_KSEG0 - (_x16mbnp * 3);
    00548         }
    00549
    00550         Kseg0Size = Kseg0Size << PAGE_SHIFT;
    00551
    00552     } else {
    00553
    00554         MiKseg0Mapping = FALSE;
    00555         Kseg0Size = 0;
    00556
    00557     }
    00558
    00559     //
    00560     // Initialize VHPT registers
    00561     //
    00562
    00563     KeInitializeVhpt ((PVOID)PTA_BASE, MiImplVirtualMsb - PAGE_SHIFT + PTE_SHIFT);
    00564
    00565     //
    00566     // Build 1 to 1 virtual to physical mapping space
    00567     //
    00568
    00569 #if defined(KSEG_VHPT)
    00570     HighestPageAddress = ((ULONG_PTR)MmHighestPhysicalPage << PAGE_SHIFT);
    00571
    00572     HighestPageAddress = (HighestPageAddress + (ULONG_PTR)X64K - 1) & ~((ULONG_PTR)X64K - 1);
    00573
    00574     Kseg3VhptSize = HighestPageAddress >> 16 << PTE_SHIFT;
    00575
    00576     size = (Kseg3VhptSize-1) >> 12;  // make the base page size 4KB
    00577     PageSize = 12;
    00578
    00579     while (size != 0) {
    00580         size = size >> 2;
    00581         PageSize += 2;
    00582     }
    00583
    00584     Kseg3VhptSize = (ULONG_PTR)1 << PageSize;
    00585
    00586     Kseg3VhptPages = (PFN_NUMBER)(Kseg3VhptSize >> PAGE_SHIFT);
    00587
    00588     if ((MiFreeDescriptor->BasePage & (_x16mbnp - 1)) != 0) {
    00589         KeBugCheckEx (INSTALL_MORE_MEMORY,
    00590                       MmNumberOfPhysicalPages,
    00591                       MmLowestPhysicalPage,
    00592                       MmHighestPhysicalPage,
    00593                       3);
    00594     }
    00595
    00596     MmKseg3VhptBase = MiNextPhysicalPage;
    00597     MiNextPhysicalPage += Kseg3VhptPages;
    00598     MiNumberOfPages -= Kseg3VhptPages;
    00599
    00600     if (MiNumberOfPages < 0) {
    00601
    00602         KeBugCheckEx(INSTALL_MORE_MEMORY,
    00603                      MmNumberOfPhysicalPages,
    00604                      MmLowestPhysicalPage,
    00605                      MmHighestPhysicalPage,
    00606                      4);
    00607     }
    00608
    00609 #endif
    00610
    00611     //
    00612     // Build a parent directory page table for the kernel space
    00613     //
    00614
    00615     PdePageNumber = (PFN_NUMBER)LoaderBlock->u.Ia64.PdrPage;
    00616
    00617     MmSystemParentTablePage = MiGetNextPhysicalPage();
    00618
    00619     RtlZeroMemory(KSEG_ADDRESS(MmSystemParentTablePage), PAGE_SIZE);
    00620
    00621     TempPte.u.Hard.PageFrameNumber = MmSystemParentTablePage;
    00622
    00623     MiSystemSelfMappedPte = TempPte;
    00624
    00625     KeFillFixedEntryTb((PHARDWARE_PTE)&TempPte, (PVOID)PDE_KTBASE, DTR_KTBASE_INDEX_TMP);
    00626
    00627     //
    00628     // Install the self-mapped Ppe entry into the kernel parent directory table
    00629     //
    00630
    00631     PointerPte = MiGetPteAddress(PDE_KTBASE);
    00632
    00633     MI_WRITE_VALID_PTE(PointerPte, TempPte);
    00634
    00635     //
    00636     // Install the kernel image Ppe entry into the parent directory table
    00637     //
    00638
    00639     PointerPte = MiGetPteAddress(PDE_KBASE);
    00640
    00641     TempPte.u.Hard.PageFrameNumber = PdePageNumber;
    00642
    00643     MI_WRITE_VALID_PTE(PointerPte, TempPte);
    00644
    00645     //
    00646     // Build a parent directory page table for the user space
    00647     //
    00648
    00649     NextPhysicalPage = MiGetNextPhysicalPage();
    00650
    00651     RtlZeroMemory (KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE);
    00652
    00653     TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    00654
    00655     INITIALIZE_DIRECTORY_TABLE_BASE
    00656       (&(PsGetCurrentProcess()->Pcb.DirectoryTableBase[0]), NextPhysicalPage);
    00657
    00658     MiUserSelfMappedPte = TempPte;
    00659
    00660     KeFillFixedEntryTb((PHARDWARE_PTE)&TempPte, (PVOID)PDE_UTBASE, DTR_UTBASE_INDEX_TMP);
    00661
    00662     //
    00663     // Install the self-mapped entry into the user parent directory table
    00664     //
    00665
    00666     PointerPte = MiGetPteAddress(PDE_UTBASE);
    00667
    00668     MI_WRITE_VALID_PTE(PointerPte, TempPte);
    00669
    00670     //
    00671     // Build a parent directory page table for the hydra space
    00672     //
    00673
    00674     NextPhysicalPage = MiGetNextPhysicalPage();
    00675
    00676     RtlZeroMemory (KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE);
    00677
    00678     TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    00679
    00680     INITIALIZE_DIRECTORY_TABLE_BASE
    00681       (&(PsGetCurrentProcess()->Pcb.SessionParentBase), NextPhysicalPage);
    00682
    00683     KeFillFixedEntryTb((PHARDWARE_PTE)&TempPte, (PVOID)PDE_STBASE, DTR_STBASE_INDEX);
    00684
    00685     //
    00686     // Install the self-mapped entry into the hydra parent directory table
    00687     //
    00688
    00689     PointerPte = MiGetPteAddress(PDE_STBASE);
    00690
    00691     MI_WRITE_VALID_PTE(PointerPte, TempPte);
    00692
    00693     //
    00694     // Build Vhpt table for KSEG3
    00695     //
    00696
    00697 #if defined(KSEG_VHPT)
    00698     va = KSEG0_ADDRESS(MmKseg3VhptBase);
    00699
    00700     RtlZeroMemory((PVOID)va, Kseg3VhptSize);
    00701
    00702     TempPte.u.Hard.PageFrameNumber = MmKseg3VhptBase;
    00703
    00704     PointerPte = MiGetKSegPteAddress(KSEG3_BASE);
    00705
    00706     KeFillFixedLargeEntryTb((PHARDWARE_PTE)&TempPte,
    00707                             (PVOID)PointerPte,
    00708                             PageSize,
    00709                             DTR_KSEG3_INDEX);
    00710
    00711     MmKseg3VhptPs = PageSize;
    00712 #endif
    00713
    00714     //
    00715     // Build non-paged pool using the physical pages following the
    00716     // data page in which to build the pool from.  Non-page pool grows
    00717     // from the high range of the virtual address space and expands
    00718     // downward.
    00719     //
    00720     // At this time non-paged pool is constructed so virtual addresses
    00721     // are also physically contiguous.
    00722     //
    00723
    00724     if ((MmSizeOfNonPagedPoolInBytes >> PAGE_SHIFT) >
    00725                         (7 * (MmNumberOfPhysicalPages << 3))) {
    00726
    00727         //
    00728         // More than 7/8 of memory allocated to nonpagedpool, reset to 0.
    00729         //
    00730
    00731         MmSizeOfNonPagedPoolInBytes = 0;
    00732     }
    00733
    00734     if (MmSizeOfNonPagedPoolInBytes < MmMinimumNonPagedPoolSize) {
    00735
    00736         //
    00737         // Calculate the size of nonpaged pool.
    00738         // Use the minimum size, then for every MB about 4mb add extra
    00739         // pages.
    00740         //
    00741
    00742         MmSizeOfNonPagedPoolInBytes = MmMinimumNonPagedPoolSize;
    00743
    00744         MmSizeOfNonPagedPoolInBytes +=
    00745             ((MmNumberOfPhysicalPages - _x16mbnp)/_x1mbnp) *
    00746             MmMinAdditionNonPagedPoolPerMb;
    00747     }
    00748
    00749     if (MmSizeOfNonPagedPoolInBytes > MM_MAX_INITIAL_NONPAGED_POOL) {
    00750         MmSizeOfNonPagedPoolInBytes = MM_MAX_INITIAL_NONPAGED_POOL;
    00751     }
    00752
    00753     //
    00754     // Align to page size boundary.
    00755     //
    00756
    00757     MmSizeOfNonPagedPoolInBytes &= ~(PAGE_SIZE - 1);
    00758
    00759     //
    00760     // Calculate the maximum size of pool.
    00761     //
    00762
    00763     if (MmMaximumNonPagedPoolInBytes == 0) {
    00764
    00765         //
    00766         // Calculate the size of nonpaged pool.  If 4mb of less use
    00767         // the minimum size, then for every MB about 4mb add extra
    00768         // pages.
    00769         //
    00770
    00771         MmMaximumNonPagedPoolInBytes = MmDefaultMaximumNonPagedPool;
    00772
    00773         //
    00774         // Make sure enough expansion for pfn database exists.
    00775         //
    00776
    00777         MmMaximumNonPagedPoolInBytes += (MmHighestPhysicalPage * sizeof(MMPFN)) & ~(PAGE_SIZE-1);
    00778
    00779         MmMaximumNonPagedPoolInBytes +=
    00780             ((MmNumberOfPhysicalPages - _x16mbnp)/_x1mbnp) *
    00781             MmMaxAdditionNonPagedPoolPerMb;
    00782
    00783     }
    00784
    00785     MaxPool = MmSizeOfNonPagedPoolInBytes + PAGE_SIZE * 16 +
    00786                 ((MmHighestPhysicalPage * sizeof(MMPFN)) & ~(PAGE_SIZE -1));
    00787
    00788     if (MmMaximumNonPagedPoolInBytes < MaxPool) {
    00789         MmMaximumNonPagedPoolInBytes = MaxPool;
    00790     }
    00791
    00792     if (MmMaximumNonPagedPoolInBytes > MM_MAX_ADDITIONAL_NONPAGED_POOL) {
    00793         MmMaximumNonPagedPoolInBytes = MM_MAX_ADDITIONAL_NONPAGED_POOL;
    00794     }
    00795
    00796     MmNonPagedPoolStart = (PVOID)((ULONG_PTR)MmNonPagedPoolEnd
    00797                                       - MmMaximumNonPagedPoolInBytes);
    00798
    00799     MmNonPagedPoolStart = (PVOID)PAGE_ALIGN(MmNonPagedPoolStart);
    00800
    00801     MmPageAlignedPoolBase[NonPagedPool] = MmNonPagedPoolStart;
    00802
    00803     //
    00804     // Calculate the starting PDE for the system PTE pool which is
    00805     // right below the nonpaged pool.
    00806     //
    00807
    00808     MmNonPagedSystemStart = (PVOID)(((ULONG_PTR)MmNonPagedPoolStart -
    00809                                 ((MmNumberOfSystemPtes + 1) * PAGE_SIZE)) &
    00810                                  (~PAGE_DIRECTORY2_MASK));
    00811
    00812     if (MmNonPagedSystemStart < MM_LOWEST_NONPAGED_SYSTEM_START) {
    00813         MmNonPagedSystemStart = MM_LOWEST_NONPAGED_SYSTEM_START;
    00814         MmNumberOfSystemPtes = (ULONG)(((ULONG_PTR)MmNonPagedPoolStart -
    00815                                 (ULONG_PTR)MmNonPagedSystemStart) >> PAGE_SHIFT)-1;
    00816         ASSERT (MmNumberOfSystemPtes > 1000);
    00817     }
    00818
    00819
    00820     //
    00821     // Allocate a page directory and a pair of page table pages.
    00822     // Map the hyper space page directory page into the top level parent
    00823     // directory & the hyper space page table page into the page directory
    00824     // and map an additional page that will eventually be used for the
    00825     // working set list.  Page tables after the first two are set up later
    00826     // on during individual process working set initialization.
    00827     //
    00828     // The working set list page will eventually be a part of hyper space.
    00829     // It is mapped into the second level page directory page so it can be
    00830     // zeroed and so it will be accounted for in the PFN database. Later
    00831     // the page will be unmapped, and its page frame number captured in the
    00832     // system process object.
    00833     //
    00834
    00835     TempPte = ValidPdePde;
    00836     StartPde = MiGetPdeAddress(HYPER_SPACE);
    00837     StartPpe = MiGetPpeAddress(HYPER_SPACE);
    00838     EndPde = StartPde;
    00839     First = (StartPpe->u.Hard.Valid == 0) ? TRUE : FALSE;
    00840
    00841     while (StartPde <= EndPde) {
    00842
    00843         if (First == TRUE || MiIsPteOnPdeBoundary(StartPde)) {
    00844             First = FALSE;
    00845             StartPpe = MiGetPteAddress(StartPde);
    00846             if (StartPpe->u.Hard.Valid == 0) {
    00847                 ASSERT (StartPpe->u.Long == 0);
    00848                 NextPhysicalPage = MiGetNextPhysicalPage();
    00849                 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE);
    00850                 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    00851                 MI_WRITE_VALID_PTE(StartPpe, TempPte);
    00852             }
    00853         }
    00854         NextPhysicalPage = MiGetNextPhysicalPage();
    00855         RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE);
    00856         TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    00857         MI_WRITE_VALID_PTE(StartPde, TempPte);
    00858         StartPde += 1;
    00859     }
    00860
    00861     //
    00862     // Allocate page directory and page table pages for
    00863     // system PTEs and nonpaged pool.
    00864     //
    00865
    00866     TempPte = ValidKernelPte;
    00867     StartPde = MiGetPdeAddress(MmNonPagedSystemStart);
    00868     StartPpe = MiGetPpeAddress(MmNonPagedSystemStart);
    00869     EndPde = MiGetPdeAddress((ULONG_PTR)MmNonPagedPoolEnd - 1);
    00870     First = (StartPpe->u.Hard.Valid == 0) ? TRUE : FALSE;
    00871
    00872     while (StartPde <= EndPde) {
    00873
    00874         if (First == TRUE || MiIsPteOnPdeBoundary(StartPde)) {
    00875             First = FALSE;
    00876             StartPpe = MiGetPteAddress(StartPde);
    00877             if (StartPpe->u.Hard.Valid == 0) {
    00878                 NextPhysicalPage = MiGetNextPhysicalPage();
    00879                 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE);
    00880                 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    00881                 MI_WRITE_VALID_PTE(StartPpe, TempPte);
    00882             }
    00883         }
    00884
    00885         if (StartPde->u.Hard.Valid == 0) {
    00886             NextPhysicalPage = MiGetNextPhysicalPage();
    00887             RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE);
    00888             TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    00889             MI_WRITE_VALID_PTE(StartPde, TempPte);
    00890         }
    00891         StartPde += 1;
    00892     }
    00893
    00894     NonPagedPoolStartVirtual = MmNonPagedPoolStart;
    00895
    00896 //    MiBuildPageTableForDrivers(LoaderBlock);
    00897
    00898
    00899     MiBuildPageTableForLoaderMemory(LoaderBlock);
    00900
    00901     MiRemoveLoaderSuperPages(LoaderBlock);
    00902
    00903     //
    00904     // remove the temporary super pages for the root page table pages,
    00905     // and remap again with DTR_KTBASE_INDEX and DTR_UTBASE_INDEX.
    00906     //
    00907
    00908     KiFlushFixedDataTb(FALSE, (PVOID)PDE_KTBASE);
    00909     KiFlushFixedDataTb(FALSE, (PVOID)PDE_UTBASE);
    00910     KeFillFixedEntryTb((PHARDWARE_PTE)&MiSystemSelfMappedPte, (PVOID)PDE_KTBASE, DTR_KTBASE_INDEX);
    00911     KeFillFixedEntryTb((PHARDWARE_PTE)&MiUserSelfMappedPte, (PVOID)PDE_UTBASE, DTR_UTBASE_INDEX);
    00912
    00913     if (MiKseg0Mapping == TRUE) {
    00914
    00915         //
    00916         // Fill the PDEs for KSEG0 space
    00917         //
    00918
    00919         StartPde = MiGetPdeAddress(MiKseg0Start);
    00920         EndPde = MiGetPdeAddress((PCHAR)KSEG0_BASE + Kseg0Size);
    00921
    00922         while (StartPde <= EndPde) {
    00923
    00924             if (StartPde->u.Hard.Valid == 0) {
    00925                 NextPhysicalPage = MiGetNextPhysicalPage();
    00926                 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE);
    00927                 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    00928                 MI_WRITE_VALID_PTE(StartPde, TempPte);
    00929             }
    00930             StartPde++;
    00931         }
    00932     }
    00933
    00934     //
    00935     // Initial NonPagedPool allocation priorities
    00936     //
    00937     // 1. allocate pages from 16mb kernel image maping space and use the 16mb super page
    00938     //    addresses
    00939     // 2. allocate pages from low memory space ( < 256mb) and use the KSEG0 addresses
    00940     // 3. allocate pages from the largest free memory descriptor list and use
    00941     //    MM_NON_PAGED_POOL addresses.
    00942     //
    00943
    00944     if (MiKseg0Mapping == TRUE) {
    00945
    00946         //
    00947         // When KiKseg0Mapping is enabled, check to see if
    00948         //
    00949
    00950         MiKseg0Mapping =
    00951             MiEnsureAvailablePagesInFreeDescriptor(BYTES_TO_PAGES(MmSizeOfNonPagedPoolInBytes),
    00952                                                    MM_PAGES_IN_KSEG0);
    00953
    00954     }
    00955
    00956     //
    00957     // Fill in the PTEs to cover the initial nonpaged pool. The physical
    00958     // page frames to cover this range were reserved earlier from the
    00959     // largest low memory free descriptor. The initial allocation is both
    00960     // physically and virtually contiguous.
    00961     //
    00962
    00963     PointerPte = MiGetPteAddress(MmNonPagedPoolStart);
    00964     LastPte = MiGetPteAddress((PCHAR)MmNonPagedPoolStart +
    00965                                                 MmSizeOfNonPagedPoolInBytes - 1);
    00966
    00967     while (PointerPte <= LastPte) {
    00968         NextPhysicalPage = MiGetNextPhysicalPage();
    00969         TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    00970         MI_WRITE_VALID_PTE(PointerPte, TempPte);
    00971         PointerPte++;
    00972     }
    00973
    00974     //
    00975     // Zero the remaining PTEs (if any) for the initial nonpaged pool up to
    00976     // the end of the current page table page.
    00977     //
    00978
    00979     while (!MiIsPteOnPdeBoundary (PointerPte)) {
    00980         MI_WRITE_INVALID_PTE(PointerPte, ZeroKernelPte);
    00981         PointerPte += 1;
    00982     }
    00983
    00984     //
    00985     // Convert the starting nonpaged pool address to KSEG0 space
    00986     // address and set the address of the initial nonpaged pool allocation.
    00987     //
    00988
    00989     if (MiKseg0Mapping == TRUE) {
    00990
    00991
    00992         //
    00993         // No need to get page table pages for these as we can reference
    00994         // them via large pages.
    00995         //
    00996
    00997         PointerPte = MiGetPteAddress (MmNonPagedPoolStart);
    00998         MmNonPagedPoolStart = KSEG0_ADDRESS(PointerPte->u.Hard.PageFrameNumber);
    00999         MmSubsectionBase = KSEG0_BASE;
    01000
    01001         StartPte = MiGetPteAddress(MmNonPagedPoolStart);
    01002         LastPte = MiGetPteAddress((PCHAR)MmNonPagedPoolStart +
    01003                                   MmSizeOfNonPagedPoolInBytes - 1);
    01004
    01005         MiKseg0Start = MiGetVirtualAddressMappedByPte(StartPte);
    01006
    01007         while (StartPte <= LastPte) {
    01008
    01009             //
    01010             // duplicating PTEs to map non initial non paged pool
    01011             // in the KSEG0 space.
    01012             //
    01013
    01014             MI_WRITE_VALID_PTE(StartPte, *PointerPte);
    01015             StartPte++;
    01016             PointerPte++;
    01017         }
    01018
    01019         MiKseg0End = MiGetVirtualAddressMappedByPte(LastPte);
    01020
    01021     } else {
    01022
    01023         MiKseg0Mapping = FALSE;
    01024         MmSubsectionBase = 0;
    01025
    01026     }
    01027
    01028     //
    01029     // As only the initial non paged pool is mapped through superpages,
    01030     // MmSubsectionToPage is always set to zero.
    01031     //
    01032
    01033     MmSubsectionTopPage = 0;
    01034
    01035
    01036     MmNonPagedPoolExpansionStart = (PVOID)((PCHAR)NonPagedPoolStartVirtual +
    01037                                            MmSizeOfNonPagedPoolInBytes);
    01038
    01039     MmPageAlignedPoolBase[NonPagedPool] = MmNonPagedPoolStart;
    01040
    01041
    01042     //
    01043     // Non-paged pages now exist, build the pool structures.
    01044     //
    01045
    01046     MiInitializeNonPagedPool ();
    01047
    01048     //
    01049     // Before Non-paged pool can be used, the PFN database must
    01050     // be built.  This is due to the fact that the start and end of
    01051     // allocation bits for nonpaged pool are maintained in the
    01052     // PFN elements for the corresponding pages.
    01053     //
    01054
    01055     //
    01056     // Calculate the number of pages required from page zero to
    01057     // the highest page.
    01058     //
    01059     // Get secondary color value from registry.
    01060     //
    01061
    01062     MmSecondaryColors = MmSecondaryColors >> PAGE_SHIFT;
    01063
    01064     if (MmSecondaryColors == 0) {
    01065         MmSecondaryColors = MM_SECONDARY_COLORS_DEFAULT;
    01066     } else {
    01067
    01068         //
    01069         // Make sure value is power of two and within limits.
    01070         //
    01071
    01072         if (((MmSecondaryColors & (MmSecondaryColors -1)) != 0) ||
    01073             (MmSecondaryColors < MM_SECONDARY_COLORS_MIN) ||
    01074             (MmSecondaryColors > MM_SECONDARY_COLORS_MAX)) {
    01075             MmSecondaryColors = MM_SECONDARY_COLORS_DEFAULT;
    01076         }
    01077     }
    01078
    01079     MmSecondaryColorMask = MmSecondaryColors - 1;
    01080
    01081     //
    01082     // Get the number of secondary colors and add the arrary for tracking
    01083     // secondary colors to the end of the PFN database.
    01084     //
    01085
    01086
    01087     PfnAllocation = 1 + ((((MmHighestPhysicalPage + 1) * sizeof(MMPFN)) +
    01088                         (MmSecondaryColors * sizeof(MMCOLOR_TABLES)*2))
    01089                             >> PAGE_SHIFT);
    01090
    01091
    01092     if ((MmHighestPhysicalPage < _x4gbnp) &&
    01093         (MiKseg0Mapping == TRUE) &&
    01094         (MiEnsureAvailablePagesInFreeDescriptor(PfnAllocation,
    01095                                                 MM_PAGES_IN_KSEG0))) {
    01096         //
    01097         // Allocate the PFN database in the superpage space
    01098         //
    01099         // Compute the address of the PFN by allocating the appropriate
    01100         // number of pages from the end of the free descriptor.
    01101         //
    01102
    01103         MmPfnDatabase = (PMMPFN)KSEG0_ADDRESS(MiNextPhysicalPage);
    01104
    01105         StartPte = MiGetPteAddress(MmPfnDatabase);
    01106         LastPte = MiGetPteAddress((PCHAR)MmPfnDatabase + (PfnAllocation << PAGE_SHIFT) - 1);
    01107
    01108         while (StartPte <= LastPte) {
    01109             TempPte.u.Hard.PageFrameNumber = MiGetNextPhysicalPage();
    01110             MI_WRITE_VALID_PTE(StartPte, TempPte);
    01111             StartPte++;
    01112         }
    01113
    01114         RtlZeroMemory(MmPfnDatabase, PfnAllocation * PAGE_SIZE);
    01115         MiKseg0End = MiGetVirtualAddressMappedByPte(LastPte);
    01116
    01117     } else {
    01118
    01119         //
    01120         // Calculate the start of the Pfn Database (it starts a physical
    01121         // page zero, even if the Lowest physical page is not zero).
    01122         //
    01123
    01124         MmPfnDatabase = (PMMPFN)MM_PFN_DATABASE_START;
    01125
    01126         //
    01127         // Go through the memory descriptors and for each physical page
    01128         // make the PFN database has a valid PTE to map it.  This allows
    01129         // machines with sparse physical memory to have a minimal PFN
    01130         // database.
    01131         //
    01132
    01133         NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
    01134
    01135         while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
    01136
    01137             MemoryDescriptor = CONTAINING_RECORD(NextMd,
    01138                                                  MEMORY_ALLOCATION_DESCRIPTOR,
    01139                                                  ListEntry);
    01140
    01141             PointerPte = MiGetPteAddress (MI_PFN_ELEMENT(
    01142                                             MemoryDescriptor->BasePage));
    01143
    01144             LastPte = MiGetPteAddress (((PCHAR)(MI_PFN_ELEMENT(
    01145                                         MemoryDescriptor->BasePage +
    01146                                         MemoryDescriptor->PageCount))) - 1);
    01147
    01148             First = TRUE;
    01149
    01150             while (PointerPte <= LastPte) {
    01151
    01152                 if (First == TRUE || MiIsPteOnPpeBoundary(PointerPte)) {
    01153                     StartPpe = MiGetPdeAddress(PointerPte);
    01154                     if (StartPpe->u.Hard.Valid == 0) {
    01155                         ASSERT (StartPpe->u.Long == 0);
    01156                         NextPhysicalPage = MiGetNextPhysicalPage();
    01157                         RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE);
    01158                         TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    01159                         MI_WRITE_VALID_PTE(StartPpe, TempPte);
    01160                     }
    01161                 }
    01162
    01163                 if ((First == TRUE) || MiIsPteOnPdeBoundary(PointerPte)) {
    01164                     First = FALSE;
    01165                     StartPde = MiGetPteAddress(PointerPte);
    01166                     if (StartPde->u.Hard.Valid == 0) {
    01167                         NextPhysicalPage = MiGetNextPhysicalPage();
    01168                         RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE);
    01169                         TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    01170                         MI_WRITE_VALID_PTE(StartPde, TempPte);
    01171                     }
    01172                 }
    01173
    01174                 if (PointerPte->u.Hard.Valid == 0) {
    01175                     NextPhysicalPage = MiGetNextPhysicalPage();
    01176                     RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE);
    01177                     TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    01178                     MI_WRITE_VALID_PTE(PointerPte, TempPte);
    01179                 }
    01180
    01181                 PointerPte++;
    01182             }
    01183             NextMd = MemoryDescriptor->ListEntry.Flink;
    01184         }
    01185     }
    01186
    01187     if (MiKseg0Mapping == TRUE) {
    01188
    01189         //
    01190         // Try to convert to superpages
    01191         //
    01192
    01193         MiConvertToSuperPages(MiKseg0Start,
    01194                               MiKseg0End,
    01195                               _x1mb,
    01196                               MM_PTE_1MB_PAGE);
    01197
    01198         MiConvertToSuperPages(MiKseg0Start,
    01199                               MiKseg0End,
    01200                               _x4mb,
    01201                               MM_PTE_4MB_PAGE);
    01202
    01203         MiConvertToSuperPages(MiKseg0Start,
    01204                               MiKseg0End,
    01205                               _x16mb,
    01206                               MM_PTE_16MB_PAGE);
    01207
    01208         MiConvertToSuperPages(MiKseg0Start,
    01209                               MiKseg0End,
    01210                               _x64mb,
    01211                               MM_PTE_64MB_PAGE);
    01212
    01213         MiConvertToSuperPages(MiKseg0Start,
    01214                               MiKseg0End,
    01215                               _x256mb,
    01216                               MM_PTE_256MB_PAGE);
    01217
    01218     }
    01219
    01220
    01221     //
    01222     // Initialize support for colored pages.
    01223     //
    01224
    01225     MmFreePagesByColor[0] = (PMMCOLOR_TABLES)
    01226                                 &MmPfnDatabase[MmHighestPhysicalPage + 1];
    01227
    01228     MmFreePagesByColor[1] = &MmFreePagesByColor[0][MmSecondaryColors];
    01229
    01230     //
    01231     // Make sure the PTEs are mapped.
    01232     //
    01233
    01234     if (!MI_IS_PHYSICAL_ADDRESS(MmFreePagesByColor[0])) {
    01235         PointerPte = MiGetPteAddress (&MmFreePagesByColor[0][0]);
    01236
    01237         LastPte = MiGetPteAddress (
    01238               (PVOID)((PCHAR)&MmFreePagesByColor[1][MmSecondaryColors] - 1));
    01239
    01240         while (PointerPte <= LastPte) {
    01241             if (PointerPte->u.Hard.Valid == 0) {
    01242                 NextPhysicalPage = MiGetNextPhysicalPage();
    01243                 RtlZeroMemory(KSEG_ADDRESS(NextPhysicalPage), PAGE_SIZE);
    01244                 TempPte.u.Hard.PageFrameNumber = NextPhysicalPage;
    01245                 MI_WRITE_VALID_PTE(PointerPte, TempPte);
    01246             }
    01247             PointerPte++;
    01248         }
    01249     }
    01250
    01251     for (i = 0; i < MmSecondaryColors; i++) {
    01252         MmFreePagesByColor[ZeroedPageList][i].Flink = MM_EMPTY_LIST;
    01253         MmFreePagesByColor[FreePageList][i].Flink = MM_EMPTY_LIST;
    01254     }
    01255
    01256 #if MM_MAXIMUM_NUMBER_OF_COLORS > 1
    01257     for (i = 0; i < MM_MAXIMUM_NUMBER_OF_COLORS; i++) {
    01258         MmFreePagesByPrimaryColor[ZeroedPageList][i].ListName = ZeroedPageList;
    01259         MmFreePagesByPrimaryColor[FreePageList][i].ListName = FreePageList;
    01260         MmFreePagesByPrimaryColor[ZeroedPageList][i].Flink = MM_EMPTY_LIST;
    01261         MmFreePagesByPrimaryColor[FreePageList][i].Flink = MM_EMPTY_LIST;
    01262         MmFreePagesByPrimaryColor[ZeroedPageList][i].Blink = MM_EMPTY_LIST;
    01263         MmFreePagesByPrimaryColor[FreePageList][i].Blink = MM_EMPTY_LIST;
    01264     }
    01265 #endif
    01266
    01267     //
    01268     // Go through the page table entries and for any page which is
    01269     // valid, update the corresponding PFN database element.
    01270     //
    01271
    01272     StartPde = MiGetPdeAddress (HYPER_SPACE);
    01273     StartPpe = MiGetPpeAddress (HYPER_SPACE);
    01274     EndPde = MiGetPdeAddress(HYPER_SPACE_END);
    01275     First = (StartPpe->u.Hard.Valid == 0) ? TRUE : FALSE;
    01276
    01277     while (StartPde <= EndPde) {
    01278
    01279         if (First == TRUE || MiIsPteOnPdeBoundary(StartPde)) {
    01280             First = FALSE;
    01281             StartPpe = MiGetPteAddress(StartPde);
    01282             if (StartPpe->u.Hard.Valid == 0) {
    01283                 StartPpe += 1;
    01284                 StartPde = MiGetVirtualAddressMappedByPte (StartPpe);
    01285                 continue;
    01286             }
    01287
    01288             PdePage = MI_GET_PAGE_FRAME_FROM_PTE(StartPpe);
    01289
    01290             Pfn1 = MI_PFN_ELEMENT(PdePage);
    01291             Pfn1->PteFrame = MmSystemParentTablePage;
    01292             Pfn1->PteAddress = StartPde;
    01293             Pfn1->u2.ShareCount += 1;
    01294             Pfn1->u3.e2.ReferenceCount = 1;
    01295             Pfn1->u3.e1.PageLocation = ActiveAndValid;
    01296             Pfn1->u3.e1.PageColor =
    01297                 MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE(StartPpe));
    01298         }
    01299
    01300
    01301         if (StartPde->u.Hard.Valid == 1) {
    01302             PdePage = MI_GET_PAGE_FRAME_FROM_PTE(StartPde);
    01303             Pfn1 = MI_PFN_ELEMENT(PdePage);
    01304             PointerPde = MiGetPteAddress(StartPde);
    01305             Pfn1->PteFrame = MI_GET_PAGE_FRAME_FROM_PTE(PointerPde);
    01306             Pfn1->PteAddress = StartPde;
    01307             Pfn1->u2.ShareCount += 1;
    01308             Pfn1->u3.e2.ReferenceCount = 1;
    01309             Pfn1->u3.e1.PageLocation = ActiveAndValid;
    01310             Pfn1->u3.e1.PageColor =
    01311                 MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE (StartPde));
    01312
    01313             PointerPte = MiGetVirtualAddressMappedByPte(StartPde);
    01314             for (j = 0 ; j < PTE_PER_PAGE; j++) {
    01315                 if (PointerPte->u.Hard.Valid == 1) {
    01316
    01317                     Pfn1->u2.ShareCount += 1;
    01318
    01319                     if (PointerPte->u.Hard.PageFrameNumber <=
    01320                                             MmHighestPhysicalPage) {
    01321                         Pfn2 = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
    01322                         Pfn2->PteFrame = PdePage;
    01323                         Pfn2->PteAddress = PointerPte;
    01324                         Pfn2->u2.ShareCount += 1;
    01325                         Pfn2->u3.e2.ReferenceCount = 1;
    01326                         Pfn2->u3.e1.PageLocation = ActiveAndValid;
    01327                         Pfn2->u3.e1.PageColor =
    01328                             MI_GET_COLOR_FROM_SECONDARY(
    01329                                                   MI_GET_PAGE_COLOR_FROM_PTE (
    01330                                                         PointerPte));
    01331                     }
    01332                 }
    01333                 PointerPte += 1;
    01334             }
    01335         }
    01336
    01337         StartPde++;
    01338     }
    01339
    01340     //
    01341     // do it for the kernel space
    01342     //
    01343
    01344     StartPde = MiGetPdeAddress (KADDRESS_BASE);
    01345     StartPpe = MiGetPpeAddress (KADDRESS_BASE);
    01346     EndPde = MiGetPdeAddress(MM_SYSTEM_SPACE_END);
    01347     First = (StartPpe->u.Hard.Valid == 0) ? TRUE : FALSE;
    01348
    01349     while (StartPde <= EndPde) {
    01350
    01351         if (First == TRUE || MiIsPteOnPdeBoundary(StartPde)) {
    01352             First = FALSE;
    01353             StartPpe = MiGetPteAddress(StartPde);
    01354             if (StartPpe->u.Hard.Valid == 0) {
    01355                 StartPpe += 1;
    01356                 StartPde = MiGetVirtualAddressMappedByPte (StartPpe);
    01357                 continue;
    01358             }
    01359
    01360             PdePage = MI_GET_PAGE_FRAME_FROM_PTE(StartPpe);
    01361
    01362             Pfn1 = MI_PFN_ELEMENT(PdePage);
    01363             Pfn1->PteFrame = MmSystemParentTablePage;
    01364             Pfn1->PteAddress = StartPde;
    01365             Pfn1->u2.ShareCount += 1;
    01366             Pfn1->u3.e2.ReferenceCount = 1;
    01367             Pfn1->u3.e1.PageLocation = ActiveAndValid;
    01368             Pfn1->u3.e1.PageColor =
    01369                 MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE(StartPpe));
    01370         }
    01371
    01372         if (StartPde->u.Hard.Valid == 1) {
    01373             PdePage = MI_GET_PAGE_FRAME_FROM_PTE(StartPde);
    01374             Pfn1 = MI_PFN_ELEMENT(PdePage);
    01375             PointerPde = MiGetPteAddress(StartPde);
    01376             Pfn1->PteFrame = MI_GET_PAGE_FRAME_FROM_PTE(PointerPde);
    01377             Pfn1->PteAddress = StartPde;
    01378             Pfn1->u2.ShareCount += 1;
    01379             Pfn1->u3.e2.ReferenceCount = 1;
    01380             Pfn1->u3.e1.PageLocation = ActiveAndValid;
    01381             Pfn1->u3.e1.PageColor =
    01382                 MI_GET_COLOR_FROM_SECONDARY(GET_PAGE_COLOR_FROM_PTE (StartPde));
    01383
    01384             PointerPte = MiGetVirtualAddressMappedByPte(StartPde);
    01385             for (j = 0 ; j < PTE_PER_PAGE; j++) {
    01386                 if (PointerPte->u.Hard.Valid == 1) {
    01387
    01388                     Pfn1->u2.ShareCount += 1;
    01389
    01390                     if (PointerPte->u.Hard.PageFrameNumber <=
    01391                                             MmHighestPhysicalPage) {
    01392                         Pfn2 = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
    01393                         Pfn2->PteFrame = PdePage;
    01394                         Pfn2->PteAddress = PointerPte;
    01395                         Pfn2->u2.ShareCount += 1;
    01396                         Pfn2->u3.e2.ReferenceCount = 1;
    01397                         Pfn2->u3.e1.PageLocation = ActiveAndValid;
    01398                         Pfn2->u3.e1.PageColor =
    01399                             MI_GET_COLOR_FROM_SECONDARY(
    01400                                                   MI_GET_PAGE_COLOR_FROM_PTE (
    01401                                                         PointerPte));
    01402                     }
    01403                 }
    01404                 PointerPte += 1;
    01405             }
    01406         }
    01407
    01408         StartPde++;
    01409     }
    01410
    01411     //
    01412     // If page zero is still unused, mark it as in use. This is
    01413     // temporary as we want to find bugs where a physical page
    01414     // is specified as zero.
    01415     //
    01416
    01417     Pfn1 = &MmPfnDatabase[MmLowestPhysicalPage];
    01418     if (Pfn1->u3.e2.ReferenceCount == 0) {
    01419
    01420         //
    01421         // Make the reference count non-zero and point it into a
    01422         // page directory.
    01423         //
    01424
    01425         Pde = MiGetPdeAddress (KADDRESS_BASE + 0xb0000000);
    01426         PdePage = MI_GET_PAGE_FRAME_FROM_PTE(Pde);
    01427         Pfn1->PteFrame = PdePageNumber;
    01428         Pfn1->PteAddress = Pde;
    01429         Pfn1->u2.ShareCount += 1;
    01430         Pfn1->u3.e2.ReferenceCount = 1;
    01431         Pfn1->u3.e1.PageLocation = ActiveAndValid;
    01432         Pfn1->u3.e1.PageColor = MI_GET_COLOR_FROM_SECONDARY(
    01433                                             MI_GET_PAGE_COLOR_FROM_PTE (Pde));
    01434     }
    01435
    01436     // end of temporary set to physical page zero.
    01437
    01438     //
    01439     //
    01440     // Walk through the memory descriptors and add pages to the
    01441     // free list in the PFN database.
    01442     //
    01443
    01444     MiFreeDescriptor->PageCount -=
    01445         (PFN_COUNT)(MiNextPhysicalPage - MiOldFreeDescriptorBase);
    01446
    01447     //
    01448     // Until BasePage (arc.h) is changed to PFN_NUMBER, NextPhysicalPage
    01449     // needs (ULONG) cast.
    01450     //
    01451
    01452     MiFreeDescriptor->BasePage = (ULONG)MiNextPhysicalPage;
    01453
    01454     //
    01455     // making unused pages inside the kernel super page mapping unusable
    01456     // so that no one is going to reclaim it for uncached pages.
    01457     //
    01458
    01459     if (MiFreeDescriptorNonPaged != NULL) {
    01460
    01461         if (MiFreeDescriptorNonPaged->BasePage > KernelEnd) {
    01462
    01463             MiWasteStart = KernelEnd;
    01464             MiWasteEnd = KernelEnd;
    01465
    01466
    01467         } else if ((MiFreeDescriptorNonPaged->BasePage +
    01468                     MiFreeDescriptorNonPaged->PageCount) > KernelEnd) {
    01469
    01470             MiWasteStart = MiFreeDescriptorNonPaged->BasePage;
    01471             MiWasteEnd = KernelEnd;
    01472
    01473             MiFreeDescriptorNonPaged->PageCount -=
    01474                 (PFN_COUNT) (KernelEnd - MiFreeDescriptorNonPaged->BasePage);
    01475
    01476             MiFreeDescriptorNonPaged->BasePage = (ULONG) KernelEnd;
    01477
    01478         } else if (MiFreeDescriptorNonPaged->PageCount != 0) {
    01479
    01480             MiWasteStart = MiFreeDescriptorNonPaged->BasePage;
    01481             MiWasteEnd = MiWasteStart + MiFreeDescriptorNonPaged->PageCount;
    01482             MiFreeDescriptorNonPaged->PageCount = 0;
    01483
    01484         }
    01485     }
    01486
    01487     NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
    01488
    01489     while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
    01490
    01491         MemoryDescriptor = CONTAINING_RECORD(NextMd,
    01492                                              MEMORY_ALLOCATION_DESCRIPTOR,
    01493                                              ListEntry);
    01494
    01495         i = MemoryDescriptor->PageCount;
    01496         NextPhysicalPage = MemoryDescriptor->BasePage;
    01497
    01498         switch (MemoryDescriptor->MemoryType) {
    01499             case LoaderBad:
    01500                 while (i != 0) {
    01501                     MiInsertPageInList (MmPageLocationList[BadPageList],
    01502                                         NextPhysicalPage);
    01503                     i -= 1;
    01504                     NextPhysicalPage += 1;
    01505                 }
    01506                 break;
    01507
    01508             case LoaderFree:
    01509             case LoaderLoadedProgram:
    01510             case LoaderFirmwareTemporary:
    01511             case LoaderOsloaderStack:
    01512
    01513                 Pfn1 = MI_PFN_ELEMENT (NextPhysicalPage);
    01514                 while (i != 0) {
    01515                     if (Pfn1->u3.e2.ReferenceCount == 0) {
    01516
    01517                         //
    01518                         // Set the PTE address to the physical page for
    01519                         // virtual address alignment checking.
    01520                         //
    01521
    01522                         Pfn1->PteAddress = KSEG_ADDRESS (NextPhysicalPage);
    01523                         MiInsertPageInList (MmPageLocationList[FreePageList],
    01524                                             NextPhysicalPage);
    01525                     }
    01526                     Pfn1++;
    01527                     i -= 1;
    01528                     NextPhysicalPage += 1;
    01529                 }
    01530                 break;
    01531
    01532             default:
    01533
    01534                 PointerPte = KSEG_ADDRESS(NextPhysicalPage);
    01535                 Pfn1 = MI_PFN_ELEMENT (NextPhysicalPage);
    01536                 while (i != 0) {
    01537
    01538                     //
    01539                     // Set page as in use.
    01540                     //
    01541
    01542                     if (Pfn1->u3.e2.ReferenceCount == 0) {
    01543                         Pfn1->PteFrame = PdePageNumber;
    01544                         Pfn1->PteAddress = PointerPte;
    01545                         Pfn1->u2.ShareCount += 1;
    01546                         Pfn1->u3.e2.ReferenceCount = 1;
    01547                         Pfn1->u3.e1.PageLocation = ActiveAndValid;
    01548                         Pfn1->u3.e1.PageColor = MI_GET_COLOR_FROM_SECONDARY(
    01549                                         MI_GET_PAGE_COLOR_FROM_PTE (
    01550                                                         PointerPte));
    01551                     }
    01552                     Pfn1++;
    01553                     i -= 1;
    01554                     NextPhysicalPage += 1;
    01555                     PointerPte += 1;
    01556                 }
    01557                 break;
    01558         }
    01559
    01560         NextMd = MemoryDescriptor->ListEntry.Flink;
    01561     }
    01562
    01563     if (MI_IS_PHYSICAL_ADDRESS(MmPfnDatabase) == FALSE) {
    01564
    01565         //
    01566         // Indicate that the PFN database is allocated in NonPaged pool.
    01567         //
    01568
    01569         PointerPte = MiGetPteAddress (&MmPfnDatabase[MmLowestPhysicalPage]);
    01570         Pfn1 = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
    01571         Pfn1->u3.e1.StartOfAllocation = 1;
    01572
    01573         //
    01574         // Set the end of the allocation.
    01575         //
    01576
    01577         PointerPte = MiGetPteAddress (&MmPfnDatabase[MmHighestPhysicalPage]);
    01578         Pfn1 = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
    01579         Pfn1->u3.e1.EndOfAllocation = 1;
    01580
    01581     } else {
    01582         //
    01583         // The PFN database is allocated in the superpage space
    01584         //
    01585         // Mark all pfn entries for the pfn pages in use.
    01586         //
    01587
    01588         PageFrameIndex = MI_CONVERT_PHYSICAL_TO_PFN (MmPfnDatabase);
    01589         Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
    01590         do {
    01591             Pfn1->PteAddress = KSEG_ADDRESS(PageFrameIndex);
    01592             Pfn1->u3.e1.PageColor = 0;
    01593             Pfn1->u3.e2.ReferenceCount += 1;
    01594             Pfn1->u3.e1.PageLocation = ActiveAndValid;
    01595             PageFrameIndex += 1;
    01596             Pfn1 += 1;
    01597             PfnAllocation -= 1;
    01598         } while (PfnAllocation != 0);
    01599
    01600         //
    01601         // To avoid creating WB/UC/WC aliasing problem, we should not scan
    01602         // and add free pages to the free list.
    01603         //
    01604 #if 0
    01605         // Scan the PFN database backward for pages that are completely zero.
    01606         // These pages are unused and can be added to the free list
    01607         //
    01608
    01609         BottomPfn = MI_PFN_ELEMENT(MmHighestPhysicalPage);
    01610         do {
    01611
    01612             //
    01613             // Compute the address of the start of the page that is next
    01614             // lower in memory and scan backwards until that page address
    01615             // is reached or just crossed.
    01616             //
    01617
    01618             if (((ULONG_PTR)BottomPfn & (PAGE_SIZE - 1)) != 0) {
    01619                 BasePfn = (PMMPFN)((ULONG_PTR)BottomPfn & ~(PAGE_SIZE - 1));
    01620                 TopPfn = BottomPfn + 1;
    01621
    01622             } else {
    01623                 BasePfn = (PMMPFN)((ULONG_PTR)BottomPfn - PAGE_SIZE);
    01624                 TopPfn = BottomPfn;
    01625             }
    01626
    01627             while (BottomPfn > BasePfn) {
    01628                 BottomPfn -= 1;
    01629             }
    01630
    01631             //
    01632             // If the entire range over which the PFN entries span is
    01633             // completely zero and the PFN entry that maps the page is
    01634             // not in the range, then add the page to the appropriate
    01635             // free list.
    01636             //
    01637
    01638             Range = (ULONG_PTR)TopPfn - (ULONG_PTR)BottomPfn;
    01639             if (RtlCompareMemoryUlong((PVOID)BottomPfn, Range, 0) == Range) {
    01640
    01641                 //
    01642                 // Set the PTE address to the physical page for virtual
    01643                 // address alignment checking.
    01644                 //
    01645
    01646                 PageFrameIndex = MI_CONVERT_PHYSICAL_TO_PFN (BasePfn);
    01647                 Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
    01648
    01649                 ASSERT (Pfn1->u3.e2.ReferenceCount == 1);
    01650                 ASSERT (Pfn1->PteAddress == KSEG_ADDRESS(PageFrameIndex));
    01651                 Pfn1->u3.e2.ReferenceCount = 0;
    01652                 PfnAllocation += 1;
    01653                 Pfn1->PteAddress = (PMMPTE)((ULONG_PTR)PageFrameIndex << PTE_SHIFT);
    01654                 Pfn1->u3.e1.PageColor = 0;
    01655                 MiInsertPageInList(MmPageLocationList[FreePageList],
    01656                                    PageFrameIndex);
    01657             }
    01658
    01659         } while (BottomPfn > MmPfnDatabase);
    01660 #endif
    01661
    01662     }
    01663
    01664
    01665     //
    01666     // Indicate that nonpaged pool must succeed is allocated in
    01667     // nonpaged pool.
    01668     //
    01669
    01670     if (MI_IS_PHYSICAL_ADDRESS(MmNonPagedMustSucceed)) {
    01671         Pfn1 = MI_PFN_ELEMENT(MI_CONVERT_PHYSICAL_TO_PFN (MmNonPagedMustSucceed));
    01672     } else {
    01673         PointerPte = MiGetPteAddress(MmNonPagedMustSucceed);
    01674         Pfn1 = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
    01675     }
    01676
    01677     i = MmSizeOfNonPagedMustSucceed;
    01678     while ((LONG)i > 0) {
    01679         Pfn1->u3.e1.StartOfAllocation = 1;
    01680         Pfn1->u3.e1.EndOfAllocation = 1;
    01681         i -= PAGE_SIZE;
    01682         Pfn1 += 1;
    01683     }
    01684
    01685 #if 0
    01686     //
    01687     // Adjust the memory descriptors to indicate that free pool has
    01688     // been used for nonpaged pool creation.
    01689     //
    01690
    01691     MiFreeDescriptor->PageCount = (ULONG)MiOldFreeDescriptorCount;
    01692
    01693     //
    01694     // Until PagePage is defined to PFN_NUMBER, we need (ULONG) cast to
    01695     // remove warning.
    01696     //
    01697
    01698     MiFreeDescriptor->BasePage = (ULONG)MiOldFreeDescriptorBase;
    01699
    01700 #endif
    01701
    01702 // moved from above for pool hack routines...
    01703     KeInitializeSpinLock (&MmSystemSpaceLock);
    01704
    01705     KeInitializeSpinLock (&MmPfnLock);
    01706
    01707     //
    01708     // Initialize the nonpaged available PTEs for mapping I/O space
    01709     // and kernel stacks.
    01710     //
    01711
    01712     PointerPte = MiGetPteAddress (MmNonPagedSystemStart);
    01713     ASSERT (((ULONG_PTR)PointerPte & (PAGE_SIZE - 1)) == 0);
    01714
    01715     MmNumberOfSystemPtes = (ULONG)(MiGetPteAddress(NonPagedPoolStartVirtual) - PointerPte - 1);
    01716
    01717     MiInitializeSystemPtes (PointerPte, MmNumberOfSystemPtes, SystemPteSpace);
    01718
    01719     //
    01720     // Initialize the nonpaged pool.
    01721     //
    01722
    01723     InitializePool(NonPagedPool,0);
    01724
    01725     //
    01726     // Initialize memory management structures for the system process.
    01727     //
    01728     // Set the address of the first and last reserved PTE in hyper space.
    01729     //
    01730
    01731     MmFirstReservedMappingPte = MiGetPteAddress (FIRST_MAPPING_PTE);
    01732     MmLastReservedMappingPte = MiGetPteAddress (LAST_MAPPING_PTE);
    01733
    01734     MmWorkingSetList = WORKING_SET_LIST;
    01735     MmWsle = (PMMWSLE)((PUCHAR)WORKING_SET_LIST + sizeof(MMWSL));
    01736
    01737     //
    01738     // The PFN element for the page directory parent will be initialized
    01739     // a second time when the process address space is initialized. Therefore,
    01740     // the share count and the reference count must be set to zero.
    01741     //
    01742
    01743     Pfn1 = MI_PFN_ELEMENT(MI_GET_PAGE_FRAME_FROM_PTE((PMMPTE)PDE_SELFMAP));
    01744     Pfn1->u2.ShareCount = 0;
    01745     Pfn1->u3.e2.ReferenceCount = 0;
    01746
    01747     //
    01748     // The PFN element for the hyper space page directory page will be
    01749     // initialized a second time when the process address space is initialized.
    01750     // Therefore, the share count and the reference count must be set to zero.
    01751     //
    01752
    01753     PointerPte = MiGetPpeAddress(HYPER_SPACE);
    01754     Pfn1 = MI_PFN_ELEMENT(MI_GET_PAGE_FRAME_FROM_PTE(PointerPte));
    01755     Pfn1->u2.ShareCount = 0;
    01756     Pfn1->u3.e2.ReferenceCount = 0;
    01757
    01758     //
    01759     // The PFN elements for the hyper space page table page and working set list
    01760     // page will be initialized a second time when the process address space
    01761     // is initialized. Therefore, the share count and the reference must be
    01762     // set to zero.
    01763     //
    01764
    01765     StartPde = MiGetPdeAddress(HYPER_SPACE);
    01766
    01767     Pfn1 = MI_PFN_ELEMENT(MI_GET_PAGE_FRAME_FROM_PTE(StartPde));
    01768     Pfn1->u2.ShareCount = 0;
    01769     Pfn1->u3.e2.ReferenceCount = 0;
    01770
    01771     //
    01772     // Initialize this process's memory management structures including
    01773     // the working set list.
    01774     //
    01775
    01776     //
    01777     // The pfn element for the page directory has already been initialized,
    01778     // zero the reference count and the share count so they won't be
    01779     // wrong.
    01780     //
    01781
    01782     Pfn1 = MI_PFN_ELEMENT (PdePageNumber);
    01783     Pfn1->u2.ShareCount = 0;
    01784     Pfn1->u3.e2.ReferenceCount = 0;
    01785
    01786     CurrentProcess = PsGetCurrentProcess ();
    01787
    01788     //
    01789     // Get a page for the working set list and map it into the Page
    01790     // directory at the page after hyperspace.
    01791     //
    01792
    01793     PageFrameIndex = MiRemoveAnyPage (0);
    01794
    01795     CurrentProcess->WorkingSetPage = PageFrameIndex;
    01796     TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
    01797
    01798     RtlZeroMemory (KSEG_ADDRESS(PageFrameIndex), PAGE_SIZE);
    01799
    01800     CurrentProcess->Vm.MaximumWorkingSetSize = (ULONG)MmSystemProcessWorkingSetMax;
    01801     CurrentProcess->Vm.MinimumWorkingSetSize = (ULONG)MmSystemProcessWorkingSetMin;
    01802
    01803     MmInitializeProcessAddressSpace (CurrentProcess,
    01804                                 (PEPROCESS)NULL,
    01805                                 (PVOID)NULL,
    01806                                 (PVOID)NULL);
    01807
    01808
    01809     //    *PointerPde = ZeroPte;
    01810
    01811     //
    01812     // page after hyperspace should be reclaimed for system cache structure
    01813     //
    01814
    01815     KeFlushCurrentTb();
    01816
    01817     //
    01818     // Check to see if moving the secondary page structures to the end
    01819     // of the PFN database is a waste of memory.  And if so, copy it
    01820     // to paged pool.
    01821     //
    01822     // If the PFN datbase ends on a page aligned boundary and the
    01823     // size of the two arrays is less than a page, free the page
    01824     // and allocate nonpagedpool for this.
    01825     //
    01826
    01827     if ((((ULONG_PTR)MmFreePagesByColor[0] & (PAGE_SIZE - 1)) == 0) &&
    01828        ((MmSecondaryColors * 2 * sizeof(MMCOLOR_TABLES)) < PAGE_SIZE)) {
    01829
    01830         PMMCOLOR_TABLES c;
    01831
    01832         c = MmFreePagesByColor[0];
    01833
    01834         MmFreePagesByColor[0] = ExAllocatePoolWithTag (NonPagedPoolMustSucceed,
    01835                                MmSecondaryColors * 2 * sizeof(MMCOLOR_TABLES),
    01836                                '  mM');
    01837
    01838         MmFreePagesByColor[1] = &MmFreePagesByColor[0][MmSecondaryColors];
    01839
    01840         RtlMoveMemory (MmFreePagesByColor[0],
    01841                        c,
    01842                        MmSecondaryColors * 2 * sizeof(MMCOLOR_TABLES));
    01843
    01844         //
    01845         // Free the page.
    01846         //
    01847
    01848         if (!MI_IS_PHYSICAL_ADDRESS(c)) {
    01849             PointerPte = MiGetPteAddress(c);
    01850             PageFrameIndex = MI_GET_PAGE_FRAME_FROM_PTE(PointerPte);
    01851             MI_WRITE_INVALID_PTE(PointerPte, ZeroKernelPte);
    01852         } else {
    01853             PageFrameIndex = MI_CONVERT_PHYSICAL_TO_PFN (c);
    01854         }
    01855
    01856         Pfn1 = MI_PFN_ELEMENT (PageFrameIndex);
    01857         ASSERT ((Pfn1->u2.ShareCount <= 1) && (Pfn1->u3.e2.ReferenceCount <= 1));
    01858         Pfn1->u2.ShareCount = 0;
    01859         Pfn1->u3.e2.ReferenceCount = 1;
    01860         MI_SET_PFN_DELETED (Pfn1);
    01861 #if DBG
    01862         Pfn1->u3.e1.PageLocation = StandbyPageList;
    01863 #endif //DBG
    01864         MiDecrementReferenceCount (PageFrameIndex);
    01865     }
    01866
    01867     return;
    01868 }

VOID MiMakeKernelPagesPermanent | ( | IN PLOADER_PARAMETER_BLOCK | LoaderBlock | ) |

Definition at line 2354 of file mm/ia64/initia64.c.

References _MEMORY_ALLOCATION_DESCRIPTOR::BasePage, LoaderNlsData, LoaderOsloaderHeap, LoaderRegistryData, LoaderSpecialMemory, _MEMORY_ALLOCATION_DESCRIPTOR::MemoryType, MiNtoskrnlPageShift, MiNtoskrnlPhysicalBase, and PAGE_SHIFT.

Referenced by MiInitMachineDependent().

    02357 {
    02358     PFN_NUMBER KernelStart;
    02359     PFN_NUMBER KernelEnd;
    02360     ULONG_PTR PageSize;
    02361     PLIST_ENTRY NextEntry;
    02362     PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
    02363
    02364     KernelStart = MiNtoskrnlPhysicalBase >> PAGE_SHIFT;
    02365     PageSize = (ULONG_PTR)1 << MiNtoskrnlPageShift;
    02366     KernelEnd = KernelStart + (PageSize >> PAGE_SHIFT);
    02367
    02368     NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
    02369
    02370     for ( ; NextEntry != &LoaderBlock->MemoryDescriptorListHead; NextEntry = NextEntry->Flink) {
    02371
    02372         MemoryDescriptor = CONTAINING_RECORD(NextEntry,
    02373                                              MEMORY_ALLOCATION_DESCRIPTOR,
    02374                                              ListEntry);
    02375
    02376         if (((MemoryDescriptor->BasePage >= KernelStart) &&
    02377              (MemoryDescriptor->BasePage < KernelEnd)) &&
    02378             ((MemoryDescriptor->MemoryType == LoaderOsloaderHeap) ||
    02379              (MemoryDescriptor->MemoryType == LoaderRegistryData) ||
    02380              (MemoryDescriptor->MemoryType == LoaderNlsData))) {
    02381
    02382             //
    02383             // prevent these pages from being reclaimed later
    02384             //
    02385
    02386             MemoryDescriptor->MemoryType = LoaderSpecialMemory;
    02387
    02388         }
    02389
    02390     }
    02391 }

VOID MiRemoveLoaderSuperPages | ( | IN PLOADER_PARAMETER_BLOCK | LoaderBlock | ) |

Definition at line 2337 of file mm/ia64/initia64.c.

References FALSE.

Referenced by MiInitMachineDependent().

    02340 {
    02341
    02342     //
    02343     //  remove the super pages for the boot drivers
    02344     //
    02345
    02346     KiFlushFixedInstTb(FALSE, LoaderBlock->u.Ia64.ItrInfo[ITR_DRIVER0_INDEX].VirtualAddress);
    02347     KiFlushFixedInstTb(FALSE, LoaderBlock->u.Ia64.ItrInfo[ITR_DRIVER1_INDEX].VirtualAddress);
    02348     KiFlushFixedDataTb(FALSE, LoaderBlock->u.Ia64.DtrInfo[DTR_DRIVER0_INDEX].VirtualAddress);
    02349     KiFlushFixedDataTb(FALSE, LoaderBlock->u.Ia64.DtrInfo[DTR_DRIVER1_INDEX].VirtualAddress);
    02350
    02351 }

VOID MiSweepCacheMachineDependent | ( | IN PVOID | VirtualAddress,
|  | IN SIZE_T | Size,
|  | IN MEMORY_CACHING_TYPE | CacheType
| ) |

Definition at line 2042 of file mm/ia64/initia64.c.

References COMPUTE_PAGES_SPANNED, KeSweepCacheRangeWithDrain(), MEMORY_CACHING_TYPE, MI_SET_PTE_WRITE_COMBINE, MI_WRITE_VALID_PTE, MiGetPteAddress, MmWriteCombined, PAGE_ALIGN, PAGE_SIZE, Size, and TRUE.

Referenced by MiMapLockedPagesInUserSpace(), MiMapSinglePage(), MiMapViewOfPhysicalSection(), MmAllocateNonCachedMemory(), MmMapIoSpace(), and MmMapLockedPagesSpecifyCache().

    02049                    :
    02050
    02051     This function checks and perform appropriate cache flushing operations.
    02052
    02053 Arguments:
    02054
    02055     StartVirtual - the start address of the region of pages to be examined.
    02056
    02057     Size - the size of the region of pages
    02058
    02059     Cache - the new cache type
    02060
    02061 Return Value:
    02062
    02063     None.
    02064
    02065 --*/
    02066 {
    02067     PFN_NUMBER j;
    02068     PFN_NUMBER NumberOfPages;
    02069     KIRQL OldIrql;
    02070     PMMPTE PointerPte;
    02071     MMPTE TempPte;
    02072
    02073     NumberOfPages = COMPUTE_PAGES_SPANNED (VirtualAddress, Size);
    02074     VirtualAddress = PAGE_ALIGN(VirtualAddress);
    02075     Size = NumberOfPages * PAGE_SIZE;
    02076
    02077     KeSweepCacheRangeWithDrain(TRUE, VirtualAddress, (ULONG)Size);
    02078
    02079     if (CacheType == MmWriteCombined) {
    02080         PointerPte = MiGetPteAddress(VirtualAddress);
    02081         for (j = 0; j < NumberOfPages; j += 1) {
    02082             TempPte = *PointerPte;
    02083             MI_SET_PTE_WRITE_COMBINE (TempPte);
    02084             MI_WRITE_VALID_PTE (PointerPte, TempPte);
    02085             PointerPte += 1;
    02086         }
    02087     }
    02088 }

## Variable Documentation

PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor

| Definition at line 121 of file mm/ia64/initia64.c. Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorLargest = NULL

| Definition at line 122 of file mm/ia64/initia64.c. Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorLowMem = NULL

| Definition at line 123 of file mm/ia64/initia64.c. Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorNonPaged = NULL

| Definition at line 124 of file mm/ia64/initia64.c. Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

ULONG MiImplVirtualMsb = 50

| Definition at line 135 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

PVOID MiKseg0End = 0

| Definition at line 87 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

BOOLEAN MiKseg0Mapping = TRUE

| Definition at line 88 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

PVOID MiKseg0Start = 0

| Definition at line 86 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

PFN_NUMBER MiNextPhysicalPage

| Definition at line 126 of file mm/ia64/initia64.c. Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

ULONG MiNtoskrnlPageShift

| Definition at line 92 of file mm/ia64/initia64.c. Referenced by MiCheckMemoryDescriptorList(), MiInitMachineDependent(), and MiMakeKernelPagesPermanent().

PFN_NUMBER MiNtoskrnlPhysicalBase

| Definition at line 90 of file mm/ia64/initia64.c. Referenced by MiCheckMemoryDescriptorList(), MiInitMachineDependent(), and MiMakeKernelPagesPermanent().

ULONG_PTR MiNtoskrnlVirtualBase

| Definition at line 91 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

PFN_NUMBER MiNumberOfPages

| Definition at line 127 of file mm/ia64/initia64.c. Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

PFN_NUMBER MiOldFreeDescriptorBase

| Definition at line 128 of file mm/ia64/initia64.c. Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

PFN_NUMBER MiOldFreeDescriptorCount

| Definition at line 129 of file mm/ia64/initia64.c. Referenced by MiEnsureAvailablePagesInFreeDescriptor(), MiGetNextPhysicalPage(), and MiInitMachineDependent().

BOOLEAN MiPrintMemoryDescriptors = FALSE

| Definition at line 89 of file mm/ia64/initia64.c. Referenced by MiCheckMemoryDescriptorList(), and MiInitMachineDependent().

MMPTE MiSystemSelfMappedPte

| Definition at line 84 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

MMPTE MiUserSelfMappedPte

| Definition at line 85 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

PFN_NUMBER MiWasteEnd = 0

| Definition at line 94 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

PFN_NUMBER MiWasteStart = 0

| Definition at line 93 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

ULONG_PTR MmKseg3VhptBase

| Definition at line 80 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

ULONG MmKseg3VhptPs

| Definition at line 81 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().

PFN_NUMBER MmSystemParentTablePage

| Definition at line 83 of file mm/ia64/initia64.c. Referenced by MiInitMachineDependent().