From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 431762095B9D7 for ; Fri, 18 Aug 2017 08:58:37 -0700 (PDT) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Aug 2017 09:00:52 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,393,1498546800"; d="scan'208";a="1005243138" Received: from shwdeopenpsi068.ccr.corp.intel.com ([10.239.9.22]) by orsmga003.jf.intel.com with ESMTP; 18 Aug 2017 09:00:51 -0700 From: Star Zeng To: edk2-devel@lists.01.org Cc: Star Zeng , Liming Gao Date: Sat, 19 Aug 2017 00:00:37 +0800 Message-Id: <1503072038-134760-5-git-send-email-star.zeng@intel.com> X-Mailer: git-send-email 2.7.0.windows.1 In-Reply-To: <1503072038-134760-1-git-send-email-star.zeng@intel.com> References: <1503072038-134760-1-git-send-email-star.zeng@intel.com> Subject: [PATCH 4/5] MdePkg PeiMemoryAllocationLib: Update InternalAllocateAlignedPages X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Aug 2017 15:58:37 -0000 Update InternalAllocateAlignedPages to use PeiServicesFreePages. Let the InternalAllocateAlignedPages in PeiMemoryAllocationLib use same algorithm with InternalAllocateAlignedPages in UefiMemoryAllocationLib. Cc: Liming Gao Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Star Zeng --- .../PeiMemoryAllocationLib/MemoryAllocationLib.c | 172 +++++---------------- 1 file changed, 40 insertions(+), 132 deletions(-) diff --git a/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c b/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c index 37273dde561a..755f89c72ea2 100644 --- a/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c @@ -181,15 +181,12 @@ InternalAllocateAlignedPages ( IN UINTN Alignment ) { - EFI_PHYSICAL_ADDRESS Memory; - EFI_PHYSICAL_ADDRESS AlignedMemory; - EFI_PEI_HOB_POINTERS Hob; - BOOLEAN SkipBeforeMemHob; - BOOLEAN SkipAfterMemHob; - EFI_PHYSICAL_ADDRESS HobBaseAddress; - UINT64 HobLength; - EFI_MEMORY_TYPE HobMemoryType; - UINTN TotalPages; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + UINTN AlignedMemory; + UINTN AlignmentMask; + UINTN UnalignedPages; + UINTN RealPages; // // Alignment must be a power of two or zero. @@ -199,139 +196,50 @@ InternalAllocateAlignedPages ( if (Pages == 0) { return NULL; } - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment))); - - // - // We would rather waste some memory to save PEI code size. - // meaning in addition to the requested size for the aligned mem, - // we simply reserve an overhead memory equal to Alignmemt(page-aligned), no matter what. - // The overhead mem size could be reduced later with more involved malloc mechanisms - // (e.g., somthing that can detect the alignment boundary before allocating memory or - // can request that memory be allocated at a certain address that is aleady aligned). - // - TotalPages = Pages + (Alignment <= EFI_PAGE_SIZE ? 0 : EFI_SIZE_TO_PAGES(Alignment)); - Memory = (EFI_PHYSICAL_ADDRESS) (UINTN) InternalAllocatePages (MemoryType, TotalPages); - if (Memory == 0) { - DEBUG((DEBUG_INFO, "Out of memory resource! \n")); - return NULL; - } - DEBUG ((DEBUG_INFO, "Allocated Memory unaligned: Address = 0x%LX, Pages = 0x%X, Type = %d \n", Memory, TotalPages, (UINTN) MemoryType)); - - // - // Alignment calculation - // - AlignedMemory = Memory; if (Alignment > EFI_PAGE_SIZE) { - AlignedMemory = ALIGN_VALUE (Memory, Alignment); - } - DEBUG ((DEBUG_INFO, "After aligning to 0x%X bytes: Address = 0x%LX, Pages = 0x%X \n", Alignment, AlignedMemory, Pages)); - - // - // In general three HOBs cover the total allocated space. - // The aligned portion is covered by the aligned mem HOB and - // the unaligned(to be freed) portions before and after the aligned portion are covered by newly created HOBs. - // - // Before mem HOB covers the region between "Memory" and "AlignedMemory" - // Aligned mem HOB covers the region between "AlignedMemory" and "AlignedMemory + EFI_PAGES_TO_SIZE(Pages)" - // After mem HOB covers the region between "AlignedMemory + EFI_PAGES_TO_SIZE(Pages)" and "Memory + EFI_PAGES_TO_SIZE(TotalPages)" - // - // The before or after mem HOBs need to be skipped under special cases where the aligned portion - // touches either the top or bottom of the original allocated space. - // - SkipBeforeMemHob = FALSE; - SkipAfterMemHob = FALSE; - if (Memory == AlignedMemory) { - SkipBeforeMemHob = TRUE; - } - if ((Memory + EFI_PAGES_TO_SIZE(TotalPages)) == (AlignedMemory + EFI_PAGES_TO_SIZE(Pages))) { // - // This condition is never met in the current implementation. - // There is always some after-mem since the overhead mem(used in TotalPages) - // is no less than Alignment. + // Calculate the total number of pages since alignment is larger than page size. // - SkipAfterMemHob = TRUE; - } - - // - // Search for the mem HOB referring to the original(unaligned) allocation - // and update the size and type if needed. - // - Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION); - while (Hob.Raw != NULL) { - if (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == Memory) { - break; - } - Hob.Raw = GET_NEXT_HOB (Hob); - Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw); - } - ASSERT (Hob.Raw != NULL); - if (SkipBeforeMemHob) { + AlignmentMask = Alignment - 1; + RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); // - // Use this HOB as aligned mem HOB as there is no portion before it. + // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. // - HobLength = EFI_PAGES_TO_SIZE(Pages); - Hob.MemoryAllocation->AllocDescriptor.MemoryLength = HobLength; + ASSERT (RealPages > Pages); + + Status = PeiServicesAllocatePages (MemoryType, RealPages, &Memory); + if (EFI_ERROR (Status)) { + return NULL; + } + AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask; + UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory); + if (UnalignedPages > 0) { + // + // Free first unaligned page(s). + // + Status = PeiServicesFreePages (Memory, UnalignedPages); + ASSERT_EFI_ERROR (Status); + } + Memory = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages)); + UnalignedPages = RealPages - Pages - UnalignedPages; + if (UnalignedPages > 0) { + // + // Free last unaligned page(s). + // + Status = PeiServicesFreePages (Memory, UnalignedPages); + ASSERT_EFI_ERROR (Status); + } } else { // - // Use this HOB as before mem HOB and create a new HOB for the aligned portion + // Do not over-allocate pages in this case. // - HobLength = (AlignedMemory - Memory); - Hob.MemoryAllocation->AllocDescriptor.MemoryLength = HobLength; - Hob.MemoryAllocation->AllocDescriptor.MemoryType = EfiConventionalMemory; - } - - HobBaseAddress = Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress; - HobMemoryType = Hob.MemoryAllocation->AllocDescriptor.MemoryType; - - // - // Build the aligned mem HOB if needed - // - if (!SkipBeforeMemHob) { - DEBUG((DEBUG_INFO, "Updated before-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n", - HobBaseAddress, HobLength, (UINTN) HobMemoryType)); - - HobBaseAddress = AlignedMemory; - HobLength = EFI_PAGES_TO_SIZE(Pages); - HobMemoryType = MemoryType; - - BuildMemoryAllocationHob ( - HobBaseAddress, - HobLength, - HobMemoryType - ); - - DEBUG((DEBUG_INFO, "Created aligned-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n", - HobBaseAddress, HobLength, (UINTN) HobMemoryType)); - } else { - if (HobBaseAddress != 0) { - DEBUG((DEBUG_INFO, "Updated aligned-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n", - HobBaseAddress, HobLength, (UINTN) HobMemoryType)); + Status = PeiServicesAllocatePages (MemoryType, Pages, &Memory); + if (EFI_ERROR (Status)) { + return NULL; } + AlignedMemory = (UINTN) Memory; } - - - // - // Build the after mem HOB if needed - // - if (!SkipAfterMemHob) { - HobBaseAddress = AlignedMemory + EFI_PAGES_TO_SIZE(Pages); - HobLength = (Memory + EFI_PAGES_TO_SIZE(TotalPages)) - (AlignedMemory + EFI_PAGES_TO_SIZE(Pages)); - HobMemoryType = EfiConventionalMemory; - - BuildMemoryAllocationHob ( - HobBaseAddress, - HobLength, - HobMemoryType - ); - - DEBUG((DEBUG_INFO, "Created after-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n", - HobBaseAddress, HobLength, (UINTN) HobMemoryType)); - } - - return (VOID *) (UINTN) AlignedMemory; + return (VOID *) AlignedMemory; } /** -- 2.7.0.windows.1