Author: ion Date: Sun May 14 00:39:30 2017 New Revision: 74542
URL: http://svn.reactos.org/svn/reactos?rev=74542&view=rev Log: [BOOTLIB]: Implement MmMdTruncateDescriptors [BOOTLIB]: Implement MmPaTruncateMemory and call it during paging initialization to remove > 4GB memory.c [BOOTLIB]: Implement BlpMmInitializeConstraints if those BCD options are used.
Modified: trunk/reactos/boot/environ/include/bl.h trunk/reactos/boot/environ/lib/mm/descriptor.c trunk/reactos/boot/environ/lib/mm/i386/mmx86.c trunk/reactos/boot/environ/lib/mm/pagealloc.c
Modified: trunk/reactos/boot/environ/include/bl.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/include/bl.h?r... ============================================================================== --- trunk/reactos/boot/environ/include/bl.h [iso-8859-1] (original) +++ trunk/reactos/boot/environ/include/bl.h [iso-8859-1] Sun May 14 00:39:30 2017 @@ -2088,6 +2088,13 @@ _In_ ULONG Flags );
+NTSTATUS +MmMdTruncateDescriptors ( + _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList, + _In_ PBL_MEMORY_DESCRIPTOR_LIST NewList, + _In_ ULONGLONG BasePage + ); + VOID MmMdRemoveDescriptorFromList ( _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList, @@ -2122,6 +2129,11 @@ );
/* PAGE ALLOCATOR ROUTINES ***************************************************/ + +NTSTATUS +MmPaTruncateMemory ( + _In_ ULONGLONG BasePage + );
NTSTATUS BlMmAllocatePhysicalPages(
Modified: trunk/reactos/boot/environ/lib/mm/descriptor.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/descrip... ============================================================================== --- trunk/reactos/boot/environ/lib/mm/descriptor.c [iso-8859-1] (original) +++ trunk/reactos/boot/environ/lib/mm/descriptor.c [iso-8859-1] Sun May 14 00:39:30 2017 @@ -406,6 +406,82 @@ /* Increment the count and return the descriptor */ MmGlobalMemoryDescriptorsUsed++; return MemoryDescriptor; +} + +NTSTATUS +MmMdTruncateDescriptors ( + _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList, + _In_ PBL_MEMORY_DESCRIPTOR_LIST NewList, + _In_ ULONGLONG BasePage + ) +{ + PLIST_ENTRY ListHead, NextEntry; + PBL_MEMORY_DESCRIPTOR Descriptor, NewDescriptor; + ULONGLONG FoundEndPage; + + /* Search the descriptor list */ + ListHead = MdList->First; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the current descriptor */ + Descriptor = CONTAINING_RECORD(NextEntry, + BL_MEMORY_DESCRIPTOR, + ListEntry); + + /* Go to the next entry in case we have to remove */ + NextEntry = NextEntry->Flink; + + /* Don't touch anything else but free RAM */ + if (((Descriptor->Type >> BL_MEMORY_CLASS_SHIFT) == BlSystemClass) && + (Descriptor->Type != BlConventionalMemory)) + { + continue; + } + + /* Check if this page is within the descriptor's region */ + FoundEndPage = Descriptor->BasePage + Descriptor->PageCount; + if (BasePage > Descriptor->BasePage) + { + /* Check if it doesn't go beyond the descriptor */ + if (BasePage < FoundEndPage) + { + /* Create a new descriptor to describe this region */ + EfiPrintf(L"Truncating descriptor type %lx base: %llx end: %llx\r\n", + Descriptor->Type, Descriptor->BasePage, FoundEndPage); + NewDescriptor = MmMdInitByteGranularDescriptor(Descriptor->Flags, + Descriptor->Type, + BasePage, + 0, + FoundEndPage - BasePage); + if (!NewDescriptor) + { + return STATUS_NO_MEMORY; + } + + /* Cut off this descriptor to make it shorter */ + Descriptor->PageCount = BasePage - Descriptor->BasePage; + + /* Add the region to the new list */ + MmMdAddDescriptorToList(NewList, + NewDescriptor, + BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG); + } + } + else + { + /* This whole descriptor covers the truncated area */ + EfiPrintf(L"Truncating descriptor type %lx base: %llx end: %llx\r\n", + Descriptor->Type, Descriptor->BasePage, FoundEndPage); + MmMdRemoveDescriptorFromList(MdList, Descriptor); + MmMdAddDescriptorToList(NewList, + Descriptor, + BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG); + } + } + + /* All good if we got here */ + return STATUS_SUCCESS; }
BOOLEAN
Modified: trunk/reactos/boot/environ/lib/mm/i386/mmx86.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/i386/mm... ============================================================================== --- trunk/reactos/boot/environ/lib/mm/i386/mmx86.c [iso-8859-1] (original) +++ trunk/reactos/boot/environ/lib/mm/i386/mmx86.c [iso-8859-1] Sun May 14 00:39:30 2017 @@ -939,10 +939,8 @@ Mmx86SelfMapBase.QuadPart = 0; MmArchReferencePage = NULL;
- /* Truncate all memory above 4GB so that we don't use it @TODO: FIXME */ - EfiPrintf(L"Warning: not truncating > 4GB memory. Don't boot with more than 4GB of RAM!\r\n"); - //Status = MmPaTruncateMemory(0x100000); - Status = STATUS_SUCCESS; + /* Truncate all memory above 4GB so that we don't use it */ + Status = MmPaTruncateMemory(0x100000); if (!NT_SUCCESS(Status)) { goto Quickie;
Modified: trunk/reactos/boot/environ/lib/mm/pagealloc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/pageall... ============================================================================== --- trunk/reactos/boot/environ/lib/mm/pagealloc.c [iso-8859-1] (original) +++ trunk/reactos/boot/environ/lib/mm/pagealloc.c [iso-8859-1] Sun May 14 00:39:30 2017 @@ -48,12 +48,71 @@ /* FUNCTIONS *****************************************************************/
NTSTATUS +MmPaTruncateMemory ( + _In_ ULONGLONG BasePage + ) +{ + NTSTATUS Status; + + /* Increase nesting depth */ + ++MmDescriptorCallTreeCount; + + /* Set the maximum page to the truncated request */ + if (BasePage < PapMaximumPhysicalPage) + { + PapMaximumPhysicalPage = BasePage; + } + + /* Truncate mapped and allocated memory */ + Status = MmMdTruncateDescriptors(&MmMdlMappedAllocated, + &MmMdlTruncatedMemory, + BasePage); + if (NT_SUCCESS(Status)) + { + /* Truncate unmapped and allocated memory */ + Status = MmMdTruncateDescriptors(&MmMdlUnmappedAllocated, + &MmMdlTruncatedMemory, + BasePage); + if (NT_SUCCESS(Status)) + { + /* Truncate mapped and unallocated memory */ + Status = MmMdTruncateDescriptors(&MmMdlMappedUnallocated, + &MmMdlTruncatedMemory, + BasePage); + if (NT_SUCCESS(Status)) + { + /* Truncate unmapped and unallocated memory */ + Status = MmMdTruncateDescriptors(&MmMdlUnmappedUnallocated, + &MmMdlTruncatedMemory, + BasePage); + if (NT_SUCCESS(Status)) + { + /* Truncate reserved memory */ + Status = MmMdTruncateDescriptors(&MmMdlReservedAllocated, + &MmMdlTruncatedMemory, + BasePage); + } + } + } + } + + /* Restore the nesting depth */ + MmMdFreeGlobalDescriptors(); + --MmDescriptorCallTreeCount; + return Status; +} + +NTSTATUS BlpMmInitializeConstraints ( VOID ) { - NTSTATUS Status; + NTSTATUS Status, ReturnStatus; ULONGLONG LowestAddressValid, HighestAddressValid; + ULONGLONG LowestPage, HighestPage; + + /* Assume success */ + ReturnStatus = STATUS_SUCCESS;
/* Check for LOWMEM */ Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData, @@ -61,8 +120,15 @@ &LowestAddressValid); if (NT_SUCCESS(Status)) { - EfiPrintf(L"/LOWMEM not supported\r\n"); - return STATUS_NOT_IMPLEMENTED; + /* Align the address */ + LowestAddressValid = (ULONG_PTR)PAGE_ALIGN(LowestAddressValid); + LowestPage = LowestAddressValid >> PAGE_SHIFT; + + /* Make sure it's below 4GB */ + if (LowestPage <= 0x100000) + { + PapMinimumPhysicalPage = LowestPage; + } }
/* Check for MAXMEM */ @@ -71,12 +137,15 @@ &HighestAddressValid); if (NT_SUCCESS(Status)) { - EfiPrintf(L"/MAXMEM not supported\r\n"); - return STATUS_NOT_IMPLEMENTED; + /* Get the page */ + HighestPage = HighestAddressValid >> PAGE_SHIFT; + + /* Truncate memory above this page */ + ReturnStatus = MmPaTruncateMemory(HighestPage); }
/* Return back to the caller */ - return STATUS_SUCCESS; + return ReturnStatus; }
NTSTATUS