mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-31 01:24:12 +02:00
Adds X64 support to the SRAT table generator library. Adds EX64ObjLocalApicX2ApicAffinity CM object to get platform configuration information. Update the parser with newly added CM object. Cc: Sami Mujawar <Sami.Mujawar@arm.com> Cc: Pierre Gondois <pierre.gondois@arm.com> Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
237 lines
8.8 KiB
C
237 lines
8.8 KiB
C
/** @file
|
|
X64 SRAT Table Generator
|
|
|
|
Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.
|
|
Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved.
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
@par Reference(s):
|
|
- ACPI 6.3 Specification, January 2019
|
|
|
|
@par Glossary:
|
|
- Cm or CM - Configuration Manager
|
|
- Obj or OBJ - Object
|
|
**/
|
|
|
|
#include <Library/AcpiLib.h>
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Protocol/AcpiTable.h>
|
|
|
|
// Module specific include files.
|
|
#include <AcpiTableGenerator.h>
|
|
#include <ConfigurationManagerObject.h>
|
|
#include <ConfigurationManagerHelper.h>
|
|
#include <Library/TableHelperLib.h>
|
|
#include <Protocol/ConfigurationManagerProtocol.h>
|
|
|
|
#include "SratGenerator.h"
|
|
|
|
/**
|
|
This macro is used to get the object information for the Local APIC X2APIC
|
|
Affinity object.
|
|
*/
|
|
GET_OBJECT_LIST (
|
|
EObjNameSpaceX64,
|
|
EX64ObjLocalApicX2ApicAffinityInfo,
|
|
CM_X64_LOCAL_APIC_X2APIC_AFFINITY_INFO
|
|
);
|
|
|
|
/** Enum of the X64 specific CM objects required to
|
|
build the arch specific information of the SRAT table.
|
|
*/
|
|
typedef enum X64SratSubTableType {
|
|
EX64LocalApicX2ApicAffinityTableType,
|
|
EX64SubTableTypeMax
|
|
} EX64_SRAT_SUB_TABLE_TYPE;
|
|
|
|
typedef struct SratSubTable {
|
|
/// Start offset of the arch specific sub-table.
|
|
UINT32 Offset;
|
|
|
|
/// Count
|
|
UINT32 Count;
|
|
|
|
/// Array of CmInfo objects of the relevant type.
|
|
VOID *CmInfo;
|
|
} SRAT_SUB_TABLE;
|
|
|
|
STATIC SRAT_SUB_TABLE mSratSubTable[EX64SubTableTypeMax];
|
|
|
|
/** Reserve arch sub-tables space.
|
|
|
|
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
|
|
@param [in, out] ArchOffset On input, contains the offset where arch specific
|
|
sub-tables can be written. It is expected that
|
|
there enough space to write all the arch specific
|
|
sub-tables from this offset onward.
|
|
On ouput, contains the ending offset of the arch
|
|
specific sub-tables.
|
|
|
|
@retval EFI_SUCCESS Table generated successfully.
|
|
@retval EFI_UNSUPPORTED Not supported.
|
|
@retval EFI_INVALID_PARAMETER A parameter is invalid.
|
|
@retval EFI_NOT_FOUND The required object information is not found.
|
|
@retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
|
|
Manager is less than the Object size for the
|
|
requested object.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ArchReserveOffsets (
|
|
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
|
|
IN OUT UINT32 *ArchOffset
|
|
)
|
|
{
|
|
CM_X64_LOCAL_APIC_X2APIC_AFFINITY_INFO *CmX2ApicAffinity;
|
|
EFI_STATUS Status;
|
|
LOCAL_APIC_MODE ApicMode;
|
|
UINT32 CmCount;
|
|
UINT32 Index;
|
|
|
|
ASSERT (CfgMgrProtocol != NULL);
|
|
ASSERT (ArchOffset != NULL);
|
|
|
|
Status = GetEX64ObjLocalApicX2ApicAffinityInfo (
|
|
CfgMgrProtocol,
|
|
CM_NULL_TOKEN,
|
|
&CmX2ApicAffinity,
|
|
&CmCount
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((
|
|
DEBUG_ERROR,
|
|
"ERROR: SRAT: Failed to get Local Apic/X2Apic Affinity Info. Status = %r\n",
|
|
Status
|
|
));
|
|
return Status;
|
|
}
|
|
|
|
if (CmCount == 0) {
|
|
DEBUG ((
|
|
DEBUG_ERROR,
|
|
"ERROR: SRAT: Local Apic/X2Apic Affinity information not provided.\n"
|
|
));
|
|
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
ApicMode = CmX2ApicAffinity[0].ApicMode;
|
|
for (Index = 0; Index < CmCount; Index++) {
|
|
if ((CmX2ApicAffinity[Index].Flags &
|
|
~EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED) != 0)
|
|
{
|
|
DEBUG ((
|
|
DEBUG_ERROR,
|
|
"ERROR: SRAT: Invalid Flags. Flags = 0x%x\n",
|
|
CmX2ApicAffinity[Index].Flags
|
|
));
|
|
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (CmX2ApicAffinity[Index].ApicMode == LocalApicModeXApic) {
|
|
if (CmX2ApicAffinity[Index].ApicId > MAX_UINT8) {
|
|
DEBUG ((
|
|
DEBUG_ERROR,
|
|
"ERROR: SRAT: Local Apic Id is invalid. ApicId = 0x%x\n",
|
|
CmX2ApicAffinity[Index].ApicId
|
|
));
|
|
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
|
|
if (CmX2ApicAffinity[Index].ApicMode != ApicMode) {
|
|
DEBUG ((
|
|
DEBUG_ERROR,
|
|
"ERROR: SRAT: Mixed Apic Modes are not supported.\n"
|
|
));
|
|
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
|
|
mSratSubTable[EX64LocalApicX2ApicAffinityTableType].CmInfo = CmX2ApicAffinity;
|
|
mSratSubTable[EX64LocalApicX2ApicAffinityTableType].Count = CmCount;
|
|
mSratSubTable[EX64LocalApicX2ApicAffinityTableType].Offset = *ArchOffset;
|
|
|
|
if (CmX2ApicAffinity[0].ApicMode == LocalApicModeX2Apic) {
|
|
*ArchOffset += sizeof (EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE) * CmCount;
|
|
} else {
|
|
*ArchOffset += sizeof (EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE) * CmCount;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/** Add the arch specific sub-tables to the SRAT table.
|
|
|
|
These sub-tables are written in the space reserved beforehand.
|
|
|
|
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
|
|
Protocol Interface.
|
|
@param [in] Srat Pointer to the SRAT Table.
|
|
|
|
@retval EFI_SUCCESS Table generated successfully.
|
|
@retval EFI_UNSUPPORTED Not supported.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
AddArchObjects (
|
|
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
|
|
IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat
|
|
)
|
|
{
|
|
CM_X64_LOCAL_APIC_X2APIC_AFFINITY_INFO *CmX2ApicAffinity;
|
|
EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE *ApicAffinity;
|
|
EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE *X2ApicAffinity;
|
|
|
|
CmX2ApicAffinity = (CM_X64_LOCAL_APIC_X2APIC_AFFINITY_INFO *)
|
|
mSratSubTable[EX64LocalApicX2ApicAffinityTableType].CmInfo;
|
|
|
|
if (CmX2ApicAffinity->ApicMode == LocalApicModeX2Apic) {
|
|
X2ApicAffinity = (EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE *)
|
|
((UINT8 *)Srat +
|
|
mSratSubTable[EX64LocalApicX2ApicAffinityTableType].Offset);
|
|
while (mSratSubTable[EX64LocalApicX2ApicAffinityTableType].Count-- != 0) {
|
|
X2ApicAffinity->Type = EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC_AFFINITY;
|
|
X2ApicAffinity->Length = sizeof (EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE);
|
|
X2ApicAffinity->Reserved1[0] = EFI_ACPI_RESERVED_BYTE;
|
|
X2ApicAffinity->Reserved1[1] = EFI_ACPI_RESERVED_BYTE;
|
|
X2ApicAffinity->ProximityDomain = CmX2ApicAffinity->ProximityDomain;
|
|
X2ApicAffinity->X2ApicId = CmX2ApicAffinity->ApicId;
|
|
X2ApicAffinity->Flags = CmX2ApicAffinity->Flags;
|
|
X2ApicAffinity->ClockDomain = CmX2ApicAffinity->ClockDomain;
|
|
X2ApicAffinity->Reserved2[0] = EFI_ACPI_RESERVED_BYTE;
|
|
X2ApicAffinity->Reserved2[1] = EFI_ACPI_RESERVED_BYTE;
|
|
X2ApicAffinity->Reserved2[2] = EFI_ACPI_RESERVED_BYTE;
|
|
X2ApicAffinity->Reserved2[3] = EFI_ACPI_RESERVED_BYTE;
|
|
X2ApicAffinity++;
|
|
// Next
|
|
CmX2ApicAffinity++;
|
|
}
|
|
} else {
|
|
ApicAffinity = (EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE *)
|
|
((UINT8 *)Srat +
|
|
mSratSubTable[EX64LocalApicX2ApicAffinityTableType].Offset);
|
|
while (mSratSubTable[EX64LocalApicX2ApicAffinityTableType].Count-- != 0) {
|
|
ApicAffinity->Type = EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY;
|
|
ApicAffinity->Length = sizeof (EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE);
|
|
ApicAffinity->ProximityDomain7To0 = (CmX2ApicAffinity->ProximityDomain & MAX_UINT8);
|
|
ApicAffinity->ApicId = CmX2ApicAffinity->ApicId & MAX_UINT8;
|
|
ApicAffinity->Flags = CmX2ApicAffinity->Flags;
|
|
ApicAffinity->LocalSapicEid = 0;
|
|
ApicAffinity->ProximityDomain31To8[0] = (CmX2ApicAffinity->ProximityDomain >> 8) & MAX_UINT8;
|
|
ApicAffinity->ProximityDomain31To8[0] = (CmX2ApicAffinity->ProximityDomain >> 16) & MAX_UINT8;
|
|
ApicAffinity->ProximityDomain31To8[0] = (CmX2ApicAffinity->ProximityDomain >> 24) & MAX_UINT8;
|
|
ApicAffinity->ClockDomain = CmX2ApicAffinity->ClockDomain;
|
|
ApicAffinity++;
|
|
CmX2ApicAffinity++;
|
|
} // while
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|