X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FCore%2FDxe%2FMem%2FPage.c;h=18780070c5eaf8df44a27756933ba236c8c3800a;hp=6d5a259eb669dc7a462e0c217ecd28ba6325d07e;hb=84edd20bd0756ef5719835498d4283435d6b5e77;hpb=3d78c020d22023d35d27b48817d73ff31a361ac7 diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c index 6d5a259eb6..18780070c5 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -1,7 +1,7 @@ /** @file UEFI Memory page management functions. -Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
+Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -177,7 +177,20 @@ CoreAddRange ( ASSERT_LOCKED (&gMemoryLock); DEBUG ((DEBUG_PAGE, "AddRange: %lx-%lx to %d\n", Start, End, Type)); - + + // + // If memory of type EfiConventionalMemory is being added that includes the page + // starting at address 0, then zero the page starting at address 0. This has + // two benifits. It helps find NULL pointer bugs and it also maximizes + // compatibility with operating systems that may evaluate memory in this page + // for legacy data structures. If memory of any other type is added starting + // at address 0, then do not zero the page at address 0 because the page is being + // used for other purposes. + // + if (Type == EfiConventionalMemory && Start == 0 && (End >= EFI_PAGE_SIZE - 1)) { + SetMem ((VOID *)(UINTN)Start, EFI_PAGE_SIZE, 0); + } + // // Memory map being altered so updated key // @@ -834,7 +847,18 @@ CoreConvertPages ( // CoreAddRange (NewType, Start, RangeEnd, Attribute); if (NewType == EfiConventionalMemory) { - DEBUG_CLEAR_MEMORY ((VOID *)(UINTN) Start, (UINTN) (RangeEnd - Start + 1)); + // + // Avoid calling DEBUG_CLEAR_MEMORY() for an address of 0 because this + // macro will ASSERT() if address is 0. Instead, CoreAddRange() guarantees + // that the page starting at address 0 is always filled with zeros. + // + if (Start == 0) { + if (RangeEnd > EFI_PAGE_SIZE) { + DEBUG_CLEAR_MEMORY ((VOID *)(UINTN) EFI_PAGE_SIZE, (UINTN) (RangeEnd - EFI_PAGE_SIZE + 1)); + } + } else { + DEBUG_CLEAR_MEMORY ((VOID *)(UINTN) Start, (UINTN) (RangeEnd - Start + 1)); + } } // @@ -906,7 +930,7 @@ CoreFindFreePagesI ( // // Set MaxAddress to a page boundary // - MaxAddress &= ~EFI_PAGE_MASK; + MaxAddress &= ~(UINT64)EFI_PAGE_MASK; // // Set MaxAddress to end of the page @@ -1082,7 +1106,7 @@ FindFreePages ( **/ EFI_STATUS EFIAPI -CoreAllocatePages ( +CoreInternalAllocatePages ( IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN NumberOfPages, @@ -1168,6 +1192,41 @@ Done: return Status; } +/** + Allocates pages from the memory map. + + @param Type The type of allocation to perform + @param MemoryType The type of memory to turn the allocated pages + into + @param NumberOfPages The number of pages to allocate + @param Memory A pointer to receive the base allocated memory + address + + @return Status. On success, Memory is filled in with the base address allocated + @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in + spec. + @retval EFI_NOT_FOUND Could not allocate pages match the requirement. + @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. + @retval EFI_SUCCESS Pages successfully allocated. + +**/ +EFI_STATUS +EFIAPI +CoreAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NumberOfPages, + OUT EFI_PHYSICAL_ADDRESS *Memory + ) +{ + EFI_STATUS Status; + + Status = CoreInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory); + if (!EFI_ERROR (Status)) { + CoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionAllocatePages, MemoryType, EFI_PAGES_TO_SIZE (NumberOfPages), (VOID *) (UINTN) *Memory); + } + return Status; +} /** Frees previous allocated pages. @@ -1182,7 +1241,7 @@ Done: **/ EFI_STATUS EFIAPI -CoreFreePages ( +CoreInternalFreePages ( IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages ) @@ -1243,6 +1302,33 @@ Done: return Status; } +/** + Frees previous allocated pages. + + @param Memory Base address of memory being freed + @param NumberOfPages The number of pages to free + + @retval EFI_NOT_FOUND Could not find the entry that covers the range + @retval EFI_INVALID_PARAMETER Address not aligned + @return EFI_SUCCESS -Pages successfully freed. + +**/ +EFI_STATUS +EFIAPI +CoreFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ) +{ + EFI_STATUS Status; + + Status = CoreInternalFreePages (Memory, NumberOfPages); + if (!EFI_ERROR (Status)) { + CoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionFreePages, 0, EFI_PAGES_TO_SIZE (NumberOfPages), (VOID *) (UINTN) Memory); + } + return Status; +} + /** This function checks to see if the last memory map descriptor in a memory map can be merged with any of the other memory map descriptors in a memorymap.