mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-31 01:24:12 +02:00
This commit is to check if the resource HOB range does not exceed the max supported physical address. The function BuildMemoryMapFromResDescHobs is to build Memory Region from resource HOBs. Then the memory maps will be used during creating or modifying SMM page table. If the resource HOB range exceeds the max supported physical address, then subsequent calling of PageTableMap() will fail. Signed-off-by: Dun Tan <dun.tan@intel.com>
225 lines
6.5 KiB
C
225 lines
6.5 KiB
C
/** @file
|
|
|
|
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include "PiSmmCpuCommon.h"
|
|
|
|
/**
|
|
Get SmmProfileData.
|
|
|
|
@param[in, out] Size Return Size of SmmProfileData.
|
|
0 means the gMmProfileDataHobGuid does not exist.
|
|
|
|
@return Address of SmmProfileData
|
|
|
|
**/
|
|
EFI_PHYSICAL_ADDRESS
|
|
GetSmmProfileData (
|
|
IN OUT UINT64 *Size
|
|
)
|
|
{
|
|
EFI_PEI_HOB_POINTERS SmmProfileDataHob;
|
|
|
|
ASSERT (Size != NULL);
|
|
|
|
//
|
|
// Get Smm Profile Base from Memory Allocation HOB
|
|
//
|
|
SmmProfileDataHob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
|
|
while (SmmProfileDataHob.Raw != NULL) {
|
|
//
|
|
// Find gMmProfileDataHobGuid
|
|
//
|
|
if (CompareGuid (&SmmProfileDataHob.MemoryAllocation->AllocDescriptor.Name, &gMmProfileDataHobGuid)) {
|
|
break;
|
|
}
|
|
|
|
SmmProfileDataHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (SmmProfileDataHob));
|
|
}
|
|
|
|
if (SmmProfileDataHob.Raw == NULL) {
|
|
*Size = 0;
|
|
return 0;
|
|
}
|
|
|
|
*Size = SmmProfileDataHob.MemoryAllocation->AllocDescriptor.MemoryLength;
|
|
|
|
return SmmProfileDataHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress;
|
|
}
|
|
|
|
/**
|
|
Return if the Address is the NonMmram logging Address.
|
|
|
|
@param[in] Address the address to be checked
|
|
|
|
@return TRUE The address is the NonMmram logging Address.
|
|
@return FALSE The address is not the NonMmram logging Address.
|
|
**/
|
|
BOOLEAN
|
|
IsNonMmramLoggingAddress (
|
|
IN UINT64 Address
|
|
)
|
|
{
|
|
EFI_PEI_HOB_POINTERS Hob;
|
|
|
|
Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
|
|
while (Hob.Raw != NULL) {
|
|
if ((Address >= Hob.ResourceDescriptor->PhysicalStart) && (Address < Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength)) {
|
|
if ((Hob.ResourceDescriptor->ResourceAttribute & MM_RESOURCE_ATTRIBUTE_LOGGING) != 0) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
Hob.Raw = GET_NEXT_HOB (Hob);
|
|
Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
Return if the Address is forbidden as SMM communication buffer.
|
|
|
|
@param[in] Address the address to be checked
|
|
|
|
@return TRUE The address is forbidden as SMM communication buffer.
|
|
@return FALSE The address is allowed as SMM communication buffer.
|
|
**/
|
|
BOOLEAN
|
|
IsSmmCommBufferForbiddenAddress (
|
|
IN UINT64 Address
|
|
)
|
|
{
|
|
EFI_PEI_HOB_POINTERS Hob;
|
|
|
|
Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
|
|
while (Hob.Raw != NULL) {
|
|
if ((Address >= Hob.ResourceDescriptor->PhysicalStart) && (Address < Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength)) {
|
|
return FALSE;
|
|
}
|
|
|
|
Hob.Raw = GET_NEXT_HOB (Hob);
|
|
Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
Build Memory Region from ResourceDescriptor HOBs by excluding Logging attribute range.
|
|
|
|
@param[out] MemoryRegion Returned Non-Mmram Memory regions.
|
|
@param[out] MemoryRegionCount A pointer to the number of Memory regions.
|
|
**/
|
|
VOID
|
|
BuildMemoryMapFromResDescHobs (
|
|
OUT MM_CPU_MEMORY_REGION **MemoryRegion,
|
|
OUT UINTN *MemoryRegionCount
|
|
)
|
|
{
|
|
EFI_PEI_HOB_POINTERS Hob;
|
|
UINTN Count;
|
|
UINTN Index;
|
|
EFI_PHYSICAL_ADDRESS MaxPhysicalAddress;
|
|
EFI_PHYSICAL_ADDRESS ResourceHobEnd;
|
|
|
|
ASSERT (MemoryRegion != NULL && MemoryRegionCount != NULL);
|
|
|
|
*MemoryRegion = NULL;
|
|
*MemoryRegionCount = 0;
|
|
MaxPhysicalAddress = LShiftU64 (1, mPhysicalAddressBits);
|
|
|
|
//
|
|
// Get the count.
|
|
//
|
|
Count = 0;
|
|
Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
|
|
while (Hob.Raw != NULL) {
|
|
if ((Hob.ResourceDescriptor->ResourceAttribute & MM_RESOURCE_ATTRIBUTE_LOGGING) == 0) {
|
|
ResourceHobEnd = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength;
|
|
|
|
ASSERT (ResourceHobEnd <= MaxPhysicalAddress);
|
|
if (ResourceHobEnd > MaxPhysicalAddress) {
|
|
CpuDeadLoop ();
|
|
}
|
|
|
|
//
|
|
// Resource HOBs describe all accessible non-smram regions.
|
|
// Logging attribute range is treated as not present. Not-present ranges are not included in this memory map.
|
|
//
|
|
Count++;
|
|
}
|
|
|
|
Hob.Raw = GET_NEXT_HOB (Hob);
|
|
Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
|
|
}
|
|
|
|
*MemoryRegionCount = Count;
|
|
|
|
*MemoryRegion = (MM_CPU_MEMORY_REGION *)AllocateZeroPool (sizeof (MM_CPU_MEMORY_REGION) * Count);
|
|
ASSERT (*MemoryRegion != NULL);
|
|
|
|
Index = 0;
|
|
Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
|
|
while (Hob.Raw != NULL) {
|
|
if ((Hob.ResourceDescriptor->ResourceAttribute & MM_RESOURCE_ATTRIBUTE_LOGGING) == 0) {
|
|
ASSERT (Index < Count);
|
|
(*MemoryRegion)[Index].Base = Hob.ResourceDescriptor->PhysicalStart;
|
|
(*MemoryRegion)[Index].Length = Hob.ResourceDescriptor->ResourceLength;
|
|
(*MemoryRegion)[Index].Attribute = EFI_MEMORY_XP;
|
|
if (Hob.ResourceDescriptor->ResourceAttribute == EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED) {
|
|
(*MemoryRegion)[Index].Attribute |= EFI_MEMORY_RO;
|
|
}
|
|
|
|
Index++;
|
|
}
|
|
|
|
Hob.Raw = GET_NEXT_HOB (Hob);
|
|
Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
Build extended protection MemoryRegion.
|
|
|
|
The caller is responsible for freeing MemoryRegion via FreePool().
|
|
|
|
@param[out] MemoryRegion Returned Non-Mmram Memory regions.
|
|
@param[out] MemoryRegionCount A pointer to the number of Memory regions.
|
|
**/
|
|
VOID
|
|
CreateExtendedProtectionRange (
|
|
OUT MM_CPU_MEMORY_REGION **MemoryRegion,
|
|
OUT UINTN *MemoryRegionCount
|
|
)
|
|
{
|
|
BuildMemoryMapFromResDescHobs (MemoryRegion, MemoryRegionCount);
|
|
}
|
|
|
|
/**
|
|
Create the Non-Mmram Memory Region within the ResourceDescriptor HOBs
|
|
without Logging attribute.
|
|
|
|
The caller is responsible for freeing MemoryRegion via FreePool().
|
|
|
|
@param[in] PhysicalAddressBits The bits of physical address to map.
|
|
@param[out] MemoryRegion Returned Non-Mmram Memory regions.
|
|
@param[out] MemoryRegionCount A pointer to the number of Memory regions.
|
|
**/
|
|
VOID
|
|
CreateNonMmramMemMap (
|
|
IN UINT8 PhysicalAddressBits,
|
|
OUT MM_CPU_MEMORY_REGION **MemoryRegion,
|
|
OUT UINTN *MemoryRegionCount
|
|
)
|
|
{
|
|
BuildMemoryMapFromResDescHobs (MemoryRegion, MemoryRegionCount);
|
|
}
|