mirror of
https://github.com/tianocore/edk2
synced 2026-08-27 00:23:19 -04:00
Merge 4639733287 into fb2ac429de
This commit is contained in:
commit
8808fdae75
24 changed files with 5719 additions and 132 deletions
|
|
@ -117,6 +117,7 @@
|
||||||
"gerror",
|
"gerror",
|
||||||
"invoc",
|
"invoc",
|
||||||
"ITARGETSR",
|
"ITARGETSR",
|
||||||
|
"iwbdevicetabletemplate",
|
||||||
"GTBLOCK",
|
"GTBLOCK",
|
||||||
"lgreater",
|
"lgreater",
|
||||||
"lless",
|
"lless",
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
|
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
|
||||||
|
|
||||||
[LibraryClasses.AARCH64]
|
[LibraryClasses.AARCH64]
|
||||||
|
ArmLib|MdePkg/Library/ArmLib/ArmBaseLib.inf
|
||||||
PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
|
PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
|
||||||
|
|
||||||
[Components.common]
|
[Components.common]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/** @file
|
/** @file
|
||||||
|
|
||||||
Copyright (c) 2017 - 2024, Arm Limited. All rights reserved.<BR>
|
Copyright (c) 2017 - 2026, Arm Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
|
@ -55,6 +55,10 @@ typedef enum ArmObjectID {
|
||||||
EArmObjDmc620PmuRegInfo, ///< 25 - DMC620 PMU Reg Info
|
EArmObjDmc620PmuRegInfo, ///< 25 - DMC620 PMU Reg Info
|
||||||
EArmObjProcessorSpecificBlockInfo, ///< 26 - Processor Specific Block.
|
EArmObjProcessorSpecificBlockInfo, ///< 26 - Processor Specific Block.
|
||||||
EArmObjProcessorSpecificSubDataArchInfo, ///< 27 - Processor Specific Sub Data (ArchData)
|
EArmObjProcessorSpecificSubDataArchInfo, ///< 27 - Processor Specific Sub Data (ArchData)
|
||||||
|
EArmObjGicIrsInfo, ///< 28 - GIC IRS Info
|
||||||
|
EArmObjGicItsV5Info, ///< 29 - GIC ITS v5 Info
|
||||||
|
EArmObjGicItsV5TranslateFrameInfo, ///< 30 - GIC ITS v5 Translate Frame Info
|
||||||
|
EArmObjGicIwbInfo, ///< 34 - GIC IWB Info
|
||||||
EArmObjMax
|
EArmObjMax
|
||||||
} EARM_OBJECT_ID;
|
} EARM_OBJECT_ID;
|
||||||
|
|
||||||
|
|
@ -205,6 +209,16 @@ typedef struct CmArmGicCInfo {
|
||||||
CM_ARM_GICC_INFO.ClockDomain
|
CM_ARM_GICC_INFO.ClockDomain
|
||||||
*/
|
*/
|
||||||
CM_OBJECT_TOKEN ClockDomainToken;
|
CM_OBJECT_TOKEN ClockDomainToken;
|
||||||
|
|
||||||
|
/** GICv5 Interrupt Controller processor affinity ID.
|
||||||
|
This must be 0 for pre-v5 GIC.
|
||||||
|
*/
|
||||||
|
UINT16 IAffId;
|
||||||
|
|
||||||
|
/** The ID of the IRS that this processor is connected to.
|
||||||
|
This must be CM_NULL_TOKEN for pre-v5 GIC.
|
||||||
|
*/
|
||||||
|
CM_OBJECT_TOKEN IrsToken;
|
||||||
} CM_ARM_GICC_INFO;
|
} CM_ARM_GICC_INFO;
|
||||||
|
|
||||||
/** A structure that describes the
|
/** A structure that describes the
|
||||||
|
|
@ -621,7 +635,7 @@ typedef struct CmArmPmcgNode {
|
||||||
ID: EArmObjGicItsIdentifierArray
|
ID: EArmObjGicItsIdentifierArray
|
||||||
*/
|
*/
|
||||||
typedef struct CmArmGicItsIdentifier {
|
typedef struct CmArmGicItsIdentifier {
|
||||||
/// The ITS Identifier
|
/// The ITS Identifier or ITS Translate Id (GicV5)
|
||||||
UINT32 ItsId;
|
UINT32 ItsId;
|
||||||
} CM_ARM_ITS_IDENTIFIER;
|
} CM_ARM_ITS_IDENTIFIER;
|
||||||
|
|
||||||
|
|
@ -873,4 +887,99 @@ typedef struct CmArmProcessorSpecificSubDataArchInfo {
|
||||||
UINT64 IdAA64Zfr0;
|
UINT64 IdAA64Zfr0;
|
||||||
} CM_ARM_PROCESSOR_SPECIFIC_SUB_DATA_ARCH_INFO;
|
} CM_ARM_PROCESSOR_SPECIFIC_SUB_DATA_ARCH_INFO;
|
||||||
|
|
||||||
|
/** A structure that describes GIC interrupt Routing Service (IRS).
|
||||||
|
|
||||||
|
ID: EArmObjGicIrsInfo
|
||||||
|
*/
|
||||||
|
typedef struct CmArmGicIrsInfo {
|
||||||
|
/// An unique token used to identify this object
|
||||||
|
CM_OBJECT_TOKEN Token;
|
||||||
|
/// GIC version.
|
||||||
|
UINT32 GicVersion;
|
||||||
|
/// The GIC IRS ID
|
||||||
|
UINT32 GicIrsId;
|
||||||
|
/// Flags
|
||||||
|
UINT32 Flags;
|
||||||
|
/// Base address of the IRS config frame
|
||||||
|
UINT64 ConfigFrameBase;
|
||||||
|
/// Base address of the IRS SET_LPI frame
|
||||||
|
UINT64 SetLpiFrameBase;
|
||||||
|
/// Proximity domain that this IRS belongs to
|
||||||
|
UINT32 ProximityDomain;
|
||||||
|
|
||||||
|
/** Optional field: Reference Token to the ProximityDomain this object
|
||||||
|
belongs to. If this field is used, the following field is ignored:
|
||||||
|
CM_ARM_GIC_IRS_INFO.ProximityDomain
|
||||||
|
*/
|
||||||
|
CM_OBJECT_TOKEN ProximityDomainToken;
|
||||||
|
} CM_ARM_GIC_IRS_INFO;
|
||||||
|
|
||||||
|
/** A structure that describes the
|
||||||
|
GICv5 Interrupt Translation Service information for the Platform.
|
||||||
|
|
||||||
|
ID: EArmObjGicItsV5Info
|
||||||
|
*/
|
||||||
|
typedef struct CmArmGicItsV5Info {
|
||||||
|
/// An unique token used to identify this object
|
||||||
|
CM_OBJECT_TOKEN Token;
|
||||||
|
/// The GIC ITSv5 ID
|
||||||
|
UINT32 GicItsId;
|
||||||
|
/// Flags
|
||||||
|
UINT32 Flags;
|
||||||
|
/// Base address of the ITS config frame
|
||||||
|
UINT64 PhysicalBaseAddress;
|
||||||
|
|
||||||
|
/** The proximity domain to which the logical processor belongs.
|
||||||
|
This field is used to populate the GIC ITS affinity structure
|
||||||
|
in the SRAT table.
|
||||||
|
*/
|
||||||
|
UINT32 ProximityDomain;
|
||||||
|
|
||||||
|
/** Optional field: Reference Token to the ProximityDomain this object
|
||||||
|
belongs to. If this field is used, the following field is ignored:
|
||||||
|
CM_ARM_GIC_ITSV5_INFO.ProximityDomain
|
||||||
|
*/
|
||||||
|
CM_OBJECT_TOKEN ProximityDomainToken;
|
||||||
|
} CM_ARM_GIC_ITSV5_INFO;
|
||||||
|
|
||||||
|
/** A structure that describes the
|
||||||
|
frame information for GICv5 Interrupt Translation Service.
|
||||||
|
|
||||||
|
ID: EArmObjGicItsV5Info
|
||||||
|
*/
|
||||||
|
typedef struct CmArmGicItsV5TranslateFrameInfo {
|
||||||
|
/// Relevant ITSv5 Token
|
||||||
|
CM_OBJECT_TOKEN ItsV5Token;
|
||||||
|
/// The GIC ITSv5 translate frame ID
|
||||||
|
UINT32 ItsTranslateId;
|
||||||
|
/// Base address of the ITS translate frame
|
||||||
|
UINT64 ItsTranslateFrameBase;
|
||||||
|
} CM_ARM_GIC_ITSV5_TRANSLATE_FRAME_INFO;
|
||||||
|
|
||||||
|
/** A structure that describes the
|
||||||
|
Interrupt Wire Bridge (IWB) information.
|
||||||
|
|
||||||
|
ID: EArmObjGicIwbInfo
|
||||||
|
*/
|
||||||
|
typedef struct CmArmGicIwbInfo {
|
||||||
|
/// An unique token used to identify this object
|
||||||
|
CM_OBJECT_TOKEN Token;
|
||||||
|
/// The GIC IWB ID
|
||||||
|
UINT32 GicIwbId;
|
||||||
|
/// Linked ITSv5 ID Token
|
||||||
|
CM_OBJECT_TOKEN ItsV5Token;
|
||||||
|
/// Base address of the IWB config frame
|
||||||
|
UINT64 ConfigFrameBase;
|
||||||
|
/// Device ID used to signal any interrupt to the connected ITS
|
||||||
|
UINT32 DeviceId;
|
||||||
|
/// Base GSIV for this IWB
|
||||||
|
UINT32 BaseGsiv;
|
||||||
|
/// Number of wires handled by this IWB
|
||||||
|
UINT32 NumWires;
|
||||||
|
/// Reference token for the ID mapping array
|
||||||
|
CM_OBJECT_TOKEN IdMappingToken;
|
||||||
|
/// Unique identifier for this node.
|
||||||
|
UINT32 Identifier;
|
||||||
|
} CM_ARM_GIC_IWB_INFO;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
|
||||||
|
|
@ -63,3 +63,16 @@ ValidateSerialPortInfo (
|
||||||
IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfoTable,
|
IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfoTable,
|
||||||
IN UINT32 SerialPortCount
|
IN UINT32 SerialPortCount
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/** Validate the Serial Port Architecture Information.
|
||||||
|
|
||||||
|
@param [in] SerialPortInfoTable Table of CM_ARCH_COMMON_SERIAL_PORT_INFO.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Success.
|
||||||
|
@retval EFI_INVALID_PARAMETER Invalid parameter.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
ArchValidateSerialPortInfo (
|
||||||
|
IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo
|
||||||
|
);
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@
|
||||||
[Sources]
|
[Sources]
|
||||||
IortGenerator.c
|
IortGenerator.c
|
||||||
IortGenerator.h
|
IortGenerator.h
|
||||||
|
IwbDeviceTable.c
|
||||||
|
IwbDeviceTableTemplate.asl
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
/** @file
|
/** @file
|
||||||
IORT Table Generator
|
IORT Table Generator
|
||||||
|
|
||||||
Copyright (c) 2017 - 2022, Arm Limited. All rights reserved.
|
Copyright (c) 2017 - 2026, Arm Limited. All rights reserved.
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
@par Reference(s):
|
@par Reference(s):
|
||||||
- IO Remapping Table, Platform Design Document, Revision E.d, Feb 2022
|
- IO Remapping Table, Platform Design Document, Revision E.g, Mar 2026
|
||||||
(https://developer.arm.com/documentation/den0049/)
|
(https://developer.arm.com/documentation/den0049/)
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
@ -15,17 +15,25 @@
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/MemoryAllocationLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Library/PrintLib.h>
|
||||||
#include <Protocol/AcpiTable.h>
|
#include <Protocol/AcpiTable.h>
|
||||||
|
|
||||||
// Module specific include files.
|
// Module specific include files.
|
||||||
#include <AcpiTableGenerator.h>
|
#include <AcpiTableGenerator.h>
|
||||||
#include <ConfigurationManagerObject.h>
|
#include <ConfigurationManagerObject.h>
|
||||||
#include <ConfigurationManagerHelper.h>
|
#include <ConfigurationManagerHelper.h>
|
||||||
|
#include <Library/AcpiHelperLib.h>
|
||||||
#include <Library/TableHelperLib.h>
|
#include <Library/TableHelperLib.h>
|
||||||
#include <Protocol/ConfigurationManagerProtocol.h>
|
#include <Protocol/ConfigurationManagerProtocol.h>
|
||||||
|
|
||||||
#include "IortGenerator.h"
|
#include "IortGenerator.h"
|
||||||
|
|
||||||
|
/** According to GICv5 spec, maximum wires per IWB instance is 65,336.
|
||||||
|
Therefore, it's reasonable to set the maximum number of IWB instance
|
||||||
|
as 16.
|
||||||
|
*/
|
||||||
|
#define MAX_IWB_COUNT (16)
|
||||||
|
|
||||||
/** ARM standard IORT Generator
|
/** ARM standard IORT Generator
|
||||||
|
|
||||||
Requirements:
|
Requirements:
|
||||||
|
|
@ -42,6 +50,7 @@ Requirements:
|
||||||
- EArmObjIdMappingArray
|
- EArmObjIdMappingArray
|
||||||
- EArmObjSmmuInterruptArray
|
- EArmObjSmmuInterruptArray
|
||||||
- EArmObjMemoryRangeDescriptor
|
- EArmObjMemoryRangeDescriptor
|
||||||
|
- EArmObjGicIwbInfo
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** This macro expands to a function that retrieves the ITS
|
/** This macro expands to a function that retrieves the ITS
|
||||||
|
|
@ -143,6 +152,15 @@ GET_OBJECT_LIST (
|
||||||
CM_ARM_SMMU_INTERRUPT
|
CM_ARM_SMMU_INTERRUPT
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/** This macro expands to a function that retrieves the
|
||||||
|
GIC IWB information from the Configuration Manager.
|
||||||
|
*/
|
||||||
|
GET_OBJECT_LIST (
|
||||||
|
EObjNameSpaceArm,
|
||||||
|
EArmObjGicIwbInfo,
|
||||||
|
CM_ARM_GIC_IWB_INFO
|
||||||
|
);
|
||||||
|
|
||||||
/** Returns the size of the ITS Group node.
|
/** Returns the size of the ITS Group node.
|
||||||
|
|
||||||
@param [in] Node Pointer to ITS Group node.
|
@param [in] Node Pointer to ITS Group node.
|
||||||
|
|
@ -2164,6 +2182,225 @@ AddRmrNodes (
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the size of the IWB node.
|
||||||
|
|
||||||
|
@param [in] Node Pointer to IWB node.
|
||||||
|
|
||||||
|
@retval Size of the IWB node.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
UINT32
|
||||||
|
GetIwbNodeSize (
|
||||||
|
IN CONST CM_ARM_GIC_IWB_INFO *Node
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (Node != NULL);
|
||||||
|
|
||||||
|
/* Size of IWB node +
|
||||||
|
Size of ID mapping array +
|
||||||
|
Size of ASCII string + 'padding to 32-bit word aligned'.
|
||||||
|
*/
|
||||||
|
return (UINT32)(sizeof (EFI_ACPI_6_0_IO_REMAPPING_IWB_NODE) +
|
||||||
|
sizeof (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE) +
|
||||||
|
ALIGN_VALUE (IWB_DEV_PATH_SIZE, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the total size required for the Iwb nodes and
|
||||||
|
updates the Node Indexer.
|
||||||
|
|
||||||
|
This function calculates the size required for the node group
|
||||||
|
and also populates the Node Indexer array with offsets for the
|
||||||
|
individual nodes.
|
||||||
|
|
||||||
|
@param [in] NodeStartOffset Offset from the start of the
|
||||||
|
IORT where this node group starts.
|
||||||
|
@param [in] NodeList Pointer to IWB node list.
|
||||||
|
@param [in] NodeCount Count of the IWB nodes.
|
||||||
|
@param [in, out] NodeIndexer Pointer to the next Node Indexer.
|
||||||
|
|
||||||
|
@retval Total size of the IWB nodes.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
UINT64
|
||||||
|
GetSizeofIwbNodes (
|
||||||
|
IN CONST UINT32 NodeStartOffset,
|
||||||
|
IN CONST CM_ARM_GIC_IWB_INFO *NodeList,
|
||||||
|
IN UINT32 NodeCount,
|
||||||
|
IN OUT IORT_NODE_INDEXER **CONST NodeIndexer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT64 Size;
|
||||||
|
|
||||||
|
ASSERT (NodeList != NULL);
|
||||||
|
|
||||||
|
Size = 0;
|
||||||
|
while (NodeCount-- != 0) {
|
||||||
|
(*NodeIndexer)->Token = NodeList->Token;
|
||||||
|
(*NodeIndexer)->Object = (VOID *)NodeList;
|
||||||
|
(*NodeIndexer)->Offset = (UINT32)(Size + NodeStartOffset);
|
||||||
|
(*NodeIndexer)->Identifier = NodeList->Identifier;
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_INFO,
|
||||||
|
"IORT: Node Indexer = %p, Token = %p, Object = %p,"
|
||||||
|
" Offset = 0x%x, Identifier = 0x%x\n",
|
||||||
|
*NodeIndexer,
|
||||||
|
(*NodeIndexer)->Token,
|
||||||
|
(*NodeIndexer)->Object,
|
||||||
|
(*NodeIndexer)->Offset,
|
||||||
|
(*NodeIndexer)->Identifier
|
||||||
|
));
|
||||||
|
|
||||||
|
Size += GetIwbNodeSize (NodeList);
|
||||||
|
(*NodeIndexer)++;
|
||||||
|
NodeList++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update the IWB Node Information.
|
||||||
|
|
||||||
|
@param [in] This Pointer to the table Generator.
|
||||||
|
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
|
||||||
|
Protocol Interface.
|
||||||
|
@param [in] AcpiTableInfo Pointer to the ACPI table info structure.
|
||||||
|
@param [in] Iort Pointer to IORT table structure.
|
||||||
|
@param [in] NodesStartOffset Offset for the start of the IWB Group
|
||||||
|
Nodes.
|
||||||
|
@param [in] NodeList Pointer to an array of IWB Group Node
|
||||||
|
Objects.
|
||||||
|
@param [in] NodeCount Number of IWB Group Node Objects.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Table generated successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER A parameter is invalid.
|
||||||
|
@retval EFI_NOT_FOUND The required object was not found.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
AddIwbNodes (
|
||||||
|
IN CONST ACPI_TABLE_GENERATOR *CONST This,
|
||||||
|
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
|
||||||
|
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
|
||||||
|
IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE *Iort,
|
||||||
|
IN CONST UINT32 NodesStartOffset,
|
||||||
|
IN CONST CM_ARM_GIC_IWB_INFO *NodeList,
|
||||||
|
IN UINT32 NodeCount
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_ACPI_6_0_IO_REMAPPING_IWB_NODE *IwbNode;
|
||||||
|
EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE *IdMapArray;
|
||||||
|
UINT64 NodeLength;
|
||||||
|
CHAR8 *ObjectName;
|
||||||
|
CHAR8 IwbDevPath[IWB_DEV_PATH_SIZE];
|
||||||
|
UINT32 Idx;
|
||||||
|
|
||||||
|
ASSERT (Iort != NULL);
|
||||||
|
|
||||||
|
IwbNode = (EFI_ACPI_6_0_IO_REMAPPING_IWB_NODE *)((UINT8 *)Iort +
|
||||||
|
NodesStartOffset);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Auto generated object name could be IWB0 to IWBF for
|
||||||
|
* the limit of AML_NAME_SEG_SIZE (4 chars).
|
||||||
|
*/
|
||||||
|
if (NodeCount > MAX_IWB_COUNT) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: IORT: Too many number of IWB. Couldn't generate object name. Count: %d\n",
|
||||||
|
NodeCount
|
||||||
|
));
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Idx = 0; Idx < NodeCount; Idx++) {
|
||||||
|
NodeLength = GetIwbNodeSize (NodeList);
|
||||||
|
if (NodeLength > MAX_UINT16) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: IORT: IWB Id Array Node length 0x%lx > MAX_UINT16."
|
||||||
|
" Status = %r\n",
|
||||||
|
NodeLength,
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate the node header
|
||||||
|
IwbNode->Node.Type = EFI_ACPI_IORT_TYPE_IWB;
|
||||||
|
IwbNode->Node.Length = (UINT16)NodeLength;
|
||||||
|
IwbNode->Node.Revision = 1;
|
||||||
|
IwbNode->Node.Identifier = NodeList->Identifier;
|
||||||
|
IwbNode->Node.NumIdMappings = 1;
|
||||||
|
IwbNode->Node.IdReference = NodeLength - sizeof (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE);
|
||||||
|
|
||||||
|
// IORT specific data
|
||||||
|
IwbNode->ConfigFrameBase = NodeList->ConfigFrameBase;
|
||||||
|
IwbNode->IwbIndex = NodeList->GicIwbId;
|
||||||
|
|
||||||
|
// Generate object name
|
||||||
|
AsciiSPrint (IwbDevPath, IWB_DEV_PATH_SIZE, "\\_SB_.IWB%x", IwbNode->IwbIndex);
|
||||||
|
|
||||||
|
// Copy the object name
|
||||||
|
ObjectName = (CHAR8 *)((UINT8 *)IwbNode +
|
||||||
|
sizeof (EFI_ACPI_6_0_IO_REMAPPING_IWB_NODE));
|
||||||
|
|
||||||
|
Status = AsciiStrCpyS (
|
||||||
|
ObjectName,
|
||||||
|
IWB_DEV_PATH_SIZE,
|
||||||
|
IwbDevPath
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: IORT: Failed to copy Object Name. Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NodeList->IdMappingToken == CM_NULL_TOKEN) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: IORT: Invalid Id Mapping token,"
|
||||||
|
" Token = 0x%x, Status =%r\n",
|
||||||
|
NodeList->IdMappingToken,
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ids for IWB node
|
||||||
|
IdMapArray = (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE *)((UINT8 *)IwbNode +
|
||||||
|
IwbNode->Node.IdReference);
|
||||||
|
|
||||||
|
Status = AddIdMappingArray (
|
||||||
|
This,
|
||||||
|
CfgMgrProtocol,
|
||||||
|
IdMapArray,
|
||||||
|
1,
|
||||||
|
NodeList->IdMappingToken
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: IORT: Failed to add Id Mapping Array. Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next IORT Group Node
|
||||||
|
IwbNode = (EFI_ACPI_6_0_IO_REMAPPING_IWB_NODE *)((UINT8 *)IwbNode +
|
||||||
|
IwbNode->Node.Length);
|
||||||
|
NodeList++;
|
||||||
|
} // IORT Group Node
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/** Validates that the IORT nodes Identifier are unique.
|
/** Validates that the IORT nodes Identifier are unique.
|
||||||
|
|
||||||
@param [in] NodeIndexer Pointer to the Node Indexer.
|
@param [in] NodeIndexer Pointer to the Node Indexer.
|
||||||
|
|
@ -2189,10 +2426,12 @@ ValidateNodeIdentifiers (
|
||||||
{
|
{
|
||||||
DEBUG ((
|
DEBUG ((
|
||||||
DEBUG_ERROR,
|
DEBUG_ERROR,
|
||||||
"ERROR: IORT: UID %d of Token %p matches with that of Token %p.\n",
|
"ERROR: IORT: UID %d of Token %p matches with that of Token %p. (%u/%u)\n",
|
||||||
NodeIndexer[IndexI].Identifier,
|
NodeIndexer[IndexI].Identifier,
|
||||||
NodeIndexer[IndexI].Token,
|
NodeIndexer[IndexI].Token,
|
||||||
NodeIndexer[IndexJ].Token
|
NodeIndexer[IndexJ].Token,
|
||||||
|
IndexI,
|
||||||
|
IndexJ
|
||||||
));
|
));
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
@ -2215,7 +2454,8 @@ ValidateNodeIdentifiers (
|
||||||
@param [in] AcpiTableInfo Pointer to the ACPI Table Info.
|
@param [in] AcpiTableInfo Pointer to the ACPI Table Info.
|
||||||
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
|
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
|
||||||
Protocol Interface.
|
Protocol Interface.
|
||||||
@param [out] Table Pointer to the constructed ACPI Table.
|
@param [out] Table Pointer to a list of generated ACPI table(s).
|
||||||
|
@param [out] TableCount Number of generated ACPI table(s).
|
||||||
|
|
||||||
@retval EFI_SUCCESS Table generated successfully.
|
@retval EFI_SUCCESS Table generated successfully.
|
||||||
@retval EFI_INVALID_PARAMETER A parameter is invalid.
|
@retval EFI_INVALID_PARAMETER A parameter is invalid.
|
||||||
|
|
@ -2227,11 +2467,12 @@ ValidateNodeIdentifiers (
|
||||||
STATIC
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
BuildIortTable (
|
BuildIortTableEx (
|
||||||
IN CONST ACPI_TABLE_GENERATOR *CONST This,
|
IN CONST ACPI_TABLE_GENERATOR *CONST This,
|
||||||
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
|
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
|
||||||
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
|
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
|
||||||
OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table
|
OUT EFI_ACPI_DESCRIPTION_HEADER ***Table,
|
||||||
|
OUT UINTN *CONST TableCount
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
@ -2247,6 +2488,7 @@ BuildIortTable (
|
||||||
UINT32 SmmuV3NodeCount;
|
UINT32 SmmuV3NodeCount;
|
||||||
UINT32 PmcgNodeCount;
|
UINT32 PmcgNodeCount;
|
||||||
UINT32 RmrNodeCount;
|
UINT32 RmrNodeCount;
|
||||||
|
UINT32 IwbNodeCount;
|
||||||
|
|
||||||
UINT32 ItsGroupOffset;
|
UINT32 ItsGroupOffset;
|
||||||
UINT32 NamedComponentOffset;
|
UINT32 NamedComponentOffset;
|
||||||
|
|
@ -2255,6 +2497,7 @@ BuildIortTable (
|
||||||
UINT32 SmmuV3Offset;
|
UINT32 SmmuV3Offset;
|
||||||
UINT32 PmcgOffset;
|
UINT32 PmcgOffset;
|
||||||
UINT32 RmrOffset;
|
UINT32 RmrOffset;
|
||||||
|
UINT32 IwbOffset;
|
||||||
|
|
||||||
CM_ARM_ITS_GROUP_NODE *ItsGroupNodeList;
|
CM_ARM_ITS_GROUP_NODE *ItsGroupNodeList;
|
||||||
CM_ARM_NAMED_COMPONENT_NODE *NamedComponentNodeList;
|
CM_ARM_NAMED_COMPONENT_NODE *NamedComponentNodeList;
|
||||||
|
|
@ -2263,11 +2506,16 @@ BuildIortTable (
|
||||||
CM_ARM_SMMUV3_NODE *SmmuV3NodeList;
|
CM_ARM_SMMUV3_NODE *SmmuV3NodeList;
|
||||||
CM_ARM_PMCG_NODE *PmcgNodeList;
|
CM_ARM_PMCG_NODE *PmcgNodeList;
|
||||||
CM_ARM_RMR_NODE *RmrNodeList;
|
CM_ARM_RMR_NODE *RmrNodeList;
|
||||||
|
CM_ARM_GIC_IWB_INFO *IwbNodeList;
|
||||||
|
|
||||||
EFI_ACPI_6_0_IO_REMAPPING_TABLE *Iort;
|
EFI_ACPI_6_0_IO_REMAPPING_TABLE *Iort;
|
||||||
IORT_NODE_INDEXER *NodeIndexer;
|
IORT_NODE_INDEXER *NodeIndexer;
|
||||||
ACPI_IORT_GENERATOR *Generator;
|
ACPI_IORT_GENERATOR *Generator;
|
||||||
|
|
||||||
|
EFI_ACPI_DESCRIPTION_HEADER **TableList;
|
||||||
|
UINT32 TableIdx;
|
||||||
|
UINT32 IwbIdx;
|
||||||
|
|
||||||
ASSERT (This != NULL);
|
ASSERT (This != NULL);
|
||||||
ASSERT (AcpiTableInfo != NULL);
|
ASSERT (AcpiTableInfo != NULL);
|
||||||
ASSERT (CfgMgrProtocol != NULL);
|
ASSERT (CfgMgrProtocol != NULL);
|
||||||
|
|
@ -2301,8 +2549,13 @@ BuildIortTable (
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
Generator = (ACPI_IORT_GENERATOR *)This;
|
Generator = (ACPI_IORT_GENERATOR *)This;
|
||||||
*Table = NULL;
|
*Table = NULL;
|
||||||
|
*TableCount = 0;
|
||||||
|
|
||||||
|
TableList = NULL;
|
||||||
|
Iort = NULL;
|
||||||
|
IwbNodeCount = 0;
|
||||||
|
|
||||||
// Get the ITS group node info
|
// Get the ITS group node info
|
||||||
Status = GetEArmObjItsGroup (
|
Status = GetEArmObjItsGroup (
|
||||||
|
|
@ -2320,6 +2573,18 @@ BuildIortTable (
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((AcpiTableInfo->AcpiTableRevision >= EFI_ACPI_IO_REMAPPING_TABLE_REVISION_07) &&
|
||||||
|
(ItsGroupNodeCount > 1))
|
||||||
|
{
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: IORT: Number of ITS Group Node Info must be 1. ItsGroupCount: %d\n",
|
||||||
|
ItsGroupNodeCount
|
||||||
|
));
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
// Add the ITS group node count
|
// Add the ITS group node count
|
||||||
IortNodeCount = ItsGroupNodeCount;
|
IortNodeCount = ItsGroupNodeCount;
|
||||||
|
|
||||||
|
|
@ -2441,6 +2706,29 @@ BuildIortTable (
|
||||||
IortNodeCount += RmrNodeCount;
|
IortNodeCount += RmrNodeCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AcpiTableInfo->AcpiTableRevision >=
|
||||||
|
EFI_ACPI_IO_REMAPPING_TABLE_REVISION_07)
|
||||||
|
{
|
||||||
|
// Get the IWB node info
|
||||||
|
Status = GetEArmObjGicIwbInfo (
|
||||||
|
CfgMgrProtocol,
|
||||||
|
CM_NULL_TOKEN,
|
||||||
|
&IwbNodeList,
|
||||||
|
&IwbNodeCount
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: IORT: Failed to get IWB Node Info. Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the IWB node count
|
||||||
|
IortNodeCount += IwbNodeCount;
|
||||||
|
}
|
||||||
|
|
||||||
// Allocate Node Indexer array
|
// Allocate Node Indexer array
|
||||||
NodeIndexer = (IORT_NODE_INDEXER *)AllocateZeroPool (
|
NodeIndexer = (IORT_NODE_INDEXER *)AllocateZeroPool (
|
||||||
(sizeof (IORT_NODE_INDEXER) *
|
(sizeof (IORT_NODE_INDEXER) *
|
||||||
|
|
@ -2684,6 +2972,40 @@ BuildIortTable (
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IWB Nodes
|
||||||
|
if ((AcpiTableInfo->AcpiTableRevision >=
|
||||||
|
EFI_ACPI_IO_REMAPPING_TABLE_REVISION_07) &&
|
||||||
|
(IwbNodeCount > 0))
|
||||||
|
{
|
||||||
|
IwbOffset = (UINT32)TableSize;
|
||||||
|
// Size of IWB node list.
|
||||||
|
NodeSize = GetSizeofIwbNodes (
|
||||||
|
IwbOffset,
|
||||||
|
IwbNodeList,
|
||||||
|
IwbNodeCount,
|
||||||
|
&NodeIndexer
|
||||||
|
);
|
||||||
|
if (NodeSize > MAX_UINT32) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: IORT: Invalid Size of IWB Nodes. Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
TableSize += NodeSize;
|
||||||
|
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_INFO,
|
||||||
|
" IwbNodeCount = %d\n" \
|
||||||
|
" IwbOffset = %d\n",
|
||||||
|
IwbNodeCount,
|
||||||
|
IwbOffset
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG ((
|
DEBUG ((
|
||||||
DEBUG_INFO,
|
DEBUG_INFO,
|
||||||
"INFO: IORT:\n" \
|
"INFO: IORT:\n" \
|
||||||
|
|
@ -2720,9 +3042,24 @@ BuildIortTable (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate the Buffer for IORT table
|
// Allocate the Buffer for IORT and IWB SSDT tables.
|
||||||
*Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize);
|
TableList = (EFI_ACPI_DESCRIPTION_HEADER **)
|
||||||
if (*Table == NULL) {
|
AllocateZeroPool (
|
||||||
|
(sizeof (EFI_ACPI_DESCRIPTION_HEADER *) * (1 + IwbNodeCount))
|
||||||
|
);
|
||||||
|
if (TableList == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: IORT: Failed to allocate memory for TableList.\n"
|
||||||
|
));
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The IORT ACPI table is at index 0 in the TableList[]
|
||||||
|
TableIdx = 0;
|
||||||
|
TableList[TableIdx] = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize);
|
||||||
|
if (TableList[TableIdx] == NULL) {
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
DEBUG ((
|
DEBUG ((
|
||||||
DEBUG_ERROR,
|
DEBUG_ERROR,
|
||||||
|
|
@ -2734,7 +3071,7 @@ BuildIortTable (
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iort = (EFI_ACPI_6_0_IO_REMAPPING_TABLE *)*Table;
|
Iort = (EFI_ACPI_6_0_IO_REMAPPING_TABLE *)TableList[TableIdx];
|
||||||
|
|
||||||
DEBUG ((
|
DEBUG ((
|
||||||
DEBUG_INFO,
|
DEBUG_INFO,
|
||||||
|
|
@ -2907,6 +3244,49 @@ BuildIortTable (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((AcpiTableInfo->AcpiTableRevision >=
|
||||||
|
EFI_ACPI_IO_REMAPPING_TABLE_REVISION_07) &&
|
||||||
|
(IwbNodeCount > 0))
|
||||||
|
{
|
||||||
|
Status = AddIwbNodes (
|
||||||
|
This,
|
||||||
|
CfgMgrProtocol,
|
||||||
|
AcpiTableInfo,
|
||||||
|
Iort,
|
||||||
|
IwbOffset,
|
||||||
|
IwbNodeList,
|
||||||
|
IwbNodeCount
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: IORT: Failed to add IWB Node. Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IwbIdx = 0; IwbIdx < IwbNodeCount; IwbIdx++) {
|
||||||
|
// The Iwb AML table list starts at index 1.
|
||||||
|
TableIdx++;
|
||||||
|
Status = BuildIwbDeviceTable (
|
||||||
|
&IwbNodeList[IwbIdx],
|
||||||
|
&TableList[TableIdx]
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: IORT: Failed to add IWB SSDT table. Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
} // for
|
||||||
|
}
|
||||||
|
|
||||||
|
*Table = TableList;
|
||||||
|
*TableCount = 1 + IwbNodeCount;
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
error_handler:
|
error_handler:
|
||||||
|
|
@ -2915,9 +3295,17 @@ error_handler:
|
||||||
Generator->NodeIndexer = NULL;
|
Generator->NodeIndexer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*Table != NULL) {
|
if (TableList != NULL) {
|
||||||
FreePool (*Table);
|
while (TableIdx > 1) {
|
||||||
*Table = NULL;
|
TableIdx--;
|
||||||
|
FreeIwbDeviceTable (TableList[TableIdx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Iort != NULL) {
|
||||||
|
FreePool (TableList[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool (TableList);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
|
@ -2929,21 +3317,26 @@ error_handler:
|
||||||
@param [in] AcpiTableInfo Pointer to the ACPI Table Info.
|
@param [in] AcpiTableInfo Pointer to the ACPI Table Info.
|
||||||
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
|
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
|
||||||
Protocol Interface.
|
Protocol Interface.
|
||||||
@param [in, out] Table Pointer to the ACPI Table.
|
@param [in, out] Table Pointer to an array of pointers
|
||||||
|
to ACPI Table(s).
|
||||||
|
@param [in] TableCount Number of ACPI table(s).
|
||||||
|
|
||||||
@retval EFI_SUCCESS The resources were freed successfully.
|
@retval EFI_SUCCESS The resources were freed successfully.
|
||||||
@retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
|
@retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
|
||||||
**/
|
**/
|
||||||
STATIC
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
FreeIortTableResources (
|
FreeIortTableResourcesEx (
|
||||||
IN CONST ACPI_TABLE_GENERATOR *CONST This,
|
IN CONST ACPI_TABLE_GENERATOR *CONST This,
|
||||||
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
|
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
|
||||||
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
|
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
|
||||||
IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table
|
IN OUT EFI_ACPI_DESCRIPTION_HEADER ***CONST Table,
|
||||||
|
IN CONST UINTN TableCount
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ACPI_IORT_GENERATOR *Generator;
|
ACPI_IORT_GENERATOR *Generator;
|
||||||
|
EFI_ACPI_DESCRIPTION_HEADER **TableList;
|
||||||
|
UINTN Idx;
|
||||||
|
|
||||||
ASSERT (This != NULL);
|
ASSERT (This != NULL);
|
||||||
ASSERT (AcpiTableInfo != NULL);
|
ASSERT (AcpiTableInfo != NULL);
|
||||||
|
|
@ -2965,6 +3358,16 @@ FreeIortTableResources (
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TableList = *Table;
|
||||||
|
|
||||||
|
for (Idx = 1; Idx < TableCount; Idx++) {
|
||||||
|
FreeIwbDeviceTable (TableList[Idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TableList[0] != NULL) {
|
||||||
|
FreePool (TableList[0]);
|
||||||
|
}
|
||||||
|
|
||||||
FreePool (*Table);
|
FreePool (*Table);
|
||||||
*Table = NULL;
|
*Table = NULL;
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
@ -2985,9 +3388,9 @@ ACPI_IORT_GENERATOR IortGenerator = {
|
||||||
// Generator Description
|
// Generator Description
|
||||||
L"ACPI.STD.IORT.GENERATOR",
|
L"ACPI.STD.IORT.GENERATOR",
|
||||||
// ACPI Table Signature
|
// ACPI Table Signature
|
||||||
EFI_ACPI_6_4_IO_REMAPPING_TABLE_SIGNATURE,
|
EFI_ACPI_6_7_IO_REMAPPING_TABLE_SIGNATURE,
|
||||||
// ACPI Table Revision supported by this Generator
|
// ACPI Table Revision supported by this Generator
|
||||||
EFI_ACPI_IO_REMAPPING_TABLE_REVISION_06,
|
EFI_ACPI_IO_REMAPPING_TABLE_REVISION_07,
|
||||||
// Minimum supported ACPI Table Revision
|
// Minimum supported ACPI Table Revision
|
||||||
EFI_ACPI_IO_REMAPPING_TABLE_REVISION_00,
|
EFI_ACPI_IO_REMAPPING_TABLE_REVISION_00,
|
||||||
// Creator ID
|
// Creator ID
|
||||||
|
|
@ -2995,14 +3398,13 @@ ACPI_IORT_GENERATOR IortGenerator = {
|
||||||
// Creator Revision
|
// Creator Revision
|
||||||
IORT_GENERATOR_REVISION,
|
IORT_GENERATOR_REVISION,
|
||||||
// Build Table function
|
// Build Table function
|
||||||
BuildIortTable,
|
|
||||||
// Free Resource function
|
|
||||||
FreeIortTableResources,
|
|
||||||
// Extended build function not needed
|
|
||||||
NULL,
|
NULL,
|
||||||
// Extended build function not implemented by the generator.
|
// Free Resource function
|
||||||
// Hence extended free resource function is not required.
|
NULL,
|
||||||
NULL
|
// Extended build function not needed
|
||||||
|
BuildIortTableEx,
|
||||||
|
// Extended Free Resource function
|
||||||
|
FreeIortTableResourcesEx,
|
||||||
},
|
},
|
||||||
|
|
||||||
// IORT Generator private data
|
// IORT Generator private data
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#define IWB_DEV_NAME_SIZE (AML_NAME_SEG_SIZE + 1)
|
||||||
|
#define IWB_DEV_PATH_SIZE (IWB_DEV_NAME_SIZE + 6) /* "\\_SB_." */
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
/** A structure that describes the Node indexer
|
/** A structure that describes the Node indexer
|
||||||
|
|
@ -41,4 +44,36 @@ typedef struct AcpiIortGenerator {
|
||||||
IORT_NODE_INDEXER *NodeIndexer;
|
IORT_NODE_INDEXER *NodeIndexer;
|
||||||
} ACPI_IORT_GENERATOR;
|
} ACPI_IORT_GENERATOR;
|
||||||
|
|
||||||
|
/** Build a SSDT table describing the IWB device.
|
||||||
|
|
||||||
|
The table created by this function must be freed by FreeSimpleIwbDeviceTable.
|
||||||
|
|
||||||
|
@param [in] IwbInfo IWB device info to describe in the SSDT table.
|
||||||
|
@param [out] Table If success, pointer to the created SSDT table.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Table generated successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER A parameter is invalid.
|
||||||
|
@retval EFI_NOT_FOUND Could not find information.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Could not allocate memory.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
BuildIwbDeviceTable (
|
||||||
|
IN CONST CM_ARM_GIC_IWB_INFO *IwbInfo,
|
||||||
|
OUT EFI_ACPI_DESCRIPTION_HEADER **Table
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Free an Iwb device table previously created by
|
||||||
|
the BuildIwbDeviceTable function.
|
||||||
|
|
||||||
|
@param [in] Table Pointer to a Iwb Device table allocated by
|
||||||
|
the BuildIwbDeviceTable function.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
FreeIwbDeviceTable (
|
||||||
|
IN EFI_ACPI_DESCRIPTION_HEADER *Table
|
||||||
|
);
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,333 @@
|
||||||
|
/** @file
|
||||||
|
Generate IWB SSDT table.
|
||||||
|
|
||||||
|
Copyright (c) 2026, Arm Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
@par Reference(s):
|
||||||
|
- IO Remapping Table, Platform Design Document, Revision E.g, Mar 2026
|
||||||
|
(https://developer.arm.com/documentation/den0049/)
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <Library/AcpiLib.h>
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Library/PcdLib.h>
|
||||||
|
|
||||||
|
#include <Protocol/AcpiTable.h>
|
||||||
|
|
||||||
|
// Module specific include files.
|
||||||
|
#include <ConfigurationManagerObject.h>
|
||||||
|
#include <Library/AcpiHelperLib.h>
|
||||||
|
#include <Library/AmlLib/AmlLib.h>
|
||||||
|
|
||||||
|
#include "IortGenerator.h"
|
||||||
|
|
||||||
|
/** According to GICv5 specification chapther 10.4.1 IWB_CONFIG_FRAME,
|
||||||
|
IWB_CONFIG_FRAME's block size is 0x10000 bytes.
|
||||||
|
*/
|
||||||
|
#define IWB_FRAME_BLOCK_SIZE 0x10000
|
||||||
|
|
||||||
|
/** C array containing the compiled AML template.
|
||||||
|
This symbol is defined in the auto generated C file
|
||||||
|
containing the AML bytecode array.
|
||||||
|
*/
|
||||||
|
extern CHAR8 iwbdevicetabletemplate_aml_code[];
|
||||||
|
|
||||||
|
/** Fixup the IWB device UID (_UID).
|
||||||
|
|
||||||
|
@param [in] RootNodeHandle Pointer to the root of an AML tree.
|
||||||
|
@param [in] Uid UID for the IWB device.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The function completed successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER Invalid parameter.
|
||||||
|
@retval EFI_NOT_FOUND Could not find information.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Out of resources.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
FixupIwbDeviceUid (
|
||||||
|
IN AML_ROOT_NODE_HANDLE RootNodeHandle,
|
||||||
|
IN CONST UINT64 Uid
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
AML_OBJECT_NODE_HANDLE NameOpIdNode;
|
||||||
|
|
||||||
|
// Get the _UID NameOp object defined by the "Name ()" statement,
|
||||||
|
// and update its value.
|
||||||
|
Status = AmlFindNode (
|
||||||
|
RootNodeHandle,
|
||||||
|
"\\_SB_.IWB0._UID",
|
||||||
|
&NameOpIdNode
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AmlNameOpUpdateInteger (NameOpIdNode, (UINT64)Uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Fixup the Iwb device name.
|
||||||
|
|
||||||
|
@param [in] RootNodeHandle Pointer to the root of an AML tree.
|
||||||
|
@param [in] Name The Name to give to the Device.
|
||||||
|
Must be a NULL-terminated ASL NameString
|
||||||
|
e.g.: "DEV0", "DV15.DEV0", etc.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The function completed successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER Invalid parameter.
|
||||||
|
@retval EFI_NOT_FOUND Could not find information.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Out of resources.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
FixupIwbDeviceName (
|
||||||
|
IN AML_ROOT_NODE_HANDLE RootNodeHandle,
|
||||||
|
IN CONST CHAR8 *Name
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
AML_OBJECT_NODE_HANDLE DeviceNode;
|
||||||
|
|
||||||
|
// Get the COM0 variable defined by the "Device ()" statement.
|
||||||
|
Status = AmlFindNode (RootNodeHandle, "\\_SB_.IWB0", &DeviceNode);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the Device's name.
|
||||||
|
return AmlDeviceOpUpdateName (DeviceNode, Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Fixup the Iwb device _CRS values (BaseAddress, ...).
|
||||||
|
|
||||||
|
@param [in] RootNodeHandle Pointer to the root of an AML tree.
|
||||||
|
@param [in] IwbInfo Pointer to a IWB device Information
|
||||||
|
structure.
|
||||||
|
Get the device size Information from there.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The function completed successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER Invalid parameter.
|
||||||
|
@retval EFI_NOT_FOUND Could not find information.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Out of resources.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
FixupIwbDeviceCrs (
|
||||||
|
IN AML_ROOT_NODE_HANDLE RootNodeHandle,
|
||||||
|
IN CONST CM_ARM_GIC_IWB_INFO *IwbInfo
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
AML_OBJECT_NODE_HANDLE NameOpCrsNode;
|
||||||
|
AML_DATA_NODE_HANDLE QWordRdNode;
|
||||||
|
|
||||||
|
// Get the "_CRS" object defined by the "Name ()" statement.
|
||||||
|
Status = AmlFindNode (
|
||||||
|
RootNodeHandle,
|
||||||
|
"\\_SB_.IWB0._CRS",
|
||||||
|
&NameOpCrsNode
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the first Rd node in the "_CRS" object.
|
||||||
|
Status = AmlNameOpGetFirstRdNode (NameOpCrsNode, &QWordRdNode);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QWordRdNode == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the IWB device's base address and length.
|
||||||
|
Status = AmlUpdateRdQWord (
|
||||||
|
QWordRdNode,
|
||||||
|
IwbInfo->ConfigFrameBase,
|
||||||
|
IWB_FRAME_BLOCK_SIZE
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Fixup the IWB Device in the AML tree.
|
||||||
|
|
||||||
|
For each template value:
|
||||||
|
- find the node to update;
|
||||||
|
- update the value.
|
||||||
|
|
||||||
|
@param [in] RootNodeHandle Pointer to the root of the AML tree.
|
||||||
|
@param [in] IwbInfo Pointer to a IWB device Information
|
||||||
|
structure.
|
||||||
|
@param [in] Name The Name to give to the Device.
|
||||||
|
Must be a NULL-terminated ASL NameString
|
||||||
|
e.g.: "DEV0", "DV15.DEV0", etc.
|
||||||
|
@param [in] Uid UID for the IWB device.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The function completed successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER Invalid parameter.
|
||||||
|
@retval EFI_NOT_FOUND Could not find information.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Out of resources.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
FixupIwbDeviceInfo (
|
||||||
|
IN AML_ROOT_NODE_HANDLE RootNodeHandle,
|
||||||
|
IN CONST CM_ARM_GIC_IWB_INFO *IwbInfo,
|
||||||
|
IN CONST CHAR8 *Name,
|
||||||
|
IN CONST UINT64 Uid
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
ASSERT (RootNodeHandle != NULL);
|
||||||
|
ASSERT (IwbInfo != NULL);
|
||||||
|
ASSERT (Name != NULL);
|
||||||
|
|
||||||
|
// Fixup the _UID value.
|
||||||
|
Status = FixupIwbDeviceUid (RootNodeHandle, Uid);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fixup the _CRS values.
|
||||||
|
Status = FixupIwbDeviceCrs (RootNodeHandle, IwbInfo);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fixup the Iwb device name.
|
||||||
|
// This MUST be done at the end, otherwise AML paths won't be valid anymore.
|
||||||
|
return FixupIwbDeviceName (RootNodeHandle, Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Build a SSDT table describing the IWB device.
|
||||||
|
|
||||||
|
The table created by this function must be freed by FreeSimpleIwbDeviceTable.
|
||||||
|
|
||||||
|
@param [in] IwbInfo IWB device info to describe in the SSDT table.
|
||||||
|
@param [out] Table If success, pointer to the created SSDT table.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Table generated successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER A parameter is invalid.
|
||||||
|
@retval EFI_NOT_FOUND Could not find information.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Could not allocate memory.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
BuildIwbDeviceTable (
|
||||||
|
IN CONST CM_ARM_GIC_IWB_INFO *IwbInfo,
|
||||||
|
OUT EFI_ACPI_DESCRIPTION_HEADER **Table
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_STATUS Status1;
|
||||||
|
AML_ROOT_NODE_HANDLE RootNodeHandle;
|
||||||
|
CHAR8 IwbDevName[IWB_DEV_NAME_SIZE];
|
||||||
|
|
||||||
|
ASSERT (IwbInfo != NULL);
|
||||||
|
ASSERT (Table != NULL);
|
||||||
|
|
||||||
|
IwbDevName[0] = 'I';
|
||||||
|
IwbDevName[1] = 'W';
|
||||||
|
IwbDevName[2] = 'B';
|
||||||
|
IwbDevName[3] = AsciiFromHex (IwbInfo->GicIwbId);
|
||||||
|
IwbDevName[4] = '\0';
|
||||||
|
|
||||||
|
// Parse the IWB Device Table Template.
|
||||||
|
Status = AmlParseDefinitionBlock (
|
||||||
|
(EFI_ACPI_DESCRIPTION_HEADER *)iwbdevicetabletemplate_aml_code,
|
||||||
|
&RootNodeHandle
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: IWB-DEVICE-FIXUP:"
|
||||||
|
" Failed to parse SSDT IWB device Template. Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fixup the template values.
|
||||||
|
Status = FixupIwbDeviceInfo (
|
||||||
|
RootNodeHandle,
|
||||||
|
IwbInfo,
|
||||||
|
IwbDevName,
|
||||||
|
IwbInfo->GicIwbId
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: IWB-DEVICE-FIXUP: Failed to fixup SSDT IWB Device Table."
|
||||||
|
" Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
goto ExitHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serialize the tree.
|
||||||
|
Status = AmlSerializeDefinitionBlock (
|
||||||
|
RootNodeHandle,
|
||||||
|
Table
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: IWB-DEVICE-FIXUP: Failed to Serialize SSDT Table Data."
|
||||||
|
" Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
ExitHandler:
|
||||||
|
// Cleanup
|
||||||
|
if (RootNodeHandle != NULL) {
|
||||||
|
Status1 = AmlDeleteTree (RootNodeHandle);
|
||||||
|
if (EFI_ERROR (Status1)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: IWB-DEVICE-FIXUP: Failed to cleanup AML tree."
|
||||||
|
" Status = %r\n",
|
||||||
|
Status1
|
||||||
|
));
|
||||||
|
// If Status was success but we failed to delete the AML Tree
|
||||||
|
// return Status1 else return the original error code, i.e. Status.
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
return Status1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Free an Iwb device table previously created by
|
||||||
|
the BuildIwbDeviceTable function.
|
||||||
|
|
||||||
|
@param [in] Table Pointer to a Iwb Device table allocated by
|
||||||
|
the BuildIwbDeviceTable function.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
FreeIwbDeviceTable (
|
||||||
|
IN EFI_ACPI_DESCRIPTION_HEADER *Table
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (Table != NULL);
|
||||||
|
FreePool (Table);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
/** @file
|
||||||
|
IWB Device Table Template
|
||||||
|
|
||||||
|
Copyright (c) 2026, Arm Ltd. All rights reserved.<BR>
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
@par Reference(s)
|
||||||
|
- IO Remapping Table, Platform Design Document, Revision E.g Mar 2026
|
||||||
|
|
||||||
|
@par Glossary:
|
||||||
|
- {template} - Data fixed up using AML Fixup APIs.
|
||||||
|
**/
|
||||||
|
|
||||||
|
DefinitionBlock("IwbDeviceTableTemplate.aml", "SSDT", 2, "ARMLTD", "IWB", 1) {
|
||||||
|
Scope(_SB) {
|
||||||
|
Device (IWB0) { // {template}
|
||||||
|
Name (_HID, "ARMH0003")
|
||||||
|
Name (_UID, 0) // {template}
|
||||||
|
Name (_CRS, ResourceTemplate () {
|
||||||
|
QWordMemory (
|
||||||
|
,
|
||||||
|
,
|
||||||
|
MinFixed,
|
||||||
|
MaxFixed,
|
||||||
|
NonCacheable,
|
||||||
|
ReadWrite,
|
||||||
|
0x0,
|
||||||
|
0x000000002F000000, // IWB config frame base // {template}
|
||||||
|
0x000000002F00FFFF, // IWB config frame last byte // {template}
|
||||||
|
0, // Translation Offset
|
||||||
|
0x0000000000010000, // IWB config frame length
|
||||||
|
) // QWordMemory
|
||||||
|
}) // Name
|
||||||
|
} // Device
|
||||||
|
} // Scope(_SB)
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
/** @file
|
/** @file
|
||||||
MADT Table Generator
|
MADT Table Generator
|
||||||
|
|
||||||
Copyright (c) 2017 - 2023, Arm Limited. All rights reserved.
|
Copyright (c) 2017 - 2026, Arm Limited. All rights reserved.
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
@par Reference(s):
|
@par Reference(s):
|
||||||
- ACPI 6.5 Specification - Aug 29, 2022
|
- ACPI 6.7 Specification.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
|
@ -81,19 +81,157 @@ GET_OBJECT_LIST (
|
||||||
CM_ARM_GIC_ITS_INFO
|
CM_ARM_GIC_ITS_INFO
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/** This macro expands to a function that retrieves the GIC
|
||||||
|
IRS Information from the Configuration Manager.
|
||||||
|
*/
|
||||||
|
GET_OBJECT_LIST (
|
||||||
|
EObjNameSpaceArm,
|
||||||
|
EArmObjGicIrsInfo,
|
||||||
|
CM_ARM_GIC_IRS_INFO
|
||||||
|
);
|
||||||
|
|
||||||
|
/** This macro expands to a function that retrieves the GIC
|
||||||
|
Interrupt Translation Service v5 Information from the
|
||||||
|
Configuration Manager.
|
||||||
|
*/
|
||||||
|
GET_OBJECT_LIST (
|
||||||
|
EObjNameSpaceArm,
|
||||||
|
EArmObjGicItsV5Info,
|
||||||
|
CM_ARM_GIC_ITSV5_INFO
|
||||||
|
);
|
||||||
|
|
||||||
|
/** This macro expands to a function that retrieves the GIC
|
||||||
|
ITS v5 Translate Frame Information from the
|
||||||
|
Configuration Manager.
|
||||||
|
*/
|
||||||
|
GET_OBJECT_LIST (
|
||||||
|
EObjNameSpaceArm,
|
||||||
|
EArmObjGicItsV5TranslateFrameInfo,
|
||||||
|
CM_ARM_GIC_ITSV5_TRANSLATE_FRAME_INFO
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Add the GIC Interrupt Routing Service Information
|
||||||
|
to the MADT Table.
|
||||||
|
|
||||||
|
@param [in] GicIrs GIC IRS structure.
|
||||||
|
@param [in] GicIrsInfo GIC IRS Info.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
AddGICInterruptRoutingService (
|
||||||
|
IN EFI_ACPI_6_7_GIC_IRS_STRUCTURE *CONST GicIrs,
|
||||||
|
IN CONST CM_ARM_GIC_IRS_INFO *CONST GicIrsInfo
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (GicIrs != NULL);
|
||||||
|
ASSERT (GicIrsInfo != NULL);
|
||||||
|
|
||||||
|
// UINT8 Type
|
||||||
|
GicIrs->Type = EFI_ACPI_6_7_GIC_IRS;
|
||||||
|
// UINT8 Length
|
||||||
|
GicIrs->Length = sizeof (EFI_ACPI_6_7_GIC_IRS_STRUCTURE);
|
||||||
|
// UINT8 GicVersion
|
||||||
|
GicIrs->GicVersion = EFI_ACPI_6_7_GIC_V5;
|
||||||
|
// UINT8 Reserved
|
||||||
|
GicIrs->Reserved = EFI_ACPI_RESERVED_BYTE;
|
||||||
|
|
||||||
|
// UINT32 IrsId
|
||||||
|
GicIrs->IrsId = GicIrsInfo->GicIrsId;
|
||||||
|
// UINT32 Flags
|
||||||
|
GicIrs->Flags = GicIrsInfo->Flags;
|
||||||
|
// UINT32 Reserved2
|
||||||
|
GicIrs->Reserved2 = EFI_ACPI_RESERVED_DWORD;
|
||||||
|
// UINT32 IrsConfigFrameBase
|
||||||
|
GicIrs->IrsConfigFrameBase = GicIrsInfo->ConfigFrameBase;
|
||||||
|
// UINT32 IrsSetLpiFrameBase
|
||||||
|
GicIrs->IrsSetLpiFrameBase = GicIrsInfo->SetLpiFrameBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Add the GICv5 Interrupt Translation Service Information
|
||||||
|
to the MADT Table.
|
||||||
|
|
||||||
|
@param [in] GicItsV5 GIC ITSv5 structure list.
|
||||||
|
@param [in] GicItsV5Info GIC ITSv5 Info.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
AddGICInterruptTranslationServiceV5 (
|
||||||
|
IN EFI_ACPI_6_7_GIC_ITSV5_STRUCTURE *CONST GicItsV5,
|
||||||
|
IN CONST CM_ARM_GIC_ITSV5_INFO *CONST GicItsV5Info
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (GicItsV5 != NULL);
|
||||||
|
ASSERT (GicItsV5Info != NULL);
|
||||||
|
|
||||||
|
// UINT8 Type
|
||||||
|
GicItsV5->Type = EFI_ACPI_6_7_GIC_ITSV5;
|
||||||
|
// UINT8 Length
|
||||||
|
GicItsV5->Length = sizeof (EFI_ACPI_6_7_GIC_ITSV5_STRUCTURE);
|
||||||
|
// UINT8 Flags
|
||||||
|
GicItsV5->Flags = GicItsV5Info->Flags;
|
||||||
|
// UINT8 Reserved
|
||||||
|
GicItsV5->Reserved = EFI_ACPI_RESERVED_BYTE;
|
||||||
|
|
||||||
|
// UINT32 GicItsId
|
||||||
|
GicItsV5->GicItsId = GicItsV5Info->GicItsId;
|
||||||
|
// UINT64 PhysicalBaseAddress
|
||||||
|
GicItsV5->PhysicalBaseAddress = GicItsV5Info->PhysicalBaseAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Add the GICv5 Interrupt Translation Service Translate Frame Information
|
||||||
|
to the MADT Table.
|
||||||
|
|
||||||
|
@param [in] GicItsV5TranslateFrame GIC ITSv5 Translate frame
|
||||||
|
structure.
|
||||||
|
@param [in] GicItsV5TransFrameInfo GIC ITSv5 Translate frame Info.
|
||||||
|
@param [in] GicItsV5Info GIC ITSv5 Info.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
AddGICInterruptTranslationServiceV5TranslateFrame (
|
||||||
|
IN EFI_ACPI_6_7_GIC_ITSV5_TRANSLATE_FRAME_STRUCTURE *CONST GicItsV5TranslateFrame,
|
||||||
|
IN CONST CM_ARM_GIC_ITSV5_TRANSLATE_FRAME_INFO *CONST GicItsV5TransFrameInfo,
|
||||||
|
IN CONST CM_ARM_GIC_ITSV5_INFO *CONST GicItsV5Info
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (GicItsV5TranslateFrame != NULL);
|
||||||
|
ASSERT (GicItsV5TransFrameInfo != NULL);
|
||||||
|
|
||||||
|
// UINT8 Type
|
||||||
|
GicItsV5TranslateFrame->Type = EFI_ACPI_6_7_GIC_ITSV5_TRANSLATE_FRAME;
|
||||||
|
// UINT8 Length
|
||||||
|
GicItsV5TranslateFrame->Length = sizeof (EFI_ACPI_6_7_GIC_ITSV5_TRANSLATE_FRAME_STRUCTURE);
|
||||||
|
// UINT16 Reserved
|
||||||
|
GicItsV5TranslateFrame->Reserved = EFI_ACPI_RESERVED_WORD;
|
||||||
|
|
||||||
|
// UINT32 LinkedGicItsId
|
||||||
|
GicItsV5TranslateFrame->LinkedGicItsId = GicItsV5Info->GicItsId;
|
||||||
|
// UINT32 ItsTranslateId
|
||||||
|
GicItsV5TranslateFrame->ItsTranslateId = GicItsV5TransFrameInfo->ItsTranslateId;
|
||||||
|
// UINT32 Reserved2
|
||||||
|
GicItsV5TranslateFrame->Reserved2 = EFI_ACPI_RESERVED_DWORD;
|
||||||
|
// UINT32 ItsTranslateFrameBase
|
||||||
|
GicItsV5TranslateFrame->ItsTranslateFrameBase = GicItsV5TransFrameInfo->ItsTranslateFrameBase;
|
||||||
|
}
|
||||||
|
|
||||||
/** This function updates the GIC CPU Interface Information in the
|
/** This function updates the GIC CPU Interface Information in the
|
||||||
EFI_ACPI_6_5_GIC_STRUCTURE structure.
|
EFI_ACPI_6_7_GIC_STRUCTURE structure.
|
||||||
|
|
||||||
@param [in] Gicc Pointer to GIC CPU Interface structure.
|
@param [in] Gicc Pointer to GIC CPU Interface structure.
|
||||||
@param [in] GicCInfo Pointer to the GIC CPU Interface Information.
|
@param [in] GicCInfo Pointer to the GIC CPU Interface Information.
|
||||||
|
@param [in] GicIrsInfo Pointer to the GIC IRS structure.
|
||||||
@param [in] MadtRev MADT table revision.
|
@param [in] MadtRev MADT table revision.
|
||||||
@param [in] GicRPresent TRUE if MADT also contains any GICR structures.
|
@param [in] GicRPresent TRUE if MADT also contains any GICR structures.
|
||||||
**/
|
**/
|
||||||
STATIC
|
STATIC
|
||||||
VOID
|
VOID
|
||||||
AddGICC (
|
AddGICC (
|
||||||
IN EFI_ACPI_6_5_GIC_STRUCTURE *CONST Gicc,
|
IN EFI_ACPI_6_7_GIC_STRUCTURE *CONST Gicc,
|
||||||
IN CONST CM_ARM_GICC_INFO *CONST GicCInfo,
|
IN CONST CM_ARM_GICC_INFO *CONST GicCInfo,
|
||||||
|
IN CONST CM_ARM_GIC_IRS_INFO *CONST GicIrsInfo,
|
||||||
IN CONST UINT8 MadtRev,
|
IN CONST UINT8 MadtRev,
|
||||||
IN CONST BOOLEAN GicRPresent
|
IN CONST BOOLEAN GicRPresent
|
||||||
)
|
)
|
||||||
|
|
@ -102,9 +240,9 @@ AddGICC (
|
||||||
ASSERT (GicCInfo != NULL);
|
ASSERT (GicCInfo != NULL);
|
||||||
|
|
||||||
// UINT8 Type
|
// UINT8 Type
|
||||||
Gicc->Type = EFI_ACPI_6_5_GIC;
|
Gicc->Type = EFI_ACPI_6_7_GIC;
|
||||||
// UINT8 Length
|
// UINT8 Length
|
||||||
Gicc->Length = sizeof (EFI_ACPI_6_5_GIC_STRUCTURE);
|
Gicc->Length = sizeof (EFI_ACPI_6_7_GIC_STRUCTURE);
|
||||||
// UINT16 Reserved
|
// UINT16 Reserved
|
||||||
Gicc->Reserved = EFI_ACPI_RESERVED_WORD;
|
Gicc->Reserved = EFI_ACPI_RESERVED_WORD;
|
||||||
|
|
||||||
|
|
@ -159,6 +297,13 @@ AddGICC (
|
||||||
if (MadtRev > EFI_ACPI_6_4_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) {
|
if (MadtRev > EFI_ACPI_6_4_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) {
|
||||||
Gicc->TrbeInterrupt = GicCInfo->TrbeInterrupt;
|
Gicc->TrbeInterrupt = GicCInfo->TrbeInterrupt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MadtRev >= EFI_ACPI_6_6_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) {
|
||||||
|
if (GicIrsInfo != NULL) {
|
||||||
|
Gicc->IrsId = GicIrsInfo->GicIrsId;
|
||||||
|
Gicc->IAffId = GicCInfo->IAffId;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -214,6 +359,8 @@ IsAcpiUidEqual (
|
||||||
@param [in] Gicc Pointer to GIC CPU Interface structure list.
|
@param [in] Gicc Pointer to GIC CPU Interface structure list.
|
||||||
@param [in] GicCInfo Pointer to the GIC CPU Information list.
|
@param [in] GicCInfo Pointer to the GIC CPU Information list.
|
||||||
@param [in] GicCCount Count of GIC CPU Interfaces.
|
@param [in] GicCCount Count of GIC CPU Interfaces.
|
||||||
|
@param [in] GicIrsInfo Pointer to the GIC IRS list.
|
||||||
|
@param [in] GicIrsCount Count of GIC IRS.
|
||||||
@param [in] MadtRev MADT table revision.
|
@param [in] MadtRev MADT table revision.
|
||||||
@param [in] GicRPresent TRUE if MADT also contains any GICR
|
@param [in] GicRPresent TRUE if MADT also contains any GICR
|
||||||
structures.
|
structures.
|
||||||
|
|
@ -227,14 +374,18 @@ IsAcpiUidEqual (
|
||||||
STATIC
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
AddGICCList (
|
AddGICCList (
|
||||||
IN EFI_ACPI_6_5_GIC_STRUCTURE *Gicc,
|
IN EFI_ACPI_6_7_GIC_STRUCTURE *Gicc,
|
||||||
IN CONST CM_ARM_GICC_INFO *GicCInfo,
|
IN CONST CM_ARM_GICC_INFO *GicCInfo,
|
||||||
IN UINT32 GicCCount,
|
IN UINT32 GicCCount,
|
||||||
|
IN CONST CM_ARM_GIC_IRS_INFO *GicIrsInfo,
|
||||||
|
IN UINT32 GicIrsCount,
|
||||||
IN CONST UINT8 MadtRev,
|
IN CONST UINT8 MadtRev,
|
||||||
IN CONST BOOLEAN GicRPresent
|
IN CONST BOOLEAN GicRPresent
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
BOOLEAN IsAcpiProcUidDuplicated;
|
BOOLEAN IsAcpiProcUidDuplicated;
|
||||||
|
CONST CM_ARM_GIC_IRS_INFO *IrsInfo;
|
||||||
|
UINTN Idx;
|
||||||
|
|
||||||
ASSERT (Gicc != NULL);
|
ASSERT (Gicc != NULL);
|
||||||
ASSERT (GicCInfo != NULL);
|
ASSERT (GicCInfo != NULL);
|
||||||
|
|
@ -252,7 +403,22 @@ AddGICCList (
|
||||||
}
|
}
|
||||||
|
|
||||||
while (GicCCount-- != 0) {
|
while (GicCCount-- != 0) {
|
||||||
AddGICC (Gicc++, GicCInfo++, MadtRev, GicRPresent);
|
IrsInfo = NULL;
|
||||||
|
|
||||||
|
if ((GicIrsInfo != NULL) && (GicCInfo->IrsToken != CM_NULL_TOKEN)) {
|
||||||
|
for (Idx = 0; Idx < GicIrsCount; Idx++) {
|
||||||
|
if (GicCInfo->IrsToken == GicIrsInfo[Idx].Token) {
|
||||||
|
IrsInfo = &GicIrsInfo[Idx];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IrsInfo == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AddGICC (Gicc++, GicCInfo++, IrsInfo, MadtRev, GicRPresent);
|
||||||
}
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
@ -434,6 +600,106 @@ AddGICItsList (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Add the GIC Interrupt Routing Service Information
|
||||||
|
to the MADT Table.
|
||||||
|
|
||||||
|
@param [in] GicIrs Pointer to GIC IRS structure list.
|
||||||
|
@param [in] GicIrsInfo Pointer to the GIC IRS list.
|
||||||
|
@param [in] GicIrsCount Count of GIC IRS.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
AddGICIrsList (
|
||||||
|
IN EFI_ACPI_6_7_GIC_IRS_STRUCTURE *GicIrs,
|
||||||
|
IN CONST CM_ARM_GIC_IRS_INFO *GicIrsInfo,
|
||||||
|
IN UINT32 GicIrsCount
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (GicIrs != NULL);
|
||||||
|
ASSERT (GicIrsInfo != NULL);
|
||||||
|
|
||||||
|
while (GicIrsCount-- != 0) {
|
||||||
|
AddGICInterruptRoutingService (GicIrs++, GicIrsInfo++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Add the GICv5 Interrupt Translation Service Information
|
||||||
|
to the MADT Table.
|
||||||
|
|
||||||
|
@param [in] GicItsV5 Pointer to GIC ITSv5 structure list.
|
||||||
|
@param [in] GicItsV5Info Pointer to the GIC ITSv5 list.
|
||||||
|
@param [in] GicItsV5Count Count of GIC ITSv5.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
AddGICItsV5List (
|
||||||
|
IN EFI_ACPI_6_7_GIC_ITSV5_STRUCTURE *GicItsV5,
|
||||||
|
IN CONST CM_ARM_GIC_ITSV5_INFO *GicItsV5Info,
|
||||||
|
IN UINT32 GicItsV5Count
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (GicItsV5 != NULL);
|
||||||
|
ASSERT (GicItsV5Info != NULL);
|
||||||
|
|
||||||
|
while (GicItsV5Count-- != 0) {
|
||||||
|
AddGICInterruptTranslationServiceV5 (GicItsV5++, GicItsV5Info++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Add the GICv5 Interrupt Translation Service Translate Frame Information
|
||||||
|
to the MADT Table.
|
||||||
|
|
||||||
|
@param [in] GicItsV5TranslateFrame Pointer to GIC ITSv5 Translate frame
|
||||||
|
structure list.
|
||||||
|
@param [in] GicItsV5TransFrameInfo Pointer to the GIC ITSv5
|
||||||
|
Translate frame list.
|
||||||
|
@param [in] GicItsV5TransFrameCount Count of GIC ITSv5.Translate frame.
|
||||||
|
|
||||||
|
@param [in] GicItsV5Info Pointer to the GIC ITSv5 list.
|
||||||
|
@param [in] GicItsV5Count Count of GIC ITSv5.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
AddGICItsV5TranslateFrameList (
|
||||||
|
IN EFI_ACPI_6_7_GIC_ITSV5_TRANSLATE_FRAME_STRUCTURE *GicItsV5TranslateFrame,
|
||||||
|
IN CONST CM_ARM_GIC_ITSV5_TRANSLATE_FRAME_INFO *GicItsV5TransFrameInfo,
|
||||||
|
IN UINT32 GicItsV5TransFrameCount,
|
||||||
|
IN CONST CM_ARM_GIC_ITSV5_INFO *GicItsV5Info,
|
||||||
|
IN UINT32 GicItsV5Count
|
||||||
|
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CONST CM_ARM_GIC_ITSV5_INFO *ItsInfo;
|
||||||
|
UINTN Idx;
|
||||||
|
|
||||||
|
ASSERT (GicItsV5TranslateFrame != NULL);
|
||||||
|
ASSERT (GicItsV5TransFrameInfo != NULL);
|
||||||
|
ASSERT (GicItsV5Info != NULL);
|
||||||
|
|
||||||
|
while (GicItsV5TransFrameCount-- != 0) {
|
||||||
|
ItsInfo = NULL;
|
||||||
|
|
||||||
|
for (Idx = 0; Idx < GicItsV5Count; Idx++) {
|
||||||
|
if (GicItsV5TransFrameInfo->ItsV5Token == GicItsV5Info[Idx].Token) {
|
||||||
|
ItsInfo = &GicItsV5Info[Idx];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ItsInfo == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddGICInterruptTranslationServiceV5TranslateFrame (
|
||||||
|
GicItsV5TranslateFrame++,
|
||||||
|
GicItsV5TransFrameInfo++,
|
||||||
|
ItsInfo
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/** Construct the MADT ACPI table.
|
/** Construct the MADT ACPI table.
|
||||||
|
|
||||||
This function invokes the Configuration Manager protocol interface
|
This function invokes the Configuration Manager protocol interface
|
||||||
|
|
@ -466,25 +732,34 @@ BuildMadtTable (
|
||||||
OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table
|
OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT32 TableSize;
|
UINT32 TableSize;
|
||||||
UINT32 GicCCount;
|
UINT32 GicCCount;
|
||||||
UINT32 GicDCount;
|
UINT32 GicDCount;
|
||||||
UINT32 GicMSICount;
|
UINT32 GicMSICount;
|
||||||
UINT32 GicRedistCount;
|
UINT32 GicRedistCount;
|
||||||
UINT32 GicItsCount;
|
UINT32 GicItsCount;
|
||||||
CM_ARM_GICC_INFO *GicCInfo;
|
UINT32 GicIrsCount;
|
||||||
CM_ARM_GICD_INFO *GicDInfo;
|
UINT32 GicItsV5Count;
|
||||||
CM_ARM_GIC_MSI_FRAME_INFO *GicMSIInfo;
|
UINT32 GicItsV5TransFrameCount;
|
||||||
CM_ARM_GIC_REDIST_INFO *GicRedistInfo;
|
CM_ARM_GICC_INFO *GicCInfo;
|
||||||
CM_ARM_GIC_ITS_INFO *GicItsInfo;
|
CM_ARM_GICD_INFO *GicDInfo;
|
||||||
UINT32 GicCOffset;
|
CM_ARM_GIC_MSI_FRAME_INFO *GicMSIInfo;
|
||||||
UINT32 GicDOffset;
|
CM_ARM_GIC_REDIST_INFO *GicRedistInfo;
|
||||||
UINT32 GicMSIOffset;
|
CM_ARM_GIC_ITS_INFO *GicItsInfo;
|
||||||
UINT32 GicRedistOffset;
|
CM_ARM_GIC_IRS_INFO *GicIrsInfo;
|
||||||
UINT32 GicItsOffset;
|
CM_ARM_GIC_ITSV5_INFO *GicItsV5Info;
|
||||||
|
CM_ARM_GIC_ITSV5_TRANSLATE_FRAME_INFO *GicItsV5TransFrameInfo;
|
||||||
|
UINT32 GicCOffset;
|
||||||
|
UINT32 GicDOffset;
|
||||||
|
UINT32 GicMSIOffset;
|
||||||
|
UINT32 GicRedistOffset;
|
||||||
|
UINT32 GicItsOffset;
|
||||||
|
UINT32 GicIrsOffset;
|
||||||
|
UINT32 GicItsV5Offset;
|
||||||
|
UINT32 GicItsV5TranslateFrameOffset;
|
||||||
|
|
||||||
EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *Madt;
|
EFI_ACPI_6_7_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *Madt;
|
||||||
|
|
||||||
ASSERT (This != NULL);
|
ASSERT (This != NULL);
|
||||||
ASSERT (AcpiTableInfo != NULL);
|
ASSERT (AcpiTableInfo != NULL);
|
||||||
|
|
@ -540,7 +815,10 @@ BuildMadtTable (
|
||||||
&GicDInfo,
|
&GicDInfo,
|
||||||
&GicDCount
|
&GicDCount
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status) &&
|
||||||
|
((AcpiTableInfo->AcpiTableRevision < EFI_ACPI_6_7_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) ||
|
||||||
|
(Status != EFI_NOT_FOUND)))
|
||||||
|
{
|
||||||
DEBUG ((
|
DEBUG ((
|
||||||
DEBUG_ERROR,
|
DEBUG_ERROR,
|
||||||
"ERROR: MADT: Failed to get GICD Info. Status = %r\n",
|
"ERROR: MADT: Failed to get GICD Info. Status = %r\n",
|
||||||
|
|
@ -549,16 +827,6 @@ BuildMadtTable (
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GicDCount == 0) {
|
|
||||||
DEBUG ((
|
|
||||||
DEBUG_ERROR,
|
|
||||||
"ERROR: MADT: GIC Distributor information not provided.\n"
|
|
||||||
));
|
|
||||||
ASSERT (GicDCount != 0);
|
|
||||||
Status = EFI_INVALID_PARAMETER;
|
|
||||||
goto error_handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GicDCount > 1) {
|
if (GicDCount > 1) {
|
||||||
DEBUG ((
|
DEBUG ((
|
||||||
DEBUG_ERROR,
|
DEBUG_ERROR,
|
||||||
|
|
@ -616,10 +884,77 @@ BuildMadtTable (
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
TableSize = sizeof (EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);
|
Status = GetEArmObjGicIrsInfo (
|
||||||
|
CfgMgrProtocol,
|
||||||
|
CM_NULL_TOKEN,
|
||||||
|
&GicIrsInfo,
|
||||||
|
&GicIrsCount
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: MADT: Failed to get GIC IRS Info. Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = GetEArmObjGicItsV5Info (
|
||||||
|
CfgMgrProtocol,
|
||||||
|
CM_NULL_TOKEN,
|
||||||
|
&GicItsV5Info,
|
||||||
|
&GicItsV5Count
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: MADT: Failed to get GIC ITSv5 Info. Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = GetEArmObjGicItsV5TranslateFrameInfo (
|
||||||
|
CfgMgrProtocol,
|
||||||
|
CM_NULL_TOKEN,
|
||||||
|
&GicItsV5TransFrameInfo,
|
||||||
|
&GicItsV5TransFrameCount
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: MADT: Failed to get GIC ITSv5 Info. Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((GicIrsCount == 0) && (GicDCount == 0)) ||
|
||||||
|
((GicIrsCount > 0) && (GicDCount > 0)))
|
||||||
|
{
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: MADT: No GicIrs and GicD Info or have both. Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((GicItsV5Count != 0) && (GicItsV5Count > GicItsV5TransFrameCount)) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: MADT: Each GicItsV5 should have at least 1 Translate Frame. Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
TableSize = sizeof (EFI_ACPI_6_7_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);
|
||||||
|
|
||||||
GicCOffset = TableSize;
|
GicCOffset = TableSize;
|
||||||
TableSize += (sizeof (EFI_ACPI_6_5_GIC_STRUCTURE) * GicCCount);
|
TableSize += (sizeof (EFI_ACPI_6_7_GIC_STRUCTURE) * GicCCount);
|
||||||
|
|
||||||
GicDOffset = TableSize;
|
GicDOffset = TableSize;
|
||||||
TableSize += (sizeof (EFI_ACPI_6_5_GIC_DISTRIBUTOR_STRUCTURE) * GicDCount);
|
TableSize += (sizeof (EFI_ACPI_6_5_GIC_DISTRIBUTOR_STRUCTURE) * GicDCount);
|
||||||
|
|
@ -633,6 +968,15 @@ BuildMadtTable (
|
||||||
GicItsOffset = TableSize;
|
GicItsOffset = TableSize;
|
||||||
TableSize += (sizeof (EFI_ACPI_6_5_GIC_ITS_STRUCTURE) * GicItsCount);
|
TableSize += (sizeof (EFI_ACPI_6_5_GIC_ITS_STRUCTURE) * GicItsCount);
|
||||||
|
|
||||||
|
GicIrsOffset = TableSize;
|
||||||
|
TableSize += (sizeof (EFI_ACPI_6_7_GIC_IRS_STRUCTURE) * GicIrsCount);
|
||||||
|
|
||||||
|
GicItsV5Offset = TableSize;
|
||||||
|
TableSize += (sizeof (EFI_ACPI_6_7_GIC_ITSV5_STRUCTURE) * GicItsV5Count);
|
||||||
|
|
||||||
|
GicItsV5TranslateFrameOffset = TableSize;
|
||||||
|
TableSize += (sizeof (EFI_ACPI_6_7_GIC_ITSV5_TRANSLATE_FRAME_STRUCTURE) * GicItsV5TransFrameCount);
|
||||||
|
|
||||||
// Allocate the Buffer for MADT table
|
// Allocate the Buffer for MADT table
|
||||||
*Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize);
|
*Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize);
|
||||||
if (*Table == NULL) {
|
if (*Table == NULL) {
|
||||||
|
|
@ -647,7 +991,7 @@ BuildMadtTable (
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
Madt = (EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)*Table;
|
Madt = (EFI_ACPI_6_7_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)*Table;
|
||||||
|
|
||||||
DEBUG ((
|
DEBUG ((
|
||||||
DEBUG_INFO,
|
DEBUG_INFO,
|
||||||
|
|
@ -673,9 +1017,11 @@ BuildMadtTable (
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = AddGICCList (
|
Status = AddGICCList (
|
||||||
(EFI_ACPI_6_5_GIC_STRUCTURE *)((UINT8 *)Madt + GicCOffset),
|
(EFI_ACPI_6_7_GIC_STRUCTURE *)((UINT8 *)Madt + GicCOffset),
|
||||||
GicCInfo,
|
GicCInfo,
|
||||||
GicCCount,
|
GicCCount,
|
||||||
|
GicIrsInfo,
|
||||||
|
GicIrsCount,
|
||||||
Madt->Header.Revision,
|
Madt->Header.Revision,
|
||||||
GicRedistCount != 0
|
GicRedistCount != 0
|
||||||
);
|
);
|
||||||
|
|
@ -688,10 +1034,12 @@ BuildMadtTable (
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddGICD (
|
if (GicDCount != 0) {
|
||||||
(EFI_ACPI_6_5_GIC_DISTRIBUTOR_STRUCTURE *)((UINT8 *)Madt + GicDOffset),
|
AddGICD (
|
||||||
GicDInfo
|
(EFI_ACPI_6_5_GIC_DISTRIBUTOR_STRUCTURE *)((UINT8 *)Madt + GicDOffset),
|
||||||
);
|
GicDInfo
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (GicMSICount != 0) {
|
if (GicMSICount != 0) {
|
||||||
AddGICMsiFrameInfoList (
|
AddGICMsiFrameInfoList (
|
||||||
|
|
@ -717,6 +1065,40 @@ BuildMadtTable (
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GicIrsCount != 0) {
|
||||||
|
AddGICIrsList (
|
||||||
|
(EFI_ACPI_6_7_GIC_IRS_STRUCTURE *)((UINT8 *)Madt + GicIrsOffset),
|
||||||
|
GicIrsInfo,
|
||||||
|
GicIrsCount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GicItsV5Count != 0) {
|
||||||
|
AddGICItsV5List (
|
||||||
|
(EFI_ACPI_6_7_GIC_ITSV5_STRUCTURE *)((UINT8 *)Madt + GicItsV5Offset),
|
||||||
|
GicItsV5Info,
|
||||||
|
GicItsV5Count
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GicItsV5TransFrameCount != 0) {
|
||||||
|
Status = AddGICItsV5TranslateFrameList (
|
||||||
|
(EFI_ACPI_6_7_GIC_ITSV5_TRANSLATE_FRAME_STRUCTURE *)((UINT8 *)Madt + GicItsV5TranslateFrameOffset),
|
||||||
|
GicItsV5TransFrameInfo,
|
||||||
|
GicItsV5TransFrameCount,
|
||||||
|
GicItsV5Info,
|
||||||
|
GicItsV5Count
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: MADT: Failed to add GIC ITSv5 translate frame structures. Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
error_handler:
|
error_handler:
|
||||||
|
|
@ -779,9 +1161,9 @@ ACPI_TABLE_GENERATOR MadtGenerator = {
|
||||||
// Generator Description
|
// Generator Description
|
||||||
L"ACPI.STD.MADT.GENERATOR",
|
L"ACPI.STD.MADT.GENERATOR",
|
||||||
// ACPI Table Signature
|
// ACPI Table Signature
|
||||||
EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
|
EFI_ACPI_6_7_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
|
||||||
// ACPI Table Revision supported by this Generator
|
// ACPI Table Revision supported by this Generator
|
||||||
EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
|
EFI_ACPI_6_7_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
|
||||||
// Minimum supported ACPI Table Revision
|
// Minimum supported ACPI Table Revision
|
||||||
EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
|
EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
|
||||||
// Creator ID
|
// Creator ID
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
/** @file
|
/** @file
|
||||||
Arm SRAT Table Generator
|
Arm SRAT Table Generator
|
||||||
|
|
||||||
Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.
|
Copyright (c) 2019 - 2026, Arm Limited. All rights reserved.
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
@par Reference(s):
|
@par Reference(s):
|
||||||
- ACPI 6.3 Specification, January 2019
|
- ACPI 6.7 Specification.
|
||||||
|
|
||||||
@par Glossary:
|
@par Glossary:
|
||||||
- Cm or CM - Configuration Manager
|
- Cm or CM - Configuration Manager
|
||||||
|
|
@ -56,12 +56,34 @@ GET_OBJECT_LIST (
|
||||||
CM_ARM_GIC_ITS_INFO
|
CM_ARM_GIC_ITS_INFO
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/** This macro expands to a function that retrieves the GIC
|
||||||
|
Interrupt Translation Service v5 Information from the
|
||||||
|
Configuration Manager.
|
||||||
|
*/
|
||||||
|
GET_OBJECT_LIST (
|
||||||
|
EObjNameSpaceArm,
|
||||||
|
EArmObjGicItsV5Info,
|
||||||
|
CM_ARM_GIC_ITSV5_INFO
|
||||||
|
);
|
||||||
|
|
||||||
|
/** This macro expands to a function that retrieves the GIC
|
||||||
|
Interrupt Routing Service Information from the
|
||||||
|
Configuration Manager.
|
||||||
|
*/
|
||||||
|
GET_OBJECT_LIST (
|
||||||
|
EObjNameSpaceArm,
|
||||||
|
EArmObjGicIrsInfo,
|
||||||
|
CM_ARM_GIC_IRS_INFO
|
||||||
|
);
|
||||||
|
|
||||||
/** Enum of the Arm specific CM objects required to
|
/** Enum of the Arm specific CM objects required to
|
||||||
build the arch specific information of the SRAT table.
|
build the arch specific information of the SRAT table.
|
||||||
*/
|
*/
|
||||||
typedef enum ArmSratSubTableType {
|
typedef enum ArmSratSubTableType {
|
||||||
EArmGicCSubTableType,
|
EArmGicCSubTableType,
|
||||||
EArmGicItsSubTableType,
|
EArmGicItsSubTableType,
|
||||||
|
EArmGicItsV5SubTableType,
|
||||||
|
EArmGicIrsSubTableType,
|
||||||
EArmSubTableTypeMax,
|
EArmSubTableTypeMax,
|
||||||
} EARM_SRAT_SUB_TABLE_TYPE;
|
} EARM_SRAT_SUB_TABLE_TYPE;
|
||||||
|
|
||||||
|
|
@ -146,16 +168,58 @@ ArchReserveOffsets (
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status = GetEArmObjGicItsV5Info (
|
||||||
|
CfgMgrProtocol,
|
||||||
|
CM_NULL_TOKEN,
|
||||||
|
(CM_ARM_GIC_ITSV5_INFO **)&mSratSubTable[EArmGicItsV5SubTableType].CmInfo,
|
||||||
|
&mSratSubTable[EArmGicItsV5SubTableType].Count
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: SRAT: Failed to get GIC ITSv5 Info. Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = GetEArmObjGicIrsInfo (
|
||||||
|
CfgMgrProtocol,
|
||||||
|
CM_NULL_TOKEN,
|
||||||
|
(CM_ARM_GIC_IRS_INFO **)&mSratSubTable[EArmGicIrsSubTableType].CmInfo,
|
||||||
|
&mSratSubTable[EArmGicIrsSubTableType].Count
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: SRAT: Failed to get GIC IRS Info. Status = %r\n",
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
mSratSubTable[EArmGicCSubTableType].Offset = *ArchOffset;
|
mSratSubTable[EArmGicCSubTableType].Offset = *ArchOffset;
|
||||||
*ArchOffset += (sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE) *
|
*ArchOffset += (sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE) *
|
||||||
mSratSubTable[EArmGicCSubTableType].Count);
|
mSratSubTable[EArmGicCSubTableType].Count);
|
||||||
|
|
||||||
if (mSratSubTable[EArmGicItsSubTableType].Count != 0) {
|
if (mSratSubTable[EArmGicItsSubTableType].Count != 0) {
|
||||||
mSratSubTable[EArmGicItsSubTableType].Offset = *ArchOffset;
|
mSratSubTable[EArmGicItsSubTableType].Offset = *ArchOffset;
|
||||||
*ArchOffset += (sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE) *
|
*ArchOffset += (sizeof (EFI_ACPI_6_7_GIC_ITS_AFFINITY_STRUCTURE) *
|
||||||
mSratSubTable[EArmGicItsSubTableType].Count);
|
mSratSubTable[EArmGicItsSubTableType].Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mSratSubTable[EArmGicItsV5SubTableType].Count != 0) {
|
||||||
|
mSratSubTable[EArmGicItsV5SubTableType].Offset = *ArchOffset;
|
||||||
|
*ArchOffset += (sizeof (EFI_ACPI_6_7_GIC_ITS_AFFINITY_STRUCTURE) *
|
||||||
|
mSratSubTable[EArmGicItsV5SubTableType].Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSratSubTable[EArmGicIrsSubTableType].Count != 0) {
|
||||||
|
mSratSubTable[EArmGicIrsSubTableType].Offset = *ArchOffset;
|
||||||
|
*ArchOffset += (sizeof (EFI_ACPI_6_7_GIC_IRS_AFFINITY_STRUCTURE) *
|
||||||
|
mSratSubTable[EArmGicIrsSubTableType].Count);
|
||||||
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,36 +286,55 @@ AddGICCAffinity (
|
||||||
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
|
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
|
||||||
Protocol Interface.
|
Protocol Interface.
|
||||||
@param [in] Srat Pointer to the SRAT Table.
|
@param [in] Srat Pointer to the SRAT Table.
|
||||||
|
@param [in] ItsType EArmGicItsSubTableType or EArmGicItsV5SubTableType.
|
||||||
**/
|
**/
|
||||||
STATIC
|
STATIC
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
AddGICItsAffinity (
|
AddGICItsAffinity (
|
||||||
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
|
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
|
||||||
IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat
|
IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat,
|
||||||
|
IN EARM_SRAT_SUB_TABLE_TYPE CONST ItsType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *GicItsAff;
|
EFI_ACPI_6_7_GIC_ITS_AFFINITY_STRUCTURE *GicItsAff;
|
||||||
CM_ARM_GIC_ITS_INFO *GicItsInfo;
|
CM_ARM_GIC_ITS_INFO *GicItsInfo;
|
||||||
|
CM_ARM_GIC_ITSV5_INFO *GicItsV5Info;
|
||||||
|
UINT32 ProximityDomain;
|
||||||
|
CM_OBJECT_TOKEN ProximityDomainToken;
|
||||||
|
|
||||||
GicItsInfo = mSratSubTable[EArmGicItsSubTableType].CmInfo;
|
if (ItsType == EArmGicItsSubTableType) {
|
||||||
GicItsAff = (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *)((UINT8 *)Srat +
|
GicItsInfo = mSratSubTable[ItsType].CmInfo;
|
||||||
mSratSubTable[EArmGicItsSubTableType].Offset);
|
} else {
|
||||||
|
GicItsV5Info = mSratSubTable[ItsType].CmInfo;
|
||||||
|
}
|
||||||
|
|
||||||
while (mSratSubTable[EArmGicItsSubTableType].Count-- != 0) {
|
GicItsAff = (EFI_ACPI_6_7_GIC_ITS_AFFINITY_STRUCTURE *)((UINT8 *)Srat +
|
||||||
|
mSratSubTable[ItsType].Offset);
|
||||||
|
|
||||||
|
while (mSratSubTable[ItsType].Count-- != 0) {
|
||||||
DEBUG ((DEBUG_INFO, "SRAT: GicItsAff = 0x%p\n", GicItsAff));
|
DEBUG ((DEBUG_INFO, "SRAT: GicItsAff = 0x%p\n", GicItsAff));
|
||||||
|
|
||||||
GicItsAff->Type = EFI_ACPI_6_3_GIC_ITS_AFFINITY;
|
GicItsAff->Type = EFI_ACPI_6_7_GIC_ITS_AFFINITY;
|
||||||
GicItsAff->Length = sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE);
|
GicItsAff->Length = sizeof (EFI_ACPI_6_7_GIC_ITS_AFFINITY_STRUCTURE);
|
||||||
GicItsAff->Reserved[0] = EFI_ACPI_RESERVED_BYTE;
|
GicItsAff->Reserved[0] = EFI_ACPI_RESERVED_BYTE;
|
||||||
GicItsAff->Reserved[1] = EFI_ACPI_RESERVED_BYTE;
|
GicItsAff->Reserved[1] = EFI_ACPI_RESERVED_BYTE;
|
||||||
GicItsAff->ItsId = GicItsInfo->GicItsId;
|
|
||||||
|
if (ItsType == EArmGicItsSubTableType) {
|
||||||
|
ProximityDomain = GicItsInfo->ProximityDomain;
|
||||||
|
ProximityDomainToken = GicItsInfo->ProximityDomainToken;
|
||||||
|
GicItsAff->ItsId = GicItsInfo->GicItsId;
|
||||||
|
} else {
|
||||||
|
ProximityDomain = GicItsV5Info->ProximityDomain;
|
||||||
|
ProximityDomainToken = GicItsV5Info->ProximityDomainToken;
|
||||||
|
GicItsAff->ItsId = GicItsV5Info->GicItsId;
|
||||||
|
}
|
||||||
|
|
||||||
Status = GetProximityDomainId (
|
Status = GetProximityDomainId (
|
||||||
CfgMgrProtocol,
|
CfgMgrProtocol,
|
||||||
GicItsInfo->ProximityDomain,
|
ProximityDomain,
|
||||||
GicItsInfo->ProximityDomainToken,
|
ProximityDomainToken,
|
||||||
&GicItsAff->ProximityDomain
|
&GicItsAff->ProximityDomain
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
|
@ -265,6 +348,54 @@ AddGICItsAffinity (
|
||||||
}// while
|
}// while
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Add the GIC IRS Affinity Structures in the SRAT Table.
|
||||||
|
|
||||||
|
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
|
||||||
|
Protocol Interface.
|
||||||
|
@param [in] Srat Pointer to the SRAT Table.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
AddGICIrsAffinity (
|
||||||
|
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
|
||||||
|
IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_ACPI_6_7_GIC_IRS_AFFINITY_STRUCTURE *GicIrsAff;
|
||||||
|
CM_ARM_GIC_IRS_INFO *GicIrsInfo;
|
||||||
|
|
||||||
|
GicIrsInfo = mSratSubTable[EArmGicIrsSubTableType].CmInfo;
|
||||||
|
GicIrsAff = (EFI_ACPI_6_7_GIC_IRS_AFFINITY_STRUCTURE *)((UINT8 *)Srat +
|
||||||
|
mSratSubTable[EArmGicIrsSubTableType].Offset);
|
||||||
|
|
||||||
|
while (mSratSubTable[EArmGicIrsSubTableType].Count-- != 0) {
|
||||||
|
DEBUG ((DEBUG_INFO, "SRAT: GicIrsAff = 0x%p\n", GicIrsAff));
|
||||||
|
|
||||||
|
GicIrsAff->Type = EFI_ACPI_6_7_GIC_IRS_AFFINITY;
|
||||||
|
GicIrsAff->Length = sizeof (EFI_ACPI_6_7_GIC_IRS_AFFINITY_STRUCTURE);
|
||||||
|
GicIrsAff->Reserved = EFI_ACPI_RESERVED_WORD;
|
||||||
|
GicIrsAff->IrsId = GicIrsInfo->GicIrsId;
|
||||||
|
GicIrsAff->Reserved2 = EFI_ACPI_RESERVED_DWORD;
|
||||||
|
|
||||||
|
Status = GetProximityDomainId (
|
||||||
|
CfgMgrProtocol,
|
||||||
|
GicIrsInfo->ProximityDomain,
|
||||||
|
GicIrsInfo->ProximityDomainToken,
|
||||||
|
&GicIrsAff->ProximityDomain
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next
|
||||||
|
GicIrsAff++;
|
||||||
|
GicIrsInfo++;
|
||||||
|
}// while
|
||||||
|
}
|
||||||
|
|
||||||
/** Add the arch specific sub-tables to the SRAT table.
|
/** Add the arch specific sub-tables to the SRAT table.
|
||||||
|
|
||||||
These sub-tables are written in the space reserved beforehand.
|
These sub-tables are written in the space reserved beforehand.
|
||||||
|
|
@ -287,8 +418,16 @@ AddArchObjects (
|
||||||
|
|
||||||
AddGICCAffinity (CfgMgrProtocol, Srat);
|
AddGICCAffinity (CfgMgrProtocol, Srat);
|
||||||
|
|
||||||
if (mSratSubTable[EArmGicCSubTableType].Count != 0) {
|
if (mSratSubTable[EArmGicItsSubTableType].Count != 0) {
|
||||||
AddGICItsAffinity (CfgMgrProtocol, Srat);
|
AddGICItsAffinity (CfgMgrProtocol, Srat, EArmGicItsSubTableType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSratSubTable[EArmGicItsV5SubTableType].Count != 0) {
|
||||||
|
AddGICItsAffinity (CfgMgrProtocol, Srat, EArmGicItsV5SubTableType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSratSubTable[EArmGicIrsSubTableType].Count != 0) {
|
||||||
|
AddGICIrsAffinity (CfgMgrProtocol, Srat);
|
||||||
}
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
/** @file
|
/** @file
|
||||||
SRAT Table Generator
|
SRAT Table Generator
|
||||||
|
|
||||||
Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.
|
Copyright (c) 2019 - 2026, Arm Limited. All rights reserved.
|
||||||
Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved.
|
Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
@par Reference(s):
|
@par Reference(s):
|
||||||
- ACPI 6.3 Specification, January 2019
|
- ACPI 6.7 Specification.
|
||||||
|
|
||||||
@par Glossary:
|
@par Glossary:
|
||||||
- Cm or CM - Configuration Manager
|
- Cm or CM - Configuration Manager
|
||||||
|
|
@ -623,9 +623,9 @@ ACPI_TABLE_GENERATOR SratGenerator = {
|
||||||
// Generator Description
|
// Generator Description
|
||||||
L"ACPI.STD.SRAT.GENERATOR",
|
L"ACPI.STD.SRAT.GENERATOR",
|
||||||
// ACPI Table Signature
|
// ACPI Table Signature
|
||||||
EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE,
|
EFI_ACPI_6_7_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE,
|
||||||
// ACPI Table Revision supported by this Generator
|
// ACPI Table Revision supported by this Generator
|
||||||
EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION,
|
EFI_ACPI_6_7_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION,
|
||||||
// Minimum supported ACPI Table Revision
|
// Minimum supported ACPI Table Revision
|
||||||
EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION,
|
EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION,
|
||||||
// Creator ID
|
// Creator ID
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
/** @file
|
||||||
|
SSDT Serial Port Fixup Library.
|
||||||
|
|
||||||
|
Copyright (c) 2026, Arm Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
@par Reference(s):
|
||||||
|
- Arm Server Base Boot Requirements (SBBR), s4.2.1.8 "SPCR".
|
||||||
|
- Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.
|
||||||
|
- ACPI for Arm Components 1.0 - 2020
|
||||||
|
- Arm Generic Interrupt Controller Architecture Specification,
|
||||||
|
Issue H, January 2022.
|
||||||
|
(https://developer.arm.com/documentation/ihi0069/)
|
||||||
|
**/
|
||||||
|
#include <Library/ArmLib.h>
|
||||||
|
#include <Library/ArmGicLib.h>
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
|
||||||
|
#include <ArchCommonNameSpaceObjects.h>
|
||||||
|
|
||||||
|
/** Validate the Serial Port Architecture Information.
|
||||||
|
|
||||||
|
@param [in] SerialPortInfoTable Table of CM_ARCH_COMMON_SERIAL_PORT_INFO.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Success.
|
||||||
|
@retval EFI_INVALID_PARAMETER Invalid parameter.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
ArchValidateSerialPortInfo (
|
||||||
|
IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN ValidInterrupt;
|
||||||
|
|
||||||
|
if (SerialPortInfo == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If an interrupt is not wired to the serial port, the Configuration
|
||||||
|
// Manager specifies the interrupt as 0.
|
||||||
|
// Any other value must be within the SPI or extended SPI range.
|
||||||
|
if ((SerialPortInfo->Interrupt != 0)) {
|
||||||
|
ValidInterrupt = FALSE;
|
||||||
|
|
||||||
|
if (ArmHasGicV5SystemRegisters ()) {
|
||||||
|
if ((SerialPortInfo->Interrupt >= ARM_GICV5_ARCH_SPI_MIN) &&
|
||||||
|
(SerialPortInfo->Interrupt <= ARM_GICV5_ARCH_SPI_MAX))
|
||||||
|
{
|
||||||
|
ValidInterrupt = TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (((SerialPortInfo->Interrupt >= ARM_GIC_ARCH_SPI_MIN) &&
|
||||||
|
(SerialPortInfo->Interrupt <= ARM_GIC_ARCH_SPI_MAX)) ||
|
||||||
|
((SerialPortInfo->Interrupt >= ARM_GIC_ARCH_EXT_SPI_MIN) &&
|
||||||
|
(SerialPortInfo->Interrupt <= ARM_GIC_ARCH_EXT_SPI_MAX)))
|
||||||
|
{
|
||||||
|
ValidInterrupt = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ValidInterrupt) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"ERROR: Invalid UART port interrupt ID. Interrupt = %lu\n",
|
||||||
|
SerialPortInfo->Interrupt
|
||||||
|
));
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
/** @file
|
||||||
|
SSDT Serial Port Fixup Library.
|
||||||
|
|
||||||
|
Copyright (c) 2026, Arm Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
@par Reference(s):
|
||||||
|
- Arm Server Base Boot Requirements (SBBR), s4.2.1.8 "SPCR".
|
||||||
|
- Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.
|
||||||
|
- ACPI for Arm Components 1.0 - 2020
|
||||||
|
- Arm Generic Interrupt Controller Architecture Specification,
|
||||||
|
Issue H, January 2022.
|
||||||
|
(https://developer.arm.com/documentation/ihi0069/)
|
||||||
|
**/
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
|
||||||
|
#include <ArchCommonNameSpaceObjects.h>
|
||||||
|
|
||||||
|
/** Validate the Serial Port Architecture Information.
|
||||||
|
|
||||||
|
@param [in] SerialPortInfoTable Table of CM_ARCH_COMMON_SERIAL_PORT_INFO.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Success.
|
||||||
|
@retval EFI_INVALID_PARAMETER Invalid parameter.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
ArchValidateSerialPortInfo (
|
||||||
|
IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/// Nothing to do.
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
@ -28,12 +28,9 @@
|
||||||
#include <ConfigurationManagerHelper.h>
|
#include <ConfigurationManagerHelper.h>
|
||||||
#include <Library/AcpiHelperLib.h>
|
#include <Library/AcpiHelperLib.h>
|
||||||
#include <Library/AmlLib/AmlLib.h>
|
#include <Library/AmlLib/AmlLib.h>
|
||||||
|
#include <Library/SsdtSerialPortFixupLib.h>
|
||||||
#include <Protocol/ConfigurationManagerProtocol.h>
|
#include <Protocol/ConfigurationManagerProtocol.h>
|
||||||
|
|
||||||
#if defined (MDE_CPU_AARCH64)
|
|
||||||
#include <Library/ArmGicLib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** C array containing the compiled AML template.
|
/** C array containing the compiled AML template.
|
||||||
This symbol is defined in the auto generated C file
|
This symbol is defined in the auto generated C file
|
||||||
containing the AML bytecode array.
|
containing the AML bytecode array.
|
||||||
|
|
@ -61,6 +58,7 @@ ValidateSerialPortInfo (
|
||||||
{
|
{
|
||||||
UINT32 Index;
|
UINT32 Index;
|
||||||
CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo;
|
CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
if ((SerialPortInfoTable == NULL) ||
|
if ((SerialPortInfoTable == NULL) ||
|
||||||
(SerialPortCount == 0))
|
(SerialPortCount == 0))
|
||||||
|
|
@ -107,26 +105,11 @@ ValidateSerialPortInfo (
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (MDE_CPU_AARCH64)
|
Status = ArchValidateSerialPortInfo (SerialPortInfo);
|
||||||
// If an interrupt is not wired to the serial port, the Configuration
|
if (EFI_ERROR (Status)) {
|
||||||
// Manager specifies the interrupt as 0.
|
return Status;
|
||||||
// Any other value must be within the SPI or extended SPI range.
|
|
||||||
if ((SerialPortInfo->Interrupt != 0) &&
|
|
||||||
!(((SerialPortInfo->Interrupt >= ARM_GIC_ARCH_SPI_MIN) &&
|
|
||||||
(SerialPortInfo->Interrupt <= ARM_GIC_ARCH_SPI_MAX)) ||
|
|
||||||
((SerialPortInfo->Interrupt >= ARM_GIC_ARCH_EXT_SPI_MIN) &&
|
|
||||||
(SerialPortInfo->Interrupt <= ARM_GIC_ARCH_EXT_SPI_MAX))))
|
|
||||||
{
|
|
||||||
DEBUG ((
|
|
||||||
DEBUG_ERROR,
|
|
||||||
"ERROR: Invalid UART port interrupt ID. Interrupt = %lu\n",
|
|
||||||
SerialPortInfo->Interrupt
|
|
||||||
));
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO, "UART Configuration:\n"));
|
DEBUG ((DEBUG_INFO, "UART Configuration:\n"));
|
||||||
DEBUG ((
|
DEBUG ((
|
||||||
DEBUG_INFO,
|
DEBUG_INFO,
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,15 @@
|
||||||
SsdtSerialPortFixupLib.c
|
SsdtSerialPortFixupLib.c
|
||||||
SsdtSerialPortTemplate.asl
|
SsdtSerialPortTemplate.asl
|
||||||
|
|
||||||
|
[Sources.AARCH64]
|
||||||
|
Arm/ArmSsdtSerialPortFixupLib.c
|
||||||
|
|
||||||
|
[Sources.IA32, Sources.X64]
|
||||||
|
X64/X64SsdtSerialPortFixupLib.c
|
||||||
|
|
||||||
|
[Sources.RISCV64]
|
||||||
|
RiscV/RiscVSsdtSerialPortFixupLib.c
|
||||||
|
|
||||||
[Packages.common]
|
[Packages.common]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
MdeModulePkg/MdeModulePkg.dec
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
|
|
@ -32,5 +41,8 @@
|
||||||
AmlLib
|
AmlLib
|
||||||
BaseLib
|
BaseLib
|
||||||
|
|
||||||
|
[LibraryClasses.AARCH64]
|
||||||
|
ArmLib
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gEdkiiDynamicTablesPkgTokenSpaceGuid.PcdNonBsaCompliant16550SerialHid
|
gEdkiiDynamicTablesPkgTokenSpaceGuid.PcdNonBsaCompliant16550SerialHid
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
/** @file
|
||||||
|
SSDT Serial Port Fixup Library.
|
||||||
|
|
||||||
|
Copyright (c) 2026, Arm Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
@par Reference(s):
|
||||||
|
- Arm Server Base Boot Requirements (SBBR), s4.2.1.8 "SPCR".
|
||||||
|
- Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.
|
||||||
|
- ACPI for Arm Components 1.0 - 2020
|
||||||
|
- Arm Generic Interrupt Controller Architecture Specification,
|
||||||
|
Issue H, January 2022.
|
||||||
|
(https://developer.arm.com/documentation/ihi0069/)
|
||||||
|
**/
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
|
||||||
|
#include <ArchCommonNameSpaceObjects.h>
|
||||||
|
|
||||||
|
/** Validate the Serial Port Architecture Information.
|
||||||
|
|
||||||
|
@param [in] SerialPortInfoTable Table of CM_ARCH_COMMON_SERIAL_PORT_INFO.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Success.
|
||||||
|
@retval EFI_INVALID_PARAMETER Invalid parameter.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
ArchValidateSerialPortInfo (
|
||||||
|
IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/// Nothing to do.
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
@ -11,4 +11,4 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <IndustryStandard/Acpi66.h>
|
#include <IndustryStandard/Acpi67.h>
|
||||||
|
|
|
||||||
3741
MdePkg/Include/IndustryStandard/Acpi67.h
Normal file
3741
MdePkg/Include/IndustryStandard/Acpi67.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -29,6 +29,7 @@
|
||||||
#define EFI_ACPI_IO_REMAPPING_TABLE_REVISION_04 0x4 // Deprecated
|
#define EFI_ACPI_IO_REMAPPING_TABLE_REVISION_04 0x4 // Deprecated
|
||||||
#define EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05 0x5
|
#define EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05 0x5
|
||||||
#define EFI_ACPI_IO_REMAPPING_TABLE_REVISION_06 0x6
|
#define EFI_ACPI_IO_REMAPPING_TABLE_REVISION_06 0x6
|
||||||
|
#define EFI_ACPI_IO_REMAPPING_TABLE_REVISION_07 0x7
|
||||||
|
|
||||||
#define EFI_ACPI_IORT_TYPE_ITS_GROUP 0x0
|
#define EFI_ACPI_IORT_TYPE_ITS_GROUP 0x0
|
||||||
#define EFI_ACPI_IORT_TYPE_NAMED_COMP 0x1
|
#define EFI_ACPI_IORT_TYPE_NAMED_COMP 0x1
|
||||||
|
|
@ -37,6 +38,7 @@
|
||||||
#define EFI_ACPI_IORT_TYPE_SMMUv3 0x4
|
#define EFI_ACPI_IORT_TYPE_SMMUv3 0x4
|
||||||
#define EFI_ACPI_IORT_TYPE_PMCG 0x5
|
#define EFI_ACPI_IORT_TYPE_PMCG 0x5
|
||||||
#define EFI_ACPI_IORT_TYPE_RMR 0x6
|
#define EFI_ACPI_IORT_TYPE_RMR 0x6
|
||||||
|
#define EFI_ACPI_IORT_TYPE_IWB 0x7
|
||||||
|
|
||||||
#define EFI_ACPI_IORT_MEM_ACCESS_PROP_CCA BIT0
|
#define EFI_ACPI_IORT_MEM_ACCESS_PROP_CCA BIT0
|
||||||
|
|
||||||
|
|
@ -279,4 +281,16 @@ typedef struct {
|
||||||
// EFI_ACPI_6_0_IO_REMAPPING_MEM_RANGE_DESC MemRangeDesc[1];
|
// EFI_ACPI_6_0_IO_REMAPPING_MEM_RANGE_DESC MemRangeDesc[1];
|
||||||
} EFI_ACPI_6_0_IO_REMAPPING_RMR_NODE;
|
} EFI_ACPI_6_0_IO_REMAPPING_RMR_NODE;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Node type 7: IWB node
|
||||||
|
///
|
||||||
|
typedef struct {
|
||||||
|
EFI_ACPI_6_0_IO_REMAPPING_NODE Node;
|
||||||
|
|
||||||
|
UINT64 ConfigFrameBase;
|
||||||
|
UINT16 IwbIndex;
|
||||||
|
// UINT8 ObjectName[];
|
||||||
|
// EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE IdMapping[1];
|
||||||
|
} EFI_ACPI_6_0_IO_REMAPPING_IWB_NODE;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@
|
||||||
"Include/Guid/Cper.h",
|
"Include/Guid/Cper.h",
|
||||||
"Include/IndustryStandard/Acpi64.h",
|
"Include/IndustryStandard/Acpi64.h",
|
||||||
"Include/IndustryStandard/Acpi65.h",
|
"Include/IndustryStandard/Acpi65.h",
|
||||||
|
"Include/IndustryStandard/Acpi67.h",
|
||||||
"Include/IndustryStandard/Tpm12.h",
|
"Include/IndustryStandard/Tpm12.h",
|
||||||
"Include/IndustryStandard/Tpm20.h",
|
"Include/IndustryStandard/Tpm20.h",
|
||||||
"Include/IndustryStandard/IoRemappingTable.h",
|
"Include/IndustryStandard/IoRemappingTable.h",
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
@par Reference(s):
|
@par Reference(s):
|
||||||
- IO Remapping Table, Platform Design Document, Revision E.d, Feb 2022
|
- IO Remapping Table, Platform Design Document, Revision E.f, Apr 2024
|
||||||
(https://developer.arm.com/documentation/den0049/)
|
(https://developer.arm.com/documentation/den0049/)
|
||||||
|
|
||||||
@par Glossary:
|
@par Glossary:
|
||||||
|
|
@ -162,6 +162,52 @@ ValidateRmrMemDescCount (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function validates the ID Mapping array count for the IWB node.
|
||||||
|
|
||||||
|
@param [in] Ptr Pointer to the start of the field data.
|
||||||
|
@param [in] Length Length of the field.
|
||||||
|
@param [in] Context Pointer to context specific information e.g. this
|
||||||
|
could be a pointer to the ACPI table header.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ValidateIwbIdMappingCount (
|
||||||
|
IN UINT8 *Ptr,
|
||||||
|
IN UINT32 Length,
|
||||||
|
IN VOID *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (*(UINT32 *)Ptr != 1) {
|
||||||
|
IncrementErrorCount ();
|
||||||
|
Print (L"\nERROR: IORT ID Mapping count must be equal to 1.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function validates the ID Mapping array offset for the IWB node.
|
||||||
|
|
||||||
|
@param [in] Ptr Pointer to the start of the field data.
|
||||||
|
@param [in] Length Length of the field.
|
||||||
|
@param [in] Context Pointer to context specific information e.g. this
|
||||||
|
could be a pointer to the ACPI table header.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ValidateIwbIdArrayReference (
|
||||||
|
IN UINT8 *Ptr,
|
||||||
|
IN UINT32 Length,
|
||||||
|
IN VOID *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (*(UINT32 *)Ptr == 0) {
|
||||||
|
IncrementErrorCount ();
|
||||||
|
Print (L"\nERROR: IORT ID Mapping offset must non-zero.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Helper Macro for populating the IORT Node header in the ACPI_PARSER array.
|
Helper Macro for populating the IORT Node header in the ACPI_PARSER array.
|
||||||
|
|
||||||
|
|
@ -340,6 +386,18 @@ STATIC CONST ACPI_PARSER IortNodeRmrMemRangeDescParser[] = {
|
||||||
{ L"Reserved", 4, 16, L"0x%x", NULL, NULL, NULL, NULL}
|
{ L"Reserved", 4, 16, L"0x%x", NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
An ACPI_PARSER array describing the IORT IWB node.
|
||||||
|
**/
|
||||||
|
STATIC CONST ACPI_PARSER IortNodeIwbParser[] = {
|
||||||
|
PARSE_IORT_NODE_HEADER (
|
||||||
|
ValidateIwbIdMappingCount,
|
||||||
|
ValidateIwbIdArrayReference
|
||||||
|
),
|
||||||
|
{ L"Config frame base", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"IWB_index", 2, 24, L"%d", NULL, NULL, NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function parses the IORT Node Id Mapping array.
|
This function parses the IORT Node Id Mapping array.
|
||||||
|
|
||||||
|
|
@ -786,6 +844,54 @@ DumpIortNodeRmr (
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function parses the IORT IWB node.
|
||||||
|
|
||||||
|
@param [in] Ptr Pointer to the start of the buffer.
|
||||||
|
@param [in] Length Length of the buffer.
|
||||||
|
@param [in] MappingCount The ID Mapping count.
|
||||||
|
@param [in] MappingOffset The offset of the ID Mapping array
|
||||||
|
from the start of the IORT table.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
DumpIortNodeIwb (
|
||||||
|
IN UINT8 *Ptr,
|
||||||
|
IN UINT16 Length,
|
||||||
|
IN UINT32 MappingCount,
|
||||||
|
IN UINT32 MappingOffset
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 Offset;
|
||||||
|
|
||||||
|
Offset = ParseAcpi (
|
||||||
|
TRUE,
|
||||||
|
2,
|
||||||
|
"IWB Node",
|
||||||
|
Ptr,
|
||||||
|
Length,
|
||||||
|
PARSER_PARAMS (IortNodeIwbParser)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Estimate the Device Name length
|
||||||
|
PrintFieldName (2, L"Device Object Name");
|
||||||
|
|
||||||
|
while ((*(Ptr + Offset) != 0) &&
|
||||||
|
(Offset < Length))
|
||||||
|
{
|
||||||
|
Print (L"%c", *(Ptr + Offset));
|
||||||
|
Offset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Print (L"\n");
|
||||||
|
|
||||||
|
DumpIortNodeIdMappings (
|
||||||
|
Ptr + MappingOffset,
|
||||||
|
Length - MappingOffset,
|
||||||
|
MappingCount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function parses the ACPI IORT table.
|
This function parses the ACPI IORT table.
|
||||||
When trace is enabled this function parses the IORT table and traces the ACPI
|
When trace is enabled this function parses the IORT table and traces the ACPI
|
||||||
|
|
@ -799,6 +905,7 @@ DumpIortNodeRmr (
|
||||||
- SMMUv3
|
- SMMUv3
|
||||||
- PMCG
|
- PMCG
|
||||||
- RMR
|
- RMR
|
||||||
|
- IWB
|
||||||
|
|
||||||
This function also performs validation of the ACPI table fields.
|
This function also performs validation of the ACPI table fields.
|
||||||
|
|
||||||
|
|
@ -970,6 +1077,14 @@ ParseAcpiIort (
|
||||||
*IortIdMappingOffset
|
*IortIdMappingOffset
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case EFI_ACPI_IORT_TYPE_IWB:
|
||||||
|
DumpIortNodeIwb (
|
||||||
|
NodePtr,
|
||||||
|
*IortNodeLength,
|
||||||
|
*IortIdMappingCount,
|
||||||
|
*IortIdMappingOffset
|
||||||
|
);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
IncrementErrorCount ();
|
IncrementErrorCount ();
|
||||||
Print (L"ERROR: Unsupported IORT Node type = %d\n", *IortNodeType);
|
Print (L"ERROR: Unsupported IORT Node type = %d\n", *IortNodeType);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
MADT table parser
|
MADT table parser
|
||||||
|
|
||||||
Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
|
Copyright (c) 2016 - 2026, Arm Limited. All rights reserved.
|
||||||
Copyright (c) 2022, AMD Incorporated. All rights reserved.
|
Copyright (c) 2022, AMD Incorporated. All rights reserved.
|
||||||
Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.
|
Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
@ -84,7 +84,7 @@ ValidateSpeOverflowInterrupt (
|
||||||
IncrementErrorCount ();
|
IncrementErrorCount ();
|
||||||
Print (
|
Print (
|
||||||
L"\nERROR: SPE Overflow Interrupt ID of %d is not in the allowed PPI ID "
|
L"\nERROR: SPE Overflow Interrupt ID of %d is not in the allowed PPI ID "
|
||||||
L"ranges of %d-%d or %d-%d (for GICv3.1 or later).",
|
L"ranges of %d-%d or %d-%d (for GICv3.1 - 4).",
|
||||||
SpeOverflowInterrupt,
|
SpeOverflowInterrupt,
|
||||||
ARM_PPI_ID_MIN,
|
ARM_PPI_ID_MIN,
|
||||||
ARM_PPI_ID_MAX,
|
ARM_PPI_ID_MAX,
|
||||||
|
|
@ -136,7 +136,7 @@ ValidateTrbeInterrupt (
|
||||||
IncrementErrorCount ();
|
IncrementErrorCount ();
|
||||||
Print (
|
Print (
|
||||||
L"\nERROR: TRBE Interrupt ID of %d is not in the allowed PPI ID "
|
L"\nERROR: TRBE Interrupt ID of %d is not in the allowed PPI ID "
|
||||||
L"ranges of %d-%d or %d-%d (for GICv3.1 or later).",
|
L"ranges of %d-%d or %d-%d (for GICv3.1 - 4).",
|
||||||
TrbeInterrupt,
|
TrbeInterrupt,
|
||||||
ARM_PPI_ID_MIN,
|
ARM_PPI_ID_MIN,
|
||||||
ARM_PPI_ID_MAX,
|
ARM_PPI_ID_MAX,
|
||||||
|
|
@ -238,7 +238,9 @@ STATIC CONST ACPI_PARSER GicCParser[] = {
|
||||||
{ L"SPE overflow Interrupt", 2, 78, L"0x%x", NULL, NULL,
|
{ L"SPE overflow Interrupt", 2, 78, L"0x%x", NULL, NULL,
|
||||||
ValidateSpeOverflowInterrupt, NULL },
|
ValidateSpeOverflowInterrupt, NULL },
|
||||||
{ L"TRBE Interrupt", 2, 80, L"0x%x", NULL, NULL,
|
{ L"TRBE Interrupt", 2, 80, L"0x%x", NULL, NULL,
|
||||||
ValidateTrbeInterrupt, NULL }
|
ValidateTrbeInterrupt, NULL },
|
||||||
|
{ L"IAFFID", 2, 82, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"IrsID", 4, 84, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -485,6 +487,49 @@ STATIC CONST ACPI_PARSER LpcPic[] = {
|
||||||
{ L"Cascade vector", 2, 13, L"0x%x", NULL, NULL, NULL, NULL }
|
{ L"Cascade vector", 2, 13, L"0x%x", NULL, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
An ACPI_PARSER array describing the GIC IRS Interrupt Controller Structure.
|
||||||
|
**/
|
||||||
|
STATIC CONST ACPI_PARSER GicIrsParser[] = {
|
||||||
|
{ L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"GIC Version", 1, 2, L"%d", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"Reserved", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
|
||||||
|
{ L"GIC IRS ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"Flags", 4, 8, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"Reserved", 4, 12, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"IRS Config Frame Base", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"IRS Set LPI Frame Base", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
An ACPI_PARSER array describing the GIC ITSv5 Interrupt Controller Structure.
|
||||||
|
**/
|
||||||
|
STATIC CONST ACPI_PARSER GicItsV5Parser[] = {
|
||||||
|
{ L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"Flags", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"Reserved", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
|
||||||
|
{ L"GIC ITS ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"Physical Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
An ACPI_PARSER array describing the GIC ITSv5 Translate Frame Structure.
|
||||||
|
**/
|
||||||
|
STATIC CONST ACPI_PARSER GicItsV5TranslateFrameParser[] = {
|
||||||
|
{ L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
|
||||||
|
{ L"Linked GIC ITS ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"ITS Translate Frame ID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"Reserved", 4, 12, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"ITS Translate Frame Base Address", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
An ACPI_PARSER array describing the ACPI MADT Table.
|
An ACPI_PARSER array describing the ACPI MADT Table.
|
||||||
**/
|
**/
|
||||||
|
|
@ -517,6 +562,9 @@ STATIC CONST ACPI_PARSER MadtInterruptControllerHeaderParser[] = {
|
||||||
- GIC MSI Frame
|
- GIC MSI Frame
|
||||||
- GICR
|
- GICR
|
||||||
- GIC ITS
|
- GIC ITS
|
||||||
|
- GIC IRS
|
||||||
|
- GIC ITSv5
|
||||||
|
- GIC ITSv5 translate frame
|
||||||
|
|
||||||
This function also performs validation of the ACPI table fields.
|
This function also performs validation of the ACPI table fields.
|
||||||
|
|
||||||
|
|
@ -823,6 +871,45 @@ ParseAcpiMadt (
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case EFI_ACPI_6_7_GIC_IRS:
|
||||||
|
{
|
||||||
|
ParseAcpi (
|
||||||
|
TRUE,
|
||||||
|
2,
|
||||||
|
"GIC IRS",
|
||||||
|
InterruptContollerPtr,
|
||||||
|
*MadtInterruptControllerLength,
|
||||||
|
PARSER_PARAMS (GicIrsParser)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EFI_ACPI_6_7_GIC_ITSV5:
|
||||||
|
{
|
||||||
|
ParseAcpi (
|
||||||
|
TRUE,
|
||||||
|
2,
|
||||||
|
"GIC ITSv5",
|
||||||
|
InterruptContollerPtr,
|
||||||
|
*MadtInterruptControllerLength,
|
||||||
|
PARSER_PARAMS (GicItsV5Parser)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EFI_ACPI_6_7_GIC_ITSV5_TRANSLATE_FRAME:
|
||||||
|
{
|
||||||
|
ParseAcpi (
|
||||||
|
TRUE,
|
||||||
|
2,
|
||||||
|
"GIC ITSv5 Translate Frame",
|
||||||
|
InterruptContollerPtr,
|
||||||
|
*MadtInterruptControllerLength,
|
||||||
|
PARSER_PARAMS (GicItsV5TranslateFrameParser)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
IncrementErrorCount ();
|
IncrementErrorCount ();
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
/** @file
|
/** @file
|
||||||
SRAT table parser
|
SRAT table parser
|
||||||
|
|
||||||
Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
|
Copyright (c) 2016 - 2026, Arm Limited. All rights reserved.
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
@par Reference(s):
|
@par Reference(s):
|
||||||
- ACPI 6.3 Specification - January 2019
|
- ACPI 6.7 Specification
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#include <IndustryStandard/Acpi.h>
|
#include <IndustryStandard/Acpi.h>
|
||||||
|
|
@ -341,6 +341,19 @@ STATIC CONST ACPI_PARSER SratX2ApciAffinityParser[] = {
|
||||||
{ L"Reserved", 4, 20, L"0x%x", NULL, NULL, NULL, NULL }
|
{ L"Reserved", 4, 20, L"0x%x", NULL, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
An ACPI_PARSER array describing the GIC IRS Affinity structure.
|
||||||
|
**/
|
||||||
|
STATIC CONST ACPI_PARSER SratGicIrsAffinityParser[] = {
|
||||||
|
{ L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
|
||||||
|
{ L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"Proximity Domain", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"IRS Id", 4, 8, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
{ L"Reserved", 4, 12, L"0x%x", NULL, NULL, NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function parses the ACPI SRAT table.
|
This function parses the ACPI SRAT table.
|
||||||
When trace is enabled this function parses the SRAT table and
|
When trace is enabled this function parses the SRAT table and
|
||||||
|
|
@ -376,10 +389,12 @@ ParseAcpiSrat (
|
||||||
UINT32 MemoryAffinityIndex;
|
UINT32 MemoryAffinityIndex;
|
||||||
UINT32 ApicSapicAffinityIndex;
|
UINT32 ApicSapicAffinityIndex;
|
||||||
UINT32 X2ApicAffinityIndex;
|
UINT32 X2ApicAffinityIndex;
|
||||||
|
UINT32 GicIrsAffinityIndex;
|
||||||
CHAR8 Buffer[80]; // Used for AsciiName param of ParseAcpi
|
CHAR8 Buffer[80]; // Used for AsciiName param of ParseAcpi
|
||||||
|
|
||||||
GicCAffinityIndex = 0;
|
GicCAffinityIndex = 0;
|
||||||
GicITSAffinityIndex = 0;
|
GicITSAffinityIndex = 0;
|
||||||
|
GicIrsAffinityIndex = 0;
|
||||||
GenericInitiatorAffinityIndex = 0;
|
GenericInitiatorAffinityIndex = 0;
|
||||||
MemoryAffinityIndex = 0;
|
MemoryAffinityIndex = 0;
|
||||||
ApicSapicAffinityIndex = 0;
|
ApicSapicAffinityIndex = 0;
|
||||||
|
|
@ -542,6 +557,23 @@ ParseAcpiSrat (
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EFI_ACPI_6_7_GIC_IRS_AFFINITY:
|
||||||
|
AsciiSPrint (
|
||||||
|
Buffer,
|
||||||
|
sizeof (Buffer),
|
||||||
|
"GIC IRS Affinity Structure [%d]",
|
||||||
|
GicIrsAffinityIndex++
|
||||||
|
);
|
||||||
|
ParseAcpi (
|
||||||
|
TRUE,
|
||||||
|
2,
|
||||||
|
Buffer,
|
||||||
|
ResourcePtr,
|
||||||
|
*SratRALength,
|
||||||
|
PARSER_PARAMS (SratGicIrsAffinityParser)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
IncrementErrorCount ();
|
IncrementErrorCount ();
|
||||||
Print (L"ERROR: Unknown SRAT Affinity type = 0x%x\n", *SratRAType);
|
Print (L"ERROR: Unknown SRAT Affinity type = 0x%x\n", *SratRAType);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue