From: "Nhi Pham" <nhi@os.amperecomputing.com>
To: devel@edk2.groups.io
Cc: patches@amperecomputing.com, nhi@os.amperecomputing.com,
vunguyen@os.amperecomputing.com,
Thang Nguyen <thang@os.amperecomputing.com>,
Chuong Tran <chuong@os.amperecomputing.com>,
Phong Vo <phong@os.amperecomputing.com>,
Leif Lindholm <leif@nuviainc.com>,
Michael D Kinney <michael.d.kinney@intel.com>,
Ard Biesheuvel <ardb+tianocore@kernel.org>,
Nate DeSimone <nathaniel.l.desimone@intel.com>
Subject: [edk2-platforms][PATCH v5 18/30] JadePkg: Add ACPI tables to support PCIe
Date: Wed, 17 Nov 2021 23:47:15 +0700 [thread overview]
Message-ID: <20211117164727.10922-19-nhi@os.amperecomputing.com> (raw)
In-Reply-To: <20211117164727.10922-1-nhi@os.amperecomputing.com>
From: Vu Nguyen <vunguyen@os.amperecomputing.com>
Add IORT and MCFG tables to let the OS discover the PCIe resources. This
driver also fixup the DSDT table to adapt with the difference between 1P
and 2P system.
Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
Acked-by: Leif Lindholm <leif@nuviainc.com>
---
Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf | 4 +
Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h | 12 +
Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h | 60 ++++
Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c | 90 +++++
Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiIort.c | 349 ++++++++++++++++++++
Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMcfg.c | 151 +++++++++
Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c | 10 +
7 files changed, 676 insertions(+)
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
index 72e78fb4e31e..415f795d2a54 100644
--- a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
@@ -18,7 +18,9 @@ [Sources.common]
AcpiApei.c
AcpiApei.h
AcpiDsdt.c
+ AcpiIort.c
AcpiMadt.c
+ AcpiMcfg.c
AcpiNfit.c
AcpiPcct.c
AcpiPlatform.h
@@ -43,6 +45,7 @@ [LibraryClasses]
BaseLib
DebugLib
FlashLib
+ HobLib
MailboxInterfaceLib
SystemFirmwareInterfaceLib
TimerLib
@@ -66,6 +69,7 @@ [Guids]
gEfiAcpiTableGuid
gEfiEventReadyToBootGuid
gPlatformInfoHobGuid
+ gRootComplexInfoHobGuid
[Protocols]
gEfiAcpiTableProtocolGuid ## ALWAYS_CONSUMED
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h
index b5035067a47b..170aeff24d59 100644
--- a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h
@@ -71,4 +71,16 @@ AcpiInstallSratTable (
VOID
);
+EFI_STATUS
+EFIAPI
+AcpiInstallMcfg (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+AcpiInstallIort (
+ VOID
+ );
+
#endif /* ACPI_PLATFORM_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h b/Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h
index 132c0d6d6cac..d45688f88401 100644
--- a/Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h
@@ -279,4 +279,64 @@
//
#define AC01_PCIE_MMIO32_SIZE_1P_LIST 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x8000000, 0x10000000, 0x10000000, 0x10000000, 0, 0, 0, 0, 0, 0, 0, 0
+//
+// DSDT RCA2 PCIe MMIO32 Attribute
+//
+#define AC01_PCIE_RCA2_QMEM_LIST 0x0000000000000000, 0x0000000060000000, 0x000000006FFFFFFF, 0x0000000000000000, 0x0000000010000000
+
+//
+// DSDT RCA3 PCIe MMIO32 Attribute
+//
+#define AC01_PCIE_RCA3_QMEM_LIST 0x0000000000000000, 0x0000000070000000, 0x000000007FFFFFFF, 0x0000000000000000, 0x0000000010000000
+
+//
+// DSDT RCB0 PCIe MMIO32 Attribute
+//
+#define AC01_PCIE_RCB0_QMEM_LIST 0x0000000000000000, 0x0000000001000000, 0x000000000FFFFFFF, 0x0000000000000000, 0x000000000F000000
+
+//
+// DSDT RCB1 PCIe MMIO32 Attribute
+//
+#define AC01_PCIE_RCB1_QMEM_LIST 0x0000000000000000, 0x0000000010000000, 0x000000001FFFFFFF, 0x0000000000000000, 0x0000000010000000
+
+//
+// DSDT RCB2 PCIe MMIO32 Attribute
+//
+#define AC01_PCIE_RCB2_QMEM_LIST 0x0000000000000000, 0x0000000020000000, 0x000000002FFFFFFF, 0x0000000000000000, 0x0000000010000000
+
+//
+// DSDT RCB3 PCIe MMIO32 Attribute
+//
+#define AC01_PCIE_RCB3_QMEM_LIST 0x0000000000000000, 0x0000000030000000, 0x000000003FFFFFFF, 0x0000000000000000, 0x0000000010000000
+
+//
+// TBU PMU IRQ array
+//
+#define AC01_SMMU_TBU_PMU_IRQS_LIST 224, 230, 236, 242, 160, 170, 180, 190, 544, 550, 556, 562, 480, 490, 500, 510
+
+//
+// TCU PMU IRQ array
+//
+#define AC01_SMMU_TCU_PMU_IRQS_LIST 256, 257, 258, 259, 260, 261, 262, 263, 576, 577, 578, 579, 580, 581, 582, 583
+
+//
+// Max TBU PMU of Root Complex A
+//
+#define AC01_RCA_MAX_TBU_PMU 6
+
+//
+// Max TBU PMU of Root Complex B
+//
+#define AC01_RCB_MAX_TBU_PMU 10
+
+//
+// TBU Base offset of Root Complex A
+//
+#define AC01_RCA_TBU_PMU_OFFSET_LIST 0x40000, 0x60000, 0xA0000, 0xE0000, 0x100000, 0x140000
+
+//
+// TBU Base offset of Root Complex B
+//
+#define AC01_RCB_TBU_PMU_OFFSET_LIST 0x40000, 0x60000, 0xA0000, 0xE0000, 0x120000, 0x160000, 0x180000, 0x1C0000, 0x200000, 0x240000
+
#endif /* PLATFORM_AC01_H_ */
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c
index 82bfbb90f07f..885ad8fc3511 100644
--- a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c
@@ -6,6 +6,7 @@
**/
+#include <Guid/RootComplexInfoHob.h>
#include <Protocol/PciRootBridgeIo.h>
#include <Library/NVParamLib.h>
#include <NVParamDef.h>
@@ -40,6 +41,24 @@ typedef struct {
OP_REGION_DWORD_DATA RegionBase;
OP_REGION_DWORD_DATA RegionLen;
} AML_OP_REGION;
+
+typedef struct {
+ UINT64 AddressGranularity;
+ UINT64 AddressMin;
+ UINT64 AddressMax;
+ UINT64 AddressTranslation;
+ UINT64 RangeLength;
+} QWORD_MEMORY;
+
+STATIC QWORD_MEMORY mQMemList[] = {
+ { AC01_PCIE_RCA2_QMEM_LIST },
+ { AC01_PCIE_RCA3_QMEM_LIST },
+ { AC01_PCIE_RCB0_QMEM_LIST },
+ { AC01_PCIE_RCB1_QMEM_LIST },
+ { AC01_PCIE_RCB2_QMEM_LIST },
+ { AC01_PCIE_RCB3_QMEM_LIST }
+};
+
#pragma pack()
EFI_STATUS
@@ -543,6 +562,76 @@ AcpiPatchPcieAerFwFirst (
return Status;
}
+VOID
+AcpiPatchPcieMmio32 (
+ EFI_ACPI_SDT_PROTOCOL *AcpiSdtProtocol,
+ EFI_ACPI_HANDLE TableHandle
+ )
+{
+ AC01_ROOT_COMPLEX *RootComplexList;
+ CHAR8 *NextDescriptor, *Buffer;
+ CHAR8 NodePath[256];
+ EFI_ACPI_DATA_TYPE DataType;
+ EFI_ACPI_HANDLE ObjectHandle;
+ EFI_STATUS Status;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
+ UINTN DataSize;
+ UINTN Idx;
+ VOID *Hob;
+
+ Hob = GetFirstGuidHob (&gRootComplexInfoHobGuid);
+ if (Hob == NULL) {
+ return;
+ }
+
+ RootComplexList = (AC01_ROOT_COMPLEX *)GET_GUID_HOB_DATA (Hob);
+
+ for (Idx = 0; Idx < AC01_PCIE_MAX_ROOT_COMPLEX; Idx++) {
+ if (!RootComplexList[Idx].Active) {
+ //
+ // Patch for disabled Root Complex
+ //
+ AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.PCI%X._STA", Idx);
+ UpdateStatusMethodObject (AcpiSdtProtocol, TableHandle, NodePath, 0x0);
+ continue;
+ }
+
+ if (!IsSlaveSocketActive () && Idx <= SOCKET0_LAST_RC) {
+ //
+ // Patch MMIO32 resource in 1P system
+ //
+ AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.PCI%X.RBUF", Idx);
+ Status = AcpiSdtProtocol->FindPath (TableHandle, NodePath, &ObjectHandle);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ Status = AcpiSdtProtocol->GetOption (ObjectHandle, 2, &DataType, (VOID *)&Buffer, &DataSize);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ if (DataType != EFI_ACPI_DATA_TYPE_CHILD) {
+ AcpiSdtProtocol->Close (ObjectHandle);
+ continue;
+ }
+
+ NextDescriptor = Buffer + 5; // Point to first address space descriptor
+ while ((NextDescriptor - Buffer) < DataSize) {
+ Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)NextDescriptor;
+ if (Descriptor->Desc == ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR
+ && Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
+ CopyMem (&Descriptor->AddrSpaceGranularity, &mQMemList[Idx - 2], sizeof (QWORD_MEMORY));
+ break;
+ }
+ NextDescriptor += (Descriptor->Len + sizeof (ACPI_LARGE_RESOURCE_HEADER));
+ }
+
+ AcpiSdtProtocol->Close (ObjectHandle);
+ }
+ }
+}
+
EFI_STATUS
AcpiPatchDsdtTable (
VOID
@@ -593,6 +682,7 @@ AcpiPatchDsdtTable (
AcpiPatchNvdimm (AcpiSdtProtocol, TableHandle);
AcpiPatchPcieNuma (AcpiSdtProtocol, TableHandle);
AcpiPatchPcieAerFwFirst (AcpiSdtProtocol, TableHandle);
+ AcpiPatchPcieMmio32 (AcpiSdtProtocol, TableHandle);
AcpiSdtProtocol->Close (TableHandle);
AcpiUpdateChecksum ((UINT8 *)Table, Table->Length);
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiIort.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiIort.c
new file mode 100644
index 000000000000..b8f8cfa356af
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiIort.c
@@ -0,0 +1,349 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <AcpiHeader.h>
+#include <Guid/RootComplexInfoHob.h>
+#include <IndustryStandard/Acpi30.h>
+#include <IndustryStandard/IoRemappingTable.h>
+#include <Library/AcpiLib.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Platform/Ac01.h>
+#include <Protocol/AcpiTable.h>
+
+#define __AC01_ID_MAPPING(In, Num, Out, Ref, Flags) \
+ { \
+ In, \
+ Num, \
+ Out, \
+ OFFSET_OF (AC01_IO_REMAPPING_STRUCTURE, Ref), \
+ Flags \
+ }
+
+#define TCU_TO_SMMU_OFFSET 0x2000
+#define PAGE1_TO_PMCG_OFFSET 0x10000
+
+STATIC AC01_ROOT_COMPLEX *mRootComplexList;
+
+STATIC UINT32 mTbuPmuIrqArray[] = { AC01_SMMU_TBU_PMU_IRQS_LIST };
+STATIC UINT32 mTcuPmuIrqArray[] = { AC01_SMMU_TCU_PMU_IRQS_LIST };
+STATIC UINT64 mRcaTbuPmuOffset[] = { AC01_RCA_TBU_PMU_OFFSET_LIST };
+STATIC UINT64 mRcbTbuPmuOffset[] = { AC01_RCB_TBU_PMU_OFFSET_LIST };
+
+#pragma pack(1)
+
+typedef struct {
+ EFI_ACPI_6_0_IO_REMAPPING_NODE Node;
+ UINT64 Base;
+ UINT32 Flags;
+ UINT32 Reserved;
+ UINT64 VatosAddress;
+ UINT32 Model;
+ UINT32 Event;
+ UINT32 Pri;
+ UINT32 Gerr;
+ UINT32 Sync;
+ UINT32 ProximityDomain;
+ UINT32 DeviceIdMapping;
+} EFI_ACPI_6_2_IO_REMAPPING_SMMU3_NODE;
+
+typedef struct {
+ EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE Node;
+ UINT32 ItsIdentifier;
+} AC01_ITS_NODE;
+
+typedef struct {
+ EFI_ACPI_6_0_IO_REMAPPING_RC_NODE Node;
+ EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE RcIdMapping;
+} AC01_RC_NODE;
+
+typedef struct {
+ EFI_ACPI_6_2_IO_REMAPPING_SMMU3_NODE Node;
+ EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE InterruptMsiMapping;
+ EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE InterruptMsiMappingSingle;
+} AC01_SMMU_NODE;
+
+typedef struct {
+ EFI_ACPI_6_0_IO_REMAPPING_TABLE Iort;
+ AC01_ITS_NODE ItsNode[2];
+ AC01_RC_NODE RcNode[2];
+ AC01_SMMU_NODE SmmuNode[2];
+} AC01_IO_REMAPPING_STRUCTURE;
+
+#pragma pack()
+
+EFI_ACPI_6_0_IO_REMAPPING_TABLE mIortHeader = {
+ .Header = __ACPI_HEADER (
+ EFI_ACPI_6_0_IO_REMAPPING_TABLE_SIGNATURE,
+ AC01_IO_REMAPPING_STRUCTURE,
+ EFI_ACPI_IO_REMAPPING_TABLE_REVISION
+ ),
+ .NumNodes = 0, // To be filled
+ .NodeOffset = sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE),
+ 0
+};
+
+AC01_ITS_NODE mItsNodeTemplate = {
+ .Node = {
+ {
+ EFI_ACPI_IORT_TYPE_ITS_GROUP,
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE) + 4,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ },
+ .NumItsIdentifiers = 1,
+ },
+ .ItsIdentifier = 1,
+};
+
+AC01_RC_NODE mRcNodeTemplate = {
+ {
+ {
+ EFI_ACPI_IORT_TYPE_ROOT_COMPLEX,
+ sizeof (AC01_RC_NODE),
+ 0x1,
+ 0x0,
+ 0x1,
+ OFFSET_OF (AC01_RC_NODE, RcIdMapping),
+ },
+ EFI_ACPI_IORT_MEM_ACCESS_PROP_CCA,
+ 0x0,
+ 0x0,
+ EFI_ACPI_IORT_MEM_ACCESS_FLAGS_CPM |
+ EFI_ACPI_IORT_MEM_ACCESS_FLAGS_DACS,
+ EFI_ACPI_IORT_ROOT_COMPLEX_ATS_UNSUPPORTED,
+ .PciSegmentNumber = 0,
+ .MemoryAddressSize = 64,
+ },
+ __AC01_ID_MAPPING (0x0, 0xffff, 0x0, SmmuNode, 0),
+};
+
+AC01_SMMU_NODE mSmmuNodeTemplate = {
+ {
+ {
+ EFI_ACPI_IORT_TYPE_SMMUv3,
+ sizeof (AC01_SMMU_NODE),
+ 0x2, // Revision
+ 0x0,
+ 0x2, // Mapping Count
+ OFFSET_OF (AC01_SMMU_NODE, InterruptMsiMapping),
+ },
+ .Base = 0,
+ EFI_ACPI_IORT_SMMUv3_FLAG_COHAC_OVERRIDE | EFI_ACPI_IORT_SMMUv3_FLAG_PROXIMITY_DOMAIN,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0x0,
+ 0x0,
+ 0, // Proximity domain - need fill in
+ .DeviceIdMapping = 1,
+ },
+ __AC01_ID_MAPPING (0x0, 0xffff, 0, SmmuNode, 0),
+ __AC01_ID_MAPPING (0x0, 0x1, 0, SmmuNode, 1),
+};
+
+EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE mPmcgNodeTemplate = {
+ {
+ EFI_ACPI_IORT_TYPE_PMCG,
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE),
+ 0x1,
+ 0x0,
+ 0x0,
+ 0x0,
+ },
+ 0, // Page 0 Base. Need to be filled
+ 0, // GSIV. Need to be filled
+ 0, // Node reference. Need to be filled
+ 0, // Page 1 Base. Need to be filled
+};
+
+STATIC
+VOID
+ConstructIort (
+ VOID *IortBuffer,
+ UINT32 RcCount,
+ UINT32 SmmuPmuAgentCount,
+ UINT32 HeaderCount,
+ INT32 *EnabledRCs
+ )
+{
+ AC01_ROOT_COMPLEX *RootComplex;
+ UINT32 Idx, Idx1;
+ UINT32 ItsOffset[AC01_PCIE_MAX_ROOT_COMPLEX];
+ UINT32 SmmuNodeOffset[AC01_PCIE_MAX_ROOT_COMPLEX];
+ UINT64 *TbuPmuOffset;
+ UINTN MaxTbuPmu;
+ VOID *IortIter, *SmmuIter, *PmcgIter;
+
+ IortIter = IortBuffer;
+ mIortHeader.Header.Length = HeaderCount;
+ mIortHeader.NumNodes = (3 * RcCount) + SmmuPmuAgentCount,
+ CopyMem (IortIter, &mIortHeader, sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE));
+
+ IortIter += sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE);
+ for (Idx = 0; Idx < RcCount; Idx++) {
+ ItsOffset[Idx] = IortIter - IortBuffer;
+ mItsNodeTemplate.ItsIdentifier = EnabledRCs[Idx];
+ CopyMem (IortIter, &mItsNodeTemplate, sizeof (AC01_ITS_NODE));
+ IortIter += sizeof (AC01_ITS_NODE);
+ }
+
+ SmmuIter = IortIter + RcCount * sizeof (AC01_RC_NODE);
+ PmcgIter = SmmuIter + RcCount * sizeof (AC01_SMMU_NODE);
+ for (Idx = 0; Idx < RcCount; Idx++) {
+ SmmuNodeOffset[Idx] = SmmuIter - IortBuffer;
+ RootComplex = &mRootComplexList[EnabledRCs[Idx]];
+ mSmmuNodeTemplate.Node.Base = RootComplex->TcuBase;
+ mSmmuNodeTemplate.InterruptMsiMapping.OutputBase = EnabledRCs[Idx] << 16;
+ mSmmuNodeTemplate.InterruptMsiMapping.OutputReference = ItsOffset[Idx];
+ mSmmuNodeTemplate.InterruptMsiMappingSingle.OutputBase = EnabledRCs[Idx] << 16;
+ mSmmuNodeTemplate.InterruptMsiMappingSingle.OutputReference = ItsOffset[Idx];
+ /* All RCs on master be assigned to node 0, while remote RCs will be assigned to first remote node */
+ mSmmuNodeTemplate.Node.ProximityDomain = 0;
+ if ((RootComplex->TcuBase & SLAVE_SOCKET_BASE_ADDRESS_OFFSET) != 0) {
+ // RootComplex on remote socket
+ switch (CpuGetSubNumaMode ()) {
+ case SUBNUMA_MODE_MONOLITHIC:
+ mSmmuNodeTemplate.Node.ProximityDomain += MONOLITIC_NUM_OF_REGION;
+ break;
+ case SUBNUMA_MODE_HEMISPHERE:
+ mSmmuNodeTemplate.Node.ProximityDomain += HEMISPHERE_NUM_OF_REGION;
+ break;
+ case SUBNUMA_MODE_QUADRANT:
+ mSmmuNodeTemplate.Node.ProximityDomain += QUADRANT_NUM_OF_REGION;
+ break;
+ }
+ }
+ CopyMem (SmmuIter, &mSmmuNodeTemplate, sizeof (AC01_SMMU_NODE));
+ SmmuIter += sizeof (AC01_SMMU_NODE);
+
+ if (SmmuPmuAgentCount == 0) {
+ continue;
+ }
+
+ //
+ // Add TBU PMCG nodes
+ //
+ if (RootComplex->Type == RootComplexTypeA) {
+ MaxTbuPmu = AC01_RCA_MAX_TBU_PMU;
+ TbuPmuOffset = mRcaTbuPmuOffset;
+ } else {
+ MaxTbuPmu = AC01_RCB_MAX_TBU_PMU;
+ TbuPmuOffset = mRcbTbuPmuOffset;
+ }
+
+ for (Idx1 = 0; Idx1 < MaxTbuPmu; Idx1++) {
+ mPmcgNodeTemplate.Base = RootComplex->TcuBase + TCU_TO_SMMU_OFFSET + TbuPmuOffset[Idx1];
+ mPmcgNodeTemplate.Page1Base = mPmcgNodeTemplate.Base + PAGE1_TO_PMCG_OFFSET;
+ mPmcgNodeTemplate.NodeReference = SmmuNodeOffset[Idx];
+ mPmcgNodeTemplate.OverflowInterruptGsiv = mTbuPmuIrqArray[EnabledRCs[Idx]] + Idx1;
+ CopyMem (PmcgIter, &mPmcgNodeTemplate, sizeof (mPmcgNodeTemplate));
+ PmcgIter += sizeof (mPmcgNodeTemplate);
+ }
+
+ //
+ // Add TCU PMCG node
+ //
+ mPmcgNodeTemplate.Base = RootComplex->TcuBase + TCU_TO_SMMU_OFFSET;
+ mPmcgNodeTemplate.Page1Base = mPmcgNodeTemplate.Base + PAGE1_TO_PMCG_OFFSET;
+ mPmcgNodeTemplate.NodeReference = SmmuNodeOffset[Idx];
+ mPmcgNodeTemplate.OverflowInterruptGsiv = mTcuPmuIrqArray[EnabledRCs[Idx]];
+ CopyMem (PmcgIter, &mPmcgNodeTemplate, sizeof (mPmcgNodeTemplate));
+ PmcgIter += sizeof (mPmcgNodeTemplate);
+ }
+
+ for (Idx = 0; Idx < RcCount; Idx++) {
+ mRcNodeTemplate.Node.PciSegmentNumber = mRootComplexList[EnabledRCs[Idx]].Logical;
+ mRcNodeTemplate.RcIdMapping.OutputReference = SmmuNodeOffset[Idx];
+ CopyMem (IortIter, &mRcNodeTemplate, sizeof (AC01_RC_NODE));
+ IortIter += sizeof (AC01_RC_NODE);
+ }
+}
+
+EFI_STATUS
+EFIAPI
+AcpiInstallIort (
+ VOID
+ )
+{
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
+ EFI_STATUS Status;
+ INT32 EnabledRCs[AC01_PCIE_MAX_ROOT_COMPLEX];
+ UINT32 RcCount, SmmuPmuAgentCount, TotalCount;
+ UINT8 Idx;
+ UINTN TableKey;
+ VOID *Hob;
+ VOID *IortBuffer;
+
+ Hob = GetFirstGuidHob (&gRootComplexInfoHobGuid);
+ if (Hob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ mRootComplexList = (AC01_ROOT_COMPLEX *)GET_GUID_HOB_DATA (Hob);
+
+ for (Idx = 0, RcCount = 0; Idx < AC01_PCIE_MAX_ROOT_COMPLEX; Idx++) {
+ if (mRootComplexList[Idx].Active) {
+ EnabledRCs[RcCount++] = Idx;
+ }
+ }
+ EnabledRCs[RcCount] = -1;
+
+ Status = gBS->LocateProtocol (
+ &gEfiAcpiTableProtocolGuid,
+ NULL,
+ (VOID **)&AcpiTableProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "IORT: Unable to locate ACPI table entry\n"));
+ return Status;
+ }
+
+ SmmuPmuAgentCount = 0;
+ for (Idx = 0; Idx < RcCount; Idx++) {
+ if (mRootComplexList[EnabledRCs[Idx]].Type == RootComplexTypeA) {
+ SmmuPmuAgentCount += AC01_RCA_MAX_TBU_PMU;
+ } else {
+ SmmuPmuAgentCount += AC01_RCB_MAX_TBU_PMU;
+ }
+ // Plus 1 TCU
+ SmmuPmuAgentCount += 1;
+ }
+
+ TotalCount = sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE) +
+ RcCount * (sizeof (AC01_ITS_NODE) + sizeof (AC01_RC_NODE) + sizeof (AC01_SMMU_NODE)) +
+ SmmuPmuAgentCount * sizeof (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE);
+
+ IortBuffer = AllocateZeroPool (TotalCount);
+ if (IortBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ConstructIort (IortBuffer, RcCount, SmmuPmuAgentCount, TotalCount, EnabledRCs);
+
+ Status = AcpiTableProtocol->InstallAcpiTable (
+ AcpiTableProtocol,
+ IortBuffer,
+ TotalCount,
+ &TableKey
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "IORT: Unable to install IORT table entry\n"));
+ }
+
+ FreePool (IortBuffer);
+ return Status;
+}
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMcfg.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMcfg.c
new file mode 100644
index 000000000000..0b04246f06fa
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMcfg.c
@@ -0,0 +1,151 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <AcpiHeader.h>
+#include <Guid/RootComplexInfoHob.h>
+#include <IndustryStandard/Acpi30.h>
+#include <Library/AcpiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Platform/Ac01.h>
+#include <Protocol/AcpiTable.h>
+
+// Required to be 1 to match the kernel quirk for ECAM
+#define EFI_ACPI_MCFG_OEM_REVISION 1
+
+STATIC AC01_ROOT_COMPLEX *mRootComplexList;
+
+#pragma pack(1)
+
+typedef struct
+{
+ UINT64 BaseAddress;
+ UINT16 SegGroupNum;
+ UINT8 StartBusNum;
+ UINT8 EndBusNum;
+ UINT32 Reserved2;
+} EFI_MCFG_CONFIG_STRUCTURE;
+
+typedef struct
+{
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT64 Reserved1;
+} EFI_MCFG_TABLE_CONFIG;
+
+#pragma pack()
+
+EFI_MCFG_TABLE_CONFIG mMcfgHeader = {
+ {
+ EFI_ACPI_6_1_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
+ 0, // To be filled
+ 1,
+ 0x00, // Checksum will be updated at runtime
+ EFI_ACPI_OEM_ID,
+ EFI_ACPI_OEM_TABLE_ID,
+ EFI_ACPI_MCFG_OEM_REVISION,
+ EFI_ACPI_CREATOR_ID,
+ EFI_ACPI_CREATOR_REVISION
+ },
+ 0x0000000000000000, // Reserved
+};
+
+EFI_MCFG_CONFIG_STRUCTURE mMcfgNodeTemplate = {
+ .BaseAddress = 0,
+ .SegGroupNum = 0,
+ .StartBusNum = 0,
+ .EndBusNum = 255,
+ .Reserved2 = 0,
+};
+
+STATIC
+VOID
+ConstructMcfg (
+ VOID *McfgBuffer,
+ UINT32 McfgCount,
+ INT32 *EnabledRCs
+ )
+{
+ AC01_ROOT_COMPLEX *RootComplex;
+ UINT32 Idx;
+ VOID *Iter = McfgBuffer;
+
+ mMcfgHeader.Header.Length = McfgCount;
+ CopyMem (Iter, &mMcfgHeader, sizeof (EFI_MCFG_TABLE_CONFIG));
+
+ Iter += sizeof (EFI_MCFG_TABLE_CONFIG);
+ for (Idx = 0; EnabledRCs[Idx] != -1; Idx++) {
+ RootComplex = &mRootComplexList[EnabledRCs[Idx]];
+ mMcfgNodeTemplate.BaseAddress = RootComplex->MmcfgBase;
+ mMcfgNodeTemplate.SegGroupNum = RootComplex->Logical;
+ CopyMem (Iter, &mMcfgNodeTemplate, sizeof (EFI_MCFG_CONFIG_STRUCTURE));
+ Iter += sizeof (EFI_MCFG_CONFIG_STRUCTURE);
+ }
+}
+
+EFI_STATUS
+EFIAPI
+AcpiInstallMcfg (
+ VOID
+ )
+{
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
+ EFI_STATUS Status;
+ INT32 EnabledRCs[AC01_PCIE_MAX_ROOT_COMPLEX];
+ UINT32 RcCount, McfgCount;
+ UINT8 Idx;
+ UINTN TableKey;
+ VOID *Hob;
+ VOID *McfgBuffer;
+
+ Hob = GetFirstGuidHob (&gRootComplexInfoHobGuid);
+ if (Hob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ mRootComplexList = (AC01_ROOT_COMPLEX *)GET_GUID_HOB_DATA (Hob);
+
+ for (Idx = 0, RcCount = 0; Idx < AC01_PCIE_MAX_ROOT_COMPLEX; Idx++) {
+ if (mRootComplexList[Idx].Active) {
+ EnabledRCs[RcCount++] = Idx;
+ }
+ }
+ EnabledRCs[RcCount] = -1;
+
+ Status = gBS->LocateProtocol (
+ &gEfiAcpiTableProtocolGuid,
+ NULL,
+ (VOID **)&AcpiTableProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "MCFG: Unable to locate ACPI table entry\n"));
+ return Status;
+ }
+
+ McfgCount = sizeof (EFI_MCFG_TABLE_CONFIG) + sizeof (EFI_MCFG_CONFIG_STRUCTURE) * RcCount;
+ McfgBuffer = AllocateZeroPool (McfgCount);
+ if (McfgBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ConstructMcfg (McfgBuffer, McfgCount, EnabledRCs);
+
+ Status = AcpiTableProtocol->InstallAcpiTable (
+ AcpiTableProtocol,
+ McfgBuffer,
+ McfgCount,
+ &TableKey
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "MCFG: Unable to install MCFG table entry\n"));
+ }
+ FreePool (McfgBuffer);
+ return Status;
+}
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c
index c4022eb056e0..117f3872a84a 100644
--- a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c
@@ -93,6 +93,16 @@ InstallAcpiOnReadyToBoot (
DEBUG ((DEBUG_INFO, "Installed NFIT table\n"));
}
+ Status = AcpiInstallIort ();
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Installed IORT table\n"));
+ }
+
+ Status = AcpiInstallMcfg ();
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Installed MCFG table\n"));
+ }
+
Status = AcpiPopulateBert ();
if (!EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "Populate BERT record\n"));
--
2.17.1
next prev parent reply other threads:[~2021-11-17 16:50 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-17 16:46 [edk2-platforms][PATCH v5 00/30] Add new Ampere Mt. Jade platform Nhi Pham
2021-11-17 16:46 ` [edk2-platforms][PATCH v5 01/30] Ampere: Initial support for Ampere Altra processor and " Nhi Pham
2021-11-17 16:46 ` [edk2-platforms][PATCH v5 02/30] AmpereAltraPkg: Add FlashLib library instance Nhi Pham
2021-11-18 12:50 ` Leif Lindholm
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 03/30] AmpereAltraPkg: Add DwI2cLib " Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 04/30] AmpereAltraPkg: Add DwGpioLib " Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 05/30] JadePkg: Implement RealTimeClockLib for PCF85063 Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 06/30] AmpereAltraPkg: Add BootProgress support Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 07/30] AmpereAltraPkg: Support UEFI non-volatile variable Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 08/30] AmpereSiliconPkg: Add PlatformManagerUiLib library instance Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 09/30] AmpereAltraPkg, JadePkg: Add ACPI support Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 10/30] AmpereAltraPkg: Add Root Complex HOB data structures Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 11/30] AmpereAltraPkg: Add Ac01PcieLib library instance Nhi Pham
2021-11-18 12:33 ` Leif Lindholm
2021-11-18 13:33 ` Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 12/30] JadePkg: Add BoardPcieLib " Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 13/30] AmpereAltraPkg: Add driver to initialize PCIe Root Complex Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 14/30] AmpereAltraPkg: Add PciHostBridgeLib library instance Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 15/30] AmpereAltraPkg: Add PciSegmentLib " Nhi Pham
2021-11-18 13:10 ` Leif Lindholm
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 16/30] JadePkg: Enable PciHostBridgeDxe driver Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 17/30] JadePkg: Add PciPlatformDxe driver Nhi Pham
2021-11-17 16:47 ` Nhi Pham [this message]
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 19/30] JadePkg: Add ASpeed GOP driver Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 20/30] AmpereAltraPkg: Add Random Number Generator Support Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 21/30] JadePkg: Add SMBIOS tables support Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 22/30] AmpereAltraPkg: Add DebugInfoPei module Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 23/30] AmpereAltraPkg: Add configuration screen for PCIe Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 24/30] Ampere: Utilize the PCIe User setting Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 25/30] AmpereAltraPkg: Add platform info screen Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 26/30] AmpereAltraPkg: Add configuration screen for Memory Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 27/30] AmpereAltraPkg: Add configuration screen for CPU Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 28/30] AmpereAltraPkg: Add configuration screen for ACPI Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 29/30] AmpereAltraPkg: Add configuration screen for RAS Nhi Pham
2021-11-17 16:47 ` [edk2-platforms][PATCH v5 30/30] AmpereAltraPkg: Add configuration screen for Watchdog timer Nhi Pham
2021-11-18 13:02 ` [edk2-platforms][PATCH v5 00/30] Add new Ampere Mt. Jade platform Leif Lindholm
2021-11-18 13:45 ` Nhi Pham
2021-11-18 14:25 ` Leif Lindholm
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211117164727.10922-19-nhi@os.amperecomputing.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox