mirror of https://github.com/acidanthera/audk.git
DynamicTablesPkg: Add dynamic PPTT table generation support
The PPTT generator uses the configuration manager protocol to obtain information about platform's processor topology and caches. This data is then used to generate the PPTT table. The table generator supports ACPI 6.3, PPTT table revision 2. The dynamic PPTT generator also carries out extensive input validation which includes cycle detection and MADT-PPTT cross-validation. A number of architectural compliance checks are also performed. Signed-off-by: Krzysztof Koch <krzysztof.koch@arm.com> Reviewed-by: Alexei Fedorov <Alexei.Fedorov@arm.com> Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
This commit is contained in:
parent
8349b86836
commit
77db115601
|
@ -1,7 +1,7 @@
|
|||
## @file
|
||||
# Dsc include file for Dynamic Tables Framework.
|
||||
#
|
||||
# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR>
|
||||
# Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
|
@ -27,6 +27,7 @@
|
|||
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf
|
||||
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf
|
||||
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf
|
||||
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf
|
||||
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
|
||||
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf
|
||||
}
|
||||
|
|
|
@ -51,6 +51,8 @@ The Dynamic Tables Framework implements the following ACPI table generators:
|
|||
from the Configuration Manager and builds the MCFG table.
|
||||
- IORT : The IORT generator collates the IO Topology information from the
|
||||
Configuration Manager and builds the IORT table.
|
||||
- PPTT : The PPTT generator collates the processor topology information from
|
||||
the Configuration Manager and builds the PPTT table.
|
||||
*/
|
||||
|
||||
/** The ACPI_TABLE_GENERATOR_ID type describes ACPI table generator ID.
|
||||
|
@ -72,6 +74,7 @@ typedef enum StdAcpiTableId {
|
|||
EStdAcpiTableIdSpcr, ///< SPCR Generator
|
||||
EStdAcpiTableIdMcfg, ///< MCFG Generator
|
||||
EStdAcpiTableIdIort, ///< IORT Generator
|
||||
EStdAcpiTableIdPptt, ///< PPTT Generator
|
||||
EStdAcpiTableIdMax
|
||||
} ESTD_ACPI_TABLE_ID;
|
||||
|
||||
|
|
|
@ -48,6 +48,10 @@ typedef enum ArmObjectID {
|
|||
EArmObjGicItsIdentifierArray, ///< 24 - GIC ITS Identifier Array
|
||||
EArmObjIdMappingArray, ///< 25 - ID Mapping Array
|
||||
EArmObjSmmuInterruptArray, ///< 26 - SMMU Interrupt Array
|
||||
EArmObjProcHierarchyInfo, ///< 27 - Processor Hierarchy Info
|
||||
EArmObjCacheInfo, ///< 28 - Cache Info
|
||||
EArmObjProcNodeIdInfo, ///< 29 - Processor Hierarchy Node ID Info
|
||||
EArmObjCmRef, ///< 30 - CM Object Reference
|
||||
EArmObjMax
|
||||
} EARM_OBJECT_ID;
|
||||
|
||||
|
@ -628,6 +632,97 @@ typedef struct CmArmSmmuInterrupt {
|
|||
UINT32 Flags;
|
||||
} CM_ARM_SMMU_INTERRUPT;
|
||||
|
||||
/** A structure that describes the Processor Hierarchy Node (Type 0) in PPTT
|
||||
|
||||
ID: EArmObjProcHierarchyInfo
|
||||
*/
|
||||
typedef struct CmArmProcHierarchyInfo {
|
||||
/// A unique token used to identify this object
|
||||
CM_OBJECT_TOKEN Token;
|
||||
/// Processor structure flags (ACPI 6.3 - January 2019, PPTT, Table 5-155)
|
||||
UINT32 Flags;
|
||||
/// Token for the parent CM_ARM_PROC_HIERARCHY_INFO object in the processor
|
||||
/// topology. A value of CM_NULL_TOKEN means this node has no parent.
|
||||
CM_OBJECT_TOKEN ParentToken;
|
||||
/// Token of the associated CM_ARM_GICC_INFO object which has the
|
||||
/// corresponding ACPI Processor ID. A value of CM_NULL_TOKEN means this
|
||||
/// node represents a group of associated processors and it does not have an
|
||||
/// associated GIC CPU interface.
|
||||
CM_OBJECT_TOKEN GicCToken;
|
||||
/// Number of resources private to this Node
|
||||
UINT32 NoOfPrivateResources;
|
||||
/// Token of the array which contains references to the resources private to
|
||||
/// this CM_ARM_PROC_HIERARCHY_INFO instance. This field is ignored if
|
||||
/// the NoOfPrivateResources is 0, in which case it is recomended to set
|
||||
/// this field to CM_NULL_TOKEN.
|
||||
CM_OBJECT_TOKEN PrivateResourcesArrayToken;
|
||||
} CM_ARM_PROC_HIERARCHY_INFO;
|
||||
|
||||
/** A structure that describes the Cache Type Structure (Type 1) in PPTT
|
||||
|
||||
ID: EArmObjCacheInfo
|
||||
*/
|
||||
typedef struct CmArmCacheInfo {
|
||||
/// A unique token used to identify this object
|
||||
CM_OBJECT_TOKEN Token;
|
||||
/// Reference token for the next level of cache that is private to the same
|
||||
/// CM_ARM_PROC_HIERARCHY_INFO instance. A value of CM_NULL_TOKEN means this
|
||||
/// entry represents the last cache level appropriate to the processor
|
||||
/// hierarchy node structures using this entry.
|
||||
CM_OBJECT_TOKEN NextLevelOfCacheToken;
|
||||
/// Size of the cache in bytes
|
||||
UINT32 Size;
|
||||
/// Number of sets in the cache
|
||||
UINT32 NumberOfSets;
|
||||
/// Integer number of ways. The maximum associativity supported by
|
||||
/// ACPI Cache type structure is limited to MAX_UINT8. However,
|
||||
/// the maximum number of ways supported by the architecture is
|
||||
/// PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX. Therfore this field
|
||||
/// is 32-bit wide.
|
||||
UINT32 Associativity;
|
||||
/// Cache attributes (ACPI 6.3 - January 2019, PPTT, Table 5-156)
|
||||
UINT8 Attributes;
|
||||
/// Line size in bytes
|
||||
UINT16 LineSize;
|
||||
} CM_ARM_CACHE_INFO;
|
||||
|
||||
/** A structure that describes the ID Structure (Type 2) in PPTT
|
||||
|
||||
ID: EArmObjProcNodeIdInfo
|
||||
*/
|
||||
typedef struct CmArmProcNodeIdInfo {
|
||||
/// A unique token used to identify this object
|
||||
CM_OBJECT_TOKEN Token;
|
||||
// Vendor ID (as described in ACPI ID registry)
|
||||
UINT32 VendorId;
|
||||
/// First level unique node ID
|
||||
UINT64 Level1Id;
|
||||
/// Second level unique node ID
|
||||
UINT64 Level2Id;
|
||||
/// Major revision of the node
|
||||
UINT16 MajorRev;
|
||||
/// Minor revision of the node
|
||||
UINT16 MinorRev;
|
||||
/// Spin revision of the node
|
||||
UINT16 SpinRev;
|
||||
} CM_ARM_PROC_NODE_ID_INFO;
|
||||
|
||||
/** A structure that describes a reference to another Configuration Manager
|
||||
object.
|
||||
|
||||
This is useful for creating an array of reference tokens. The framework
|
||||
can then query the configuration manager for these arrays using the
|
||||
object ID EArmObjCmRef.
|
||||
|
||||
This can be used is to represent one-to-many relationships between objects.
|
||||
|
||||
ID: EArmObjCmRef
|
||||
*/
|
||||
typedef struct CmArmObjRef {
|
||||
/// Token of the CM object being referenced
|
||||
CM_OBJECT_TOKEN ReferenceToken;
|
||||
} CM_ARM_OBJ_REF;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif // ARM_NAMESPACE_OBJECTS_H_
|
||||
|
|
|
@ -63,10 +63,24 @@ Object ID's in the ARM Namespace:
|
|||
10 - Serial Debug Port Info
|
||||
11 - Generic Timer Info
|
||||
12 - Platform GT Block Info
|
||||
13 - Platform Generic Watchdog
|
||||
14 - PCI Configuration Space Info
|
||||
15 - Hypervisor Vendor Id
|
||||
16 - Fixed feature flags for FADT
|
||||
13 - Generic Timer Block Frame Info
|
||||
14 - Platform Generic Watchdog
|
||||
15 - PCI Configuration Space Info
|
||||
16 - Hypervisor Vendor Id
|
||||
17 - Fixed feature flags for FADT
|
||||
18 - ITS Group
|
||||
19 - Named Component
|
||||
20 - Root Complex
|
||||
21 - SMMUv1 or SMMUv2
|
||||
22 - SMMUv3
|
||||
23 - PMCG
|
||||
24 - GIC ITS Identifier Array
|
||||
25 - ID Mapping Array
|
||||
26 - SMMU Interrupt Array
|
||||
27 - Processor Hierarchy Info
|
||||
28 - Cache Info
|
||||
29 - Processor Hierarchy Node ID Info
|
||||
30 - CM Object Reference
|
||||
*/
|
||||
typedef UINT32 CM_OBJECT_ID;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2017, ARM Limited. All rights reserved.
|
||||
Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
|
@ -55,6 +55,7 @@ _______________________________________________________________________________
|
|||
7 - DBG2
|
||||
8 - SPCR
|
||||
9 - MCFG
|
||||
10 - PPTT
|
||||
|
||||
Standard SMBIOS Table IDs:
|
||||
0 - Reserved
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
## @file
|
||||
# PPTT Table Generator
|
||||
#
|
||||
# Copyright (c) 2019, ARM Limited. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x0001001B
|
||||
BASE_NAME = AcpiPpttLibArm
|
||||
FILE_GUID = FA102D52-5A92-4F95-A097-1D53F9CF5959
|
||||
VERSION_STRING = 1.0
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
LIBRARY_CLASS = NULL|DXE_DRIVER
|
||||
CONSTRUCTOR = AcpiPpttLibConstructor
|
||||
DESTRUCTOR = AcpiPpttLibDestructor
|
||||
|
||||
[Sources]
|
||||
PpttGenerator.c
|
||||
|
||||
[Packages]
|
||||
EmbeddedPkg/EmbeddedPkg.dec
|
||||
DynamicTablesPkg/DynamicTablesPkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,190 @@
|
|||
/** @file
|
||||
Header file for the dynamic PPTT generator
|
||||
|
||||
Copyright (c) 2019, ARM Limited. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@par Reference(s):
|
||||
- ACPI 6.3 Specification, January 2019
|
||||
- ARM Architecture Reference Manual ARMv8 (D.a)
|
||||
|
||||
@par Glossary:
|
||||
- Cm or CM - Configuration Manager
|
||||
- Obj or OBJ - Object
|
||||
**/
|
||||
|
||||
#ifndef PPTT_GENERATOR_H_
|
||||
#define PPTT_GENERATOR_H_
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
/// Cache parameters allowed by the architecture with
|
||||
/// ARMv8.3-CCIDX (Cache extended number of sets)
|
||||
/// Derived from CCSIDR_EL1 when ID_AA64MMFR2_EL1.CCIDX==0001
|
||||
#define PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX (1 << 24)
|
||||
#define PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX (1 << 21)
|
||||
|
||||
/// Cache parameters allowed by the architecture without
|
||||
/// ARMv8.3-CCIDX (Cache extended number of sets)
|
||||
/// Derived from CCSIDR_EL1 when ID_AA64MMFR2_EL1.CCIDX==0000
|
||||
#define PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX (1 << 15)
|
||||
#define PPTT_ARM_CACHE_ASSOCIATIVITY_MAX (1 << 10)
|
||||
|
||||
/// Common cache parameters
|
||||
/// Derived from CCSIDR_EL1
|
||||
/// The LineSize is represented by bits 2:0
|
||||
/// (Log2(Number of bytes in cache line)) - 4 is used to represent
|
||||
/// the LineSize bits.
|
||||
#define PPTT_ARM_CACHE_LINE_SIZE_MAX (1 << 11)
|
||||
#define PPTT_ARM_CACHE_LINE_SIZE_MIN (1 << 4)
|
||||
|
||||
/// Test if the given Processor Hierarchy Info object has the 'Node is a Leaf'
|
||||
/// flag set
|
||||
#define IS_PROC_NODE_LEAF(Node) ((Node->Flags & BIT3) != 0)
|
||||
|
||||
/// Test if the given Processor Hierarchy Info object has the 'ACPI Processor
|
||||
/// ID valid' flag set
|
||||
#define IS_ACPI_PROC_ID_VALID(Node) ((Node->Flags & BIT1) != 0)
|
||||
|
||||
/**
|
||||
The GET_SIZE_OF_PPTT_STRUCTS macro expands to a function that is used to
|
||||
calculate the total memory requirement for the PPTT structures represented
|
||||
by the given list of Configuration Manager Objects of the same type. This
|
||||
function also indexes the input CM objects so that various other CM objects
|
||||
(possibly of different type) can reference them.
|
||||
|
||||
The size of memory needed for the specified type of PPTT structures is based
|
||||
on the number and type of CM objects provided. The macro assumes that the
|
||||
ACPI object PpttObjName has fixed size.
|
||||
|
||||
The macro expands to a function which has the following prototype:
|
||||
|
||||
STATIC
|
||||
UINT32
|
||||
EFIAPI
|
||||
GetSizeof<PpttObjName> (
|
||||
IN CONST UINT32 StartOffset,
|
||||
IN CONST CmObjectType * Nodes,
|
||||
IN UINT32 NodeCount,
|
||||
IN OUT PPTT_NODE_INDEXER ** CONST NodeIndexer
|
||||
)
|
||||
|
||||
Generated function parameters:
|
||||
@param [in] StartOffset Offset from the start of PPTT to where
|
||||
the PPTT structures will be placed.
|
||||
@param [in] NodesToIndex Pointer to the list of CM objects to be
|
||||
indexed and size-estimated.
|
||||
@param [out] NodeCount Number of CM objects in NodesToIndex.
|
||||
@param [in, out] NodeIndexer Pointer to the list of Node Indexer
|
||||
elements to populate.
|
||||
@retval Size Total memory requirement for the PPTT
|
||||
structures described in NodesToIndex.
|
||||
|
||||
Macro Parameters:
|
||||
@param [in] PpttObjName Name for the type of PPTT structures which
|
||||
size is estimated.
|
||||
@param [in] PpttObjSize Expression to use to calculate the size of
|
||||
of a single instance of the PPTT structure
|
||||
which corresponds to the CM object being
|
||||
indexed.
|
||||
@param [in] CmObjectType Data type of the CM nodes in NodesToIndex.
|
||||
**/
|
||||
#define GET_SIZE_OF_PPTT_STRUCTS( \
|
||||
PpttObjName, \
|
||||
PpttObjSize, \
|
||||
CmObjectType \
|
||||
) \
|
||||
STATIC \
|
||||
UINT32 \
|
||||
GetSizeof##PpttObjName ( \
|
||||
IN CONST UINT32 StartOffset, \
|
||||
IN CONST CmObjectType * NodesToIndex, \
|
||||
IN UINT32 NodeCount, \
|
||||
IN OUT PPTT_NODE_INDEXER ** CONST NodeIndexer \
|
||||
) \
|
||||
{ \
|
||||
UINT32 Size; \
|
||||
\
|
||||
ASSERT ( \
|
||||
(NodesToIndex != NULL) && \
|
||||
(NodeIndexer != NULL) \
|
||||
); \
|
||||
\
|
||||
Size = 0; \
|
||||
while (NodeCount-- != 0) { \
|
||||
(*NodeIndexer)->Token = NodesToIndex->Token; \
|
||||
(*NodeIndexer)->Object = (VOID*)NodesToIndex; \
|
||||
(*NodeIndexer)->Offset = Size + StartOffset; \
|
||||
(*NodeIndexer)->CycleDetectionStamp = 0; \
|
||||
(*NodeIndexer)->TopologyParent = NULL; \
|
||||
DEBUG (( \
|
||||
DEBUG_INFO, \
|
||||
"PPTT: Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n", \
|
||||
*NodeIndexer, \
|
||||
(*NodeIndexer)->Token, \
|
||||
(*NodeIndexer)->Object, \
|
||||
(*NodeIndexer)->Offset \
|
||||
)); \
|
||||
\
|
||||
Size += PpttObjSize; \
|
||||
(*NodeIndexer)++; \
|
||||
NodesToIndex++; \
|
||||
} \
|
||||
return Size; \
|
||||
}
|
||||
|
||||
/**
|
||||
A structure for indexing CM objects (nodes) used in PPTT generation.
|
||||
|
||||
PPTT_NODE_INDEXER is a wrapper around CM objects which augments these objects
|
||||
with additional information that enables generating PPTT structures with
|
||||
correct cross-references.
|
||||
|
||||
PPTT_NODE_INDEXER keeps track of each structure's offset from the base
|
||||
address of the generated table. It also caches certain information and makes
|
||||
PPTT cyclic reference detection possible.
|
||||
*/
|
||||
typedef struct PpttNodeIndexer {
|
||||
/// Unique identifier for the node
|
||||
CM_OBJECT_TOKEN Token;
|
||||
/// Pointer to the CM object being indexed
|
||||
VOID * Object;
|
||||
/// Offset from the start of the PPTT table to the PPTT structure which is
|
||||
/// represented by Object
|
||||
UINT32 Offset;
|
||||
/// Field used to mark nodes as 'visited' when detecting cycles in processor
|
||||
/// and cache topology
|
||||
UINT32 CycleDetectionStamp;
|
||||
/// Reference to a Node Indexer element which is the parent of this Node
|
||||
/// Indexer element in the processor and cache topology
|
||||
/// e.g For a hardware thread the TopologyParent would point to a CPU node
|
||||
/// For a L1 cache the TopologyParent would point to a L2 cache
|
||||
struct PpttNodeIndexer * TopologyParent;
|
||||
} PPTT_NODE_INDEXER;
|
||||
|
||||
typedef struct AcpiPpttGenerator {
|
||||
/// ACPI Table generator header
|
||||
ACPI_TABLE_GENERATOR Header;
|
||||
/// PPTT structure count
|
||||
UINT32 ProcTopologyStructCount;
|
||||
/// List of indexed CM objects for PPTT generation
|
||||
PPTT_NODE_INDEXER * NodeIndexer;
|
||||
/// Pointer to the start of Processor Hierarchy nodes in
|
||||
/// the Node Indexer array
|
||||
PPTT_NODE_INDEXER * ProcHierarchyNodeIndexedList;
|
||||
/// Pointer to the start of Cache Structures in the Node Indexer array
|
||||
PPTT_NODE_INDEXER * CacheStructIndexedList;
|
||||
/// Pointer to the start of Id Structures in the Node Indexer array
|
||||
PPTT_NODE_INDEXER * IdStructIndexedList;
|
||||
/// Count of Processor Hierarchy Nodes
|
||||
UINT32 ProcHierarchyNodeCount;
|
||||
/// Count of Cache Structures
|
||||
UINT32 CacheStructCount;
|
||||
/// Count of Id Structures
|
||||
UINT32 IdStructCount;
|
||||
|
||||
} ACPI_PPTT_GENERATOR;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif // PPTT_GENERATOR_H_
|
Loading…
Reference in New Issue