Bugzilla: 3150 (https://bugzilla.tianocore.org/show_bug.cgi?id=3150) Fix the following error reported by the Ecc tool: [1001] 'TAB' character is not allowed in source code, please replace each 'TAB' with two spaces. Signed-off-by: Sami Mujawar <sami.mujawar@arm.com> Acked-by: Jiewen Yao <Jiewen.yao@intel.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			288 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			288 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   SMM Memory pool management functions.
 | |
| 
 | |
|   Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
 | |
|   Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "StandaloneMmCore.h"
 | |
| 
 | |
| LIST_ENTRY  mMmPoolLists[MAX_POOL_INDEX];
 | |
| //
 | |
| // To cache the MMRAM base since when Loading modules At fixed address feature is enabled,
 | |
| // all module is assigned an offset relative the MMRAM base in build time.
 | |
| //
 | |
| GLOBAL_REMOVE_IF_UNREFERENCED  EFI_PHYSICAL_ADDRESS       gLoadModuleAtFixAddressMmramBase = 0;
 | |
| 
 | |
| /**
 | |
|   Called to initialize the memory service.
 | |
| 
 | |
|   @param   MmramRangeCount       Number of MMRAM Regions
 | |
|   @param   MmramRanges           Pointer to MMRAM Descriptors
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| MmInitializeMemoryServices (
 | |
|   IN UINTN                 MmramRangeCount,
 | |
|   IN EFI_MMRAM_DESCRIPTOR  *MmramRanges
 | |
|   )
 | |
| {
 | |
|   UINTN                  Index;
 | |
| 
 | |
|   //
 | |
|   // Initialize Pool list
 | |
|   //
 | |
|   for (Index = sizeof (mMmPoolLists) / sizeof (*mMmPoolLists); Index > 0;) {
 | |
|     InitializeListHead (&mMmPoolLists[--Index]);
 | |
|   }
 | |
| 
 | |
| 
 | |
|   //
 | |
|   // Initialize free MMRAM regions
 | |
|   //
 | |
|   for (Index = 0; Index < MmramRangeCount; Index++) {
 | |
|     //
 | |
|     // BUGBUG: Add legacy MMRAM region is buggy.
 | |
|     //
 | |
|     if (MmramRanges[Index].CpuStart < BASE_1MB) {
 | |
|       continue;
 | |
|     }
 | |
|     DEBUG ((DEBUG_INFO, "MmAddMemoryRegion %d : 0x%016lx - 0x%016lx\n",
 | |
|       Index, MmramRanges[Index].CpuStart, MmramRanges[Index].PhysicalSize));
 | |
|     MmAddMemoryRegion (
 | |
|       MmramRanges[Index].CpuStart,
 | |
|       MmramRanges[Index].PhysicalSize,
 | |
|       EfiConventionalMemory,
 | |
|       MmramRanges[Index].RegionState
 | |
|       );
 | |
|   }
 | |
| 
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Internal Function. Allocate a pool by specified PoolIndex.
 | |
| 
 | |
|   @param  PoolIndex             Index which indicate the Pool size.
 | |
|   @param  FreePoolHdr           The returned Free pool.
 | |
| 
 | |
|   @retval EFI_OUT_OF_RESOURCES   Allocation failed.
 | |
|   @retval EFI_SUCCESS            Pool successfully allocated.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| InternalAllocPoolByIndex (
 | |
|   IN  UINTN             PoolIndex,
 | |
|   OUT FREE_POOL_HEADER  **FreePoolHdr
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS            Status;
 | |
|   FREE_POOL_HEADER      *Hdr;
 | |
|   EFI_PHYSICAL_ADDRESS  Address;
 | |
| 
 | |
|   ASSERT (PoolIndex <= MAX_POOL_INDEX);
 | |
|   Status = EFI_SUCCESS;
 | |
|   Hdr = NULL;
 | |
|   if (PoolIndex == MAX_POOL_INDEX) {
 | |
|     Status = MmInternalAllocatePages (
 | |
|                AllocateAnyPages,
 | |
|                EfiRuntimeServicesData,
 | |
|                EFI_SIZE_TO_PAGES (MAX_POOL_SIZE << 1),
 | |
|                &Address
 | |
|                );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return EFI_OUT_OF_RESOURCES;
 | |
|     }
 | |
|     Hdr = (FREE_POOL_HEADER *) (UINTN) Address;
 | |
|   } else if (!IsListEmpty (&mMmPoolLists[PoolIndex])) {
 | |
|     Hdr = BASE_CR (GetFirstNode (&mMmPoolLists[PoolIndex]), FREE_POOL_HEADER, Link);
 | |
|     RemoveEntryList (&Hdr->Link);
 | |
|   } else {
 | |
|     Status = InternalAllocPoolByIndex (PoolIndex + 1, &Hdr);
 | |
|     if (!EFI_ERROR (Status)) {
 | |
|       Hdr->Header.Size >>= 1;
 | |
|       Hdr->Header.Available = TRUE;
 | |
|       InsertHeadList (&mMmPoolLists[PoolIndex], &Hdr->Link);
 | |
|       Hdr = (FREE_POOL_HEADER*)((UINT8*)Hdr + Hdr->Header.Size);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     Hdr->Header.Size = MIN_POOL_SIZE << PoolIndex;
 | |
|     Hdr->Header.Available = FALSE;
 | |
|   }
 | |
| 
 | |
|   *FreePoolHdr = Hdr;
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Internal Function. Free a pool by specified PoolIndex.
 | |
| 
 | |
|   @param  FreePoolHdr           The pool to free.
 | |
| 
 | |
|   @retval EFI_SUCCESS           Pool successfully freed.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| InternalFreePoolByIndex (
 | |
|   IN FREE_POOL_HEADER  *FreePoolHdr
 | |
|   )
 | |
| {
 | |
|   UINTN  PoolIndex;
 | |
| 
 | |
|   ASSERT ((FreePoolHdr->Header.Size & (FreePoolHdr->Header.Size - 1)) == 0);
 | |
|   ASSERT (((UINTN)FreePoolHdr & (FreePoolHdr->Header.Size - 1)) == 0);
 | |
|   ASSERT (FreePoolHdr->Header.Size >= MIN_POOL_SIZE);
 | |
| 
 | |
|   PoolIndex = (UINTN) (HighBitSet32 ((UINT32)FreePoolHdr->Header.Size) - MIN_POOL_SHIFT);
 | |
|   FreePoolHdr->Header.Available = TRUE;
 | |
|   ASSERT (PoolIndex < MAX_POOL_INDEX);
 | |
|   InsertHeadList (&mMmPoolLists[PoolIndex], &FreePoolHdr->Link);
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Allocate pool of a particular type.
 | |
| 
 | |
|   @param  PoolType               Type of pool to allocate.
 | |
|   @param  Size                   The amount of pool to allocate.
 | |
|   @param  Buffer                 The address to return a pointer to the allocated
 | |
|                                  pool.
 | |
| 
 | |
|   @retval EFI_INVALID_PARAMETER  PoolType not valid.
 | |
|   @retval EFI_OUT_OF_RESOURCES   Size exceeds max pool size or allocation failed.
 | |
|   @retval EFI_SUCCESS            Pool successfully allocated.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| MmInternalAllocatePool (
 | |
|   IN   EFI_MEMORY_TYPE  PoolType,
 | |
|   IN   UINTN            Size,
 | |
|   OUT  VOID             **Buffer
 | |
|   )
 | |
| {
 | |
|   POOL_HEADER           *PoolHdr;
 | |
|   FREE_POOL_HEADER      *FreePoolHdr;
 | |
|   EFI_STATUS            Status;
 | |
|   EFI_PHYSICAL_ADDRESS  Address;
 | |
|   UINTN                 PoolIndex;
 | |
| 
 | |
|   if (PoolType != EfiRuntimeServicesCode &&
 | |
|       PoolType != EfiRuntimeServicesData) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   Size += sizeof (*PoolHdr);
 | |
|   if (Size > MAX_POOL_SIZE) {
 | |
|     Size = EFI_SIZE_TO_PAGES (Size);
 | |
|     Status = MmInternalAllocatePages (AllocateAnyPages, PoolType, Size, &Address);
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return Status;
 | |
|     }
 | |
| 
 | |
|     PoolHdr = (POOL_HEADER*)(UINTN)Address;
 | |
|     PoolHdr->Size = EFI_PAGES_TO_SIZE (Size);
 | |
|     PoolHdr->Available = FALSE;
 | |
|     *Buffer = PoolHdr + 1;
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Size = (Size + MIN_POOL_SIZE - 1) >> MIN_POOL_SHIFT;
 | |
|   PoolIndex = (UINTN) HighBitSet32 ((UINT32)Size);
 | |
|   if ((Size & (Size - 1)) != 0) {
 | |
|     PoolIndex++;
 | |
|   }
 | |
| 
 | |
|   Status = InternalAllocPoolByIndex (PoolIndex, &FreePoolHdr);
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     *Buffer = &FreePoolHdr->Header + 1;
 | |
|   }
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Allocate pool of a particular type.
 | |
| 
 | |
|   @param  PoolType               Type of pool to allocate.
 | |
|   @param  Size                   The amount of pool to allocate.
 | |
|   @param  Buffer                 The address to return a pointer to the allocated
 | |
|                                  pool.
 | |
| 
 | |
|   @retval EFI_INVALID_PARAMETER  PoolType not valid.
 | |
|   @retval EFI_OUT_OF_RESOURCES   Size exceeds max pool size or allocation failed.
 | |
|   @retval EFI_SUCCESS            Pool successfully allocated.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| MmAllocatePool (
 | |
|   IN   EFI_MEMORY_TYPE  PoolType,
 | |
|   IN   UINTN            Size,
 | |
|   OUT  VOID             **Buffer
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   Status = MmInternalAllocatePool (PoolType, Size, Buffer);
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Frees pool.
 | |
| 
 | |
|   @param  Buffer                 The allocated pool entry to free.
 | |
| 
 | |
|   @retval EFI_INVALID_PARAMETER  Buffer is not a valid value.
 | |
|   @retval EFI_SUCCESS            Pool successfully freed.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| MmInternalFreePool (
 | |
|   IN VOID  *Buffer
 | |
|   )
 | |
| {
 | |
|   FREE_POOL_HEADER  *FreePoolHdr;
 | |
| 
 | |
|   if (Buffer == NULL) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   FreePoolHdr = (FREE_POOL_HEADER*)((POOL_HEADER*)Buffer - 1);
 | |
|   ASSERT (!FreePoolHdr->Header.Available);
 | |
| 
 | |
|   if (FreePoolHdr->Header.Size > MAX_POOL_SIZE) {
 | |
|     ASSERT (((UINTN)FreePoolHdr & EFI_PAGE_MASK) == 0);
 | |
|     ASSERT ((FreePoolHdr->Header.Size & EFI_PAGE_MASK) == 0);
 | |
|     return MmInternalFreePages (
 | |
|              (EFI_PHYSICAL_ADDRESS)(UINTN)FreePoolHdr,
 | |
|              EFI_SIZE_TO_PAGES (FreePoolHdr->Header.Size)
 | |
|              );
 | |
|   }
 | |
|   return InternalFreePoolByIndex (FreePoolHdr);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Frees pool.
 | |
| 
 | |
|   @param  Buffer                 The allocated pool entry to free.
 | |
| 
 | |
|   @retval EFI_INVALID_PARAMETER  Buffer is not a valid value.
 | |
|   @retval EFI_SUCCESS            Pool successfully freed.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| MmFreePool (
 | |
|   IN VOID  *Buffer
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   Status = MmInternalFreePool (Buffer);
 | |
|   return Status;
 | |
| }
 |