Date   

Re: [PATCH v1 07/14] DynamicTablesPkg: FdtHwInfoParser: Add GICC parser

Sami Mujawar
 

Hi Pierre,

Please find my feedback inline marked [SAMI].

Regards,

Sami Mujawar

On 23/06/2021 01:38 PM, Pierre.Gondois@arm.com wrote:
From: Pierre Gondois <Pierre.Gondois@arm.com>

The GIC CPU Interface (GICC) structure is part of the Multiple
APIC Description Table (MADT) that describes the interrupt model
for the platform. The MADT table is a mandatory table required
for booting a standards-based operating system.

Arm requires the GIC interrupt model, in which the logical
processors are required to have a Processor Device object in
the DSDT, and must convey each processor’s GIC information to
the OS using the GICC structure.

The CPU and GIC information is described in the platform Device
Tree, the bindings for which can be found at:
- linux/Documentation/devicetree/bindings/arm/cpus.yaml
- linux/Documentation/devicetree/bindings/interrupt-controller/
arm,gic.yaml
- linux/Documentation/devicetree/bindings/interrupt-controller/
arm,gic-v3.yaml

The FdtHwInfoParser implements a GIC CPU Interface Parser that
parses the platform Device Tree to create CM_ARM_GICC_INFO
objects which are encapsulated in a Configuration Manager
descriptor object and added to the platform information
repository.

The platform Configuration Manager can then utilise this
information when generating the MADT and the SSDT CPU
information tables.

Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
.../FdtHwInfoParserLib/Gic/ArmGicCParser.c | 762 ++++++++++++++++++
.../FdtHwInfoParserLib/Gic/ArmGicCParser.h | 67 ++
2 files changed, 829 insertions(+)
create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c
create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h

diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c
new file mode 100644
index 000000000000..2163888c870e
--- /dev/null
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c
@@ -0,0 +1,762 @@
+/** @file
+ Arm Gic cpu parser.
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - linux/Documentation/devicetree/bindings/arm/cpus.yaml
+ - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
+ - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml
+**/
+
+#include "FdtHwInfoParser.h"
+#include "CmObjectDescUtility.h"
+#include "Gic/ArmGicCParser.h"
+#include "Gic/ArmGicDispatcher.h"
+
+/** List of "compatible" property values for CPU nodes.
+
+ Any other "compatible" value is not supported by this module.
+*/
+STATIC CONST COMPATIBILITY_STR CpuCompatibleStr[] = {
+ {"arm,arm-v7"},
+ {"arm,arm-v8"},
+ {"arm,cortex-a15"},
+ {"arm,cortex-a7"},
+ {"arm,cortex-a57"}
+};
+
+/** COMPATIBILITY_INFO structure for CPU nodes.
+*/
+STATIC CONST COMPATIBILITY_INFO CpuCompatibleInfo = {
+ ARRAY_SIZE (CpuCompatibleStr),
+ CpuCompatibleStr
+};
+
+/** Parse a "cpu" node.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
+ @param [in] CpuNode Offset of a cpu node.
+ @param [in] GicVersion Version of the GIC.
+ @param [in] AddressCells Number of address cells used for the reg
+ property.
+ @param [out] GicCInfo CM_ARM_GICC_INFO structure to populate.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_UNSUPPORTED Unsupported.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuNodeParser (
+ IN CONST VOID * Fdt,
+ IN INT32 CpuNode,
+ IN UINT32 GicVersion,
+ IN UINT32 AddressCells,
+ OUT CM_ARM_GICC_INFO * GicCInfo
+)
+{
+ UINT32 CpuRegProp;
+ CONST VOID * Data;
+ INT32 DataSize;
+ UINT64 MpIdr;
+
+ if (GicCInfo == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Data = fdt_getprop (Fdt, CpuNode, "reg", &DataSize);
+ if ((Data == NULL) ||
+ ((DataSize != sizeof (UINT32)) &&
+ (DataSize != sizeof (UINT64)))) {
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+
+ if (AddressCells == 1) {
+ MpIdr = fdt32_to_cpu (*((UINT32*)Data));
+ } else if (AddressCells == 2) {
+ MpIdr = fdt64_to_cpu (*((UINT64*)Data));
+ } else {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Currently we only support 3 affinity levels.
+ if ((MpIdr & ~(ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2)) != 0) {
+ ASSERT (0);
+ return EFI_UNSUPPORTED;
+ }
[SAMI] Is there a reason we are not supporting AFF3?
+
+ CpuRegProp = (MpIdr & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2));
+
+ /* ACPI 6.3, s5.2.12.14 GIC CPU Interface (GICC) Structure:
+ GIC 's CPU Interface Number. In GICv1/v2 implementations,
+ this value matches the bit index of the associated processor
+ in the GIC distributor's GICD_ITARGETSR register. For
+ GICv3/4 implementations this field must be provided by the
+ platform, if compatibility mode is supported. If it is not supported
+ by the implementation, then this field must be zero.
+
+ Note: We do not support compatibility mode for GicV3
+ */
+ if (GicVersion == 2) {
+ GicCInfo->CPUInterfaceNumber = CpuRegProp;
+ } else {
+ GicCInfo->CPUInterfaceNumber = 0;
+ }
+
+ GicCInfo->AcpiProcessorUid = CpuRegProp;
+ GicCInfo->Flags = EFI_ACPI_6_3_GIC_ENABLED;
+ GicCInfo->MPIDR= MpIdr;
+
+ return EFI_SUCCESS;
+}
+
+/** Parse a "cpus" node and its children "cpu" nodes.
+
+ Create as many CM_ARM_GICC_INFO structures as "cpu" nodes.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
+ @param [in] CpusNode Offset of a cpus node.
+ @param [in] GicVersion Version of the GIC.
+ @param [out] NewGicCmObjDesc If success, CM_OBJ_DESCRIPTOR containing
+ all the created CM_ARM_GICC_INFO.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_UNSUPPORTED Unsupported.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpusNodeParser (
+ IN CONST VOID * Fdt,
+ IN INT32 CpusNode,
+ IN UINT32 GicVersion,
+ OUT CM_OBJ_DESCRIPTOR ** NewGicCmObjDesc
+ )
+{
+ EFI_STATUS Status;
+ INT32 CpuNode;
+ UINT32 CpuNodeCount;
+ INT32 AddressCells;
+
+ UINT32 Index;
+ CM_ARM_GICC_INFO * GicCInfoBuffer;
+ UINT32 GicCInfoBufferSize;
+
+ if (NewGicCmObjDesc == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AddressCells = fdt_address_cells (Fdt, CpusNode);
+ if (AddressCells < 0) {
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+
+ // Count the number of "cpu" nodes under the "cpus" node.
+ Status = FdtCountNamedNodeInBranch (Fdt, CpusNode, "cpu", &CpuNodeCount);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ if (CpuNodeCount == 0) {
+ ASSERT (0);
+ return EFI_NOT_FOUND;
+ }
+
+ // Allocate memory for CpuNodeCount CM_ARM_GICC_INFO structures.
+ GicCInfoBufferSize = CpuNodeCount * sizeof (CM_ARM_GICC_INFO);
+ GicCInfoBuffer = AllocateZeroPool (GicCInfoBufferSize);
+ if (GicCInfoBuffer == NULL) {
+ ASSERT (0);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CpuNode = CpusNode;
+ for (Index = 0; Index < CpuNodeCount; Index++) {
+ Status = FdtGetNextNamedNodeInBranch (Fdt, CpusNode, "cpu", &CpuNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ if (Status == EFI_NOT_FOUND) {
+ // Should have found the node.
+ Status = EFI_ABORTED;
+ }
+ goto exit_handler;
+ }
+
+ // Parse the "cpu" node.
+ if (!FdtNodeIsCompatible (Fdt, CpuNode, &CpuCompatibleInfo)) {
+ ASSERT (0);
+ Status = EFI_UNSUPPORTED;
+ goto exit_handler;
+ }
+
+ Status = CpuNodeParser (
+ Fdt,
+ CpuNode,
+ GicVersion,
+ AddressCells,
+ &GicCInfoBuffer[Index]
+ );
[SAMI] Please adjust code alignment.
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto exit_handler;
+ }
+ } // for
+
+ Status = CreateCmObjDesc (
+ CREATE_CM_ARM_OBJECT_ID (EArmObjGicCInfo),
+ CpuNodeCount,
+ GicCInfoBuffer,
+ GicCInfoBufferSize,
+ NewGicCmObjDesc
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ }
+
+exit_handler:
+ FreePool (GicCInfoBuffer);
+ return Status;
+}
+
+/** Parse a Gic compatible interrupt-controller node,
+ extracting GicC information generic to Gic v2 and v3.
+
+ This function modifies a CM_OBJ_DESCRIPTOR object.
+ The following CM_ARM_GICC_INFO fields are patched:
+ - VGICMaintenanceInterrupt;
+ - Flags;
+
+ @param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
+ @param [in] GicIntcNode Offset of a Gic compatible
+ interrupt-controller node.
+ @param [in, out] GicCCmObjDesc The CM_ARM_GICC_INFO to patch.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GicCIntcNodeParser (
+ IN CONST VOID * Fdt,
+ IN INT32 GicIntcNode,
+ IN OUT CM_OBJ_DESCRIPTOR * GicCCmObjDesc
+ )
+{
+ EFI_STATUS Status;
+ INT32 IntCells;
+ CM_ARM_GICC_INFO * GicCInfo;
+
+ CONST UINT8 * Data;
+ INT32 DataSize;
+
+ if (GicCCmObjDesc == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Get the number of cells used to encode an interrupt.
+ Status = FdtGetInterruptCellsInfo (Fdt, GicIntcNode, &IntCells);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // Get the GSIV maintenance interrupt.
+ // According to the DT bindings, this could be the:
+ // "Interrupt source of the parent interrupt controller on secondary GICs"
+ // but it is assumed that only one Gic is available.
+ Data = fdt_getprop (Fdt, GicIntcNode, "interrupts", &DataSize);
+ if ((Data != NULL) && (DataSize == (IntCells * sizeof (UINT32)))) {
+ GicCInfo = (CM_ARM_GICC_INFO*)GicCCmObjDesc->Data;
+ GicCInfo->VGICMaintenanceInterrupt =
+ FdtGetInterruptId ((CONST UINT32*)Data);
+ GicCInfo->Flags = DT_IRQ_IS_EDGE_TRIGGERED (
+ fdt32_to_cpu (((UINT32*)Data)[IRQ_FLAGS_OFFSET])
+ ) ?
+ EFI_ACPI_6_3_VGIC_MAINTENANCE_INTERRUPT_MODE_FLAGS :
+ 0;
+ return Status;
+ } else if (DataSize < 0) {
+ // This property is optional and was not found. Just return.
+ return Status;
+ }
+ // The property exists and its size doesn't match for one interrupt.
+ ASSERT (0);
+ return EFI_ABORTED;
+}
+
+/** Parse a Gic compatible interrupt-controller node,
+ extracting GicCv2 information.
+
+ This function modifies a CM_OBJ_DESCRIPTOR object.
+ The following CM_ARM_GICC_INFO fields are patched:
+ - PhysicalAddress;
+ - GICH;
+ - GICV;
+
+ @param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
+ @param [in] Gicv2IntcNode Offset of a Gicv2 compatible
+ interrupt-controller node.
+ @param [in, out] GicCCmObjDesc The CM_ARM_GICC_INFO to patch.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GicCv2IntcNodeParser (
+ IN CONST VOID * Fdt,
+ IN INT32 Gicv2IntcNode,
+ IN OUT CM_OBJ_DESCRIPTOR * GicCCmObjDesc
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+ CM_ARM_GICC_INFO * GicCInfo;
+ INT32 AddressCells;
+ INT32 SizeCells;
+
+ CONST UINT8 * GicCValue;
+ CONST UINT8 * GicVValue;
+ CONST UINT8 * GicHValue;
+
+ CONST UINT8 * Data;
+ INT32 DataSize;
+ UINT32 RegSize;
+ UINT32 RegCount;
+
+ if (GicCCmObjDesc == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ GicCInfo = (CM_ARM_GICC_INFO*)GicCCmObjDesc->Data;
+ GicVValue = NULL;
+ GicHValue = NULL;
+
+ // Get the #address-cells and #size-cells property values.
+ Status = FdtGetParentAddressInfo (
+ Fdt,
+ Gicv2IntcNode,
+ &AddressCells,
+ &SizeCells
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // Don't support more than 64 bits and less than 32 bits addresses.
+ if ((AddressCells < 1) ||
+ (AddressCells > 2) ||
+ (SizeCells < 1) ||
+ (SizeCells > 2)) {
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+
+ RegSize = (AddressCells + SizeCells) * sizeof (UINT32);
+
+ Data = fdt_getprop (Fdt, Gicv2IntcNode, "reg", &DataSize);
+ if ((Data == NULL) ||
+ (DataSize < 0) ||
+ ((DataSize % RegSize) != 0)) {
+ // If error or wrong size.
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+
+ RegCount = DataSize/RegSize;
+
+ switch (RegCount) {
+ case 4:
+ {
+ // GicV is at index 3 in the reg property. GicV is optional.
+ GicVValue = Data + (sizeof (UINT32) *
+ GET_DT_REG_ADDRESS_OFFSET (3, AddressCells, SizeCells));
+ // fall-through.
+ }
+ case 3:
+ {
+ // GicH is at index 2 in the reg property. GicH is optional.
+ GicHValue = Data + (sizeof (UINT32) *
+ GET_DT_REG_ADDRESS_OFFSET (2, AddressCells, SizeCells));
+ // fall-through.
+ }
+ case 2:
+ {
+ // GicC is at index 1 in the reg property. GicC is mandatory.
+ GicCValue = Data + (sizeof (UINT32) *
+ GET_DT_REG_ADDRESS_OFFSET (1, AddressCells, SizeCells));
+ break;
+ }
+ default:
+ {
+ // Not enough or too much information.
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+ }
+
+ // Patch the relevant fields of the CM_ARM_GICC_INFO objects.
+ for (Index = 0; Index < GicCCmObjDesc->Count; Index++) {
+ if (AddressCells == 2) {
+ GicCInfo[Index].PhysicalBaseAddress = fdt64_to_cpu (*(UINT64*)GicCValue);
+ GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 :
+ fdt64_to_cpu (*(UINT64*)GicHValue);
+ GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 :
+ fdt64_to_cpu (*(UINT64*)GicVValue);
+ } else {
+ GicCInfo[Index].PhysicalBaseAddress = fdt32_to_cpu (*(UINT32*)GicCValue);
+ GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 :
+ fdt32_to_cpu (*(UINT32*)GicHValue);
+ GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 :
+ fdt32_to_cpu (*(UINT32*)GicVValue);
+ }
+ } // for
+
+ return EFI_SUCCESS;
+}
+
+/** Parse a Gic compatible interrupt-controller node,
+ extracting GicCv3 information.
+
+ This function modifies a CM_OBJ_DESCRIPTOR object.
+ The following CM_ARM_GICC_INFO fields are patched:
+ - PhysicalAddress;
+ - GICH;
+ - GICV;
+
+ @param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
+ @param [in] Gicv3IntcNode Offset of a Gicv3 compatible
+ interrupt-controller node.
+ @param [in, out] GicCCmObjDesc The CM_ARM_GICC_INFO to patch.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GicCv3IntcNodeParser (
+ IN CONST VOID * Fdt,
+ IN INT32 Gicv3IntcNode,
+ IN OUT CM_OBJ_DESCRIPTOR * GicCCmObjDesc
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+ CM_ARM_GICC_INFO * GicCInfo;
+ INT32 AddressCells;
+ INT32 SizeCells;
+ UINT32 AdditionalRedistReg;
+
+ CONST UINT8 * GicCValue;
+ CONST UINT8 * GicVValue;
+ CONST UINT8 * GicHValue;
+
+ CONST UINT8 * Data;
+ INT32 DataSize;
+ UINT32 RegSize;
+ UINT32 RegCount;
+
+ if (GicCCmObjDesc == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ GicCInfo = (CM_ARM_GICC_INFO*)GicCCmObjDesc->Data;
+ GicCValue = NULL;
+ GicVValue = NULL;
+ GicHValue = NULL;
+
+ // Get the #address-cells and #size-cells property values.
+ Status = FdtGetParentAddressInfo (
+ Fdt,
+ Gicv3IntcNode,
+ &AddressCells,
+ &SizeCells
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // Don't support more than 64 bits and less than 32 bits addresses.
+ if ((AddressCells < 1) ||
+ (AddressCells > 2) ||
+ (SizeCells < 1) ||
+ (SizeCells > 2)) {
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+
+ // The "#redistributor-regions" property is optional.
+ Data = fdt_getprop (Fdt, Gicv3IntcNode, "#redistributor-regions", &DataSize);
+ if ((Data != NULL) && (DataSize == sizeof (UINT32))) {
+ ASSERT (fdt32_to_cpu (*(UINT32*)Data) > 1);
+ AdditionalRedistReg = fdt32_to_cpu (*(UINT32*)Data) - 1;
+ } else {
+ AdditionalRedistReg = 0;
+ }
+
+ RegSize = (AddressCells + SizeCells) * sizeof (UINT32);
+
+ /*
+ Ref: linux/blob/master/Documentation/devicetree/bindings/
+ interrupt-controller/arm%2Cgic-v3.yaml
+
+ reg:
+ description: |
+ Specifies base physical address(s) and size of the GIC
+ registers, in the following order:
+ - GIC Distributor interface (GICD)
+ - GIC Redistributors (GICR), one range per redistributor region
+ - GIC CPU interface (GICC)
+ - GIC Hypervisor interface (GICH)
+ - GIC Virtual CPU interface (GICV)
+ GICC, GICH and GICV are optional.
+ minItems: 2
+ maxItems: 4096
+ */
+ Data = fdt_getprop (Fdt, Gicv3IntcNode, "reg", &DataSize);
+ if ((Data == NULL) ||
+ (DataSize < 0) ||
+ ((DataSize % RegSize) != 0)) {
+ // If error or wrong size.
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+
+ RegCount = (DataSize / RegSize) - AdditionalRedistReg;
+
+ // The GicD and GicR info is mandatory.
+ switch (RegCount) {
+ case 5:
+ {
+ // GicV is at index 4 in the reg property. GicV is optional.
+ GicVValue = Data + (sizeof (UINT32) *
+ GET_DT_REG_ADDRESS_OFFSET (
+ 4 + AdditionalRedistReg,
+ AddressCells,
+ SizeCells
+ ));
+ // fall-through.
+ }
+ case 4:
+ {
+ // GicH is at index 3 in the reg property. GicH is optional.
+ GicHValue = Data + (sizeof (UINT32) *
+ GET_DT_REG_ADDRESS_OFFSET (
+ 3 + AdditionalRedistReg,
+ AddressCells,
+ SizeCells
+ ));
+ // fall-through.
+ }
+ case 3:
+ {
+ // GicC is at index 2 in the reg property. GicC is optional.
+ // Even though GicC is optional, it is made mandatory in this parser.
+ GicCValue = Data + (sizeof (UINT32) *
+ GET_DT_REG_ADDRESS_OFFSET (
+ 2 + AdditionalRedistReg,
+ AddressCells,
+ SizeCells
+ ));
+ // fall-through
+ }
+ case 2:
+ {
+ // GicR is discribed by the CM_ARM_GIC_REDIST_INFO object.
+ // GicD is described by the CM_ARM_GICD_INFO object.
+ break;
+ }
+ default:
+ {
+ // Not enough or too much information.
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+ }
+
+ // Patch the relevant fields of the CM_ARM_GICC_INFO objects.
+ if (AddressCells == 2) {
+ for (Index = 0; Index < GicCCmObjDesc->Count; Index++) {
+ // GicR is discribed by the CM_ARM_GIC_REDIST_INFO object.
+ GicCInfo[Index].GICRBaseAddress = 0;
+ GicCInfo[Index].PhysicalBaseAddress = (GicCValue == NULL) ? 0 :
+ fdt64_to_cpu (*(UINT64*)GicCValue);
+ GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 :
+ fdt64_to_cpu (*(UINT64*)GicHValue);
+ GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 :
+ fdt64_to_cpu (*(UINT64*)GicVValue);
+ }
+ } else {
+ for (Index = 0; Index < GicCCmObjDesc->Count; Index++) {
+ // GicR is discribed by the CM_ARM_GIC_REDIST_INFO object.
+ GicCInfo[Index].GICRBaseAddress = 0;
+ GicCInfo[Index].PhysicalBaseAddress = (GicCValue == NULL) ? 0 :
+ fdt32_to_cpu (*(UINT32*)GicCValue);
+ GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 :
+ fdt32_to_cpu (*(UINT32*)GicHValue);
+ GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 :
+ fdt32_to_cpu (*(UINT32*)GicVValue);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** CM_ARM_GICC_INFO parser function.
+
+ This parser expects FdtBranch to be the "\cpus" node node.
+ At most one CmObj is created.
+ The following structure is populated:
+ typedef struct CmArmGicCInfo {
+ UINT32 CPUInterfaceNumber; // {Populated}
+ UINT32 AcpiProcessorUid; // {Populated}
+ UINT32 Flags; // {Populated}
+ UINT32 ParkingProtocolVersion; // {default = 0}
+ UINT32 PerformanceInterruptGsiv; // {default = 0}
+ UINT64 ParkedAddress; // {default = 0}
+ UINT64 PhysicalBaseAddress; // {Populated}
+ UINT64 GICV; // {Populated}
+ UINT64 GICH; // {Populated}
+ UINT32 VGICMaintenanceInterrupt; // {Populated}
+ UINT64 GICRBaseAddress; // {default = 0}
+ UINT64 MPIDR; // {Populated}
+ UINT8 ProcessorPowerEfficiencyClass; // {default = 0}
+ UINT16 SpeOverflowInterrupt; // {default = 0}
+ UINT32 ProximityDomain; // {default = 0}
+ UINT32 ClockDomain; // {default = 0}
+ UINT32 AffinityFlags; // {default = 0}
+ } CM_ARM_GICC_INFO;
+
+ The pmu information can be found in the pmu node. There is no support
+ for now.
+
+ A parser parses a Device Tree to populate a specific CmObj type. None,
+ one or many CmObj can be created by the parser.
+ The created CmObj are then handed to the parser's caller through the
+ HW_INFO_ADD_OBJECT interface.
+ This can also be a dispatcher. I.e. a function that not parsing a
+ Device Tree but calling other parsers.
+
+ @param [in] FdtParserHandle A handle to the parser instance.
+ @param [in] FdtBranch When searching for DT node name, restrict
+ the search to this Device Tree branch.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Not found.
+ @retval EFI_UNSUPPORTED Unsupported.
+**/
+EFI_STATUS
+EFIAPI
+ArmGicCInfoParser (
+ IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle,
+ IN INT32 FdtBranch
+ )
+{
+ EFI_STATUS Status;
+ INT32 IntcNode;
+ UINT32 GicVersion;
+ CM_OBJ_DESCRIPTOR * NewCmObjDesc;
+ VOID * Fdt;
+
+ if (FdtParserHandle == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Fdt = FdtParserHandle->Fdt;
+ NewCmObjDesc = NULL;
+
+ // The FdtBranch points to the Cpus Node.
+ // Get the interrupt-controller node associated to the "cpus" node.
+ Status = FdtGetIntcParentNode (Fdt, FdtBranch, &IntcNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ if (Status == EFI_NOT_FOUND) {
+ // Should have found the node.
+ Status = EFI_ABORTED;
+ }
+ goto exit_handler;
[SAMI] Return directly from here as memory for NewCmObjDescis not yet allocated.
+ }
+
+ Status = GetGicVersion (Fdt, IntcNode, &GicVersion);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto exit_handler;
[SAMI] Return directly from here as memory for NewCmObjDescis not yet allocated.
+ }
+
+ // Parse the "cpus" nodes and its children "cpu" nodes,
+ // and create a CM_OBJ_DESCRIPTOR.
+ Status = CpusNodeParser (Fdt, FdtBranch, GicVersion, &NewCmObjDesc);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // Parse the interrupt-controller node according to the Gic version.
+ switch (GicVersion) {
+ case 2:
+ {
+ Status = GicCv2IntcNodeParser (Fdt, IntcNode, NewCmObjDesc);
+ break;
+ }
+ case 3:
+ {
+ Status = GicCv3IntcNodeParser (Fdt, IntcNode, NewCmObjDesc);
+ break;
+ }
+ default:
+ {
+ // Unsupported Gic version.
+ ASSERT (0);
+ Status = EFI_UNSUPPORTED;
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto exit_handler;
+ }
+
+ // Parse the Gic information common to Gic v2 and v3.
+ Status = GicCIntcNodeParser (Fdt, IntcNode, NewCmObjDesc);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto exit_handler;
+ }
+
+ // Add all the CmObjs to the Configuration Manager.
+ Status = AddMultipleCmObj (FdtParserHandle, NewCmObjDesc, 0, NULL);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto exit_handler;
+ }
+
+exit_handler:
+ FreeCmObjDesc (NewCmObjDesc);
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h
new file mode 100644
index 000000000000..10e6b03c541f
--- /dev/null
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h
@@ -0,0 +1,67 @@
+/** @file
+ Arm Gic cpu parser.
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
+ - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml
+**/
+
+#ifndef ARM_GICC_PARSER_H_
+#define ARM_GICC_PARSER_H_
+
+/** CM_ARM_GICC_INFO parser function.
+
+ This parser expects FdtBranch to be the "\cpus" node node.
+ At most one CmObj is created.
+ The following structure is populated:
+ typedef struct CmArmGicCInfo {
+ UINT32 CPUInterfaceNumber; // {Populated}
+ UINT32 AcpiProcessorUid; // {Populated}
+ UINT32 Flags; // {Populated}
+ UINT32 ParkingProtocolVersion; // {default = 0}
+ UINT32 PerformanceInterruptGsiv; // {default = 0}
+ UINT64 ParkedAddress; // {default = 0}
+ UINT64 PhysicalBaseAddress; // {Populated}
+ UINT64 GICV; // {Populated}
+ UINT64 GICH; // {Populated}
+ UINT32 VGICMaintenanceInterrupt; // {Populated}
+ UINT64 GICRBaseAddress; // {default = 0}
+ UINT64 MPIDR; // {Populated}
+ UINT8 ProcessorPowerEfficiencyClass; // {default = 0}
+ UINT16 SpeOverflowInterrupt; // {default = 0}
+ UINT32 ProximityDomain; // {default = 0}
+ UINT32 ClockDomain; // {default = 0}
+ UINT32 AffinityFlags; // {default = 0}
+ } CM_ARM_GICC_INFO;
+
+ The pmu information can be found in the pmu node. There is no support
+ for now.
+
+ A parser parses a Device Tree to populate a specific CmObj type. None,
+ one or many CmObj can be created by the parser.
+ The created CmObj are then handed to the parser's caller through the
+ HW_INFO_ADD_OBJECT interface.
+ This can also be a dispatcher. I.e. a function that not parsing a
+ Device Tree but calling other parsers.
+
+ @param [in] FdtParserHandle A handle to the parser instance.
+ @param [in] FdtBranch When searching for DT node name, restrict
+ the search to this Device Tree branch.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Not found.
+ @retval EFI_UNSUPPORTED Unsupported.
+**/
+EFI_STATUS
+EFIAPI
+ArmGicCInfoParser (
+ IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle,
+ IN INT32 FdtBranch
+ );
+
+#endif // ARM_GICC_PARSER_H_


Re: [PATCH v1 06/14] DynamicTablesPkg: FdtHwInfoParser: Add Serial port parser

Sami Mujawar
 

Hi Pierre,

Please find my response inline marked [SAMI].

Regards,

Sami Mujawar


On 23/06/2021 01:38 PM, Pierre.Gondois@... wrote:
From: Pierre Gondois <Pierre.Gondois@...>

The Microsoft Debug Port Table 2 (DBG2), the Serial Port Console
Redirector (SPCR) table are mandatory tables required for booting
a standards-based operating system. The DBG2 table is used by the
OS debugger while the SPCR table is used to configure the serial
terminal. Additionally, the serial ports available on a platform
for generic use also need to be described in DSDT/SSDT for an OS
to be able to use the serial ports.

The Arm Base System Architecture 1.0 specification a lists of
supported serial port hardware for Arm Platforms. This list
includes the following serial port UARTs:
 - SBSA/Generic UART
 - a fully 16550 compatible UART.
Along, with these the PL011 UART is the most commonly used serial
port hardware on Arm platforms.

The serial port hardware information is described in the platform
Device Tree, the bindings for which can be found at:
 - linux/Documentation/devicetree/bindings/serial/serial.yaml
 - linux/Documentation/devicetree/bindings/serial/8250.txt
 - linux/Documentation/devicetree/bindings/serial/arm_sbsa_uart.txt
 - linux/Documentation/devicetree/bindings/serial/pl011.yaml

The FdtHwInfoParser implements a Serial Port Parser that parses
the platform Device Tree to create CM_ARM_SERIAL_PORT_INFO objects
with the following IDs:
 - EArmObjSerialConsolePortInfo (for use by SPCR)
 - EArmObjSerialDebugPortInfo (for use by DBG2)
 - EArmObjSerialPortInfo (for use as generic Serial Ports)

The Serial Port for use by SPCR is selected by parsing the Device
Tree for the '/chosen' node with the 'stdout-path' property. The
next Serial Port is selected for use as the Debug Serial Port and
the remaining serial ports are used as generic serial ports.

The CM_ARM_SERIAL_PORT_INFO objects are encapsulated in Configuration
Manager descriptor objects with the respective IDs and are added to
the platform information repository.

The platform Configuration Manager can then utilise this information
when generating the DBG2, SPCR and the SSDT serial port tables.

Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
Signed-off-by: Sami Mujawar <sami.mujawar@...>
---
 .../Serial/ArmSerialPortParser.c              | 621 ++++++++++++++++++
 .../Serial/ArmSerialPortParser.h              |  47 ++
 2 files changed, 668 insertions(+)
 create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.c
 create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.h

diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.c
new file mode 100644
index 000000000000..d5db206ae93c
--- /dev/null
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.c
@@ -0,0 +1,621 @@
+/** @file
+  Arm Serial Port Parser.
+
+  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Reference(s):
+  - linux/Documentation/devicetree/bindings/serial/serial.yaml
+  - linux/Documentation/devicetree/bindings/serial/8250.txt
+  - linux/Documentation/devicetree/bindings/serial/arm_sbsa_uart.txt
+  - linux/Documentation/devicetree/bindings/serial/pl011.yaml
+**/
+
+#include <IndustryStandard/DebugPort2Table.h>
+
+#include "CmObjectDescUtility.h"
+#include "FdtHwInfoParser.h"
+#include "Serial/ArmSerialPortParser.h"
+
+/** List of "compatible" property values for serial port nodes.
+
+  Any other "compatible" value is not supported by this module.
+*/
+STATIC CONST COMPATIBILITY_STR SerialCompatibleStr[] = {
+  {"ns16550a"},
+  {"arm,sbsa-uart"}
+};
+
+/** COMPATIBILITY_INFO structure for the SerialCompatible.
+*/
+CONST COMPATIBILITY_INFO SerialCompatibleInfo = {
+  ARRAY_SIZE (SerialCompatibleStr),
+  SerialCompatibleStr
+};
+
+/** 16550 UART compatible strings.
+
+  Any string of this list must be part of SerialCompatible.
+*/
+STATIC CONST COMPATIBILITY_STR Serial16550CompatibleStr[] = {
+  {"ns16550a"}
+};
+
+/** COMPATIBILITY_INFO structure for the Serial16550Compatible.
+*/
+CONST COMPATIBILITY_INFO Serial16550CompatibleInfo = {
+  ARRAY_SIZE (Serial16550CompatibleStr),
+  Serial16550CompatibleStr
+};
+
+/** SBSA UART compatible strings.
+
+  Any string of this list must be part of SerialCompatible.
+*/
+STATIC CONST COMPATIBILITY_STR SerialSbsaCompatibleStr[] = {
+  {"arm,sbsa-uart"}
+};
+
+/** COMPATIBILITY_INFO structure for the SerialSbsaCompatible.
+*/
+CONST COMPATIBILITY_INFO SerialSbsaCompatibleInfo = {
+  ARRAY_SIZE (SerialSbsaCompatibleStr),
+  SerialSbsaCompatibleStr
+};
+
+/** Parse a serial port node.
+
+  @param [in]  Fdt               Pointer to a Flattened Device Tree (Fdt).
+  @param [in]  SerialPortNode    Offset of a serial-port node.
+  @param [in]  SerialPortInfo    The CM_ARM_SERIAL_PORT_INFO to populate.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_ABORTED             An error occurred.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+  @retval EFI_UNSUPPORTED         Unsupported.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SerialPortNodeParser (
+  IN  CONST VOID               * Fdt,
+  IN  INT32                      SerialPortNode,
+  IN  CM_ARM_SERIAL_PORT_INFO  * SerialPortInfo
+  )
+{
+  EFI_STATUS     Status;
+  INT32          IntcNode;
+  CONST UINT8  * SizeValue;
+
+  INT32          AddressCells;
+  INT32          SizeCells;
+  INT32          IntCells;
+
+  CONST UINT8  * Data;
+  INT32          DataSize;
+  UINT8          AccessSize;
+
+  if ((Fdt == NULL) ||
+      (SerialPortInfo == NULL)) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = FdtGetParentAddressInfo (
+             Fdt,
+             SerialPortNode,
+             &AddressCells,
+             &SizeCells
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
+    return Status;
+  }
+
+  // Don't support more than 64 bits and less than 32 bits addresses.
+  if ((AddressCells < 1)  ||
+      (AddressCells > 2)  ||
+      (SizeCells < 1)     ||
+      (SizeCells > 2)) {
+    ASSERT (0);
+    return EFI_ABORTED;
+  }
+
+  Data = fdt_getprop (Fdt, SerialPortNode, "reg", &DataSize);
+  if ((Data == NULL) ||
+      (DataSize < (INT32)(sizeof (UINT32) *
+         GET_DT_REG_ADDRESS_OFFSET (1, AddressCells, SizeCells)) - 1)) {
+    // If error or not enough space.
+    ASSERT (0);
+    return EFI_ABORTED;
+  }
+
+  if (AddressCells == 2) {
+    SerialPortInfo->BaseAddress = fdt64_to_cpu (*(UINT64*)Data);
+  } else {
+    SerialPortInfo->BaseAddress = fdt32_to_cpu (*(UINT32*)Data);
+  }
+
+  SizeValue = Data + (sizeof (UINT32) *
+    GET_DT_REG_SIZE_OFFSET (0, AddressCells, SizeCells));
+  if (SizeCells == 2) {
+    SerialPortInfo->BaseAddressLength = fdt64_to_cpu (*(UINT64*)SizeValue);
+  } else {
+    SerialPortInfo->BaseAddressLength = fdt32_to_cpu (*(UINT32*)SizeValue);
+  }
+
+  // Get the associated interrupt-controller.
+  Status= FdtGetIntcParentNode (Fdt, SerialPortNode, &IntcNode);
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
+    if (Status == EFI_NOT_FOUND) {
+      // Should have found the node.
+      Status = EFI_ABORTED;
+    }
+    return Status;
+  }
+
+  // Get the number of cells used to encode an interrupt.
+  Status = FdtGetInterruptCellsInfo (Fdt, IntcNode, &IntCells);
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
+    return Status;
+  }
+
+  Data = fdt_getprop (Fdt, SerialPortNode, "interrupts", &DataSize);
+  if ((Data == NULL) || (DataSize != (IntCells * sizeof (UINT32)))) {
+    // If error or not 1 interrupt.
+    ASSERT (0);
+    return EFI_ABORTED;
+  }
+
+  SerialPortInfo->Interrupt = FdtGetInterruptId ((CONST UINT32*)Data);
+
+  // Note: clock-frequency is optional for SBSA UART.
+  Data = fdt_getprop (Fdt, SerialPortNode, "clock-frequency", &DataSize);
+  if (Data != NULL) {
+    if (DataSize < sizeof (UINT32)) {
+      // If error or not enough space.
+      ASSERT (0);
+      return EFI_ABORTED;
+    } else if (fdt_node_offset_by_phandle (Fdt, fdt32_to_cpu (*Data)) >= 0) {
+      // "clock-frequency" can be a "clocks phandle to refer to the clk used".
+      // This is not supported.
+      ASSERT (0);
+      return EFI_UNSUPPORTED;
+    }
+    SerialPortInfo->Clock = fdt32_to_cpu (*(UINT32*)Data);
+  }
+
+  if (FdtNodeIsCompatible (Fdt, SerialPortNode, &Serial16550CompatibleInfo)) {
+    SerialPortInfo->PortSubtype = EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_FULL_16550;
[SAMI] I think this needs to be set to EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_16550_WITH_GAS.
+
+    /* reg-io-width:
+         description: |
+         The size (in bytes) of the IO accesses that should be performed on the
+         device. There are some systems that require 32-bit accesses to the
+         UART.
+    */
+    Data = fdt_getprop (Fdt, SerialPortNode, "reg-io-width", &DataSize);
+    if (Data != NULL) {
+      if (DataSize < sizeof (UINT32)) {
+        // If error or not enough space.
+        ASSERT (0);
+        return EFI_ABORTED;
+      }
+
+      AccessSize = fdt32_to_cpu (*(UINT32*)Data);
+      if (AccessSize > EFI_ACPI_6_3_QWORD) {
+        ASSERT (0);
+        return EFI_INVALID_PARAMETER;
+      }
+      SerialPortInfo->AccessSize = AccessSize;
+    } else {
+      // 8250/16550 defaults to byte access.
+      SerialPortInfo->AccessSize = EFI_ACPI_6_3_BYTE;
+    }
+  } else if (FdtNodeIsCompatible (
+               Fdt,
+               SerialPortNode,
+               &SerialSbsaCompatibleInfo
+               )) {
+    SerialPortInfo->PortSubtype =
+      EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART;
[SAMI] Should PL011 be supported as well?
+  } else {
+    ASSERT (0);
+    return EFI_UNSUPPORTED;
+  }
+
+  // Set Baudrate to 115200 by default
+  SerialPortInfo->BaudRate = 115200;
+  return EFI_SUCCESS;
+}
+
+/** Find the console serial-port node in the DT.
+
+  This function fetches the node referenced in the "stdout-path"
+  property of the "chosen" node.
+
+  @param [in]  Fdt                  Pointer to a Flattened Device Tree (Fdt).
+  @param [out] SerialConsoleNode    If success, contains the node offset
+                                    of the console serial-port node.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_ABORTED             An error occurred.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+  @retval EFI_NOT_FOUND           Not found.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GetSerialConsoleNode (
+  IN  CONST VOID    * Fdt,
+  OUT       INT32   * SerialConsoleNode
+  )
+{
+  CONST CHAR8 * Prop;
+  INT32         PropSize;
+  CONST CHAR8 * Path;
+  INT32         PathLen;
+  INT32         ChosenNode;
+
+  if ((Fdt == NULL) ||
+      (SerialConsoleNode == NULL)) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // The "chosen" node resides at the the root of the DT. Fetch it.
+  ChosenNode = fdt_path_offset (Fdt, "/chosen");
+  if (ChosenNode < 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  Prop = fdt_getprop (Fdt, ChosenNode, "stdout-path", &PropSize);
+  if ((Prop == NULL) || (PropSize < 0)) {
+    return EFI_NOT_FOUND;
+  }
+
+  // Determine the actual path length, as a colon terminates the path.
+  Path = ScanMem8 (Prop, ':', PropSize);
+  if (Path == NULL) {
+    PathLen = (UINT32)AsciiStrLen (Prop);
+  } else {
+    PathLen = (INT32)(Path - Prop);
+  }
+
+  // Aliases cannot start with a '/', so it must be the actual path.
+  if (Prop[0] == '/') {
+    *SerialConsoleNode = fdt_path_offset_namelen (Fdt, Prop, PathLen);
+    return EFI_SUCCESS;
+  }
+
+  // Lookup the alias, as this contains the actual path.
+  Path = fdt_get_alias_namelen (Fdt, Prop, PathLen);
+  if (Path == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  *SerialConsoleNode = fdt_path_offset (Fdt, Path);
+  return EFI_SUCCESS;
+}
+
+/** CM_ARM_SERIAL_PORT_INFO dispatcher function (for a generic serial-port).
+
+  @param [in]  FdtParserHandle A handle to the parser instance.
+  @param [in]  GenericSerialInfo  Pointer to a serial port info list.
+  @param [in]  NodeCount          Count of serial ports to dispatch.
+  @param [in]  SerialObjectId     Serial port object ID.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_ABORTED             An error occurred.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+  @retval EFI_NOT_FOUND           Not found.
+  @retval EFI_UNSUPPORTED         Unsupported.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ArmSerialPortInfoDispatch (
+  IN  CONST FDT_HW_INFO_PARSER_HANDLE   FdtParserHandle,
+  IN  CM_ARM_SERIAL_PORT_INFO         * GenericSerialInfo,
+  IN  INT32                             NodeCount,
+  IN  EARM_OBJECT_ID                    SerialObjectId
+)
+{
+  EFI_STATUS                Status;
+  CM_OBJ_DESCRIPTOR       * NewCmObjDesc;
+
+  if ((GenericSerialInfo == NULL) || (NodeCount == 0)) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((SerialObjectId != EArmObjSerialPortInfo) &&
+      (SerialObjectId != EArmObjSerialDebugPortInfo) &&
+      (SerialObjectId != EArmObjSerialConsolePortInfo)) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Dispatch the Generic Serial ports
+  Status = CreateCmObjDesc (
+             CREATE_CM_ARM_OBJECT_ID (SerialObjectId),
+             NodeCount,
+             GenericSerialInfo,
+             sizeof (CM_ARM_SERIAL_PORT_INFO) * NodeCount,
+             &NewCmObjDesc
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
+    return Status;
+  }
+
+  // Add all the CmObjs to the Configuration Manager.
+  Status = AddMultipleCmObj (FdtParserHandle, NewCmObjDesc, 0, NULL);
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
+  }
+
+  FreeCmObjDesc (NewCmObjDesc);
+  return Status;
+}
+
+/** CM_ARM_SERIAL_PORT_INFO parser function (for debug/console serial-port).
+
+  This parser expects FdtBranch to be the debug serial-port node.
+  At most one CmObj is created.
+  The following structure is populated:
+  typedef struct CmArmSerialPortInfo {
+    UINT64  BaseAddress;                      // {Populated}
+    UINT32  Interrupt;                        // {Populated}
+    UINT64  BaudRate;                         // {default}
+    UINT32  Clock;                            // {Populated}
+    UINT16  PortSubtype;                      // {Populated}
+    UINT64  BaseAddressLength                 // {Populated}
+  } CM_ARM_SERIAL_PORT_INFO;
+
+  A parser parses a Device Tree to populate a specific CmObj type. None,
+  one or many CmObj can be created by the parser.
+  The created CmObj are then handed to the parser's caller through the
+  HW_INFO_ADD_OBJECT interface.
+  This can also be a dispatcher. I.e. a function that not parsing a
+  Device Tree but calling other parsers.
+
+  @param [in]  FdtParserHandle A handle to the parser instance.
+  @param [in]  FdtBranch       When searching for DT node name, restrict
+                               the search to this Device Tree branch.
+  @param [in]  SerialObjectId  ArmNamespace Object ID for the serial port.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_ABORTED             An error occurred.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+  @retval EFI_NOT_FOUND           Not found.
+  @retval EFI_UNSUPPORTED         Unsupported.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ArmSerialPortInfoParser (
+  IN  CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle,
+  IN        INT32                     FdtBranch,
+  IN        EARM_OBJECT_ID            SerialObjectId
+  )
+{
+  EFI_STATUS                Status;
+  CM_ARM_SERIAL_PORT_INFO   SerialInfo;
+
+  if ((SerialObjectId != EArmObjSerialDebugPortInfo) &&
+      (SerialObjectId != EArmObjSerialConsolePortInfo)) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ZeroMem (&SerialInfo, sizeof (SerialInfo));
+
+  Status = SerialPortNodeParser (
+             FdtParserHandle->Fdt,
+             FdtBranch,
+             &SerialInfo
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
+    return Status;
+  }
+
+  Status = ArmSerialPortInfoDispatch (
+             FdtParserHandle,
+             &SerialInfo,
+             1,
+             SerialObjectId
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
+  }
+
+  return Status;
+}
+
+/** SerialPort dispatcher.
+
+  This disptacher populates the CM_ARM_SERIAL_PORT_INFO structure for
+  the following CM_OBJ_ID:
+   - EArmObjSerialConsolePortInfo
+   - EArmObjSerialDebugPortInfo
+   - EArmObjSerialPortInfo
+
+  A parser parses a Device Tree to populate a specific CmObj type. None,
+  one or many CmObj can be created by the parser.
+  The created CmObj are then handed to the parser's caller through the
+  HW_INFO_ADD_OBJECT interface.
+  This can also be a dispatcher. I.e. a function that not parsing a
+  Device Tree but calling other parsers.
+
+  @param [in]  FdtParserHandle A handle to the parser instance.
+  @param [in]  FdtBranch       When searching for DT node name, restrict
+                               the search to this Device Tree branch.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_ABORTED             An error occurred.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+  @retval EFI_NOT_FOUND           Not found.
+  @retval EFI_UNSUPPORTED         Unsupported.
+**/
+EFI_STATUS
+EFIAPI
+SerialPortDispatcher (
+  IN  CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle,
+  IN        INT32                     FdtBranch
+  )
+{
+  EFI_STATUS                Status;
+  INT32                     SerialConsoleNode;
+  INT32                     SerialDebugNode;
+  INT32                     SerialNode;
+  UINT32                    Index;
+  UINT32                    SerialNodeCount;
+  UINT32                    SerialNodesRemaining;
+  CM_ARM_SERIAL_PORT_INFO * GenericSerialInfo;
+  UINT32                    GenericSerialIndex;
+  VOID                    * Fdt;
+
+  if (FdtParserHandle == NULL) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Fdt = FdtParserHandle->Fdt;
+
+  // Count the number of serial-ports.
+  Status = FdtCountCompatNodeInBranch (
+             Fdt,
+             FdtBranch,
+             &SerialCompatibleInfo,
+             &SerialNodeCount
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
+    return Status;
+  }
+
+  if (SerialNodeCount == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  // Track remaining nodes separately as SerialNodeCount
+  // is used in for loop below and reducing SerialNodeCount
+  // would result in the Generic Serial port nodes not
+  // being found if the serial console port node is among
+  // the first few serial nodes.
+  SerialNodesRemaining = SerialNodeCount;
+
+  // Identify the serial console port.
+  Status = GetSerialConsoleNode (Fdt, &SerialConsoleNode);
+  if (Status == EFI_NOT_FOUND) {
+    // No serial console.
+    SerialConsoleNode = -1;
+  } else if (EFI_ERROR (Status)) {
+    ASSERT (0);
+    return Status;
+  } else {
+    // Parse the console serial-port.
+    Status = ArmSerialPortInfoParser (
+               FdtParserHandle,
+               SerialConsoleNode,
+               EArmObjSerialConsolePortInfo
+               );
+    if (EFI_ERROR (Status)) {
+      ASSERT (0);
+      return Status;
+    }
+    SerialNodesRemaining--;
+  }
+
+  GenericSerialInfo = NULL;
+  if (SerialNodesRemaining > 1) {
+    // We have more than one serial port remaining.
+    // This means that the first serial port will
+    // be reserved as a debug port, and the remaining
+    // will be for general purpose use.
+    SerialNodesRemaining--;
+    GenericSerialInfo = AllocateZeroPool (
+                          SerialNodesRemaining *
+                          sizeof (CM_ARM_SERIAL_PORT_INFO)
+                          );
+    if (GenericSerialInfo == NULL) {
+      ASSERT (0);
+      return EFI_OUT_OF_RESOURCES;
+    }
+  }
+
+  SerialNode = FdtBranch;
+  SerialDebugNode = -1;
+  GenericSerialIndex = 0;
+  for (Index = 0; Index < SerialNodeCount; Index++) {
+    // Search the next serial-port node in the branch.
+    Status = FdtGetNextCompatNodeInBranch (
+               Fdt,
+               FdtBranch,
+               &SerialCompatibleInfo,
+               &SerialNode
+               );
+    if (EFI_ERROR (Status)) {
+      ASSERT (0);
+      if (Status == EFI_NOT_FOUND) {
+        // Should have found the node.
+        Status = EFI_ABORTED;
+      }
+      goto exit_handler;
+    }
+
+    // Ignore the serial console node.
+    if (SerialNode == SerialConsoleNode) {
+      continue;
+    } else if (SerialDebugNode == -1) {
+      // The first serial-port node, not being the console serial-port,
+      // will be the debug serial-port.
+      SerialDebugNode = SerialNode;
+      Status = ArmSerialPortInfoParser (
+                 FdtParserHandle,
+                 SerialDebugNode,
+                 EArmObjSerialDebugPortInfo
+                 );
+      if (EFI_ERROR (Status)) {
+        ASSERT (0);
+        goto exit_handler;
+      }
+    } else {
+      if (GenericSerialInfo == NULL) {
+        // Should not be possible.
+        ASSERT (0);
+        Status = EFI_ABORTED;
+        goto exit_handler;
+      }
+
+      Status = SerialPortNodeParser (
+                 Fdt,
+                 SerialNode,
+                 &GenericSerialInfo[GenericSerialIndex++]
+                 );
+      if (EFI_ERROR (Status)) {
+        ASSERT (0);
+        goto exit_handler;
+      }
+    }
+  } // for
+
+  if (GenericSerialIndex > 0) {
+    Status = ArmSerialPortInfoDispatch (
+               FdtParserHandle,
+               GenericSerialInfo,
+               GenericSerialIndex,
+               EArmObjSerialPortInfo
+               );
+  }
+
+exit_handler:
+  if (GenericSerialInfo != NULL) {
+    FreePool (GenericSerialInfo);
+  }
+  return Status;
+}
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.h
new file mode 100644
index 000000000000..5e4707849e39
--- /dev/null
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.h
@@ -0,0 +1,47 @@
+/** @file
+  Arm Serial Port Parser.
+
+  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Reference(s):
+  - linux/Documentation/devicetree/bindings/serial/serial.yaml
+  - linux/Documentation/devicetree/bindings/serial/8250.txt
+**/
+
+#ifndef ARM_SERIAL_PORT_PARSER_H_
+#define ARM_SERIAL_PORT_PARSER_H_
+
+/** SerialPort dispatcher.
+
+  This disptacher populates the CM_ARM_SERIAL_PORT_INFO structure for
+  the following CM_OBJ_ID:
+   - EArmObjSerialConsolePortInfo
+   - EArmObjSerialDebugPortInfo
+   - EArmObjSerialPortInfo
+
+  A parser parses a Device Tree to populate a specific CmObj type. None,
+  one or many CmObj can be created by the parser.
+  The created CmObj are then handed to the parser's caller through the
+  HW_INFO_ADD_OBJECT interface.
+  This can also be a dispatcher. I.e. a function that not parsing a
+  Device Tree but calling other parsers.
+
+  @param [in]  FdtParserHandle A handle to the parser instance.
+  @param [in]  FdtBranch       When searching for DT node name, restrict
+                               the search to this Device Tree branch.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_ABORTED             An error occurred.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+  @retval EFI_NOT_FOUND           Not found.
+  @retval EFI_UNSUPPORTED         Unsupported.
+**/
+EFI_STATUS
+EFIAPI
+SerialPortDispatcher (
+  IN  CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle,
+  IN        INT32                     FdtBranch
+  );
+
+#endif // ARM_SERIAL_PORT_PARSER_H_


Re: [PATCH v1 03/14] DynamicTablesPkg: FdtHwInfoParser: Add FDT utility functions

Sami Mujawar
 

Hi Pierre,

I have a minor comment, otherwise this patch looks good to me.

Regards,

Sami Mujawar

On 23/06/2021 01:38 PM, Pierre.Gondois@arm.com wrote:
From: Pierre Gondois <Pierre.Gondois@arm.com>

The FdtHwInfoParser parses a platform Device Tree and populates
the Platform Information repository with Configuration Manager
objects.

Therefore, add a set of helper functions to simplify parsing of
the platform Device Tree.

Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
.../Library/FdtHwInfoParserLib/FdtUtility.c | 909 ++++++++++++++++++
.../Library/FdtHwInfoParserLib/FdtUtility.h | 458 +++++++++
2 files changed, 1367 insertions(+)
create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.c
create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.h

diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.c
new file mode 100644
index 000000000000..0fca82aedf9e
--- /dev/null
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.c
@@ -0,0 +1,909 @@
+/** @file
+ Flattened device tree utility.
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - Device tree Specification - Release v0.3
+ - linux/Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.yaml
+ - linux//Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.yaml
+**/
+
+#include <FdtHwInfoParserInclude.h>
+#include "FdtUtility.h"
+
+/** Get the interrupt Id of an interrupt described in a fdt.
+
+ Data must describe a GIC interrupt. A GIC interrupt is on at least
+ 3 UINT32 cells.
+ This function DOES NOT SUPPORT extended SPI range and extended PPI range.
+
+ @param [in] Data Pointer to the first cell of an "interrupts" property.
+
+ @retval The interrupt id.
+**/
+UINT32
+EFIAPI
+FdtGetInterruptId (
+ UINT32 CONST * Data
+ )
+{
+ UINT32 IrqType;
+ UINT32 IrqId;
+
+ ASSERT (Data != NULL);
+
+ IrqType = fdt32_to_cpu (Data[IRQ_TYPE_OFFSET]);
+ IrqId = fdt32_to_cpu (Data[IRQ_NUMBER_OFFSET]);
+
+ switch (IrqType) {
+ case DT_SPI_IRQ:
+ IrqId += SPI_OFFSET;
+ break;
+
+ case DT_PPI_IRQ:
+ IrqId += PPI_OFFSET;
+ break;
+
+ default:
+ ASSERT (0);
+ IrqId = 0;
+ }
+
+ return IrqId;
+}
+
+/** Get the ACPI interrupt flags of an interrupt described in a fdt.
+
+ Data must describe a GIC interrupt. A GIC interrupt is on at least
+ 3 UINT32 cells.
+
+ PPI interrupt cpu mask on bits [15:8] are ignored.
+
+ @param [in] Data Pointer to the first cell of an "interrupts" property.
+
+ @retval The interrupt flags (for ACPI).
+**/
+UINT32
+EFIAPI
+FdtGetInterruptFlags (
+ UINT32 CONST * Data
+ )
+{
+ UINT32 IrqFlags;
+ UINT32 AcpiIrqFlags;
+
+ ASSERT (Data != NULL);
+
+ IrqFlags = fdt32_to_cpu (Data[IRQ_FLAGS_OFFSET]);
+
+ AcpiIrqFlags = DT_IRQ_IS_EDGE_TRIGGERED (IrqFlags) ? BIT0 : 0;
+ AcpiIrqFlags |= DT_IRQ_IS_ACTIVE_LOW (IrqFlags) ? BIT1 : 0;
+
+ return AcpiIrqFlags;
+}
+
+/** Check whether a node has the input name.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] Node Offset of the node to check the name.
+ @param [in] SearchName Node name to search.
+ This is a NULL terminated string.
+
+ @retval True The node has the input name.
+ @retval FALSE Otherwise, or error.
+**/
+STATIC
+BOOLEAN
+EFIAPI
+FdtNodeHasName (
+ IN CONST VOID * Fdt,
+ IN INT32 Node,
+ IN CONST VOID * SearchName
+ )
+{
+ CONST CHAR8 * NodeName;
+ UINT32 Length;
+
+ if ((Fdt == NULL) ||
+ (SearchName == NULL)) {
+ ASSERT (0);
+ return FALSE;
+ }
+
+ // Always compare the whole string. Don't stop at the "@" char.
+ Length = (UINT32)AsciiStrLen (SearchName);
+
+ // Get the address of the node name.
+ NodeName = fdt_offset_ptr (Fdt, Node + FDT_TAGSIZE, Length + 1);
+ if (NodeName == NULL) {
+ return FALSE;
+ }
+
+ // SearchName must be longer than the node name.
+ if (Length > AsciiStrLen (NodeName)) {
+ return FALSE;
+ }
+
+ // Use CompareMem here instead of AsciiStrnCmp as the NodeName
[SAMI] I think the comment here needs to be updated.
+ // may contain the node name followed by '@'0x<addr>.
+ if (AsciiStrnCmp (NodeName, SearchName, Length) != 0) {
+ return FALSE;
+ }
+
+ // The name matches perfectly, or
+ // the node name is XXX@addr and the XXX matches.
+ if ((NodeName[Length] == '\0') ||
+ (NodeName[Length] == '@')) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/** Iterate through the list of strings in the Context,
+ and check whether at least one string is matching the
+ "compatible" property of the node.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] Node Offset of the node to operate the check on.
+ @param [in] CompatInfo COMPATIBILITY_INFO containing the list of compatible
+ strings to compare with the "compatible" property
+ of the node.
+
+ @retval TRUE At least one string matched, the node is compatible.
+ @retval FALSE Otherwise, or error.
+**/
+BOOLEAN
+EFIAPI
+FdtNodeIsCompatible (
+ IN CONST VOID * Fdt,
+ IN INT32 Node,
+ IN CONST VOID * CompatInfo
+ )
+{
+ UINT32 Index;
+ CONST COMPATIBILITY_STR * CompatibleTable;
+ UINT32 Count;
+ CONST VOID * Prop;
+ INT32 PropLen;
+
+ if ((Fdt == NULL) ||
+ (CompatInfo == NULL)) {
+ ASSERT (0);
+ return FALSE;
+ }
+
+ Count = ((COMPATIBILITY_INFO*)CompatInfo)->Count;
+ CompatibleTable = ((COMPATIBILITY_INFO*)CompatInfo)->CompatTable;
+
+ // Get the "compatible" property.
+ Prop = fdt_getprop (Fdt, Node, "compatible", &PropLen);
+ if ((Prop == NULL) || (PropLen < 0)) {
+ return FALSE;
+ }
+
+ for (Index = 0; Index < Count; Index++) {
+ if (fdt_stringlist_contains (
+ Prop,
+ PropLen,
+ CompatibleTable[Index].CompatStr
+ )) {
+ return TRUE;
+ }
+ } // for
+
+ return FALSE;
+}
+
+/** Check whether a node has a property.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] Node Offset of the node to operate the check on.
+ @param [in] PropertyName Name of the property to search.
+ This is a NULL terminated string.
+
+ @retval True The node has the property.
+ @retval FALSE Otherwise, or error.
+**/
+BOOLEAN
+EFIAPI
+FdtNodeHasProperty (
+ IN CONST VOID * Fdt,
+ IN INT32 Node,
+ IN CONST VOID * PropertyName
+ )
+{
+ INT32 Size;
+ CONST VOID * Prop;
+
+ if ((Fdt == NULL) ||
+ (PropertyName == NULL)) {
+ ASSERT (0);
+ return FALSE;
+ }
+
+ Prop = fdt_getprop (Fdt, Node, PropertyName, &Size);
+ if ((Prop == NULL) || (Size < 0)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/** Get the next node in the whole DT fulfilling a condition.
+
+ The condition to fulfill is checked by the NodeChecker function.
+ Context is passed to NodeChecker.
+
+ The Device tree is traversed in a depth-first search, starting from Node.
+ The input Node is skipped.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in, out] Node At entry: Node offset to start the search.
+ This first node is skipped.
+ Write (-1) to search the whole tree.
+ At exit: If success, contains the offset of
+ the next node fulfilling the
+ condition.
+ @param [in, out] Depth Depth is incremented/decremented of the depth
+ difference between the input Node and the
+ output Node.
+ E.g.: If the output Node is a child node
+ of the input Node, contains (+1).
+ @param [in] NodeChecker Function called to check if the condition
+ is fulfilled.
+ @param [in] Context Context for the NodeChecker.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND No matching node found.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FdtGetNextCondNode (
+ IN CONST VOID * Fdt,
+ IN OUT INT32 * Node,
+ IN OUT INT32 * Depth,
+ IN NODE_CHECKER_FUNC NodeChecker,
+ IN CONST VOID * Context
+ )
+{
+ INT32 CurrNode;
+
+ if ((Fdt == NULL) ||
+ (Node == NULL) ||
+ (Depth == NULL) ||
+ (NodeChecker == NULL)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CurrNode = *Node;
+ do {
+ CurrNode = fdt_next_node (Fdt, CurrNode, Depth);
+ if ((CurrNode == -FDT_ERR_NOTFOUND) ||
+ (*Depth < 0)) {
+ // End of the tree, no matching node found.
+ return EFI_NOT_FOUND;
+ } else if (CurrNode < 0) {
+ // An error occurred.
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+ } while (!NodeChecker (Fdt, CurrNode, Context));
+
+ // Matching node found.
+ *Node = CurrNode;
+ return EFI_SUCCESS;
+}
+
+/** Get the next node in a branch fulfilling a condition.
+
+ The condition to fulfill is checked by the NodeChecker function.
+ Context is passed to NodeChecker.
+
+ The Device tree is traversed in a depth-first search, starting from Node.
+ The input Node is skipped.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] FdtBranch Only search in the sub-nodes of this
+ branch.
+ Write (-1) to search the whole tree.
+ @param [in] NodeChecker Function called to check if the condition
+ is fulfilled.
+ @param [in] Context Context for the NodeChecker.
+ @param [in, out] Node At entry: Node offset to start the search.
+ This first node is skipped.
+ Write (-1) to search the whole tree.
+ At exit: If success, contains the offset
+ of the next node in the branch
+ fulfilling the condition.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND No matching node found.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FdtGetNextCondNodeInBranch (
+ IN CONST VOID * Fdt,
+ IN INT32 FdtBranch,
+ IN NODE_CHECKER_FUNC NodeChecker,
+ IN CONST VOID * Context,
+ IN OUT INT32 * Node
+ )
+{
+ EFI_STATUS Status;
+ INT32 CurrNode;
+ INT32 Depth;
+
+ if ((Fdt == NULL) ||
+ (Node == NULL) ||
+ (NodeChecker == NULL)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CurrNode = FdtBranch;
+ Depth = 0;
+
+ // First, check the Node is in the sub-nodes of the branch.
+ // This allows to find the relative depth of Node in the branch.
+ if (CurrNode != *Node) {
+ for (CurrNode = fdt_next_node (Fdt, CurrNode, &Depth);
+ (CurrNode >= 0) && (Depth > 0);
+ CurrNode = fdt_next_node (Fdt, CurrNode, &Depth)) {
+ if (CurrNode == *Node) {
+ // Node found.
+ break;
+ }
+ } // for
+
+ if ((CurrNode < 0) || (Depth <= 0)) {
+ // Node is not a node in the branch, or an error occurred.
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ // Get the next node in the tree fulfilling the condition,
+ // in any branch.
+ Status = FdtGetNextCondNode (
+ Fdt,
+ Node,
+ &Depth,
+ NodeChecker,
+ Context
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (Status == EFI_NOT_FOUND);
+ return Status;
+ }
+
+ if (Depth <= 0) {
+ // The node found is not in the right branch.
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Get the next node in a branch having a matching name.
+
+ The Device tree is traversed in a depth-first search, starting from Node.
+ The input Node is skipped.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] FdtBranch Only search in the sub-nodes of this branch.
+ Write (-1) to search the whole tree.
+ @param [in] NodeName The node name to search.
+ This is a NULL terminated string.
+ @param [in, out] Node At entry: Node offset to start the search.
+ This first node is skipped.
+ Write (-1) to search the whole tree.
+ At exit: If success, contains the offset of
+ the next node in the branch
+ having a matching name.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND No matching node found.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetNextNamedNodeInBranch (
+ IN CONST VOID * Fdt,
+ IN INT32 FdtBranch,
+ IN CONST CHAR8 * NodeName,
+ IN OUT INT32 * Node
+ )
+{
+ return FdtGetNextCondNodeInBranch (
+ Fdt,
+ FdtBranch,
+ FdtNodeHasName,
+ NodeName,
+ Node
+ );
+}
+
+/** Get the next node in a branch with at least one compatible property.
+
+ The Device tree is traversed in a depth-first search, starting from Node.
+ The input Node is skipped.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] FdtBranch Only search in the sub-nodes of this branch.
+ Write (-1) to search the whole tree.
+ @param [in] CompatNamesInfo Table of compatible strings to compare with
+ the compatible property of the node.
+ @param [in, out] Node At entry: Node offset to start the search.
+ This first node is skipped.
+ Write (-1) to search the whole tree.
+ At exit: If success, contains the offset of
+ the next node in the branch
+ being compatible.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND No matching node found.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetNextCompatNodeInBranch (
+ IN CONST VOID * Fdt,
+ IN INT32 FdtBranch,
+ IN CONST COMPATIBILITY_INFO * CompatNamesInfo,
+ IN OUT INT32 * Node
+ )
+{
+ return FdtGetNextCondNodeInBranch (
+ Fdt,
+ FdtBranch,
+ FdtNodeIsCompatible,
+ (CONST VOID*)CompatNamesInfo,
+ Node
+ );
+}
+
+/** Get the next node in a branch having the PropName property.
+
+ The Device tree is traversed in a depth-first search, starting from Node.
+ The input Node is skipped.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] FdtBranch Only search in the sub-nodes of this branch.
+ Write (-1) to search the whole tree.
+ @param [in] PropName Name of the property to search.
+ This is a NULL terminated string.
+ @param [in, out] Node At entry: Node offset to start the search.
+ This first node is skipped.
+ Write (-1) to search the whole tree.
+ At exit: If success, contains the offset of
+ the next node in the branch
+ being compatible.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND No matching node found.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetNextPropNodeInBranch (
+ IN CONST VOID * Fdt,
+ IN INT32 FdtBranch,
+ IN CONST CHAR8 * PropName,
+ IN OUT INT32 * Node
+ )
+{
+ return FdtGetNextCondNodeInBranch (
+ Fdt,
+ FdtBranch,
+ FdtNodeHasProperty,
+ (CONST VOID*)PropName,
+ Node
+ );
+}
+
+/** Count the number of Device Tree nodes fulfilling a condition
+ in a Device Tree branch.
+
+ The condition to fulfill is checked by the NodeChecker function.
+ Context is passed to NodeChecker.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] FdtBranch Only search in the sub-nodes of this branch.
+ Write (-1) to search the whole tree.
+ @param [in] NodeChecker Function called to check the condition is
+ fulfilled.
+ @param [in] Context Context for the NodeChecker.
+ @param [out] NodeCount If success, contains the count of nodes
+ fulfilling the condition.
+ Can be 0.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FdtCountCondNodeInBranch (
+ IN CONST VOID * Fdt,
+ IN INT32 FdtBranch,
+ IN NODE_CHECKER_FUNC NodeChecker,
+ IN CONST VOID * Context,
+ OUT UINT32 * NodeCount
+ )
+{
+ EFI_STATUS Status;
+ INT32 CurrNode;
+
+ if ((Fdt == NULL) ||
+ (NodeChecker == NULL) ||
+ (NodeCount == NULL)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *NodeCount = 0;
+ CurrNode = FdtBranch;
+ while (TRUE) {
+ Status = FdtGetNextCondNodeInBranch (
+ Fdt,
+ FdtBranch,
+ NodeChecker,
+ Context,
+ &CurrNode
+ );
+ if (EFI_ERROR (Status) &&
+ (Status != EFI_NOT_FOUND)) {
+ ASSERT (0);
+ return Status;
+ } else if (Status == EFI_NOT_FOUND) {
+ break;
+ }
+ (*NodeCount)++;
+ }
+ return EFI_SUCCESS;
+}
+
+/** Count the number of nodes in a branch with the input name.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] FdtBranch Only search in the sub-nodes of this branch.
+ Write (-1) to search the whole tree.
+ @param [in] NodeName Node name to search.
+ This is a NULL terminated string.
+ @param [out] NodeCount If success, contains the count of nodes
+ fulfilling the condition.
+ Can be 0.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FdtCountNamedNodeInBranch (
+ IN CONST VOID * Fdt,
+ IN INT32 FdtBranch,
+ IN CONST CHAR8 * NodeName,
+ OUT UINT32 * NodeCount
+ )
+{
+ return FdtCountCondNodeInBranch (
+ Fdt,
+ FdtBranch,
+ FdtNodeHasName,
+ NodeName,
+ NodeCount
+ );
+}
+
+/** Count the number of nodes in a branch with at least
+ one compatible property.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] FdtBranch Only search in the sub-nodes of this branch.
+ Write (-1) to search the whole tree.
+ @param [in] CompatNamesInfo Table of compatible strings to
+ compare with the compatible property
+ of the node.
+ @param [out] NodeCount If success, contains the count of nodes
+ fulfilling the condition.
+ Can be 0.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FdtCountCompatNodeInBranch (
+ IN CONST VOID * Fdt,
+ IN INT32 FdtBranch,
+ IN CONST COMPATIBILITY_INFO * CompatNamesInfo,
+ OUT UINT32 * NodeCount
+ )
+{
+ return FdtCountCondNodeInBranch (
+ Fdt,
+ FdtBranch,
+ FdtNodeIsCompatible,
+ CompatNamesInfo,
+ NodeCount
+ );
+}
+
+/** Count the number of nodes in a branch having the PropName property.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] FdtBranch Only search in the sub-nodes of this branch.
+ Write (-1) to search the whole tree.
+ @param [in] PropName Name of the property to search.
+ This is a NULL terminated string.
+ @param [out] NodeCount If success, contains the count of nodes
+ fulfilling the condition.
+ Can be 0.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FdtCountPropNodeInBranch (
+ IN CONST VOID * Fdt,
+ IN INT32 FdtBranch,
+ IN CONST CHAR8 * PropName,
+ OUT UINT32 * NodeCount
+ )
+{
+ return FdtCountCondNodeInBranch (
+ Fdt,
+ FdtBranch,
+ FdtNodeHasProperty,
+ PropName,
+ NodeCount
+ );
+}
+
+/** Get the interrupt-controller node handling the interrupts of
+ the input node.
+
+ To do this, recursively search a node with either the "interrupt-controller"
+ or the "interrupt-parent" property in the parents of Node.
+
+ Devicetree Specification, Release v0.3,
+ 2.4.1 "Properties for Interrupt Generating Devices":
+ Because the hierarchy of the nodes in the interrupt tree
+ might not match the devicetree, the interrupt-parent
+ property is available to make the definition of an
+ interrupt parent explicit. The value is the phandle to the
+ interrupt parent. If this property is missing from a
+ device, its interrupt parent is assumed to be its devicetree
+ parent.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] Node Offset of the node to start the search.
+ @param [out] IntcNode If success, contains the offset of the
+ interrupt-controller node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_NOT_FOUND No interrupt-controller node found.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetIntcParentNode (
+ IN CONST VOID * Fdt,
+ IN INT32 Node,
+ OUT INT32 * IntcNode
+ )
+{
+ CONST UINT32 * PHandle;
+ INT32 Size;
+ CONST VOID * Prop;
+
+ if ((Fdt == NULL) ||
+ (IntcNode == NULL)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ while (TRUE) {
+ // Check whether the node has the "interrupt-controller" property.
+ Prop = fdt_getprop (Fdt, Node, "interrupt-controller", &Size);
+ if ((Prop != NULL) && (Size >= 0)) {
+ // The interrupt-controller has been found.
+ *IntcNode = Node;
+ return EFI_SUCCESS;
+ } else {
+ // Check whether the node has the "interrupt-parent" property.
+ PHandle = fdt_getprop (Fdt, Node, "interrupt-parent", &Size);
+ if ((PHandle != NULL) && (Size == sizeof (UINT32))) {
+ // The phandle of the interrupt-controller has been found.
+ // Search the node having this phandle and return it.
+ Node = fdt_node_offset_by_phandle (Fdt, fdt32_to_cpu (*PHandle));
+ if (Node < 0) {
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+
+ *IntcNode = Node;
+ return EFI_SUCCESS;
+ } else if (Size != -FDT_ERR_NOTFOUND) {
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+ }
+
+ if (Node == 0) {
+ // We are at the root of the tree. Not parent available.
+ return EFI_NOT_FOUND;
+ }
+
+ // Get the parent of the node.
+ Node = fdt_parent_offset (Fdt, Node);
+ if (Node < 0) {
+ // An error occurred.
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+ } // while
+}
+
+/** Get the "interrupt-cells" property value of the node.
+
+ The "interrupts" property requires to know the number of cells used
+ to encode an interrupt. This information is stored in the
+ interrupt-controller of the input Node.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
+ @param [in] IntcNode Offset of an interrupt-controller node.
+ @param [out] IntCells If success, contains the "interrupt-cells"
+ property of the IntcNode.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_UNSUPPORTED Unsupported.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetInterruptCellsInfo (
+ IN CONST VOID * Fdt,
+ IN INT32 IntcNode,
+ OUT INT32 * IntCells
+ )
+{
+ CONST UINT32 * Data;
+ INT32 Size;
+
+ if ((Fdt == NULL) ||
+ (IntCells == NULL)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Data = fdt_getprop (Fdt, IntcNode, "#interrupt-cells", &Size);
+ if ((Data == NULL) || (Size != sizeof (UINT32))) {
+ // If error or not on one UINT32 cell.
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+
+ *IntCells = fdt32_to_cpu (*Data);
+
+ return EFI_SUCCESS;
+}
+
+/** Get the "#address-cells" and/or "#size-cells" property of the node.
+
+ According to the Device Tree specification, s2.3.5 "#address-cells and
+ #size-cells":
+ "If missing, a client program should assume a default value of 2 for
+ #address-cells, and a value of 1 for #size-cells."
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] Node Offset of the node having to get the
+ "#address-cells" and "#size-cells"
+ properties from.
+ @param [out] AddressCells If success, number of address-cells.
+ If the property is not available,
+ default value is 2.
+ @param [out] SizeCells If success, number of size-cells.
+ If the property is not available,
+ default value is 1.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetAddressInfo (
+ IN CONST VOID * Fdt,
+ IN INT32 Node,
+ OUT INT32 * AddressCells, OPTIONAL
+ OUT INT32 * SizeCells OPTIONAL
+ )
+{
+ if (Fdt == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (AddressCells != NULL) {
+ *AddressCells = fdt_address_cells (Fdt, Node);
+ if (*AddressCells < 0) {
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+ }
+
+ if (SizeCells != NULL) {
+ *SizeCells = fdt_size_cells (Fdt, Node);
+ if (*SizeCells < 0) {
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Get the "#address-cells" and/or "#size-cells" property of the parent node.
+
+ According to the Device Tree specification, s2.3.5 "#address-cells and
+ #size-cells":
+ "If missing, a client program should assume a default value of 2 for
+ #address-cells, and a value of 1 for #size-cells."
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] Node Offset of the node having to get the
+ "#address-cells" and "#size-cells"
+ properties from its parent.
+ @param [out] AddressCells If success, number of address-cells.
+ If the property is not available,
+ default value is 2.
+ @param [out] SizeCells If success, number of size-cells.
+ If the property is not available,
+ default value is 1.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetParentAddressInfo (
+ IN CONST VOID * Fdt,
+ IN INT32 Node,
+ OUT INT32 * AddressCells, OPTIONAL
+ OUT INT32 * SizeCells OPTIONAL
+ )
+{
+ if (Fdt == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Node = fdt_parent_offset (Fdt, Node);
+ if (Node < 0) {
+ // End of the tree, or an error occurred.
+ ASSERT (0);
+ return EFI_ABORTED;
+ }
+
+ return FdtGetAddressInfo (Fdt, Node, AddressCells, SizeCells);
+}
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.h
new file mode 100644
index 000000000000..0076c5066d4c
--- /dev/null
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.h
@@ -0,0 +1,458 @@
+/** @file
+ Flattened device tree utility.
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - Device tree Specification - Release v0.3
+ - linux/Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.yaml
+ - linux//Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.yaml
+**/
+
+#ifndef FDT_UTILITY_H_
+#define FDT_UTILITY_H_
+
+/** Get the offset of an address in a "reg" Device Tree property.
+
+ In a Device Tree, the "reg" property stores address/size couples.
+ They are stored on N 32-bits cells.
+ Based on the value of the #address-cells, the #size-cells and the
+ index in the "reg" property, compute the number of 32-bits cells
+ to skip.
+
+ @param [in] Index Index in the reg property.
+ @param [in] AddrCells Number of cells used to store an address.
+ @param [in] SizeCells Number of cells used to store the size of
+ an address.
+
+ @retval Number of 32-bits cells to skip to access the address.
+*/
+#define GET_DT_REG_ADDRESS_OFFSET(Index, AddrCells, SizeCells) ( \
+ (Index) * ((AddrCells) + (SizeCells)) \
+ )
+
+/** Get the offset of an address size in a "reg" Device Tree property.
+
+ In a Device Tree, the "reg" property stores address/size couples.
+ They are stored on N 32-bits cells.
+ Based on the value of the #address-cells, the #size-cells and the
+ index in the "reg" property, compute the number of 32-bits cells
+ to skip.
+
+ @param [in] Index Index in the reg property.
+ @param [in] AddrCells Number of cells used to store an address.
+ @param [in] SizeCells Number of cells used to store the size of
+ an address.
+
+ @retval Number of 32-bits cells to skip to access the address size.
+*/
+#define GET_DT_REG_SIZE_OFFSET(Index, AddrCells, SizeCells) ( \
+ GET_DT_REG_ADDRESS_OFFSET ((Index), (AddrCells), (SizeCells)) + \
+ (SizeCells) \
+ )
+
+/// Maximum string length for compatible names.
+#define COMPATIBLE_STR_LEN (32U)
+
+/// Interrupt macros
+#define PPI_OFFSET (16U)
+#define SPI_OFFSET (32U)
+#define DT_PPI_IRQ (1U)
+#define DT_SPI_IRQ (0U)
+#define DT_IRQ_IS_EDGE_TRIGGERED(x) ((((x) & (BIT0 | BIT2)) != 0))
+#define DT_IRQ_IS_ACTIVE_LOW(x) ((((x) & (BIT1 | BIT3)) != 0))
+#define IRQ_TYPE_OFFSET (0U)
+#define IRQ_NUMBER_OFFSET (1U)
+#define IRQ_FLAGS_OFFSET (2U)
+
+/** Get the interrupt Id of an interrupt described in a fdt.
+
+ Data must describe a GIC interrupt. A GIC interrupt is on at least
+ 3 UINT32 cells.
+ This function DOES NOT SUPPORT extended SPI range and extended PPI range.
+
+ @param [in] Data Pointer to the first cell of an "interrupts" property.
+
+ @retval The interrupt id.
+**/
+UINT32
+EFIAPI
+FdtGetInterruptId (
+ UINT32 CONST * Data
+ );
+
+/** Get the ACPI interrupt flags of an interrupt described in a fdt.
+
+ Data must describe a GIC interrupt. A GIC interrupt is on at least
+ 3 UINT32 cells.
+
+ @param [in] Data Pointer to the first cell of an "interrupts" property.
+
+ @retval The interrupt flags (for ACPI).
+**/
+UINT32
+EFIAPI
+FdtGetInterruptFlags (
+ UINT32 CONST * Data
+ );
+
+/** A structure describing a compatibility string.
+*/
+typedef struct CompatStr {
+ CONST CHAR8 CompatStr[COMPATIBLE_STR_LEN];
+} COMPATIBILITY_STR;
+
+/** Structure containing a list of compatible names and their count.
+*/
+typedef struct CompatibilityInfo {
+ /// Count of entries in the NAME_TABLE.
+ UINT32 Count;
+
+ /// Pointer to a table storing the names.
+ CONST COMPATIBILITY_STR * CompatTable;
+} COMPATIBILITY_INFO;
+
+/** Operate a check on a Device Tree node.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] NodeOffset Offset of the node to compare input string.
+ @param [in] Context Context to operate the check on the node.
+
+ @retval True The check is correct.
+ @retval FALSE Otherwise, or error.
+**/
+typedef
+BOOLEAN
+(EFIAPI *NODE_CHECKER_FUNC) (
+ IN CONST VOID * Fdt,
+ IN INT32 NodeOffset,
+ IN CONST VOID * Context
+ );
+
+/** Iterate through the list of strings in the Context,
+ and check whether at least one string is matching the
+ "compatible" property of the node.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] Node Offset of the node to operate the check on.
+ @param [in] CompatInfo COMPATIBILITY_INFO containing the list of compatible
+ strings to compare with the "compatible" property
+ of the node.
+
+ @retval TRUE At least one string matched, the node is compatible.
+ @retval FALSE Otherwise, or error.
+**/
+BOOLEAN
+EFIAPI
+FdtNodeIsCompatible (
+ IN CONST VOID * Fdt,
+ IN INT32 Node,
+ IN CONST VOID * CompatInfo
+ );
+
+/** Check whether a node has a property.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] Node Offset of the node to operate the check on.
+ @param [in] PropertyName Name of the property to search.
+ This is a NULL terminated string.
+
+ @retval True The node has the property.
+ @retval FALSE Otherwise, or error.
+**/
+BOOLEAN
+EFIAPI
+FdtNodeHasProperty (
+ IN CONST VOID * Fdt,
+ IN INT32 Node,
+ IN CONST VOID * PropertyName
+ );
+
+/** Get the next node in a branch having a matching name.
+
+ The Device tree is traversed in a depth-first search, starting from Node.
+ The input Node is skipped.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] FdtBranch Only search in the sub-nodes of this branch.
+ Write (-1) to search the whole tree.
+ @param [in] NodeName The node name to search.
+ This is a NULL terminated string.
+ @param [in, out] Node At entry: Node offset to start the search.
+ This first node is skipped.
+ Write (-1) to search the whole tree.
+ At exit: If success, contains the offset of
+ the next node in the branch
+ having a matching name.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND No matching node found.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetNextNamedNodeInBranch (
+ IN CONST VOID * Fdt,
+ IN INT32 FdtBranch,
+ IN CONST CHAR8 * NodeName,
+ IN OUT INT32 * Node
+ );
+
+/** Get the next node in a branch with at least one compatible property.
+
+ The Device tree is traversed in a depth-first search, starting from Node.
+ The input Node is skipped.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] FdtBranch Only search in the sub-nodes of this branch.
+ Write (-1) to search the whole tree.
+ @param [in] CompatNamesInfo Table of compatible strings to compare with
+ the compatible property of the node.
+ @param [in, out] Node At entry: Node offset to start the search.
+ This first node is skipped.
+ Write (-1) to search the whole tree.
+ At exit: If success, contains the offset of
+ the next node in the branch
+ being compatible.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND No matching node found.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetNextCompatNodeInBranch (
+ IN CONST VOID * Fdt,
+ IN INT32 FdtBranch,
+ IN CONST COMPATIBILITY_INFO * CompatNamesInfo,
+ IN OUT INT32 * Node
+ );
+
+/** Get the next node in a branch having the PropName property.
+
+ The Device tree is traversed in a depth-first search, starting from Node.
+ The input Node is skipped.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] FdtBranch Only search in the sub-nodes of this branch.
+ Write (-1) to search the whole tree.
+ @param [in] PropName Name of the property to search.
+ This is a NULL terminated string.
+ @param [in, out] Node At entry: Node offset to start the search.
+ This first node is skipped.
+ Write (-1) to search the whole tree.
+ At exit: If success, contains the offset of
+ the next node in the branch
+ being compatible.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND No matching node found.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetNextPropNodeInBranch (
+ IN CONST VOID * Fdt,
+ IN INT32 FdtBranch,
+ IN CONST CHAR8 * PropName,
+ IN OUT INT32 * Node
+ );
+
+/** Count the number of nodes in a branch with the input name.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] FdtBranch Only search in the sub-nodes of this branch.
+ Write (-1) to search the whole tree.
+ @param [in] NodeName Node name to search.
+ This is a NULL terminated string.
+ @param [out] NodeCount If success, contains the count of nodes
+ fulfilling the condition.
+ Can be 0.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FdtCountNamedNodeInBranch (
+ IN CONST VOID * Fdt,
+ IN INT32 FdtBranch,
+ IN CONST CHAR8 * NodeName,
+ OUT UINT32 * NodeCount
+ );
+
+/** Count the number of nodes in a branch with at least
+ one compatible property.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] FdtBranch Only search in the sub-nodes of this branch.
+ Write (-1) to search the whole tree.
+ @param [in] CompatibleTable Table of compatible strings to
+ compare with the compatible property
+ of the node.
+ @param [out] NodeCount If success, contains the count of nodes
+ fulfilling the condition.
+ Can be 0.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FdtCountCompatNodeInBranch (
+ IN CONST VOID * Fdt,
+ IN INT32 FdtBranch,
+ IN CONST COMPATIBILITY_INFO * CompatNamesInfo,
+ OUT UINT32 * NodeCount
+ );
+
+/** Count the number of nodes in a branch having the PropName property.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] FdtBranch Only search in the sub-nodes of this branch.
+ Write (-1) to search the whole tree.
+ @param [in] PropName Name of the property to search.
+ This is a NULL terminated string.
+ @param [out] NodeCount If success, contains the count of nodes
+ fulfilling the condition.
+ Can be 0.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FdtCountPropNodeInBranch (
+ IN CONST VOID * Fdt,
+ IN INT32 FdtBranch,
+ IN CONST CHAR8 * PropName,
+ OUT UINT32 * NodeCount
+ );
+
+/** Get the interrupt-controller node handling the interrupts of
+ the input node.
+
+ To do this, recursively search a node with either the "interrupt-controller"
+ or the "interrupt-parent" property in the parents of Node.
+
+ Devicetree Specification, Release v0.3,
+ 2.4.1 "Properties for Interrupt Generating Devices":
+ Because the hierarchy of the nodes in the interrupt tree
+ might not match the devicetree, the interrupt-parent
+ property is available to make the definition of an
+ interrupt parent explicit. The value is the phandle to the
+ interrupt parent. If this property is missing from a
+ device, its interrupt parent is assumed to be its devicetree
+ parent.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] Node Offset of the node to start the search.
+ @param [out] IntcNode If success, contains the offset of the
+ interrupt-controller node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_NOT_FOUND No interrupt-controller node found.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetIntcParentNode (
+ IN CONST VOID * Fdt,
+ IN INT32 Node,
+ OUT INT32 * IntcNode
+ );
+
+/** Get the "interrupt-cells" property value of the node.
+
+ The "interrupts" property requires to know the number of cells used
+ to encode an interrupt. This information is stored in the
+ interrupt-controller of the input Node.
+
+ @param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
+ @param [in] IntcNode Offset of an interrupt-controller node.
+ @param [out] IntCells If success, contains the "interrupt-cells"
+ property of the IntcNode.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_UNSUPPORTED Unsupported.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetInterruptCellsInfo (
+ IN CONST VOID * Fdt,
+ IN INT32 IntcNode,
+ OUT INT32 * InterruptCells
+ );
+
+/** Get the "#address-cells" and/or "#size-cells" property of the node.
+
+ According to the Device Tree specification, s2.3.5 "#address-cells and
+ #size-cells":
+ "If missing, a client program should assume a default value of 2 for
+ #address-cells, and a value of 1 for #size-cells."
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] Node Offset of the node having to get the
+ "#address-cells" and "#size-cells"
+ properties from.
+ @param [out] AddressCells If success, number of address-cells.
+ If the property is not available,
+ default value is 2.
+ @param [out] SizeCells If success, number of size-cells.
+ If the property is not available,
+ default value is 1.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetAddressInfo (
+ IN CONST VOID * Fdt,
+ IN INT32 Node,
+ OUT INT32 * AddressCells, OPTIONAL
+ OUT INT32 * SizeCells OPTIONAL
+ );
+
+/** Get the "#address-cells" and/or "#size-cells" property of the parent node.
+
+ According to the Device Tree specification, s2.3.5 "#address-cells and
+ #size-cells":
+ "If missing, a client program should assume a default value of 2 for
+ #address-cells, and a value of 1 for #size-cells."
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] Node Offset of the node having to get the
+ "#address-cells" and "#size-cells"
+ properties from its parent.
+ @param [out] AddressCells If success, number of address-cells.
+ If the property is not available,
+ default value is 2.
+ @param [out] SizeCells If success, number of size-cells.
+ If the property is not available,
+ default value is 1.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetParentAddressInfo (
+ IN CONST VOID * Fdt,
+ IN INT32 Node,
+ OUT INT32 * AddressCells, OPTIONAL
+ OUT INT32 * SizeCells OPTIONAL
+ );
+
+#endif // FDT_UTILITY_H_


Re: [PATCH v1 02/14] DynamicTablesPkg: FdtHwInfoParser: CM Object descriptor helper

Sami Mujawar
 

Hi Pierre,

Thank you for this patch.

Please find my feedback inline marked [SAMI].

Regards,

Sami Mujawar

On 23/06/2021 01:38 PM, Pierre.Gondois@... wrote:
From: Pierre Gondois <Pierre.Gondois@...>

FdtHwInfoParserLib is an instance of the HwInfoParser. The
FdtHwInfoParser parses a platform Device Tree and populates
the Platform Information repository with Configuration
Manager objects that describe the platform hardware.
These Configuration Manager objects are encapsulated in
Configuration Manager Object Descriptors.

Therefore, add helper functions to create and free the
Configuration Manager Object descriptors.

Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
Signed-off-by: Sami Mujawar <sami.mujawar@...>
---
 .../FdtHwInfoParserLib/CmObjectDescUtility.c  | 305 ++++++++++++++++++
 .../FdtHwInfoParserLib/CmObjectDescUtility.h  | 131 ++++++++
 2 files changed, 436 insertions(+)
 create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.c
 create mode 100644 DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.h

diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.c
new file mode 100644
index 000000000000..e471217504fe
--- /dev/null
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.c
@@ -0,0 +1,305 @@
+/** @file
+  Configuration manager Object Descriptor Utility.
+
+  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <FdtHwInfoParserInclude.h>
+#include <ConfigurationManagerObject.h>
+
+#include "CmObjectDescUtility.h"
+
+/** Create a CM_OBJ_DESCRIPTOR.
+
+  @param [in]  ObjectId       CM_OBJECT_ID of the node.
+  @param [in]  Count          Number of CmObj stored in the
+                              data field.
+  @param [in]  Data           Pointer to one or more CmObj objects.
+                              The content of this Data buffer is copied.
+  @param [in]  Size           Size of the Data buffer.
+  @param [out] NewCmObjDesc   The created CM_OBJ_DESCRIPTOR.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+  @retval EFI_OUT_OF_RESOURCES    An allocation has failed.
+**/
+EFI_STATUS
+EFIAPI
+CreateCmObjDesc (
+  IN  CM_OBJECT_ID          ObjectId,
+  IN  UINT32                Count,
+  IN  VOID                * Data,
+  IN  UINT32                Size,
+  OUT CM_OBJ_DESCRIPTOR  ** NewCmObjDesc
+  )
+{
+  CM_OBJ_DESCRIPTOR   * CmObjDesc;
+  VOID                * DataBuffer;
+
+  if ((Count == 0)      ||
+      (Data == NULL)    ||
+      (Size == 0)       ||
+      (NewCmObjDesc == NULL)) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  CmObjDesc = AllocateZeroPool (sizeof (CM_OBJ_DESCRIPTOR));
+  if (CmObjDesc == NULL) {
+    ASSERT (0);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  DataBuffer = AllocateCopyPool (Size, Data);
+  if (DataBuffer == NULL) {
+    ASSERT (0);
+    return EFI_OUT_OF_RESOURCES;
[SAMI] CmObjDescmust be freed here otherwise there would be a memory leak.
+  }
+
+  CmObjDesc->ObjectId = ObjectId;
+  CmObjDesc->Count = Count;
+  CmObjDesc->Data = DataBuffer;
+  CmObjDesc->Size = Size;
+
+  *NewCmObjDesc = CmObjDesc;
+
+  return EFI_SUCCESS;
+}
+
+/** Free resources allocated for the CM_OBJ_DESCRIPTOR.
+
+  @param [in] CmObjDesc           Pointer to the CM_OBJ_DESCRIPTOR.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FreeCmObjDesc (
+  IN CM_OBJ_DESCRIPTOR  * CmObjDesc
+  )
+{
+  if (CmObjDesc == NULL) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (CmObjDesc->Data != NULL) {
+    FreePool (CmObjDesc->Data);
+  }
+
+  FreePool (CmObjDesc);
+  return EFI_SUCCESS;
+}
+
+/** Add a single CmObj to the Configuration Manager.
+
+  @param  [in]  FdtParserHandle   A handle to the parser instance.
+  @param  [in]  ObjectId          CmObj ObjectId.
+  @param  [in]  Data              CmObj Data.
+  @param  [in]  Size              CmObj Size.
+  @param  [out] Token             If provided and success,
+                                  token generated for this CmObj.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AddSingleCmObj (
+  IN  CONST FDT_HW_INFO_PARSER_HANDLE   FdtParserHandle,
+  IN        CM_OBJECT_ID                ObjectId,
+  IN        VOID                        *Data,
+  IN        UINT32                      Size,
+  OUT       CM_OBJECT_TOKEN             *Token    OPTIONAL
+  )
+{
+  EFI_STATUS          Status;
+  CM_OBJ_DESCRIPTOR   CmObjDesc;
+
+  if ((FdtParserHandle == NULL)             ||
+      (FdtParserHandle->HwInfoAdd == NULL)  ||
+      (Data == NULL)                        ||
+      (Size == 0)) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  CmObjDesc.ObjectId = ObjectId;
+  CmObjDesc.Count = 1;
+  CmObjDesc.Data = Data;
+  CmObjDesc.Size = Size;
+
+  // Add the CmObj.
+  // Don't ask for a token.
+  Status = FdtParserHandle->HwInfoAdd (
+                              FdtParserHandle,
+                              FdtParserHandle->Context,
+                              &CmObjDesc,
+                              Token
+                              );
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
+  }
[SAMI] I think ASSERT_EFI_ERROR() can be used here.
+  return Status;
+}
+
+/** Add multiple CmObj to the Configuration Manager.
+
+  @param  [in]  FdtParserHandle   A handle to the parser instance.
+  @param  [in]  CmObjDesc         CmObjDesc containing multiple CmObj
+                                  to add.
+  @param  [in]  TokenCount        If provided, count of entries in the
+                                  TokenTable.
+  @param  [out] TokenTable        If provided and success,
+                                  token generated for these CmObj.
+                                  Address of an array of CM_OBJECT_TOKEN
+                                  with the same number of elements as the
+                                  CmObjDesc.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AddMultipleCmObj (
+  IN  CONST FDT_HW_INFO_PARSER_HANDLE   FdtParserHandle,
+  IN  CONST CM_OBJ_DESCRIPTOR           *CmObjDesc,
+  IN        UINT32                      TokenCount,   OPTIONAL
+  OUT       CM_OBJECT_TOKEN             *TokenTable   OPTIONAL
+  )
+{
+  EFI_STATUS          Status;
+  UINT32              Index;
+  UINT32              Count;
+  VOID              * Data;
+  UINT32              Size;
+  CM_OBJ_DESCRIPTOR   SingleCmObjDesc;
+
+  if ((FdtParserHandle == NULL)             ||
+      (FdtParserHandle->HwInfoAdd == NULL)  ||
+      (CmObjDesc == NULL)                   ||
+      (CmObjDesc->Count == 0)               ||
+      (CmObjDesc->Data == NULL)             ||
+      (CmObjDesc->Size == 0)){
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Count = CmObjDesc->Count;
+  Data = CmObjDesc->Data;
+  Size = CmObjDesc->Size / Count;
+
+  SingleCmObjDesc.ObjectId = CmObjDesc->ObjectId;
+  SingleCmObjDesc.Count = 1;
+  SingleCmObjDesc.Size = Size;
+
+  for (Index = 0; Index < Count; Index++) {
+    SingleCmObjDesc.Data = Data + Index * Size;
[SAMI] Data needs to be typecasted to UINT8 for the pointer arithmetic to work. Also, enclose Index * Size in parenthesis.
+    // Add the CmObj.
+    Status = FdtParserHandle->HwInfoAdd (
+                                FdtParserHandle,
+                                FdtParserHandle->Context,
+                                &SingleCmObjDesc,
+                                (TokenTable != NULL) ?
+                                  &TokenTable[Index] :
+                                  NULL
+                                );
+    if (EFI_ERROR (Status)) {
+      ASSERT (0);
+      return Status;
+    }
+  } // for
+
+  return Status;
+}
+
+/** Add multiple CmObj to the Configuration Manager.
+
+  Get one token referencing a EArmObjCmRef CmObj itself referencing
+  the input CmObj. In the table below, RefToken is returned.
+
+  Token referencing an      Array of tokens             Array of CmObj
+  array of EArmObjCmRef     referencing each            from the input:
+  CmObj:                    CmObj from the input:
+
+  RefToken         --->     CmObjToken[0]        --->   CmObj[0]
+                            CmObjToken[1]        --->   CmObj[1]
+                            CmObjToken[2]        --->   CmObj[2]
+
+  @param  [in]  FdtParserHandle   A handle to the parser instance.
+  @param  [in]  CmObjDesc         CmObjDesc containing multiple CmObj
+                                  to add.
+  @param  [out] Token             If success, token referencing an array
+                                  of EArmObjCmRef CmObj, themselves
+                                  referencing the input CmObjs.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+  @retval EFI_OUT_OF_RESOURCES    An allocation has failed.
+**/
+EFI_STATUS
+EFIAPI
+AddMultipleCmObjWithCmObjRef (
+  IN  CONST FDT_HW_INFO_PARSER_HANDLE     FdtParserHandle,
+  IN  CM_OBJ_DESCRIPTOR                 * CmObjDesc,
+  OUT CM_OBJECT_TOKEN                   * Token
+  )
+{
+  EFI_STATUS          Status;
+  CM_OBJ_DESCRIPTOR   CmObjRef;
+  CM_OBJECT_TOKEN    *TokenTable;
+  INT32               TokenTableSize;
+
+  if ((FdtParserHandle == NULL)             ||
+      (FdtParserHandle->HwInfoAdd == NULL)  ||
+      (CmObjDesc == NULL)                   ||
+      (CmObjDesc->Count == 0)               ||
+      (CmObjDesc->Data == NULL)             ||
+      (CmObjDesc->Size == 0)                ||
+      (Token == NULL)) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Allocate a buffer to store the tokens.
+  TokenTableSize = CmObjDesc->Count * sizeof (CM_OBJECT_TOKEN);
+  TokenTable = AllocateZeroPool (TokenTableSize);
+  if (TokenTable == NULL) {
+    ASSERT (0);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  // Add the input CmObjs.
+  Status = AddMultipleCmObj (
+             FdtParserHandle,
+             CmObjDesc,
+             CmObjDesc->Count,
+             TokenTable
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
+    goto exit_handler;
+  }
+
+  CmObjRef.ObjectId = CREATE_CM_ARM_OBJECT_ID (EArmObjCmRef);
+  CmObjRef.Data = TokenTable;
+  CmObjRef.Count = CmObjDesc->Count;
+  CmObjRef.Size = TokenTableSize;
+
+  // Add the array of EArmObjCmRef CmObjs.
+  Status = FdtParserHandle->HwInfoAdd (
+                              FdtParserHandle,
+                              FdtParserHandle->Context,
+                              &CmObjRef,
+                              Token
+                              );
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
+  }
[SAMI] I think ASSERT_EFI_ERROR() can be used here.
+
+exit_handler:
+  FreePool (TokenTable);
+  return Status;
+}
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.h
new file mode 100644
index 000000000000..34439c716fb3
--- /dev/null
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.h
@@ -0,0 +1,131 @@
+/** @file
+  Configuration manager Object Descriptor Utility.
+
+  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef CM_OBJECT_DESC_UTILITY_H_
+#define CM_OBJECT_DESC_UTILITY_H_
+
+#include <ConfigurationManagerObject.h>
+
+#include "FdtHwInfoParser.h"
+
+/** Create a CM_OBJ_DESCRIPTOR.
+
+  @param [in]  ObjectId       CM_OBJECT_ID of the node.
+  @param [in]  Count          Number of CmObj stored in the
+                              data field.
+  @param [in]  Data           Pointer to one or more CmObj objects.
+                              The content of this Data buffer is copied.
+  @param [in]  Size           Size of the Data buffer.
+  @param [out] NewCmObjDesc   The created CM_OBJ_DESCRIPTOR.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+  @retval EFI_OUT_OF_RESOURCES    An allocation has failed.
+**/
+EFI_STATUS
+EFIAPI
+CreateCmObjDesc (
+  IN  CM_OBJECT_ID          ObjectId,
+  IN  UINT32                Count,
+  IN  VOID                * Data,
+  IN  UINT32                Size,
+  OUT CM_OBJ_DESCRIPTOR  ** NewCmObjDesc
+  );
+
+/** Free resources allocated for the CM_OBJ_DESCRIPTOR.
+
+  @param [in] CmObjDesc           Pointer to the CM_OBJ_DESCRIPTOR.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FreeCmObjDesc (
+  IN CM_OBJ_DESCRIPTOR  * CmObjDesc
+  );
+
+/** Add a single CmObj to the Configuration Manager.
+
+  @param  [in]  FdtParserHandle   A handle to the parser instance.
+  @param  [in]  ObjectId          CmObj ObjectId.
+  @param  [in]  Data              CmObj Data.
+  @param  [in]  Size              CmObj Size.
+  @param  [out] Token             If provided and success,
+                                  token generated for this CmObj.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AddSingleCmObj (
+  IN  CONST FDT_HW_INFO_PARSER_HANDLE   FdtParserHandle,
+  IN        CM_OBJECT_ID                ObjectId,
+  IN        VOID                        *Data,
+  IN        UINT32                      Size,
+  OUT       CM_OBJECT_TOKEN             *Token    OPTIONAL
+  );
+
+/** Add multiple CmObj to the Configuration Manager.
+
+  @param  [in]  FdtParserHandle   A handle to the parser instance.
+  @param  [in]  CmObjDesc         CmObjDesc containing multiple CmObj
+                                  to add.
+  @param  [in]  TokenCount        If provided, count of entries in the
+                                  TokenTable.
+  @param  [out] TokenTable        If provided and success,
+                                  token generated for these CmObj.
+                                  Address of an array of CM_OBJECT_TOKEN
+                                  with the same number of elements as the
+                                  CmObjDesc.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AddMultipleCmObj (
+  IN  CONST FDT_HW_INFO_PARSER_HANDLE   FdtParserHandle,
+  IN  CONST CM_OBJ_DESCRIPTOR           *CmObjDesc,
+  IN        UINT32                      TokenCount,   OPTIONAL
+  OUT       CM_OBJECT_TOKEN             *TokenTable   OPTIONAL
+  );
+
+/** Add multiple CmObj to the Configuration Manager.
+
+  Get one token referencing a EArmObjCmRef CmObj itself referencing
+  the input CmObj. In the table below, RefToken is returned.
+
+  Token referencing an      Array of tokens             Array of CmObj
+  array of EArmObjCmRef     referencing each            from the input:
+  CmObj:                    CmObj from the input:
+
+  RefToken         --->     CmObjToken[0]        --->   CmObj[0]
+                            CmObjToken[1]        --->   CmObj[1]
+                            CmObjToken[2]        --->   CmObj[2]
+
+  @param  [in]  FdtParserHandle   A handle to the parser instance.
+  @param  [in]  CmObjDesc         CmObjDesc containing multiple CmObj
+                                  to add.
+  @param  [out] Token             If success, token referencing an array
+                                  of EArmObjCmRef CmObj, themselves
+                                  referencing the input CmObjs.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+  @retval EFI_OUT_OF_RESOURCES    An allocation has failed.
+**/
+EFI_STATUS
+EFIAPI
+AddMultipleCmObjWithCmObjRef (
+  IN  CONST FDT_HW_INFO_PARSER_HANDLE     FdtParserHandle,
+  IN  CM_OBJ_DESCRIPTOR                 * CmObjDesc,
+  OUT CM_OBJECT_TOKEN                   * Token
+  );
+
+#endif // CM_OBJECT_DESC_UTILITY_H_


Re: [PATCH v4 4/7] Platform/ARM/N1Sdp: Enable N1Sdp platform specific configurations

Khasim Mohammed
 

Hi Sami,

On Fri, Nov 5, 2021 at 06:54 AM, Khasim Mohammed wrote:
Hi Sami,

On Fri, Nov 5, 2021 at 06:05 AM, Sami Mujawar wrote:
Hi Khasim,

Please find my response inline marked [SAMI].

Regards,

Sami Mujawar

On 26/10/2021 06:39 PM, Khasim Mohammed via groups.io wrote:
This patch adds PCDs and updates the fdf file for N1Sdp
platform specific configurations.

Signed-off-by: Deepak Pandey <Deepak.Pandey@...>
Signed-off-by: Khasim Syed Mohammed <khasim.mohammed@...>
---
Platform/ARM/N1Sdp/N1SdpPlatform.dec | 98 ++++++++++++++++++++++++++++
Platform/ARM/N1Sdp/N1SdpPlatform.dsc | 37 ++++++++++-
Platform/ARM/N1Sdp/N1SdpPlatform.fdf | 13 +++-
3 files changed, 144 insertions(+), 4 deletions(-)
create mode 100644 Platform/ARM/N1Sdp/N1SdpPlatform.dec

diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.dec b/Platform/ARM/N1Sdp/N1SdpPlatform.dec
new file mode 100644
index 0000000000..d56891b985
--- /dev/null
+++ b/Platform/ARM/N1Sdp/N1SdpPlatform.dec
@@ -0,0 +1,98 @@
+## @file
+# Describes the N1Sdp configuration.
+#
+# Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x0001001A
+ PACKAGE_NAME = N1SdpPlatform
+ PACKAGE_GUID = 29aacb23-61e8-4fe2-8a06-793537cd26e9
+ PACKAGE_VERSION = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+# Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+
+[LibraryClasses]
+ ArmPlatformLib|Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLib.inf
+
+[Guids.common]
+ gArmN1SdpTokenSpaceGuid = { 0xd8f1624a, 0x98c1, 0x4f64, { 0xa6, 0x41, 0x19, 0x5e, 0xb5, 0x3b, 0x26, 0x0f } }
+
+[PcdsFixedAtBuild]
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskBase|0x88000000|UINT32|0x00000001
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSize|0x18000000|UINT32|0x00000002
+
+ # PCIe
+ gArmN1SdpTokenSpaceGuid.PcdPcieExpressBaseAddress|0x70000000|UINT32|0x00000007
+
+ # External memory
+ gArmNeoverseN1SocTokenSpaceGuid.PcdExtMemorySpace|0|UINT64|0x00000029
+
+[PcdsFeatureFlag.common]
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSupported|FALSE|BOOLEAN|0x00000003
+
+[PcdsFixedAtBuild.common]
+ # CoreSight Debug and Trace components
+ # CoreSight ETMs
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm0Base|0x402040000|UINT64|0x0000002D
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm0MaxBase|0x402040FFF|UINT64|0x0000002E
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm1Base|0x402140000|UINT64|0x0000002F
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm1MaxBase|0x402140FFF|UINT64|0x00000030
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm2Base|0x403040000|UINT64|0x00000031
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm2MaxBase|0x403040FFF|UINT64|0x00000032
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm3Base|0x403140000|UINT64|0x00000033
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm3MaxBase|0x403140FFF|UINT64|0x00000034
+
+ # CoreSight TMC (ETRs/ETFs/ETBs)
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf0Base|0x400410000|UINT64|0x00000035
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf0MaxBase|0x400410FFF|UINT64|0x00000036
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf1Base|0x400420000|UINT64|0x00000037
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf1MaxBase|0x400420FFF|UINT64|0x00000038
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf2Base|0x400010000|UINT64|0x00000039
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf2MaxBase|0x400010FFF|UINT64|0x0000003A
+ gArmN1SdpTokenSpaceGuid.PcdCsEtrBase|0x400120000|UINT64|0x00000043
+ gArmN1SdpTokenSpaceGuid.PcdCsEtrMaxBase|0x400120FFF|UINT64|0x00000044
+
+ # CoreSight Dynamic Funnel(s)
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel0Base|0x4000B0000|UINT64|0x0000003B
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel0MaxBase|0x4000B0FFF|UINT64|0x0000003C
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel1Base|0x4000A0000|UINT64|0x0000003D
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel1MaxBase|0x4000A0FFF|UINT64|0x0000003E
+
+ # CoreSight Dynamic Replicator(s)
+ gArmN1SdpTokenSpaceGuid.PcdCsReplicatorBase|0x400110000|UINT64|0x0000003F
+ gArmN1SdpTokenSpaceGuid.PcdCsReplicatorMaxBase|0x400110FFF|UINT64|0x00000040
+
+ # CoreSight TPIU
+ gArmN1SdpTokenSpaceGuid.PcdCsTpiuBase|0x400130000|UINT64|0x00000041
+ gArmN1SdpTokenSpaceGuid.PcdCsTpiuMaxBase|0x400130FFF|UINT64|0x00000042
+
+ # CoreSight STM and STM Stimulus
+ gArmN1SdpTokenSpaceGuid.PcdCsStmBase|0x400800000|UINT64|0x00000045
+ gArmN1SdpTokenSpaceGuid.PcdCsStmMaxBase|0x400800FFF|UINT64|0x00000046
+ gArmN1SdpTokenSpaceGuid.PcdCsStmStimulusBase|0x4D000000|UINT32|0x00000047
+ gArmN1SdpTokenSpaceGuid.PcdCsStmStimulusSize|0x1000000|UINT32|0x00000048
+
+ # CoreSight Components' Size
+ #
+ # Newton TRMs specify the size for these coresight components as 64K.
+ # The actual size is just 4K though 64K is reserved. Access to the
+ # unmapped reserved region results in a DECERR response.
+ #
+ gArmN1SdpTokenSpaceGuid.PcdCsComponentSize|0x1000|UINT32|0x00000049
+
+ # Remote Chip PCIe
+ gArmN1SdpTokenSpaceGuid.PcdRemotePcieIoTranslation|0x40075200000|UINT64|0x0000004A
+ gArmN1SdpTokenSpaceGuid.PcdRemotePcieMmio32Translation|0x40000000000|UINT64|0x0000004B
+ gArmN1SdpTokenSpaceGuid.PcdRemotePcieMmio64Translation|0x40000000000|UINT64|0x0000004C
diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.dsc b/Platform/ARM/N1Sdp/N1SdpPlatform.dsc
index 61e7a909f8..0bc3fa6dfe 100644
--- a/Platform/ARM/N1Sdp/N1SdpPlatform.dsc
+++ b/Platform/ARM/N1Sdp/N1SdpPlatform.dsc
@@ -1,8 +1,18 @@
+## @file
+# Component Description File for N1Sdp
#
-# Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
+# This provides platform specific component descriptions and libraries that
+# conform to EFI/Framework standards.
#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
+# Copyright (c) 2018 - 2021, ARM Limited. All rights reserved.<BR>
#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+# IMPLIED.
+#
[SAMI] Is the above disclaimer required? Is the
"SPDX-License-Identifier: BSD-2-Clause-Patent" not sufficient? I think I
noticed something similar in another patch.
Can you check, please?
[/SAMI]
Initially in v1 and v2 patches I was not having this disclaimer, but in latest I had to include this disclaimer without this the CI tests were failing which Pierre had setup for edk2-platforms.

I confirm we will need this disclaimer.
I rerun the CI tests by just keeping the "SPDX-License-Identifier: BSD-2-Clause-Patent", this is sufficient.

I have removed this from the header and have posted v5 version of patches, no other changes as such to other patches.

Thanks for the review and pointing this out.

Regards,
Khasim

Regards,
Khasim
+##

################################################################################
#
@@ -33,6 +43,9 @@
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf

+ # file explorer library support
+ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+
[LibraryClasses.common.SEC]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
@@ -71,6 +84,9 @@
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+!if $(TARGET) != RELEASE
+ DebugLib|MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
+!endif

[LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -82,11 +98,16 @@
################################################################################

[PcdsFeatureFlag.common]
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSupported|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE

[PcdsFixedAtBuild.common]
gArmTokenSpaceGuid.PcdVFPEnabled|1

+ # RAM Disk
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskBase|0x88000000
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSize|0x18000000
+
# Stacks for MPCores in Normal World
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x80000000
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x40000
@@ -99,6 +120,9 @@
# Secondary DDR memory
gArmNeoverseN1SocTokenSpaceGuid.PcdDramBlock2Base|0x8080000000

+ # External memory
+ gArmNeoverseN1SocTokenSpaceGuid.PcdExtMemorySpace|0x40000000000
+
# GIC Base Addresses
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C000000
gArmTokenSpaceGuid.PcdGicDistributorBase|0x30000000
@@ -198,6 +222,9 @@
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
}

+ # Platform driver
+ Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.inf
+
# Human Interface Support
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf

@@ -236,6 +263,9 @@
# SATA Controller
MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf

+ # NVMe boot devices
+ MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
# Usb Support
MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
@@ -244,3 +274,6 @@
MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf
+
+ # RAM Disk
+ MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.fdf b/Platform/ARM/N1Sdp/N1SdpPlatform.fdf
index c4e1f7b4b8..6b097438ad 100644
--- a/Platform/ARM/N1Sdp/N1SdpPlatform.fdf
+++ b/Platform/ARM/N1Sdp/N1SdpPlatform.fdf
@@ -1,8 +1,10 @@
+## @file
+# FDF file of N1Sdp
#
-# Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
+# Copyright (c) 2018 - 2021, ARM Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
+##

################################################################################
#
@@ -109,6 +111,9 @@ READ_LOCK_STATUS = TRUE
# SATA Controller
INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf

+ # NVMe boot devices
+ INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
# Usb Support
INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
@@ -137,10 +142,14 @@ READ_LOCK_STATUS = TRUE

# FV FileSystem
INF MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf
+ INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf

# UEFI applications
INF ShellPkg/Application/Shell/Shell.inf

+ # Platform driver
+ INF Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.inf
+
# Bds
INF MdeModulePkg/Application/UiApp/UiApp.inf
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf


[PATCH v5 6/7] Platform/ARM/N1Sdp: Configuration Manager for N1Sdp

Khasim Mohammed
 

The dynamic tables framework utilizes the configuration manager
protocol to get the platform specific information required for
building the firmware tables.

The configuration manager is a platform specific component that
collates the platform hardware information and builds an abstract
platform configuration repository. The configuration manager also
implements the configuration manager protocol which returns the
hardware information requested by the table generators.

This patch implements the configuration manager for N1SDP
platform. It enables support for generating the following
ACPI tables:
1. FACP
2. DSDT
3. GTDT
4. APIC
5. SPCR
6. DBG2
7. PPTT
8. IORT
9. MCFG
10. SSDT - PCI
11. SSDT - REMOTE PCI

Also added :
HMAT table and expose CCIX memory as EFI_MEMORY_SP

Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Signed-off-by: Khasim Syed Mohammed <khasim.mohammed@arm.com>
Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
Signed-off-by: Manoj Kumar <manoj.kumar3@arm.com>
Signed-off-by: Patrik Berglund <patrik.berglund@arm.com>
Signed-off-by: anukou01 <anurag.koul@arm.com>
Signed-off-by: Sayanta Pattanayak <sayanta.pattanayak@arm.com>
---
.../ConfigurationManager.c | 2199 +++++++++++++++++
.../ConfigurationManager.h | 307 +++
.../ConfigurationManagerDxe.inf | 166 ++
.../ConfigurationManagerDxe/Hmat.c | 103 +
.../ConfigurationManagerDxe/Platform.h | 92 +
5 files changed, 2867 insertions(+)
create mode 100644 Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.c
create mode 100644 Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.h
create mode 100644 Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf
create mode 100644 Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/Hmat.c
create mode 100644 Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/Platform.h

diff --git a/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.c b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.c
new file mode 100644
index 0000000000..374be28653
--- /dev/null
+++ b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.c
@@ -0,0 +1,2199 @@
+/** @file
+ Configuration Manager Dxe
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#include <IndustryStandard/DebugPort2Table.h>
+#include <IndustryStandard/IoRemappingTable.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
+#include <Library/ArmLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <NeoverseN1Soc.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+#include "ConfigurationManager.h"
+#include "N1SdpAcpiHeader.h"
+#include "Platform.h"
+
+extern struct EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE Hmat;
+
+/** The platform configuration repository information.
+*/
+STATIC
+EDKII_PLATFORM_REPOSITORY_INFO N1sdpRepositoryInfo = {
+ // Configuration Manager information
+ { CONFIGURATION_MANAGER_REVISION, CFG_MGR_OEM_ID },
+
+ // ACPI Table List
+ {
+ // FADT Table
+ {
+ EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+ EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt),
+ NULL
+ },
+ // GTDT Table
+ {
+ EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
+ EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION,
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdGtdt),
+ NULL
+ },
+ // MADT Table
+ {
+ EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
+ EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMadt),
+ NULL
+ },
+ // SPCR Table
+ {
+ EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
+ EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION,
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSpcr),
+ NULL
+ },
+ // DSDT Table
+ {
+ EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+ 0, // Unused
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDsdt),
+ (EFI_ACPI_DESCRIPTION_HEADER*)dsdt_aml_code
+ },
+ // DBG2 Table
+ {
+ EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE,
+ EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDbg2),
+ NULL
+ },
+ // PPTT Table
+ {
+ EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
+ EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION,
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdPptt),
+ NULL
+ },
+ // IORT Table
+ {
+ EFI_ACPI_6_3_IO_REMAPPING_TABLE_SIGNATURE,
+ EFI_ACPI_IO_REMAPPING_TABLE_REVISION,
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdIort),
+ NULL
+ },
+ // PCI MCFG Table
+ {
+ EFI_ACPI_6_3_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
+ EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION,
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMcfg),
+ NULL,
+ SIGNATURE_64 ('A','R','M','N','1','S','D','P'),
+ 0x20181101
+ },
+ // SSDT table describing the PCI root complex
+ {
+ EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+ 0, // Unused
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdt),
+ (EFI_ACPI_DESCRIPTION_HEADER*)ssdtpci_aml_code
+ },
+ // SRAT Table
+ {
+ EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE,
+ EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION,
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSrat),
+ NULL
+ },
+ // HMAT Table
+ {
+ EFI_ACPI_6_3_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE,
+ EFI_ACPI_6_3_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_REVISION,
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdRaw),
+ (EFI_ACPI_DESCRIPTION_HEADER*)&Hmat
+ },
+ // SSDT table describing the Remote Chip PCI root complex
+ {
+ EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+ 0, // Unused
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdt),
+ (EFI_ACPI_DESCRIPTION_HEADER*)ssdtremotepci_aml_code
+ },
+ },
+
+ // Boot architecture information
+ { EFI_ACPI_6_3_ARM_PSCI_COMPLIANT }, // BootArchFlags
+
+ // Fixed feature flag information
+ { EFI_ACPI_6_3_HEADLESS }, // Fixed feature flags
+
+ // Power management profile information
+ { EFI_ACPI_6_3_PM_PROFILE_ENTERPRISE_SERVER }, // PowerManagement Profile
+
+ /* GIC CPU Interface information
+ GICC_ENTRY (CPUInterfaceNumber, Mpidr, PmuIrq, VGicIrq, GicRedistBase,
+ EnergyEfficiency, SpeIrq, ProximityDomain, ClockDomain)
+ */
+ {
+ GICC_ENTRY (0, GET_MPID3 (0x0, 0x0, 0x0, 0x0), 23, 25, 0, 0, 21, 0, 0),
+ GICC_ENTRY (1, GET_MPID3 (0x0, 0x0, 0x1, 0x0), 23, 25, 0, 0, 21, 0, 0),
+ GICC_ENTRY (2, GET_MPID3 (0x0, 0x1, 0x0, 0x0), 23, 25, 0, 0, 21, 0, 0),
+ GICC_ENTRY (3, GET_MPID3 (0x0, 0x1, 0x1, 0x0), 23, 25, 0, 0, 21, 0, 0),
+ GICC_ENTRY (4, GET_MPID3 (0x1, 0x0, 0x0, 0x0), 23, 25, 0, 0, 21, 1, 0),
+ GICC_ENTRY (5, GET_MPID3 (0x1, 0x0, 0x1, 0x0), 23, 25, 0, 0, 21, 1, 0),
+ GICC_ENTRY (6, GET_MPID3 (0x1, 0x1, 0x0, 0x0), 23, 25, 0, 0, 21, 1, 0),
+ GICC_ENTRY (7, GET_MPID3 (0x1, 0x1, 0x1, 0x0), 23, 25, 0, 0, 21, 1, 0),
+ },
+
+ // GIC Distributor Info
+ {
+ FixedPcdGet64 (PcdGicDistributorBase), // UINT64 PhysicalBaseAddress
+ 0, // UINT32 SystemVectorBase
+ 3 // UINT8 GicVersion
+ },
+
+ // GIC Re-Distributor Info
+ {
+ {
+ // UINT64 DiscoveryRangeBaseAddress
+ FixedPcdGet64 (PcdGicRedistributorsBase),
+ // UINT32 DiscoveryRangeLength
+ SIZE_1MB
+ },
+ {
+ // UINT64 DiscoveryRangeBaseAddress
+ FixedPcdGet64 (PcdGicRedistributorsBase) + (1ULL << 42),
+ // UINT32 DiscoveryRangeLength
+ SIZE_1MB
+ },
+ },
+
+ // GIC ITS
+ {
+ // GIC ITS - CCIX TCU
+ {
+ // The GIC ITS ID.
+ 0,
+ // The physical address for the Interrupt Translation Service
+ 0x30040000,
+ //Proximity Domain
+ 0
+ },
+ // GIC ITS - PCIe TCU
+ {
+ // The GIC ITS ID.
+ 1,
+ // The physical address for the Interrupt Translation Service
+ 0x30060000,
+ //Proximity Domain
+ 0
+ },
+ // GIC ITS - CCIX RC
+ {
+ // The GIC ITS ID.
+ 2,
+ // The physical address for the Interrupt Translation Service
+ 0x30080000,
+ //Proximity Domain
+ 0
+ },
+ // GIC ITS - PCIe RC
+ {
+ // The GIC ITS ID.
+ 3,
+ // The physical address for the Interrupt Translation Service
+ 0x300A0000,
+ //Proximity Domain
+ 0
+ },
+ //Remote chip GIC ITS - PCIe TCU
+ {
+ Its_remote_smmu_pcie,
+ 0x40030060000,
+ 1
+ },
+ //Remote chip GIC ITS - PCIe RC
+ {
+ Its_remote_pcie,
+ 0x400300a0000,
+ 1
+ },
+ },
+
+ // Generic Timer Info
+ {
+ // The physical base address for the counter control frame
+ N1SDP_SYSTEM_TIMER_BASE_ADDRESS,
+ // The physical base address for the counter read frame
+ N1SDP_CNT_READ_BASE_ADDRESS,
+ // The secure PL1 timer interrupt
+ FixedPcdGet32 (PcdArmArchTimerSecIntrNum),
+ // The secure PL1 timer flags
+ N1SDP_GTDT_GTIMER_FLAGS,
+ // The non-secure PL1 timer interrupt
+ FixedPcdGet32 (PcdArmArchTimerIntrNum),
+ // The non-secure PL1 timer flags
+ N1SDP_GTDT_GTIMER_FLAGS,
+ // The virtual timer interrupt
+ FixedPcdGet32 (PcdArmArchTimerVirtIntrNum),
+ // The virtual timer flags
+ N1SDP_GTDT_GTIMER_FLAGS,
+ // The non-secure PL2 timer interrupt
+ FixedPcdGet32 (PcdArmArchTimerHypIntrNum),
+ // The non-secure PL2 timer flags
+ N1SDP_GTDT_GTIMER_FLAGS
+ },
+
+ // Generic Timer Block Information
+ {
+ {
+ // The physical base address for the GT Block Timer structure
+ N1SDP_GT_BLOCK_CTL_BASE,
+ // The number of timer frames implemented in the GT Block
+ N1SDP_TIMER_FRAMES_COUNT,
+ // Reference token for the GT Block timer frame list
+ REFERENCE_TOKEN (GTBlock0TimerInfo)
+ }
+ },
+
+ // GT Block Timer Frames
+ {
+ // Frame 0
+ {
+ 0, // UINT8 FrameNumber
+ N1SDP_GT_BLOCK_FRAME0_CTL_BASE, // UINT64 PhysicalAddressCntBase
+ N1SDP_GT_BLOCK_FRAME0_CTL_EL0_BASE, // UINT64 PhysicalAddressCntEL0Base
+ N1SDP_GT_BLOCK_FRAME0_GSIV, // UINT32 PhysicalTimerGSIV
+ N1SDP_GTX_TIMER_FLAGS, // UINT32 PhysicalTimerFlags
+ 0, // UINT32 VirtualTimerGSIV
+ 0, // UINT32 VirtualTimerFlags
+ N1SDP_GTX_COMMON_FLAGS_NS // UINT32 CommonFlags
+ },
+ // Frame 1
+ {
+ 1, // UINT8 FrameNumber
+ N1SDP_GT_BLOCK_FRAME1_CTL_BASE, // UINT64 PhysicalAddressCntBase
+ N1SDP_GT_BLOCK_FRAME1_CTL_EL0_BASE, // UINT64 PhysicalAddressCntEL0Base
+ N1SDP_GT_BLOCK_FRAME1_GSIV, // UINT32 PhysicalTimerGSIV
+ N1SDP_GTX_TIMER_FLAGS, // UINT32 PhysicalTimerFlags
+ 0, // UINT32 VirtualTimerGSIV
+ 0, // UINT32 VirtualTimerFlags
+ N1SDP_GTX_COMMON_FLAGS_S // UINT32 CommonFlags
+ },
+ },
+
+ // Watchdog Info
+ {
+ // The physical base address of the SBSA Watchdog control frame
+ FixedPcdGet64 (PcdGenericWatchdogControlBase),
+ // The physical base address of the SBSA Watchdog refresh frame
+ FixedPcdGet64 (PcdGenericWatchdogRefreshBase),
+ // The watchdog interrupt
+ FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum),
+ // The watchdog flags
+ N1SDP_SBSA_WATCHDOG_FLAGS
+ },
+
+ // SPCR Serial Port
+ {
+ FixedPcdGet64 (PcdSerialRegisterBase), // BaseAddress
+ FixedPcdGet32 (PL011UartInterrupt), // Interrupt
+ FixedPcdGet64 (PcdUartDefaultBaudRate), // BaudRate
+ FixedPcdGet32 (PL011UartClkInHz), // Clock
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART // Port subtype
+ },
+
+ // Debug Serial Port
+ {
+ FixedPcdGet64 (PcdSerialDbgRegisterBase), // BaseAddress
+ 0, // Interrupt -unused
+ FixedPcdGet64 (PcdSerialDbgUartBaudRate), // BaudRate
+ FixedPcdGet32 (PcdSerialDbgUartClkInHz), // Clock
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART // Port subtype
+ },
+
+ // Processor Hierarchy Nodes
+ {
+ // Package
+ {
+ // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (ProcHierarchyInfo[0]),
+ // UINT32 Flags
+ PROC_NODE_FLAGS (
+ EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD,
+ EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF,
+ EFI_ACPI_6_3_PPTT_IMPLEMENTATION_IDENTICAL
+ ),
+ // CM_OBJECT_TOKEN ParentToken
+ CM_NULL_TOKEN,
+ // CM_OBJECT_TOKEN GicCToken
+ CM_NULL_TOKEN,
+ // UINT32 NoOfPrivateResources
+ SOC_RESOURCE_COUNT,
+ // CM_OBJECT_TOKEN PrivateResourcesArrayToken
+ REFERENCE_TOKEN (SocResources)
+ },
+ // Cluster0
+ {
+ // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (ProcHierarchyInfo[1]),
+ // UINT32 Flags
+ PROC_NODE_FLAGS (
+ EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD,
+ EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF,
+ EFI_ACPI_6_3_PPTT_IMPLEMENTATION_IDENTICAL
+ ),
+ // CM_OBJECT_TOKEN ParentToken
+ REFERENCE_TOKEN (ProcHierarchyInfo[0]), // -> Package
+ // CM_OBJECT_TOKEN GicCToken
+ CM_NULL_TOKEN,
+ // UINT32 NoOfPrivateResources
+ CLUSTER_RESOURCE_COUNT,
+ // CM_OBJECT_TOKEN PrivateResourcesArrayToken
+ REFERENCE_TOKEN (ClusterResources)
+ },
+ // Cluster1
+ {
+ // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (ProcHierarchyInfo[2]),
+ // UINT32 Flags
+ PROC_NODE_FLAGS (
+ EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD,
+ EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF,
+ EFI_ACPI_6_3_PPTT_IMPLEMENTATION_IDENTICAL
+ ),
+ // CM_OBJECT_TOKEN ParentToken
+ REFERENCE_TOKEN (ProcHierarchyInfo[0]), // -> Package
+ // CM_OBJECT_TOKEN GicCToken
+ CM_NULL_TOKEN,
+ // UINT32 NoOfPrivateResources
+ CLUSTER_RESOURCE_COUNT,
+ // CM_OBJECT_TOKEN PrivateResourcesArrayToken
+ REFERENCE_TOKEN (ClusterResources)
+ },
+ // Cluster0 - Cpu0
+ {
+ // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (ProcHierarchyInfo[3]),
+ // UINT32 Flags
+ PROC_NODE_FLAGS (
+ EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD,
+ EFI_ACPI_6_3_PPTT_NODE_IS_LEAF,
+ EFI_ACPI_6_3_PPTT_IMPLEMENTATION_NOT_IDENTICAL
+ ),
+ // CM_OBJECT_TOKEN ParentToken
+ REFERENCE_TOKEN (ProcHierarchyInfo[1]), // -> 'cluster in Cluster0
+ // CM_OBJECT_TOKEN GicCToken
+ REFERENCE_TOKEN (GicCInfo[0]),
+ // UINT32 NoOfPrivateResources
+ CORE_RESOURCE_COUNT,
+ // CM_OBJECT_TOKEN PrivateResourcesArrayToken
+ REFERENCE_TOKEN (CoreResources)
+ },
+ // Cluster0 - Cpu1
+ {
+ // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (ProcHierarchyInfo[4]),
+ // UINT32 Flags
+ PROC_NODE_FLAGS (
+ EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD,
+ EFI_ACPI_6_3_PPTT_NODE_IS_LEAF,
+ EFI_ACPI_6_3_PPTT_IMPLEMENTATION_NOT_IDENTICAL
+ ),
+ // CM_OBJECT_TOKEN ParentToken
+ REFERENCE_TOKEN (ProcHierarchyInfo[1]), // -> 'cluster in Cluster0
+ // CM_OBJECT_TOKEN GicCToken
+ REFERENCE_TOKEN (GicCInfo[1]),
+ // UINT32 NoOfPrivateResources
+ CORE_RESOURCE_COUNT,
+ // CM_OBJECT_TOKEN PrivateResourcesArrayToken
+ REFERENCE_TOKEN (CoreResources)
+ },
+ // Cluster1 - Cpu0
+ {
+ // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (ProcHierarchyInfo[3]),
+ // UINT32 Flags
+ PROC_NODE_FLAGS (
+ EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD,
+ EFI_ACPI_6_3_PPTT_NODE_IS_LEAF,
+ EFI_ACPI_6_3_PPTT_IMPLEMENTATION_NOT_IDENTICAL
+ ),
+ // CM_OBJECT_TOKEN ParentToken
+ REFERENCE_TOKEN (ProcHierarchyInfo[2]), // -> 'cluster in Cluster1
+ // CM_OBJECT_TOKEN GicCToken
+ REFERENCE_TOKEN (GicCInfo[2]),
+ // UINT32 NoOfPrivateResources
+ CORE_RESOURCE_COUNT,
+ // CM_OBJECT_TOKEN PrivateResourcesArrayToken
+ REFERENCE_TOKEN (CoreResources)
+ },
+ // Cluster1 - Cpu1
+ {
+ // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (ProcHierarchyInfo[4]),
+ // UINT32 Flags
+ PROC_NODE_FLAGS (
+ EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD,
+ EFI_ACPI_6_3_PPTT_NODE_IS_LEAF,
+ EFI_ACPI_6_3_PPTT_IMPLEMENTATION_NOT_IDENTICAL
+ ),
+ // CM_OBJECT_TOKEN ParentToken
+ REFERENCE_TOKEN (ProcHierarchyInfo[2]), // -> 'cluster in Cluster1
+ // CM_OBJECT_TOKEN GicCToken
+ REFERENCE_TOKEN (GicCInfo[3]),
+ // UINT32 NoOfPrivateResources
+ CORE_RESOURCE_COUNT,
+ // CM_OBJECT_TOKEN PrivateResourcesArrayToken
+ REFERENCE_TOKEN (CoreResources)
+ },
+ // Slave chip hierarchy
+ // Package
+ {
+ // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (ProcHierarchyInfo[7]),
+ // UINT32 Flags
+ PROC_NODE_FLAGS (
+ EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD,
+ EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF,
+ EFI_ACPI_6_3_PPTT_IMPLEMENTATION_IDENTICAL
+ ),
+ // CM_OBJECT_TOKEN ParentToken
+ CM_NULL_TOKEN,
+ // CM_OBJECT_TOKEN GicCToken
+ CM_NULL_TOKEN,
+ // UINT32 NoOfPrivateResources
+ SOC_RESOURCE_COUNT,
+ // CM_OBJECT_TOKEN PrivateResourcesArrayToken
+ REFERENCE_TOKEN (SocResources)
+ },
+ // Cluster0
+ {
+ // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (ProcHierarchyInfo[8]),
+ // UINT32 Flags
+ PROC_NODE_FLAGS (
+ EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD,
+ EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF,
+ EFI_ACPI_6_3_PPTT_IMPLEMENTATION_IDENTICAL
+ ),
+ // CM_OBJECT_TOKEN ParentToken
+ REFERENCE_TOKEN (ProcHierarchyInfo[7]), // -> Package
+ // CM_OBJECT_TOKEN GicCToken
+ CM_NULL_TOKEN,
+ // UINT32 NoOfPrivateResources
+ CLUSTER_RESOURCE_COUNT,
+ // CM_OBJECT_TOKEN PrivateResourcesArrayToken
+ REFERENCE_TOKEN (ClusterResources)
+ },
+ // Cluster1
+ {
+ // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (ProcHierarchyInfo[9]),
+ // UINT32 Flags
+ PROC_NODE_FLAGS (
+ EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD,
+ EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF,
+ EFI_ACPI_6_3_PPTT_IMPLEMENTATION_IDENTICAL
+ ),
+ // CM_OBJECT_TOKEN ParentToken
+ REFERENCE_TOKEN (ProcHierarchyInfo[7]), // -> Package
+ // CM_OBJECT_TOKEN GicCToken
+ CM_NULL_TOKEN,
+ // UINT32 NoOfPrivateResources
+ CLUSTER_RESOURCE_COUNT,
+ // CM_OBJECT_TOKEN PrivateResourcesArrayToken
+ REFERENCE_TOKEN (ClusterResources)
+ },
+ // Cluster0 - Cpu0
+ {
+ // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (ProcHierarchyInfo[10]),
+ // UINT32 Flags
+ PROC_NODE_FLAGS (
+ EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD,
+ EFI_ACPI_6_3_PPTT_NODE_IS_LEAF,
+ EFI_ACPI_6_3_PPTT_IMPLEMENTATION_NOT_IDENTICAL
+ ),
+ // CM_OBJECT_TOKEN ParentToken
+ REFERENCE_TOKEN (ProcHierarchyInfo[8]), // -> 'cluster in Cluster0
+ // CM_OBJECT_TOKEN GicCToken
+ REFERENCE_TOKEN (GicCInfo[4]),
+ // UINT32 NoOfPrivateResources
+ CORE_RESOURCE_COUNT,
+ // CM_OBJECT_TOKEN PrivateResourcesArrayToken
+ REFERENCE_TOKEN (CoreResources)
+ },
+ // Cluster0 - Cpu1
+ {
+ // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (ProcHierarchyInfo[11]),
+ // UINT32 Flags
+ PROC_NODE_FLAGS (
+ EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD,
+ EFI_ACPI_6_3_PPTT_NODE_IS_LEAF,
+ EFI_ACPI_6_3_PPTT_IMPLEMENTATION_NOT_IDENTICAL
+ ),
+ // CM_OBJECT_TOKEN ParentToken
+ REFERENCE_TOKEN (ProcHierarchyInfo[8]), // -> 'cluster in Cluster0
+ // CM_OBJECT_TOKEN GicCToken
+ REFERENCE_TOKEN (GicCInfo[5]),
+ // UINT32 NoOfPrivateResources
+ CORE_RESOURCE_COUNT,
+ // CM_OBJECT_TOKEN PrivateResourcesArrayToken
+ REFERENCE_TOKEN (CoreResources)
+ },
+ // Cluster1 - Cpu0
+ {
+ // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (ProcHierarchyInfo[10]),
+ // UINT32 Flags
+ PROC_NODE_FLAGS (
+ EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD,
+ EFI_ACPI_6_3_PPTT_NODE_IS_LEAF,
+ EFI_ACPI_6_3_PPTT_IMPLEMENTATION_NOT_IDENTICAL
+ ),
+ // CM_OBJECT_TOKEN ParentToken
+ REFERENCE_TOKEN (ProcHierarchyInfo[9]), // -> 'cluster in Cluster1
+ // CM_OBJECT_TOKEN GicCToken
+ REFERENCE_TOKEN (GicCInfo[6]),
+ // UINT32 NoOfPrivateResources
+ CORE_RESOURCE_COUNT,
+ // CM_OBJECT_TOKEN PrivateResourcesArrayToken
+ REFERENCE_TOKEN (CoreResources)
+ },
+ // Cluster1 - Cpu1
+ {
+ // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (ProcHierarchyInfo[11]),
+ // UINT32 Flags
+ PROC_NODE_FLAGS (
+ EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID,
+ EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD,
+ EFI_ACPI_6_3_PPTT_NODE_IS_LEAF,
+ EFI_ACPI_6_3_PPTT_IMPLEMENTATION_NOT_IDENTICAL
+ ),
+ // CM_OBJECT_TOKEN ParentToken
+ REFERENCE_TOKEN (ProcHierarchyInfo[9]), // -> 'cluster in Cluster1
+ // CM_OBJECT_TOKEN GicCToken
+ REFERENCE_TOKEN (GicCInfo[7]),
+ // UINT32 NoOfPrivateResources
+ CORE_RESOURCE_COUNT,
+ // CM_OBJECT_TOKEN PrivateResourcesArrayToken
+ REFERENCE_TOKEN (CoreResources)
+ },
+ },
+
+ // Cache information
+ {
+ // 'cluster's L3 cache
+ {
+ REFERENCE_TOKEN (CacheInfo[0]), // CM_OBJECT_TOKEN Token
+ CM_NULL_TOKEN, // CM_OBJECT_TOKEN NextLevelOfCacheToken
+ SIZE_1MB, // UINT32 Size
+ 2048, // UINT32 NumberOfSets
+ 8, // UINT32 Associativity
+ CACHE_ATTRIBUTES ( // UINT8 Attributes
+ EFI_ACPI_6_3_CACHE_ATTRIBUTES_ALLOCATION_READ,
+ EFI_ACPI_6_3_CACHE_ATTRIBUTES_CACHE_TYPE_UNIFIED,
+ EFI_ACPI_6_3_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_BACK
+ ),
+ 64 // UINT16 LineSize
+ },
+ // 'core's L1 instruction cache
+ {
+ REFERENCE_TOKEN (CacheInfo[1]), // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (CacheInfo[3]), // CM_OBJECT_TOKEN NextLevelOfCacheToken
+ SIZE_64KB, // UINT32 Size
+ 256, // UINT32 NumberOfSets
+ 4, // UINT32 Associativity
+ CACHE_ATTRIBUTES ( // UINT8 Attributes
+ EFI_ACPI_6_3_CACHE_ATTRIBUTES_ALLOCATION_READ,
+ EFI_ACPI_6_3_CACHE_ATTRIBUTES_CACHE_TYPE_INSTRUCTION,
+ EFI_ACPI_6_3_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_BACK
+ ),
+ 64 // UINT16 LineSize
+ },
+ // 'core's L1 data cache
+ {
+ REFERENCE_TOKEN (CacheInfo[2]), // CM_OBJECT_TOKEN Token
+ REFERENCE_TOKEN (CacheInfo[3]), // CM_OBJECT_TOKEN NextLevelOfCacheToken
+ SIZE_64KB, // UINT32 Size
+ 256, // UINT32 NumberOfSets
+ 4, // UINT32 Associativity
+ CACHE_ATTRIBUTES ( // UINT8 Attributes
+ EFI_ACPI_6_3_CACHE_ATTRIBUTES_ALLOCATION_READ_WRITE,
+ EFI_ACPI_6_3_CACHE_ATTRIBUTES_CACHE_TYPE_DATA,
+ EFI_ACPI_6_3_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_BACK
+ ),
+ 64 // UINT16 LineSize
+ },
+ // cores's L2 cache
+ {
+ REFERENCE_TOKEN (CacheInfo[3]), // CM_OBJECT_TOKEN Token
+ CM_NULL_TOKEN, // CM_OBJECT_TOKEN NextLevelOfCacheToken
+ SIZE_1MB, // UINT32 Size
+ 2048, // UINT32 NumberOfSets
+ 8, // UINT32 Associativity
+ CACHE_ATTRIBUTES ( // UINT8 Attributes
+ EFI_ACPI_6_3_CACHE_ATTRIBUTES_ALLOCATION_READ,
+ EFI_ACPI_6_3_CACHE_ATTRIBUTES_CACHE_TYPE_UNIFIED,
+ EFI_ACPI_6_3_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_BACK
+ ),
+ 64 // UINT16 LineSize
+ },
+ // slc cache
+ {
+ REFERENCE_TOKEN (CacheInfo[4]), // CM_OBJECT_TOKEN Token
+ CM_NULL_TOKEN, // CM_OBJECT_TOKEN NextLevelOfCacheToken
+ SIZE_8MB, // UINT32 Size
+ 8192, // UINT32 NumberOfSets
+ 16, // UINT32 Associativity
+ CACHE_ATTRIBUTES ( // UINT8 Attributes
+ EFI_ACPI_6_3_CACHE_ATTRIBUTES_ALLOCATION_READ,
+ EFI_ACPI_6_3_CACHE_ATTRIBUTES_CACHE_TYPE_UNIFIED,
+ EFI_ACPI_6_3_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_BACK
+ ),
+ 64 // UINT16 LineSize
+ },
+ },
+
+ // Resources private to the 'cluster (shared among cores) in Cluster
+ {
+ { REFERENCE_TOKEN (CacheInfo[0]) } // -> 'cluster's L3 cache in Cluster
+ },
+
+ // Resources private to each individual 'core instance in Cluster
+ {
+ { REFERENCE_TOKEN (CacheInfo[1]) }, // -> 'core's L1 I-cache in Cluster
+ { REFERENCE_TOKEN (CacheInfo[2]) } // -> 'core's L1 D-cache in Cluster
+ },
+
+ // Resources private to the SoC
+ {
+ { REFERENCE_TOKEN (CacheInfo[4]) }, // -> slc for SoC
+ },
+
+ // ITS group node
+ {
+ {
+ // Reference token for this Iort node
+ REFERENCE_TOKEN (ItsGroupInfo[Its_smmu_ccix]),
+ // The number of ITS identifiers in the ITS node.
+ 1,
+ // Reference token for the ITS identifier array
+ REFERENCE_TOKEN (ItsIdentifierArray[Its_smmu_pcie])
+ },
+ {
+ // Reference token for this Iort node
+ REFERENCE_TOKEN (ItsGroupInfo[Its_smmu_pcie]),
+ // The number of ITS identifiers in the ITS node.
+ 1,
+ // Reference token for the ITS identifier array
+ REFERENCE_TOKEN (ItsIdentifierArray[Its_smmu_pcie])
+ },
+ {
+ // Reference token for this Iort node
+ REFERENCE_TOKEN (ItsGroupInfo[Its_ccix]),
+ // The number of ITS identifiers in the ITS node.
+ 1,
+ // Reference token for the ITS identifier array
+ REFERENCE_TOKEN (ItsIdentifierArray[Its_ccix])
+ },
+ {
+ // Reference token for this Iort node
+ REFERENCE_TOKEN (ItsGroupInfo[Its_pcie]),
+ // The number of ITS identifiers in the ITS node.
+ 1,
+ // Reference token for the ITS identifier array
+ REFERENCE_TOKEN (ItsIdentifierArray[Its_pcie])
+ },
+ //Remote Chip ITS
+ {
+ REFERENCE_TOKEN (ItsGroupInfo[Its_remote_smmu_pcie]),
+ 1,
+ REFERENCE_TOKEN (ItsIdentifierArray[Its_remote_smmu_pcie])
+ },
+ {
+ REFERENCE_TOKEN (ItsGroupInfo[Its_remote_pcie]),
+ 1,
+ REFERENCE_TOKEN (ItsIdentifierArray[Its_remote_pcie])
+ },
+ },
+
+ // ITS identifier array
+ {
+ {
+ // The ITS Identifier - 0
+ Its_smmu_ccix
+ },
+ {
+ // The ITS Identifier - 1
+ Its_smmu_pcie
+ },
+ {
+ // The ITS Identifier - 2
+ Its_ccix
+ },
+ {
+ // The ITS Identifier - 3
+ Its_pcie
+ },
+ {
+ // The ITS Identifier - 4
+ Its_remote_smmu_pcie
+ },
+ {
+ // The ITS Identifier - 5
+ Its_remote_pcie
+ }
+ },
+
+ {
+ // SMMUv3 Node
+ {
+ // Reference token for this Iort node
+ REFERENCE_TOKEN (SmmuV3Info[Smmuv3info_pcie]),
+ // Number of ID mappings
+ 2,
+ // Reference token for the ID mapping array
+ REFERENCE_TOKEN (DeviceIdMapping[Devicemapping_smmu_pcie][0]),
+ // SMMU Base Address
+ 0x4F400000,
+ // SMMU flags
+ EFI_ACPI_IORT_SMMUv3_FLAG_COHAC_OVERRIDE,
+ // VATOS address
+ 0,
+ // Model
+ EFI_ACPI_IORT_SMMUv3_MODEL_GENERIC,
+ // GSIV of the Event interrupt if SPI based
+ 0x10B,
+ // PRI Interrupt if SPI based
+ 0,
+ // GERR interrupt if GSIV based
+ 0x10D,
+ // Sync interrupt if GSIV based
+ 0x10C,
+ // Proximity domain flag, ignored in this case
+ 0,
+ // Index into the array of ID mapping
+ 1
+ },
+ // SMMUv3 Node
+ {
+ // Reference token for this Iort node
+ REFERENCE_TOKEN (SmmuV3Info[Smmuv3info_ccix]),
+ // Number of ID mappings
+ 2,
+ // Reference token for the ID mapping array
+ REFERENCE_TOKEN (DeviceIdMapping[Devicemapping_smmu_ccix][0]),
+ // SMMU Base Address
+ 0x4F000000,
+ // SMMU flags
+ EFI_ACPI_IORT_SMMUv3_FLAG_COHAC_OVERRIDE,
+ // VATOS address
+ 0,
+ // Model
+ EFI_ACPI_IORT_SMMUv3_MODEL_GENERIC,
+ // GSIV of the Event interrupt if SPI based
+ 0x104,
+ // PRI Interrupt if SPI based
+ 0,
+ // GERR interrupt if GSIV based
+ 0x106,
+ // Sync interrupt if GSIV based
+ 0x105,
+ // Proximity domain flag, ignored in this case
+ 0,
+ // Index into the array of ID mapping
+ 1
+ },
+ //Remote Chip SMMU V3 setting
+ {
+ REFERENCE_TOKEN (SmmuV3Info[Smmuv3info_remote_pcie]),
+ 2,
+ REFERENCE_TOKEN (DeviceIdMapping[Devicemapping_remote_smmu_pcie][0]),
+ 0x4004f400000,
+ EFI_ACPI_IORT_SMMUv3_FLAG_COHAC_OVERRIDE,
+ 0,
+ EFI_ACPI_IORT_SMMUv3_MODEL_GENERIC,
+ 747,
+ 0,
+ 749,
+ 748,
+ 0,
+ 1
+ }
+ },
+
+ {
+ // Root Complex node info
+ {
+ // Reference token for this Iort node
+ REFERENCE_TOKEN (RootComplexInfo[0]),
+ // Number of ID mappings
+ 1,
+ // Reference token for the ID mapping array
+ REFERENCE_TOKEN (DeviceIdMapping[Devicemapping_pcie][0]),
+ // Memory access properties : Cache coherent attributes
+ EFI_ACPI_IORT_MEM_ACCESS_PROP_CCA,
+ // Memory access properties : Allocation hints
+ 0,
+ // Memory access properties : Memory access flags
+ 0,
+ // ATS attributes
+ EFI_ACPI_IORT_ROOT_COMPLEX_ATS_SUPPORTED,
+ // PCI segment number
+ 0,
+ // Memory address size limit
+ 42
+ },
+ // Root Complex node info
+ {
+ // Reference token for this Iort node
+ REFERENCE_TOKEN (RootComplexInfo[1]),
+ // Number of ID mappings
+ 1,
+ // Reference token for the ID mapping array
+ REFERENCE_TOKEN (DeviceIdMapping[Devicemapping_pcie][1]),
+ // Memory access properties : Cache coherent attributes
+ EFI_ACPI_IORT_MEM_ACCESS_PROP_CCA,
+ // Memory access properties : Allocation hints
+ 0,
+ // Memory access properties : Memory access flags
+ 0,
+ // ATS attributes
+ EFI_ACPI_IORT_ROOT_COMPLEX_ATS_SUPPORTED,
+ // PCI segment number
+ 1,
+ // Memory address size limit
+ 42
+ },
+ //Remote Chip Root Complex node Info
+ {
+ REFERENCE_TOKEN (RootComplexInfo[Root_remote_pcie]),
+ 1,
+ REFERENCE_TOKEN (DeviceIdMapping[Devicemapping_remote_pcie][0]),
+ EFI_ACPI_IORT_MEM_ACCESS_PROP_CCA,
+ 0,
+ 0,
+ EFI_ACPI_IORT_ROOT_COMPLEX_ATS_SUPPORTED,
+ 2,
+ 42
+ }
+ },
+
+ // Array of Device ID mappings
+ {
+ // DeviceIdMapping[0][0] - [0][1]
+ {
+ // Mapping SMMUv3 -> ITS Group
+ // SMMUv3 device ID mapping
+ {
+ // Input base
+ 0x0,
+ // Number of input IDs
+ 0x0000FFFF,
+ // Output Base
+ 0x0,
+ // Output reference
+ REFERENCE_TOKEN (ItsGroupInfo[Its_pcie]),
+ // Flags
+ 0
+ },
+ // SMMUv3 device ID mapping
+ {
+ // Input base
+ 0x0,
+ // Number of input IDs
+ 0x00000001,
+ // Output Base
+ 0x0,
+ // Output reference token for the IORT node
+ REFERENCE_TOKEN (ItsGroupInfo[Its_smmu_pcie]),
+ // Flags
+ EFI_ACPI_IORT_ID_MAPPING_FLAGS_SINGLE
+ }
+ },
+ // DeviceIdMapping[1][0] - [1][1]
+ {
+ // Mapping SMMUv3 -> ITS Group
+ // SMMUv3 device ID mapping
+ {
+ // Input base
+ 0x0,
+ // Number of input IDs
+ 0x0000FFFF,
+ // Output Base
+ 0x0,
+ // Output reference
+ REFERENCE_TOKEN (ItsGroupInfo[Its_ccix]),
+ // Flags
+ 0
+ },
+ // SMMUv3 device ID mapping
+ {
+ // Input base
+ 0x0,
+ // Number of input IDs
+ 0x00000001,
+ // Output Base
+ 0x0,
+ // Output reference token for the IORT node
+ REFERENCE_TOKEN (ItsGroupInfo[Its_smmu_ccix]),
+ // Flags
+ EFI_ACPI_IORT_ID_MAPPING_FLAGS_SINGLE
+ }
+ },
+ // DeviceIdMapping[2][0] - [2][1]
+ {
+ // Mapping for RootComplex -> SMMUv3
+ // Device ID mapping for Root complex node
+ {
+ // Input base
+ 0x0,
+ // Number of input IDs
+ 0x0000FFFF,
+ // Output Base
+ 0x0,
+ // Output reference
+ REFERENCE_TOKEN (SmmuV3Info[Smmuv3info_pcie]),
+ // Flags
+ 0
+ },
+ // Device ID mapping for Root complex node
+ {
+ // Input base
+ 0x0,
+ // Number of input IDs
+ 0x0000FFFF,
+ // Output Base
+ 0x0,
+ // Output reference token for the IORT node
+ REFERENCE_TOKEN (SmmuV3Info[Smmuv3info_ccix]),
+ // Flags
+ 0
+ }
+ },
+ // Mapping of Remote Chip SMMUv3 -> ITS Group
+ {
+ {
+ 0x0,
+ 0x0000ffff,
+ 0x0,
+ REFERENCE_TOKEN (ItsGroupInfo[Its_remote_pcie]),
+ 0
+ },
+ {
+ 0x0,
+ 0x00000001,
+ 0x0,
+ REFERENCE_TOKEN (ItsGroupInfo[Its_remote_smmu_pcie]),
+ EFI_ACPI_IORT_ID_MAPPING_FLAGS_SINGLE
+ }
+ },
+ // Mapping for Remote Chip RootComplex -> SMMUv3
+ {
+ {
+ 0x0,
+ 0x0000ffff,
+ 0x0,
+ REFERENCE_TOKEN (SmmuV3Info[Smmuv3info_remote_pcie]),
+ 0
+ }
+ },
+ },
+
+ // PCI Configuration Space Info
+ {
+ // PCIe ECAM
+ {
+ 0x70000000, // Base Address
+ 0x0, // Segment Group Number
+ 0x0, // Start Bus Number
+ 17 // End Bus Number
+ },
+ // CCIX ECAM
+ {
+ 0x68000000, // Base Address
+ 0x1, // Segment Group Number
+ 0x0, // Start Bus Number
+ 17 // End Bus Number
+ },
+ //Remote Chip PCIe ECAM
+ {
+ 0x40070000000, // Base Address
+ 0x2, // Segment Group Number
+ 0x0, // Start Bus Number
+ 17 // End Bus Number
+ }
+ },
+
+ // Memory Affinity Info
+ {
+ {
+ // Proximity domain to which memory range belongs
+ 0,
+ //Base Address
+ 0x80000000,
+ //Length
+ 0x80000000,
+ //Flags
+ EFI_ACPI_6_3_MEMORY_ENABLED
+ },
+ {
+ // Proximity domain to which memory range belongs
+ 0,
+ //Base Address
+ 0x8080000000,
+ //Length is updated dynamically from SRAM
+ 0,
+ //Flags
+ EFI_ACPI_6_3_MEMORY_ENABLED
+ }
+ }
+
+};
+
+/** A helper function for returning the Configuration Manager Objects.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Object Pointer to the Object(s).
+ @param [in] ObjectSize Total size of the Object(s).
+ @param [in] ObjectCount Number of Objects.
+ @param [in, out] CmObjectDesc Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+ @retval EFI_SUCCESS Success.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+HandleCmObject (
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN VOID * Object,
+ IN CONST UINTN ObjectSize,
+ IN CONST UINTN ObjectCount,
+ IN OUT CM_OBJ_DESCRIPTOR * CONST CmObjectDesc
+ )
+{
+ CmObjectDesc->ObjectId = CmObjectId;
+ CmObjectDesc->Size = ObjectSize;
+ CmObjectDesc->Data = (VOID*)Object;
+ CmObjectDesc->Count = ObjectCount;
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: CmObjectId = %x, Ptr = 0x%p, Size = %d, Count = %d\n",
+ CmObjectId,
+ CmObjectDesc->Data,
+ CmObjectDesc->Size,
+ CmObjectDesc->Count
+ ));
+ return EFI_SUCCESS;
+}
+
+/** A helper function for returning the Configuration Manager Objects that
+ match the token.
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Object Pointer to the Object(s).
+ @param [in] ObjectSize Total size of the Object(s).
+ @param [in] ObjectCount Number of Objects.
+ @param [in] Token A token identifying the object.
+ @param [in] HandlerProc A handler function to search the object
+ referenced by the token.
+ @param [in, out] CmObjectDesc Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+HandleCmObjectRefByToken (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN VOID * Object,
+ IN CONST UINTN ObjectSize,
+ IN CONST UINTN ObjectCount,
+ IN CONST CM_OBJECT_TOKEN Token,
+ IN CONST CM_OBJECT_HANDLER_PROC HandlerProc,
+ IN OUT CM_OBJ_DESCRIPTOR * CONST CmObjectDesc
+ )
+{
+ EFI_STATUS Status;
+ CmObjectDesc->ObjectId = CmObjectId;
+ if (Token == CM_NULL_TOKEN) {
+ CmObjectDesc->Size = ObjectSize;
+ CmObjectDesc->Data = (VOID*)Object;
+ CmObjectDesc->Count = ObjectCount;
+ Status = EFI_SUCCESS;
+ } else {
+ Status = HandlerProc (This, CmObjectId, Token, CmObjectDesc);
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: Token = 0x%p, CmObjectId = %x, Ptr = 0x%p, Size = %d, Count = %d\n",
+ (VOID*)Token,
+ CmObjectId,
+ CmObjectDesc->Data,
+ CmObjectDesc->Size,
+ CmObjectDesc->Count
+ ));
+ return Status;
+}
+
+/** A helper function for returning Configuration Manager Object(s) referenced
+ by token when the entire platform repository is in scope and the
+ CM_NULL_TOKEN value is not allowed.
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token A token identifying the object.
+ @param [in] HandlerProc A handler function to search the object(s)
+ referenced by the token.
+ @param [in, out] CmObjectDesc Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+HandleCmObjectSearchPlatformRepo (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN Token,
+ IN CONST CM_OBJECT_HANDLER_PROC HandlerProc,
+ IN OUT CM_OBJ_DESCRIPTOR * CONST CmObjectDesc
+ )
+{
+ EFI_STATUS Status;
+ CmObjectDesc->ObjectId = CmObjectId;
+ if (Token == CM_NULL_TOKEN) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: CM_NULL_TOKEN value is not allowed when searching"
+ " the entire platform repository.\n"
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = HandlerProc (This, CmObjectId, Token, CmObjectDesc);
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: Token = 0x%p, CmObjectId = %x, Ptr = 0x%p, Size = %d, Count = %d\n",
+ CmObjectId,
+ (VOID*)Token,
+ CmObjectDesc->Data,
+ CmObjectDesc->Size,
+ CmObjectDesc->Count
+ ));
+ return Status;
+}
+
+/** Initialize the Platform Configuration Repository.
+ @param [in] PlatRepoInfo Pointer to the Configuration Manager Protocol.
+ @retval EFI_SUCCESS Success
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+InitializePlatformRepository (
+ IN EDKII_PLATFORM_REPOSITORY_INFO * CONST PlatRepoInfo
+ )
+{
+ NEOVERSEN1SOC_PLAT_INFO *PlatInfo;
+ UINT64 Dram2Size;
+ UINT64 RemoteDdrSize;
+
+ RemoteDdrSize = 0;
+
+ PlatInfo = (NEOVERSEN1SOC_PLAT_INFO *)NEOVERSEN1SOC_PLAT_INFO_STRUCT_BASE;
+ Dram2Size = ((PlatInfo->LocalDdrSize - 2) * SIZE_1GB);
+
+ PlatRepoInfo->MemAffInfo[LOCAL_DDR_REGION2].Length = Dram2Size;
+
+ if (PlatInfo->MultichipMode == 1) {
+ RemoteDdrSize = ((PlatInfo->RemoteDdrSize - 2) * SIZE_1GB);
+
+ // Update Remote DDR Region1
+ PlatRepoInfo->MemAffInfo[REMOTE_DDR_REGION1].ProximityDomain = 1;
+ PlatRepoInfo->MemAffInfo[REMOTE_DDR_REGION1]. \
+ BaseAddress = FixedPcdGet64 (PcdExtMemorySpace)
+ + FixedPcdGet64 (PcdSystemMemoryBase);
+ PlatRepoInfo->MemAffInfo[REMOTE_DDR_REGION1]. \
+ Length = FixedPcdGet64 (PcdSystemMemorySize);
+ PlatRepoInfo->MemAffInfo[REMOTE_DDR_REGION1]. \
+ Flags = EFI_ACPI_6_3_MEMORY_ENABLED;
+
+ // Update Remote DDR Region2
+ PlatRepoInfo->MemAffInfo[REMOTE_DDR_REGION2]. \
+ ProximityDomain = 1;
+ PlatRepoInfo->MemAffInfo[REMOTE_DDR_REGION2]. \
+ BaseAddress = FixedPcdGet64 (PcdExtMemorySpace)
+ + FixedPcdGet64 (PcdDramBlock2Base);
+ PlatRepoInfo->MemAffInfo[REMOTE_DDR_REGION2]. \
+ Length = RemoteDdrSize;
+ PlatRepoInfo->MemAffInfo[REMOTE_DDR_REGION2]. \
+ Flags = EFI_ACPI_6_3_MEMORY_ENABLED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Return a GT Block timer frame info list.
+
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token A token for identifying the object
+ @param [in, out] CmObject Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetGTBlockTimerFrameInfo (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN Token,
+ IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject
+ )
+{
+ EDKII_PLATFORM_REPOSITORY_INFO * PlatformRepo;
+
+ if ((This == NULL) || (CmObject == NULL)) {
+ ASSERT (This != NULL);
+ ASSERT (CmObject != NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PlatformRepo = This->PlatRepoInfo;
+
+ if (Token != (CM_OBJECT_TOKEN)&PlatformRepo->GTBlock0TimerInfo) {
+ return EFI_NOT_FOUND;
+ }
+
+ CmObject->ObjectId = CmObjectId;
+ CmObject->Size = sizeof (PlatformRepo->GTBlock0TimerInfo);
+ CmObject->Data = (VOID*)&PlatformRepo->GTBlock0TimerInfo;
+ CmObject->Count = ARRAY_SIZE (PlatformRepo->GTBlock0TimerInfo);
+ return EFI_SUCCESS;
+}
+
+/** Return an ITS identifier array.
+
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token A token for identifying the object
+ @param [in, out] CmObject Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetItsIdentifierArray (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN Token,
+ IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject
+ )
+{
+ EDKII_PLATFORM_REPOSITORY_INFO * PlatformRepo;
+ UINTN Count;
+ UINTN Index;
+
+ if ((This == NULL) || (CmObject == NULL)) {
+ ASSERT (This != NULL);
+ ASSERT (CmObject != NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PlatformRepo = This->PlatRepoInfo;
+
+ Count = ARRAY_SIZE (PlatformRepo->ItsIdentifierArray);
+
+ for (Index = 0; Index < Count; Index++) {
+ if (Token == (CM_OBJECT_TOKEN)&PlatformRepo->ItsIdentifierArray[Index]) {
+ CmObject->ObjectId = CmObjectId;
+ CmObject->Size = sizeof (PlatformRepo->ItsIdentifierArray[0]);
+ CmObject->Data = (VOID*)&PlatformRepo->ItsIdentifierArray[Index];
+ CmObject->Count = 1;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/** Return an ITS group info.
+
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token A token for identifying the object
+ @param [in, out] CmObject Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetItsGroupInfo (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN Token,
+ IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject
+ )
+{
+ EDKII_PLATFORM_REPOSITORY_INFO * PlatformRepo;
+ UINTN Count;
+ UINTN Index;
+
+ if ((This == NULL) || (CmObject == NULL)) {
+ ASSERT (This != NULL);
+ ASSERT (CmObject != NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PlatformRepo = This->PlatRepoInfo;
+
+ Count = ARRAY_SIZE (PlatformRepo->ItsGroupInfo);
+
+ for (Index = 0; Index < Count; Index++) {
+ if (Token == (CM_OBJECT_TOKEN)&PlatformRepo->ItsGroupInfo[Index]) {
+ CmObject->ObjectId = CmObjectId;
+ CmObject->Size = sizeof (PlatformRepo->ItsGroupInfo[0]);
+ CmObject->Data = (VOID*)&PlatformRepo->ItsGroupInfo[Index];
+ CmObject->Count = 1;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/** Return a device Id mapping array.
+
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token A token for identifying the object
+ @param [in, out] CmObject Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetDeviceIdMappingArray (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN Token,
+ IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject
+ )
+{
+ EDKII_PLATFORM_REPOSITORY_INFO * PlatformRepo;
+ UINTN Count;
+
+ if ((This == NULL) || (CmObject == NULL)) {
+ ASSERT (This != NULL);
+ ASSERT (CmObject != NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PlatformRepo = This->PlatRepoInfo;
+
+ DEBUG ((DEBUG_INFO, "DeviceIdMapping - Token = %p\n"));
+
+ if (Token == (CM_OBJECT_TOKEN)&PlatformRepo->DeviceIdMapping[0][0]) {
+ Count = 2;
+ DEBUG ((DEBUG_INFO, "DeviceIdMapping - Found DeviceIdMapping[0][0]\n"));
+ } else if (Token ==
+ (CM_OBJECT_TOKEN)&PlatformRepo->DeviceIdMapping[1][0]) {
+ Count = 2;
+ DEBUG ((DEBUG_INFO, "DeviceIdMapping - Found DeviceIdMapping[1][0]\n"));
+ } else if (Token ==
+ (CM_OBJECT_TOKEN)&PlatformRepo->DeviceIdMapping[2][0]) {
+ Count = 1;
+ DEBUG ((DEBUG_INFO, "DeviceIdMapping - Found DeviceIdMapping[2][0]\n"));
+ } else if (Token ==
+ (CM_OBJECT_TOKEN)&PlatformRepo->DeviceIdMapping[2][1]) {
+ Count = 1;
+ DEBUG ((DEBUG_INFO, "DeviceIdMapping - Found DeviceIdMapping[2][1]\n"));
+ } else if (Token ==
+ (CM_OBJECT_TOKEN)&PlatformRepo->DeviceIdMapping[Devicemapping_remote_smmu_pcie][0]) {
+ Count = 2;
+ DEBUG ((DEBUG_INFO, "DeviceIdMapping - Found DeviceIdMapping[Devicemapping_remote_smmu_pcie][0]\n"));
+ } else if (Token ==
+ (CM_OBJECT_TOKEN)&PlatformRepo->DeviceIdMapping[Devicemapping_remote_pcie][0]) {
+ Count = 1;
+ DEBUG ((DEBUG_INFO, "DeviceIdMapping - Found DeviceIdMapping[Devicemapping_remote_pcie][0]\n"));
+ } else {
+ DEBUG ((DEBUG_INFO, "DeviceIdMapping - Not Found\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ CmObject->Data = (VOID*)Token;
+ CmObject->ObjectId = CmObjectId;
+ CmObject->Count = Count;
+ CmObject->Size = Count * sizeof (CM_ARM_ID_MAPPING);
+
+ return EFI_SUCCESS;
+}
+
+/** Return GIC CPU Interface Info.
+
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Object ID of the CM object requested
+ @param [in] SearchToken A unique token for identifying the requested
+ CM_ARM_GICC_INFO object.
+ @param [in, out] CmObject Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetGicCInfo (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN SearchToken,
+ IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject
+ )
+{
+ EDKII_PLATFORM_REPOSITORY_INFO * PlatformRepo;
+ NEOVERSEN1SOC_PLAT_INFO *PlatInfo;
+ UINT32 TotalObjCount;
+ UINT32 ObjIndex;
+
+ if ((This == NULL) || (CmObject == NULL)) {
+ ASSERT (This != NULL);
+ ASSERT (CmObject != NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PlatformRepo = This->PlatRepoInfo;
+ PlatInfo = (NEOVERSEN1SOC_PLAT_INFO *)NEOVERSEN1SOC_PLAT_INFO_STRUCT_BASE;
+
+ if (PlatInfo->MultichipMode == 1) {
+ TotalObjCount = PLAT_CPU_COUNT * 2;
+ } else {
+ TotalObjCount = PLAT_CPU_COUNT;
+ }
+
+ for (ObjIndex = 0; ObjIndex < TotalObjCount; ObjIndex++) {
+ if (SearchToken == (CM_OBJECT_TOKEN)&PlatformRepo->GicCInfo[ObjIndex]) {
+ CmObject->ObjectId = CmObjectId;
+ CmObject->Size = sizeof (PlatformRepo->GicCInfo[ObjIndex]);
+ CmObject->Data = (VOID*)&PlatformRepo->GicCInfo[ObjIndex];
+ CmObject->Count = 1;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/** Return a list of Configuration Manager object references pointed to by the
+ given input token.
+
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Object ID of the CM object requested
+ @param [in] SearchToken A unique token for identifying the requested
+ CM_ARM_OBJ_REF list.
+ @param [in, out] CmObject Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetCmObjRefs (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN SearchToken,
+ IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject
+ )
+{
+ EDKII_PLATFORM_REPOSITORY_INFO * PlatformRepo;
+
+ if ((This == NULL) || (CmObject == NULL)) {
+ ASSERT (This != NULL);
+ ASSERT (CmObject != NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PlatformRepo = This->PlatRepoInfo;
+
+ if (SearchToken == (CM_OBJECT_TOKEN)&PlatformRepo->ClusterResources) {
+ CmObject->Size = sizeof (PlatformRepo->ClusterResources);
+ CmObject->Data = (VOID*)&PlatformRepo->ClusterResources;
+ CmObject->Count = ARRAY_SIZE (PlatformRepo->ClusterResources);
+ return EFI_SUCCESS;
+ }
+ if (SearchToken == (CM_OBJECT_TOKEN)&PlatformRepo->CoreResources) {
+ CmObject->Size = sizeof (PlatformRepo->CoreResources);
+ CmObject->Data = (VOID*)&PlatformRepo->CoreResources;
+ CmObject->Count = ARRAY_SIZE (PlatformRepo->CoreResources);
+ return EFI_SUCCESS;
+ }
+ if (SearchToken == (CM_OBJECT_TOKEN)&PlatformRepo->SocResources) {
+ CmObject->Size = sizeof (PlatformRepo->SocResources);
+ CmObject->Data = (VOID*)&PlatformRepo->SocResources;
+ CmObject->Count = ARRAY_SIZE (PlatformRepo->SocResources);
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/** Return a standard namespace object.
+
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token An optional token identifying the object. If
+ unused this must be CM_NULL_TOKEN.
+ @param [in, out] CmObject Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetStandardNameSpaceObject (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
+ IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject
+ )
+{
+ EFI_STATUS Status;
+ EDKII_PLATFORM_REPOSITORY_INFO * PlatformRepo;
+ NEOVERSEN1SOC_PLAT_INFO *PlatInfo;
+ UINT32 AcpiTableCount;
+
+ if ((This == NULL) || (CmObject == NULL)) {
+ ASSERT (This != NULL);
+ ASSERT (CmObject != NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = EFI_NOT_FOUND;
+ PlatformRepo = This->PlatRepoInfo;
+ PlatInfo = (NEOVERSEN1SOC_PLAT_INFO *)NEOVERSEN1SOC_PLAT_INFO_STRUCT_BASE;
+ AcpiTableCount = ARRAY_SIZE (PlatformRepo->CmAcpiTableList);
+ if (PlatInfo->MultichipMode == 0)
+ AcpiTableCount -= 1;
+
+ switch (GET_CM_OBJECT_ID (CmObjectId)) {
+ case EStdObjCfgMgrInfo:
+ Status = HandleCmObject (
+ CmObjectId,
+ &PlatformRepo->CmInfo,
+ sizeof (PlatformRepo->CmInfo),
+ 1,
+ CmObject
+ );
+ break;
+ case EStdObjAcpiTableList:
+ Status = HandleCmObject (
+ CmObjectId,
+ &PlatformRepo->CmAcpiTableList,
+ sizeof (PlatformRepo->CmAcpiTableList),
+ AcpiTableCount,
+ CmObject
+ );
+ break;
+ default: {
+ Status = EFI_NOT_FOUND;
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Object 0x%x. Status = %r\n",
+ CmObjectId,
+ Status
+ ));
+ break;
+ }
+ }
+
+ return Status;
+}
+
+/** Return an ARM namespace object.
+
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token An optional token identifying the object. If
+ unused this must be CM_NULL_TOKEN.
+ @param [in, out] CmObject Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetArmNameSpaceObject (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
+ IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject
+ )
+{
+ EFI_STATUS Status;
+ EDKII_PLATFORM_REPOSITORY_INFO * PlatformRepo;
+ NEOVERSEN1SOC_PLAT_INFO *PlatInfo;
+ UINT32 GicRedistCount;
+ UINT32 GicCpuCount;
+ UINT32 ProcHierarchyInfoCount;
+ UINT32 GicItsInfoCount;
+ UINT32 ItsGroupInfoCount;
+ UINT32 ItsIdentifierArrayCount;
+ UINT32 SmmuV3InfoCount;
+ UINT32 DeviceIdMappingCount;
+ UINT32 RootComplexInfoCount;
+ UINT32 PciConfigInfoCount;
+
+ if ((This == NULL) || (CmObject == NULL)) {
+ ASSERT (This != NULL);
+ ASSERT (CmObject != NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = EFI_NOT_FOUND;
+ PlatformRepo = This->PlatRepoInfo;
+
+ // Probe for multi chip information
+ PlatInfo = (NEOVERSEN1SOC_PLAT_INFO *)NEOVERSEN1SOC_PLAT_INFO_STRUCT_BASE;
+ if (PlatInfo->MultichipMode == 1) {
+ GicRedistCount = 2;
+ GicCpuCount = PLAT_CPU_COUNT * 2;
+ ProcHierarchyInfoCount = PLAT_PROC_HIERARCHY_NODE_COUNT * 2;
+ GicItsInfoCount = Its_max;
+ ItsGroupInfoCount = Its_max;
+ ItsIdentifierArrayCount = Its_max;
+ SmmuV3InfoCount = Smmuv3info_max;
+ DeviceIdMappingCount = Devicemapping_max;
+ RootComplexInfoCount = Root_pcie_max;
+ PciConfigInfoCount = Root_pcie_max;
+ } else {
+ GicRedistCount = 1;
+ GicCpuCount = PLAT_CPU_COUNT;
+ ProcHierarchyInfoCount = PLAT_PROC_HIERARCHY_NODE_COUNT;
+ GicItsInfoCount = Its_master_chip_max;
+ ItsGroupInfoCount = Its_master_chip_max;
+ ItsIdentifierArrayCount = Its_master_chip_max;
+ SmmuV3InfoCount = Smmuv3info_master_chip_max;
+ DeviceIdMappingCount = Devicemapping_master_chip_max;
+ RootComplexInfoCount = Root_pcie_master_chip_max;
+ PciConfigInfoCount = Root_pcie_master_chip_max;
+ }
+
+ switch (GET_CM_OBJECT_ID (CmObjectId)) {
+ case EArmObjBootArchInfo:
+ Status = HandleCmObject (
+ CmObjectId,
+ &PlatformRepo->BootArchInfo,
+ sizeof (PlatformRepo->BootArchInfo),
+ 1,
+ CmObject
+ );
+ break;
+
+ case EArmObjFixedFeatureFlags:
+ Status = HandleCmObject (
+ CmObjectId,
+ &PlatformRepo->FixedFeatureFlags,
+ sizeof (PlatformRepo->FixedFeatureFlags),
+ 1,
+ CmObject
+ );
+ break;
+
+ case EArmObjPowerManagementProfileInfo:
+ Status = HandleCmObject (
+ CmObjectId,
+ &PlatformRepo->PmProfileInfo,
+ sizeof (PlatformRepo->PmProfileInfo),
+ 1,
+ CmObject
+ );
+ break;
+
+ case EArmObjGenericTimerInfo:
+ Status = HandleCmObject (
+ CmObjectId,
+ &PlatformRepo->GenericTimerInfo,
+ sizeof (PlatformRepo->GenericTimerInfo),
+ 1,
+ CmObject
+ );
+ break;
+
+ case EArmObjPlatformGenericWatchdogInfo:
+ Status = HandleCmObject (
+ CmObjectId,
+ &PlatformRepo->Watchdog,
+ sizeof (PlatformRepo->Watchdog),
+ 1,
+ CmObject
+ );
+ break;
+
+ case EArmObjPlatformGTBlockInfo:
+ Status = HandleCmObject (
+ CmObjectId,
+ PlatformRepo->GTBlockInfo,
+ sizeof (PlatformRepo->GTBlockInfo),
+ ARRAY_SIZE (PlatformRepo->GTBlockInfo),
+ CmObject
+ );
+ break;
+
+ case EArmObjGTBlockTimerFrameInfo:
+ Status = HandleCmObjectRefByToken (
+ This,
+ CmObjectId,
+ PlatformRepo->GTBlock0TimerInfo,
+ sizeof (PlatformRepo->GTBlock0TimerInfo),
+ ARRAY_SIZE (PlatformRepo->GTBlock0TimerInfo),
+ Token,
+ GetGTBlockTimerFrameInfo,
+ CmObject
+ );
+ break;
+
+ case EArmObjGicCInfo:
+ Status = HandleCmObjectRefByToken (
+ This,
+ CmObjectId,
+ PlatformRepo->GicCInfo,
+ sizeof (PlatformRepo->GicCInfo),
+ GicCpuCount,
+ Token,
+ GetGicCInfo,
+ CmObject
+ );
+ break;
+
+ case EArmObjGicDInfo:
+ Status = HandleCmObject (
+ CmObjectId,
+ &PlatformRepo->GicDInfo,
+ sizeof (PlatformRepo->GicDInfo),
+ 1,
+ CmObject
+ );
+ break;
+
+ case EArmObjGicRedistributorInfo:
+ Status = HandleCmObject (
+ CmObjectId,
+ PlatformRepo->GicRedistInfo,
+ sizeof (PlatformRepo->GicRedistInfo),
+ GicRedistCount,
+ CmObject
+ );
+ break;
+
+ case EArmObjSerialConsolePortInfo:
+ Status = HandleCmObject (
+ CmObjectId,
+ &PlatformRepo->SpcrSerialPort,
+ sizeof (PlatformRepo->SpcrSerialPort),
+ 1,
+ CmObject
+ );
+ break;
+
+ case EArmObjSerialDebugPortInfo:
+ Status = HandleCmObject (
+ CmObjectId,
+ &PlatformRepo->DbgSerialPort,
+ sizeof (PlatformRepo->DbgSerialPort),
+ 1,
+ CmObject
+ );
+ break;
+
+ case EArmObjGicItsInfo:
+ Status = HandleCmObject (
+ CmObjectId,
+ PlatformRepo->GicItsInfo,
+ sizeof (PlatformRepo->GicItsInfo),
+ GicItsInfoCount,
+ CmObject
+ );
+ break;
+
+ case EArmObjSmmuV3:
+ Status = HandleCmObject (
+ CmObjectId,
+ PlatformRepo->SmmuV3Info,
+ sizeof (PlatformRepo->SmmuV3Info),
+ SmmuV3InfoCount,
+ CmObject
+ );
+ break;
+
+ case EArmObjItsGroup:
+ Status = HandleCmObjectRefByToken (
+ This,
+ CmObjectId,
+ PlatformRepo->ItsGroupInfo,
+ sizeof (PlatformRepo->ItsGroupInfo),
+ ItsGroupInfoCount,
+ Token,
+ GetItsGroupInfo,
+ CmObject
+ );
+ break;
+
+ case EArmObjGicItsIdentifierArray:
+ Status = HandleCmObjectRefByToken (
+ This,
+ CmObjectId,
+ PlatformRepo->ItsIdentifierArray,
+ sizeof (PlatformRepo->ItsIdentifierArray),
+ ItsIdentifierArrayCount,
+ Token,
+ GetItsIdentifierArray,
+ CmObject
+ );
+ break;
+
+ case EArmObjRootComplex:
+ Status = HandleCmObject (
+ CmObjectId,
+ PlatformRepo->RootComplexInfo,
+ sizeof (PlatformRepo->RootComplexInfo),
+ RootComplexInfoCount,
+ CmObject
+ );
+ break;
+
+ case EArmObjIdMappingArray:
+ Status = HandleCmObjectRefByToken (
+ This,
+ CmObjectId,
+ PlatformRepo->DeviceIdMapping,
+ sizeof (PlatformRepo->DeviceIdMapping),
+ DeviceIdMappingCount,
+ Token,
+ GetDeviceIdMappingArray,
+ CmObject
+ );
+ break;
+
+ case EArmObjProcHierarchyInfo:
+ Status = HandleCmObject (
+ CmObjectId,
+ PlatformRepo->ProcHierarchyInfo,
+ sizeof (PlatformRepo->ProcHierarchyInfo),
+ ProcHierarchyInfoCount,
+ CmObject
+ );
+ break;
+
+ case EArmObjCacheInfo:
+ Status = HandleCmObject (
+ CmObjectId,
+ PlatformRepo->CacheInfo,
+ sizeof (PlatformRepo->CacheInfo),
+ ARRAY_SIZE (PlatformRepo->CacheInfo),
+ CmObject
+ );
+ break;
+
+ case EArmObjCmRef:
+ Status = HandleCmObjectSearchPlatformRepo (
+ This,
+ CmObjectId,
+ Token,
+ GetCmObjRefs,
+ CmObject
+ );
+ break;
+
+ case EArmObjPciConfigSpaceInfo:
+ Status = HandleCmObject (
+ CmObjectId,
+ PlatformRepo->PciConfigInfo,
+ sizeof (PlatformRepo->PciConfigInfo),
+ PciConfigInfoCount,
+ CmObject
+ );
+ break;
+
+ case EArmObjMemoryAffinityInfo:
+ Status = HandleCmObject (
+ CmObjectId,
+ PlatformRepo->MemAffInfo,
+ sizeof (PlatformRepo->MemAffInfo),
+ ARRAY_SIZE (PlatformRepo->MemAffInfo),
+ CmObject
+ );
+ break;
+
+ default: {
+ Status = EFI_NOT_FOUND;
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: Object 0x%x. Status = %r\n",
+ CmObjectId,
+ Status
+ ));
+ break;
+ }
+ }//switch
+
+ return Status;
+}
+
+/** Return an OEM namespace object.
+
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token An optional token identifying the object. If
+ unused this must be CM_NULL_TOKEN.
+ @param [in, out] CmObject Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetOemNameSpaceObject (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
+ IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ if ((This == NULL) || (CmObject == NULL)) {
+ ASSERT (This != NULL);
+ ASSERT (CmObject != NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (GET_CM_OBJECT_ID (CmObjectId)) {
+ default: {
+ Status = EFI_NOT_FOUND;
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Object 0x%x. Status = %r\n",
+ CmObjectId,
+ Status
+ ));
+ break;
+ }
+ }
+
+ return Status;
+}
+
+/** The GetObject function defines the interface implemented by the
+ Configuration Manager Protocol for returning the Configuration
+ Manager Objects.
+
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token An optional token identifying the object. If
+ unused this must be CM_NULL_TOKEN.
+ @param [in, out] CmObject Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+N1sdpPlatformGetObject (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
+ IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject
+ )
+{
+ EFI_STATUS Status;
+
+ if ((This == NULL) || (CmObject == NULL)) {
+ ASSERT (This != NULL);
+ ASSERT (CmObject != NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (GET_CM_NAMESPACE_ID (CmObjectId)) {
+ case EObjNameSpaceStandard:
+ Status = GetStandardNameSpaceObject (This, CmObjectId, Token, CmObject);
+ break;
+ case EObjNameSpaceArm:
+ Status = GetArmNameSpaceObject (This, CmObjectId, Token, CmObject);
+ break;
+ case EObjNameSpaceOem:
+ Status = GetOemNameSpaceObject (This, CmObjectId, Token, CmObject);
+ break;
+ default: {
+ Status = EFI_INVALID_PARAMETER;
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Unknown Namespace Object = 0x%x. Status = %r\n",
+ CmObjectId,
+ Status
+ ));
+ break;
+ }
+ }
+
+ return Status;
+}
+
+/** The SetObject function defines the interface implemented by the
+ Configuration Manager Protocol for updating the Configuration
+ Manager Objects.
+
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token An optional token identifying the object. If
+ unused this must be CM_NULL_TOKEN.
+ @param [in] CmObject Pointer to the Configuration Manager Object
+ descriptor describing the Object.
+
+ @retval EFI_UNSUPPORTED This operation is not supported.
+**/
+EFI_STATUS
+EFIAPI
+N1sdpPlatformSetObject (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
+ IN CM_OBJ_DESCRIPTOR * CONST CmObject
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/** A structure describing the configuration manager protocol interface.
+*/
+STATIC
+CONST
+EDKII_CONFIGURATION_MANAGER_PROTOCOL N1sdpPlatformConfigManagerProtocol = {
+ CREATE_REVISION(1,0),
+ N1sdpPlatformGetObject,
+ N1sdpPlatformSetObject,
+ &N1sdpRepositoryInfo
+};
+
+/**
+ Entrypoint of Configuration Manager Dxe.
+
+ @param [in] ImageHandle
+ @param [in] SystemTable
+
+ @return EFI_SUCCESS
+ @return EFI_LOAD_ERROR
+ @return EFI_OUT_OF_RESOURCES
+**/
+EFI_STATUS
+EFIAPI
+ConfigurationManagerDxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ // Initialize the Platform Configuration Repository before installing the
+ // Configuration Manager Protocol
+ Status = InitializePlatformRepository (
+ N1sdpPlatformConfigManagerProtocol.PlatRepoInfo
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to initialize the Platform Configuration Repository." \
+ " Status = %r\n",
+ Status
+ ));
+ }
+
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gEdkiiConfigurationManagerProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ (VOID*)&N1sdpPlatformConfigManagerProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to get Install Configuration Manager Protocol." \
+ " Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+
+error_handler:
+ return Status;
+}
diff --git a/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.h b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.h
new file mode 100644
index 0000000000..303c38dcae
--- /dev/null
+++ b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.h
@@ -0,0 +1,307 @@
+/** @file
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#ifndef CONFIGURATION_MANAGER_H_
+#define CONFIGURATION_MANAGER_H_
+
+/** C array containing the compiled AML template.
+ This symbol is defined in the auto generated C file
+ containing the AML bytecode array.
+*/
+extern CHAR8 dsdt_aml_code[];
+extern CHAR8 ssdtpci_aml_code[];
+extern CHAR8 ssdtremotepci_aml_code[];
+
+/** The configuration manager version.
+*/
+#define CONFIGURATION_MANAGER_REVISION CREATE_REVISION (1, 0)
+
+/** The OEM ID
+*/
+#define CFG_MGR_OEM_ID { 'A', 'R', 'M', 'L', 'T', 'D' }
+
+/** A helper macro for mapping a reference token
+*/
+#define REFERENCE_TOKEN(Field) \
+ (CM_OBJECT_TOKEN)((UINT8*)&N1sdpRepositoryInfo + \
+ OFFSET_OF (EDKII_PLATFORM_REPOSITORY_INFO, Field))
+
+/** A helper macro that constructs the MPID based on the
+ Aff0, Aff1, Aff2, Aff3 values
+*/
+#define GET_MPID3(Aff3, Aff2, Aff1, Aff0) \
+ (((Aff3##ULL) << 32) | ((Aff2) << 16) | ((Aff1) << 8) | (Aff0))
+
+/** A helper macro for populating the GIC CPU information
+*/
+#define GICC_ENTRY( \
+ CPUInterfaceNumber, \
+ Mpidr, \
+ PmuIrq, \
+ VGicIrq, \
+ GicRedistBase, \
+ EnergyEfficiency, \
+ SpeIrq, \
+ ProximityDomain, \
+ ClockDomain \
+ ) { \
+ CPUInterfaceNumber, /* UINT32 CPUInterfaceNumber */ \
+ CPUInterfaceNumber, /* UINT32 AcpiProcessorUid */ \
+ EFI_ACPI_6_2_GIC_ENABLED, /* UINT32 Flags */ \
+ 0, /* UINT32 ParkingProtocolVersion */ \
+ PmuIrq, /* UINT32 PerformanceInterruptGsiv */ \
+ 0, /* UINT64 ParkedAddress */ \
+ FixedPcdGet64 ( \
+ PcdGicInterruptInterfaceBase \
+ ), /* UINT64 PhysicalBaseAddress */ \
+ 0, /* UINT64 GICV */ \
+ 0, /* UINT64 GICH */ \
+ VGicIrq, /* UINT32 VGICMaintenanceInterrupt */ \
+ GicRedistBase, /* UINT64 GICRBaseAddress */ \
+ Mpidr, /* UINT64 MPIDR */ \
+ EnergyEfficiency, /* UINT8 ProcessorPowerEfficiencyClass*/ \
+ SpeIrq, /* UINT16 SpeOverflowInterrupt */ \
+ ProximityDomain, /* UINT32 ProximityDomain */ \
+ ClockDomain, /* UINT32 ClockDomain */ \
+ EFI_ACPI_6_3_GICC_ENABLED,/* UINT32 Flags */ \
+ }
+
+/** A helper macro for populating the Processor Hierarchy Node flags
+*/
+#define PROC_NODE_FLAGS( \
+ PhysicalPackage, \
+ AcpiProcessorIdValid, \
+ ProcessorIsThread, \
+ NodeIsLeaf, \
+ IdenticalImplementation \
+ ) \
+ ( \
+ PhysicalPackage | \
+ (AcpiProcessorIdValid << 1) | \
+ (ProcessorIsThread << 2) | \
+ (NodeIsLeaf << 3) | \
+ (IdenticalImplementation << 4) \
+ )
+
+/** A helper macro for populating the Cache Type Structure's attributes
+*/
+#define CACHE_ATTRIBUTES( \
+ AllocationType, \
+ CacheType, \
+ WritePolicy \
+ ) \
+ ( \
+ AllocationType | \
+ (CacheType << 2) | \
+ (WritePolicy << 4) \
+ )
+
+/** A function that prepares Configuration Manager Objects for returning.
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token A token for identifying the object.
+ @param [out] CmObject Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+typedef EFI_STATUS (*CM_OBJECT_HANDLER_PROC) (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN Token,
+ IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject
+ );
+
+/** The number of CPUs
+*/
+#define PLAT_CPU_COUNT 4
+
+/** The number of ACPI tables to install
+*/
+#define PLAT_ACPI_TABLE_COUNT 13
+
+/** The number of platform generic timer blocks
+*/
+#define PLAT_GTBLOCK_COUNT 1
+
+/** The number of timer frames per generic timer block
+*/
+#define PLAT_GTFRAME_COUNT 2
+
+/** The number of Processor Hierarchy Nodes
+ - one package node
+ - two cluster nodes
+ - two cores in cluster 0
+ - two cores in cluster 1
+*/
+#define PLAT_PROC_HIERARCHY_NODE_COUNT 7
+
+/** The number of unique cache structures:
+ - cluster L3 unified cache
+ - core L1 instruction cache
+ - core L1 data cache
+ - core L2 cache
+ - slc unified cache
+*/
+#define PLAT_CACHE_COUNT 5
+
+/** The number of resources private to the cluster
+ - L3 cache
+*/
+#define CLUSTER_RESOURCE_COUNT 1
+
+/** The number of resources private to 'core instance
+ - L1 data cache
+ - L1 instruction cache
+*/
+#define CORE_RESOURCE_COUNT 2
+
+/** The number of resources private to SoC
+ - slc cache
+*/
+#define SOC_RESOURCE_COUNT 1
+
+/** Number of memory affinity entries
+*/
+#define LOCAL_DDR_REGION1 0
+#define LOCAL_DDR_REGION2 1
+#define REMOTE_DDR_REGION1 2
+#define REMOTE_DDR_REGION2 3
+#define DDR_REGION_COUNT 4
+
+typedef enum {
+ Its_smmu_ccix = 0,
+ Its_smmu_pcie,
+ Its_ccix,
+ Its_pcie,
+ Its_master_chip_max,
+ Its_remote_smmu_pcie = Its_master_chip_max,
+ Its_remote_pcie,
+ Its_max
+} ITS_ID;
+
+typedef enum {
+ Smmuv3info_pcie = 0,
+ Smmuv3info_ccix,
+ Smmuv3info_master_chip_max,
+ Smmuv3info_remote_pcie = Smmuv3info_master_chip_max,
+ Smmuv3info_max
+} SMMU_INFO_V3;
+
+typedef enum {
+ Root_pcie = 0,
+ Root_pcie_ccix,
+ Root_pcie_master_chip_max,
+ Root_remote_pcie = Root_pcie_master_chip_max,
+ Root_pcie_max
+} N1SDP_ROOT_PORT;
+
+typedef enum {
+ Devicemapping_smmu_pcie = 0,
+ Devicemapping_smmu_ccix,
+ Devicemapping_pcie,
+ Devicemapping_master_chip_max,
+ Devicemapping_remote_smmu_pcie = Devicemapping_master_chip_max,
+ Devicemapping_remote_pcie,
+ Devicemapping_max,
+} N1SDP_DEVID;
+
+/** A structure describing the platform configuration
+ manager repository information
+*/
+typedef struct PlatformRepositoryInfo {
+ /// Configuration Manager Information
+ CM_STD_OBJ_CONFIGURATION_MANAGER_INFO CmInfo;
+
+ /// List of ACPI tables
+ CM_STD_OBJ_ACPI_TABLE_INFO CmAcpiTableList[PLAT_ACPI_TABLE_COUNT];
+
+ /// Boot architecture information
+ CM_ARM_BOOT_ARCH_INFO BootArchInfo;
+
+ /// Fixed feature flag information
+ CM_ARM_FIXED_FEATURE_FLAGS FixedFeatureFlags;
+
+ /// Power management profile information
+ CM_ARM_POWER_MANAGEMENT_PROFILE_INFO PmProfileInfo;
+
+ /// GIC CPU interface information
+ CM_ARM_GICC_INFO GicCInfo[PLAT_CPU_COUNT * 2];
+
+ /// GIC distributor information
+ CM_ARM_GICD_INFO GicDInfo;
+
+ /// GIC Redistributor information
+ CM_ARM_GIC_REDIST_INFO GicRedistInfo[2];
+
+ /// GIC ITS information
+ CM_ARM_GIC_ITS_INFO GicItsInfo[Its_max];
+
+ /// Generic timer information
+ CM_ARM_GENERIC_TIMER_INFO GenericTimerInfo;
+
+ /// Generic timer block information
+ CM_ARM_GTBLOCK_INFO GTBlockInfo[PLAT_GTBLOCK_COUNT];
+
+ /// Generic timer frame information
+ CM_ARM_GTBLOCK_TIMER_FRAME_INFO GTBlock0TimerInfo[PLAT_GTFRAME_COUNT];
+
+ /// Watchdog information
+ CM_ARM_GENERIC_WATCHDOG_INFO Watchdog;
+
+ /** Serial port information for the
+ serial port console redirection port
+ */
+ CM_ARM_SERIAL_PORT_INFO SpcrSerialPort;
+
+ /// Serial port information for the DBG2 UART port
+ CM_ARM_SERIAL_PORT_INFO DbgSerialPort;
+
+ // Processor topology information
+ CM_ARM_PROC_HIERARCHY_INFO ProcHierarchyInfo[PLAT_PROC_HIERARCHY_NODE_COUNT * 2];
+
+ // Cache information
+ CM_ARM_CACHE_INFO CacheInfo[PLAT_CACHE_COUNT];
+
+ // Cluster private resources
+ CM_ARM_OBJ_REF ClusterResources[CLUSTER_RESOURCE_COUNT];
+
+ // Core private resources
+ CM_ARM_OBJ_REF CoreResources[CORE_RESOURCE_COUNT];
+
+ // SoC Resources
+ CM_ARM_OBJ_REF SocResources[SOC_RESOURCE_COUNT];
+
+ /// ITS Group node
+ CM_ARM_ITS_GROUP_NODE ItsGroupInfo[Its_max];
+
+ /// ITS Identifier array
+ CM_ARM_ITS_IDENTIFIER ItsIdentifierArray[Its_max];
+
+ /// SMMUv3 node
+ CM_ARM_SMMUV3_NODE SmmuV3Info[Smmuv3info_max];
+
+ /// PCI Root complex node
+ CM_ARM_ROOT_COMPLEX_NODE RootComplexInfo[Root_pcie_max];
+
+ /// Array of DeviceID mapping
+ CM_ARM_ID_MAPPING DeviceIdMapping[Devicemapping_max][2];
+
+ /// PCI configuration space information
+ CM_ARM_PCI_CONFIG_SPACE_INFO PciConfigInfo[Root_pcie_max];
+
+ /// Memory Affinity Info
+ CM_ARM_MEMORY_AFFINITY_INFO MemAffInfo[DDR_REGION_COUNT];
+
+} EDKII_PLATFORM_REPOSITORY_INFO;
+
+#endif // CONFIGURATION_MANAGER_H_
diff --git a/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf
new file mode 100644
index 0000000000..027a4202ff
--- /dev/null
+++ b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf
@@ -0,0 +1,166 @@
+## @file
+# Configuration Manager Dxe
+#
+# Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = ConfigurationManagerDxe
+ FILE_GUID = 6808406b-b2ba-43b6-8680-1438f3bc458c
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ConfigurationManagerDxeInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = ARM AARCH64
+#
+
+[Sources]
+ AslTables/Dsdt.asl
+ AslTables/SsdtPci.asl
+ AslTables/SsdtRemotePci.asl
+ ConfigurationManager.c
+ ConfigurationManager.h
+ Hmat.c
+ Platform.h
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ DynamicTablesPkg/DynamicTablesPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ Platform/ARM/N1Sdp/N1SdpPlatform.dec
+ Silicon/ARM/NeoverseN1Soc/NeoverseN1Soc.dec
+
+[LibraryClasses]
+ ArmPlatformLib
+ PrintLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiRuntimeServicesTableLib
+
+[Protocols]
+ gEdkiiConfigurationManagerProtocolGuid
+
+[FixedPcd]
+ # PL011 Serial Debug UART
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgUartBaudRate
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgUartClkInHz
+
+ gArmPlatformTokenSpaceGuid.PL011UartClkInHz
+ gArmPlatformTokenSpaceGuid.PL011UartInterrupt
+
+ gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum
+ gArmTokenSpaceGuid.PcdArmArchTimerIntrNum
+ gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum
+ gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum
+
+ # SBSA Generic Watchdog
+ gArmTokenSpaceGuid.PcdGenericWatchdogControlBase
+ gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum
+ gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase
+
+ gArmTokenSpaceGuid.PcdGicDistributorBase
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
+ gArmTokenSpaceGuid.PcdGicRedistributorsBase
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
+
+ gArmN1SdpTokenSpaceGuid.PcdPcieExpressBaseAddress
+
+ gArmNeoverseN1SocTokenSpaceGuid.PcdExtMemorySpace
+ gArmNeoverseN1SocTokenSpaceGuid.PcdDramBlock2Base
+
+ gArmPlatformTokenSpaceGuid.PcdCoreCount
+ gArmPlatformTokenSpaceGuid.PcdClusterCount
+
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+
+ #PCIe
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieBusCount
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieBusMax
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieBusMin
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieIoBase
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieIoMaxBase
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieIoSize
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieIoTranslation
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieMmio32Base
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieMmio32MaxBase
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieMmio32Size
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieMmio32Translation
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieMmio64Base
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieMmio64MaxBase
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieMmio64Size
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieMmio64Translation
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieRootPortConfigBaseAddress
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieRootPortConfigBaseSize
+
+ # CCIX
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixBusCount
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixBusMax
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixBusMin
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixExpressBaseAddress
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixIoBase
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixIoMaxBase
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixIoSize
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixIoTranslation
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio32Base
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio32MaxBase
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio32Size
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio32Translation
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio64Base
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio64MaxBase
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio64Size
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio64Translation
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixRootPortConfigBaseAddress
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixRootPortConfigBaseSize
+
+ # Coresight
+ gArmN1SdpTokenSpaceGuid.PcdCsComponentSize
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf0Base
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf0MaxBase
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf1Base
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf1MaxBase
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf2Base
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf2MaxBase
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm0Base
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm0MaxBase
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm1Base
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm1MaxBase
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm2Base
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm2MaxBase
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm3Base
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm3MaxBase
+ gArmN1SdpTokenSpaceGuid.PcdCsEtrBase
+ gArmN1SdpTokenSpaceGuid.PcdCsEtrMaxBase
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel0Base
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel0MaxBase
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel1Base
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel1MaxBase
+ gArmN1SdpTokenSpaceGuid.PcdCsReplicatorBase
+ gArmN1SdpTokenSpaceGuid.PcdCsReplicatorMaxBase
+ gArmN1SdpTokenSpaceGuid.PcdCsStmBase
+ gArmN1SdpTokenSpaceGuid.PcdCsStmMaxBase
+ gArmN1SdpTokenSpaceGuid.PcdCsStmStimulusBase
+ gArmN1SdpTokenSpaceGuid.PcdCsStmStimulusSize
+ gArmN1SdpTokenSpaceGuid.PcdCsTpiuBase
+ gArmN1SdpTokenSpaceGuid.PcdCsTpiuMaxBase
+
+ # Remote PCIe
+ gArmN1SdpTokenSpaceGuid.PcdRemotePcieIoTranslation
+ gArmN1SdpTokenSpaceGuid.PcdRemotePcieMmio32Translation
+ gArmN1SdpTokenSpaceGuid.PcdRemotePcieMmio64Translation
+
+[Depex]
+ TRUE
diff --git a/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/Hmat.c b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/Hmat.c
new file mode 100644
index 0000000000..52fc3108a2
--- /dev/null
+++ b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/Hmat.c
@@ -0,0 +1,103 @@
+/** @file
+ Heterogeneous Memory Attribute Table (HMAT)
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/AcpiLib.h>
+#include <Library/ArmLib.h>
+#include "N1SdpAcpiHeader.h"
+
+//
+// Heterogeneous Memory Attribute Table
+//
+#pragma pack (1)
+
+typedef struct {
+ EFI_ACPI_6_3_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO LatencyStruct;
+ UINT32 InitiatorProximityDomainList[1];
+ UINT32 TargetProximityDomainList[2];
+ UINT16 LatencyEntry[1][2];
+} EFI_ACPI_6_3_HMAT_SYSTEM_LOCALITY_LATENCY_STRUCTURE;
+
+typedef struct {
+ EFI_ACPI_6_3_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER Header;
+ EFI_ACPI_6_3_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES Memory[2];
+ EFI_ACPI_6_3_HMAT_SYSTEM_LOCALITY_LATENCY_STRUCTURE LatencyInfo;
+} EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE;
+
+#pragma pack ()
+
+EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE Hmat = {
+ // Header
+ {
+ ARM_ACPI_HEADER (
+ EFI_ACPI_6_3_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE,
+ EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE,
+ EFI_ACPI_6_3_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_REVISION
+ ),
+ {0x00, 0x00, 0x00, 0x00},
+ },
+
+ // Memory Attribute Structure
+ {
+ {
+ EFI_ACPI_6_3_HMAT_TYPE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES, // Type
+ {0x00, 0x00}, // Reserved
+ 40, // Length
+ {.InitiatorProximityDomainValid = 1}, // Flags
+ {0x00, 0x00}, // Reserved1
+ 0, // InitiatorProximityDomain
+ 0, // MemoryProximityDomain
+ { 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ }, // Reserved2
+ },
+ {
+ EFI_ACPI_6_3_HMAT_TYPE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES, // Type
+ {0x00, 0x00}, // Reserved
+ 40, // Length
+ {.InitiatorProximityDomainValid = 1}, // Flags
+ {0x00, 0x00}, // Reserved1
+ 0, // InitiatorProximityDomain
+ 1, // MemoryProximityDomain
+ { 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ }, // Reserved2
+ },
+ },
+
+ // System Locality Latency Structure (LatencyInfo)
+ {
+ // LatencyStruct
+ {
+ EFI_ACPI_6_3_HMAT_TYPE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO, // Type
+ {0x00, 0x00}, // Reserved
+ sizeof (EFI_ACPI_6_3_HMAT_SYSTEM_LOCALITY_LATENCY_STRUCTURE), // Length
+ {.MemoryHierarchy = 0}, // Flags
+ 0, // DataType - Access latency
+ {0x00, 0x00}, // Reserved1
+ 1, // NumberOfInitiatorProximityDomains
+ 2, // NumberOfTargetProximityDomains
+ {0x00, 0x00, 0x00, 0x00}, // Reserved2
+ 1000, // EntryBaseUnit - 1000ps = 1ns
+ },
+ // InitiatorProximityDomainList
+ { 0 },
+ // TargetProximityDomainList
+ { 0, 1 },
+ // LatencyEntry
+ {
+ {119, 200},
+ },
+ },
+};
diff --git a/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/Platform.h b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/Platform.h
new file mode 100644
index 0000000000..d220b09446
--- /dev/null
+++ b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/Platform.h
@@ -0,0 +1,92 @@
+/** @file
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PLATFORM_H_
+#define PLATFORM_H_
+
+#define ENABLE_MEM_MAPPED_TIMER
+
+#ifdef ENABLE_MEM_MAPPED_TIMER
+// REFCLK CNTControl
+#define N1SDP_SYSTEM_TIMER_BASE_ADDRESS 0x2A430000
+// REFCLK CNTRead
+#define N1SDP_CNT_READ_BASE_ADDRESS 0x2A800000
+#else
+#define N1SDP_SYSTEM_TIMER_BASE_ADDRESS 0xFFFFFFFFFFFFFFFF
+#define N1SDP_CNT_READ_BASE_ADDRESS 0xFFFFFFFFFFFFFFFF
+#endif
+
+// GT Block Timer
+// AP_REFCLK CNTCTL
+#define N1SDP_GT_BLOCK_CTL_BASE 0x2A810000
+#define N1SDP_TIMER_FRAMES_COUNT 2
+
+// GT Block Timer Frames
+// AP_REFCLK_S CNTBase0
+#define N1SDP_GT_BLOCK_FRAME0_CTL_BASE 0x2A830000
+#define N1SDP_GT_BLOCK_FRAME0_CTL_EL0_BASE 0xFFFFFFFFFFFFFFFF
+#define N1SDP_GT_BLOCK_FRAME0_GSIV 92
+
+// AP_REFCLK_NS CNTBase1
+#define N1SDP_GT_BLOCK_FRAME1_CTL_BASE 0x2A820000
+#define N1SDP_GT_BLOCK_FRAME1_CTL_EL0_BASE 0xFFFFFFFFFFFFFFFF
+#define N1SDP_GT_BLOCK_FRAME1_GSIV 91
+
+#define GTDT_TIMER_EDGE_TRIGGERED \
+ EFI_ACPI_6_3_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE
+#define GTDT_TIMER_LEVEL_TRIGGERED 0
+#define GTDT_TIMER_ACTIVE_LOW \
+ EFI_ACPI_6_3_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY
+#define GTDT_TIMER_ACTIVE_HIGH 0
+#define GTDT_TIMER_SAVE_CONTEXT \
+ EFI_ACPI_6_3_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY
+#define GTDT_TIMER_LOSE_CONTEXT 0
+
+#define N1SDP_GTDT_GTIMER_FLAGS (GTDT_TIMER_LOSE_CONTEXT | \
+ GTDT_TIMER_ACTIVE_LOW | \
+ GTDT_TIMER_LEVEL_TRIGGERED)
+
+// GT Block Timer Flags
+#define GTX_TIMER_EDGE_TRIGGERED \
+ EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE
+#define GTX_TIMER_LEVEL_TRIGGERED 0
+#define GTX_TIMER_ACTIVE_LOW \
+ EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY
+#define GTX_TIMER_ACTIVE_HIGH 0
+
+#define N1SDP_GTX_TIMER_FLAGS (GTX_TIMER_ACTIVE_HIGH | \
+ GTX_TIMER_LEVEL_TRIGGERED)
+
+#define GTX_TIMER_SECURE \
+ EFI_ACPI_6_3_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER
+#define GTX_TIMER_NON_SECURE 0
+#define GTX_TIMER_SAVE_CONTEXT \
+ EFI_ACPI_6_3_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY
+#define GTX_TIMER_LOSE_CONTEXT 0
+
+#define N1SDP_GTX_COMMON_FLAGS_S (GTX_TIMER_SAVE_CONTEXT | \
+ GTX_TIMER_SECURE)
+#define N1SDP_GTX_COMMON_FLAGS_NS (GTX_TIMER_SAVE_CONTEXT | \
+ GTX_TIMER_NON_SECURE)
+
+// Watchdog
+#define SBSA_WATCHDOG_EDGE_TRIGGERED \
+ EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE
+#define SBSA_WATCHDOG_LEVEL_TRIGGERED 0
+#define SBSA_WATCHDOG_ACTIVE_LOW \
+ EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY
+#define SBSA_WATCHDOG_ACTIVE_HIGH 0
+#define SBSA_WATCHDOG_SECURE \
+ EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_SECURE_TIMER
+#define SBSA_WATCHDOG_NON_SECURE 0
+
+#define N1SDP_SBSA_WATCHDOG_FLAGS (SBSA_WATCHDOG_NON_SECURE | \
+ SBSA_WATCHDOG_ACTIVE_HIGH | \
+ SBSA_WATCHDOG_LEVEL_TRIGGERED)
+
+#endif // PLATFORM_H_
--
2.17.1


[PATCH v5 7/7] Platform/ARM/N1Sdp: Enable ACPI tables and configuration manager

Khasim Mohammed
 

This patch enables ACPI tables and configuration manager for N1SDP

Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Signed-off-by: Khasim Syed Mohammed <khasim.mohammed@arm.com>
---
Platform/ARM/N1Sdp/Include/N1SdpAcpiHeader.h | 35 ++++++++++++++++++++
Platform/ARM/N1Sdp/N1SdpPlatform.dec | 1 +
Platform/ARM/N1Sdp/N1SdpPlatform.dsc | 10 ++++++
Platform/ARM/N1Sdp/N1SdpPlatform.fdf | 9 +++++
4 files changed, 55 insertions(+)
create mode 100644 Platform/ARM/N1Sdp/Include/N1SdpAcpiHeader.h

diff --git a/Platform/ARM/N1Sdp/Include/N1SdpAcpiHeader.h b/Platform/ARM/N1Sdp/Include/N1SdpAcpiHeader.h
new file mode 100644
index 0000000000..d81bdb3576
--- /dev/null
+++ b/Platform/ARM/N1Sdp/Include/N1SdpAcpiHeader.h
@@ -0,0 +1,35 @@
+/** @file
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef N1SDP_ACPI_HEADER_
+#define N1SDP_ACPI_HEADER_
+
+//
+// ACPI table information used to initialize tables.
+//
+#define EFI_ACPI_ARM_OEM_ID 'A','R','M','L','T','D' // OEMID 6 bytes long
+#define EFI_ACPI_ARM_OEM_TABLE_ID SIGNATURE_64('A','R','M','N','1','S','D','P') // OEM table id 8 bytes long
+#define EFI_ACPI_ARM_OEM_REVISION 0x20181101
+#define EFI_ACPI_ARM_CREATOR_ID SIGNATURE_32('A','R','M',' ')
+#define EFI_ACPI_ARM_CREATOR_REVISION 0x00000099
+
+// A macro to initialise the common header part of EFI ACPI tables as defined by
+// EFI_ACPI_DESCRIPTION_HEADER structure.
+#define ARM_ACPI_HEADER(Signature, Type, Revision) { \
+ Signature, /* UINT32 Signature */ \
+ sizeof (Type), /* UINT32 Length */ \
+ Revision, /* UINT8 Revision */ \
+ 0, /* UINT8 Checksum */ \
+ { EFI_ACPI_ARM_OEM_ID }, /* UINT8 OemId[6] */ \
+ EFI_ACPI_ARM_OEM_TABLE_ID, /* UINT64 OemTableId */ \
+ EFI_ACPI_ARM_OEM_REVISION, /* UINT32 OemRevision */ \
+ EFI_ACPI_ARM_CREATOR_ID, /* UINT32 CreatorId */ \
+ EFI_ACPI_ARM_CREATOR_REVISION /* UINT32 CreatorRevision */ \
+ }
+
+#endif /* N1SDP_ACPI_HEADER_ */
diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.dec b/Platform/ARM/N1Sdp/N1SdpPlatform.dec
index d56891b985..36123ddac0 100644
--- a/Platform/ARM/N1Sdp/N1SdpPlatform.dec
+++ b/Platform/ARM/N1Sdp/N1SdpPlatform.dec
@@ -22,6 +22,7 @@
#
################################################################################
[Includes.common]
+ Include # Root include for the pakage

[LibraryClasses]
ArmPlatformLib|Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLib.inf
diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.dsc b/Platform/ARM/N1Sdp/N1SdpPlatform.dsc
index f76b9eb0ce..7488bdc036 100644
--- a/Platform/ARM/N1Sdp/N1SdpPlatform.dsc
+++ b/Platform/ARM/N1Sdp/N1SdpPlatform.dsc
@@ -30,6 +30,8 @@
!include Platform/ARM/VExpressPkg/ArmVExpress.dsc.inc
!include MdePkg/MdeLibs.dsc.inc

+!include DynamicTablesPkg/DynamicTables.dsc.inc
+
[LibraryClasses.common]
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
@@ -159,6 +161,9 @@
gArmPlatformTokenSpaceGuid.PcdCoreCount|2
gArmPlatformTokenSpaceGuid.PcdClusterCount|2

+ # ACPI Table Version
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions|0x20
+
# Runtime Variable storage
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
@@ -218,6 +223,11 @@
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
}

+ # ACPI Support
+ MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+ MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+ Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf
+
# Platform driver
Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.inf

diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.fdf b/Platform/ARM/N1Sdp/N1SdpPlatform.fdf
index 6b097438ad..6ede2b7fc8 100644
--- a/Platform/ARM/N1Sdp/N1SdpPlatform.fdf
+++ b/Platform/ARM/N1Sdp/N1SdpPlatform.fdf
@@ -94,6 +94,15 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf

+ # ACPI Support
+ INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+
+ # Configuration Manager
+ INF Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf
+
+ # Dynamic Table fdf
+ !include DynamicTablesPkg/DynamicTables.fdf.inc
+
# Human Interface Support
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf

--
2.17.1


[PATCH v5 5/7] Platform/ARM/N1Sdp: Introduce platform specific asl tables

Khasim Mohammed
 

This patch creates Dsdt.asl, SsdtPci.asl and SsdtRemotePci.asl files
to provide the platform specific APCI table entries.

Three PCI root ports are available on N1Sdp, PCI0 is the default root port
PCI1 is the CCIX root port and PCI2 is the Remote host root port.

The Remote host specific entries are defined in a separate file
SsdtRemotePci.asl to avoid confusions with other PCI entries
and for better readability and understanding of interfaces.

Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Signed-off-by: Khasim Syed Mohammed <khasim.mohammed@arm.com>
Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
Signed-off-by: anukou01 <anurag.koul@arm.com>
Signed-off-by: Manoj Kumar <manoj.kumar3@arm.com>
---
.../AslTables/Dsdt.asl | 482 ++++++++++++++++++
.../AslTables/SsdtPci.asl | 252 +++++++++
.../AslTables/SsdtRemotePci.asl | 161 ++++++
3 files changed, 895 insertions(+)
create mode 100644 Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/AslTables/Dsdt.asl
create mode 100644 Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtPci.asl
create mode 100644 Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtRemotePci.asl

diff --git a/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/AslTables/Dsdt.asl b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/AslTables/Dsdt.asl
new file mode 100644
index 0000000000..818862cd75
--- /dev/null
+++ b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/AslTables/Dsdt.asl
@@ -0,0 +1,482 @@
+/** @file
+ Differentiated System Description Table Fields (DSDT)
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI for CoreSight 1.1, Platform Design Document
+ - ACPI for Arm Components 1.0, Platform Design Document
+
+**/
+
+#include "N1SdpAcpiHeader.h"
+#include "NeoverseN1Soc.h"
+
+#define ACPI_GRAPH_REV 0
+#define ACPI_GRAPH_UUID "ab02a46b-74c7-45a2-bd68-f7d344ef2153"
+
+#define CORESIGHT_GRAPH_UUID "3ecbc8b6-1d0e-4fb3-8107-e627f805c6cd"
+
+#define CS_LINK_MASTER 1
+#define CS_LINK_SLAVE 0
+
+#define DSD_CS_GRAPH_BEGIN(_nports) \
+ Package () { \
+ 1, \
+ ToUUID(CORESIGHT_GRAPH_UUID), \
+ _nports,
+
+#define DSD_CS_GRAPH_END \
+ }
+
+#define DSD_GRAPH_BEGIN(_nports) \
+ ToUUID(ACPI_GRAPH_UUID), \
+ Package() { \
+ ACPI_GRAPH_REV, \
+ 1, \
+ DSD_CS_GRAPH_BEGIN(_nports)
+
+#define DSD_GRAPH_END \
+ DSD_CS_GRAPH_END \
+ }
+
+#define DSD_PORTS_BEGIN(_nports) \
+ Name (_DSD, Package () { \
+ DSD_GRAPH_BEGIN(_nports)
+
+#define DSD_PORTS_END \
+ DSD_GRAPH_END \
+ })
+
+#define CS_PORT(_port, _rport, _rphandle, _dir) \
+ Package () { _port, _rport, _rphandle, _dir}
+
+#define CS_INPUT_PORT(_port, _rport, _rphandle) \
+ CS_PORT(_port, _rport, _rphandle, CS_LINK_SLAVE)
+
+#define CS_OUTPUT_PORT(_port, _rport, _rphandle) \
+ CS_PORT(_port, _rport, _rphandle, CS_LINK_MASTER)
+
+DefinitionBlock("Dsdt.aml", "DSDT", 1, "ARMLTD", "N1Sdp", EFI_ACPI_ARM_OEM_REVISION) {
+ Scope(_SB) {
+ Device(CP00) { // Ares-0: Cluster 0, Cpu 0
+ Name(_HID, "ACPI0007")
+ Name(_UID, 0)
+ Name(_STA, 0xF)
+ Device(ETM0) { // ETM on Cluster0 CPU0
+ Name (_HID, "ARMHC500")
+ Name (_CID, "ARMHC500")
+ Name (_CRS, ResourceTemplate() {
+ QWordMemory (
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdCsEtm0Base), // Min Base Address
+ FixedPcdGet64 (PcdCsEtm0MaxBase), // Max Base Address
+ 0, // Translate
+ FixedPcdGet32 (PcdCsComponentSize) // Length
+ )
+ })
+ DSD_PORTS_BEGIN(1)
+ CS_OUTPUT_PORT(0, 0, \_SB_.SFN0)
+ DSD_PORTS_END
+ } // ETM0
+ }
+
+ Device(CP01) { // Ares-1: Cluster 0, Cpu 1
+ Name(_HID, "ACPI0007")
+ Name(_UID, 1)
+ Name(_STA, 0xF)
+ Device(ETM1) { // ETM on Cluster0 CPU1
+ Name (_HID, "ARMHC500")
+ Name (_CID, "ARMHC500")
+ Name (_CRS, ResourceTemplate() {
+ QWordMemory (
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdCsEtm1Base), // Min Base Address
+ FixedPcdGet64 (PcdCsEtm1MaxBase), // Max Base Address
+ 0, // Translate
+ FixedPcdGet32 (PcdCsComponentSize) // Length
+ )
+ })
+ DSD_PORTS_BEGIN(1)
+ CS_OUTPUT_PORT(0, 1, \_SB_.SFN0)
+ DSD_PORTS_END
+ } // ETM1
+ }
+
+ Device(CP02) { // Ares-2: Cluster 1, Cpu 0
+ Name(_HID, "ACPI0007")
+ Name(_UID, 2)
+ Name(_STA, 0xF)
+ Device(ETM2) { // ETM on Cluster1 CPU0
+ Name (_HID, "ARMHC500")
+ Name (_CID, "ARMHC500")
+ Name (_CRS, ResourceTemplate() {
+ QWordMemory (
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdCsEtm2Base), // Min Base Address
+ FixedPcdGet64 (PcdCsEtm2MaxBase), // Max Base Address
+ 0, // Translate
+ FixedPcdGet32 (PcdCsComponentSize) // Length
+ )
+ })
+ DSD_PORTS_BEGIN(1)
+ CS_OUTPUT_PORT(0, 0, \_SB_.SFN1)
+ DSD_PORTS_END
+ } // ETM2
+ }
+
+ Device(CP03) { // Ares-3: Cluster 1, Cpu 1
+ Name(_HID, "ACPI0007")
+ Name(_UID, 3)
+ Name(_STA, 0xF)
+ Device(ETM3) { // ETM on Cluster0 CPU0
+ Name (_HID, "ARMHC500")
+ Name (_CID, "ARMHC500")
+ Name (_CRS, ResourceTemplate() {
+ QWordMemory (
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdCsEtm3Base), // Min Base Address
+ FixedPcdGet64 (PcdCsEtm3MaxBase), // Max Base Address
+ 0, // Translate
+ FixedPcdGet32 (PcdCsComponentSize) // Length
+ )
+ })
+
+ DSD_PORTS_BEGIN(1)
+ CS_OUTPUT_PORT(0, 1, \_SB_.SFN1)
+ DSD_PORTS_END
+ } // ETM3
+ }
+
+ Device(ETF0) {
+ Name(_HID, "ARMHC97C") // TMC
+ Name(_CID, "ARMHC97C") // TMC
+ Name(_CRS, ResourceTemplate() {
+ QWordMemory (
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdCsEtf0Base), // Min Base Address
+ FixedPcdGet64 (PcdCsEtf0MaxBase), // Max Base Address
+ 0, // Translate
+ FixedPcdGet32 (PcdCsComponentSize) // Length
+ )
+ })
+
+ DSD_PORTS_BEGIN(2)
+ CS_OUTPUT_PORT(0, 0, \_SB_.FUN),
+ CS_INPUT_PORT(0, 0, \_SB_.SFN0)
+ DSD_PORTS_END
+ } // ETF0
+
+ Device(ETF1) {
+ Name(_HID, "ARMHC97C") // TMC
+ Name(_CID, "ARMHC97C") // TMC
+ Name(_CRS, ResourceTemplate() {
+ QWordMemory (
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdCsEtf1Base), // Min Base Address
+ FixedPcdGet64 (PcdCsEtf1MaxBase), // Max Base Address
+ 0, // Translate
+ FixedPcdGet32 (PcdCsComponentSize) // Length
+ )
+ })
+
+ DSD_PORTS_BEGIN(2)
+ CS_OUTPUT_PORT(0, 1, \_SB_.FUN),
+ CS_INPUT_PORT(0, 0, \_SB_.SFN1)
+ DSD_PORTS_END
+ } // ETF1
+
+ Device(ETF2) {
+ Name(_HID, "ARMHC97C") // TMC
+ Name(_CID, "ARMHC97C") // TMC
+ Name(_CRS, ResourceTemplate() {
+ QWordMemory (
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdCsEtf2Base), // Min Base Address
+ FixedPcdGet64 (PcdCsEtf2MaxBase), // Max Base Address
+ 0, // Translate
+ FixedPcdGet32 (PcdCsComponentSize) // Length
+ )
+ })
+
+ DSD_PORTS_BEGIN(2)
+ CS_OUTPUT_PORT(0, 5, \_SB_.MFUN),
+ CS_INPUT_PORT(0, 0, \_SB_.STM0)
+ DSD_PORTS_END
+ } // ETF2
+
+ Device(FUN) {
+ Name(_HID, "ARMHC9FF")
+ Name(_CID, "ARMHC9FF")
+ Name(_CRS, ResourceTemplate() {
+ QWordMemory (
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdCsFunnel0Base), // Min Base Address
+ FixedPcdGet64 (PcdCsFunnel0MaxBase), // Max Base Address
+ 0, // Translate
+ FixedPcdGet32 (PcdCsComponentSize) // Length
+ )
+ })
+ DSD_PORTS_BEGIN(3)
+ CS_OUTPUT_PORT(0, 0, \_SB_.MFUN),
+ CS_INPUT_PORT(0, 0, \_SB_.ETF0),
+ CS_INPUT_PORT(1, 0, \_SB_.ETF1)
+ DSD_PORTS_END
+ } // FUN
+
+ Device(STM0) {
+ Name(_HID, "ARMHC502") // STM
+ Name(_CID, "ARMHC502")
+ Name(_CRS, ResourceTemplate() {
+ QWordMemory (
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdCsStmBase), // Min Base Address
+ FixedPcdGet64 (PcdCsStmMaxBase), // Max Base Address
+ 0, // Translate
+ FixedPcdGet32 (PcdCsComponentSize) // Length
+ )
+ Memory32Fixed(ReadWrite,
+ FixedPcdGet32 (PcdCsStmStimulusBase),
+ FixedPcdGet32 (PcdCsStmStimulusSize))
+ })
+
+ DSD_PORTS_BEGIN(1)
+ CS_OUTPUT_PORT(0, 0, \_SB_.ETF2)
+ DSD_PORTS_END
+ }
+
+ Device(MFUN) { // Master Funnel
+ Name(_HID, "ARMHC9FF") // Funnel
+ Name(_CID, "ARMHC9FF") // Funnel
+ Name(_CRS, ResourceTemplate() {
+ QWordMemory (
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdCsFunnel1Base), // Min Base Address
+ FixedPcdGet64 (PcdCsFunnel1MaxBase), // Max Base Address
+ 0, // Translate
+ FixedPcdGet32 (PcdCsComponentSize) // Length
+ )
+ })
+
+ DSD_PORTS_BEGIN(3)
+ CS_OUTPUT_PORT(0, 0, \_SB_.REP),
+ CS_INPUT_PORT(0, 0, \_SB_.FUN),
+ CS_INPUT_PORT(5, 0, \_SB_.ETF2)
+ DSD_PORTS_END
+ } // MFUN
+
+ Device(REP) {
+ Name(_HID, "ARMHC98D") // Replicator
+ Name(_CID, "ARMHC98D") // Replicator
+ Name(_CRS, ResourceTemplate() {
+ QWordMemory (
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdCsReplicatorBase), // Min Base Address
+ FixedPcdGet64 (PcdCsReplicatorMaxBase), // Max Base Address
+ 0, // Translate
+ FixedPcdGet32 (PcdCsComponentSize) // Length
+ )
+ })
+
+ DSD_PORTS_BEGIN(3)
+ CS_OUTPUT_PORT(0, 0, \_SB_.TPIU),
+ CS_OUTPUT_PORT(1, 0, \_SB_.ETR),
+ CS_INPUT_PORT(0, 0, \_SB_.MFUN)
+ DSD_PORTS_END
+ } // REP
+
+ Device(TPIU) {
+ Name(_HID, "ARMHC979") // TPIU
+ Name(_CID, "ARMHC979") // TPIU
+ Name(_CRS, ResourceTemplate() {
+ QWordMemory (
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdCsTpiuBase), // Min Base Address
+ FixedPcdGet64 (PcdCsTpiuMaxBase), // Max Base Address
+ 0, // Translate
+ FixedPcdGet32 (PcdCsComponentSize) // Length
+ )
+ })
+
+ DSD_PORTS_BEGIN(1)
+ CS_INPUT_PORT(0, 0, \_SB_.REP)
+ DSD_PORTS_END
+ } // TPIU
+
+ Device(ETR) {
+ Name(_HID, "ARMHC97C") // TMC
+ Name(_CID, "ARMHC97C") // TMC
+ Name(_CCA, 0) // The ETR on this platform is not coherent
+ Name(_CRS, ResourceTemplate() {
+ QWordMemory (
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdCsEtrBase), // Min Base Address
+ FixedPcdGet64 (PcdCsEtrMaxBase), // Max Base Address
+ 0, // Translate
+ FixedPcdGet32 (PcdCsComponentSize) // Length
+ )
+ })
+
+ Name(_DSD, Package() {
+ DSD_GRAPH_BEGIN(1)
+ CS_INPUT_PORT(0, 1, \_SB_.REP)
+ DSD_GRAPH_END,
+
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package() {
+ Package(2) {"arm,scatter-gather", 1}
+ }
+ })
+
+ } // ETR
+
+ Device(SFN0) { // Static Funnel 0
+ Name(_HID, "ARMHC9FE") // Funnel
+ Name(_CID, "ARMHC9FE") // Funnel
+
+ DSD_PORTS_BEGIN(3)
+ CS_OUTPUT_PORT(0, 0, \_SB_.ETF0),
+ CS_INPUT_PORT(0, 0, \_SB_.CP00.ETM0),
+ CS_INPUT_PORT(1, 0, \_SB_.CP01.ETM1)
+ DSD_PORTS_END
+ } // SFN0
+
+ Device(SFN1) { // Static Funnel 1
+ Name(_HID, "ARMHC9FE") // Funnel
+ Name(_CID, "ARMHC9FE") // Funnel
+
+ DSD_PORTS_BEGIN(3)
+ CS_OUTPUT_PORT(0, 0, \_SB_.ETF1),
+ CS_INPUT_PORT(0, 0, \_SB_.CP02.ETM2),
+ CS_INPUT_PORT(1, 0, \_SB_.CP03.ETM3)
+ DSD_PORTS_END
+ } // SFN1
+
+ Device(CMN6) {
+ Name(_HID, "ARMHC600")
+
+ Name(_CRS, ResourceTemplate () {
+ // Region location is platform specific
+ // Other name(s) of this region: PERIPHBASE
+ QWordMemory (
+ ResourceConsumer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ NonCacheable,
+ ReadWrite,
+ 0x00000000,
+ 0x50000000,
+ 0x5FFFFFFF,
+ 0x00000000,
+ 0x10000000,
+ ,
+ ,
+ CFGR
+ )
+
+ // Sub-region location is platform specific
+ // Other name(s) of this region: ROOTNODEBASE
+ QWordMemory (
+ ResourceConsumer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ NonCacheable,
+ ReadWrite,
+ 0x00000000,
+ 0x50D00000,
+ 0x50D03FFF,
+ 0x00000000,
+ 0x00004000,
+ ,
+ ,
+ ROOT
+ )
+
+ // CMN600_INTREQPMU_DTC0
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { 78 }
+ })
+ }
+ } // Scope(_SB)
+}
diff --git a/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtPci.asl b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtPci.asl
new file mode 100644
index 0000000000..cdbd42c154
--- /dev/null
+++ b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtPci.asl
@@ -0,0 +1,252 @@
+/** @file
+ Secondary System Description Table (SSDT)
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI for CoreSight 1.1, Platform Design Document
+ - ACPI for Arm Components 1.0, Platform Design Document
+
+**/
+
+#include "N1SdpAcpiHeader.h"
+
+/*
+ See ACPI 6.4 Section 6.2.13
+
+ There are two ways that _PRT can be used.
+
+ In the first model, a PCI Link device is used to provide additional
+ configuration information such as whether the interrupt is Level or
+ Edge triggered, it is active High or Low, Shared or Exclusive, etc.
+
+ In the second model, the PCI interrupts are hardwired to specific
+ interrupt inputs on the interrupt controller and are not
+ configurable. In this case, the Source field in _PRT does not
+ reference a device, but instead contains the value zero, and the
+ Source Index field contains the global system interrupt to which the
+ PCI interrupt is hardwired.
+
+ We use the first model with link indirection to set the correct
+ interrupt type as PCI defaults (Level Triggered, Active Low) are not
+ compatible with GICv2.
+*/
+#define LNK_DEVICE(Unique_Id, Link_Name, irq) \
+ Device(Link_Name) { \
+ Name(_HID, EISAID("PNP0C0F")) \
+ Name(_UID, Unique_Id) \
+ Name(_PRS, ResourceTemplate() { \
+ Interrupt(ResourceProducer, Level, ActiveHigh, Exclusive) { irq } \
+ }) \
+ Method (_CRS, 0) { Return (_PRS) } \
+ Method (_SRS, 1) { } \
+ Method (_DIS) { } \
+}
+
+#define PRT_ENTRY(Address, Pin, Link) \
+ Package (4) { \
+ Address, /* uses the same format as _ADR */ \
+ Pin, /* The PCI pin number of the device (0-INTA, 1-INTB, 2-INTC, 3-INTD) */ \
+ Link, /* Interrupt allocated via Link device */ \
+ Zero /* global system interrupt number (no used) */ \
+}
+
+/*
+ See Reference [1] 6.1.1
+ "High word-Device #, Low word-Function #. (for example, device 3,
+ function 2 is 0x00030002). To refer to all the functions on a device #,
+ use a function number of FFFF)."
+*/
+#define ROOT_PRT_ENTRY(Pin, Link) PRT_ENTRY(0x0000FFFF, Pin, Link) // Device 0 for Bridge.
+
+DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "N1Sdp",
+ EFI_ACPI_ARM_OEM_REVISION)
+{
+ Scope (_SB) {
+
+ // PCI Root Complex
+ LNK_DEVICE(1, LNKA, 201)
+ LNK_DEVICE(2, LNKB, 202)
+ LNK_DEVICE(3, LNKC, 203)
+ LNK_DEVICE(4, LNKD, 204)
+ LNK_DEVICE(5, LNKE, 233)
+ LNK_DEVICE(6, LNKF, 234)
+ LNK_DEVICE(7, LNKG, 235)
+ LNK_DEVICE(8, LNKH, 236)
+
+ // PCI Root Complex
+ Device(PCI0) {
+ Name (_HID, EISAID("PNP0A08")) // PCI Express Root Bridge
+ Name (_CID, EISAID("PNP0A03")) // Compatible PCI Root Bridge
+ Name (_SEG, Zero) // PCI Segment Group number
+ Name (_BBN, Zero) // PCI Base Bus Number
+ Name (_CCA, 1) // Cache Coherency Attribute
+
+ // Root Complex 0
+ Device (RP0) {
+ Name(_ADR, 0xF0000000) // Dev 0, Func 0
+ }
+
+ // PCI Routing Table
+ Name(_PRT, Package() {
+ ROOT_PRT_ENTRY(0, LNKA), // INTA
+ ROOT_PRT_ENTRY(1, LNKB), // INTB
+ ROOT_PRT_ENTRY(2, LNKC), // INTC
+ ROOT_PRT_ENTRY(3, LNKD), // INTD
+ })
+
+ // Root complex resources
+ Method (_CRS, 0, Serialized) {
+ Name (RBUF, ResourceTemplate () {
+ WordBusNumber ( // Bus numbers assigned to this root
+ ResourceProducer,
+ MinFixed,
+ MaxFixed,
+ PosDecode,
+ 0, // AddressGranularity
+ FixedPcdGet32 (PcdPcieBusMin), // AddressMinimum - Minimum Bus Number
+ FixedPcdGet32 (PcdPcieBusMax), // AddressMaximum - Maximum Bus Number
+ 0, // AddressTranslation - Set to 0
+ FixedPcdGet32 (PcdPcieBusCount) // RangeLength - Number of Busses
+ )
+
+ DWordMemory ( // 32-bit BAR Windows
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet32 (PcdPcieMmio32Base), // Min Base Address
+ FixedPcdGet32 (PcdPcieMmio32MaxBase), // Max Base Address
+ FixedPcdGet32 (PcdPcieMmio32Translation), // Translate
+ FixedPcdGet32 (PcdPcieMmio32Size) // Length
+ )
+
+ QWordMemory ( // 64-bit BAR Windows
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdPcieMmio64Base), // Min Base Address
+ FixedPcdGet64 (PcdPcieMmio64MaxBase), // Max Base Address
+ FixedPcdGet64 (PcdPcieMmio64Translation), // Translate
+ FixedPcdGet64 (PcdPcieMmio64Size) // Length
+ )
+
+ DWordIo ( // IO window
+ ResourceProducer,
+ MinFixed,
+ MaxFixed,
+ PosDecode,
+ EntireRange,
+ 0x00000000, // Granularity
+ FixedPcdGet32 (PcdPcieIoBase), // Min Base Address
+ FixedPcdGet32 (PcdPcieIoMaxBase), // Max Base Address
+ FixedPcdGet32 (PcdPcieIoTranslation), // Translate
+ FixedPcdGet32 (PcdPcieIoSize), // Length
+ ,
+ ,
+ ,
+ TypeTranslation
+ )
+ }) // Name(RBUF)
+
+ Return (RBUF)
+ } // Method (_CRS)
+ }
+
+ // CCIX Root Complex
+ Device(PCI1) {
+ Name (_HID, EISAID("PNP0A08")) // PCI Express Root Bridge
+ Name (_CID, EISAID("PNP0A03")) // Compatible PCI Root Bridge
+ Name (_SEG, 1) // PCI Segment Group number
+ Name (_BBN, Zero) // PCI Base Bus Number
+ Name (_CCA, 1) // Cache Coherency Attribute
+
+ // Root Complex 1
+ Device (RP1) {
+ Name(_ADR, 0xF0000000) // Dev 0, Func 0
+ }
+
+ // PCI Routing Table
+ Name(_PRT, Package() {
+ ROOT_PRT_ENTRY(0, LNKE), // INTA
+ ROOT_PRT_ENTRY(1, LNKF), // INTB
+ ROOT_PRT_ENTRY(2, LNKG), // INTC
+ ROOT_PRT_ENTRY(3, LNKH), // INTD
+ })
+
+ // Root complex resources
+ Method (_CRS, 0, Serialized) {
+ Name (RBUF, ResourceTemplate () {
+ WordBusNumber ( // Bus numbers assigned to this root
+ ResourceProducer,
+ MinFixed,
+ MaxFixed,
+ PosDecode,
+ 0, // AddressGranularity
+ FixedPcdGet32 (PcdCcixBusMin), // AddressMinimum - Minimum Bus Number
+ FixedPcdGet32 (PcdCcixBusMax), // AddressMaximum - Maximum Bus Number
+ 0, // AddressTranslation - Set to 0
+ FixedPcdGet32 (PcdCcixBusCount) // RangeLength - Number of Busses
+ )
+
+ DWordMemory ( // 32-bit BAR Windows
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet32 (PcdCcixMmio32Base), // Min Base Address
+ FixedPcdGet32 (PcdCcixMmio32MaxBase), // Max Base Address
+ FixedPcdGet32 (PcdCcixMmio32Translation), // Translate
+ FixedPcdGet32 (PcdCcixMmio32Size) // Length
+ )
+
+ QWordMemory ( // 64-bit BAR Windows
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdCcixMmio64Base), // Min Base Address
+ FixedPcdGet64 (PcdCcixMmio64MaxBase), // Max Base Address
+ FixedPcdGet64 (PcdCcixMmio64Translation), // Translate
+ FixedPcdGet64 (PcdCcixMmio64Size) // Length
+ )
+
+ DWordIo ( // IO window
+ ResourceProducer,
+ MinFixed,
+ MaxFixed,
+ PosDecode,
+ EntireRange,
+ 0x00000000, // Granularity
+ FixedPcdGet32 (PcdCcixIoBase), // Min Base Address
+ FixedPcdGet32 (PcdCcixIoMaxBase), // Max Base Address
+ FixedPcdGet32 (PcdCcixIoTranslation), // Translate
+ FixedPcdGet32 (PcdCcixIoSize), // Length
+ ,
+ ,
+ ,
+ TypeTranslation
+ )
+ }) // Name(RBUF)
+
+ Return (RBUF)
+ } // Method (_CRS)
+ }
+
+ }
+}
diff --git a/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtRemotePci.asl b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtRemotePci.asl
new file mode 100644
index 0000000000..b6bec7c106
--- /dev/null
+++ b/Platform/ARM/N1Sdp/ConfigurationManager/ConfigurationManagerDxe/AslTables/SsdtRemotePci.asl
@@ -0,0 +1,161 @@
+/** @file
+ Secondary System Description Table (SSDT)
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI for CoreSight 1.1, Platform Design Document
+ - ACPI for Arm Components 1.0, Platform Design Document
+
+**/
+
+#include "N1SdpAcpiHeader.h"
+
+/*
+ See ACPI 6.4 Section 6.2.13
+
+ There are two ways that _PRT can be used.
+
+ In the first model, a PCI Link device is used to provide additional
+ configuration information such as whether the interrupt is Level or
+ Edge triggered, it is active High or Low, Shared or Exclusive, etc.
+
+ In the second model, the PCI interrupts are hardwired to specific
+ interrupt inputs on the interrupt controller and are not
+ configurable. In this case, the Source field in _PRT does not
+ reference a device, but instead contains the value zero, and the
+ Source Index field contains the global system interrupt to which the
+ PCI interrupt is hardwired.
+
+ We use the first model with link indirection to set the correct
+ interrupt type as PCI defaults (Level Triggered, Active Low) are not
+ compatible with GICv2.
+*/
+#define LNK_DEVICE(Unique_Id, Link_Name, irq) \
+ Device(Link_Name) { \
+ Name(_HID, EISAID("PNP0C0F")) \
+ Name(_UID, Unique_Id) \
+ Name(_PRS, ResourceTemplate() { \
+ Interrupt(ResourceProducer, Level, ActiveHigh, Exclusive) { irq } \
+ }) \
+ Method (_CRS, 0) { Return (_PRS) } \
+ Method (_SRS, 1) { } \
+ Method (_DIS) { } \
+}
+
+#define PRT_ENTRY(Address, Pin, Link) \
+ Package (4) { \
+ Address, /* uses the same format as _ADR */ \
+ Pin, /* The PCI pin number of the device (0-INTA, 1-INTB, 2-INTC, 3-INTD) */ \
+ Link, /* Interrupt allocated via Link device */ \
+ Zero /* global system interrupt number (no used) */ \
+}
+
+/*
+ See Reference [1] 6.1.1
+ "High word-Device #, Low word-Function #. (for example, device 3,
+ function 2 is 0x00030002). To refer to all the functions on a device #,
+ use a function number of FFFF)."
+*/
+#define ROOT_PRT_ENTRY(Pin, Link) PRT_ENTRY(0x0000FFFF, Pin, Link) // Device 0 for Bridge.
+
+DefinitionBlock("SsdtRemotePci.aml", "SSDT", 1, "ARMLTD", "N1Sdp",
+ EFI_ACPI_ARM_OEM_REVISION)
+{
+ Scope (_SB) {
+
+ // Remote PCI Root Complex
+ LNK_DEVICE(9, LNKI, 681)
+ LNK_DEVICE(10, LNKJ, 682)
+ LNK_DEVICE(11, LNKK, 683)
+ LNK_DEVICE(12, LNKL, 684)
+
+ //Remote PCIe root complex
+ Device(PCI2) {
+ Name (_HID, EISAID("PNP0A08")) // PCI Express Root Bridge
+ Name (_CID, EISAID("PNP0A03")) // Compatible PCI Root Bridge
+ Name (_SEG, 2) // PCI Segment Group number
+ Name (_BBN, Zero) // PCI Base Bus Number
+ Name (_CCA, 1) // Cache Coherency Attribute
+
+ // Remote Root Complex 0
+ Device (RP0) {
+ Name(_ADR, 0xF0000000) // Dev 0, Func 0
+ }
+
+ // PCI Routing Table
+ Name(_PRT, Package() {
+ ROOT_PRT_ENTRY(0, LNKI), // INTA
+ ROOT_PRT_ENTRY(1, LNKJ), // INTB
+ ROOT_PRT_ENTRY(2, LNKK), // INTC
+ ROOT_PRT_ENTRY(3, LNKL), // INTD
+ })
+
+ // Root complex resources
+ Method (_CRS, 0, Serialized) {
+ Name (RBUF, ResourceTemplate () {
+ WordBusNumber ( // Bus numbers assigned to this root
+ ResourceProducer,
+ MinFixed,
+ MaxFixed,
+ PosDecode,
+ 0, // AddressGranularity
+ FixedPcdGet32 (PcdPcieBusMin), // AddressMinimum - Minimum Bus Number
+ FixedPcdGet32 (PcdPcieBusMax), // AddressMaximum - Maximum Bus Number
+ 0, // AddressTranslation - Set to 0
+ FixedPcdGet32 (PcdPcieBusCount) // RangeLength - Number of Busses
+ )
+
+ QWordMemory ( // 32-bit BAR Windows
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet32 (PcdPcieMmio32Base), // Min Base Address
+ FixedPcdGet32 (PcdPcieMmio32MaxBase), // Max Base Address
+ FixedPcdGet32 (PcdRemotePcieMmio32Translation), // Translate
+ FixedPcdGet32 (PcdPcieMmio32Size) // Length
+ )
+
+ QWordMemory ( // 64-bit BAR Windows
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ FixedPcdGet64 (PcdPcieMmio64Base), // Min Base Address
+ FixedPcdGet64 (PcdPcieMmio64MaxBase), // Max Base Address
+ FixedPcdGet64 (PcdRemotePcieMmio64Translation), // Translate
+ FixedPcdGet64 (PcdPcieMmio64Size) // Length
+ )
+
+ QWordIo ( // IO window
+ ResourceProducer,
+ MinFixed,
+ MaxFixed,
+ PosDecode,
+ EntireRange,
+ 0x00000000, // Granularity
+ FixedPcdGet32 (PcdPcieIoBase), // Min Base Address
+ FixedPcdGet32 (PcdPcieIoMaxBase), // Max Base Address
+ FixedPcdGet64 (PcdRemotePcieIoTranslation), // Translate
+ FixedPcdGet32 (PcdPcieIoSize), // Length
+ ,
+ ,
+ ,
+ TypeTranslation
+ )
+ }) // Name(RBUF)
+
+ Return (RBUF)
+ } // Method (_CRS)
+ }
+ }
+}
--
2.17.1


[PATCH v5 2/7] Silicon/ARM/NeoverseN1Soc: Define new PCDs and configure memory map

Khasim Mohammed
 

This patch introduces new PCDs required to enable
chip to chip interface and corresponding memory map is updated.

Signed-off-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
Signed-off-by: Khasim Syed Mohammed <khasim.mohammed@arm.com>
---
.../Library/PlatformLib/PlatformLib.inf | 28 +++++--
.../Library/PlatformLib/PlatformLibMem.c | 84 ++++++++++++++++---
Silicon/ARM/NeoverseN1Soc/NeoverseN1Soc.dec | 35 +++++++-
3 files changed, 125 insertions(+), 22 deletions(-)

diff --git a/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLib.inf b/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLib.inf
index 166c9e0444..8e2154aadf 100644
--- a/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLib.inf
+++ b/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLib.inf
@@ -1,6 +1,7 @@
## @file
+# Platform Library for N1Sdp.
#
-# Copyright (c) 2018-2020, ARM Limited. All rights reserved.
+# Copyright (c) 2018-2021, ARM Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -29,13 +30,17 @@
AArch64/Helper.S | GCC

[FixedPcd]
- gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
-
- gArmTokenSpaceGuid.PcdSystemMemoryBase
- gArmTokenSpaceGuid.PcdSystemMemorySize
- gArmTokenSpaceGuid.PcdArmPrimaryCore
- gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
-
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixBusMax
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixBusMin
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixExpressBaseAddress
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio32Base
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio32Size
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio64Base
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio64Size
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixRootPortConfigBaseAddress
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixRootPortConfigBaseSize
+ gArmNeoverseN1SocTokenSpaceGuid.PcdDramBlock2Base
+ gArmNeoverseN1SocTokenSpaceGuid.PcdExtMemorySpace
gArmNeoverseN1SocTokenSpaceGuid.PcdPcieBusMax
gArmNeoverseN1SocTokenSpaceGuid.PcdPcieBusMin
gArmNeoverseN1SocTokenSpaceGuid.PcdPcieMmio32Base
@@ -45,7 +50,12 @@
gArmNeoverseN1SocTokenSpaceGuid.PcdPcieRootPortConfigBaseAddress
gArmNeoverseN1SocTokenSpaceGuid.PcdPcieRootPortConfigBaseSize

- gArmNeoverseN1SocTokenSpaceGuid.PcdDramBlock2Base
+ gArmTokenSpaceGuid.PcdArmPrimaryCore
+ gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress

[Guids]
gEfiHobListGuid ## CONSUMES ## SystemTable
diff --git a/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLibMem.c b/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLibMem.c
index f9b3d03753..1c4a445c5e 100644
--- a/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLibMem.c
+++ b/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLibMem.c
@@ -1,9 +1,9 @@
/** @file
-*
-* Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
-*
-* SPDX-License-Identifier: BSD-2-Clause-Patent
-*
+
+ Copyright (c) 2018 - 2021, ARM Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
**/

#include <Library/ArmPlatformLib.h>
@@ -13,7 +13,7 @@
#include <NeoverseN1Soc.h>

// The total number of descriptors, including the final "end-of-table" descriptor.
-#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 13
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 19

/**
Returns the Virtual Memory Map of the platform.
@@ -21,21 +21,23 @@
This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU
on your platform.

- @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing
- a Physical-to-Virtual Memory mapping. This array
- must be ended by a zero-filled entry.
+ @param[in] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing
+ a Physical-to-Virtual Memory mapping. This array
+ must be ended by a zero-filled entry.
**/
VOID
ArmPlatformGetVirtualMemoryMap (
IN ARM_MEMORY_REGION_DESCRIPTOR **VirtualMemoryMap
)
{
- UINTN Index = 0;
+ UINTN Index;
ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable;
EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
NEOVERSEN1SOC_PLAT_INFO *PlatInfo;
UINT64 DramBlock2Size;
+ UINT64 RemoteDdrSize;

+ Index = 0;
PlatInfo = (NEOVERSEN1SOC_PLAT_INFO *)NEOVERSEN1SOC_PLAT_INFO_STRUCT_BASE;
DramBlock2Size = ((UINT64)(PlatInfo->LocalDdrSize -
NEOVERSEN1SOC_DRAM_BLOCK1_SIZE / SIZE_1GB) *
@@ -55,6 +57,24 @@ ArmPlatformGetVirtualMemoryMap (
FixedPcdGet64 (PcdDramBlock2Base),
DramBlock2Size);

+ if (PlatInfo->MultichipMode == 1) {
+ RemoteDdrSize = ((PlatInfo->RemoteDdrSize - 2) * SIZE_1GB);
+
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ ResourceAttributes,
+ FixedPcdGet64 (PcdExtMemorySpace) + FixedPcdGet64 (PcdSystemMemoryBase),
+ PcdGet64 (PcdSystemMemorySize)
+ );
+
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ ResourceAttributes,
+ FixedPcdGet64 (PcdExtMemorySpace) + FixedPcdGet64 (PcdDramBlock2Base),
+ RemoteDdrSize
+ );
+ }
+
ASSERT (VirtualMemoryMap != NULL);
Index = 0;

@@ -114,6 +134,32 @@ ArmPlatformGetVirtualMemoryMap (
VirtualMemoryTable[Index].Length = PcdGet64 (PcdPcieMmio64Size);
VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;

+ // CCIX RC Configuration Space
+ VirtualMemoryTable[++Index].PhysicalBase = PcdGet32 (PcdCcixRootPortConfigBaseAddress);
+ VirtualMemoryTable[Index].VirtualBase = PcdGet32 (PcdCcixRootPortConfigBaseAddress);
+ VirtualMemoryTable[Index].Length = PcdGet32 (PcdCcixRootPortConfigBaseSize);
+ VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+ // CCIX ECAM Configuration Space
+ VirtualMemoryTable[++Index].PhysicalBase = PcdGet32 (PcdCcixExpressBaseAddress);
+ VirtualMemoryTable[Index].VirtualBase = PcdGet32 (PcdCcixExpressBaseAddress);
+ VirtualMemoryTable[Index].Length = (FixedPcdGet32 (PcdCcixBusMax) -
+ FixedPcdGet32 (PcdCcixBusMin) + 1) *
+ SIZE_1MB;
+ VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+ // CCIX MMIO32 Memory Space
+ VirtualMemoryTable[++Index].PhysicalBase = PcdGet32 (PcdCcixMmio32Base);
+ VirtualMemoryTable[Index].VirtualBase = PcdGet32 (PcdCcixMmio32Base);
+ VirtualMemoryTable[Index].Length = PcdGet32 (PcdCcixMmio32Size);
+ VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+ // CCIX MMIO64 Memory Space
+ VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdCcixMmio64Base);
+ VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdCcixMmio64Base);
+ VirtualMemoryTable[Index].Length = PcdGet64 (PcdCcixMmio64Size);
+ VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
// SubSystem Pheripherals - UART0
VirtualMemoryTable[++Index].PhysicalBase = NEOVERSEN1SOC_UART0_BASE;
VirtualMemoryTable[Index].VirtualBase = NEOVERSEN1SOC_UART0_BASE;
@@ -138,6 +184,24 @@ ArmPlatformGetVirtualMemoryMap (
VirtualMemoryTable[Index].Length = NEOVERSEN1SOC_EXP_PERIPH_BASE0_SZ;
VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;

+ if (PlatInfo->MultichipMode == 1) {
+ //Remote DDR (2GB)
+ VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdExtMemorySpace) +
+ PcdGet64 (PcdSystemMemoryBase);
+ VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdExtMemorySpace) +
+ PcdGet64 (PcdSystemMemoryBase);
+ VirtualMemoryTable[Index].Length = PcdGet64 (PcdSystemMemorySize);
+ VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH;
+
+ //Remote DDR
+ VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdExtMemorySpace) +
+ PcdGet64 (PcdDramBlock2Base);
+ VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdExtMemorySpace) +
+ PcdGet64 (PcdDramBlock2Base);
+ VirtualMemoryTable[Index].Length = RemoteDdrSize;
+ VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH;
+ }
+
// End of Table
VirtualMemoryTable[++Index].PhysicalBase = 0;
VirtualMemoryTable[Index].VirtualBase = 0;
diff --git a/Silicon/ARM/NeoverseN1Soc/NeoverseN1Soc.dec b/Silicon/ARM/NeoverseN1Soc/NeoverseN1Soc.dec
index 54b793a937..eea2d58402 100644
--- a/Silicon/ARM/NeoverseN1Soc/NeoverseN1Soc.dec
+++ b/Silicon/ARM/NeoverseN1Soc/NeoverseN1Soc.dec
@@ -1,5 +1,7 @@
+## @file
+# Describes the entire platform configuration.
#
-# Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
+# Copyright (c) 2018 - 2021, ARM Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -33,8 +35,8 @@
gArmNeoverseN1SocTokenSpaceGuid.PcdPcieBusMax|17|UINT32|0x00000005
gArmNeoverseN1SocTokenSpaceGuid.PcdPcieBusMin|0|UINT32|0x00000006
gArmNeoverseN1SocTokenSpaceGuid.PcdPcieIoBase|0x0|UINT32|0x00000007
- gArmNeoverseN1SocTokenSpaceGuid.PcdPcieIoMaxBase|0x00FFFFFF|UINT32|0x00000008
- gArmNeoverseN1SocTokenSpaceGuid.PcdPcieIoSize|0x01000000|UINT32|0x00000009
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieIoMaxBase|0x001FFFF|UINT32|0x00000008
+ gArmNeoverseN1SocTokenSpaceGuid.PcdPcieIoSize|0x020000|UINT32|0x00000009
gArmNeoverseN1SocTokenSpaceGuid.PcdPcieIoTranslation|0x75200000|UINT32|0x0000000A
gArmNeoverseN1SocTokenSpaceGuid.PcdPcieMmio32Base|0x71200000|UINT32|0x0000000B
gArmNeoverseN1SocTokenSpaceGuid.PcdPcieMmio32MaxBase|0x751FFFFF|UINT32|0x0000000C
@@ -44,3 +46,30 @@
gArmNeoverseN1SocTokenSpaceGuid.PcdPcieMmio64MaxBase|0x28FFFFFFFF|UINT64|0x00000010
gArmNeoverseN1SocTokenSpaceGuid.PcdPcieMmio64Size|0x2000000000|UINT64|0x00000011
gArmNeoverseN1SocTokenSpaceGuid.PcdPcieMmio64Translation|0x0|UINT64|0x00000012
+
+ # CCIX
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixBusCount|18|UINT32|0x00000016
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixBusMax|17|UINT32|0x00000017
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixBusMin|0|UINT32|0x00000018
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixExpressBaseAddress|0x68000000|UINT32|0x00000019
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixIoBase|0x0|UINT32|0x0000001A
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixIoMaxBase|0x01FFFF|UINT32|0x0000001B
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixIoSize|0x020000|UINT32|0x0000001C
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixIoTranslation|0x6D200000|UINT32|0x00000001D
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio32Base|0x69200000|UINT32|0x0000001E
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio32MaxBase|0x6D1FFFFF|UINT32|0x00000001F
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio32Size|0x04000000|UINT32|0x00000020
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio32Translation|0x0|UINT32|0x00000021
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio64Base|0x2900000000|UINT64|0x00000022
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio64MaxBase|0x48FFFFFFFF|UINT64|0x00000023
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio64Size|0x2000000000|UINT64|0x00000024
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixMmio64Translation|0x0|UINT64|0x00000025
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixRootPortConfigBaseAddress|0x62000000|UINT32|0x00000026
+ gArmNeoverseN1SocTokenSpaceGuid.PcdCcixRootPortConfigBaseSize|0x00001000|UINT32|0x00000027
+
+ gArmNeoverseN1SocTokenSpaceGuid.PcdExtMemorySpace|0x40000000000|UINT64|0x00000029
+
+ # Remote Chip PCIe
+ gArmNeoverseN1SocTokenSpaceGuid.PcdRemotePcieIoTranslation|0x40075200000|UINT64|0x0000004A
+ gArmNeoverseN1SocTokenSpaceGuid.PcdRemotePcieMmio32Translation|0x40000000000|UINT64|0x0000004B
+ gArmNeoverseN1SocTokenSpaceGuid.PcdRemotePcieMmio64Translation|0x40000000000|UINT64|0x0000004C
--
2.17.1


[PATCH v5 4/7] Platform/ARM/N1Sdp: Enable N1Sdp platform specific configurations

Khasim Mohammed
 

This patch adds PCDs and updates the fdf file for N1Sdp
platform specific configurations.

Signed-off-by: Deepak Pandey <Deepak.Pandey@arm.com>
Signed-off-by: Khasim Syed Mohammed <khasim.mohammed@arm.com>
---
Platform/ARM/N1Sdp/N1SdpPlatform.dec | 98 ++++++++++++++++++++++++++++
Platform/ARM/N1Sdp/N1SdpPlatform.dsc | 33 +++++++++-
Platform/ARM/N1Sdp/N1SdpPlatform.fdf | 13 +++-
3 files changed, 140 insertions(+), 4 deletions(-)
create mode 100644 Platform/ARM/N1Sdp/N1SdpPlatform.dec

diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.dec b/Platform/ARM/N1Sdp/N1SdpPlatform.dec
new file mode 100644
index 0000000000..d56891b985
--- /dev/null
+++ b/Platform/ARM/N1Sdp/N1SdpPlatform.dec
@@ -0,0 +1,98 @@
+## @file
+# Describes the N1Sdp configuration.
+#
+# Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x0001001A
+ PACKAGE_NAME = N1SdpPlatform
+ PACKAGE_GUID = 29aacb23-61e8-4fe2-8a06-793537cd26e9
+ PACKAGE_VERSION = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+# Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+
+[LibraryClasses]
+ ArmPlatformLib|Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLib.inf
+
+[Guids.common]
+ gArmN1SdpTokenSpaceGuid = { 0xd8f1624a, 0x98c1, 0x4f64, { 0xa6, 0x41, 0x19, 0x5e, 0xb5, 0x3b, 0x26, 0x0f } }
+
+[PcdsFixedAtBuild]
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskBase|0x88000000|UINT32|0x00000001
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSize|0x18000000|UINT32|0x00000002
+
+ # PCIe
+ gArmN1SdpTokenSpaceGuid.PcdPcieExpressBaseAddress|0x70000000|UINT32|0x00000007
+
+ # External memory
+ gArmNeoverseN1SocTokenSpaceGuid.PcdExtMemorySpace|0|UINT64|0x00000029
+
+[PcdsFeatureFlag.common]
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSupported|FALSE|BOOLEAN|0x00000003
+
+[PcdsFixedAtBuild.common]
+ # CoreSight Debug and Trace components
+ # CoreSight ETMs
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm0Base|0x402040000|UINT64|0x0000002D
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm0MaxBase|0x402040FFF|UINT64|0x0000002E
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm1Base|0x402140000|UINT64|0x0000002F
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm1MaxBase|0x402140FFF|UINT64|0x00000030
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm2Base|0x403040000|UINT64|0x00000031
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm2MaxBase|0x403040FFF|UINT64|0x00000032
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm3Base|0x403140000|UINT64|0x00000033
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm3MaxBase|0x403140FFF|UINT64|0x00000034
+
+ # CoreSight TMC (ETRs/ETFs/ETBs)
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf0Base|0x400410000|UINT64|0x00000035
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf0MaxBase|0x400410FFF|UINT64|0x00000036
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf1Base|0x400420000|UINT64|0x00000037
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf1MaxBase|0x400420FFF|UINT64|0x00000038
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf2Base|0x400010000|UINT64|0x00000039
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf2MaxBase|0x400010FFF|UINT64|0x0000003A
+ gArmN1SdpTokenSpaceGuid.PcdCsEtrBase|0x400120000|UINT64|0x00000043
+ gArmN1SdpTokenSpaceGuid.PcdCsEtrMaxBase|0x400120FFF|UINT64|0x00000044
+
+ # CoreSight Dynamic Funnel(s)
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel0Base|0x4000B0000|UINT64|0x0000003B
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel0MaxBase|0x4000B0FFF|UINT64|0x0000003C
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel1Base|0x4000A0000|UINT64|0x0000003D
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel1MaxBase|0x4000A0FFF|UINT64|0x0000003E
+
+ # CoreSight Dynamic Replicator(s)
+ gArmN1SdpTokenSpaceGuid.PcdCsReplicatorBase|0x400110000|UINT64|0x0000003F
+ gArmN1SdpTokenSpaceGuid.PcdCsReplicatorMaxBase|0x400110FFF|UINT64|0x00000040
+
+ # CoreSight TPIU
+ gArmN1SdpTokenSpaceGuid.PcdCsTpiuBase|0x400130000|UINT64|0x00000041
+ gArmN1SdpTokenSpaceGuid.PcdCsTpiuMaxBase|0x400130FFF|UINT64|0x00000042
+
+ # CoreSight STM and STM Stimulus
+ gArmN1SdpTokenSpaceGuid.PcdCsStmBase|0x400800000|UINT64|0x00000045
+ gArmN1SdpTokenSpaceGuid.PcdCsStmMaxBase|0x400800FFF|UINT64|0x00000046
+ gArmN1SdpTokenSpaceGuid.PcdCsStmStimulusBase|0x4D000000|UINT32|0x00000047
+ gArmN1SdpTokenSpaceGuid.PcdCsStmStimulusSize|0x1000000|UINT32|0x00000048
+
+ # CoreSight Components' Size
+ #
+ # Newton TRMs specify the size for these coresight components as 64K.
+ # The actual size is just 4K though 64K is reserved. Access to the
+ # unmapped reserved region results in a DECERR response.
+ #
+ gArmN1SdpTokenSpaceGuid.PcdCsComponentSize|0x1000|UINT32|0x00000049
+
+ # Remote Chip PCIe
+ gArmN1SdpTokenSpaceGuid.PcdRemotePcieIoTranslation|0x40075200000|UINT64|0x0000004A
+ gArmN1SdpTokenSpaceGuid.PcdRemotePcieMmio32Translation|0x40000000000|UINT64|0x0000004B
+ gArmN1SdpTokenSpaceGuid.PcdRemotePcieMmio64Translation|0x40000000000|UINT64|0x0000004C
diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.dsc b/Platform/ARM/N1Sdp/N1SdpPlatform.dsc
index 61e7a909f8..f76b9eb0ce 100644
--- a/Platform/ARM/N1Sdp/N1SdpPlatform.dsc
+++ b/Platform/ARM/N1Sdp/N1SdpPlatform.dsc
@@ -1,8 +1,14 @@
+## @file
+# Component Description File for N1Sdp
#
-# Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
+# This provides platform specific component descriptions and libraries that
+# conform to EFI/Framework standards.
#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
+# Copyright (c) 2018 - 2021, ARM Limited. All rights reserved.<BR>
#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##

################################################################################
#
@@ -33,6 +39,9 @@
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf

+ # file explorer library support
+ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+
[LibraryClasses.common.SEC]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
@@ -71,6 +80,9 @@
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+!if $(TARGET) != RELEASE
+ DebugLib|MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
+!endif

[LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -82,11 +94,16 @@
################################################################################

[PcdsFeatureFlag.common]
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSupported|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE

[PcdsFixedAtBuild.common]
gArmTokenSpaceGuid.PcdVFPEnabled|1

+ # RAM Disk
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskBase|0x88000000
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSize|0x18000000
+
# Stacks for MPCores in Normal World
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x80000000
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x40000
@@ -99,6 +116,9 @@
# Secondary DDR memory
gArmNeoverseN1SocTokenSpaceGuid.PcdDramBlock2Base|0x8080000000

+ # External memory
+ gArmNeoverseN1SocTokenSpaceGuid.PcdExtMemorySpace|0x40000000000
+
# GIC Base Addresses
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C000000
gArmTokenSpaceGuid.PcdGicDistributorBase|0x30000000
@@ -198,6 +218,9 @@
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
}

+ # Platform driver
+ Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.inf
+
# Human Interface Support
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf

@@ -236,6 +259,9 @@
# SATA Controller
MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf

+ # NVMe boot devices
+ MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
# Usb Support
MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
@@ -244,3 +270,6 @@
MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf
+
+ # RAM Disk
+ MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.fdf b/Platform/ARM/N1Sdp/N1SdpPlatform.fdf
index c4e1f7b4b8..6b097438ad 100644
--- a/Platform/ARM/N1Sdp/N1SdpPlatform.fdf
+++ b/Platform/ARM/N1Sdp/N1SdpPlatform.fdf
@@ -1,8 +1,10 @@
+## @file
+# FDF file of N1Sdp
#
-# Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
+# Copyright (c) 2018 - 2021, ARM Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
+##

################################################################################
#
@@ -109,6 +111,9 @@ READ_LOCK_STATUS = TRUE
# SATA Controller
INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf

+ # NVMe boot devices
+ INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
# Usb Support
INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
@@ -137,10 +142,14 @@ READ_LOCK_STATUS = TRUE

# FV FileSystem
INF MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf
+ INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf

# UEFI applications
INF ShellPkg/Application/Shell/Shell.inf

+ # Platform driver
+ INF Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.inf
+
# Bds
INF MdeModulePkg/Application/UiApp/UiApp.inf
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
--
2.17.1


[PATCH v5 3/7] Platform/ARM/N1Sdp: Introduce platform DXE driver

Khasim Mohammed
 

Add an initial platform DXE driver and support for ramdisk devices.

Signed-off-by: Deepak Pandey <Deepak.Pandey@arm.com>
Signed-off-by: Khasim Syed Mohammed <khasim.mohammed@arm.com>
---
.../N1Sdp/Drivers/PlatformDxe/PlatformDxe.c | 59 +++++++++++++++++++
.../N1Sdp/Drivers/PlatformDxe/PlatformDxe.inf | 47 +++++++++++++++
2 files changed, 106 insertions(+)
create mode 100644 Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.c
create mode 100644 Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.inf

diff --git a/Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.c b/Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.c
new file mode 100644
index 0000000000..3f975fa5ac
--- /dev/null
+++ b/Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.c
@@ -0,0 +1,59 @@
+/** @file
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/RamDisk.h>
+
+/**
+ Entrypoint of Platform Dxe Driver
+
+ @param ImageHandle[in] The firmware allocated handle for the EFI image.
+ @param SystemTable[in] A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The RAM disk has been registered.
+ @retval EFI_NOT_FOUND No RAM disk protocol instances were found.
+ @retval EFI_UNSUPPORTED The ImageType is not supported.
+ @retval Others Unexpected error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+ArmN1SdpEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_RAM_DISK_PROTOCOL *RamDisk;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ Status = EFI_UNSUPPORTED;
+ if (FeaturePcdGet (PcdRamDiskSupported)) {
+ Status = gBS->LocateProtocol (&gEfiRamDiskProtocolGuid, NULL,
+ (VOID**) &RamDisk);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Couldn't find the RAM Disk protocol - %r\n",
+ __FUNCTION__, Status));
+ return Status;
+ }
+
+ Status = RamDisk->Register (
+ (UINTN)PcdGet32 (PcdRamDiskBase),
+ (UINTN)PcdGet32 (PcdRamDiskSize),
+ &gEfiVirtualCdGuid,
+ NULL,
+ &DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to register RAM Disk - %r\n",
+ __FUNCTION__, Status));
+ }
+ }
+ return Status;
+}
diff --git a/Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.inf b/Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.inf
new file mode 100644
index 0000000000..d74f09b46c
--- /dev/null
+++ b/Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.inf
@@ -0,0 +1,47 @@
+## @file
+# Platform DXE driver for N1Sdp
+#
+# Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = PlatformDxe
+ FILE_GUID = 116dcefb-aa53-46aa-81cd-49581684db55
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ArmN1SdpEntryPoint
+
+[Sources.common]
+ PlatformDxe.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ Platform/ARM/N1Sdp/N1SdpPlatform.dec
+
+[LibraryClasses]
+ HobLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEfiRamDiskProtocolGuid
+
+[Guids]
+ gEfiVirtualCdGuid ## SOMETIMES_CONSUMES ## GUID
+
+[FeaturePcd]
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSupported
+
+[FixedPcd]
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskBase
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSize
+
+[Depex]
+ gEfiRamDiskProtocolGuid
--
2.17.1


[PATCH v5 1/7] Silicon/ARM/NeoverseN1Soc: Fix missing function documentation

Khasim Mohammed
 

This patch adds missing documentation for few of the functions
and fixes few formatting changes.

Signed-off-by: Khasim Syed Mohammed <khasim.mohammed@arm.com>
---
.../Library/PlatformLib/PlatformLib.c | 46 +++++++++++++++++--
1 file changed, 41 insertions(+), 5 deletions(-)

diff --git a/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLib.c b/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLib.c
index f722080e56..c0effd37f3 100644
--- a/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLib.c
+++ b/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLib.c
@@ -1,9 +1,9 @@
/** @file
-*
-* Copyright (c) 2018-2020, ARM Limited. All rights reserved.
-*
-* SPDX-License-Identifier: BSD-2-Clause-Patent
-*
+
+ Copyright (c) 2018-2021, ARM Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
**/

#include <Library/ArmPlatformLib.h>
@@ -17,6 +17,12 @@ STATIC ARM_CORE_INFO mCoreInfoTable[] = {
{ 0x1, 0x1 } // Cluster 1, Core 1
};

+/**
+ Return the current Boot Mode.
+
+ @return The boot reason on the platform.
+
+**/
EFI_BOOT_MODE
ArmPlatformGetBootMode (
VOID
@@ -25,6 +31,16 @@ ArmPlatformGetBootMode (
return BOOT_WITH_FULL_CONFIGURATION;
}

+/**
+ Initialize controllers that must be setup in the normal world.
+
+ This function is called by the ArmPlatformPkg/Pei or
+ ArmPlatformPkg/Pei/PlatformPeim in the PEI phase.
+
+ @param[in] MpId Processor ID
+ @retval RETURN_SUCCESS
+
+**/
RETURN_STATUS
ArmPlatformInitialize (
IN UINTN MpId
@@ -33,6 +49,17 @@ ArmPlatformInitialize (
return RETURN_SUCCESS;
}

+/**
+ Populate the Platform core information.
+
+ This function populates the ARM_MP_CORE_INFO_PPI with information
+ about the cores.
+
+ @param[out] CoreCount Number of cores
+ @param[out] ArmCoreTable Table containing information about the cores
+ @retval EFI_SUCCESS
+
+**/
EFI_STATUS
PrePeiCoreGetMpCoreInfo (
OUT UINTN *CoreCount,
@@ -56,6 +83,15 @@ EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = {
}
};

+/**
+ Return the Platform specific PPIs
+
+ This function exposes the N1Sdp Specific PPIs.
+
+ @param[out] PpiListSize Size in Bytes of the Platform PPI List
+ @param[out] PpiList Platform PPI List
+
+**/
VOID
ArmPlatformGetPlatformPpiList (
OUT UINTN *PpiListSize,
--
2.17.1


Re: [PATCH v1 5/5] DynamicTablesPkg: Add DynamicPlatRepo library

Sami Mujawar
 

Hi Pierre,

Please find my feedback inline marked [SAMI].

Regards,

Sami Mujawar

On 23/06/2021 02:36 PM, Pierre.Gondois@... wrote:
From: Pierre Gondois <Pierre.Gondois@...>

The DynamicPlatRepo library allows to handle dynamically created
CmObj. The dynamic platform repository can be in the following states:
1 - Non-initialised
2 - Transient:
    Possibility to add CmObj to the platform, but not to query them.
3 - Finalised:
    Possibility to query CmObj, but not to add new.

A token is allocated to each CmObj added to the dynamic platform
repository (except for reference tokens CmObj). This allows to retrieve
dynamic CmObjs among all CmObj (static CmObj for instance).

This patch add the inf file of the module and the main module
functionnalities and update the dsc file of the package.

Signed-off-by: Sami Mujawar <sami.mujawar@...>
Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
 DynamicTablesPkg/DynamicTablesPkg.dsc         |   1 +
 .../Include/Library/DynamicPlatRepoLib.h      |   4 +-
 .../DynamicPlatRepoLib/DynamicPlatRepo.c      | 518 ++++++++++++++++++
 .../DynamicPlatRepoInternal.h                 |  78 +++
 .../DynamicPlatRepoLib/DynamicPlatRepoLib.inf |  33 ++
 5 files changed, 633 insertions(+), 1 deletion(-)
 create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c
 create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h
 create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf

diff --git a/DynamicTablesPkg/DynamicTablesPkg.dsc b/DynamicTablesPkg/DynamicTablesPkg.dsc
index fd7345891cf1..432c958cf8b2 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.dsc
+++ b/DynamicTablesPkg/DynamicTablesPkg.dsc
@@ -43,6 +43,7 @@ [Components.common]
   DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.inf
   DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf
   DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf
+  DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf
 
 [BuildOptions]
   *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
diff --git a/DynamicTablesPkg/Include/Library/DynamicPlatRepoLib.h b/DynamicTablesPkg/Include/Library/DynamicPlatRepoLib.h
index 8e4665bf5c59..4a76b30399b4 100644
--- a/DynamicTablesPkg/Include/Library/DynamicPlatRepoLib.h
+++ b/DynamicTablesPkg/Include/Library/DynamicPlatRepoLib.h
@@ -13,6 +13,8 @@
 #ifndef DYNAMIC_PLAT_REPO_H_
 #define DYNAMIC_PLAT_REPO_H_
 
+#include <Protocol/ConfigurationManagerProtocol.h>
+
[SAMI] I think the changes in this file can be merged with patch 1/5.
 /** A structure describing the platform configuration
     manager repository information
 */
@@ -109,4 +111,4 @@ DynamicPlatRepoShutdown (
   IN  DYNAMIC_PLATFORM_REPOSITORY_INFO * DynPlatRepo
   );
 
-#endif DYNAMIC_PLAT_REPO_H_
+#endif // DYNAMIC_PLAT_REPO_H_
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c
new file mode 100644
index 000000000000..f26f8ad32bc8
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c
@@ -0,0 +1,518 @@
+/** @file
+  Dynamic Platform Info Repository
+
+  Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Glossary:
+    - Cm or CM   - Configuration Manager
+    - Obj or OBJ - Object
+**/
+
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include "CmObjectTokenFixer.h"
+#include "DynamicPlatRepoInternal.h"
+#include "TokenGenerator.h"
+
+/** Allocate a CM_OBJ_NODE.
+
+  @param [in]  CmObjDesc  CmObj to wrap in a node.
+                          All the fields of the CmObj (Data field included),
+                          are copied.
+  @param [in]  Token      Token to assign to this CmObj/node.
+  @param [out] ObjNode    Allocated ObjNode.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_OUT_OF_RESOURCES  An allocation has failed.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AllocCmObjNode (
+  IN  CONST CM_OBJ_DESCRIPTOR   * CmObjDesc,
+  IN        CM_OBJECT_TOKEN       Token,
+  OUT       CM_OBJ_NODE        ** ObjNode
+  )
+{
+  CM_OBJ_NODE       *Node;
+  CM_OBJ_DESCRIPTOR *Desc;
+
+  if ((CmObjDesc == NULL) || (ObjNode == NULL)) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Node = AllocateZeroPool (sizeof (CM_OBJ_NODE));
+  if (Node == NULL) {
+    ASSERT (0);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  // Initialise the list head.
+  InitializeListHead (&Node->Link);
+  Node->Token = Token;
+  Desc = &Node->CmObjDesc;
+  Desc->ObjectId = CmObjDesc->ObjectId;
+  Desc->Size = CmObjDesc->Size;
+  Desc->Count = CmObjDesc->Count;
+
+  // Allocate and copy the CmObject Data.
+  Desc->Data = AllocateCopyPool (CmObjDesc->Size, CmObjDesc->Data);
+  if (Desc->Data == NULL) {
+    FreePool (Node);
+    ASSERT (0);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  *ObjNode = Node;
+  return EFI_SUCCESS;
+}
+
+/** Free a CM_OBJ_NODE.
+
+  @param [in]  ObjNode    ObjNode to free.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FreeCmObjNode (
+  IN  CM_OBJ_NODE   * ObjNode
+  )
+{
+  CM_OBJ_DESCRIPTOR   *Desc;
+
+  if (ObjNode == NULL) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Unlink Node
+  RemoveEntryList (&ObjNode->Link);
+
+  Desc = &ObjNode->CmObjDesc;
+  if (Desc->Data != NULL) {
+    FreePool (Desc->Data);
+  }
+
+  FreePool (ObjNode);
+  return EFI_SUCCESS;
+}
+
+/** Add an object to the dynamic platform repository.
+
+  @param [in]  This       This dynamic platform repository.
+  @param [in]  CmObjDesc  CmObj to add. The data is copied.
+  @param [out] Token      If not NULL, token allocated to this CmObj.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_OUT_OF_RESOURCES  An allocation has failed.
+**/
+EFI_STATUS
+EFIAPI
+DynPlatRepoAddObject (
+  IN        DYNAMIC_PLATFORM_REPOSITORY_INFO    * This,
+  IN  CONST CM_OBJ_DESCRIPTOR                   * CmObjDesc,
+  OUT       CM_OBJECT_TOKEN                     * Token OPTIONAL
+  )
+{
+  EFI_STATUS              Status;
+  CM_OBJ_NODE             *ObjNode;
+  CM_OBJECT_ID            ArmNamespaceObjId;
+  CM_OBJECT_TOKEN         NewToken;
+
+  // The dynamic repository must be able to receive objects.
+  if ((This == NULL)      ||
+      (CmObjDesc == NULL) ||
+      (This->RepoState != DynRepoTransient)) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Check the CmObjDesc:
+  //  - only Arm objects are supported for now.
+  //  - only EArmObjCmRef objects can be added as arrays.
+  ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjDesc->ObjectId);
+  if ((CmObjDesc->Size == 0)              ||
+      (CmObjDesc->Count == 0)             ||
+      (ArmNamespaceObjId >= EArmObjMax)   ||
+      ((CmObjDesc->Count > 1)  && (ArmNamespaceObjId != EArmObjCmRef))  ||
+      (GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId) != EObjNameSpaceArm)) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Generate a token.
+  NewToken = GenerateToken ();
+
+  // Create an ObjNode.
+  Status = AllocCmObjNode (CmObjDesc, NewToken, &ObjNode);
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
+    return Status;
+  }
+
+  // Fixup self-token if necessary.
+  Status = FixupCmObjectSelfToken (&ObjNode->CmObjDesc, NewToken);
+  if (EFI_ERROR (Status)) {
+    FreeCmObjNode (ObjNode);
+    ASSERT (0);
+    return Status;
+  }
+
+  // Add to link list.
+  InsertTailList (&This->ArmCmObjList[ArmNamespaceObjId], &ObjNode->Link);
+  This->ObjectCount += 1;
+
+  if (Token != NULL) {
+    *Token = NewToken;
+  }
+  return EFI_SUCCESS;
+}
+
+/** Group lists of CmObjNode from the ArmNameSpace to one array.
+
+  @param [in]  This         This dynamic platform repository.
+  @param [in]  ArmObjIndex  Index in EARM_OBJECT_ID
+                            (must be < EArmObjMax).
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_BUFFER_TOO_SMALL    Buffer too small.
+  @retval EFI_OUT_OF_RESOURCES  An allocation has failed.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GroupCmObjNodes (
+  IN  DYNAMIC_PLATFORM_REPOSITORY_INFO    * This,
+  IN  UINT32                                ArmObjIndex
+  )
+{
+  EFI_STATUS          Status;
+  UINTN               Count;
+  UINTN               Size;
+  UINT32              CmObjId;
+  UINT8               *GroupedData;
+  UINT8               *Data;
+  CM_OBJ_DESCRIPTOR   *CmObjDesc;
+  LIST_ENTRY          *ListHead;
+  LIST_ENTRY          *Link;
+
+  if ((This == NULL)  ||
+      (ArmObjIndex >= EArmObjMax)) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Count = 0;
+  Size = 0;
+  CmObjId = CREATE_CM_ARM_OBJECT_ID (ArmObjIndex);
+  ListHead = &This->ArmCmObjList[ArmObjIndex];
+  Link = GetFirstNode (ListHead);
+
+  // Compute the total count and size of the CmObj in the list.
+  while (Link != ListHead) {
+    CmObjDesc = &((CM_OBJ_NODE*)Link)->CmObjDesc;
+
+    if (CmObjDesc->ObjectId != CmObjId) {
+      ASSERT (0);
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if ((CmObjDesc->Count != 1) && (ArmObjIndex != EArmObjCmRef)){
+      // We expect each descriptor to contain an individual object.
+      // EArmObjCmRef objects are counted as groups, so +1 as well.
+      ASSERT (0);
+      return EFI_INVALID_PARAMETER;
+    }
+
+    Count++;
+    Size += CmObjDesc->Size;
+
+    // Next Link
+    Link = GetNextNode (ListHead, Link);
+  } // while
+
+  if (Count == 0) {
+    // No objects found.
+    return EFI_SUCCESS;
+  }
+
+  GroupedData = AllocateZeroPool (Size);
+  if (GroupedData == NULL) {
+    ASSERT (0);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  // Copy the Object Data and add to the TokenMapper.
+  Data = GroupedData;
+  Link = GetFirstNode (ListHead);
+  while (Link != ListHead) {
+    CmObjDesc = &((CM_OBJ_NODE*)Link)->CmObjDesc;
+    CopyMem (Data, CmObjDesc->Data, CmObjDesc->Size);
+
+    // Add the object to the Token Mapper.
+    // Note: The CmObject Data field of objects in the Token Mapper point
+    //       to the memory in the GroupedData array.
+    Status = TokenMapperAddObject (
+               &This->TokenMapper,
+               ((CM_OBJ_NODE*)Link)->Token,
+               CmObjDesc->ObjectId,
+               CmObjDesc->Size,
+               Data
+               );
+    if (EFI_ERROR (Status)) {
+      FreePool (GroupedData);
+      return Status;
+    }
+
+    Data += CmObjDesc->Size;
+    Link = GetNextNode (ListHead, Link);
+  } // while
+
+  CmObjDesc = &This->ArmCmObjArray[ArmObjIndex];
+  CmObjDesc->ObjectId = CmObjId;
+  CmObjDesc->Size = Size;
+  CmObjDesc->Count = Count;
+  CmObjDesc->Data = GroupedData;
+
+  return Status;
+}
+
+/** Finalise the dynamic repository.
+
+  Finalising means:
+   - Preventing any further objects from being added.
+   - Allowing to get objects from the dynamic repository
+     (not possible before a call to this function).
+
+  @param [in]  This       This dynamic platform repository.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_ALREADY_STARTED   Instance already initialised.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_BUFFER_TOO_SMALL  Buffer too small.
+  @retval EFI_OUT_OF_RESOURCES  An allocation has failed.
+**/
+EFI_STATUS
+EFIAPI
+DynamicPlatRepoFinalise (
+  IN  DYNAMIC_PLATFORM_REPOSITORY_INFO      * This
+  )
+{
+  EFI_STATUS    Status;
+  UINTN         ArmObjIndex;
+
+  if ((This == NULL)  ||
+      (This->RepoState != DynRepoTransient)) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Prevent any further objects from being added.
+  This->RepoState = DynRepoFinalized;
+
+  // Initialise the token mapper.
+  Status = TokenMapperInitialise (&This->TokenMapper, This->ObjectCount);
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
+    return Status;
+  }
+
+  // For each CM_OBJECT_ID:
+  //  - Convert the list of nodes to an array
+  //    (the array is wrapped in a CmObjDesc).
+  //  - Add the Token/CmObj binding to the token mapper.
+  for (ArmObjIndex = 0; ArmObjIndex < EArmObjMax; ArmObjIndex++) {
+      Status = GroupCmObjNodes (This, ArmObjIndex);
+      if (EFI_ERROR (Status)) {
+        ASSERT (0);
+        // Free the TokenMapper.
+        // Ignore the returned Status since we already failed.
+        TokenMapperShutdown (&This->TokenMapper);
+        return Status;
+      }
+  } // for
+
+  return EFI_SUCCESS;
+}
+
+/** Get a CmObj from the dynamic repository.
+
+  @param [in]      This        Pointer to the Dynamic Platform Repository.
+  @param [in]      CmObjectId  The Configuration Manager Object ID.
+  @param [in]      Token       An optional token identifying the object. If
+                               unused this must be CM_NULL_TOKEN.
+  @param [in, out] CmObjDesc   Pointer to the Configuration Manager Object
+                               descriptor describing the requested Object.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_NOT_FOUND         The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+DynamicPlatRepoGetObject (
+  IN      DYNAMIC_PLATFORM_REPOSITORY_INFO    * This,
+  IN      CM_OBJECT_ID                          CmObjectId,
+  IN      CM_OBJECT_TOKEN                       Token OPTIONAL,
+  IN  OUT CM_OBJ_DESCRIPTOR                   * CmObjDesc
+  )
+{
+  EFI_STATUS          Status;
+  CM_OBJ_DESCRIPTOR   *Desc;
+  CM_OBJECT_ID        ArmNamespaceObjId;
+
+  if ((This == NULL)      ||
+      (CmObjDesc == NULL) ||
+      (This->RepoState != DynRepoFinalized)) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjectId);
+  if (ArmNamespaceObjId >= EArmObjMax) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Token != CM_NULL_TOKEN) {
+    // Search in the Token Mapper and return the object.
+    Status = TokenMapperGetObject (
+               &This->TokenMapper,
+               Token,
+               CmObjectId,
+               CmObjDesc
+               );
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  if (ArmNamespaceObjId == EArmObjCmRef) {
+    // EArmObjCmRef object must be requested using a valid token.
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Desc = &This->ArmCmObjArray[ArmNamespaceObjId];
+
+  // Nothing here.
+  if (Desc->Count == 0) {
+    return EFI_NOT_FOUND;
+  } else {
+    // Return the full array.
+    CmObjDesc->ObjectId = Desc->ObjectId;
+    CmObjDesc->Size = Desc->Size;
+    CmObjDesc->Data = Desc->Data;
+    CmObjDesc->Count = Desc->Count;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/** Initialize the dynamic platform repository.
+
+  @param [out]  DynPlatRepo   If success, contains the initialised dynamic
+                              platform repository.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_OUT_OF_RESOURCES  An allocation has failed.
+**/
+EFI_STATUS
+EFIAPI
+DynamicPlatRepoInit (
+  OUT DYNAMIC_PLATFORM_REPOSITORY_INFO   ** DynPlatRepo
+  )
+{
+  UINTN                              Index;
+  DYNAMIC_PLATFORM_REPOSITORY_INFO * Repo;
+
+  if (DynPlatRepo == NULL) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Repo = AllocateZeroPool (sizeof (DYNAMIC_PLATFORM_REPOSITORY_INFO));
+  if (Repo == NULL) {
+    ASSERT (0);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  // Initialise the CmObject List.
+  for (Index = 0; Index < EArmObjMax; Index++) {
+    InitializeListHead (&Repo->ArmCmObjList[Index]);
+  }
+
+  Repo->ObjectCount = 0;
+  Repo->RepoState = DynRepoTransient;
+
+  *DynPlatRepo = Repo;
+
+  return EFI_SUCCESS;
+}
+
+/** Shutdown the dynamic platform repository.
+
+  Free all the memory allocated for the dynamic platform repository.
+
+  @param [in]  DynPlatRepo    The dynamic platform repository.
+
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_SUCCESS           Success.
+**/
+EFI_STATUS
+EFIAPI
+DynamicPlatRepoShutdown (
+  IN  DYNAMIC_PLATFORM_REPOSITORY_INFO * DynPlatRepo
+  )
+{
+  EFI_STATUS            Status;
+  UINT32                Index;
+  LIST_ENTRY          * ListHead;
+  CM_OBJ_DESCRIPTOR   * CmObjDesc;
+  VOID                * Data;
+
+  if (DynPlatRepo == NULL) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Free the list of objects.
+  for (Index = 0; Index < EArmObjMax; Index++) {
+    // Free all the nodes with this object Id.
+    ListHead = &DynPlatRepo->ArmCmObjList[Index];
+    while (!IsListEmpty (ListHead)) {
+      FreeCmObjNode ((CM_OBJ_NODE*)GetFirstNode (ListHead));
+    } // while
+  } // for
+
+  // Free the arrays.
+  CmObjDesc = DynPlatRepo->ArmCmObjArray;
+  for (Index = 0; Index < EArmObjMax; Index++) {
+    Data = CmObjDesc[Index].Data;
+    if (Data != NULL) {
+      FreePool (Data);
+    }
+  } // for
+
+  // Free the TokenMapper
+  Status = TokenMapperShutdown (&DynPlatRepo->TokenMapper);
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
[SAMI] In DynamicPlatRepoFinalise() if an error occurs the Token Mapper would have been shutdown freeing all the memory.  So I think in TokenMapperShutdown(), the TokenDescArray should be set to NULL after freeing, and MaxTokenDescCount should  be set to 0.
Can you check, please?
[/SAMI]
+  }
+
+  FreePool (DynPlatRepo);
+  return Status;
+}
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h
new file mode 100644
index 000000000000..d03fa2b7dcec
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h
@@ -0,0 +1,78 @@
+/** @file
+  Dynamic Platform Info Repository Internal
+
+  Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Glossary:
+    - Cm or CM   - Configuration Manager
+    - Obj or OBJ - Object
+**/
+
+#ifndef DYNAMIC_PLAT_REPO_INTERNAL_H_
+#define DYNAMIC_PLAT_REPO_INTERNAL_H_
+
+#include "TokenMapper.h"
+
+#pragma pack(1)
+
+/** CmObj node.
+
+  This is a node wrapper around the CM_OBJ_DESCRIPTOR structure.
+  It also allows to bind a token to the CM_OBJ_DESCRIPTOR.
+*/
+typedef struct CmObjectNode {
+  /// This must be the first field in this structure.
+  LIST_ENTRY          Link;
+
+  /// Token associated with the CmObjDesc.
+  CM_OBJECT_TOKEN     Token;
+
+  /// CmObjDesc wrapped.
+  /// Note: the CM_OBJ_DESCRIPTOR.Data field is allocated and copied.
+  CM_OBJ_DESCRIPTOR   CmObjDesc;
+} CM_OBJ_NODE;
+
+/** Dynamic repository states.
+
+  The states must progress as:
+  UnInitialised -> Transient -> Finalized
+*/
+typedef enum DynRepoState {
+  DynRepoUnInitialised, ///< Un-Initialised state
+  DynRepoTransient,     ///< Transient state - CmObjects can be added.
+  DynRepoFinalized,     ///< Repo Locked - No further CmObjects can be added.
+                        ///< Getting objects is now possible.
+  DynRepoMax            ///< Max value.
+} EDYNAMIC_REPO_STATE;
+
+/** A structure describing the platform configuration
+    manager repository information
+*/
+typedef struct DynamicPlatformRepositoryInfo {
+  /// Repo state machine.
+  EDYNAMIC_REPO_STATE   RepoState;
+
+  /// Count of all the objects added to the Dynamic Platform Repo
+  /// during the Transient state.
+  UINTN                 ObjectCount;
+
+  /// Link lists of CmObj from the ArmNameSpace
+  /// that are added in the Transient state.
+  LIST_ENTRY            ArmCmObjList[EArmObjMax];
+
+  /// Structure Members used in Finalized state.
+  /// An array of CmObj Descriptors from the ArmNameSpace
+  /// This array is populated when the Repo is finalized.
+  CM_OBJ_DESCRIPTOR     ArmCmObjArray[EArmObjMax];
+
+  /// A token mapper for the objects in the ArmNamespaceObjectArray
+  /// The Token mapper is populated when the Repo is finalized in
+  /// a call to DynamicPlatRepoFinalise ().
+  TOKEN_MAPPER          TokenMapper;
+} DYNAMIC_PLATFORM_REPOSITORY_INFO;
+
+#pragma pack()
+
+#endif // DYNAMIC_PLAT_REPO_INTERNAL_H_
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf
new file mode 100644
index 000000000000..9a3cc87fd91d
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf
@@ -0,0 +1,33 @@
+## @file
+#  Dynamic Platform Repository
+#
+#  Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION    = 0x0001001B
+  BASE_NAME      = DynamicPlatRepoLib
+  FILE_GUID      = 836D253D-3144-4A89-9BEE-BC55AFDC814E
+  VERSION_STRING = 1.0
+  MODULE_TYPE    = DXE_DRIVER
+  LIBRARY_CLASS  = DynamicPlatRepoLib
+
+[Sources]
+  CmObjectTokenFixer.c
+  CmObjectTokenFixer.h
+  DynamicPlatRepo.c
+  DynamicPlatRepoInternal.h
+  TokenGenerator.c
+  TokenGenerator.h
+  TokenMapper.c
+  TokenMapper.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+  AcpiHelperLib
+  BaseLib


Re: [PATCH v4 4/7] Platform/ARM/N1Sdp: Enable N1Sdp platform specific configurations

Khasim Mohammed
 

Hi Sami,

On Fri, Nov 5, 2021 at 06:05 AM, Sami Mujawar wrote:
Hi Khasim,

Please find my response inline marked [SAMI].

Regards,

Sami Mujawar

On 26/10/2021 06:39 PM, Khasim Mohammed via groups.io wrote:
This patch adds PCDs and updates the fdf file for N1Sdp
platform specific configurations.

Signed-off-by: Deepak Pandey <Deepak.Pandey@...>
Signed-off-by: Khasim Syed Mohammed <khasim.mohammed@...>
---
Platform/ARM/N1Sdp/N1SdpPlatform.dec | 98 ++++++++++++++++++++++++++++
Platform/ARM/N1Sdp/N1SdpPlatform.dsc | 37 ++++++++++-
Platform/ARM/N1Sdp/N1SdpPlatform.fdf | 13 +++-
3 files changed, 144 insertions(+), 4 deletions(-)
create mode 100644 Platform/ARM/N1Sdp/N1SdpPlatform.dec

diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.dec b/Platform/ARM/N1Sdp/N1SdpPlatform.dec
new file mode 100644
index 0000000000..d56891b985
--- /dev/null
+++ b/Platform/ARM/N1Sdp/N1SdpPlatform.dec
@@ -0,0 +1,98 @@
+## @file
+# Describes the N1Sdp configuration.
+#
+# Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x0001001A
+ PACKAGE_NAME = N1SdpPlatform
+ PACKAGE_GUID = 29aacb23-61e8-4fe2-8a06-793537cd26e9
+ PACKAGE_VERSION = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+# Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+
+[LibraryClasses]
+ ArmPlatformLib|Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLib.inf
+
+[Guids.common]
+ gArmN1SdpTokenSpaceGuid = { 0xd8f1624a, 0x98c1, 0x4f64, { 0xa6, 0x41, 0x19, 0x5e, 0xb5, 0x3b, 0x26, 0x0f } }
+
+[PcdsFixedAtBuild]
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskBase|0x88000000|UINT32|0x00000001
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSize|0x18000000|UINT32|0x00000002
+
+ # PCIe
+ gArmN1SdpTokenSpaceGuid.PcdPcieExpressBaseAddress|0x70000000|UINT32|0x00000007
+
+ # External memory
+ gArmNeoverseN1SocTokenSpaceGuid.PcdExtMemorySpace|0|UINT64|0x00000029
+
+[PcdsFeatureFlag.common]
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSupported|FALSE|BOOLEAN|0x00000003
+
+[PcdsFixedAtBuild.common]
+ # CoreSight Debug and Trace components
+ # CoreSight ETMs
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm0Base|0x402040000|UINT64|0x0000002D
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm0MaxBase|0x402040FFF|UINT64|0x0000002E
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm1Base|0x402140000|UINT64|0x0000002F
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm1MaxBase|0x402140FFF|UINT64|0x00000030
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm2Base|0x403040000|UINT64|0x00000031
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm2MaxBase|0x403040FFF|UINT64|0x00000032
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm3Base|0x403140000|UINT64|0x00000033
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm3MaxBase|0x403140FFF|UINT64|0x00000034
+
+ # CoreSight TMC (ETRs/ETFs/ETBs)
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf0Base|0x400410000|UINT64|0x00000035
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf0MaxBase|0x400410FFF|UINT64|0x00000036
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf1Base|0x400420000|UINT64|0x00000037
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf1MaxBase|0x400420FFF|UINT64|0x00000038
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf2Base|0x400010000|UINT64|0x00000039
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf2MaxBase|0x400010FFF|UINT64|0x0000003A
+ gArmN1SdpTokenSpaceGuid.PcdCsEtrBase|0x400120000|UINT64|0x00000043
+ gArmN1SdpTokenSpaceGuid.PcdCsEtrMaxBase|0x400120FFF|UINT64|0x00000044
+
+ # CoreSight Dynamic Funnel(s)
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel0Base|0x4000B0000|UINT64|0x0000003B
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel0MaxBase|0x4000B0FFF|UINT64|0x0000003C
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel1Base|0x4000A0000|UINT64|0x0000003D
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel1MaxBase|0x4000A0FFF|UINT64|0x0000003E
+
+ # CoreSight Dynamic Replicator(s)
+ gArmN1SdpTokenSpaceGuid.PcdCsReplicatorBase|0x400110000|UINT64|0x0000003F
+ gArmN1SdpTokenSpaceGuid.PcdCsReplicatorMaxBase|0x400110FFF|UINT64|0x00000040
+
+ # CoreSight TPIU
+ gArmN1SdpTokenSpaceGuid.PcdCsTpiuBase|0x400130000|UINT64|0x00000041
+ gArmN1SdpTokenSpaceGuid.PcdCsTpiuMaxBase|0x400130FFF|UINT64|0x00000042
+
+ # CoreSight STM and STM Stimulus
+ gArmN1SdpTokenSpaceGuid.PcdCsStmBase|0x400800000|UINT64|0x00000045
+ gArmN1SdpTokenSpaceGuid.PcdCsStmMaxBase|0x400800FFF|UINT64|0x00000046
+ gArmN1SdpTokenSpaceGuid.PcdCsStmStimulusBase|0x4D000000|UINT32|0x00000047
+ gArmN1SdpTokenSpaceGuid.PcdCsStmStimulusSize|0x1000000|UINT32|0x00000048
+
+ # CoreSight Components' Size
+ #
+ # Newton TRMs specify the size for these coresight components as 64K.
+ # The actual size is just 4K though 64K is reserved. Access to the
+ # unmapped reserved region results in a DECERR response.
+ #
+ gArmN1SdpTokenSpaceGuid.PcdCsComponentSize|0x1000|UINT32|0x00000049
+
+ # Remote Chip PCIe
+ gArmN1SdpTokenSpaceGuid.PcdRemotePcieIoTranslation|0x40075200000|UINT64|0x0000004A
+ gArmN1SdpTokenSpaceGuid.PcdRemotePcieMmio32Translation|0x40000000000|UINT64|0x0000004B
+ gArmN1SdpTokenSpaceGuid.PcdRemotePcieMmio64Translation|0x40000000000|UINT64|0x0000004C
diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.dsc b/Platform/ARM/N1Sdp/N1SdpPlatform.dsc
index 61e7a909f8..0bc3fa6dfe 100644
--- a/Platform/ARM/N1Sdp/N1SdpPlatform.dsc
+++ b/Platform/ARM/N1Sdp/N1SdpPlatform.dsc
@@ -1,8 +1,18 @@
+## @file
+# Component Description File for N1Sdp
#
-# Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
+# This provides platform specific component descriptions and libraries that
+# conform to EFI/Framework standards.
#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
+# Copyright (c) 2018 - 2021, ARM Limited. All rights reserved.<BR>
#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+# IMPLIED.
+#
[SAMI] Is the above disclaimer required? Is the
"SPDX-License-Identifier: BSD-2-Clause-Patent" not sufficient? I think I
noticed something similar in another patch.
Can you check, please?
[/SAMI]
Initially in v1 and v2 patches I was not having this disclaimer, but in latest I had to include this disclaimer without this the CI tests were failing which Pierre had setup for edk2-platforms.

I confirm we will need this disclaimer.

Regards,
Khasim
+##

################################################################################
#
@@ -33,6 +43,9 @@
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf

+ # file explorer library support
+ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+
[LibraryClasses.common.SEC]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
@@ -71,6 +84,9 @@
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+!if $(TARGET) != RELEASE
+ DebugLib|MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
+!endif

[LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -82,11 +98,16 @@
################################################################################

[PcdsFeatureFlag.common]
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSupported|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE

[PcdsFixedAtBuild.common]
gArmTokenSpaceGuid.PcdVFPEnabled|1

+ # RAM Disk
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskBase|0x88000000
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSize|0x18000000
+
# Stacks for MPCores in Normal World
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x80000000
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x40000
@@ -99,6 +120,9 @@
# Secondary DDR memory
gArmNeoverseN1SocTokenSpaceGuid.PcdDramBlock2Base|0x8080000000

+ # External memory
+ gArmNeoverseN1SocTokenSpaceGuid.PcdExtMemorySpace|0x40000000000
+
# GIC Base Addresses
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C000000
gArmTokenSpaceGuid.PcdGicDistributorBase|0x30000000
@@ -198,6 +222,9 @@
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
}

+ # Platform driver
+ Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.inf
+
# Human Interface Support
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf

@@ -236,6 +263,9 @@
# SATA Controller
MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf

+ # NVMe boot devices
+ MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
# Usb Support
MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
@@ -244,3 +274,6 @@
MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf
+
+ # RAM Disk
+ MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.fdf b/Platform/ARM/N1Sdp/N1SdpPlatform.fdf
index c4e1f7b4b8..6b097438ad 100644
--- a/Platform/ARM/N1Sdp/N1SdpPlatform.fdf
+++ b/Platform/ARM/N1Sdp/N1SdpPlatform.fdf
@@ -1,8 +1,10 @@
+## @file
+# FDF file of N1Sdp
#
-# Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
+# Copyright (c) 2018 - 2021, ARM Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
+##

################################################################################
#
@@ -109,6 +111,9 @@ READ_LOCK_STATUS = TRUE
# SATA Controller
INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf

+ # NVMe boot devices
+ INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
# Usb Support
INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
@@ -137,10 +142,14 @@ READ_LOCK_STATUS = TRUE

# FV FileSystem
INF MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf
+ INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf

# UEFI applications
INF ShellPkg/Application/Shell/Shell.inf

+ # Platform driver
+ INF Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.inf
+
# Bds
INF MdeModulePkg/Application/UiApp/UiApp.inf
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf


Re: [PATCH v1 4/5] DynamicTablesPkg: DynamicPlatRepo: Add TokenMapper

Sami Mujawar
 

Hi Pierre,

Please find my response inline marked [SAMI].

Regards,

Sami Mujawar


On 23/06/2021 02:36 PM, Pierre.Gondois@arm.com wrote:
From: Pierre Gondois <Pierre.Gondois@arm.com>

The DynamicPlatRepo library allows to handle dynamically created
CmObj. The dynamic platform repository can be in the following states:
1 - Non-initialised
2 - Transient:
Possibility to add CmObj to the platform, but not to query them.
3 - Finalised:
Possibility to query CmObj, but not to add new.

A token is allocated to each CmObj added to the dynamic platform
repository (except for reference tokens CmObj). This allows to retrieve
dynamic CmObjs among all CmObj (static CmObj for instance).

This patch add the TokenMapper files, allowing to retrieve a CmObj
from a token/CmObjId couple.

Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
---
.../Common/DynamicPlatRepoLib/TokenMapper.c | 214 ++++++++++++++++++
.../Common/DynamicPlatRepoLib/TokenMapper.h | 123 ++++++++++
2 files changed, 337 insertions(+)
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.h

diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c
new file mode 100644
index 000000000000..f23bc8c1c7db
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c
@@ -0,0 +1,214 @@
+/** @file
+ Token Mapper
+
+ Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+#include "TokenMapper.h"
+
+/** Add a CmObjDesc to the TokenMapper.
+
+ @param [in] TokenMapper The TokenMapper instance.
+ @param [in] Token CmObj token.
+ @param [in] ObjectId CmObj ObjectId.
+ @param [in] Size CmObj Size.
+ @param [in] Data CmObj Data.
+ This memory is referenced, not copied.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperAddObject (
+ IN TOKEN_MAPPER *TokenMapper,
+ IN CM_OBJECT_TOKEN Token,
+ IN CM_OBJECT_ID ObjectId,
+ IN UINT32 Size,
+ IN VOID *Data
+ )
+{
+ TOKEN_MAP_DESCRIPTOR *TokenMapDesc;
+ CM_OBJ_DESCRIPTOR *CmObjDesc;
+
+ if ((TokenMapper == NULL) ||
+ (TokenMapper->TokenDescArray == NULL) ||
+ (Size == 0) ||
+ (Data == NULL)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (TokenMapper->ItemCount >= TokenMapper->MaxTokenDescCount) {
+ ASSERT (0);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ TokenMapDesc = &TokenMapper->TokenDescArray[TokenMapper->ItemCount++];
+ TokenMapDesc->Token = Token;
+ CmObjDesc = &TokenMapDesc->CmObjDesc;
+ CmObjDesc->ObjectId = ObjectId;
+ CmObjDesc->Size = Size;
+
+ // Point inside the finalized array.
+ CmObjDesc->Data = Data;
+
+ // Only EArmObjCmRef CmObj can be added as arrays (more than 1 elements).
+ if ((GET_CM_NAMESPACE_ID (ObjectId) == EObjNameSpaceArm) &&
+ (GET_CM_OBJECT_ID (ObjectId) == EArmObjCmRef)) {
+ CmObjDesc->Count = Size / sizeof (CM_ARM_OBJ_REF);
+ } else {
+ CmObjDesc->Count = 1;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Get a CmObjDesc from a ObjectId/Token couple.
+
+ The Token parameter is not optional. An existing token must be provided.
+
+ @param [in] TokenMapper The TokenMapper instance.
+ @param [in] Token Token of the CmObj to search.
+ @param [in] ObjectId Object Id of the CmObj to search.
+ @param [out] CmObjDesc CM_OBJ_DESCRIPTOR containing the CmObj searched.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND Not found.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperGetObject (
+ IN TOKEN_MAPPER *TokenMapper,
+ IN CM_OBJECT_TOKEN Token,
+ IN CM_OBJECT_ID ObjectId,
+ OUT CM_OBJ_DESCRIPTOR *CmObjDesc
+ )
+{
+ UINTN Index;
+ UINTN MaxCount;
+ TOKEN_MAP_DESCRIPTOR *TokenMapDesc;
+
+ // Nothing to do.
+ if ((TokenMapper != NULL) && (TokenMapper->MaxTokenDescCount == 0)) {
+ return EFI_SUCCESS;
[SAMI] I think EFI_INVALID_PARAMETER or EFI_NOT_FOUND should be returned here. Can you check, please?
+ }
+
+ if ((Token == CM_NULL_TOKEN) ||
+ (CmObjDesc == NULL) ||
+ (TokenMapper == NULL) ||
+ (TokenMapper->TokenDescArray == NULL)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TokenMapDesc = TokenMapper->TokenDescArray;
+ MaxCount = TokenMapper->MaxTokenDescCount;
+ for (Index = 0; Index < MaxCount; Index++) {
+ if ((TokenMapDesc->CmObjDesc.ObjectId == ObjectId) &&
+ (TokenMapDesc->Token == Token)) {
+ CopyMem (
+ CmObjDesc,
+ &TokenMapDesc->CmObjDesc,
+ sizeof (CM_OBJ_DESCRIPTOR)
+ );
+ return EFI_SUCCESS;
+ }
+ TokenMapDesc++;
+ } // for
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: Requested CmObj of type 0x%x with token 0x%x"
+ " not found in the dynamic repository\n.",
+ ObjectId,
+ Token
+ ));
+ return EFI_NOT_FOUND;
+}
+
+/** Initialise a TokenMapper.
+
+ @param [in] TokenMapper The TokenMapper to initialise.
+ @param [in] DescriptorCount Number of entries to allocate.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ALREADY_STARTED Instance already initialised.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperInitialise (
+ IN TOKEN_MAPPER * TokenMapper,
+ IN UINTN DescriptorCount
+ )
+{
+ if (TokenMapper == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Nothing to do.
+ if (DescriptorCount == 0) {
+ return EFI_SUCCESS;
+ }
+
+ if (TokenMapper->TokenDescArray != NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Token mapper already initialised\n."));
+ ASSERT (0);
+ return EFI_ALREADY_STARTED;
+ }
+
+ TokenMapper->TokenDescArray =
+ AllocateZeroPool (sizeof (TOKEN_MAP_DESCRIPTOR) * DescriptorCount);
+ if (TokenMapper->TokenDescArray == NULL) {
+ ASSERT (0);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ TokenMapper->MaxTokenDescCount = DescriptorCount;
+ TokenMapper->ItemCount = 0;
+
+ return EFI_SUCCESS;
+}
+
+/** Shutdown a TokenMapper.
+
+ @param [in] TokenMapper The TokenMapper to shutdown.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperShutdown (
+ IN TOKEN_MAPPER * TokenMapper
+ )
+{
+ // Nothing to do.
+ if ((TokenMapper != NULL) && (TokenMapper->MaxTokenDescCount == 0)) {
+ return EFI_SUCCESS;
+ }
+
+ if ((TokenMapper == NULL) ||
+ (TokenMapper->TokenDescArray == NULL)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FreePool (TokenMapper->TokenDescArray);
+ return EFI_SUCCESS;
+}
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.h b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.h
new file mode 100644
index 000000000000..377fc03dcd01
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.h
@@ -0,0 +1,123 @@
+/** @file
+ Token Mapper
+
+ Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#ifndef TOKEN_MAPPER_H_
+#define TOKEN_MAPPER_H_
+
+#pragma pack(1)
+
+/** Token mapping descriptor.
+
+ Bind a token and a CmObj together.
+*/
+typedef struct TokenMapDescriptor {
+ /// Object Token.
+ CM_OBJECT_TOKEN Token;
+
+ /// CmObjectDescriptor CM_OBJ_DESCRIPTOR.Data is a reference copy
+ /// and not allocated. It points to the individual objects in the
+ /// Dynamic Plat Repo ArmNameSpaceObjectArray.
+ CM_OBJ_DESCRIPTOR CmObjDesc;
+} TOKEN_MAP_DESCRIPTOR;
+
+/** Token mapper.
+
+ Contain all the Token/CmObj couple mapping.
+**/
+typedef struct TokenMapper {
+ /// Maximum number of TOKEN_MAP_DESCRIPTOR entries in TokenDescArray.
+ UINTN MaxTokenDescCount;
+
+ /// Next TOKEN_MAP_DESCRIPTOR entry to use in TokenDescArray.
+ UINTN ItemCount;
+
+ /// Array of TOKEN_MAP_DESCRIPTOR.
+ TOKEN_MAP_DESCRIPTOR * TokenDescArray;
+} TOKEN_MAPPER;
+
+#pragma pack()
+
+/** Add a CmObjDesc to the TokenMapper.
+
+ @param [in] TokenMapper The TokenMapper instance.
+ @param [in] Token CmObj token.
+ @param [in] ObjectId CmObj ObjectId.
+ @param [in] Size CmObj Size.
+ @param [in] Data CmObj Data.
+ This memory is referenced, not copied.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperAddObject (
+ IN TOKEN_MAPPER *TokenMapper,
+ IN CM_OBJECT_TOKEN Token,
+ IN CM_OBJECT_ID ObjectId,
+ IN UINT32 Size,
+ IN VOID *Data
+ );
+
+/** Get a CmObjDesc from a ObjectId/Token couple.
+
+ The Token parameter is not optional. An existing token must be provided.
+
+ @param [in] TokenMapper The TokenMapper instance.
+ @param [in] Token Token of the CmObj to search.
+ @param [in] ObjectId Object Id of the CmObj to search.
+ @param [out] CmObjDesc CM_OBJ_DESCRIPTOR containing the CmObj searched.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND Not found.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperGetObject (
+ IN TOKEN_MAPPER *TokenMapper,
+ IN CM_OBJECT_TOKEN Token,
+ IN CM_OBJECT_ID ObjectId,
+ OUT CM_OBJ_DESCRIPTOR *CmObjDesc
+ );
+
+/** Initialise a TokenMapper.
+
+ @param [in] TokenMapper The TokenMapper to initialise.
+ @param [in] DescriptorCount Number of entries to allocate.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ALREADY_STARTED Instance already initialised.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperInitialise (
+ IN TOKEN_MAPPER * TokenMapper,
+ IN UINTN DescriptorCount
+ );
+
+/** Shutdown a TokenMapper.
+
+ @param [in] TokenMapper The TokenMapper to shutdown.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperShutdown (
+ IN TOKEN_MAPPER * TokenMapper
+ );
+
+#endif // TOKEN_MAPPER_H_


Re: [PATCH v4 4/7] Platform/ARM/N1Sdp: Enable N1Sdp platform specific configurations

Sami Mujawar
 

Hi Khasim,

Please find my response inline marked [SAMI].

Regards,

Sami Mujawar

On 26/10/2021 06:39 PM, Khasim Mohammed via groups.io wrote:
This patch adds PCDs and updates the fdf file for N1Sdp
platform specific configurations.

Signed-off-by: Deepak Pandey <Deepak.Pandey@arm.com>
Signed-off-by: Khasim Syed Mohammed <khasim.mohammed@arm.com>
---
Platform/ARM/N1Sdp/N1SdpPlatform.dec | 98 ++++++++++++++++++++++++++++
Platform/ARM/N1Sdp/N1SdpPlatform.dsc | 37 ++++++++++-
Platform/ARM/N1Sdp/N1SdpPlatform.fdf | 13 +++-
3 files changed, 144 insertions(+), 4 deletions(-)
create mode 100644 Platform/ARM/N1Sdp/N1SdpPlatform.dec

diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.dec b/Platform/ARM/N1Sdp/N1SdpPlatform.dec
new file mode 100644
index 0000000000..d56891b985
--- /dev/null
+++ b/Platform/ARM/N1Sdp/N1SdpPlatform.dec
@@ -0,0 +1,98 @@
+## @file
+# Describes the N1Sdp configuration.
+#
+# Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x0001001A
+ PACKAGE_NAME = N1SdpPlatform
+ PACKAGE_GUID = 29aacb23-61e8-4fe2-8a06-793537cd26e9
+ PACKAGE_VERSION = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+# Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+
+[LibraryClasses]
+ ArmPlatformLib|Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLib.inf
+
+[Guids.common]
+ gArmN1SdpTokenSpaceGuid = { 0xd8f1624a, 0x98c1, 0x4f64, { 0xa6, 0x41, 0x19, 0x5e, 0xb5, 0x3b, 0x26, 0x0f } }
+
+[PcdsFixedAtBuild]
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskBase|0x88000000|UINT32|0x00000001
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSize|0x18000000|UINT32|0x00000002
+
+ # PCIe
+ gArmN1SdpTokenSpaceGuid.PcdPcieExpressBaseAddress|0x70000000|UINT32|0x00000007
+
+ # External memory
+ gArmNeoverseN1SocTokenSpaceGuid.PcdExtMemorySpace|0|UINT64|0x00000029
+
+[PcdsFeatureFlag.common]
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSupported|FALSE|BOOLEAN|0x00000003
+
+[PcdsFixedAtBuild.common]
+ # CoreSight Debug and Trace components
+ # CoreSight ETMs
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm0Base|0x402040000|UINT64|0x0000002D
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm0MaxBase|0x402040FFF|UINT64|0x0000002E
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm1Base|0x402140000|UINT64|0x0000002F
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm1MaxBase|0x402140FFF|UINT64|0x00000030
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm2Base|0x403040000|UINT64|0x00000031
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm2MaxBase|0x403040FFF|UINT64|0x00000032
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm3Base|0x403140000|UINT64|0x00000033
+ gArmN1SdpTokenSpaceGuid.PcdCsEtm3MaxBase|0x403140FFF|UINT64|0x00000034
+
+ # CoreSight TMC (ETRs/ETFs/ETBs)
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf0Base|0x400410000|UINT64|0x00000035
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf0MaxBase|0x400410FFF|UINT64|0x00000036
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf1Base|0x400420000|UINT64|0x00000037
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf1MaxBase|0x400420FFF|UINT64|0x00000038
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf2Base|0x400010000|UINT64|0x00000039
+ gArmN1SdpTokenSpaceGuid.PcdCsEtf2MaxBase|0x400010FFF|UINT64|0x0000003A
+ gArmN1SdpTokenSpaceGuid.PcdCsEtrBase|0x400120000|UINT64|0x00000043
+ gArmN1SdpTokenSpaceGuid.PcdCsEtrMaxBase|0x400120FFF|UINT64|0x00000044
+
+ # CoreSight Dynamic Funnel(s)
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel0Base|0x4000B0000|UINT64|0x0000003B
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel0MaxBase|0x4000B0FFF|UINT64|0x0000003C
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel1Base|0x4000A0000|UINT64|0x0000003D
+ gArmN1SdpTokenSpaceGuid.PcdCsFunnel1MaxBase|0x4000A0FFF|UINT64|0x0000003E
+
+ # CoreSight Dynamic Replicator(s)
+ gArmN1SdpTokenSpaceGuid.PcdCsReplicatorBase|0x400110000|UINT64|0x0000003F
+ gArmN1SdpTokenSpaceGuid.PcdCsReplicatorMaxBase|0x400110FFF|UINT64|0x00000040
+
+ # CoreSight TPIU
+ gArmN1SdpTokenSpaceGuid.PcdCsTpiuBase|0x400130000|UINT64|0x00000041
+ gArmN1SdpTokenSpaceGuid.PcdCsTpiuMaxBase|0x400130FFF|UINT64|0x00000042
+
+ # CoreSight STM and STM Stimulus
+ gArmN1SdpTokenSpaceGuid.PcdCsStmBase|0x400800000|UINT64|0x00000045
+ gArmN1SdpTokenSpaceGuid.PcdCsStmMaxBase|0x400800FFF|UINT64|0x00000046
+ gArmN1SdpTokenSpaceGuid.PcdCsStmStimulusBase|0x4D000000|UINT32|0x00000047
+ gArmN1SdpTokenSpaceGuid.PcdCsStmStimulusSize|0x1000000|UINT32|0x00000048
+
+ # CoreSight Components' Size
+ #
+ # Newton TRMs specify the size for these coresight components as 64K.
+ # The actual size is just 4K though 64K is reserved. Access to the
+ # unmapped reserved region results in a DECERR response.
+ #
+ gArmN1SdpTokenSpaceGuid.PcdCsComponentSize|0x1000|UINT32|0x00000049
+
+ # Remote Chip PCIe
+ gArmN1SdpTokenSpaceGuid.PcdRemotePcieIoTranslation|0x40075200000|UINT64|0x0000004A
+ gArmN1SdpTokenSpaceGuid.PcdRemotePcieMmio32Translation|0x40000000000|UINT64|0x0000004B
+ gArmN1SdpTokenSpaceGuid.PcdRemotePcieMmio64Translation|0x40000000000|UINT64|0x0000004C
diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.dsc b/Platform/ARM/N1Sdp/N1SdpPlatform.dsc
index 61e7a909f8..0bc3fa6dfe 100644
--- a/Platform/ARM/N1Sdp/N1SdpPlatform.dsc
+++ b/Platform/ARM/N1Sdp/N1SdpPlatform.dsc
@@ -1,8 +1,18 @@
+## @file
+# Component Description File for N1Sdp
#
-# Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
+# This provides platform specific component descriptions and libraries that
+# conform to EFI/Framework standards.
#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
+# Copyright (c) 2018 - 2021, ARM Limited. All rights reserved.<BR>
#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+# IMPLIED.
+#
[SAMI] Is the above disclaimer required? Is the "SPDX-License-Identifier: BSD-2-Clause-Patent" not sufficient? I think I noticed something similar in another patch.
Can you check, please?
[/SAMI]
+##
################################################################################
#
@@ -33,6 +43,9 @@
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+ # file explorer library support
+ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+
[LibraryClasses.common.SEC]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
@@ -71,6 +84,9 @@
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+!if $(TARGET) != RELEASE
+ DebugLib|MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
+!endif
[LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -82,11 +98,16 @@
################################################################################
[PcdsFeatureFlag.common]
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSupported|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
[PcdsFixedAtBuild.common]
gArmTokenSpaceGuid.PcdVFPEnabled|1
+ # RAM Disk
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskBase|0x88000000
+ gArmN1SdpTokenSpaceGuid.PcdRamDiskSize|0x18000000
+
# Stacks for MPCores in Normal World
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x80000000
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x40000
@@ -99,6 +120,9 @@
# Secondary DDR memory
gArmNeoverseN1SocTokenSpaceGuid.PcdDramBlock2Base|0x8080000000
+ # External memory
+ gArmNeoverseN1SocTokenSpaceGuid.PcdExtMemorySpace|0x40000000000
+
# GIC Base Addresses
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C000000
gArmTokenSpaceGuid.PcdGicDistributorBase|0x30000000
@@ -198,6 +222,9 @@
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
}
+ # Platform driver
+ Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.inf
+
# Human Interface Support
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
@@ -236,6 +263,9 @@
# SATA Controller
MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
+ # NVMe boot devices
+ MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
# Usb Support
MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
@@ -244,3 +274,6 @@
MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf
+
+ # RAM Disk
+ MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.fdf b/Platform/ARM/N1Sdp/N1SdpPlatform.fdf
index c4e1f7b4b8..6b097438ad 100644
--- a/Platform/ARM/N1Sdp/N1SdpPlatform.fdf
+++ b/Platform/ARM/N1Sdp/N1SdpPlatform.fdf
@@ -1,8 +1,10 @@
+## @file
+# FDF file of N1Sdp
#
-# Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.
+# Copyright (c) 2018 - 2021, ARM Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
+##
################################################################################
#
@@ -109,6 +111,9 @@ READ_LOCK_STATUS = TRUE
# SATA Controller
INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
+ # NVMe boot devices
+ INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
# Usb Support
INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
@@ -137,10 +142,14 @@ READ_LOCK_STATUS = TRUE
# FV FileSystem
INF MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf
+ INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
# UEFI applications
INF ShellPkg/Application/Shell/Shell.inf
+ # Platform driver
+ INF Platform/ARM/N1Sdp/Drivers/PlatformDxe/PlatformDxe.inf
+
# Bds
INF MdeModulePkg/Application/UiApp/UiApp.inf
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf


[PATCH v1 1/1] MdePkg/Include: Smbios Specification 3.5.0 changes

Abdul Lateef Attar
 

Adds following changes
1) Added support for manufacturing mode in
BIOS Characteristics Extension Byte 2.
2) Added support for slot height in
System Slot Table (type 9).
3) Updated Built-in pointing device interface with
USB, I2C and SPI.
4) Updates Onboard Devices Extended Information with
wireless LAN, bluetooth, WWAN, eMMC, NVMe and UFC.
5) Added new table Firmware Inventory Information (Type 45)
and its corresponding enum values.
6) Added new table String Property Table (Type 46)
and its corresponding enum values.

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Abdul Lateef Attar <abdattar@amd.com>
---
MdePkg/Include/IndustryStandard/SmBios.h | 144 +++++++++++++++++++-
1 file changed, 140 insertions(+), 4 deletions(-)

diff --git a/MdePkg/Include/IndustryStandard/SmBios.h b/MdePkg/Include/IndustryStandard/SmBios.h
index 2c2b32b8d462..62c96987aae2 100644
--- a/MdePkg/Include/IndustryStandard/SmBios.h
+++ b/MdePkg/Include/IndustryStandard/SmBios.h
@@ -1,9 +1,10 @@
/** @file
- Industry Standard Definitions of SMBIOS Table Specification v3.3.0.
+ Industry Standard Definitions of SMBIOS Table Specification v3.5.0.

Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2015-2017 Hewlett Packard Enterprise Development LP<BR>
(C) Copyright 2015 - 2019 Hewlett Packard Enterprise Development LP<BR>
+Copyright (c) 2021, AMD Incorporated. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/
@@ -94,6 +95,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE 42
#define SMBIOS_TYPE_TPM_DEVICE 43
#define SMBIOS_TYPE_PROCESSOR_ADDITIONAL_INFORMATION 44
+#define SMBIOS_TYPE_FIRMWARE_INVENTORY_INFORMATION 45
+#define SMBIOS_TYPE_STRING_PROPERTY_INFORMATION 46

///
/// Inactive type is added from SMBIOS 2.2. Reference SMBIOS 2.6, chapter 3.3.43.
@@ -252,7 +255,9 @@ typedef struct {
UINT8 TargetContentDistributionEnabled :1;
UINT8 UefiSpecificationSupported :1;
UINT8 VirtualMachineSupported :1;
- UINT8 ExtensionByte2Reserved :3;
+ UINT8 ManufacturingModeSupported :1;
+ UINT8 ManufacturingModeEnabled :1;
+ UINT8 ExtensionByte2Reserved :1;
} MBCE_SYSTEM_RESERVED;

///
@@ -1402,6 +1407,17 @@ typedef struct {
UINT8 Reserved :1; ///< Set to 0.
} MISC_SLOT_CHARACTERISTICS2;

+///
+/// System Slots - Slot Height
+///
+typedef enum {
+ SlotHeightNone = 0x00,
+ SlotHeightOther = 0x01,
+ SlotHeightUnknown = 0x02,
+ SlotHeightFullHeight = 0x03,
+ SlotHeightLowProfile = 0x04
+} MISC_SLOT_HEIGHT;
+
///
/// System Slots - Peer Segment/Bus/Device/Function/Width Groups
///
@@ -1447,6 +1463,10 @@ typedef struct {
UINT8 SlotInformation;
UINT8 SlotPhysicalWidth;
UINT16 SlotPitch;
+ //
+ // Add for smbios 3.5
+ //
+ UINT8 SlotHeight; ///< The enumeration value from MISC_SLOT_HEIGHT.
} SMBIOS_TABLE_TYPE9;

///
@@ -2007,7 +2027,9 @@ typedef enum {
PointingDeviceInterfaceADB = 0x08,
PointingDeviceInterfaceBusMouseDB9 = 0xA0,
PointingDeviceInterfaceBusMouseMicroDin = 0xA1,
- PointingDeviceInterfaceUsb = 0xA2
+ PointingDeviceInterfaceUsb = 0xA2,
+ PointingDeviceInterfaceI2c = 0xA3,
+ PointingDeviceInterfaceSpi = 0xA4
} BUILTIN_POINTING_DEVICE_INTERFACE;

///
@@ -2511,7 +2533,13 @@ typedef enum{
OnBoardDeviceExtendedTypeSound = 0x07,
OnBoardDeviceExtendedTypePATAController = 0x08,
OnBoardDeviceExtendedTypeSATAController = 0x09,
- OnBoardDeviceExtendedTypeSASController = 0x0A
+ OnBoardDeviceExtendedTypeSASController = 0x0A,
+ OnBoardDeviceExtendedTypeWirelessLAN = 0x0B,
+ OnBoardDeviceExtendedTypeBluetooth = 0x0C,
+ OnBoardDeviceExtendedTypeWWAN = 0x0D,
+ OnBoardDeviceExtendedTypeeMMC = 0x0E,
+ OnBoardDeviceExtendedTypeNvme = 0x0F,
+ OnBoardDeviceExtendedTypeUfc = 0x10
} ONBOARD_DEVICE_EXTENDED_INFO_TYPE;

///
@@ -2650,6 +2678,112 @@ typedef struct {
UINT32 OemDefined;
} SMBIOS_TABLE_TYPE43;

+///
+/// Firmware Inventory Version Format Type (Type 45).
+///
+typedef enum {
+ VersionFormatTypeFreeForm = 0x00,
+ VersionFormatTypeMajorMinor = 0x01,
+ VersionFormatType32BitHex = 0x02,
+ VersionFormatType64BitHex = 0x03,
+ VersionFormatTypeReserved = 0x04, /// 0x04 – 0x7F are reserved
+ VersionFormatTypeOem = 0x80 /// 0x80 - 0xFF are BIOS Vendor/OEM-specific
+} FIRMWARE_INVENTORY_VERSION_FORMAT_TYPE;
+
+///
+/// Firmware Inventory Firmware Id Format Type (Type 45).
+///
+typedef enum {
+ FirmwareIdFormatTypeFreeForm = 0x00,
+ FirmwareIdFormatTypeUuid = 0x01,
+ FirmwareIdFormatTypeReserved = 0x04, /// 0x04 – 0x7F are reserved
+ InventoryFirmwareIdFormatTypeOem = 0x80 /// 0x80 - 0xFF are BIOS Vendor/OEM-specific
+} FIRMWARE_INVENTORY_FIRMWARE_ID_FORMAT_TYPE;
+
+///
+/// Firmware Inventory Firmware Characteristics (Type 45).
+///
+typedef enum {
+ CharacteristicsUpdatable = 0x00,
+ CharacteristicsWriteProtected = 0x01,
+ CharacteristicsReserved = 0x02 /// 0x02 - 0x0F are reserved
+} FIRMWARE_INVENTORY_CHARACTERISTICS;
+
+///
+/// Firmware Inventory State Information (Type 45).
+///
+typedef enum {
+ FirmwareInventoryStateOther = 0x01,
+ FirmwareInventoryStateUnknown = 0x02,
+ FirmwareInventoryStateDisabled = 0x03,
+ FirmwareInventoryStateEnabled = 0x04,
+ FirmwareInventoryStateAbsent = 0x05,
+ FirmwareInventoryStateStandbyOffline = 0x06,
+ FirmwareInventoryStateStandbySpare = 0x07,
+ FirmwareInventoryStateUnavailableOffline = 0x08,
+} FIRMWARE_INVENTORY_STATE;
+
+///
+/// Firmware Inventory Information (Type 45)
+///
+/// The information in this structure defines an inventory of firmware
+/// components in the system. This can include firmware components such as
+/// BIOS, BMC, as well as firmware for other devices in the system.
+/// The information can be used by software to display the firmware inventory
+/// in a uniform manner. It can also be used by a management controller,
+/// such as a BMC, for remote system management.
+/// This structure is not intended to replace other standard programmatic
+/// interfaces for firmware updates.
+/// One Type 45 structure is provided for each firmware component.
+///
+typedef struct {
+ SMBIOS_STRUCTURE Hdr;
+ SMBIOS_HANDLE RefHandle;
+
+ UINT8 FirmwareComponentName;
+ UINT8 FirmwareVersion;
+ UINT8 FirmwareVersionFormat; ///< The enumeration value from FIRMWARE_INVENTORY_VERSION_FORMAT_TYPE
+ UINT8 FirmwareId;
+ UINT8 FirmwareIdFormat;
+ UINT8 ReleaseDate;
+ UINT8 Manufacturer;
+ UINT8 LowestSupportedVersion;
+ UINT64 ImageSize;
+ UINT32 Characteristics;
+ UINT8 State;
+ UINT8 AssociatedComponentCount;
+ ///
+ /// zero or n-number of handles depends on AssociatedComponentCount
+ /// handles are of type SMBIOS_HANDLE
+ ///
+} SMBIOS_TABLE_TYPE45;
+
+///
+/// String Property IDs (Type 46).
+///
+typedef enum {
+ StringPropertyIdNone = 0x0000,
+ StringPropertyIdDevicePath = 0x0001,
+ StringPropertyIdReserved = 0x0002, /// Reserved 0x0002 - 0x7FFF
+ StringPropertyIdBiosVendor = 0x8000, /// BIOS vendor 0x8000 - 0xBFFF
+ StringPropertyIdOem = 0xC000 /// OEM range 0xC000 - 0xFFFF
+} STRING_PROPERTY_ID;
+
+///
+/// This structure defines a string property for another structure.
+/// This allows adding string properties that are common to several structures
+/// without having to modify the definitions of these structures.
+/// Multiple type 46 structures can add string properties to the same
+/// parent structure.
+///
+typedef struct {
+ SMBIOS_STRUCTURE Hdr;
+ SMBIOS_HANDLE RefHandle;
+ UINT16 StringPropertyId;
+ UINT8 StringPropertyValue;
+ SMBIOS_HANDLE ParentHandle;
+} SMBIOS_TABLE_TYPE46;
+
///
/// Inactive (Type 126)
///
@@ -2714,6 +2848,8 @@ typedef union {
SMBIOS_TABLE_TYPE42 *Type42;
SMBIOS_TABLE_TYPE43 *Type43;
SMBIOS_TABLE_TYPE44 *Type44;
+ SMBIOS_TABLE_TYPE45 *Type45;
+ SMBIOS_TABLE_TYPE46 *Type46;
SMBIOS_TABLE_TYPE126 *Type126;
SMBIOS_TABLE_TYPE127 *Type127;
UINT8 *Raw;
--
2.25.1


[PATCH v1 0/1] MdePkg/Include SMBIOS 3.5.0 changes

Abdul Lateef Attar
 

Resubmitting the correct patch.
Changes to include Smbios 3.5.0 specfication delta.

Reference: https://github.com/abdattar/edk2/tree/smbios_3_5_0

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>

Abdul Lateef Attar (1):
MdePkg/Include: Smbios Specification 3.5.0 changes

MdePkg/Include/IndustryStandard/SmBios.h | 144 +++++++++++++++++++-
1 file changed, 140 insertions(+), 4 deletions(-)

--
2.25.1


Re: [PATCH v2 3/4] OvmfPkg: Enable physical presence interface for TPM 1.2

Gerd Hoffmann
 

On Tue, Nov 02, 2021 at 11:49:09AM -0400, Stefan Berger wrote:
Enable the physical presence interface for TPM 1.2. It is required for the
TPM 1.2 menu to work.

The changes to DxeTcgPhysicalPresenceLib.c are due to the device we are using
in QEMU for presenting the supported PPI commands and results to the OS via
ACPI as well as to store the PPI opcode to execute.
Fails to build for microvm.

+ TcgPhysicalPresenceLib|OvmfPkg/Library/TcgPhysicalPresenceLibNull/DxeTcgPhysicalPresenceLib.inf
I guess this line is needed just next to Tcg2PhysicalPresenceLibNull
line?

(same problem on OvmfXen.dsc)

take care,
Gerd


[PATCH v1] MdePkg/Include: Smbios Specification 3.5.0 changes

Abdul Lateef Attar
 

6381 - 6400 of 89698