StandaloneMmPkg: StandaloneMmMemLib: Extends support for X64 architecture

This change extends StandaloneMmMemLib library to support X64
architecture. The implementation is ported from MdePkg/Library/SmmMemLib.

Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Supreeth Venkatesh <supreeth.venkatesh@arm.com>

Signed-off-by: Kun Qin <kun.q@outlook.com>
Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
This commit is contained in:
Kun Qin 2020-12-18 03:09:24 -08:00
parent 2b9006762d
commit 037ccb09a2
4 changed files with 246 additions and 1 deletions

View File

@ -40,4 +40,31 @@ MmMemLibInternalCalculateMaximumSupportAddress (
DEBUG ((DEBUG_INFO, "mMmMemLibInternalMaximumSupportAddress = 0x%lx\n", mMmMemLibInternalMaximumSupportAddress)); DEBUG ((DEBUG_INFO, "mMmMemLibInternalMaximumSupportAddress = 0x%lx\n", mMmMemLibInternalMaximumSupportAddress));
} }
/**
Initialize cached Mmram Ranges from HOB.
@retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information.
@retval EFI_SUCCESS MmRanges are populated successfully.
**/
EFI_STATUS
MmMemLibInternalPopulateMmramRanges (
VOID
)
{
// Not implemented for AARCH64.
return EFI_SUCCESS;
}
/**
Deinitialize cached Mmram Ranges.
**/
VOID
MmMemLibInternalFreeMmramRanges (
VOID
)
{
// Not implemented for AARCH64.
}

View File

@ -37,6 +37,27 @@ MmMemLibInternalCalculateMaximumSupportAddress (
VOID VOID
); );
/**
Initialize cached Mmram Ranges from HOB.
@retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information.
@retval EFI_SUCCESS MmRanges are populated successfully.
**/
EFI_STATUS
MmMemLibInternalPopulateMmramRanges (
VOID
);
/**
Deinitialize cached Mmram Ranges.
**/
VOID
MmMemLibInternalFreeMmramRanges (
VOID
);
/** /**
This function check if the buffer is valid per processor architecture and not overlap with MMRAM. This function check if the buffer is valid per processor architecture and not overlap with MMRAM.
@ -253,11 +274,42 @@ MemLibConstructor (
IN EFI_MM_SYSTEM_TABLE *MmSystemTable IN EFI_MM_SYSTEM_TABLE *MmSystemTable
) )
{ {
EFI_STATUS Status;
// //
// Calculate and save maximum support address // Calculate and save maximum support address
// //
MmMemLibInternalCalculateMaximumSupportAddress (); MmMemLibInternalCalculateMaximumSupportAddress ();
//
// Initialize cached Mmram Ranges from HOB.
//
Status = MmMemLibInternalPopulateMmramRanges ();
return Status;
}
/**
Destructor for Mm Mem library.
@param ImageHandle The image handle of the process.
@param MmSystemTable The EFI System Table pointer.
@retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
**/
EFI_STATUS
EFIAPI
MemLibDestructor (
IN EFI_HANDLE ImageHandle,
IN EFI_MM_SYSTEM_TABLE *MmSystemTable
)
{
//
// Deinitialize cached Mmram Ranges.
//
MmMemLibInternalFreeMmramRanges ();
return EFI_SUCCESS; return EFI_SUCCESS;
} }

View File

@ -8,6 +8,7 @@
# #
# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR> # Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
# Copyright (c) Microsoft Corporation.
# #
# SPDX-License-Identifier: BSD-2-Clause-Patent # SPDX-License-Identifier: BSD-2-Clause-Patent
# #
@ -22,16 +23,20 @@
PI_SPECIFICATION_VERSION = 0x00010032 PI_SPECIFICATION_VERSION = 0x00010032
LIBRARY_CLASS = MemLib|MM_STANDALONE MM_CORE_STANDALONE LIBRARY_CLASS = MemLib|MM_STANDALONE MM_CORE_STANDALONE
CONSTRUCTOR = MemLibConstructor CONSTRUCTOR = MemLibConstructor
DESTRUCTOR = MemLibDestructor
# #
# The following information is for reference only and not required by the build tools. # The following information is for reference only and not required by the build tools.
# #
# VALID_ARCHITECTURES = AARCH64 # VALID_ARCHITECTURES = IA32 X64 AARCH64
# #
[Sources.Common] [Sources.Common]
StandaloneMmMemLib.c StandaloneMmMemLib.c
[Sources.IA32, Sources.X64]
X86StandaloneMmMemLibInternal.c
[Sources.AARCH64] [Sources.AARCH64]
AArch64/StandaloneMmMemLibInternal.c AArch64/StandaloneMmMemLibInternal.c
@ -42,3 +47,9 @@
[LibraryClasses] [LibraryClasses]
BaseMemoryLib BaseMemoryLib
DebugLib DebugLib
HobLib
MemoryAllocationLib
[Guids]
gMmCoreDataHobGuid ## SOMETIMES_CONSUMES ## HOB
gEfiMmPeiMmramMemoryReserveGuid ## SOMETIMES_CONSUMES ## HOB

