mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-08 17:05:09 +02:00
StandaloneMmPkg/MmIpl: Create memory resource HOBs
If PcdCpuSmmRestrictedMemoryAccess is TRUE, only unblocked memory Regions are available, if FALSE, all system memory is available. Signed-off-by: Hongbin1 Zhang <hongbin1.zhang@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Star Zeng <star.zeng@intel.com> Cc: Jiaxin Wu <jiaxin.wu@intel.com> Cc: Wei6 Xu <wei6.xu@intel.com> Cc: Sami Mujawar <sami.mujawar@arm.com> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Supreeth Venkatesh <supreeth.venkatesh@arm.com>
This commit is contained in:
parent
378aff173c
commit
6855567d52
@ -12,9 +12,15 @@
|
||||
#include <Guid/MmAcpiS3Enable.h>
|
||||
#include <Guid/MmCpuSyncConfig.h>
|
||||
#include <Guid/MmProfileData.h>
|
||||
#include <Guid/MmUnblockRegion.h>
|
||||
#include <Register/Intel/Cpuid.h>
|
||||
#include <Register/Intel/ArchitecturalMsr.h>
|
||||
|
||||
typedef struct {
|
||||
EFI_PHYSICAL_ADDRESS Base;
|
||||
UINT64 Length;
|
||||
} MM_IPL_MEMORY_REGION;
|
||||
|
||||
/**
|
||||
Add a new HOB to the HOB List.
|
||||
|
||||
@ -401,6 +407,275 @@ MmIplBuildMmProfileHobs (
|
||||
*HobBufferSize = HobLength;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Build resource Hobs from unblocked memory regions
|
||||
|
||||
This function builds resource HOBs for all unblocked memory regions.
|
||||
|
||||
@param[in] HobBuffer The pointer of new HOB buffer.
|
||||
@param[in, out] HobBufferSize The total size of the same GUID HOBs when as output.
|
||||
|
||||
**/
|
||||
VOID
|
||||
MmIplBuildResourceHobForUnblockedRegion (
|
||||
IN UINT8 *HobBuffer,
|
||||
IN OUT UINTN *HobBufferSize
|
||||
)
|
||||
{
|
||||
MM_UNBLOCK_REGION *UnblockRegion;
|
||||
EFI_HOB_GENERIC_HEADER *GuidHob;
|
||||
UINTN UsedSize;
|
||||
|
||||
UsedSize = 0;
|
||||
|
||||
GuidHob = GetFirstGuidHob (&gMmUnblockRegionHobGuid);
|
||||
while (GuidHob != NULL) {
|
||||
if (*HobBufferSize >= UsedSize + sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) {
|
||||
UnblockRegion = GET_GUID_HOB_DATA (GuidHob);
|
||||
MmIplBuildMemoryResourceHob (
|
||||
(EFI_HOB_RESOURCE_DESCRIPTOR *)(HobBuffer + UsedSize),
|
||||
EFI_RESOURCE_SYSTEM_MEMORY,
|
||||
0,
|
||||
UnblockRegion->PhysicalStart,
|
||||
EFI_PAGES_TO_SIZE (UnblockRegion->NumberOfPages),
|
||||
&UnblockRegion->IdentifierGuid
|
||||
);
|
||||
}
|
||||
|
||||
UsedSize += sizeof (EFI_HOB_RESOURCE_DESCRIPTOR);
|
||||
GuidHob = GetNextGuidHob (&gMmUnblockRegionHobGuid, GET_NEXT_HOB (GuidHob));
|
||||
}
|
||||
|
||||
*HobBufferSize = UsedSize;
|
||||
}
|
||||
|
||||
/**
|
||||
Create MMIO memory map according to platform HOB.
|
||||
|
||||
@param[in] PlatformHobList Platform HOB list.
|
||||
@param[in] PlatformHobSize Platform HOB size.
|
||||
@param[in, out] MemoryRegion Memory regions.
|
||||
@param[in, out] MemoryRegionCount Count of MMIO regions
|
||||
**/
|
||||
VOID
|
||||
CollectPlatformMemoryRegions (
|
||||
IN UINT8 *PlatformHobList,
|
||||
IN UINTN PlatformHobSize,
|
||||
IN OUT MM_IPL_MEMORY_REGION *MemoryRegion,
|
||||
IN OUT UINTN *MemoryRegionCount
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
EFI_PEI_HOB_POINTERS Hob;
|
||||
|
||||
ASSERT (MemoryRegionCount != NULL);
|
||||
ASSERT (*MemoryRegionCount == 0 || MemoryRegion != NULL);
|
||||
|
||||
Index = 0;
|
||||
//
|
||||
// Get the HOB list for processing
|
||||
//
|
||||
Hob.Raw = PlatformHobList;
|
||||
|
||||
//
|
||||
// Collect memory ranges
|
||||
//
|
||||
while (Hob.Raw < PlatformHobList + PlatformHobSize) {
|
||||
if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
|
||||
if ( (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_MAPPED_IO)
|
||||
|| (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)
|
||||
|| (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_FIRMWARE_DEVICE)
|
||||
|| (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED))
|
||||
{
|
||||
if (Index < *MemoryRegionCount) {
|
||||
MemoryRegion[Index].Base = Hob.ResourceDescriptor->PhysicalStart;
|
||||
MemoryRegion[Index].Length = Hob.ResourceDescriptor->ResourceLength;
|
||||
}
|
||||
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
|
||||
Hob.Raw = GET_NEXT_HOB (Hob);
|
||||
}
|
||||
|
||||
*MemoryRegionCount = Index;
|
||||
}
|
||||
|
||||
/**
|
||||
Function to compare 2 MM_IPL_MEMORY_REGION pointer based on Base.
|
||||
|
||||
@param[in] Buffer1 pointer to MM_IPL_MEMORY_REGION pointer to compare
|
||||
@param[in] Buffer2 pointer to second MM_IPL_MEMORY_REGION pointer to compare
|
||||
|
||||
@retval 0 Buffer1 equal to Buffer2
|
||||
@retval <0 Buffer1 is less than Buffer2
|
||||
@retval >0 Buffer1 is greater than Buffer2
|
||||
**/
|
||||
INTN
|
||||
EFIAPI
|
||||
MemoryRegionBaseAddressCompare (
|
||||
IN CONST VOID *Buffer1,
|
||||
IN CONST VOID *Buffer2
|
||||
)
|
||||
{
|
||||
if (((MM_IPL_MEMORY_REGION *)Buffer1)->Base > ((MM_IPL_MEMORY_REGION *)Buffer2)->Base) {
|
||||
return 1;
|
||||
} else if (((MM_IPL_MEMORY_REGION *)Buffer1)->Base < ((MM_IPL_MEMORY_REGION *)Buffer2)->Base) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Calculate the maximum support address.
|
||||
|
||||
@return the maximum support address.
|
||||
**/
|
||||
UINT8
|
||||
MmIplCalculateMaximumSupportAddress (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT32 RegEax;
|
||||
UINT8 PhysicalAddressBits;
|
||||
VOID *Hob;
|
||||
|
||||
//
|
||||
// Get physical address bits supported.
|
||||
//
|
||||
Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
|
||||
if (Hob != NULL) {
|
||||
PhysicalAddressBits = ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace;
|
||||
} else {
|
||||
AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
|
||||
if (RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {
|
||||
AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL);
|
||||
PhysicalAddressBits = (UINT8)RegEax;
|
||||
} else {
|
||||
PhysicalAddressBits = 36;
|
||||
}
|
||||
}
|
||||
|
||||
return PhysicalAddressBits;
|
||||
}
|
||||
|
||||
/**
|
||||
Build resource HOB to cover [0, PhysicalAddressBits length] by excluding
|
||||
all Mmram ranges, MM Profile data and MMIO ranges.
|
||||
|
||||
@param[in] HobBuffer The pointer of new HOB buffer.
|
||||
@param[in, out] HobBufferSize The available size of the HOB buffer when as input.
|
||||
The used size of when as output.
|
||||
@param[in] PlatformHobList Platform HOB list.
|
||||
@param[in] PlatformHobSize Platform HOB size.
|
||||
@param[in] Block Pointer of MMRAM descriptor block.
|
||||
@param[in] MmProfileDataHob Pointer to MM profile data HOB.
|
||||
|
||||
**/
|
||||
VOID
|
||||
MmIplBuildResourceHobForAllSystemMemory (
|
||||
IN UINT8 *HobBuffer,
|
||||
IN OUT UINTN *HobBufferSize,
|
||||
IN VOID *PlatformHobList,
|
||||
IN UINTN PlatformHobSize,
|
||||
IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block,
|
||||
IN EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINTN Count;
|
||||
UINTN PlatformRegionCount;
|
||||
UINTN UsedSize;
|
||||
UINT64 PreviousAddress;
|
||||
UINT64 MaxAddress;
|
||||
MM_IPL_MEMORY_REGION *MemoryRegions;
|
||||
MM_IPL_MEMORY_REGION SortBuffer;
|
||||
|
||||
MaxAddress = LShiftU64 (1, MmIplCalculateMaximumSupportAddress ());
|
||||
|
||||
//
|
||||
// Get the count of platform memory regions
|
||||
//
|
||||
PlatformRegionCount = 0;
|
||||
if ((PlatformHobList != NULL) && (PlatformHobSize != 0)) {
|
||||
CollectPlatformMemoryRegions (PlatformHobList, PlatformHobSize, NULL, &PlatformRegionCount);
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate buffer for platform memory regions, MM Profile data, MMRam ranges, an extra terminator.
|
||||
//
|
||||
Count = PlatformRegionCount + Block->NumberOfMmReservedRegions + ((MmProfileDataHob != NULL) ? 1 : 0) + 1;
|
||||
MemoryRegions = AllocatePages (EFI_SIZE_TO_PAGES (Count * sizeof (*MemoryRegions)));
|
||||
ASSERT (MemoryRegions != NULL);
|
||||
if (MemoryRegions == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "%a:%d - No enough memory\n", __func__, __LINE__));
|
||||
CpuDeadLoop ();
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// The very last region is the terminator
|
||||
//
|
||||
MemoryRegions[Count - 1].Base = MaxAddress;
|
||||
MemoryRegions[Count - 1].Length = 0;
|
||||
|
||||
//
|
||||
// Collect platform memory regions
|
||||
//
|
||||
if (PlatformRegionCount != 0) {
|
||||
CollectPlatformMemoryRegions (PlatformHobList, PlatformHobSize, MemoryRegions, &PlatformRegionCount);
|
||||
}
|
||||
|
||||
//
|
||||
// Collect SMRAM regions
|
||||
//
|
||||
for (Index = 0; Index < Block->NumberOfMmReservedRegions; Index++) {
|
||||
MemoryRegions[PlatformRegionCount + Index].Base = Block->Descriptor[Index].CpuStart;
|
||||
MemoryRegions[PlatformRegionCount + Index].Length = Block->Descriptor[Index].PhysicalSize;
|
||||
}
|
||||
|
||||
//
|
||||
// Collect MM profile database region
|
||||
//
|
||||
if (MmProfileDataHob != NULL) {
|
||||
MemoryRegions[PlatformRegionCount + Block->NumberOfMmReservedRegions].Base = MmProfileDataHob->AllocDescriptor.MemoryBaseAddress;
|
||||
MemoryRegions[PlatformRegionCount + Block->NumberOfMmReservedRegions].Length = MmProfileDataHob->AllocDescriptor.MemoryLength;
|
||||
}
|
||||
|
||||
//
|
||||
// Build system memory resource HOBs excluding platform memory regions, SMRAM regions, MmProfile database.
|
||||
//
|
||||
QuickSort (MemoryRegions, Count, sizeof (*MemoryRegions), MemoryRegionBaseAddressCompare, &SortBuffer);
|
||||
UsedSize = 0;
|
||||
PreviousAddress = 0;
|
||||
for (Index = 0; Index < Count; Index++) {
|
||||
ASSERT (MaxAddress >= MemoryRegions[Index].Base + MemoryRegions[Index].Length);
|
||||
|
||||
if (MemoryRegions[Index].Base > PreviousAddress) {
|
||||
if (*HobBufferSize >= UsedSize + sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) {
|
||||
MmIplBuildMemoryResourceHob (
|
||||
(EFI_HOB_RESOURCE_DESCRIPTOR *)(HobBuffer + UsedSize),
|
||||
EFI_RESOURCE_SYSTEM_MEMORY,
|
||||
FeaturePcdGet (PcdCpuSmmProfileEnable) ? MM_RESOURCE_ATTRIBUTE_LOGGING : 0,
|
||||
PreviousAddress,
|
||||
MemoryRegions[Index].Base - PreviousAddress,
|
||||
&gEfiCallerIdGuid
|
||||
);
|
||||
}
|
||||
|
||||
UsedSize += sizeof (EFI_HOB_RESOURCE_DESCRIPTOR);
|
||||
}
|
||||
|
||||
PreviousAddress = MemoryRegions[Index].Base + MemoryRegions[Index].Length;
|
||||
}
|
||||
|
||||
*HobBufferSize = UsedSize;
|
||||
FreePages (MemoryRegions, EFI_SIZE_TO_PAGES (Count * sizeof (EFI_MEMORY_DESCRIPTOR)));
|
||||
}
|
||||
|
||||
/**
|
||||
Get remaining size for building HOBs.
|
||||
|
||||
@ -439,6 +714,7 @@ GetRemainingHobSize (
|
||||
@param[in] MmCoreImageAddress Image address of MM core dirver.
|
||||
@param[in] MmCoreImageSize Image size of MM core dirver.
|
||||
@param[in] MmCoreEntryPoint Entry pinter of MM core dirver.
|
||||
@param[in] MmProfileDataHob Pointer to Mm profile data HOB.
|
||||
@param[in] Block Pointer of MMRAM descriptor block.
|
||||
|
||||
@retval RETURN_BUFFER_TOO_SMALL The buffer is too small for HOB creation.
|
||||
@ -460,6 +736,7 @@ CreateMmFoundationHobList (
|
||||
IN EFI_PHYSICAL_ADDRESS MmCoreImageAddress,
|
||||
IN UINT64 MmCoreImageSize,
|
||||
IN EFI_PHYSICAL_ADDRESS MmCoreEntryPoint,
|
||||
IN EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob,
|
||||
IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block
|
||||
)
|
||||
{
|
||||
@ -474,6 +751,16 @@ CreateMmFoundationHobList (
|
||||
((*FoundationHobSize == 0) && (FoundationHobList == NULL))
|
||||
);
|
||||
|
||||
if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
|
||||
//
|
||||
// When SmmProfile is enabled, all DRAM is accessible from SMM drivers' perspective.
|
||||
// However, underline Cpu SMM driver does not map the DRAM so that every access to it triggers #PF.
|
||||
// #PF handler records the access then sets up the mapping in the page table to allow the temporary access by current instruction.
|
||||
// The mapping is revoked before next instruction runs.
|
||||
//
|
||||
ASSERT (!PcdGetBool (PcdCpuSmmRestrictedMemoryAccess));
|
||||
}
|
||||
|
||||
UsedSize = 0;
|
||||
|
||||
//
|
||||
@ -556,6 +843,24 @@ CreateMmFoundationHobList (
|
||||
UsedSize += HobLength;
|
||||
}
|
||||
|
||||
HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
|
||||
if (PcdGetBool (PcdCpuSmmRestrictedMemoryAccess)) {
|
||||
//
|
||||
// Only unblocked memory regions are accessible
|
||||
//
|
||||
MmIplBuildResourceHobForUnblockedRegion (FoundationHobList + UsedSize, &HobLength);
|
||||
} else {
|
||||
//
|
||||
// All system memory (DRAM) is accessible.
|
||||
// When SMM Profile is enabled:
|
||||
// * Access to regions reported from MmPlatformHobProducerLib do not require logging.
|
||||
// * Access to other system memory requires logging.
|
||||
//
|
||||
MmIplBuildResourceHobForAllSystemMemory (FoundationHobList + UsedSize, &HobLength, PlatformHobList, PlatformHobSize, Block, MmProfileDataHob);
|
||||
}
|
||||
|
||||
UsedSize += HobLength;
|
||||
|
||||
if (*FoundationHobSize < UsedSize) {
|
||||
Status = RETURN_BUFFER_TOO_SMALL;
|
||||
} else {
|
||||
|
@ -294,6 +294,7 @@ CreatMmHobList (
|
||||
MmCoreImageAddress,
|
||||
MmCoreImageSize,
|
||||
MmCoreEntryPoint,
|
||||
MmProfileDataHob,
|
||||
Block
|
||||
);
|
||||
FreePages (PlatformHobList, EFI_SIZE_TO_PAGES (PlatformHobSize));
|
||||
@ -331,6 +332,7 @@ CreatMmHobList (
|
||||
MmCoreImageAddress,
|
||||
MmCoreImageSize,
|
||||
MmCoreEntryPoint,
|
||||
MmProfileDataHob,
|
||||
Block
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
@ -102,6 +102,7 @@ MmIplCreateHob (
|
||||
@param[in] MmCoreImageAddress Image address of MM core dirver.
|
||||
@param[in] MmCoreImageSize Image size of MM core dirver.
|
||||
@param[in] MmCoreEntryPoint Entry pinter of MM core dirver.
|
||||
@param[in] MmProfileDataHob Pointer to MM profile data HOB.
|
||||
@param[in] Block Pointer of MMRAM descriptor block.
|
||||
|
||||
@retval RETURN_BUFFER_TOO_SMALL The buffer is too small for HOB creation.
|
||||
@ -123,6 +124,7 @@ CreateMmFoundationHobList (
|
||||
IN EFI_PHYSICAL_ADDRESS MmCoreImageAddress,
|
||||
IN UINT64 MmCoreImageSize,
|
||||
IN EFI_PHYSICAL_ADDRESS MmCoreEntryPoint,
|
||||
IN EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob,
|
||||
IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block
|
||||
);
|
||||
|
||||
|
@ -55,6 +55,7 @@
|
||||
gMmAcpiS3EnableHobGuid
|
||||
gMmCpuSyncConfigHobGuid
|
||||
gMmProfileDataHobGuid
|
||||
gMmUnblockRegionHobGuid
|
||||
|
||||
[Ppis]
|
||||
gEfiPeiMmControlPpiGuid
|
||||
@ -73,5 +74,8 @@
|
||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileEnable ## CONSUMES
|
||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## CONSUMES
|
||||
|
||||
[Pcd.X64]
|
||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmRestrictedMemoryAccess ## CONSUMES
|
||||
|
||||
[Depex]
|
||||
gEfiPeiMmControlPpiGuid AND gEfiPeiMpServicesPpiGuid
|
||||
|
Loading…
x
Reference in New Issue
Block a user