View File

@ -0,0 +1,155 @@
/** @file
Internal ARCH Specific file of MM memory check library.
MM memory check library implementation. This library consumes MM_ACCESS_PROTOCOL
to get MMRAM information. In order to use this library instance, the platform should produce
all MMRAM range via MM_ACCESS_PROTOCOL, including the range for firmware (like MM Core
and MM driver) and/or specific dedicated hardware.
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiMm.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Guid/MmCoreData.h>
#include <Guid/MmramMemoryReserve.h>
//
// Maximum support address used to check input buffer
//
extern EFI_PHYSICAL_ADDRESS mMmMemLibInternalMaximumSupportAddress;
extern EFI_MMRAM_DESCRIPTOR *mMmMemLibInternalMmramRanges;
extern UINTN mMmMemLibInternalMmramCount;
/**
Calculate and save the maximum support address.
**/
VOID
MmMemLibInternalCalculateMaximumSupportAddress (
VOID
)
{
VOID *Hob;
UINT32 RegEax;
UINT8 PhysicalAddressBits;
//
// Get physical address bits supported.
//
Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
if (Hob != NULL) {
PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
} else {
AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
if (RegEax >= 0x80000008) {
AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
PhysicalAddressBits = (UINT8) RegEax;
} else {
PhysicalAddressBits = 36;
}
}
//
// IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
//
ASSERT (PhysicalAddressBits <= 52);
if (PhysicalAddressBits > 48) {
PhysicalAddressBits = 48;
}
//
// Save the maximum support address in one global variable
//
mMmMemLibInternalMaximumSupportAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, PhysicalAddressBits) - 1);
DEBUG ((DEBUG_INFO, "mMmMemLibInternalMaximumSupportAddress = 0x%lx\n", mMmMemLibInternalMaximumSupportAddress));
}
/**
Initialize cached Mmram Ranges from HOB.
@retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information.
@retval EFI_SUCCESS MmRanges are populated successfully.
**/
EFI_STATUS
MmMemLibInternalPopulateMmramRanges (
VOID
)
{
VOID *HobStart;
EFI_HOB_GUID_TYPE *GuidHob;
MM_CORE_DATA_HOB_DATA *DataInHob;
MM_CORE_PRIVATE_DATA *MmCorePrivateData;
EFI_HOB_GUID_TYPE *MmramRangesHob;
EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData;
EFI_MMRAM_DESCRIPTOR *MmramDescriptors;
HobStart = GetHobList ();
DEBUG ((DEBUG_INFO, "%a - 0x%x\n", __FUNCTION__, HobStart));
//
// Extract MM Core Private context from the Hob. If absent search for
// a Hob containing the MMRAM ranges
//
GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart);
if (GuidHob == NULL) {
MmramRangesHob = GetFirstGuidHob (&gEfiMmPeiMmramMemoryReserveGuid);
if (MmramRangesHob == NULL) {
return EFI_UNSUPPORTED;
}
MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob);
if (MmramRangesHobData == NULL || MmramRangesHobData->Descriptor == NULL) {
return EFI_UNSUPPORTED;
}
mMmMemLibInternalMmramCount = MmramRangesHobData->NumberOfMmReservedRegions;
MmramDescriptors = MmramRangesHobData->Descriptor;
} else {
DataInHob = GET_GUID_HOB_DATA (GuidHob);
if (DataInHob == NULL) {
return EFI_UNSUPPORTED;
}
MmCorePrivateData = (MM_CORE_PRIVATE_DATA *) (UINTN) DataInHob->Address;
if (MmCorePrivateData == NULL || MmCorePrivateData->MmramRanges == 0) {
return EFI_UNSUPPORTED;
}
mMmMemLibInternalMmramCount = (UINTN) MmCorePrivateData->MmramRangeCount;
MmramDescriptors = (EFI_MMRAM_DESCRIPTOR *) (UINTN) MmCorePrivateData->MmramRanges;
}
mMmMemLibInternalMmramRanges = AllocatePool (mMmMemLibInternalMmramCount * sizeof (EFI_MMRAM_DESCRIPTOR));
if (mMmMemLibInternalMmramRanges) {
CopyMem (mMmMemLibInternalMmramRanges,
MmramDescriptors,
mMmMemLibInternalMmramCount * sizeof (EFI_MMRAM_DESCRIPTOR));
}
return EFI_SUCCESS;
}
/**
Deinitialize cached Mmram Ranges.
**/
VOID
MmMemLibInternalFreeMmramRanges (
VOID
)
{
if (mMmMemLibInternalMmramRanges != NULL) {
FreePool (mMmMemLibInternalMmramRanges);
}
}