* [PATCH edk2-platforms 00/16] Add PCIe Support
@ 2020-05-21 23:02 Wasim Khan
2020-05-21 23:02 ` [PATCH edk2-platforms 01/16] Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs Wasim Khan
` (16 more replies)
0 siblings, 17 replies; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
Add PCIe Support for NXP Layerscape SoC which supports
different PCIe controllers.
Use generic PCIe drivers and wire up PciHostBridgeLib,
PciSegmentLib and PciCpuIo2Dxe driver for controller
specific implementation.
Wasim Khan (16):
Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs.
Silicon/NXP: LS1043A: Define PCIe related PCDs
Silicon/NXP: Implement PciHostBridgeLib support
Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS
Ctrl
Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU
Windows
Silicon/NXP: PciHostBridgeLib: add Workaround for A-011451
Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows
Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows
Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller
Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS
Controller
Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller
Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264
Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver
Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg
Platform/NXP: LS1043aRdbPkg: Enable PCIE support
Platform/NXP: LS1043aRdbPkg : Increase fv image size
Silicon/NXP/NxpQoriqLs.dec | 13 +
Silicon/NXP/LS1043A/LS1043A.dsc.inc | 8 +
Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc | 20 +
Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 20 +-
Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf | 40 +
.../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 45 ++
.../NXP/Library/PciSegmentLib/PciSegmentLib.inf | 36 +
Silicon/NXP/Include/Pcie.h | 231 ++++++
Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c | 628 +++++++++++++++
.../Library/PciHostBridgeLib/PciHostBridgeLib.c | 842 +++++++++++++++++++++
Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 699 +++++++++++++++++
11 files changed, 2579 insertions(+), 3 deletions(-)
create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
create mode 100755 Silicon/NXP/Include/Pcie.h
create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c
create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
--
2.7.4
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 01/16] Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs.
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-22 9:12 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 02/16] Silicon/NXP: LS1043A: Define " Wasim Khan
` (15 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
Add PCIe related PCDs.
Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
Silicon/NXP/NxpQoriqLs.dec | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/Silicon/NXP/NxpQoriqLs.dec b/Silicon/NXP/NxpQoriqLs.dec
index 0722f59ef4f6..bafdfd9f4298 100644
--- a/Silicon/NXP/NxpQoriqLs.dec
+++ b/Silicon/NXP/NxpQoriqLs.dec
@@ -27,3 +27,12 @@ [Guids.common]
[PcdsFeatureFlag]
gNxpQoriqLsTokenSpaceGuid.PcdI2cErratumA009203|FALSE|BOOLEAN|0x00000315
gNxpQoriqLsTokenSpaceGuid.PcdDcfgBigEndian|FALSE|BOOLEAN|0x00000316
+ gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian|FALSE|BOOLEAN|0x00000317
+
+[PcdsFixedAtBuild.common]
+ # Pcds for PCI Express
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr|0x0|UINT64|0x00000500
+ gNxpQoriqLsTokenSpaceGuid.PcdNumPciController|0|UINT32|0x00000501
+ gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase|0x0|UINT32|0x00000502
+ gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg|0x0|UINT32|0x00000503
+ gNxpQoriqLsTokenSpaceGuid.PcdPciDebug|FALSE|BOOLEAN|0x00000504
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 02/16] Silicon/NXP: LS1043A: Define PCIe related PCDs
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
2020-05-21 23:02 ` [PATCH edk2-platforms 01/16] Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-21 23:02 ` [PATCH edk2-platforms 03/16] Silicon/NXP: Implement PciHostBridgeLib support Wasim Khan
` (14 subsequent siblings)
16 siblings, 0 replies; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
Define PCIe related PCDs for LS1043A.
Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
Silicon/NXP/LS1043A/LS1043A.dsc.inc | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Silicon/NXP/LS1043A/LS1043A.dsc.inc b/Silicon/NXP/LS1043A/LS1043A.dsc.inc
index 67f5ba68dcd5..4b6eccc99885 100644
--- a/Silicon/NXP/LS1043A/LS1043A.dsc.inc
+++ b/Silicon/NXP/LS1043A/LS1043A.dsc.inc
@@ -30,4 +30,12 @@ [PcdsFixedAtBuild.common]
[PcdsFeatureFlag]
gNxpQoriqLsTokenSpaceGuid.PcdDcfgBigEndian|TRUE
+ gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian|TRUE
+
+[PcdsFixedAtBuild.common]
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr|0x4000000000
+ gNxpQoriqLsTokenSpaceGuid.PcdNumPciController|3
+ gNxpQoriqLsTokenSpaceGuid.PcdPciDebug|FALSE
+ gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase|0x10000
+ gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg|0x7FC
##
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 03/16] Silicon/NXP: Implement PciHostBridgeLib support
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
2020-05-21 23:02 ` [PATCH edk2-platforms 01/16] Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs Wasim Khan
2020-05-21 23:02 ` [PATCH edk2-platforms 02/16] Silicon/NXP: LS1043A: Define " Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-22 9:20 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 04/16] Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS Ctrl Wasim Khan
` (13 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
Implement PciHostBridgeLib that exposes the PCIe root complexes to
the generic PCI host bridge driver.
Setup PCIe Layerscape Controller and setup CFG, IO,
MMIO and MMIO64 iATU windows.
Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
.../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 40 ++
Silicon/NXP/Include/Pcie.h | 85 +++
.../Library/PciHostBridgeLib/PciHostBridgeLib.c | 568 +++++++++++++++++++++
3 files changed, 693 insertions(+)
create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
create mode 100755 Silicon/NXP/Include/Pcie.h
create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
new file mode 100644
index 000000000000..5ddb96e4fa6a
--- /dev/null
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -0,0 +1,40 @@
+## @file
+# PCI Host Bridge Library instance for NXP ARM SOC
+#
+# Copyright 2018-2020 NXP
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = PciHostBridgeLib
+ FILE_GUID = f4c99bcc-5c95-49ad-b0f3-fc5b611dc9c1
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PciHostBridgeLib
+
+[Sources]
+ PciHostBridgeLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ Silicon/NXP/NxpQoriqLs.dec
+
+[LibraryClasses]
+ DebugLib
+ DevicePathLib
+ IoAccessLib
+ MemoryAllocationLib
+ PcdLib
+
+[FeaturePcd]
+ gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian
+
+[FixedPcd]
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
+ gNxpQoriqLsTokenSpaceGuid.PcdNumPciController
+ gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase
+ gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg
diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h
new file mode 100755
index 000000000000..d5b5a3884e0a
--- /dev/null
+++ b/Silicon/NXP/Include/Pcie.h
@@ -0,0 +1,85 @@
+/** @file
+ PCI memory configuration for NXP
+
+ Copyright 2018-2020 NXP
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __PCI_H__
+#define __PCI_H__
+
+#define PCI_SEG0_NUM 0
+#define PCI_SEG1_NUM 1
+#define PCI_SEG2_NUM 2
+#define PCI_SEG3_NUM 3
+#define PCI_SEG4_NUM 4
+#define PCI_SEG5_NUM 5
+#define PCI_SEG0_MMIO_MEMBASE FixedPcdGet64 (PcdPciExp1BaseAddr)
+#define PCI_SEG0_DBI_BASE 0x03400000
+
+#define PCI_LINK_DOWN 0x0
+#define PCI_LINK_UP 0x1
+
+// Segment configuration
+#define PCI_SEG_BUSNUM_MIN 0x0
+#define PCI_SEG_BUSNUM_MAX 0xff
+#define PCI_SEG_PORTIO_MIN 0x0
+#define PCI_SEG_PORTIO_MAX 0xffff
+#define SEG_CFG_SIZE 0x00001000
+#define SEG_MEM_BASE 0x40000000
+#define SEG_MEM_SIZE 0xC0000000
+#define SEG_MEM_LIMIT SEG_MEM_BASE + (SEG_MEM_SIZE -1)
+#define SEG_IO_BASE 0x10000000
+#define SEG_MEM64_BASE 0x400000000
+#define PCI_BASE_DIFF 0x800000000
+#define PCI_DBI_SIZE_DIFF 0x100000
+#define PCI_SEG0_PHY_CFG0_BASE PCI_SEG0_MMIO_MEMBASE
+#define PCI_SEG0_PHY_CFG1_BASE PCI_SEG0_PHY_CFG0_BASE + SEG_CFG_SIZE
+#define PCI_SEG0_PHY_MEM_BASE PCI_SEG0_MMIO_MEMBASE + SEG_MEM_BASE
+#define PCI_SEG0_PHY_MEM64_BASE PCI_SEG0_MMIO_MEMBASE + SEG_MEM64_BASE
+#define PCI_SEG0_PHY_IO_BASE PCI_SEG0_MMIO_MEMBASE + SEG_IO_BASE
+
+// PCIe Controller configuration
+#define NUM_PCIE_CONTROLLER FixedPcdGet32 (PcdNumPciController)
+#define PCI_LUT_DBG FixedPcdGet32 (PcdPcieLutDbg)
+#define PCI_LUT_BASE FixedPcdGet32 (PcdPcieLutBase)
+#define LTSSM_PCIE_L0 0x11
+
+#define PCI_CLASS_BRIDGE_PCI 0x0604
+#define PCI_CLASS_DEVICE 0x8
+#define PCI_DBI_RO_WR_EN 0x8bc
+#define CLASS_CODE_MASK 0xffff
+#define CLASS_CODE_SHIFT 0x10
+
+// PCIe Layerscape Controller
+#define IATU_VIEWPORT_OFF 0x900
+#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0 0x904
+#define IATU_REGION_CTRL_2_OFF_OUTBOUND_0 0x908
+#define IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0 0x90C
+#define IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0 0x910
+#define IATU_LIMIT_ADDR_OFF_OUTBOUND_0 0x914
+#define IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0 0x918
+#define IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0 0x91C
+#define IATU_VIEWPORT_OUTBOUND 0x0
+#define IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN BIT31
+
+// ATU Programming
+#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM 0x0
+#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_IO 0x2
+#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0 0x4
+#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1 0x5
+#define IATU_REGION_INDEX0 0x0
+#define IATU_REGION_INDEX1 0x1
+#define IATU_REGION_INDEX2 0x2
+#define IATU_REGION_INDEX3 0x3
+#define IATU_REGION_INDEX4 0x4
+#define IATU_REGION_INDEX5 0x5
+#define IATU_REGION_INDEX6 0x6
+#define IATU_REGION_INDEX7 0x7
+#define SEG_CFG_BUS 0x00000000
+#define SEG_MEM_BUS 0x40000000
+#define SEG_IO_SIZE 0x10000
+#define SEG_IO_BUS 0x0
+
+#endif
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
new file mode 100644
index 000000000000..cf872370c7cd
--- /dev/null
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -0,0 +1,568 @@
+/** @file
+ PCI Host Bridge Library instance for NXP SoCs
+
+ Copyright 2018-2020 NXP
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/IoAccessLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Pcie.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#pragma pack(1)
+typedef struct {
+ ACPI_HID_DEVICE_PATH AcpiDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+#pragma pack ()
+
+STATIC CONST EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath[] = {
+ {
+ {
+ {
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ {
+ (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
+ (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
+ }
+ },
+ EISA_PNP_ID (0x0A08), // PCI Express
+ PCI_SEG0_NUM
+ },
+
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+ },
+ {
+ {
+ {
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ {
+ (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
+ (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
+ }
+ },
+ EISA_PNP_ID (0x0A08), // PCI Express
+ PCI_SEG1_NUM
+ },
+
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+ },
+ {
+ {
+ {
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ {
+ (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
+ (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
+ }
+ },
+ EISA_PNP_ID (0x0A08), // PCI Express
+ PCI_SEG2_NUM
+ },
+
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+ },
+ {
+ {
+ {
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ {
+ (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
+ (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
+ }
+ },
+ EISA_PNP_ID (0x0A08), // PCI Express
+ PCI_SEG3_NUM
+ },
+
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+ },
+ {
+ {
+ {
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ {
+ (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
+ (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
+ }
+ },
+ EISA_PNP_ID (0x0A08), // PCI Express
+ PCI_SEG4_NUM
+ },
+
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+ },
+ {
+ {
+ {
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ {
+ (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
+ (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
+ }
+ },
+ EISA_PNP_ID (0x0A08), // PCI Express
+ PCI_SEG5_NUM
+ },
+
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+ }
+};
+
+STATIC
+GLOBAL_REMOVE_IF_UNREFERENCED
+CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
+ L"Mem", L"I/O", L"Bus"
+};
+
+#define PCI_ALLOCATION_ATTRIBUTES EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | \
+ EFI_PCI_HOST_BRIDGE_MEM64_DECODE
+
+#define PCI_SUPPORT_ATTRIBUTES EFI_PCI_ATTRIBUTE_ISA_IO_16 | \
+ EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | \
+ EFI_PCI_ATTRIBUTE_VGA_MEMORY | \
+ EFI_PCI_ATTRIBUTE_VGA_IO_16 | \
+ EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16
+
+PCI_ROOT_BRIDGE mPciRootBridges[NUM_PCIE_CONTROLLER];
+
+/**
+ Helper function to check PCIe link state
+
+ @param Pcie Address of PCIe host controller.
+
+**/
+STATIC
+INTN
+PcieLinkUp (
+ IN EFI_PHYSICAL_ADDRESS Pcie,
+ IN UINT32 Idx
+ )
+{
+ MMIO_OPERATIONS *PcieOps;
+ UINT32 State;
+ UINT32 LtssmMask;
+
+ LtssmMask = 0x3f;
+
+ PcieOps = GetMmioOperations (FeaturePcdGet (PcdPciLutBigEndian));
+ State = PcieOps->Read32 ((UINTN)Pcie + PCI_LUT_BASE + PCI_LUT_DBG) & LtssmMask;
+
+ if (State < LTSSM_PCIE_L0) {
+ DEBUG ((DEBUG_INFO,"PCIE%d : reg @ 0x%lx, no link: LTSSM=0x%02x\n",
+ Idx + 1, Pcie, State));
+ return PCI_LINK_DOWN;
+ }
+
+ return PCI_LINK_UP;
+}
+
+/**
+ Function to set-up PCIe outbound window
+
+ @param Dbi Address of PCIe host controller.
+ @param Idx Index of iATU outbound window.
+ @param Type Type(Cfg0/Cfg1/Mem/IO) of iATU outbound window.
+ @param Phys PCIe controller phy address for outbound window.
+ @param BusAdr PCIe controller bus address for outbound window.
+ @param Size Window size
+
+**/
+STATIC
+VOID
+PcieOutboundSet (
+ IN EFI_PHYSICAL_ADDRESS Dbi,
+ IN UINT32 Idx,
+ IN UINT32 Type,
+ IN UINT64 Phys,
+ IN UINT64 BusAddr,
+ IN UINT64 Size
+ )
+{
+ // PCIe Layerscape : Outbound Window
+ MmioWrite32 (Dbi + IATU_VIEWPORT_OFF,
+ (UINT32)(IATU_VIEWPORT_OUTBOUND | Idx));
+
+ MmioWrite32 (Dbi + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0,
+ (UINT32)Phys);
+
+ MmioWrite32 (Dbi + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0,
+ (UINT32)(Phys >> 32));
+
+ MmioWrite32 (Dbi + IATU_LIMIT_ADDR_OFF_OUTBOUND_0,
+ (UINT32)(Phys + Size - BIT0));
+
+ MmioWrite32 (Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0,
+ (UINT32)BusAddr);
+
+ MmioWrite32 (Dbi + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0,
+ (UINT32)(BusAddr >> 32));
+
+ MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0,
+ (UINT32)Type);
+
+ MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
+ IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
+}
+
+/**
+ Function to set-up iATU windows for Layerscape PCIe controller
+
+ @param Pcie Address of PCIe host controller
+ @param Cfg0Base PCIe controller phy address Type0 Configuration Space.
+ @param Cfg1Base PCIe controller phy address Type1 Configuration Space.
+ @param MemBase PCIe controller phy address Memory Space.
+ @param Mem64Base PCIe controller phy address MMIO64 Space.
+ @param IoBase PCIe controller phy address IO Space.
+**/
+STATIC
+VOID
+PcieLsSetupAtu (
+ IN EFI_PHYSICAL_ADDRESS Pcie,
+ IN EFI_PHYSICAL_ADDRESS Cfg0Base,
+ IN EFI_PHYSICAL_ADDRESS Cfg1Base,
+ IN EFI_PHYSICAL_ADDRESS MemBase,
+ IN EFI_PHYSICAL_ADDRESS Mem64Base,
+ IN EFI_PHYSICAL_ADDRESS IoBase
+ )
+{
+ UINT64 Cfg0BaseAddr;
+ UINT64 Cfg1BaseAddr;
+ UINT64 Cfg0BusAddress;
+ UINT64 Cfg1BusAddress;
+ UINT64 Cfg0Size;
+ UINT64 Cfg1Size;
+
+ Cfg0BaseAddr = Cfg0Base;
+ Cfg1BaseAddr = Cfg1Base;
+ Cfg0BusAddress = SEG_CFG_BUS;
+ Cfg1BusAddress = SEG_CFG_BUS;
+ Cfg0Size = SEG_CFG_SIZE;
+ Cfg1Size = SEG_CFG_SIZE;
+
+ // iATU : OUTBOUND WINDOW 1 : CFG0
+ PcieOutboundSet (Pcie,
+ IATU_REGION_INDEX0,
+ IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0,
+ Cfg0BaseAddr,
+ Cfg0BusAddress,
+ Cfg0Size);
+
+ // iATU : OUTBOUND WINDOW 2 : CFG1
+ PcieOutboundSet (Pcie,
+ IATU_REGION_INDEX1,
+ IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1,
+ Cfg1BaseAddr,
+ Cfg1BusAddress,
+ Cfg1Size);
+
+ // iATU : OUTBOUND WINDOW 3 : MEM
+ PcieOutboundSet (Pcie,
+ IATU_REGION_INDEX2,
+ IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM,
+ MemBase,
+ SEG_MEM_BUS,
+ SEG_MEM_SIZE);
+
+ // iATU : OUTBOUND WINDOW 4 : MMIO64
+ PcieOutboundSet (Pcie,
+ IATU_REGION_INDEX3,
+ IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM,
+ Mem64Base,
+ Mem64Base,
+ SIZE_4GB);
+ Mem64Base += SIZE_4GB;
+
+ // iATU : OUTBOUND WINDOW 5 : MMIO64
+ PcieOutboundSet (Pcie,
+ IATU_REGION_INDEX4,
+ IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM,
+ Mem64Base,
+ Mem64Base,
+ SIZE_4GB);
+ Mem64Base += SIZE_4GB;
+
+ // iATU : OUTBOUND WINDOW 6 : MMIO64
+ PcieOutboundSet (Pcie,
+ IATU_REGION_INDEX5,
+ IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM,
+ Mem64Base,
+ Mem64Base,
+ SIZE_4GB
+ );
+ Mem64Base += SIZE_4GB;
+
+ // iATU : OUTBOUND WINDOW 7 : MMIO64
+ PcieOutboundSet (Pcie,
+ IATU_REGION_INDEX6,
+ IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM,
+ Mem64Base,
+ Mem64Base,
+ SIZE_4GB
+ );
+
+ // iATU : OUTBOUND WINDOW 8: IO
+ PcieOutboundSet (Pcie,
+ IATU_REGION_INDEX7,
+ IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_IO,
+ IoBase,
+ SEG_IO_BUS,
+ SEG_IO_SIZE
+ );
+}
+/**
+ Helper function to set-up PCIe controller
+
+ @param Pcie Address of PCIe host controller
+ @param Cfg0Base PCIe controller phy address Type0 Configuration Space.
+ @param Cfg1Base PCIe controller phy address Type1 Configuration Space.
+ @param MemBase PCIe controller phy address Memory Space.
+ @param Mem64Base PCIe controller phy address MMIO64 Space.
+ @param IoBase PCIe controller phy address IO Space.
+
+**/
+STATIC
+VOID
+PcieSetupCntrl (
+ IN EFI_PHYSICAL_ADDRESS Pcie,
+ IN EFI_PHYSICAL_ADDRESS Cfg0Base,
+ IN EFI_PHYSICAL_ADDRESS Cfg1Base,
+ IN EFI_PHYSICAL_ADDRESS MemBase,
+ IN EFI_PHYSICAL_ADDRESS Mem64Base,
+ IN EFI_PHYSICAL_ADDRESS IoBase
+ )
+{
+ UINT32 Val;
+
+ // PCIe Layerscape Controller Setup
+ PcieLsSetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase);
+
+ // Program Class code for Layerscape PCIe controller
+ MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 1);
+ Val = MmioRead32 ((UINTN)Pcie + PCI_CLASS_DEVICE);
+ Val &= ~(CLASS_CODE_MASK << CLASS_CODE_SHIFT);
+ Val |= (PCI_CLASS_BRIDGE_PCI << CLASS_CODE_SHIFT);
+ MmioWrite32 ((UINTN)Pcie + PCI_CLASS_DEVICE, Val);
+ MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 0);
+}
+
+/**
+ Return all the root bridge instances in an array.
+
+ @param Count Return the count of root bridge instances.
+
+ @return All the root bridge instances in an array.
+
+**/
+PCI_ROOT_BRIDGE *
+EFIAPI
+PciHostBridgeGetRootBridges (
+ OUT UINTN *Count
+ )
+{
+ UINTN Idx;
+ UINTN Loop;
+ UINT64 PciPhyMemAddr[NUM_PCIE_CONTROLLER];
+ UINT64 PciPhyMem64Addr[NUM_PCIE_CONTROLLER];
+ UINT64 PciPhyCfg0Addr[NUM_PCIE_CONTROLLER];
+ UINT64 PciPhyCfg1Addr[NUM_PCIE_CONTROLLER];
+ UINT64 PciPhyIoAddr[NUM_PCIE_CONTROLLER];
+ UINT64 Regs[NUM_PCIE_CONTROLLER];
+ INTN LinkUp;
+
+ for (Idx = 0, Loop = 0; Idx < NUM_PCIE_CONTROLLER; Idx++) {
+ PciPhyMemAddr[Idx] = PCI_SEG0_PHY_MEM_BASE + (PCI_BASE_DIFF * Idx);
+ PciPhyMem64Addr[Idx] = PCI_SEG0_PHY_MEM64_BASE + (PCI_BASE_DIFF * Idx);
+ PciPhyCfg0Addr[Idx] = PCI_SEG0_PHY_CFG0_BASE + (PCI_BASE_DIFF * Idx);
+ PciPhyCfg1Addr[Idx] = PCI_SEG0_PHY_CFG1_BASE + (PCI_BASE_DIFF * Idx);
+ PciPhyIoAddr [Idx] = PCI_SEG0_PHY_IO_BASE + (PCI_BASE_DIFF * Idx);
+ Regs[Idx] = PCI_SEG0_DBI_BASE + (PCI_DBI_SIZE_DIFF * Idx);
+
+ // Check PCIe Link
+ LinkUp = PcieLinkUp(Regs[Idx], Idx);
+
+ if (!LinkUp) {
+ continue;
+ }
+ DEBUG ((DEBUG_INFO, "PCIE%d Passed Linkup Phase\n", Idx + 1));
+ // Set up PCIe Controller and ATU windows
+ PcieSetupCntrl (Regs[Idx],
+ PciPhyCfg0Addr[Idx],
+ PciPhyCfg1Addr[Idx],
+ PciPhyMemAddr[Idx],
+ PciPhyMem64Addr[Idx],
+ PciPhyIoAddr[Idx]);
+
+ mPciRootBridges[Loop].Segment = Idx;
+ mPciRootBridges[Loop].Supports = PCI_SUPPORT_ATTRIBUTES;
+ mPciRootBridges[Loop].Attributes = PCI_SUPPORT_ATTRIBUTES;
+ mPciRootBridges[Loop].DmaAbove4G = TRUE;
+ mPciRootBridges[Loop].NoExtendedConfigSpace = FALSE;
+ mPciRootBridges[Loop].ResourceAssigned = FALSE;
+ mPciRootBridges[Loop].AllocationAttributes = PCI_ALLOCATION_ATTRIBUTES;
+
+ mPciRootBridges[Loop].Bus.Base = PCI_SEG_BUSNUM_MIN;
+ mPciRootBridges[Loop].Bus.Limit = PCI_SEG_BUSNUM_MAX;
+
+ mPciRootBridges[Loop].Io.Base = PCI_SEG_PORTIO_MIN;
+ mPciRootBridges[Loop].Io.Limit = PCI_SEG_PORTIO_MAX;
+ mPciRootBridges[Loop].Io.Translation = MAX_UINT64 -
+ (SEG_IO_SIZE * Idx) + 1;
+
+ mPciRootBridges[Loop].Mem.Base = SEG_MEM_BASE;
+ mPciRootBridges[Loop].Mem.Limit = SEG_MEM_LIMIT;
+ mPciRootBridges[Loop].Mem.Translation = MAX_UINT64 -
+ (PCI_SEG0_MMIO_MEMBASE +
+ (PCI_BASE_DIFF *
+ Idx)) + 1;
+
+ mPciRootBridges[Loop].MemAbove4G.Base = PciPhyMem64Addr[Idx];
+ mPciRootBridges[Loop].MemAbove4G.Limit = PciPhyMem64Addr[Idx] +
+ (SIZE_16GB - 1);
+
+ mPciRootBridges[Loop].PMem.Base = MAX_UINT64;
+ mPciRootBridges[Loop].PMem.Limit = 0;
+ mPciRootBridges[Loop].PMemAbove4G.Base = MAX_UINT64;
+ mPciRootBridges[Loop].PMemAbove4G.Limit = 0;
+ mPciRootBridges[Loop].DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[Idx];
+ Loop++;
+ }
+
+ if (Loop == 0) {
+ return NULL;
+ }
+
+ *Count = Loop;
+ return mPciRootBridges;
+}
+
+/**
+ Free the root bridge instances array returned from PciHostBridgeGetRootBridges().
+
+ @param Bridges The root bridge instances array.
+ @param Count The count of the array.
+**/
+VOID
+EFIAPI
+PciHostBridgeFreeRootBridges (
+ PCI_ROOT_BRIDGE *Bridges,
+ UINTN Count
+ )
+{
+}
+
+/**
+ Inform the platform that the resource conflict happens.
+
+ @param HostBridgeHandle Handle of the Host Bridge.
+ @param Configuration Pointer to PCI I/O and PCI memory resource
+ descriptors. The Configuration contains the resources
+ for all the root bridges. The resource for each root
+ bridge is terminated with END descriptor and an
+ additional END is appended indicating the end of the
+ entire resources. The resource descriptor field
+ values follow the description in
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+ .SubmitResources().
+
+**/
+VOID
+EFIAPI
+PciHostBridgeResourceConflict (
+ EFI_HANDLE HostBridgeHandle,
+ VOID *Configuration
+ )
+{
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
+ UINTN RootBridgeIndex;
+ DEBUG ((DEBUG_ERROR, "PciHostBridge: Resource conflict happens!\n"));
+
+ RootBridgeIndex = 0;
+ Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
+ while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+ DEBUG ((DEBUG_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
+ for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
+ ASSERT (Descriptor->ResType <
+ ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr));
+ DEBUG ((DEBUG_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n",
+ mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
+ Descriptor->AddrLen, Descriptor->AddrRangeMax
+ ));
+ if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
+ DEBUG ((DEBUG_ERROR, " Granularity/SpecificFlag = %ld / %02x%s\n",
+ Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag,
+ ((Descriptor->SpecificFlag &
+ EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
+ ) != 0) ? L" (Prefetchable)" : L""
+ ));
+ }
+ }
+ //
+ // Skip the END descriptor for root bridge
+ //
+ ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
+ Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(
+ (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
+ );
+ }
+
+ return;
+}
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 04/16] Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS Ctrl
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
` (2 preceding siblings ...)
2020-05-21 23:02 ` [PATCH edk2-platforms 03/16] Silicon/NXP: Implement PciHostBridgeLib support Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-22 9:22 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 05/16] Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU Windows Wasim Khan
` (12 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
PCIe layerscape controller supports CFG Shift feature. It can be
enabled by setting BIT[28] of iATU Control 2 Register.
Check PcdPciCfgShiftEnable to enable 'CFG Shift feature' in
PCIe controller.
if enable, PCIe layerscape controller shifts BDF from bits[27:12] to
bits[31:16] and supports Enhanced Configuration Address Mapping (ECAM)
mechanism.
PCIe layerscape controller is ECAM complaint for bus[0x1-0xff].
So create outbound CFG windows from 1MB-256MB (255 buses) for
type0/type1 configuration access.
PCIe layerscape controller is Non-ECAM complaint for bus 0.It does
not support device > 0 on bus 0. PciSegmentLib should handles this
limitation.
Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
Silicon/NXP/NxpQoriqLs.dec | 3 ++
.../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 3 ++
Silicon/NXP/Include/Pcie.h | 3 ++
.../Library/PciHostBridgeLib/PciHostBridgeLib.c | 35 +++++++++++++++++-----
4 files changed, 36 insertions(+), 8 deletions(-)
diff --git a/Silicon/NXP/NxpQoriqLs.dec b/Silicon/NXP/NxpQoriqLs.dec
index bafdfd9f4298..293fd773fd3d 100644
--- a/Silicon/NXP/NxpQoriqLs.dec
+++ b/Silicon/NXP/NxpQoriqLs.dec
@@ -36,3 +36,6 @@ [PcdsFixedAtBuild.common]
gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase|0x0|UINT32|0x00000502
gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg|0x0|UINT32|0x00000503
gNxpQoriqLsTokenSpaceGuid.PcdPciDebug|FALSE|BOOLEAN|0x00000504
+
+[PcdsDynamic.common]
+ gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable|FALSE|BOOLEAN|0x00000600
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
index 5ddb96e4fa6a..98cfb6aee6b0 100644
--- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -38,3 +38,6 @@ [FixedPcd]
gNxpQoriqLsTokenSpaceGuid.PcdNumPciController
gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase
gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg
+
+[Pcd]
+ gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h
index d5b5a3884e0a..ae85190180e8 100755
--- a/Silicon/NXP/Include/Pcie.h
+++ b/Silicon/NXP/Include/Pcie.h
@@ -63,6 +63,7 @@
#define IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0 0x91C
#define IATU_VIEWPORT_OUTBOUND 0x0
#define IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN BIT31
+#define IATU_ENABLE_CFG_SHIFT_FEATURE BIT28
// ATU Programming
#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM 0x0
@@ -82,4 +83,6 @@
#define SEG_IO_SIZE 0x10000
#define SEG_IO_BUS 0x0
+#define CFG_SHIFT_ENABLE (PcdGetBool (PcdPciCfgShiftEnable))
+
#endif
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
index cf872370c7cd..f92863c60868 100644
--- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -259,8 +259,17 @@ PcieOutboundSet (
MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0,
(UINT32)Type);
- MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
- IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
+ if (CFG_SHIFT_ENABLE &&
+ ((Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0) ||
+ (Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1))) {
+ MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
+ (IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN |
+ IATU_ENABLE_CFG_SHIFT_FEATURE)
+ );
+ } else {
+ MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
+ IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
+ }
}
/**
@@ -291,12 +300,22 @@ PcieLsSetupAtu (
UINT64 Cfg0Size;
UINT64 Cfg1Size;
- Cfg0BaseAddr = Cfg0Base;
- Cfg1BaseAddr = Cfg1Base;
- Cfg0BusAddress = SEG_CFG_BUS;
- Cfg1BusAddress = SEG_CFG_BUS;
- Cfg0Size = SEG_CFG_SIZE;
- Cfg1Size = SEG_CFG_SIZE;
+ if (CFG_SHIFT_ENABLE) {
+ DEBUG ((DEBUG_INFO, "PCIe: CFG Shit Method Enabled \n"));
+ Cfg0BaseAddr = Cfg0Base + SIZE_1MB;
+ Cfg1BaseAddr = Cfg0Base + SIZE_2MB;
+ Cfg0BusAddress = SIZE_1MB;
+ Cfg1BusAddress = SIZE_2MB;
+ Cfg0Size = SIZE_1MB;
+ Cfg1Size = (SIZE_256MB - SIZE_1MB); // 255MB
+ } else {
+ Cfg0BaseAddr = Cfg0Base;
+ Cfg1BaseAddr = Cfg1Base;
+ Cfg0BusAddress = SEG_CFG_BUS;
+ Cfg1BusAddress = SEG_CFG_BUS;
+ Cfg0Size = SEG_CFG_SIZE;
+ Cfg1Size = SEG_CFG_SIZE;
+ }
// iATU : OUTBOUND WINDOW 1 : CFG0
PcieOutboundSet (Pcie,
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 05/16] Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU Windows
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
` (3 preceding siblings ...)
2020-05-21 23:02 ` [PATCH edk2-platforms 04/16] Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS Ctrl Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-22 9:24 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 06/16] Silicon/NXP: PciHostBridgeLib: add Workaround for A-011451 Wasim Khan
` (11 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
Setup PCIe LayerscapeGen4 controller and setup CFG, IO,
MMIO and MMIO64 iATU windows.
Check for PcdPciLsGen4Ctrl to enable LsGen4 PCIe
controller.
Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
Silicon/NXP/NxpQoriqLs.dec | 1 +
.../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 1 +
Silicon/NXP/Include/Pcie.h | 120 ++++++++++
.../Library/PciHostBridgeLib/PciHostBridgeLib.c | 255 +++++++++++++++++----
4 files changed, 336 insertions(+), 41 deletions(-)
diff --git a/Silicon/NXP/NxpQoriqLs.dec b/Silicon/NXP/NxpQoriqLs.dec
index 293fd773fd3d..8271d19ed8e5 100644
--- a/Silicon/NXP/NxpQoriqLs.dec
+++ b/Silicon/NXP/NxpQoriqLs.dec
@@ -39,3 +39,4 @@ [PcdsFixedAtBuild.common]
[PcdsDynamic.common]
gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable|FALSE|BOOLEAN|0x00000600
+ gNxpQoriqLsTokenSpaceGuid.PcdPciLsGen4Ctrl|FALSE|BOOLEAN|0x00000601
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
index 98cfb6aee6b0..b777acdc103f 100644
--- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -41,3 +41,4 @@ [FixedPcd]
[Pcd]
gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
+ gNxpQoriqLsTokenSpaceGuid.PcdPciLsGen4Ctrl
diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h
index ae85190180e8..4c41c3585a8b 100755
--- a/Silicon/NXP/Include/Pcie.h
+++ b/Silicon/NXP/Include/Pcie.h
@@ -84,5 +84,125 @@
#define SEG_IO_BUS 0x0
#define CFG_SHIFT_ENABLE (PcdGetBool (PcdPciCfgShiftEnable))
+#define PCI_LS_GEN4_CTRL (PcdGetBool (PcdPciLsGen4Ctrl))
+// PCIe Layerscape Gen4 Controller
+#define GPEX_CLASSCODE 0x474
+#define GPEX_CLASSCODE_SHIFT 16
+#define GPEX_CLASSCODE_MASK 0xffff
+#define PAB_AXI_PIO_CTRL(Idx) (0x840 + 0x10 * Idx)
+#define APIO_EN 0x1
+#define MEM_WIN_EN 0x1 << 1
+#define IO_WIN_EN 0x1 << 2
+#define CFG_WIN_EN 0x1 << 3
+#define PAB_PEX_PIO_CTRL(Idx) (0x8c0 + 0x10 * Idx)
+#define PPIO_EN (0x1 << 0)
+#define PAB_PEX_PIO_STAT(Idx) (0x8c4 + 0x10 * Idx)
+#define PAB_PEX_PIO_MT_STAT(Idx) (0x8c8 + 0x10 * Idx)
+#define PEX_AMAP_CTRL_TYPE_SHIFT 0x1
+#define PEX_AMAP_CTRL_EN_SHIFT 0x0
+#define PEX_AMAP_CTRL_TYPE_MASK 0x3
+#define PEX_AMAP_CTRL_EN_MASK 0x1
+#define PAB_PEX_AMAP_CTRL(Idx) (0x4ba0 + 0x10 * Idx)
+#define PAB_EXT_PEX_AMAP_SIZE(Idx) (0xbef0 + 0x04 * Idx)
+#define PAB_PEX_AMAP_AXI_WIN(Idx) (0x4ba4 + 0x10 * Idx)
+#define PAB_EXT_PEX_AMAP_AXI_WIN(Idx) (0xb4a0 + 0x04 * Idx)
+#define PAB_PEX_AMAP_PEX_WIN_L(Idx) (0x4ba8 + 0x10 * Idx)
+#define PAB_PEX_AMAP_PEX_WIN_H(Idx) (0x4bac + 0x10 * Idx)
+#define PAB_CTRL 0x808
+#define PAB_CTRL_APIO_EN 0x1
+#define PAB_CTRL_PPIO_EN (0x1 << 1)
+#define PAB_CTRL_PAGE_SEL_SHIFT 13
+#define PAB_CTRL_PAGE_SEL_MASK 0x3f
+#define INDIRECT_ADDR_BNDRY 0xc00
+#define PAGE_IDX_SHIFT 10
+#define PAGE_ADDR_MASK 0x3ff
+#define PAB_AXI_AMAP_CTRL(Idx) (0xba0 + 0x10 * Idx)
+#define PAB_EXT_AXI_AMAP_SIZE(Idx) (0xbaf0 + 0x4 * Idx)
+#define PAB_AXI_AMAP_AXI_WIN(Idx) (0xba4 + 0x10 * Idx)
+#define PAB_EXT_AXI_AMAP_AXI_WIN(Idx) (0x80a0 + 0x4 * Idx)
+#define PAB_AXI_AMAP_PEX_WIN_L(Idx) (0xba8 + 0x10 * Idx)
+#define PAB_AXI_AMAP_PEX_WIN_H(Idx) (0xbac + 0x10 * Idx)
+#define PAB_AXI_TYPE_CFG 0x00
+#define PAB_AXI_TYPE_IO 0x01
+#define PAB_AXI_TYPE_MEM 0x02
+#define AXI_AMAP_CTRL_EN 0x1
+#define AXI_AMAP_CTRL_TYPE_SHIFT 1
+#define AXI_AMAP_CTRL_TYPE_MASK 0x3
+#define AXI_AMAP_CTRL_SIZE_SHIFT 10
+#define AXI_AMAP_CTRL_SIZE_MASK 0x3fffff
+
+
+#define OFFSET_TO_PAGE_IDX(Off) ((Off >> PAGE_IDX_SHIFT) \
+ & PAB_CTRL_PAGE_SEL_MASK)
+
+#define OFFSET_TO_PAGE_ADDR(Off) ((Off & PAGE_ADDR_MASK) \
+ | INDIRECT_ADDR_BNDRY)
+/**
+ Function to set page for LsGen4 Ctrl
+
+ @param Dbi GPEX host controller address.
+ @param PgIdx The page index to select
+
+**/
+STATIC inline VOID PciLsGen4SetPg (
+ IN EFI_PHYSICAL_ADDRESS Dbi,
+ IN UINT8 PgIdx
+ )
+{
+ UINT32 Val;
+ Val = MmioRead32 (Dbi + PAB_CTRL);
+ Val &= ~(PAB_CTRL_PAGE_SEL_MASK << PAB_CTRL_PAGE_SEL_SHIFT);
+ Val |= (PgIdx & PAB_CTRL_PAGE_SEL_MASK) << PAB_CTRL_PAGE_SEL_SHIFT;
+ MmioWrite32 (Dbi + PAB_CTRL, Val);
+}
+
+/**
+ Function to read LsGen4 PCIe controller config space
+ LsGen4 PCIe controller requires page number to be set
+ in Bridge Control Register(PAB) for offset > 3KB.
+
+ @param Dbi GPEX host controller address.
+ @param Offset Offset to read from
+
+**/
+STATIC inline INTN PciLsGen4Read32 (
+ IN EFI_PHYSICAL_ADDRESS Dbi,
+ IN UINT32 Offset
+ )
+{
+ if (Offset < INDIRECT_ADDR_BNDRY) {
+ PciLsGen4SetPg (Dbi, 0);
+ return MmioRead32 (Dbi + Offset);
+ } else {
+ // If Offset > 3KB, paging mechanism is used
+ // Select page index and offset within the page
+ PciLsGen4SetPg (Dbi, OFFSET_TO_PAGE_IDX (Offset));
+ return MmioRead32 (Dbi + OFFSET_TO_PAGE_ADDR (Offset));
+ }
+}
+
+/**
+ Function to write to LsGen4 PCIe controller config space
+ LsGen4 PCIe controller requires page number to be set
+ in Bridge Control Register(PAB) for offset > 3KB.
+
+ @param Dbi GPEX host controller address
+ @param Offset Offset to read from
+
+**/
+STATIC inline VOID PciLsGen4Write32 (
+ IN EFI_PHYSICAL_ADDRESS Dbi,
+ IN UINT32 Offset,
+ IN UINT32 Value
+ )
+{
+ if (Offset < INDIRECT_ADDR_BNDRY) {
+ PciLsGen4SetPg (Dbi, 0);
+ MmioWrite32 (Dbi + Offset, Value);
+ } else {
+ PciLsGen4SetPg (Dbi, OFFSET_TO_PAGE_IDX (Offset));
+ MmioWrite32 (Dbi + OFFSET_TO_PAGE_ADDR (Offset), Value);
+ }
+}
#endif
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
index f92863c60868..d9944313da21 100644
--- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -201,7 +201,11 @@ PcieLinkUp (
UINT32 State;
UINT32 LtssmMask;
- LtssmMask = 0x3f;
+ if (PCI_LS_GEN4_CTRL) {
+ LtssmMask = 0x7f;
+ } else {
+ LtssmMask = 0x3f;
+ }
PcieOps = GetMmioOperations (FeaturePcdGet (PcdPciLutBigEndian));
State = PcieOps->Read32 ((UINTN)Pcie + PCI_LUT_BASE + PCI_LUT_DBG) & LtssmMask;
@@ -237,38 +241,58 @@ PcieOutboundSet (
IN UINT64 Size
)
{
- // PCIe Layerscape : Outbound Window
- MmioWrite32 (Dbi + IATU_VIEWPORT_OFF,
- (UINT32)(IATU_VIEWPORT_OUTBOUND | Idx));
+ UINT32 Val;
- MmioWrite32 (Dbi + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0,
- (UINT32)Phys);
-
- MmioWrite32 (Dbi + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0,
- (UINT32)(Phys >> 32));
-
- MmioWrite32 (Dbi + IATU_LIMIT_ADDR_OFF_OUTBOUND_0,
- (UINT32)(Phys + Size - BIT0));
-
- MmioWrite32 (Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0,
- (UINT32)BusAddr);
-
- MmioWrite32 (Dbi + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0,
- (UINT32)(BusAddr >> 32));
-
- MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0,
- (UINT32)Type);
-
- if (CFG_SHIFT_ENABLE &&
- ((Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0) ||
- (Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1))) {
- MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
- (IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN |
- IATU_ENABLE_CFG_SHIFT_FEATURE)
- );
+ if (PCI_LS_GEN4_CTRL) {
+ // PCIe Layerscape Gen4: Outbound Window
+ Size = ~(Size -1 );
+ Val = PciLsGen4Read32 ((UINTN)Dbi, PAB_AXI_AMAP_CTRL (Idx));
+ Val &= ~((AXI_AMAP_CTRL_TYPE_MASK << AXI_AMAP_CTRL_TYPE_SHIFT) |
+ (AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT) |
+ AXI_AMAP_CTRL_EN);
+ Val |= ((Type & AXI_AMAP_CTRL_TYPE_MASK) << AXI_AMAP_CTRL_TYPE_SHIFT) |
+ (((UINT32)Size >> AXI_AMAP_CTRL_SIZE_SHIFT) <<
+ AXI_AMAP_CTRL_SIZE_SHIFT) | AXI_AMAP_CTRL_EN;
+ PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_CTRL (Idx), Val);
+ PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_AXI_WIN (Idx), (UINT32)Phys);
+ PciLsGen4Write32 ((UINTN)Dbi, PAB_EXT_AXI_AMAP_AXI_WIN (Idx), Phys >> 32);
+ PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_L (Idx), (UINT32)BusAddr);
+ PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_H (Idx), BusAddr >> 32);
+ PciLsGen4Write32 ((UINTN)Dbi, PAB_EXT_AXI_AMAP_SIZE (Idx), Size >> 32);
} else {
- MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
- IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
+ // PCIe Layerscape : Outbound Window
+ MmioWrite32 (Dbi + IATU_VIEWPORT_OFF,
+ (UINT32)(IATU_VIEWPORT_OUTBOUND | Idx));
+
+ MmioWrite32 (Dbi + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0,
+ (UINT32)Phys);
+
+ MmioWrite32 (Dbi + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0,
+ (UINT32)(Phys >> 32));
+
+ MmioWrite32 (Dbi + IATU_LIMIT_ADDR_OFF_OUTBOUND_0,
+ (UINT32)(Phys + Size - BIT0));
+
+ MmioWrite32 (Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0,
+ (UINT32)BusAddr);
+
+ MmioWrite32 (Dbi + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0,
+ (UINT32)(BusAddr >> 32));
+
+ MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0,
+ (UINT32)Type);
+
+ if (CFG_SHIFT_ENABLE &&
+ ((Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0) ||
+ (Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1))) {
+ MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
+ (IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN |
+ IATU_ENABLE_CFG_SHIFT_FEATURE)
+ );
+ } else {
+ MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
+ IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
+ }
}
}
@@ -387,6 +411,124 @@ PcieLsSetupAtu (
SEG_IO_SIZE
);
}
+
+/**
+ Function to set-up ATU windows for PCIe LayerscapeGen4 controller
+
+ @param Pcie Address of PCIe host controller
+ @param Cfg0Base PCIe controller phy address Type0 Configuration Space.
+ @param Cfg1Base PCIe controller phy address Type1 Configuration Space.
+ @param MemBase PCIe controller phy address Memory Space.
+ @param Mem64Base PCIe controller phy address MMIO64 Space.
+ @param IoBase PCIe controller phy address IO Space.
+**/
+STATIC
+VOID
+PcieLsGen4SetupAtu (
+ IN EFI_PHYSICAL_ADDRESS Pcie,
+ IN EFI_PHYSICAL_ADDRESS Cfg0Base,
+ IN EFI_PHYSICAL_ADDRESS Cfg1Base,
+ IN EFI_PHYSICAL_ADDRESS MemBase,
+ IN EFI_PHYSICAL_ADDRESS Mem64Base,
+ IN EFI_PHYSICAL_ADDRESS IoBase
+ )
+{
+ // ATU : OUTBOUND WINDOW 1 : CFG0
+ PcieOutboundSet (Pcie, IATU_REGION_INDEX0,
+ PAB_AXI_TYPE_CFG,
+ Cfg0Base,
+ SEG_CFG_BUS,
+ SEG_CFG_SIZE);
+
+ // ATU : OUTBOUND WINDOW 2 : IO
+ PcieOutboundSet (Pcie, IATU_REGION_INDEX1,
+ PAB_AXI_TYPE_IO,
+ IoBase,
+ SEG_IO_BUS,
+ SEG_IO_SIZE);
+
+ // ATU : OUTBOUND WINDOW 3 : MEM
+ PcieOutboundSet (Pcie, IATU_REGION_INDEX2,
+ PAB_AXI_TYPE_MEM,
+ MemBase,
+ SEG_MEM_BUS,
+ SEG_MEM_SIZE);
+
+ // ATU : OUTBOUND WINDOW 4 : MMIO64
+ PcieOutboundSet (Pcie, IATU_REGION_INDEX3,
+ PAB_AXI_TYPE_MEM,
+ Mem64Base,
+ Mem64Base,
+ SIZE_4GB);
+ Mem64Base += SIZE_4GB;
+
+ // ATU : OUTBOUND WINDOW 5 : MMIO64
+ PcieOutboundSet (Pcie, IATU_REGION_INDEX4,
+ PAB_AXI_TYPE_MEM,
+ Mem64Base,
+ Mem64Base,
+ SIZE_4GB);
+ Mem64Base += SIZE_4GB;
+
+ // ATU : OUTBOUND WINDOW 6 : MMIO64
+ PcieOutboundSet (Pcie, IATU_REGION_INDEX5,
+ PAB_AXI_TYPE_MEM,
+ Mem64Base,
+ Mem64Base,
+ SIZE_4GB);
+ Mem64Base += SIZE_4GB;
+
+ // ATU : OUTBOUND WINDOW 7 : MMIO64
+ PcieOutboundSet (Pcie, IATU_REGION_INDEX6,
+ PAB_AXI_TYPE_MEM,
+ Mem64Base,
+ Mem64Base,
+ SIZE_4GB);
+}
+
+/**
+ Function to set-up PCIe inbound window
+
+ @param Pcie Address of PCIe host controller.
+ @param Idx Index of inbound window.
+ @param Type Type(Cfg/Mem/IO) of iATU outbound window.
+ @param Phys PCIe controller phy address for inbound window.
+ @param BusAdr PCIe controller bus address for inbound window.
+ @param Size Window size
+
+**/
+
+STATIC
+VOID
+PciSetupInBoundWin (
+ IN EFI_PHYSICAL_ADDRESS Pcie,
+ IN UINT32 Idx,
+ IN UINT32 Type,
+ IN UINT64 Phys,
+ IN UINT64 BusAddr,
+ IN UINT64 Size)
+{
+ UINT32 Val;
+ UINT64 WinSize;
+
+ if (PCI_LS_GEN4_CTRL) {
+ Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_PEX_AMAP_CTRL(Idx));
+ Val &= ~(PEX_AMAP_CTRL_TYPE_MASK << PEX_AMAP_CTRL_TYPE_SHIFT);
+ Val &= ~(PEX_AMAP_CTRL_EN_MASK << PEX_AMAP_CTRL_EN_SHIFT);
+ Val = (Val | (Type << PEX_AMAP_CTRL_TYPE_SHIFT));
+ Val = (Val | (1 << PEX_AMAP_CTRL_EN_SHIFT));
+
+ WinSize = ~(Size - 1);
+ PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_CTRL(Idx),
+ (Val | (UINT32)WinSize));
+ PciLsGen4Write32 ((UINTN)Pcie, PAB_EXT_PEX_AMAP_SIZE(Idx), (WinSize>>32));
+ PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_AXI_WIN(Idx), (UINT32)Phys);
+ PciLsGen4Write32 ((UINTN)Pcie, PAB_EXT_PEX_AMAP_AXI_WIN(Idx), (Phys>>32));
+ PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_PEX_WIN_L(Idx), (UINT32)BusAddr);
+ PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_PEX_WIN_H(Idx), (BusAddr >>32));
+ }
+}
+
/**
Helper function to set-up PCIe controller
@@ -411,16 +553,47 @@ PcieSetupCntrl (
{
UINT32 Val;
- // PCIe Layerscape Controller Setup
- PcieLsSetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase);
-
- // Program Class code for Layerscape PCIe controller
- MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 1);
- Val = MmioRead32 ((UINTN)Pcie + PCI_CLASS_DEVICE);
- Val &= ~(CLASS_CODE_MASK << CLASS_CODE_SHIFT);
- Val |= (PCI_CLASS_BRIDGE_PCI << CLASS_CODE_SHIFT);
- MmioWrite32 ((UINTN)Pcie + PCI_CLASS_DEVICE, Val);
- MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 0);
+ if (PCI_LS_GEN4_CTRL) {
+ // PCIe LsGen4 Controller Setup
+
+ //Fix Class Code
+ Val = PciLsGen4Read32 ((UINTN)Pcie, GPEX_CLASSCODE);
+ Val &= ~(GPEX_CLASSCODE_MASK << GPEX_CLASSCODE_SHIFT);
+ Val |= PCI_CLASS_BRIDGE_PCI << GPEX_CLASSCODE_SHIFT;
+ PciLsGen4Write32 ((UINTN)Pcie, GPEX_CLASSCODE, Val);
+
+ // Enable APIO and Memory/IO/CFG Windows
+ Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_PIO_CTRL (0));
+ Val |= APIO_EN | MEM_WIN_EN | IO_WIN_EN | CFG_WIN_EN;
+ PciLsGen4Write32 ((UINTN)Pcie, PAB_AXI_PIO_CTRL (0), Val);
+
+ // LsGen4 Inbound Window Setup
+ PciSetupInBoundWin (Pcie, 0, PAB_AXI_TYPE_MEM, 0 , 0, SIZE_1TB);
+
+ // LsGen4 Outbound Window Setup
+ PcieLsGen4SetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase);
+
+ // Enable AMBA & PEX PIO
+ Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_CTRL);
+ Val |= PAB_CTRL_APIO_EN | PAB_CTRL_PPIO_EN;
+ PciLsGen4Write32 ((UINTN)Pcie, PAB_CTRL, Val);
+
+ Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_PEX_PIO_CTRL(0));
+ Val |= PPIO_EN;
+ PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_PIO_CTRL(0), Val);
+
+ } else {
+ // PCIe Layerscape Controller Setup
+ PcieLsSetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase);
+
+ // Program Class code for Layerscape PCIe controller
+ MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 1);
+ Val = MmioRead32 ((UINTN)Pcie + PCI_CLASS_DEVICE);
+ Val &= ~(CLASS_CODE_MASK << CLASS_CODE_SHIFT);
+ Val |= (PCI_CLASS_BRIDGE_PCI << CLASS_CODE_SHIFT);
+ MmioWrite32 ((UINTN)Pcie + PCI_CLASS_DEVICE, Val);
+ MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 0);
+ }
}
/**
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 06/16] Silicon/NXP: PciHostBridgeLib: add Workaround for A-011451
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
` (4 preceding siblings ...)
2020-05-21 23:02 ` [PATCH edk2-platforms 05/16] Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU Windows Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-21 23:02 ` [PATCH edk2-platforms 07/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows Wasim Khan
` (10 subsequent siblings)
16 siblings, 0 replies; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
When PCIe Layerscape Gen4 controller is sending multiple split
completions and ACK latency expires indicating that ACK should
be send at priority. But because of large number of split completions
and FC update DLLP,the controller does not give priority to ACK
transmission. This results into ACK latency timer timeout error
at the link partner and the pending TLPs are replayed by the
link partner again.
Workaround:
Reduce the ACK latency timeout value.
Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
Silicon/NXP/Include/Pcie.h | 4 ++++
Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c | 6 ++++++
2 files changed, 10 insertions(+)
diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h
index 4c41c3585a8b..bc35570f79bc 100755
--- a/Silicon/NXP/Include/Pcie.h
+++ b/Silicon/NXP/Include/Pcie.h
@@ -205,4 +205,8 @@ STATIC inline VOID PciLsGen4Write32 (
MmioWrite32 (Dbi + OFFSET_TO_PAGE_ADDR (Offset), Value);
}
}
+
+#define GPEX_ACK_REPLAY_TO 0x438
+#define ACK_LAT_TO_VAL_SHIFT 0
+#define ACK_LAT_TO_VAL_MASK 0x1fff
#endif
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
index d9944313da21..bacdc29d60d6 100644
--- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -556,6 +556,12 @@ PcieSetupCntrl (
if (PCI_LS_GEN4_CTRL) {
// PCIe LsGen4 Controller Setup
+ // Workaround for A-011451
+ Val = PciLsGen4Read32 ((UINTN)Pcie, GPEX_ACK_REPLAY_TO);
+ Val &= ~(ACK_LAT_TO_VAL_MASK << ACK_LAT_TO_VAL_SHIFT);
+ Val |= (4 << ACK_LAT_TO_VAL_SHIFT);
+ PciLsGen4Write32 ((UINTN)Pcie, GPEX_ACK_REPLAY_TO, Val);
+
//Fix Class Code
Val = PciLsGen4Read32 ((UINTN)Pcie, GPEX_CLASSCODE);
Val &= ~(GPEX_CLASSCODE_MASK << GPEX_CLASSCODE_SHIFT);
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 07/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
` (5 preceding siblings ...)
2020-05-21 23:02 ` [PATCH edk2-platforms 06/16] Silicon/NXP: PciHostBridgeLib: add Workaround for A-011451 Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-22 9:33 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 08/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows Wasim Khan
` (9 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
Dump ATU windows for PCIe LsGen4 controller if PcdPciDebug
is enabled.
Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
.../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 1 +
.../Library/PciHostBridgeLib/PciHostBridgeLib.c | 34 ++++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
index b777acdc103f..df1590172e15 100644
--- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -38,6 +38,7 @@ [FixedPcd]
gNxpQoriqLsTokenSpaceGuid.PcdNumPciController
gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase
gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg
+ gNxpQoriqLsTokenSpaceGuid.PcdPciDebug
[Pcd]
gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
index bacdc29d60d6..1de20c621dc0 100644
--- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -413,6 +413,36 @@ PcieLsSetupAtu (
}
/**
+ Dump PCIe LsGen4 ATU
+
+ @param Pcie Address of PCIe host controller.
+**/
+VOID LsGen4DumpAtu (
+ IN EFI_PHYSICAL_ADDRESS Pcie
+ )
+{
+ UINT32 Cnt;
+ for (Cnt = 0; Cnt <= IATU_REGION_INDEX6; Cnt++) {
+ DEBUG ((DEBUG_INFO,"APIO WINDOW%d:\n", Cnt));
+ DEBUG ((DEBUG_INFO,"\tLOWER PHYS 0x%08x\n",
+ PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_AMAP_AXI_WIN (Cnt))));
+ DEBUG ((DEBUG_INFO,"\tUPPER PHYS 0x%08x\n",
+ PciLsGen4Read32 ((UINTN)Pcie, PAB_EXT_AXI_AMAP_AXI_WIN (Cnt))));
+ DEBUG ((DEBUG_INFO,"\tLOWER BUS 0x%08x\n",
+ PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_AMAP_PEX_WIN_L (Cnt))));
+ DEBUG ((DEBUG_INFO,"\tUPPER BUS 0x%08x\n",
+ PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_AMAP_PEX_WIN_H (Cnt))));
+ DEBUG ((DEBUG_INFO,"\tSIZE 0x%08x\n",
+ PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_AMAP_CTRL (Cnt)) &
+ (AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT)));
+ DEBUG ((DEBUG_INFO,"\tEXT_SIZE 0x%08x\n",
+ PciLsGen4Read32 ((UINTN)Pcie, PAB_EXT_AXI_AMAP_SIZE (Cnt))));
+ DEBUG ((DEBUG_INFO,"\tCTRL: 0x%08x\n",
+ PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_AMAP_CTRL (Cnt))));
+ }
+}
+
+/**
Function to set-up ATU windows for PCIe LayerscapeGen4 controller
@param Pcie Address of PCIe host controller
@@ -484,6 +514,10 @@ PcieLsGen4SetupAtu (
Mem64Base,
Mem64Base,
SIZE_4GB);
+
+ if (FixedPcdGetBool (PcdPciDebug) == TRUE) {
+ LsGen4DumpAtu (Pcie);
+ }
}
/**
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 08/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
` (6 preceding siblings ...)
2020-05-21 23:02 ` [PATCH edk2-platforms 07/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-22 9:31 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 09/16] Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller Wasim Khan
` (8 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
Dump ATU windows for PCIe Layerscape controller if PcdPciDebug
is enabled.
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
.../Library/PciHostBridgeLib/PciHostBridgeLib.c | 42 ++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
index 1de20c621dc0..3ad526218bcf 100644
--- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
+++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -297,6 +297,44 @@ PcieOutboundSet (
}
/**
+ Dump PCIe Layerscape ATU
+
+ @param Pcie Address of PCIe host controller.
+**/
+VOID LsDumpAtu (
+ IN EFI_PHYSICAL_ADDRESS Pcie
+ )
+{
+ UINT32 Cnt;
+ for (Cnt = 0; Cnt <= IATU_REGION_INDEX7; Cnt++) {
+ MmioWrite32 ((UINTN)Pcie + IATU_VIEWPORT_OFF,
+ (UINT32)(IATU_VIEWPORT_OUTBOUND | Cnt));
+
+ DEBUG ((DEBUG_INFO, "iATU%d:\n",Cnt));
+ DEBUG ((DEBUG_INFO, "\tLOWER PHYS 0x%08x\n",
+ MmioRead32 ((UINTN)Pcie + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0)));
+
+ DEBUG ((DEBUG_INFO, "\tUPPER PHYS 0x%08x\n",
+ MmioRead32 ((UINTN)Pcie + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0)));
+
+ DEBUG ((DEBUG_INFO, "\tLOWER BUS 0x%08x\n",
+ MmioRead32 ((UINTN)Pcie + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0)));
+
+ DEBUG ((DEBUG_INFO, "\tUPPER BUS 0x%08x\n",
+ MmioRead32 ((UINTN)Pcie + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0)));
+
+ DEBUG ((DEBUG_INFO, "\tLIMIT 0x%08x\n",
+ MmioRead32 ((UINTN)Pcie + IATU_LIMIT_ADDR_OFF_OUTBOUND_0)));
+
+ DEBUG ((DEBUG_INFO, "\tCR1 0x%08x\n",
+ MmioRead32 ((UINTN)Pcie + IATU_REGION_CTRL_1_OFF_OUTBOUND_0)));
+
+ DEBUG ((DEBUG_INFO, "\tCR2 0x%08x\n",
+ MmioRead32 ((UINTN)Pcie + IATU_REGION_CTRL_2_OFF_OUTBOUND_0)));
+ }
+}
+
+/**
Function to set-up iATU windows for Layerscape PCIe controller
@param Pcie Address of PCIe host controller
@@ -410,6 +448,10 @@ PcieLsSetupAtu (
SEG_IO_BUS,
SEG_IO_SIZE
);
+
+ if (FixedPcdGetBool (PcdPciDebug) == TRUE) {
+ LsDumpAtu (Pcie);
+ }
}
/**
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 09/16] Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
` (7 preceding siblings ...)
2020-05-21 23:02 ` [PATCH edk2-platforms 08/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-22 9:29 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 10/16] Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS Controller Wasim Khan
` (7 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
We have different PCI config space region for bus 0 (Controller space) and
bus[0x1-0xff] on NXP SoCs with PCIe LS controller.
Add PciSegmentLib for PCIe LS controller.
For config transactions for Bus0:
- Config transaction address = PCIe controller address + offset
For config transactions for Bus[0x1-0xff]:
- PCIe IP requires target BDF to be written at bit[31:16] of PCIe
type0/type1 outbound window.
- Config transaction address = PCIe config space address + offset
Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
.../NXP/Library/PciSegmentLib/PciSegmentLib.inf | 32 ++
Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 612 +++++++++++++++++++++
2 files changed, 644 insertions(+)
create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
new file mode 100755
index 000000000000..a36e79239b33
--- /dev/null
+++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
@@ -0,0 +1,32 @@
+## @file
+# PCI Segment Library for NXP SoCs with multiple RCs
+#
+# Copyright 2018-2020 NXP
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = PciSegmentLib
+ FILE_GUID = c9f59261-5a60-4a4c-82f6-1f520442e100
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PciSegmentLib|DXE_DRIVER
+ CONSTRUCTOR = PciSegLibInit
+
+[Sources]
+ PciSegmentLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ Silicon/NXP/NxpQoriqLs.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ IoLib
+ PcdLib
+
+[FixedPcd]
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
new file mode 100755
index 000000000000..ecd36971b753
--- /dev/null
+++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
@@ -0,0 +1,612 @@
+/** @file
+ PCI Segment Library for NXP SoCs with multiple RCs
+
+ Copyright 2018-2020 NXP
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <PiDxe.h>
+#include <Base.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Pcie.h>
+
+typedef enum {
+ PciCfgWidthUint8 = 0,
+ PciCfgWidthUint16,
+ PciCfgWidthUint32,
+ PciCfgWidthMax
+} PCI_CFG_WIDTH;
+
+/**
+ Assert the validity of a PCI Segment address.
+ A valid PCI Segment address should not contain 1's in bits 28..31 and 48..63
+
+ @param A The address to validate.
+ @param M Additional bits to assert to be zero.
+
+**/
+#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
+ ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
+
+STATIC
+UINT64
+PciLsCfgTarget (
+ IN EFI_PHYSICAL_ADDRESS Dbi,
+ IN UINT64 Address,
+ IN UINT16 Segment,
+ IN UINT8 Bus,
+ IN UINT16 Offset
+ )
+{
+ UINT32 Target;
+
+ Target = ((((Address >> 20) & 0xFF) << 24) |
+ (((Address >> 15) & 0x1F) << 19) |
+ (((Address >> 12) & 0x7) << 16));
+
+ if (Bus > 1) {
+ MmioWrite32 ((UINTN)Dbi + IATU_VIEWPORT_OFF, IATU_VIEWPORT_OUTBOUND | IATU_REGION_INDEX1);
+ } else {
+ MmioWrite32 ((UINTN)Dbi + IATU_VIEWPORT_OFF, IATU_VIEWPORT_OUTBOUND | IATU_REGION_INDEX0);
+ }
+
+ MmioWrite32 ((UINTN)Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0, Target);
+
+ if (Bus > 1) {
+ return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment + SEG_CFG_SIZE + Offset;
+ } else {
+ return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment + Offset;
+ }
+}
+
+/**
+ Function to return PCIe Physical Address(PCIe view) or Controller
+ Address(CPU view) for different RCs
+
+ @param Address Address passed from bus layer.
+ @param Segment Segment number for Root Complex.
+ @param Offset Config space register offset.
+ @param Bus PCIe Bus number.
+
+ @return Return PCIe CPU or Controller address.
+
+**/
+STATIC
+UINT64
+PciLsGetConfigBase (
+ IN UINT64 Address,
+ IN UINT16 Segment,
+ IN UINT16 Offset,
+ IN UINT8 Bus
+ )
+{
+ UINT32 CfgAddr;
+
+ CfgAddr = (UINT16)Offset;
+ if (Bus) {
+ return PciLsCfgTarget (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment, Address, Segment, Bus, Offset);
+ } else {
+ return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
+ }
+}
+
+/**
+ Function to return PCIe Physical Address(PCIe view) or Controller
+ Address(CPU view) for different RCs
+
+ @param Address Address passed from bus layer.
+ @param Segment Segment number for Root Complex.
+ @param Offset Config space register offset.
+
+ @return Return PCIe CPU or Controller address.
+
+**/
+STATIC
+UINT64
+PciSegmentLibGetConfigBase (
+ IN UINT64 Address,
+ IN UINT16 Segment,
+ IN UINT16 Offset
+ )
+{
+ UINT8 Bus;
+
+ Bus = ((UINT32)Address >> 20) & 0xff;
+ return PciLsGetConfigBase (Address, Segment, Offset, Bus);
+}
+
+/**
+ Internal worker function to read a PCI configuration register.
+
+ @param Address The address that encodes the Segment, PCI Bus, Device,
+ Function and Register.
+ @param Width The width of data to read
+
+ @return The value read from the PCI configuration register.
+
+**/
+STATIC
+UINT32
+PciSegmentLibReadWorker (
+ IN UINT64 Address,
+ IN PCI_CFG_WIDTH Width
+ )
+{
+ UINT64 Base;
+ UINT16 Offset;
+ UINT16 Segment;
+
+ Segment = (Address >> 32);
+ Offset = (Address & 0xfff );
+
+ Base = PciSegmentLibGetConfigBase (Address, Segment, Offset);
+
+ // ignore devices > 0 on bus 0
+ if ((Address & 0xff00000) == 0 && (Address & 0xf8000) != 0) {
+ return MAX_UINT32;
+ }
+
+ // ignore device > 0 on bus 1
+ if ((Address & 0xfe00000) == 0 && (Address & 0xf8000) != 0) {
+ return MAX_UINT32;
+ }
+
+ switch (Width) {
+ case PciCfgWidthUint8:
+ return MmioRead8 (Base);
+ case PciCfgWidthUint16:
+ return MmioRead16 (Base);
+ case PciCfgWidthUint32:
+ return MmioRead32 (Base);
+ default:
+ ASSERT (FALSE);
+ }
+
+ return CHAR_NULL;
+}
+
+/**
+ Internal worker function to writes a PCI configuration register.
+
+ @param Address The address that encodes the Segment, PCI Bus, Device,
+ Function and Register.
+ @param Width The width of data to write
+ @param Data The value to write.
+
+ @return The value written to the PCI configuration register.
+
+**/
+STATIC
+UINT32
+PciSegmentLibWriteWorker (
+ IN UINT64 Address,
+ IN PCI_CFG_WIDTH Width,
+ IN UINT32 Data
+ )
+{
+ UINT64 Base;
+ UINT32 Offset;
+ UINT16 Segment;
+
+ Segment = (Address >> 32);
+ Offset = (Address & 0xfff );
+
+ Base = PciSegmentLibGetConfigBase (Address, Segment, Offset);
+
+ // ignore devices > 0 on bus 0
+ if ((Address & 0xff00000) == 0 && (Address & 0xf8000) != 0) {
+ return Data;
+ }
+
+ // ignore device > 0 on bus 1
+ if ((Address & 0xfe00000) == 0 && (Address & 0xf8000) != 0) {
+ return MAX_UINT32;
+ }
+
+ switch (Width) {
+ case PciCfgWidthUint8:
+ MmioWrite8 (Base , Data);
+ break;
+ case PciCfgWidthUint16:
+ MmioWrite16 (Base , Data);
+ break;
+ case PciCfgWidthUint32:
+ MmioWrite32 (Base , Data);
+ break;
+ default:
+ ASSERT (FALSE);
+ }
+
+ return Data;
+}
+
+/**
+ Register a PCI device so PCI configuration registers may be accessed after
+ SetVirtualAddressMap().
+
+ If any reserved bits in Address are set, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device,
+ Function and Register.
+
+ @retval RETURN_SUCCESS The PCI device was registered for runtime access.
+ @retval RETURN_UNSUPPORTED An attempt was made to call this function
+ after ExitBootServices().
+ @retval RETURN_UNSUPPORTED The resources required to access the PCI device
+ at runtime could not be mapped.
+ @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
+ complete the registration.
+
+**/
+RETURN_STATUS
+EFIAPI
+PciSegmentRegisterForRuntimeAccess (
+ IN UINTN Address
+ )
+{
+ ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
+ return RETURN_UNSUPPORTED;
+}
+
+/**
+ Reads an 8-bit PCI configuration register.
+
+ Reads and returns the 8-bit PCI configuration register specified by Address.
+
+ If any reserved bits in Address are set, then ASSERT().
+
+ @param Address The address that encodes the PCI Segment, Bus, Device, Function,
+ and Register.
+
+ @return The 8-bit PCI configuration register specified by Address.
+
+**/
+UINT8
+EFIAPI
+PciSegmentRead8 (
+ IN UINT64 Address
+ )
+{
+ ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
+
+ return (UINT8) PciSegmentLibReadWorker (Address, PciCfgWidthUint8);
+}
+
+/**
+ Writes an 8-bit PCI configuration register.
+
+ Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.
+ Value is returned. This function must guarantee that all PCI read and write operations are serialized.
+
+ If any reserved bits in Address are set, then ASSERT().
+
+ @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+ @param Value The value to write.
+
+ @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentWrite8 (
+ IN UINT64 Address,
+ IN UINT8 Value
+ )
+{
+ ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
+
+ return (UINT8) PciSegmentLibWriteWorker (Address, PciCfgWidthUint8, Value);
+}
+
+/**
+ Reads a 16-bit PCI configuration register.
+
+ Reads and returns the 16-bit PCI configuration register specified by Address.
+
+ If any reserved bits in Address are set, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+
+ @return The 16-bit PCI configuration register specified by Address.
+
+**/
+UINT16
+EFIAPI
+PciSegmentRead16 (
+ IN UINT64 Address
+ )
+{
+ ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
+
+ return (UINT16) PciSegmentLibReadWorker (Address, PciCfgWidthUint16);
+}
+
+/**
+ Writes a 16-bit PCI configuration register.
+
+ Writes the 16-bit PCI configuration register specified by Address with the
+ value specified by Value.
+
+ Value is returned.
+
+ If any reserved bits in Address are set, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+ @param Value The value to write.
+
+ @return The parameter of Value.
+
+**/
+UINT16
+EFIAPI
+PciSegmentWrite16 (
+ IN UINT64 Address,
+ IN UINT16 Value
+ )
+{
+ ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
+
+ return (UINT16) PciSegmentLibWriteWorker (Address, PciCfgWidthUint16, Value);
+}
+
+/**
+ Reads a 32-bit PCI configuration register.
+
+ Reads and returns the 32-bit PCI configuration register specified by Address.
+
+ If any reserved bits in Address are set, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Segment, Bus, Device, Function,
+ and Register.
+
+ @return The 32-bit PCI configuration register specified by Address.
+
+**/
+UINT32
+EFIAPI
+PciSegmentRead32 (
+ IN UINT64 Address
+ )
+{
+ ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
+
+ return PciSegmentLibReadWorker (Address, PciCfgWidthUint32);
+}
+
+/**
+ Writes a 32-bit PCI configuration register.
+
+ Writes the 32-bit PCI configuration register specified by Address with the
+ value specified by Value.
+
+ Value is returned.
+
+ If any reserved bits in Address are set, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Segment, Bus, Device,
+ Function, and Register.
+ @param Value The value to write.
+
+ @return The parameter of Value.
+
+**/
+UINT32
+EFIAPI
+PciSegmentWrite32 (
+ IN UINT64 Address,
+ IN UINT32 Value
+ )
+{
+ ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
+
+ return PciSegmentLibWriteWorker (Address, PciCfgWidthUint32, Value);
+}
+
+/**
+ Reads a range of PCI configuration registers into a caller supplied buffer.
+
+ Reads the range of PCI configuration registers specified by StartAddress and
+ Size into the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be read. Size is
+ returned.
+
+ If any reserved bits in StartAddress are set, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param StartAddress The starting address that encodes the PCI Segment, Bus,
+ Device, Function and Register.
+ @param Size The size in bytes of the transfer.
+ @param Buffer The pointer to a buffer receiving the data read.
+
+ @return Size
+
+**/
+UINTN
+EFIAPI
+PciSegmentReadBuffer (
+ IN UINT64 StartAddress,
+ IN UINTN Size,
+ OUT VOID *Buffer
+ )
+{
+ UINTN ReturnValue;
+
+ ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
+ ASSERT (((StartAddress & 0xFFF) + Size) <= SIZE_4KB);
+
+ if (Size == 0) {
+ return Size;
+ }
+
+ ASSERT (Buffer != NULL);
+
+ //
+ // Save Size for return
+ //
+ ReturnValue = Size;
+
+ if ((StartAddress & BIT0) != 0) {
+ //
+ // Read a byte if StartAddress is byte aligned
+ //
+ *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
+ StartAddress += sizeof (UINT8);
+ Size -= sizeof (UINT8);
+ Buffer = (UINT8*)Buffer + BIT0;
+ }
+
+ if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
+ //
+ // Read a word if StartAddress is word aligned
+ //
+ WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
+ StartAddress += sizeof (UINT16);
+ Size -= sizeof (UINT16);
+ Buffer = (UINT16*)Buffer + BIT0;
+ }
+
+ while (Size >= sizeof (UINT32)) {
+ //
+ // Read as many double words as possible
+ //
+ WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));
+ StartAddress += sizeof (UINT32);
+ Size -= sizeof (UINT32);
+ Buffer = (UINT32*)Buffer + BIT0;
+ }
+
+ if (Size >= sizeof (UINT16)) {
+ //
+ // Read the last remaining word if exist
+ //
+ WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
+ StartAddress += sizeof (UINT16);
+ Size -= sizeof (UINT16);
+ Buffer = (UINT16*)Buffer + BIT0;
+ }
+
+ if (Size >= sizeof (UINT8)) {
+ //
+ // Read the last remaining byte if exist
+ //
+ *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
+ }
+
+ return ReturnValue;
+}
+
+
+/**
+ Copies the data in a caller supplied buffer to a specified range of PCI
+ configuration space.
+
+ Writes the range of PCI configuration registers specified by StartAddress and
+ Size from the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be written. Size is
+ returned.
+
+ If any reserved bits in StartAddress are set, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param StartAddress The starting address that encodes the PCI Segment, Bus,
+ Device, Function and Register.
+ @param Size The size in bytes of the transfer.
+ @param Buffer The pointer to a buffer containing the data to write.
+
+ @return The parameter of Size.
+
+**/
+UINTN
+EFIAPI
+PciSegmentWriteBuffer (
+ IN UINT64 StartAddress,
+ IN UINTN Size,
+ IN VOID *Buffer
+ )
+{
+ UINTN ReturnValue;
+
+ ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
+ ASSERT (((StartAddress & 0xFFF) + Size) <= SIZE_4KB);
+
+ if (Size == 0) {
+ return Size;
+ }
+
+ ASSERT (Buffer != NULL);
+
+ //
+ // Save Size for return
+ //
+ ReturnValue = Size;
+
+ if ((StartAddress & BIT0) != 0) {
+ //
+ // Write a byte if StartAddress is byte aligned
+ //
+ PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);
+ StartAddress += sizeof (UINT8);
+ Size -= sizeof (UINT8);
+ Buffer = (UINT8*)Buffer + BIT0;
+ }
+
+ if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
+ //
+ // Write a word if StartAddress is word aligned
+ //
+ PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
+ StartAddress += sizeof (UINT16);
+ Size -= sizeof (UINT16);
+ Buffer = (UINT16*)Buffer + BIT0;
+ }
+
+ while (Size >= sizeof (UINT32)) {
+ //
+ // Write as many double words as possible
+ //
+ PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));
+ StartAddress += sizeof (UINT32);
+ Size -= sizeof (UINT32);
+ Buffer = (UINT32*)Buffer + BIT0;
+ }
+
+ if (Size >= sizeof (UINT16)) {
+ //
+ // Write the last remaining word if exist
+ //
+ PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
+ StartAddress += sizeof (UINT16);
+ Size -= sizeof (UINT16);
+ Buffer = (UINT16*)Buffer + BIT0;
+ }
+
+ if (Size >= sizeof (UINT8)) {
+ //
+ // Write the last remaining byte if exist
+ //
+ PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);
+ }
+
+ return ReturnValue;
+}
+
+EFI_STATUS
+PciSegLibInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return EFI_SUCCESS;
+}
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 10/16] Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS Controller
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
` (8 preceding siblings ...)
2020-05-21 23:02 ` [PATCH edk2-platforms 09/16] Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-22 9:36 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 11/16] Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller Wasim Khan
` (6 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
PCIe Layerscape controller can be enabled for ECAM style
configuration access using CFG SHIFT Feature.
Check for PcdPciCfgShiftEnable to decide the configuration access
scheme to be used with PCIe LS controller.
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf | 3 +++
Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 20 ++++++++++++++++----
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
index a36e79239b33..936213dc8a9d 100755
--- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
+++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
@@ -30,3 +30,6 @@ [LibraryClasses]
[FixedPcd]
gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
+
+[Pcd]
+ gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
index ecd36971b753..552a425c6832 100755
--- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
+++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
@@ -34,6 +34,8 @@ typedef enum {
#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
+static BOOLEAN CfgShiftEnable;
+
STATIC
UINT64
PciLsCfgTarget (
@@ -88,11 +90,20 @@ PciLsGetConfigBase (
{
UINT32 CfgAddr;
- CfgAddr = (UINT16)Offset;
- if (Bus) {
- return PciLsCfgTarget (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment, Address, Segment, Bus, Offset);
+ if (CfgShiftEnable) {
+ CfgAddr = (UINT32)Address;
+ if (Bus) {
+ return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment + CfgAddr;
+ } else {
+ return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
+ }
} else {
- return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
+ CfgAddr = (UINT16)Offset;
+ if (Bus) {
+ return PciLsCfgTarget (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment, Address, Segment, Bus, Offset);
+ } else {
+ return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
+ }
}
}
@@ -608,5 +619,6 @@ PciSegLibInit (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
+ CfgShiftEnable = CFG_SHIFT_ENABLE;
return EFI_SUCCESS;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 11/16] Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
` (9 preceding siblings ...)
2020-05-21 23:02 ` [PATCH edk2-platforms 10/16] Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS Controller Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-22 9:38 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 12/16] Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264 Wasim Khan
` (5 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
PCIe Layerscape Gen4 controller is not ECAM complaint and have
different PCI config space region for bus 0 (Controller space) and
bus[0x1-0xff] on NXP SoCs.
For config transactions for Bus0:
- Config transaction address = PCIe controller address + offset
For config transactions for Bus[0x1-0xff]:
- PCIe IP requires target BDF to be written at bit[31:16] of PCIe
outbound configuration window.
PCIe LsGen4 controller uses paging mechanism to access registers.
To access PCIe CCSR registers which are above 3KB offset, page number
must be set in Bridge Control Register.
Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
.../NXP/Library/PciSegmentLib/PciSegmentLib.inf | 1 +
Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 60 +++++++++++++++++++++-
2 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
index 936213dc8a9d..d6d7ea6e3b6b 100755
--- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
+++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
@@ -33,3 +33,4 @@ [FixedPcd]
[Pcd]
gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
+ gNxpQoriqLsTokenSpaceGuid.PcdPciLsGen4Ctrl
diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
index 552a425c6832..02a1525ef308 100755
--- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
+++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
@@ -35,6 +35,58 @@ typedef enum {
ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
static BOOLEAN CfgShiftEnable;
+static BOOLEAN PciLsGen4Ctrl;
+
+STATIC
+VOID
+PcieCfgSetTarget (
+ IN EFI_PHYSICAL_ADDRESS Dbi,
+ IN UINT32 Target)
+{
+ PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_L(0), Target);
+ PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_H(0), 0);
+}
+
+/**
+ Function to return PCIe Physical Address(PCIe view) or Controller
+ Address(CPU view) for NXP Layerscape Gen4 SoC
+
+ @param Address Address passed from bus layer.
+ @param Segment Segment number for Root Complex.
+ @param Offset Config space register offset.
+ @param Bus PCIe Bus number.
+
+ @return Return PCIe CPU or Controller address.
+
+**/
+STATIC
+UINT64
+PciLsGen4GetConfigBase (
+ IN UINT64 Address,
+ IN UINT16 Segment,
+ IN UINT16 Offset,
+ IN UINT8 Bus
+ )
+{
+ UINT32 Target;
+
+ if (Bus) {
+ Target = ((((Address >> 20) & 0xFF) << 24) |
+ (((Address >> 15) & 0x1F) << 19) |
+ (((Address >> 12) & 0x7) << 16));
+
+ PcieCfgSetTarget ((PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF* Segment), Target);
+ return PCI_SEG0_MMIO_MEMBASE + Offset + PCI_BASE_DIFF * Segment;
+ } else {
+ if (Offset < INDIRECT_ADDR_BNDRY) {
+ PciLsGen4SetPg (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment, 0);
+ return (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + Offset);
+ }
+ PciLsGen4SetPg (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment, OFFSET_TO_PAGE_IDX (Offset));
+ Offset = OFFSET_TO_PAGE_ADDR (Offset);
+ return (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + Offset);
+ }
+}
STATIC
UINT64
@@ -129,7 +181,12 @@ PciSegmentLibGetConfigBase (
UINT8 Bus;
Bus = ((UINT32)Address >> 20) & 0xff;
- return PciLsGetConfigBase (Address, Segment, Offset, Bus);
+
+ if (PciLsGen4Ctrl) {
+ return PciLsGen4GetConfigBase (Address, Segment, Offset, Bus);
+ } else {
+ return PciLsGetConfigBase (Address, Segment, Offset, Bus);
+ }
}
/**
@@ -620,5 +677,6 @@ PciSegLibInit (
)
{
CfgShiftEnable = CFG_SHIFT_ENABLE;
+ PciLsGen4Ctrl = PCI_LS_GEN4_CTRL;
return EFI_SUCCESS;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 12/16] Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
` (10 preceding siblings ...)
2020-05-21 23:02 ` [PATCH edk2-platforms 11/16] Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-22 9:39 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 13/16] Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver Wasim Khan
` (4 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
With PCIe LsGen4 controller, clearing the Bus Master Enable bit in
Command register blocks all outbound transactions to be sent out
in RC mode.
According to PCI Express base specification, the Command register’s
Bus Master Enable bit of a PCI Express RC controller can only
control the forwarding of memory requests received at its root port
in the upstream direction. In other words, clearing the Bus Master
Enable bit must not block all outbound transactions to be sent out
toward RC’s downstream devices. Due to this erratum, when the
Command register’s Bus Master Enable bit is cleared, all the outbound
transactions from the device’s internal bus masters, including but
not limited to configuration read and write transactions, are
terminated with the slave error (SLVERR) response status on the PCI
Express RC controller’s internal AXI bus interface.
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
index 02a1525ef308..c3bc14820ea5 100755
--- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
+++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
@@ -39,6 +39,21 @@ static BOOLEAN PciLsGen4Ctrl;
STATIC
VOID
+PciLsGen4SetBusMaster (
+ IN EFI_PHYSICAL_ADDRESS Dbi
+ )
+{
+ UINT32 Val;
+
+ /* Make sure the Master Enable bit not cleared */
+ Val = PciLsGen4Read32 ((UINTN)Dbi, PCI_COMMAND_OFFSET);
+ if (!(Val & EFI_PCI_COMMAND_BUS_MASTER)) {
+ PciLsGen4Write32 ((UINTN)Dbi, PCI_COMMAND_OFFSET, Val | EFI_PCI_COMMAND_BUS_MASTER);
+ }
+}
+
+STATIC
+VOID
PcieCfgSetTarget (
IN EFI_PHYSICAL_ADDRESS Dbi,
IN UINT32 Target)
@@ -71,6 +86,8 @@ PciLsGen4GetConfigBase (
UINT32 Target;
if (Bus) {
+ PciLsGen4SetBusMaster (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF* Segment);
+
Target = ((((Address >> 20) & 0xFF) << 24) |
(((Address >> 15) & 0x1F) << 19) |
(((Address >> 12) & 0x7) << 16));
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 13/16] Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
` (11 preceding siblings ...)
2020-05-21 23:02 ` [PATCH edk2-platforms 12/16] Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264 Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-22 9:42 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 14/16] Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg Wasim Khan
` (3 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
NXP SoC has multiple PCIe RCs and there is no fix translation
offset between I/O port accesses and MMIO accesses.
Add PciCpuIo2Dxe driver to implement EFI_CPU_IO2_PROTOCOL
to add the translation for different RCs for IO access.
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf | 40 ++
Silicon/NXP/Include/Pcie.h | 19 +
Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c | 628 ++++++++++++++++++++++
3 files changed, 687 insertions(+)
create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c
diff --git a/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
new file mode 100755
index 000000000000..0ee470e41d5e
--- /dev/null
+++ b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
@@ -0,0 +1,40 @@
+## @file
+# Produces the CPU I/O 2 Protocol by using the services of the I/O Library.
+#
+# Copyright 2018, 2020 NXP
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = PciCpuIo2Dxe
+ FILE_GUID = 7bff18d7-9aae-434b-9c06-f10a7e157eac
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PciCpuIo2Initialize
+
+[Sources]
+ PciCpuIo2Dxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ Silicon/NXP/NxpQoriqLs.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ IoLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Pcd]
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
+ gNxpQoriqLsTokenSpaceGuid.PcdNumPciController
+
+[Protocols]
+ gEfiCpuIo2ProtocolGuid ## PRODUCES
+
+[Depex]
+ TRUE
diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h
index bc35570f79bc..b561d0e3ba11 100755
--- a/Silicon/NXP/Include/Pcie.h
+++ b/Silicon/NXP/Include/Pcie.h
@@ -39,6 +39,25 @@
#define PCI_SEG0_PHY_MEM_BASE PCI_SEG0_MMIO_MEMBASE + SEG_MEM_BASE
#define PCI_SEG0_PHY_MEM64_BASE PCI_SEG0_MMIO_MEMBASE + SEG_MEM64_BASE
#define PCI_SEG0_PHY_IO_BASE PCI_SEG0_MMIO_MEMBASE + SEG_IO_BASE
+#define PCI_SEG0_PORTIO_MIN 0x0
+#define PCI_SEG0_PORTIO_MAX 0xffff
+#define PCI_SEG0_PORTIO_OFFSET 0x0
+#define PCI_SEG1_PORTIO_MIN 0x0
+#define PCI_SEG1_PORTIO_MAX 0xffff
+#define PCI_SEG1_PORTIO_OFFSET 0x10000
+#define PCI_SEG2_PORTIO_MIN 0x0
+#define PCI_SEG2_PORTIO_MAX 0xffff
+#define PCI_SEG2_PORTIO_OFFSET 0x20000
+#define PCI_SEG3_PORTIO_MIN 0x0
+#define PCI_SEG3_PORTIO_MAX 0xffff
+#define PCI_SEG3_PORTIO_OFFSET 0x30000
+#define PCI_SEG4_PORTIO_MIN 0x0
+#define PCI_SEG4_PORTIO_MAX 0xffff
+#define PCI_SEG4_PORTIO_OFFSET 0x40000
+#define PCI_SEG5_PORTIO_MIN 0x0
+#define PCI_SEG5_PORTIO_MAX 0xffff
+#define PCI_SEG5_PORTIO_OFFSET 0x50000
+#define PCI_SEG_PORTIO_LIMIT PCI_SEG5_PORTIO_MAX + PCI_SEG5_PORTIO_OFFSET
// PCIe Controller configuration
#define NUM_PCIE_CONTROLLER FixedPcdGet32 (PcdNumPciController)
diff --git a/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c
new file mode 100755
index 000000000000..17db44a8b510
--- /dev/null
+++ b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c
@@ -0,0 +1,628 @@
+/** @file
+ Produces the CPU I/O 2 Protocol.
+
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+ Copyright 2018-2020 NXP
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Pcie.h>
+#include <Protocol/CpuIo2.h>
+
+#define MAX_IO_PORT_ADDRESS PCI_SEG_PORTIO_LIMIT
+
+//
+// Handle for the CPU I/O 2 Protocol
+//
+STATIC EFI_HANDLE mHandle = NULL;
+
+//
+// Lookup table for increment values based on transfer widths
+//
+STATIC CONST UINT8 mInStride[] = {
+ 1, // EfiCpuIoWidthUint8
+ 2, // EfiCpuIoWidthUint16
+ 4, // EfiCpuIoWidthUint32
+ 8, // EfiCpuIoWidthUint64
+ 0, // EfiCpuIoWidthFifoUint8
+ 0, // EfiCpuIoWidthFifoUint16
+ 0, // EfiCpuIoWidthFifoUint32
+ 0, // EfiCpuIoWidthFifoUint64
+ 1, // EfiCpuIoWidthFillUint8
+ 2, // EfiCpuIoWidthFillUint16
+ 4, // EfiCpuIoWidthFillUint32
+ 8 // EfiCpuIoWidthFillUint64
+};
+
+//
+// Lookup table for increment values based on transfer widths
+//
+STATIC CONST UINT8 mOutStride[] = {
+ 1, // EfiCpuIoWidthUint8
+ 2, // EfiCpuIoWidthUint16
+ 4, // EfiCpuIoWidthUint32
+ 8, // EfiCpuIoWidthUint64
+ 1, // EfiCpuIoWidthFifoUint8
+ 2, // EfiCpuIoWidthFifoUint16
+ 4, // EfiCpuIoWidthFifoUint32
+ 8, // EfiCpuIoWidthFifoUint64
+ 0, // EfiCpuIoWidthFillUint8
+ 0, // EfiCpuIoWidthFillUint16
+ 0, // EfiCpuIoWidthFillUint32
+ 0 // EfiCpuIoWidthFillUint64
+};
+
+/**
+ Check parameters to a CPU I/O 2 Protocol service request.
+
+ The I/O operations are carried out exactly as requested. The caller is responsible
+ for satisfying any alignment and I/O width restrictions that a PI System on a
+ platform might require. For example on some platforms, width requests of
+ EfiCpuIoWidthUint64 do not work.
+
+ @param[in] MmioOperation TRUE for an MMIO operation, FALSE for I/O Port operation.
+ @param[in] Width Signifies the width of the I/O or Memory operation.
+ @param[in] Address The base address of the I/O operation.
+ @param[in] Count The number of I/O operations to perform. The number of
+ bytes moved is Width size * Count, starting at Address.
+ @param[in] Buffer For read operations, the destination buffer to store the results.
+ For write operations, the source buffer from which to write data.
+
+ @retval EFI_SUCCESS The parameters for this request pass the checks.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.
+ @retval EFI_UNSUPPORTED The address range specified by Address, Width,
+ and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+CpuIoCheckParameter (
+ IN BOOLEAN MmioOperation,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ UINT64 MaxCount;
+ UINT64 Limit;
+
+ //
+ // Check to see if Buffer is NULL
+ //
+ if (Buffer == NULL) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check to see if Width is in the valid range
+ //
+ if ((UINT32)Width >= EfiCpuIoWidthMaximum) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // For FIFO type, the target address won't increase during the access,
+ // so treat Count as 1
+ //
+ if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
+ Count = 1;
+ }
+
+ //
+ // Check to see if Width is in the valid range for I/O Port operations
+ //
+ Width = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
+ if (!MmioOperation && (Width == EfiCpuIoWidthUint64)) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check to see if Address is aligned
+ //
+ if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Check to see if any address associated with this transfer exceeds the maximum
+ // allowed address. The maximum address implied by the parameters passed in is
+ // Address + Size * Count. If the following condition is met, then the transfer
+ // is not supported.
+ //
+ // Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1
+ //
+ // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count
+ // can also be the maximum integer value supported by the CPU, this range
+ // check must be adjusted to avoid all oveflow conditions.
+ //
+ Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS);
+ if (Count == 0) {
+ if (Address > Limit) {
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ MaxCount = RShiftU64 (Limit, Width);
+ if (MaxCount < (Count - 1)) {
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+ }
+ if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ //
+ // Check to see if Buffer is aligned
+ //
+ if (((UINTN)Buffer & ((MIN (sizeof (UINTN), mInStride[Width]) - 1))) != 0) {
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Reads memory-mapped registers.
+
+ The I/O operations are carried out exactly as requested. The caller is responsible
+ for satisfying any alignment and I/O width restrictions that a PI System on a
+ platform might require. For example on some platforms, width requests of
+ EfiCpuIoWidthUint64 do not work.
+
+ If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+ or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+ each of the Count operations that is performed.
+
+ If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+ EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+ incremented for each of the Count operations that is performed. The read or
+ write operation is performed Count times on the same Address.
+
+ If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+ EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+ incremented for each of the Count operations that is performed. The read or
+ write operation is performed Count times from the first element of Buffer.
+
+ @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+ @param[in] Width Signifies the width of the I/O or Memory operation.
+ @param[in] Address The base address of the I/O operation.
+ @param[in] Count The number of I/O operations to perform. The number of
+ bytes moved is Width size * Count, starting at Address.
+ @param[out] Buffer For read operations, the destination buffer to store the results.
+ For write operations, the source buffer from which to write data.
+
+ @retval EFI_SUCCESS The data was read from or written to the PI system.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.
+ @retval EFI_UNSUPPORTED The address range specified by Address, Width,
+ and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceRead (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 InStride;
+ UINT8 OutStride;
+ EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth;
+ UINT8 *Uint8Buffer;
+
+ Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ InStride = mInStride[Width];
+ OutStride = mOutStride[Width];
+ OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+ for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+ if (OperationWidth == EfiCpuIoWidthUint8) {
+ *Uint8Buffer = MmioRead8 ((UINTN)Address);
+ } else if (OperationWidth == EfiCpuIoWidthUint16) {
+ *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+ } else if (OperationWidth == EfiCpuIoWidthUint32) {
+ *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+ } else if (OperationWidth == EfiCpuIoWidthUint64) {
+ *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Writes memory-mapped registers.
+
+ The I/O operations are carried out exactly as requested. The caller is responsible
+ for satisfying any alignment and I/O width restrictions that a PI System on a
+ platform might require. For example on some platforms, width requests of
+ EfiCpuIoWidthUint64 do not work.
+
+ If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+ or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+ each of the Count operations that is performed.
+
+ If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+ EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+ incremented for each of the Count operations that is performed. The read or
+ write operation is performed Count times on the same Address.
+
+ If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+ EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+ incremented for each of the Count operations that is performed. The read or
+ write operation is performed Count times from the first element of Buffer.
+
+ @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+ @param[in] Width Signifies the width of the I/O or Memory operation.
+ @param[in] Address The base address of the I/O operation.
+ @param[in] Count The number of I/O operations to perform. The number of
+ bytes moved is Width size * Count, starting at Address.
+ @param[in] Buffer For read operations, the destination buffer to store the results.
+ For write operations, the source buffer from which to write data.
+
+ @retval EFI_SUCCESS The data was read from or written to the PI system.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.
+ @retval EFI_UNSUPPORTED The address range specified by Address, Width,
+ and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceWrite (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 InStride;
+ UINT8 OutStride;
+ EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth;
+ UINT8 *Uint8Buffer;
+
+ Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ InStride = mInStride[Width];
+ OutStride = mOutStride[Width];
+ OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+ for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+ if (OperationWidth == EfiCpuIoWidthUint8) {
+ MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+ } else if (OperationWidth == EfiCpuIoWidthUint16) {
+ MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+ } else if (OperationWidth == EfiCpuIoWidthUint32) {
+ MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+ } else if (OperationWidth == EfiCpuIoWidthUint64) {
+ MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+TranslateIoAddress (
+ IN OUT UINT64 *Address
+ )
+{
+ UINT64 Start;
+ UINT64 End;
+ UINT64 Shift;
+ UINT64 SegIoHostAddressBase;
+
+ SegIoHostAddressBase = PCI_SEG0_PHY_IO_BASE;
+ Start = PCI_SEG0_PORTIO_MIN + PCI_SEG0_PORTIO_OFFSET;
+ End = PCI_SEG0_PORTIO_MAX + PCI_SEG0_PORTIO_OFFSET;
+ Shift = SegIoHostAddressBase - PCI_SEG0_PORTIO_OFFSET;
+
+ if (*Address >= Start && *Address <= End) {
+ *Address += Shift;
+ return EFI_SUCCESS;
+ }
+
+ Start = PCI_SEG1_PORTIO_MIN + PCI_SEG1_PORTIO_OFFSET;
+ End = PCI_SEG1_PORTIO_MAX + PCI_SEG1_PORTIO_OFFSET;
+ Shift = (SegIoHostAddressBase + (PCI_BASE_DIFF * 1)) - PCI_SEG1_PORTIO_OFFSET;
+
+ if (*Address >= Start && *Address <= End) {
+ *Address += Shift;
+ return EFI_SUCCESS;
+ }
+
+ Start = PCI_SEG2_PORTIO_MIN + PCI_SEG2_PORTIO_OFFSET;
+ End = PCI_SEG2_PORTIO_MAX + PCI_SEG2_PORTIO_OFFSET;
+ Shift = (SegIoHostAddressBase + (PCI_BASE_DIFF * 2)) - PCI_SEG2_PORTIO_OFFSET;
+
+ if (*Address >= Start && *Address <= End) {
+ *Address += Shift;
+ return EFI_SUCCESS;
+ }
+
+ Start = PCI_SEG3_PORTIO_MIN + PCI_SEG3_PORTIO_OFFSET;
+ End = PCI_SEG3_PORTIO_MAX + PCI_SEG3_PORTIO_OFFSET;
+ Shift = (SegIoHostAddressBase + (PCI_BASE_DIFF * 3)) - PCI_SEG3_PORTIO_OFFSET;
+
+ if (*Address >= Start && *Address <= End) {
+ *Address += Shift;
+ return EFI_SUCCESS;
+ }
+
+ Start = PCI_SEG4_PORTIO_MIN + PCI_SEG4_PORTIO_OFFSET;
+ End = PCI_SEG4_PORTIO_MAX + PCI_SEG4_PORTIO_OFFSET;
+ Shift = (SegIoHostAddressBase + (PCI_BASE_DIFF * 4)) - PCI_SEG4_PORTIO_OFFSET;
+
+ if (*Address >= Start && *Address <= End) {
+ *Address += Shift;
+ return EFI_SUCCESS;
+ }
+
+ Start = PCI_SEG5_PORTIO_MIN + PCI_SEG5_PORTIO_OFFSET;
+ End = PCI_SEG5_PORTIO_MAX + PCI_SEG5_PORTIO_OFFSET;
+ Shift = (SegIoHostAddressBase + (PCI_BASE_DIFF * 5)) - PCI_SEG5_PORTIO_OFFSET;
+
+ if (*Address >= Start && *Address <= End) {
+ *Address += Shift;
+ return EFI_SUCCESS;
+ }
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+}
+
+/**
+ Reads I/O registers.
+
+ The I/O operations are carried out exactly as requested. The caller is responsible
+ for satisfying any alignment and I/O width restrictions that a PI System on a
+ platform might require. For example on some platforms, width requests of
+ EfiCpuIoWidthUint64 do not work.
+
+ If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+ or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+ each of the Count operations that is performed.
+
+ If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+ EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+ incremented for each of the Count operations that is performed. The read or
+ write operation is performed Count times on the same Address.
+
+ If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+ EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+ incremented for each of the Count operations that is performed. The read or
+ write operation is performed Count times from the first element of Buffer.
+
+ @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+ @param[in] Width Signifies the width of the I/O or Memory operation.
+ @param[in] Address The base address of the I/O operation.
+ @param[in] Count The number of I/O operations to perform. The number of
+ bytes moved is Width size * Count, starting at Address.
+ @param[out] Buffer For read operations, the destination buffer to store the results.
+ For write operations, the source buffer from which to write data.
+
+ @retval EFI_SUCCESS The data was read from or written to the PI system.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.
+ @retval EFI_UNSUPPORTED The address range specified by Address, Width,
+ and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuIoServiceRead (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 InStride;
+ UINT8 OutStride;
+ EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth;
+ UINT8 *Uint8Buffer;
+
+ Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = TranslateIoAddress (&Address);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ InStride = mInStride[Width];
+ OutStride = mOutStride[Width];
+ OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
+
+ for (Uint8Buffer = Buffer; Count > 0;
+ Address += InStride, Uint8Buffer += OutStride, Count--) {
+ if (OperationWidth == EfiCpuIoWidthUint8) {
+ *Uint8Buffer = MmioRead8 ((UINTN)Address);
+ } else if (OperationWidth == EfiCpuIoWidthUint16) {
+ *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+ } else if (OperationWidth == EfiCpuIoWidthUint32) {
+ *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Write I/O registers.
+
+ The I/O operations are carried out exactly as requested. The caller is responsible
+ for satisfying any alignment and I/O width restrictions that a PI System on a
+ platform might require. For example on some platforms, width requests of
+ EfiCpuIoWidthUint64 do not work.
+
+ If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
+ or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
+ each of the Count operations that is performed.
+
+ If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
+ EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
+ incremented for each of the Count operations that is performed. The read or
+ write operation is performed Count times on the same Address.
+
+ If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
+ EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
+ incremented for each of the Count operations that is performed. The read or
+ write operation is performed Count times from the first element of Buffer.
+
+ @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance.
+ @param[in] Width Signifies the width of the I/O or Memory operation.
+ @param[in] Address The base address of the I/O operation.
+ @param[in] Count The number of I/O operations to perform. The number of
+ bytes moved is Width size * Count, starting at Address.
+ @param[in] Buffer For read operations, the destination buffer to store the results.
+ For write operations, the source buffer from which to write data.
+
+ @retval EFI_SUCCESS The data was read from or written to the PI system.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.
+ @retval EFI_UNSUPPORTED The address range specified by Address, Width,
+ and Count is not valid for this PI system.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CpuIoServiceWrite (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 InStride;
+ UINT8 OutStride;
+ EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth;
+ UINT8 *Uint8Buffer;
+
+ //
+ // Make sure the parameters are valid
+ //
+ Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = TranslateIoAddress (&Address);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Select loop based on the width of the transfer
+ //
+ InStride = mInStride[Width];
+ OutStride = mOutStride[Width];
+ OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
+
+ for (Uint8Buffer = (UINT8 *)Buffer; Count > 0;
+ Address += InStride, Uint8Buffer += OutStride, Count--) {
+ if (OperationWidth == EfiCpuIoWidthUint8) {
+ MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+ } else if (OperationWidth == EfiCpuIoWidthUint16) {
+ MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+ } else if (OperationWidth == EfiCpuIoWidthUint32) {
+ MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//
+// CPU I/O 2 Protocol instance
+//
+STATIC EFI_CPU_IO2_PROTOCOL mCpuIo2 = {
+ {
+ CpuMemoryServiceRead,
+ CpuMemoryServiceWrite
+ },
+ {
+ CpuIoServiceRead,
+ CpuIoServiceWrite
+ }
+};
+
+
+/**
+ The user Entry Point for module CpuIo2Dxe. The user code starts with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+PciCpuIo2Initialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiCpuIo2ProtocolGuid);
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEfiCpuIo2ProtocolGuid, &mCpuIo2,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 14/16] Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
` (12 preceding siblings ...)
2020-05-21 23:02 ` [PATCH edk2-platforms 13/16] Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-22 9:42 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 15/16] Platform/NXP: LS1043aRdbPkg: Enable PCIE support Wasim Khan
` (2 subsequent siblings)
16 siblings, 1 reply; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
Enable NetworkPkg for LS1043aRdb Platform.
Signed-off-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc | 11 +++++++++++
Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 5 +++++
2 files changed, 16 insertions(+)
diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
index d45fd67c03b5..8f7f9d171587 100644
--- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
+++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
@@ -22,6 +22,13 @@ [Defines]
OUTPUT_DIRECTORY = Build/LS1043aRdbPkg
FLASH_DEFINITION = Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
+ #
+ # Network definition
+ #
+ DEFINE NETWORK_TLS_ENABLE = FALSE
+ DEFINE NETWORK_HTTP_BOOT_ENABLE = FALSE
+ DEFINE NETWORK_ISCSI_ENABLE = FALSE
+
!include Silicon/NXP/NxpQoriqLs.dsc.inc
!include Silicon/NXP/LS1043A/LS1043A.dsc.inc
@@ -54,4 +61,8 @@ [Components.common]
Silicon/NXP/Drivers/I2cDxe/I2cDxe.inf
Platform/NXP/LS1043aRdbPkg/Drivers/PlatformDxe/PlatformDxe.inf
+ #
+ # Networking stack
+ #
+!include NetworkPkg/Network.dsc.inc
##
diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
index 931d0bb14f9b..596922221e8c 100644
--- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
+++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
@@ -119,6 +119,11 @@ [FV.FvMain]
INF EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
#
+ # Networking stack
+ #
+!include NetworkPkg/Network.fdf.inc
+
+ #
# FAT filesystem + GPT/MBR partitioning
#
INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 15/16] Platform/NXP: LS1043aRdbPkg: Enable PCIE support
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
` (13 preceding siblings ...)
2020-05-21 23:02 ` [PATCH edk2-platforms 14/16] Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-21 23:02 ` [PATCH edk2-platforms 16/16] Platform/NXP: LS1043aRdbPkg : Increase fv image size Wasim Khan
2020-05-22 9:46 ` [PATCH edk2-platforms 00/16] Add PCIe Support Ard Biesheuvel
16 siblings, 0 replies; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
Enable generic PCIe drivers and Wire up PciHostBridgeLib,
PciSegmentLib and PciCpuIo2Dxe.
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc | 9 +++++++++
Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 7 +++++++
2 files changed, 16 insertions(+)
diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
index 8f7f9d171587..6d07d5164002 100644
--- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
+++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
@@ -35,6 +35,8 @@ [Defines]
[LibraryClasses.common]
ArmPlatformLib|Platform/NXP/LS1043aRdbPkg/Library/ArmPlatformLib/ArmPlatformLib.inf
RealTimeClockLib|Silicon/Maxim/Library/Ds1307RtcLib/Ds1307RtcLib.inf
+ PciSegmentLib|Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
+ PciHostBridgeLib|Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
[PcdsFixedAtBuild.common]
#
@@ -62,6 +64,13 @@ [Components.common]
Platform/NXP/LS1043aRdbPkg/Drivers/PlatformDxe/PlatformDxe.inf
#
+ # PCI
+ #
+ Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
+ MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+ MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+ #
# Networking stack
#
!include NetworkPkg/Network.dsc.inc
diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
index 596922221e8c..81142f217a63 100644
--- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
+++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
@@ -124,6 +124,13 @@ [FV.FvMain]
!include NetworkPkg/Network.fdf.inc
#
+ # PCI
+ #
+ INF Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
+ INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+ INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+ #
# FAT filesystem + GPT/MBR partitioning
#
INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH edk2-platforms 16/16] Platform/NXP: LS1043aRdbPkg : Increase fv image size
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
` (14 preceding siblings ...)
2020-05-21 23:02 ` [PATCH edk2-platforms 15/16] Platform/NXP: LS1043aRdbPkg: Enable PCIE support Wasim Khan
@ 2020-05-21 23:02 ` Wasim Khan
2020-05-22 9:44 ` Ard Biesheuvel
2020-05-22 9:46 ` [PATCH edk2-platforms 00/16] Add PCIe Support Ard Biesheuvel
16 siblings, 1 reply; 42+ messages in thread
From: Wasim Khan @ 2020-05-21 23:02 UTC (permalink / raw)
To: devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi, ard.biesheuvel,
leif, jon
Cc: Wasim Khan
From: Wasim Khan <wasim.khan@nxp.com>
Increase fv image size to pass debug build.
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
---
Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
index 81142f217a63..1c160e349eb9 100644
--- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
+++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
@@ -24,10 +24,12 @@
[FD.LS1043ARDB_EFI]
BaseAddress = 0x82000000|gArmTokenSpaceGuid.PcdFdBaseAddress #The base address of the FLASH Device.
-Size = 0x00140000|gArmTokenSpaceGuid.PcdFdSize #The size in bytes of the FLASH Device
+Size = 0x00180000|gArmTokenSpaceGuid.PcdFdSize #The size in bytes of the FLASH Device
ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
BlockSize = 0x40000
-NumBlocks = 0x5
+NumBlocks = 0x6
################################################################################
#
@@ -44,7 +46,7 @@ [FD.LS1043ARDB_EFI]
# RegionType <FV, DATA, or FILE>
#
################################################################################
-0x00000000|0x00140000
+0x00000000|0x00180000
gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
FV = FVMAIN_COMPACT
--
2.7.4
^ permalink raw reply related [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 01/16] Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs.
2020-05-21 23:02 ` [PATCH edk2-platforms 01/16] Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs Wasim Khan
@ 2020-05-22 9:12 ` Ard Biesheuvel
2020-05-24 18:31 ` Wasim Khan (OSS)
0 siblings, 1 reply; 42+ messages in thread
From: Ard Biesheuvel @ 2020-05-22 9:12 UTC (permalink / raw)
To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
leif, jon
Cc: Wasim Khan
On 5/22/20 1:02 AM, Wasim Khan wrote:
> From: Wasim Khan <wasim.khan@nxp.com>
>
> Add PCIe related PCDs.
>
> Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Please drop this signoff. This is not the correct way to acknowledge
(co-)authorship.
> Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> ---
> Silicon/NXP/NxpQoriqLs.dec | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/Silicon/NXP/NxpQoriqLs.dec b/Silicon/NXP/NxpQoriqLs.dec
> index 0722f59ef4f6..bafdfd9f4298 100644
> --- a/Silicon/NXP/NxpQoriqLs.dec
> +++ b/Silicon/NXP/NxpQoriqLs.dec
> @@ -27,3 +27,12 @@ [Guids.common]
> [PcdsFeatureFlag]
> gNxpQoriqLsTokenSpaceGuid.PcdI2cErratumA009203|FALSE|BOOLEAN|0x00000315
> gNxpQoriqLsTokenSpaceGuid.PcdDcfgBigEndian|FALSE|BOOLEAN|0x00000316
> + gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian|FALSE|BOOLEAN|0x00000317
> +
> +[PcdsFixedAtBuild.common]
> + # Pcds for PCI Express
> + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr|0x0|UINT64|0x00000500
> + gNxpQoriqLsTokenSpaceGuid.PcdNumPciController|0|UINT32|0x00000501
> + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase|0x0|UINT32|0x00000502
> + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg|0x0|UINT32|0x00000503
> + gNxpQoriqLsTokenSpaceGuid.PcdPciDebug|FALSE|BOOLEAN|0x00000504
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 03/16] Silicon/NXP: Implement PciHostBridgeLib support
2020-05-21 23:02 ` [PATCH edk2-platforms 03/16] Silicon/NXP: Implement PciHostBridgeLib support Wasim Khan
@ 2020-05-22 9:20 ` Ard Biesheuvel
0 siblings, 0 replies; 42+ messages in thread
From: Ard Biesheuvel @ 2020-05-22 9:20 UTC (permalink / raw)
To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
leif, jon
Cc: Wasim Khan
On 5/22/20 1:02 AM, Wasim Khan wrote:
> From: Wasim Khan <wasim.khan@nxp.com>
>
> Implement PciHostBridgeLib that exposes the PCIe root complexes to
> the generic PCI host bridge driver.
>
> Setup PCIe Layerscape Controller and setup CFG, IO,
> MMIO and MMIO64 iATU windows.
>
> Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
> Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> ---
> .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 40 ++
> Silicon/NXP/Include/Pcie.h | 85 +++
> .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 568 +++++++++++++++++++++
> 3 files changed, 693 insertions(+)
> create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> create mode 100755 Silicon/NXP/Include/Pcie.h
> create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
>
> diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> new file mode 100644
> index 000000000000..5ddb96e4fa6a
> --- /dev/null
> +++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> @@ -0,0 +1,40 @@
> +## @file
> +# PCI Host Bridge Library instance for NXP ARM SOC
> +#
> +# Copyright 2018-2020 NXP
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x0001001A
> + BASE_NAME = PciHostBridgeLib
> + FILE_GUID = f4c99bcc-5c95-49ad-b0f3-fc5b611dc9c1
> + MODULE_TYPE = BASE
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = PciHostBridgeLib
> +
> +[Sources]
> + PciHostBridgeLib.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + EmbeddedPkg/EmbeddedPkg.dec
Do you need this?
> + Silicon/NXP/NxpQoriqLs.dec
> +
> +[LibraryClasses]
> + DebugLib
> + DevicePathLib
> + IoAccessLib
> + MemoryAllocationLib
> + PcdLib
> +
> +[FeaturePcd]
> + gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian
> +
> +[FixedPcd]
> + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
> + gNxpQoriqLsTokenSpaceGuid.PcdNumPciController
> + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase
> + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg
> diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h
> new file mode 100755
> index 000000000000..d5b5a3884e0a
> --- /dev/null
> +++ b/Silicon/NXP/Include/Pcie.h
> @@ -0,0 +1,85 @@
> +/** @file
> + PCI memory configuration for NXP
> +
> + Copyright 2018-2020 NXP
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __PCI_H__
> +#define __PCI_H__
> +
Please don't use leading __ for header include guards
> +#define PCI_SEG0_NUM 0
> +#define PCI_SEG1_NUM 1
> +#define PCI_SEG2_NUM 2
> +#define PCI_SEG3_NUM 3
> +#define PCI_SEG4_NUM 4
> +#define PCI_SEG5_NUM 5
> +#define PCI_SEG0_MMIO_MEMBASE FixedPcdGet64 (PcdPciExp1BaseAddr)
> +#define PCI_SEG0_DBI_BASE 0x03400000
> +
> +#define PCI_LINK_DOWN 0x0
> +#define PCI_LINK_UP 0x1
> +
> +// Segment configuration
> +#define PCI_SEG_BUSNUM_MIN 0x0
> +#define PCI_SEG_BUSNUM_MAX 0xff
> +#define PCI_SEG_PORTIO_MIN 0x0
> +#define PCI_SEG_PORTIO_MAX 0xffff
> +#define SEG_CFG_SIZE 0x00001000
> +#define SEG_MEM_BASE 0x40000000
> +#define SEG_MEM_SIZE 0xC0000000
> +#define SEG_MEM_LIMIT SEG_MEM_BASE + (SEG_MEM_SIZE -1)
> +#define SEG_IO_BASE 0x10000000
> +#define SEG_MEM64_BASE 0x400000000
> +#define PCI_BASE_DIFF 0x800000000
> +#define PCI_DBI_SIZE_DIFF 0x100000
> +#define PCI_SEG0_PHY_CFG0_BASE PCI_SEG0_MMIO_MEMBASE
> +#define PCI_SEG0_PHY_CFG1_BASE PCI_SEG0_PHY_CFG0_BASE + SEG_CFG_SIZE
> +#define PCI_SEG0_PHY_MEM_BASE PCI_SEG0_MMIO_MEMBASE + SEG_MEM_BASE
> +#define PCI_SEG0_PHY_MEM64_BASE PCI_SEG0_MMIO_MEMBASE + SEG_MEM64_BASE
> +#define PCI_SEG0_PHY_IO_BASE PCI_SEG0_MMIO_MEMBASE + SEG_IO_BASE
> +
> +// PCIe Controller configuration
> +#define NUM_PCIE_CONTROLLER FixedPcdGet32 (PcdNumPciController)
> +#define PCI_LUT_DBG FixedPcdGet32 (PcdPcieLutDbg)
> +#define PCI_LUT_BASE FixedPcdGet32 (PcdPcieLutBase)
> +#define LTSSM_PCIE_L0 0x11
> +
> +#define PCI_CLASS_BRIDGE_PCI 0x0604
> +#define PCI_CLASS_DEVICE 0x8
> +#define PCI_DBI_RO_WR_EN 0x8bc
> +#define CLASS_CODE_MASK 0xffff
> +#define CLASS_CODE_SHIFT 0x10
> +
> +// PCIe Layerscape Controller
> +#define IATU_VIEWPORT_OFF 0x900
> +#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0 0x904
> +#define IATU_REGION_CTRL_2_OFF_OUTBOUND_0 0x908
> +#define IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0 0x90C
> +#define IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0 0x910
> +#define IATU_LIMIT_ADDR_OFF_OUTBOUND_0 0x914
> +#define IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0 0x918
> +#define IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0 0x91C
> +#define IATU_VIEWPORT_OUTBOUND 0x0
> +#define IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN BIT31
> +
> +// ATU Programming
> +#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM 0x0
> +#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_IO 0x2
> +#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0 0x4
> +#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1 0x5
> +#define IATU_REGION_INDEX0 0x0
> +#define IATU_REGION_INDEX1 0x1
> +#define IATU_REGION_INDEX2 0x2
> +#define IATU_REGION_INDEX3 0x3
> +#define IATU_REGION_INDEX4 0x4
> +#define IATU_REGION_INDEX5 0x5
> +#define IATU_REGION_INDEX6 0x6
> +#define IATU_REGION_INDEX7 0x7
> +#define SEG_CFG_BUS 0x00000000
> +#define SEG_MEM_BUS 0x40000000
> +#define SEG_IO_SIZE 0x10000
> +#define SEG_IO_BUS 0x0
> +
> +#endif
> diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> new file mode 100644
> index 000000000000..cf872370c7cd
> --- /dev/null
> +++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> @@ -0,0 +1,568 @@
> +/** @file
> + PCI Host Bridge Library instance for NXP SoCs
> +
> + Copyright 2018-2020 NXP
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiDxe.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <Library/IoAccessLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
Please keep these alphabetically sorted
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Pcie.h>
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +
> +#pragma pack(1)
> +typedef struct {
> + ACPI_HID_DEVICE_PATH AcpiDevicePath;
> + EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
> +} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
> +#pragma pack ()
> +
> +STATIC CONST EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath[] = {
> + {
> + {
> + {
> + ACPI_DEVICE_PATH,
> + ACPI_DP,
> + {
> + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
> + }
> + },
> + EISA_PNP_ID (0x0A08), // PCI Express
> + PCI_SEG0_NUM
> + },
> +
> + {
> + END_DEVICE_PATH_TYPE,
> + END_ENTIRE_DEVICE_PATH_SUBTYPE,
> + {
> + END_DEVICE_PATH_LENGTH,
> + 0
> + }
> + }
> + },
> + {
> + {
> + {
> + ACPI_DEVICE_PATH,
> + ACPI_DP,
> + {
> + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
> + }
> + },
> + EISA_PNP_ID (0x0A08), // PCI Express
> + PCI_SEG1_NUM
> + },
> +
> + {
> + END_DEVICE_PATH_TYPE,
> + END_ENTIRE_DEVICE_PATH_SUBTYPE,
> + {
> + END_DEVICE_PATH_LENGTH,
> + 0
> + }
> + }
> + },
> + {
> + {
> + {
> + ACPI_DEVICE_PATH,
> + ACPI_DP,
> + {
> + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
> + }
> + },
> + EISA_PNP_ID (0x0A08), // PCI Express
> + PCI_SEG2_NUM
> + },
> +
> + {
> + END_DEVICE_PATH_TYPE,
> + END_ENTIRE_DEVICE_PATH_SUBTYPE,
> + {
> + END_DEVICE_PATH_LENGTH,
> + 0
> + }
> + }
> + },
> + {
> + {
> + {
> + ACPI_DEVICE_PATH,
> + ACPI_DP,
> + {
> + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
> + }
> + },
> + EISA_PNP_ID (0x0A08), // PCI Express
> + PCI_SEG3_NUM
> + },
> +
> + {
> + END_DEVICE_PATH_TYPE,
> + END_ENTIRE_DEVICE_PATH_SUBTYPE,
> + {
> + END_DEVICE_PATH_LENGTH,
> + 0
> + }
> + }
> + },
> + {
> + {
> + {
> + ACPI_DEVICE_PATH,
> + ACPI_DP,
> + {
> + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
> + }
> + },
> + EISA_PNP_ID (0x0A08), // PCI Express
> + PCI_SEG4_NUM
> + },
> +
> + {
> + END_DEVICE_PATH_TYPE,
> + END_ENTIRE_DEVICE_PATH_SUBTYPE,
> + {
> + END_DEVICE_PATH_LENGTH,
> + 0
> + }
> + }
> + },
> + {
> + {
> + {
> + ACPI_DEVICE_PATH,
> + ACPI_DP,
> + {
> + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> + (UINT8)(sizeof (ACPI_HID_DEVICE_PATH) >> 8)
> + }
> + },
> + EISA_PNP_ID (0x0A08), // PCI Express
> + PCI_SEG5_NUM
> + },
> +
> + {
> + END_DEVICE_PATH_TYPE,
> + END_ENTIRE_DEVICE_PATH_SUBTYPE,
> + {
> + END_DEVICE_PATH_LENGTH,
> + 0
> + }
> + }
> + }
> +};
> +
> +STATIC
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
> + L"Mem", L"I/O", L"Bus"
> +};
> +
> +#define PCI_ALLOCATION_ATTRIBUTES EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | \
> + EFI_PCI_HOST_BRIDGE_MEM64_DECODE
> +
> +#define PCI_SUPPORT_ATTRIBUTES EFI_PCI_ATTRIBUTE_ISA_IO_16 | \
> + EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | \
> + EFI_PCI_ATTRIBUTE_VGA_MEMORY | \
> + EFI_PCI_ATTRIBUTE_VGA_IO_16 | \
> + EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16
> +
> +PCI_ROOT_BRIDGE mPciRootBridges[NUM_PCIE_CONTROLLER];
> +
> +/**
> + Helper function to check PCIe link state
> +
> + @param Pcie Address of PCIe host controller.
> +
> +**/
> +STATIC
> +INTN
> +PcieLinkUp (
> + IN EFI_PHYSICAL_ADDRESS Pcie,
> + IN UINT32 Idx
> + )
> +{
> + MMIO_OPERATIONS *PcieOps;
> + UINT32 State;
> + UINT32 LtssmMask;
> +
> + LtssmMask = 0x3f;
> +
> + PcieOps = GetMmioOperations (FeaturePcdGet (PcdPciLutBigEndian));
> + State = PcieOps->Read32 ((UINTN)Pcie + PCI_LUT_BASE + PCI_LUT_DBG) & LtssmMask;
> +
> + if (State < LTSSM_PCIE_L0) {
> + DEBUG ((DEBUG_INFO,"PCIE%d : reg @ 0x%lx, no link: LTSSM=0x%02x\n",
> + Idx + 1, Pcie, State));
> + return PCI_LINK_DOWN;
> + }
> +
> + return PCI_LINK_UP;
> +}
> +
> +/**
> + Function to set-up PCIe outbound window
> +
> + @param Dbi Address of PCIe host controller.
> + @param Idx Index of iATU outbound window.
> + @param Type Type(Cfg0/Cfg1/Mem/IO) of iATU outbound window.
> + @param Phys PCIe controller phy address for outbound window.
> + @param BusAdr PCIe controller bus address for outbound window.
> + @param Size Window size
> +
> +**/
> +STATIC
> +VOID
> +PcieOutboundSet (
> + IN EFI_PHYSICAL_ADDRESS Dbi,
> + IN UINT32 Idx,
> + IN UINT32 Type,
> + IN UINT64 Phys,
> + IN UINT64 BusAddr,
> + IN UINT64 Size
> + )
> +{
> + // PCIe Layerscape : Outbound Window
> + MmioWrite32 (Dbi + IATU_VIEWPORT_OFF,
> + (UINT32)(IATU_VIEWPORT_OUTBOUND | Idx));
> +
> + MmioWrite32 (Dbi + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0,
> + (UINT32)Phys);
> +
> + MmioWrite32 (Dbi + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0,
> + (UINT32)(Phys >> 32));
> +
> + MmioWrite32 (Dbi + IATU_LIMIT_ADDR_OFF_OUTBOUND_0,
> + (UINT32)(Phys + Size - BIT0));
> +
> + MmioWrite32 (Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0,
> + (UINT32)BusAddr);
> +
> + MmioWrite32 (Dbi + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0,
> + (UINT32)(BusAddr >> 32));
> +
> + MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0,
> + (UINT32)Type);
> +
> + MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
> + IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
> +}
> +
> +/**
> + Function to set-up iATU windows for Layerscape PCIe controller
> +
> + @param Pcie Address of PCIe host controller
> + @param Cfg0Base PCIe controller phy address Type0 Configuration Space.
> + @param Cfg1Base PCIe controller phy address Type1 Configuration Space.
> + @param MemBase PCIe controller phy address Memory Space.
> + @param Mem64Base PCIe controller phy address MMIO64 Space.
> + @param IoBase PCIe controller phy address IO Space.
> +**/
> +STATIC
> +VOID
> +PcieLsSetupAtu (
> + IN EFI_PHYSICAL_ADDRESS Pcie,
> + IN EFI_PHYSICAL_ADDRESS Cfg0Base,
> + IN EFI_PHYSICAL_ADDRESS Cfg1Base,
> + IN EFI_PHYSICAL_ADDRESS MemBase,
> + IN EFI_PHYSICAL_ADDRESS Mem64Base,
> + IN EFI_PHYSICAL_ADDRESS IoBase
> + )
> +{
> + UINT64 Cfg0BaseAddr;
> + UINT64 Cfg1BaseAddr;
> + UINT64 Cfg0BusAddress;
> + UINT64 Cfg1BusAddress;
> + UINT64 Cfg0Size;
> + UINT64 Cfg1Size;
> +
> + Cfg0BaseAddr = Cfg0Base;
> + Cfg1BaseAddr = Cfg1Base;
> + Cfg0BusAddress = SEG_CFG_BUS;
> + Cfg1BusAddress = SEG_CFG_BUS;
> + Cfg0Size = SEG_CFG_SIZE;
> + Cfg1Size = SEG_CFG_SIZE;
> +
> + // iATU : OUTBOUND WINDOW 1 : CFG0
> + PcieOutboundSet (Pcie,
> + IATU_REGION_INDEX0,
> + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0,
> + Cfg0BaseAddr,
> + Cfg0BusAddress,
> + Cfg0Size);
> +
> + // iATU : OUTBOUND WINDOW 2 : CFG1
> + PcieOutboundSet (Pcie,
> + IATU_REGION_INDEX1,
> + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1,
> + Cfg1BaseAddr,
> + Cfg1BusAddress,
> + Cfg1Size);
> +
> + // iATU : OUTBOUND WINDOW 3 : MEM
> + PcieOutboundSet (Pcie,
> + IATU_REGION_INDEX2,
> + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM,
> + MemBase,
> + SEG_MEM_BUS,
> + SEG_MEM_SIZE);
> +
> + // iATU : OUTBOUND WINDOW 4 : MMIO64
> + PcieOutboundSet (Pcie,
> + IATU_REGION_INDEX3,
> + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM,
> + Mem64Base,
> + Mem64Base,
> + SIZE_4GB);
> + Mem64Base += SIZE_4GB;
> +
> + // iATU : OUTBOUND WINDOW 5 : MMIO64
> + PcieOutboundSet (Pcie,
> + IATU_REGION_INDEX4,
> + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM,
> + Mem64Base,
> + Mem64Base,
> + SIZE_4GB);
> + Mem64Base += SIZE_4GB;
> +
> + // iATU : OUTBOUND WINDOW 6 : MMIO64
> + PcieOutboundSet (Pcie,
> + IATU_REGION_INDEX5,
> + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM,
> + Mem64Base,
> + Mem64Base,
> + SIZE_4GB
> + );
> + Mem64Base += SIZE_4GB;
> +
> + // iATU : OUTBOUND WINDOW 7 : MMIO64
> + PcieOutboundSet (Pcie,
> + IATU_REGION_INDEX6,
> + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM,
> + Mem64Base,
> + Mem64Base,
> + SIZE_4GB
> + );
> +
This logic only works correctly if the window is exactly 16 GB in size.
You should at least put an ASSERT() somewhere, but even better would be
to make this code work as expected for any window size
> + // iATU : OUTBOUND WINDOW 8: IO
> + PcieOutboundSet (Pcie,
> + IATU_REGION_INDEX7,
> + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_IO,
> + IoBase,
> + SEG_IO_BUS,
> + SEG_IO_SIZE
> + );
> +}
> +/**
> + Helper function to set-up PCIe controller
> +
> + @param Pcie Address of PCIe host controller
> + @param Cfg0Base PCIe controller phy address Type0 Configuration Space.
> + @param Cfg1Base PCIe controller phy address Type1 Configuration Space.
> + @param MemBase PCIe controller phy address Memory Space.
> + @param Mem64Base PCIe controller phy address MMIO64 Space.
> + @param IoBase PCIe controller phy address IO Space.
> +
> +**/
> +STATIC
> +VOID
> +PcieSetupCntrl (
> + IN EFI_PHYSICAL_ADDRESS Pcie,
> + IN EFI_PHYSICAL_ADDRESS Cfg0Base,
> + IN EFI_PHYSICAL_ADDRESS Cfg1Base,
> + IN EFI_PHYSICAL_ADDRESS MemBase,
> + IN EFI_PHYSICAL_ADDRESS Mem64Base,
> + IN EFI_PHYSICAL_ADDRESS IoBase
> + )
> +{
> + UINT32 Val;
> +
> + // PCIe Layerscape Controller Setup
> + PcieLsSetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase);
> +
> + // Program Class code for Layerscape PCIe controller
> + MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 1);
> + Val = MmioRead32 ((UINTN)Pcie + PCI_CLASS_DEVICE);
> + Val &= ~(CLASS_CODE_MASK << CLASS_CODE_SHIFT);
> + Val |= (PCI_CLASS_BRIDGE_PCI << CLASS_CODE_SHIFT);
> + MmioWrite32 ((UINTN)Pcie + PCI_CLASS_DEVICE, Val);
> + MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 0);
> +}
> +
> +/**
> + Return all the root bridge instances in an array.
> +
> + @param Count Return the count of root bridge instances.
> +
> + @return All the root bridge instances in an array.
> +
> +**/
> +PCI_ROOT_BRIDGE *
> +EFIAPI
> +PciHostBridgeGetRootBridges (
> + OUT UINTN *Count
> + )
> +{
> + UINTN Idx;
> + UINTN Loop;
> + UINT64 PciPhyMemAddr[NUM_PCIE_CONTROLLER];
> + UINT64 PciPhyMem64Addr[NUM_PCIE_CONTROLLER];
> + UINT64 PciPhyCfg0Addr[NUM_PCIE_CONTROLLER];
> + UINT64 PciPhyCfg1Addr[NUM_PCIE_CONTROLLER];
> + UINT64 PciPhyIoAddr[NUM_PCIE_CONTROLLER];
> + UINT64 Regs[NUM_PCIE_CONTROLLER];
> + INTN LinkUp;
> +
> + for (Idx = 0, Loop = 0; Idx < NUM_PCIE_CONTROLLER; Idx++) {
> + PciPhyMemAddr[Idx] = PCI_SEG0_PHY_MEM_BASE + (PCI_BASE_DIFF * Idx);
> + PciPhyMem64Addr[Idx] = PCI_SEG0_PHY_MEM64_BASE + (PCI_BASE_DIFF * Idx);
> + PciPhyCfg0Addr[Idx] = PCI_SEG0_PHY_CFG0_BASE + (PCI_BASE_DIFF * Idx);
> + PciPhyCfg1Addr[Idx] = PCI_SEG0_PHY_CFG1_BASE + (PCI_BASE_DIFF * Idx);
> + PciPhyIoAddr [Idx] = PCI_SEG0_PHY_IO_BASE + (PCI_BASE_DIFF * Idx);
> + Regs[Idx] = PCI_SEG0_DBI_BASE + (PCI_DBI_SIZE_DIFF * Idx);
> +
> + // Check PCIe Link
> + LinkUp = PcieLinkUp(Regs[Idx], Idx);
> +
> + if (!LinkUp) {
> + continue;
> + }
> + DEBUG ((DEBUG_INFO, "PCIE%d Passed Linkup Phase\n", Idx + 1));
> + // Set up PCIe Controller and ATU windows
> + PcieSetupCntrl (Regs[Idx],
> + PciPhyCfg0Addr[Idx],
> + PciPhyCfg1Addr[Idx],
> + PciPhyMemAddr[Idx],
> + PciPhyMem64Addr[Idx],
> + PciPhyIoAddr[Idx]);
> +
> + mPciRootBridges[Loop].Segment = Idx;
> + mPciRootBridges[Loop].Supports = PCI_SUPPORT_ATTRIBUTES;
> + mPciRootBridges[Loop].Attributes = PCI_SUPPORT_ATTRIBUTES;
> + mPciRootBridges[Loop].DmaAbove4G = TRUE;
> + mPciRootBridges[Loop].NoExtendedConfigSpace = FALSE;
> + mPciRootBridges[Loop].ResourceAssigned = FALSE;
> + mPciRootBridges[Loop].AllocationAttributes = PCI_ALLOCATION_ATTRIBUTES;
> +
> + mPciRootBridges[Loop].Bus.Base = PCI_SEG_BUSNUM_MIN;
> + mPciRootBridges[Loop].Bus.Limit = PCI_SEG_BUSNUM_MAX;
> +
> + mPciRootBridges[Loop].Io.Base = PCI_SEG_PORTIO_MIN;
> + mPciRootBridges[Loop].Io.Limit = PCI_SEG_PORTIO_MAX;
> + mPciRootBridges[Loop].Io.Translation = MAX_UINT64 -
> + (SEG_IO_SIZE * Idx) + 1;
> +
> + mPciRootBridges[Loop].Mem.Base = SEG_MEM_BASE;
> + mPciRootBridges[Loop].Mem.Limit = SEG_MEM_LIMIT;
> + mPciRootBridges[Loop].Mem.Translation = MAX_UINT64 -
> + (PCI_SEG0_MMIO_MEMBASE +
> + (PCI_BASE_DIFF *
> + Idx)) + 1;
> +
> + mPciRootBridges[Loop].MemAbove4G.Base = PciPhyMem64Addr[Idx];
> + mPciRootBridges[Loop].MemAbove4G.Limit = PciPhyMem64Addr[Idx] +
> + (SIZE_16GB - 1);
> +
> + mPciRootBridges[Loop].PMem.Base = MAX_UINT64;
> + mPciRootBridges[Loop].PMem.Limit = 0;
> + mPciRootBridges[Loop].PMemAbove4G.Base = MAX_UINT64;
> + mPciRootBridges[Loop].PMemAbove4G.Limit = 0;
> + mPciRootBridges[Loop].DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[Idx];
> + Loop++;
> + }
> +
> + if (Loop == 0) {
> + return NULL;
> + }
> +
> + *Count = Loop;
> + return mPciRootBridges;
> +}
> +
> +/**
> + Free the root bridge instances array returned from PciHostBridgeGetRootBridges().
> +
> + @param Bridges The root bridge instances array.
> + @param Count The count of the array.
> +**/
> +VOID
> +EFIAPI
> +PciHostBridgeFreeRootBridges (
> + PCI_ROOT_BRIDGE *Bridges,
> + UINTN Count
> + )
> +{
> +}
> +
> +/**
> + Inform the platform that the resource conflict happens.
> +
> + @param HostBridgeHandle Handle of the Host Bridge.
> + @param Configuration Pointer to PCI I/O and PCI memory resource
> + descriptors. The Configuration contains the resources
> + for all the root bridges. The resource for each root
> + bridge is terminated with END descriptor and an
> + additional END is appended indicating the end of the
> + entire resources. The resource descriptor field
> + values follow the description in
> + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
> + .SubmitResources().
> +
> +**/
> +VOID
> +EFIAPI
> +PciHostBridgeResourceConflict (
> + EFI_HANDLE HostBridgeHandle,
> + VOID *Configuration
> + )
> +{
> + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
> + UINTN RootBridgeIndex;
I know this is copy/paste from elsewhere but please insert a newline here
> + DEBUG ((DEBUG_ERROR, "PciHostBridge: Resource conflict happens!\n"));
> +
> + RootBridgeIndex = 0;
> + Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
> + while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
> + DEBUG ((DEBUG_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
> + for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
> + ASSERT (Descriptor->ResType <
> + ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr));
> + DEBUG ((DEBUG_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n",
> + mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
> + Descriptor->AddrLen, Descriptor->AddrRangeMax
> + ));
> + if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
> + DEBUG ((DEBUG_ERROR, " Granularity/SpecificFlag = %ld / %02x%s\n",
> + Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag,
> + ((Descriptor->SpecificFlag &
> + EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
> + ) != 0) ? L" (Prefetchable)" : L""
> + ));
> + }
> + }
> + //
> + // Skip the END descriptor for root bridge
> + //
> + ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
> + Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(
> + (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
> + );
> + }
> +
> + return;
> +}
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 04/16] Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS Ctrl
2020-05-21 23:02 ` [PATCH edk2-platforms 04/16] Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS Ctrl Wasim Khan
@ 2020-05-22 9:22 ` Ard Biesheuvel
0 siblings, 0 replies; 42+ messages in thread
From: Ard Biesheuvel @ 2020-05-22 9:22 UTC (permalink / raw)
To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
leif, jon
Cc: Wasim Khan
On 5/22/20 1:02 AM, Wasim Khan wrote:
> From: Wasim Khan <wasim.khan@nxp.com>
>
> PCIe layerscape controller supports CFG Shift feature. It can be
> enabled by setting BIT[28] of iATU Control 2 Register.
> Check PcdPciCfgShiftEnable to enable 'CFG Shift feature' in
> PCIe controller.
> if enable, PCIe layerscape controller shifts BDF from bits[27:12] to
> bits[31:16] and supports Enhanced Configuration Address Mapping (ECAM)
> mechanism.
>
> PCIe layerscape controller is ECAM complaint for bus[0x1-0xff].
> So create outbound CFG windows from 1MB-256MB (255 buses) for
> type0/type1 configuration access.
> PCIe layerscape controller is Non-ECAM complaint for bus 0.It does
> not support device > 0 on bus 0. PciSegmentLib should handles this
> limitation.
>
> Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
> Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> ---
> Silicon/NXP/NxpQoriqLs.dec | 3 ++
> .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 3 ++
> Silicon/NXP/Include/Pcie.h | 3 ++
> .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 35 +++++++++++++++++-----
> 4 files changed, 36 insertions(+), 8 deletions(-)
>
> diff --git a/Silicon/NXP/NxpQoriqLs.dec b/Silicon/NXP/NxpQoriqLs.dec
> index bafdfd9f4298..293fd773fd3d 100644
> --- a/Silicon/NXP/NxpQoriqLs.dec
> +++ b/Silicon/NXP/NxpQoriqLs.dec
> @@ -36,3 +36,6 @@ [PcdsFixedAtBuild.common]
> gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase|0x0|UINT32|0x00000502
> gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg|0x0|UINT32|0x00000503
> gNxpQoriqLsTokenSpaceGuid.PcdPciDebug|FALSE|BOOLEAN|0x00000504
> +
> +[PcdsDynamic.common]
> + gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable|FALSE|BOOLEAN|0x00000600
> diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> index 5ddb96e4fa6a..98cfb6aee6b0 100644
> --- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> +++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> @@ -38,3 +38,6 @@ [FixedPcd]
> gNxpQoriqLsTokenSpaceGuid.PcdNumPciController
> gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase
> gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg
> +
> +[Pcd]
> + gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
> diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h
> index d5b5a3884e0a..ae85190180e8 100755
> --- a/Silicon/NXP/Include/Pcie.h
> +++ b/Silicon/NXP/Include/Pcie.h
> @@ -63,6 +63,7 @@
> #define IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0 0x91C
> #define IATU_VIEWPORT_OUTBOUND 0x0
> #define IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN BIT31
> +#define IATU_ENABLE_CFG_SHIFT_FEATURE BIT28
>
> // ATU Programming
> #define IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM 0x0
> @@ -82,4 +83,6 @@
> #define SEG_IO_SIZE 0x10000
> #define SEG_IO_BUS 0x0
>
> +#define CFG_SHIFT_ENABLE (PcdGetBool (PcdPciCfgShiftEnable))
> +
> #endif
> diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> index cf872370c7cd..f92863c60868 100644
> --- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> +++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> @@ -259,8 +259,17 @@ PcieOutboundSet (
> MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0,
> (UINT32)Type);
>
> - MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
> - IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
> + if (CFG_SHIFT_ENABLE &&
> + ((Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0) ||
> + (Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1))) {
> + MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
> + (IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN |
> + IATU_ENABLE_CFG_SHIFT_FEATURE)
> + );
> + } else {
> + MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
> + IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
> + }
> }
>
> /**
> @@ -291,12 +300,22 @@ PcieLsSetupAtu (
> UINT64 Cfg0Size;
> UINT64 Cfg1Size;
>
> - Cfg0BaseAddr = Cfg0Base;
> - Cfg1BaseAddr = Cfg1Base;
> - Cfg0BusAddress = SEG_CFG_BUS;
> - Cfg1BusAddress = SEG_CFG_BUS;
> - Cfg0Size = SEG_CFG_SIZE;
> - Cfg1Size = SEG_CFG_SIZE;
> + if (CFG_SHIFT_ENABLE) {
> + DEBUG ((DEBUG_INFO, "PCIe: CFG Shit Method Enabled \n"));
Please add the missing 'f'
> + Cfg0BaseAddr = Cfg0Base + SIZE_1MB;
> + Cfg1BaseAddr = Cfg0Base + SIZE_2MB;
> + Cfg0BusAddress = SIZE_1MB;
> + Cfg1BusAddress = SIZE_2MB;
> + Cfg0Size = SIZE_1MB;
> + Cfg1Size = (SIZE_256MB - SIZE_1MB); // 255MB
This logic would be much more self-explanatory if you used a symbolic
constant 'ECAM_BUS_SIZE' instead of SIZE_1MB (and add a comment that
type 0 CFG TLPs only go to bus #1)
> + } else {
> + Cfg0BaseAddr = Cfg0Base;
> + Cfg1BaseAddr = Cfg1Base;
> + Cfg0BusAddress = SEG_CFG_BUS;
> + Cfg1BusAddress = SEG_CFG_BUS;
> + Cfg0Size = SEG_CFG_SIZE;
> + Cfg1Size = SEG_CFG_SIZE;
> + }
>
> // iATU : OUTBOUND WINDOW 1 : CFG0
> PcieOutboundSet (Pcie,
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 05/16] Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU Windows
2020-05-21 23:02 ` [PATCH edk2-platforms 05/16] Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU Windows Wasim Khan
@ 2020-05-22 9:24 ` Ard Biesheuvel
2020-05-24 18:31 ` Wasim Khan (OSS)
0 siblings, 1 reply; 42+ messages in thread
From: Ard Biesheuvel @ 2020-05-22 9:24 UTC (permalink / raw)
To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
leif, jon
Cc: Wasim Khan
On 5/22/20 1:02 AM, Wasim Khan wrote:
> From: Wasim Khan <wasim.khan@nxp.com>
>
> Setup PCIe LayerscapeGen4 controller and setup CFG, IO,
> MMIO and MMIO64 iATU windows.
> Check for PcdPciLsGen4Ctrl to enable LsGen4 PCIe
> controller.
>
> Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
> Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
How much overlap is there between these controllers? Does it really make
sense to use the same PciHostBridgeLib implementation and parameterize
the hell out of it?
> ---
> Silicon/NXP/NxpQoriqLs.dec | 1 +
> .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 1 +
> Silicon/NXP/Include/Pcie.h | 120 ++++++++++
> .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 255 +++++++++++++++++----
> 4 files changed, 336 insertions(+), 41 deletions(-)
>
> diff --git a/Silicon/NXP/NxpQoriqLs.dec b/Silicon/NXP/NxpQoriqLs.dec
> index 293fd773fd3d..8271d19ed8e5 100644
> --- a/Silicon/NXP/NxpQoriqLs.dec
> +++ b/Silicon/NXP/NxpQoriqLs.dec
> @@ -39,3 +39,4 @@ [PcdsFixedAtBuild.common]
>
> [PcdsDynamic.common]
> gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable|FALSE|BOOLEAN|0x00000600
> + gNxpQoriqLsTokenSpaceGuid.PcdPciLsGen4Ctrl|FALSE|BOOLEAN|0x00000601
> diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> index 98cfb6aee6b0..b777acdc103f 100644
> --- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> +++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> @@ -41,3 +41,4 @@ [FixedPcd]
>
> [Pcd]
> gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
> + gNxpQoriqLsTokenSpaceGuid.PcdPciLsGen4Ctrl
> diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h
> index ae85190180e8..4c41c3585a8b 100755
> --- a/Silicon/NXP/Include/Pcie.h
> +++ b/Silicon/NXP/Include/Pcie.h
> @@ -84,5 +84,125 @@
> #define SEG_IO_BUS 0x0
>
> #define CFG_SHIFT_ENABLE (PcdGetBool (PcdPciCfgShiftEnable))
> +#define PCI_LS_GEN4_CTRL (PcdGetBool (PcdPciLsGen4Ctrl))
>
> +// PCIe Layerscape Gen4 Controller
> +#define GPEX_CLASSCODE 0x474
> +#define GPEX_CLASSCODE_SHIFT 16
> +#define GPEX_CLASSCODE_MASK 0xffff
> +#define PAB_AXI_PIO_CTRL(Idx) (0x840 + 0x10 * Idx)
> +#define APIO_EN 0x1
> +#define MEM_WIN_EN 0x1 << 1
> +#define IO_WIN_EN 0x1 << 2
> +#define CFG_WIN_EN 0x1 << 3
> +#define PAB_PEX_PIO_CTRL(Idx) (0x8c0 + 0x10 * Idx)
> +#define PPIO_EN (0x1 << 0)
> +#define PAB_PEX_PIO_STAT(Idx) (0x8c4 + 0x10 * Idx)
> +#define PAB_PEX_PIO_MT_STAT(Idx) (0x8c8 + 0x10 * Idx)
> +#define PEX_AMAP_CTRL_TYPE_SHIFT 0x1
> +#define PEX_AMAP_CTRL_EN_SHIFT 0x0
> +#define PEX_AMAP_CTRL_TYPE_MASK 0x3
> +#define PEX_AMAP_CTRL_EN_MASK 0x1
> +#define PAB_PEX_AMAP_CTRL(Idx) (0x4ba0 + 0x10 * Idx)
> +#define PAB_EXT_PEX_AMAP_SIZE(Idx) (0xbef0 + 0x04 * Idx)
> +#define PAB_PEX_AMAP_AXI_WIN(Idx) (0x4ba4 + 0x10 * Idx)
> +#define PAB_EXT_PEX_AMAP_AXI_WIN(Idx) (0xb4a0 + 0x04 * Idx)
> +#define PAB_PEX_AMAP_PEX_WIN_L(Idx) (0x4ba8 + 0x10 * Idx)
> +#define PAB_PEX_AMAP_PEX_WIN_H(Idx) (0x4bac + 0x10 * Idx)
> +#define PAB_CTRL 0x808
> +#define PAB_CTRL_APIO_EN 0x1
> +#define PAB_CTRL_PPIO_EN (0x1 << 1)
> +#define PAB_CTRL_PAGE_SEL_SHIFT 13
> +#define PAB_CTRL_PAGE_SEL_MASK 0x3f
> +#define INDIRECT_ADDR_BNDRY 0xc00
> +#define PAGE_IDX_SHIFT 10
> +#define PAGE_ADDR_MASK 0x3ff
> +#define PAB_AXI_AMAP_CTRL(Idx) (0xba0 + 0x10 * Idx)
> +#define PAB_EXT_AXI_AMAP_SIZE(Idx) (0xbaf0 + 0x4 * Idx)
> +#define PAB_AXI_AMAP_AXI_WIN(Idx) (0xba4 + 0x10 * Idx)
> +#define PAB_EXT_AXI_AMAP_AXI_WIN(Idx) (0x80a0 + 0x4 * Idx)
> +#define PAB_AXI_AMAP_PEX_WIN_L(Idx) (0xba8 + 0x10 * Idx)
> +#define PAB_AXI_AMAP_PEX_WIN_H(Idx) (0xbac + 0x10 * Idx)
> +#define PAB_AXI_TYPE_CFG 0x00
> +#define PAB_AXI_TYPE_IO 0x01
> +#define PAB_AXI_TYPE_MEM 0x02
> +#define AXI_AMAP_CTRL_EN 0x1
> +#define AXI_AMAP_CTRL_TYPE_SHIFT 1
> +#define AXI_AMAP_CTRL_TYPE_MASK 0x3
> +#define AXI_AMAP_CTRL_SIZE_SHIFT 10
> +#define AXI_AMAP_CTRL_SIZE_MASK 0x3fffff
> +
> +
> +#define OFFSET_TO_PAGE_IDX(Off) ((Off >> PAGE_IDX_SHIFT) \
> + & PAB_CTRL_PAGE_SEL_MASK)
> +
> +#define OFFSET_TO_PAGE_ADDR(Off) ((Off & PAGE_ADDR_MASK) \
> + | INDIRECT_ADDR_BNDRY)
> +/**
> + Function to set page for LsGen4 Ctrl
> +
> + @param Dbi GPEX host controller address.
> + @param PgIdx The page index to select
> +
> +**/
> +STATIC inline VOID PciLsGen4SetPg (
> + IN EFI_PHYSICAL_ADDRESS Dbi,
> + IN UINT8 PgIdx
> + )
> +{
> + UINT32 Val;
> + Val = MmioRead32 (Dbi + PAB_CTRL);
> + Val &= ~(PAB_CTRL_PAGE_SEL_MASK << PAB_CTRL_PAGE_SEL_SHIFT);
> + Val |= (PgIdx & PAB_CTRL_PAGE_SEL_MASK) << PAB_CTRL_PAGE_SEL_SHIFT;
> + MmioWrite32 (Dbi + PAB_CTRL, Val);
> +}
> +
> +/**
> + Function to read LsGen4 PCIe controller config space
> + LsGen4 PCIe controller requires page number to be set
> + in Bridge Control Register(PAB) for offset > 3KB.
> +
> + @param Dbi GPEX host controller address.
> + @param Offset Offset to read from
> +
> +**/
> +STATIC inline INTN PciLsGen4Read32 (
> + IN EFI_PHYSICAL_ADDRESS Dbi,
> + IN UINT32 Offset
> + )
> +{
> + if (Offset < INDIRECT_ADDR_BNDRY) {
> + PciLsGen4SetPg (Dbi, 0);
> + return MmioRead32 (Dbi + Offset);
> + } else {
> + // If Offset > 3KB, paging mechanism is used
> + // Select page index and offset within the page
> + PciLsGen4SetPg (Dbi, OFFSET_TO_PAGE_IDX (Offset));
> + return MmioRead32 (Dbi + OFFSET_TO_PAGE_ADDR (Offset));
> + }
> +}
> +
> +/**
> + Function to write to LsGen4 PCIe controller config space
> + LsGen4 PCIe controller requires page number to be set
> + in Bridge Control Register(PAB) for offset > 3KB.
> +
> + @param Dbi GPEX host controller address
> + @param Offset Offset to read from
> +
> +**/
> +STATIC inline VOID PciLsGen4Write32 (
> + IN EFI_PHYSICAL_ADDRESS Dbi,
> + IN UINT32 Offset,
> + IN UINT32 Value
> + )
> +{
> + if (Offset < INDIRECT_ADDR_BNDRY) {
> + PciLsGen4SetPg (Dbi, 0);
> + MmioWrite32 (Dbi + Offset, Value);
> + } else {
> + PciLsGen4SetPg (Dbi, OFFSET_TO_PAGE_IDX (Offset));
> + MmioWrite32 (Dbi + OFFSET_TO_PAGE_ADDR (Offset), Value);
> + }
> +}
> #endif
> diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> index f92863c60868..d9944313da21 100644
> --- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> +++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> @@ -201,7 +201,11 @@ PcieLinkUp (
> UINT32 State;
> UINT32 LtssmMask;
>
> - LtssmMask = 0x3f;
> + if (PCI_LS_GEN4_CTRL) {
> + LtssmMask = 0x7f;
> + } else {
> + LtssmMask = 0x3f;
> + }
>
> PcieOps = GetMmioOperations (FeaturePcdGet (PcdPciLutBigEndian));
> State = PcieOps->Read32 ((UINTN)Pcie + PCI_LUT_BASE + PCI_LUT_DBG) & LtssmMask;
> @@ -237,38 +241,58 @@ PcieOutboundSet (
> IN UINT64 Size
> )
> {
> - // PCIe Layerscape : Outbound Window
> - MmioWrite32 (Dbi + IATU_VIEWPORT_OFF,
> - (UINT32)(IATU_VIEWPORT_OUTBOUND | Idx));
> + UINT32 Val;
>
> - MmioWrite32 (Dbi + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0,
> - (UINT32)Phys);
> -
> - MmioWrite32 (Dbi + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0,
> - (UINT32)(Phys >> 32));
> -
> - MmioWrite32 (Dbi + IATU_LIMIT_ADDR_OFF_OUTBOUND_0,
> - (UINT32)(Phys + Size - BIT0));
> -
> - MmioWrite32 (Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0,
> - (UINT32)BusAddr);
> -
> - MmioWrite32 (Dbi + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0,
> - (UINT32)(BusAddr >> 32));
> -
> - MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0,
> - (UINT32)Type);
> -
> - if (CFG_SHIFT_ENABLE &&
> - ((Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0) ||
> - (Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1))) {
> - MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
> - (IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN |
> - IATU_ENABLE_CFG_SHIFT_FEATURE)
> - );
> + if (PCI_LS_GEN4_CTRL) {
> + // PCIe Layerscape Gen4: Outbound Window
> + Size = ~(Size -1 );
> + Val = PciLsGen4Read32 ((UINTN)Dbi, PAB_AXI_AMAP_CTRL (Idx));
> + Val &= ~((AXI_AMAP_CTRL_TYPE_MASK << AXI_AMAP_CTRL_TYPE_SHIFT) |
> + (AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT) |
> + AXI_AMAP_CTRL_EN);
> + Val |= ((Type & AXI_AMAP_CTRL_TYPE_MASK) << AXI_AMAP_CTRL_TYPE_SHIFT) |
> + (((UINT32)Size >> AXI_AMAP_CTRL_SIZE_SHIFT) <<
> + AXI_AMAP_CTRL_SIZE_SHIFT) | AXI_AMAP_CTRL_EN;
> + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_CTRL (Idx), Val);
> + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_AXI_WIN (Idx), (UINT32)Phys);
> + PciLsGen4Write32 ((UINTN)Dbi, PAB_EXT_AXI_AMAP_AXI_WIN (Idx), Phys >> 32);
> + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_L (Idx), (UINT32)BusAddr);
> + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_H (Idx), BusAddr >> 32);
> + PciLsGen4Write32 ((UINTN)Dbi, PAB_EXT_AXI_AMAP_SIZE (Idx), Size >> 32);
> } else {
> - MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
> - IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
> + // PCIe Layerscape : Outbound Window
> + MmioWrite32 (Dbi + IATU_VIEWPORT_OFF,
> + (UINT32)(IATU_VIEWPORT_OUTBOUND | Idx));
> +
> + MmioWrite32 (Dbi + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0,
> + (UINT32)Phys);
> +
> + MmioWrite32 (Dbi + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0,
> + (UINT32)(Phys >> 32));
> +
> + MmioWrite32 (Dbi + IATU_LIMIT_ADDR_OFF_OUTBOUND_0,
> + (UINT32)(Phys + Size - BIT0));
> +
> + MmioWrite32 (Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0,
> + (UINT32)BusAddr);
> +
> + MmioWrite32 (Dbi + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0,
> + (UINT32)(BusAddr >> 32));
> +
> + MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0,
> + (UINT32)Type);
> +
> + if (CFG_SHIFT_ENABLE &&
> + ((Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0) ||
> + (Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1))) {
> + MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
> + (IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN |
> + IATU_ENABLE_CFG_SHIFT_FEATURE)
> + );
> + } else {
> + MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
> + IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
> + }
> }
> }
>
> @@ -387,6 +411,124 @@ PcieLsSetupAtu (
> SEG_IO_SIZE
> );
> }
> +
> +/**
> + Function to set-up ATU windows for PCIe LayerscapeGen4 controller
> +
> + @param Pcie Address of PCIe host controller
> + @param Cfg0Base PCIe controller phy address Type0 Configuration Space.
> + @param Cfg1Base PCIe controller phy address Type1 Configuration Space.
> + @param MemBase PCIe controller phy address Memory Space.
> + @param Mem64Base PCIe controller phy address MMIO64 Space.
> + @param IoBase PCIe controller phy address IO Space.
> +**/
> +STATIC
> +VOID
> +PcieLsGen4SetupAtu (
> + IN EFI_PHYSICAL_ADDRESS Pcie,
> + IN EFI_PHYSICAL_ADDRESS Cfg0Base,
> + IN EFI_PHYSICAL_ADDRESS Cfg1Base,
> + IN EFI_PHYSICAL_ADDRESS MemBase,
> + IN EFI_PHYSICAL_ADDRESS Mem64Base,
> + IN EFI_PHYSICAL_ADDRESS IoBase
> + )
> +{
> + // ATU : OUTBOUND WINDOW 1 : CFG0
> + PcieOutboundSet (Pcie, IATU_REGION_INDEX0,
> + PAB_AXI_TYPE_CFG,
> + Cfg0Base,
> + SEG_CFG_BUS,
> + SEG_CFG_SIZE);
> +
> + // ATU : OUTBOUND WINDOW 2 : IO
> + PcieOutboundSet (Pcie, IATU_REGION_INDEX1,
> + PAB_AXI_TYPE_IO,
> + IoBase,
> + SEG_IO_BUS,
> + SEG_IO_SIZE);
> +
> + // ATU : OUTBOUND WINDOW 3 : MEM
> + PcieOutboundSet (Pcie, IATU_REGION_INDEX2,
> + PAB_AXI_TYPE_MEM,
> + MemBase,
> + SEG_MEM_BUS,
> + SEG_MEM_SIZE);
> +
> + // ATU : OUTBOUND WINDOW 4 : MMIO64
> + PcieOutboundSet (Pcie, IATU_REGION_INDEX3,
> + PAB_AXI_TYPE_MEM,
> + Mem64Base,
> + Mem64Base,
> + SIZE_4GB);
> + Mem64Base += SIZE_4GB;
> +
> + // ATU : OUTBOUND WINDOW 5 : MMIO64
> + PcieOutboundSet (Pcie, IATU_REGION_INDEX4,
> + PAB_AXI_TYPE_MEM,
> + Mem64Base,
> + Mem64Base,
> + SIZE_4GB);
> + Mem64Base += SIZE_4GB;
> +
> + // ATU : OUTBOUND WINDOW 6 : MMIO64
> + PcieOutboundSet (Pcie, IATU_REGION_INDEX5,
> + PAB_AXI_TYPE_MEM,
> + Mem64Base,
> + Mem64Base,
> + SIZE_4GB);
> + Mem64Base += SIZE_4GB;
> +
> + // ATU : OUTBOUND WINDOW 7 : MMIO64
> + PcieOutboundSet (Pcie, IATU_REGION_INDEX6,
> + PAB_AXI_TYPE_MEM,
> + Mem64Base,
> + Mem64Base,
> + SIZE_4GB);
> +}
> +
> +/**
> + Function to set-up PCIe inbound window
> +
> + @param Pcie Address of PCIe host controller.
> + @param Idx Index of inbound window.
> + @param Type Type(Cfg/Mem/IO) of iATU outbound window.
> + @param Phys PCIe controller phy address for inbound window.
> + @param BusAdr PCIe controller bus address for inbound window.
> + @param Size Window size
> +
> +**/
> +
> +STATIC
> +VOID
> +PciSetupInBoundWin (
> + IN EFI_PHYSICAL_ADDRESS Pcie,
> + IN UINT32 Idx,
> + IN UINT32 Type,
> + IN UINT64 Phys,
> + IN UINT64 BusAddr,
> + IN UINT64 Size)
> +{
> + UINT32 Val;
> + UINT64 WinSize;
> +
> + if (PCI_LS_GEN4_CTRL) {
> + Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_PEX_AMAP_CTRL(Idx));
> + Val &= ~(PEX_AMAP_CTRL_TYPE_MASK << PEX_AMAP_CTRL_TYPE_SHIFT);
> + Val &= ~(PEX_AMAP_CTRL_EN_MASK << PEX_AMAP_CTRL_EN_SHIFT);
> + Val = (Val | (Type << PEX_AMAP_CTRL_TYPE_SHIFT));
> + Val = (Val | (1 << PEX_AMAP_CTRL_EN_SHIFT));
> +
> + WinSize = ~(Size - 1);
> + PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_CTRL(Idx),
> + (Val | (UINT32)WinSize));
> + PciLsGen4Write32 ((UINTN)Pcie, PAB_EXT_PEX_AMAP_SIZE(Idx), (WinSize>>32));
> + PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_AXI_WIN(Idx), (UINT32)Phys);
> + PciLsGen4Write32 ((UINTN)Pcie, PAB_EXT_PEX_AMAP_AXI_WIN(Idx), (Phys>>32));
> + PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_PEX_WIN_L(Idx), (UINT32)BusAddr);
> + PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_PEX_WIN_H(Idx), (BusAddr >>32));
> + }
> +}
> +
> /**
> Helper function to set-up PCIe controller
>
> @@ -411,16 +553,47 @@ PcieSetupCntrl (
> {
> UINT32 Val;
>
> - // PCIe Layerscape Controller Setup
> - PcieLsSetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase);
> -
> - // Program Class code for Layerscape PCIe controller
> - MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 1);
> - Val = MmioRead32 ((UINTN)Pcie + PCI_CLASS_DEVICE);
> - Val &= ~(CLASS_CODE_MASK << CLASS_CODE_SHIFT);
> - Val |= (PCI_CLASS_BRIDGE_PCI << CLASS_CODE_SHIFT);
> - MmioWrite32 ((UINTN)Pcie + PCI_CLASS_DEVICE, Val);
> - MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 0);
> + if (PCI_LS_GEN4_CTRL) {
> + // PCIe LsGen4 Controller Setup
> +
> + //Fix Class Code
> + Val = PciLsGen4Read32 ((UINTN)Pcie, GPEX_CLASSCODE);
> + Val &= ~(GPEX_CLASSCODE_MASK << GPEX_CLASSCODE_SHIFT);
> + Val |= PCI_CLASS_BRIDGE_PCI << GPEX_CLASSCODE_SHIFT;
> + PciLsGen4Write32 ((UINTN)Pcie, GPEX_CLASSCODE, Val);
> +
> + // Enable APIO and Memory/IO/CFG Windows
> + Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_PIO_CTRL (0));
> + Val |= APIO_EN | MEM_WIN_EN | IO_WIN_EN | CFG_WIN_EN;
> + PciLsGen4Write32 ((UINTN)Pcie, PAB_AXI_PIO_CTRL (0), Val);
> +
> + // LsGen4 Inbound Window Setup
> + PciSetupInBoundWin (Pcie, 0, PAB_AXI_TYPE_MEM, 0 , 0, SIZE_1TB);
> +
> + // LsGen4 Outbound Window Setup
> + PcieLsGen4SetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase);
> +
> + // Enable AMBA & PEX PIO
> + Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_CTRL);
> + Val |= PAB_CTRL_APIO_EN | PAB_CTRL_PPIO_EN;
> + PciLsGen4Write32 ((UINTN)Pcie, PAB_CTRL, Val);
> +
> + Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_PEX_PIO_CTRL(0));
> + Val |= PPIO_EN;
> + PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_PIO_CTRL(0), Val);
> +
> + } else {
> + // PCIe Layerscape Controller Setup
> + PcieLsSetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase);
> +
> + // Program Class code for Layerscape PCIe controller
> + MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 1);
> + Val = MmioRead32 ((UINTN)Pcie + PCI_CLASS_DEVICE);
> + Val &= ~(CLASS_CODE_MASK << CLASS_CODE_SHIFT);
> + Val |= (PCI_CLASS_BRIDGE_PCI << CLASS_CODE_SHIFT);
> + MmioWrite32 ((UINTN)Pcie + PCI_CLASS_DEVICE, Val);
> + MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 0);
> + }
> }
>
> /**
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 09/16] Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller
2020-05-21 23:02 ` [PATCH edk2-platforms 09/16] Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller Wasim Khan
@ 2020-05-22 9:29 ` Ard Biesheuvel
2020-05-24 18:32 ` Wasim Khan (OSS)
0 siblings, 1 reply; 42+ messages in thread
From: Ard Biesheuvel @ 2020-05-22 9:29 UTC (permalink / raw)
To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
leif, jon
Cc: Wasim Khan
On 5/22/20 1:02 AM, Wasim Khan wrote:
> From: Wasim Khan <wasim.khan@nxp.com>
>
> We have different PCI config space region for bus 0 (Controller space) and
> bus[0x1-0xff] on NXP SoCs with PCIe LS controller.
> Add PciSegmentLib for PCIe LS controller.
>
> For config transactions for Bus0:
> - Config transaction address = PCIe controller address + offset
>
> For config transactions for Bus[0x1-0xff]:
> - PCIe IP requires target BDF to be written at bit[31:16] of PCIe
> type0/type1 outbound window.
> - Config transaction address = PCIe config space address + offset
>
> Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
> Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> ---
> .../NXP/Library/PciSegmentLib/PciSegmentLib.inf | 32 ++
> Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 612 +++++++++++++++++++++
> 2 files changed, 644 insertions(+)
> create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
>
> diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> new file mode 100755
> index 000000000000..a36e79239b33
> --- /dev/null
> +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> @@ -0,0 +1,32 @@
> +## @file
> +# PCI Segment Library for NXP SoCs with multiple RCs
> +#
> +# Copyright 2018-2020 NXP
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x0001001A
> + BASE_NAME = PciSegmentLib
> + FILE_GUID = c9f59261-5a60-4a4c-82f6-1f520442e100
> + MODULE_TYPE = DXE_DRIVER
Can this be BASE ?
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = PciSegmentLib|DXE_DRIVER
> + CONSTRUCTOR = PciSegLibInit
> +
> +[Sources]
> + PciSegmentLib.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + Silicon/NXP/NxpQoriqLs.dec
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + IoLib
> + PcdLib
> +
> +[FixedPcd]
> + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
> diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> new file mode 100755
> index 000000000000..ecd36971b753
> --- /dev/null
> +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> @@ -0,0 +1,612 @@
> +/** @file
> + PCI Segment Library for NXP SoCs with multiple RCs
> +
> + Copyright 2018-2020 NXP
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +#include <PiDxe.h>
> +#include <Base.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Pcie.h>
> +
> +typedef enum {
> + PciCfgWidthUint8 = 0,
> + PciCfgWidthUint16,
> + PciCfgWidthUint32,
> + PciCfgWidthMax
> +} PCI_CFG_WIDTH;
> +
> +/**
> + Assert the validity of a PCI Segment address.
> + A valid PCI Segment address should not contain 1's in bits 28..31 and 48..63
> +
> + @param A The address to validate.
> + @param M Additional bits to assert to be zero.
> +
> +**/
> +#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
> + ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
> +
> +STATIC
> +UINT64
> +PciLsCfgTarget (
> + IN EFI_PHYSICAL_ADDRESS Dbi,
> + IN UINT64 Address,
> + IN UINT16 Segment,
> + IN UINT8 Bus,
> + IN UINT16 Offset
> + )
> +{
> + UINT32 Target;
> +
> + Target = ((((Address >> 20) & 0xFF) << 24) |
> + (((Address >> 15) & 0x1F) << 19) |
> + (((Address >> 12) & 0x7) << 16));
You can drop the outer () here
> +
> + if (Bus > 1) {
> + MmioWrite32 ((UINTN)Dbi + IATU_VIEWPORT_OFF, IATU_VIEWPORT_OUTBOUND | IATU_REGION_INDEX1);
> + } else {
> + MmioWrite32 ((UINTN)Dbi + IATU_VIEWPORT_OFF, IATU_VIEWPORT_OUTBOUND | IATU_REGION_INDEX0);
> + }
> +
> + MmioWrite32 ((UINTN)Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0, Target);
> +
> + if (Bus > 1) {
> + return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment + SEG_CFG_SIZE + Offset;
> + } else {
> + return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment + Offset;
> + }
OK, so this is the version for the IP that does not implement ECAM
shift, right?
> +}
> +
> +/**
> + Function to return PCIe Physical Address(PCIe view) or Controller
> + Address(CPU view) for different RCs
> +
> + @param Address Address passed from bus layer.
> + @param Segment Segment number for Root Complex.
> + @param Offset Config space register offset.
> + @param Bus PCIe Bus number.
> +
> + @return Return PCIe CPU or Controller address.
> +
> +**/
> +STATIC
> +UINT64
> +PciLsGetConfigBase (
> + IN UINT64 Address,
> + IN UINT16 Segment,
> + IN UINT16 Offset,
> + IN UINT8 Bus
> + )
> +{
> + UINT32 CfgAddr;
> +
> + CfgAddr = (UINT16)Offset;
> + if (Bus) {
Please use Bus > 0 here
> + return PciLsCfgTarget (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment, Address, Segment, Bus, Offset);
> + } else {
> + return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
> + }
> +}
> +
> +/**
> + Function to return PCIe Physical Address(PCIe view) or Controller
> + Address(CPU view) for different RCs
> +
> + @param Address Address passed from bus layer.
> + @param Segment Segment number for Root Complex.
> + @param Offset Config space register offset.
> +
> + @return Return PCIe CPU or Controller address.
> +
> +**/
> +STATIC
> +UINT64
> +PciSegmentLibGetConfigBase (
> + IN UINT64 Address,
> + IN UINT16 Segment,
> + IN UINT16 Offset
> + )
> +{
> + UINT8 Bus;
> +
> + Bus = ((UINT32)Address >> 20) & 0xff;
> + return PciLsGetConfigBase (Address, Segment, Offset, Bus);
> +}
> +
> +/**
> + Internal worker function to read a PCI configuration register.
> +
> + @param Address The address that encodes the Segment, PCI Bus, Device,
> + Function and Register.
> + @param Width The width of data to read
> +
> + @return The value read from the PCI configuration register.
> +
> +**/
> +STATIC
> +UINT32
> +PciSegmentLibReadWorker (
> + IN UINT64 Address,
> + IN PCI_CFG_WIDTH Width
> + )
> +{
> + UINT64 Base;
> + UINT16 Offset;
> + UINT16 Segment;
> +
> + Segment = (Address >> 32);
> + Offset = (Address & 0xfff );
> +
> + Base = PciSegmentLibGetConfigBase (Address, Segment, Offset);
> +
> + // ignore devices > 0 on bus 0
> + if ((Address & 0xff00000) == 0 && (Address & 0xf8000) != 0) {
> + return MAX_UINT32;
> + }
> +
> + // ignore device > 0 on bus 1
> + if ((Address & 0xfe00000) == 0 && (Address & 0xf8000) != 0) {
> + return MAX_UINT32;
> + }
> +
> + switch (Width) {
> + case PciCfgWidthUint8:
> + return MmioRead8 (Base);
> + case PciCfgWidthUint16:
> + return MmioRead16 (Base);
> + case PciCfgWidthUint32:
> + return MmioRead32 (Base);
> + default:
> + ASSERT (FALSE);
> + }
> +
> + return CHAR_NULL;
> +}
> +
> +/**
> + Internal worker function to writes a PCI configuration register.
> +
> + @param Address The address that encodes the Segment, PCI Bus, Device,
> + Function and Register.
> + @param Width The width of data to write
> + @param Data The value to write.
> +
> + @return The value written to the PCI configuration register.
> +
> +**/
> +STATIC
> +UINT32
> +PciSegmentLibWriteWorker (
> + IN UINT64 Address,
> + IN PCI_CFG_WIDTH Width,
> + IN UINT32 Data
> + )
> +{
> + UINT64 Base;
> + UINT32 Offset;
> + UINT16 Segment;
> +
> + Segment = (Address >> 32);
> + Offset = (Address & 0xfff );
> +
> + Base = PciSegmentLibGetConfigBase (Address, Segment, Offset);
> +
> + // ignore devices > 0 on bus 0
> + if ((Address & 0xff00000) == 0 && (Address & 0xf8000) != 0) {
> + return Data;
> + }
> +
> + // ignore device > 0 on bus 1
> + if ((Address & 0xfe00000) == 0 && (Address & 0xf8000) != 0) {
> + return MAX_UINT32;
> + }
> +
> + switch (Width) {
> + case PciCfgWidthUint8:
> + MmioWrite8 (Base , Data);
> + break;
> + case PciCfgWidthUint16:
> + MmioWrite16 (Base , Data);
> + break;
> + case PciCfgWidthUint32:
> + MmioWrite32 (Base , Data);
> + break;
> + default:
> + ASSERT (FALSE);
> + }
> +
> + return Data;
> +}
> +
> +/**
> + Register a PCI device so PCI configuration registers may be accessed after
> + SetVirtualAddressMap().
> +
> + If any reserved bits in Address are set, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device,
> + Function and Register.
> +
> + @retval RETURN_SUCCESS The PCI device was registered for runtime access.
> + @retval RETURN_UNSUPPORTED An attempt was made to call this function
> + after ExitBootServices().
> + @retval RETURN_UNSUPPORTED The resources required to access the PCI device
> + at runtime could not be mapped.
> + @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
> + complete the registration.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +PciSegmentRegisterForRuntimeAccess (
> + IN UINTN Address
> + )
> +{
> + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> + return RETURN_UNSUPPORTED;
> +}
> +
> +/**
> + Reads an 8-bit PCI configuration register.
> +
> + Reads and returns the 8-bit PCI configuration register specified by Address.
> +
> + If any reserved bits in Address are set, then ASSERT().
> +
> + @param Address The address that encodes the PCI Segment, Bus, Device, Function,
> + and Register.
> +
> + @return The 8-bit PCI configuration register specified by Address.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentRead8 (
> + IN UINT64 Address
> + )
> +{
> + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> +
> + return (UINT8) PciSegmentLibReadWorker (Address, PciCfgWidthUint8);
> +}
> +
> +/**
> + Writes an 8-bit PCI configuration register.
> +
> + Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.
> + Value is returned. This function must guarantee that all PCI read and write operations are serialized.
> +
> + If any reserved bits in Address are set, then ASSERT().
> +
> + @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
> + @param Value The value to write.
> +
> + @return The value written to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentWrite8 (
> + IN UINT64 Address,
> + IN UINT8 Value
> + )
> +{
> + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> +
> + return (UINT8) PciSegmentLibWriteWorker (Address, PciCfgWidthUint8, Value);
> +}
> +
> +/**
> + Reads a 16-bit PCI configuration register.
> +
> + Reads and returns the 16-bit PCI configuration register specified by Address.
> +
> + If any reserved bits in Address are set, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
> +
> + @return The 16-bit PCI configuration register specified by Address.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentRead16 (
> + IN UINT64 Address
> + )
> +{
> + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
> +
> + return (UINT16) PciSegmentLibReadWorker (Address, PciCfgWidthUint16);
> +}
> +
> +/**
> + Writes a 16-bit PCI configuration register.
> +
> + Writes the 16-bit PCI configuration register specified by Address with the
> + value specified by Value.
> +
> + Value is returned.
> +
> + If any reserved bits in Address are set, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
> + @param Value The value to write.
> +
> + @return The parameter of Value.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentWrite16 (
> + IN UINT64 Address,
> + IN UINT16 Value
> + )
> +{
> + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
> +
> + return (UINT16) PciSegmentLibWriteWorker (Address, PciCfgWidthUint16, Value);
> +}
> +
> +/**
> + Reads a 32-bit PCI configuration register.
> +
> + Reads and returns the 32-bit PCI configuration register specified by Address.
> +
> + If any reserved bits in Address are set, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Segment, Bus, Device, Function,
> + and Register.
> +
> + @return The 32-bit PCI configuration register specified by Address.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentRead32 (
> + IN UINT64 Address
> + )
> +{
> + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
> +
> + return PciSegmentLibReadWorker (Address, PciCfgWidthUint32);
> +}
> +
> +/**
> + Writes a 32-bit PCI configuration register.
> +
> + Writes the 32-bit PCI configuration register specified by Address with the
> + value specified by Value.
> +
> + Value is returned.
> +
> + If any reserved bits in Address are set, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Segment, Bus, Device,
> + Function, and Register.
> + @param Value The value to write.
> +
> + @return The parameter of Value.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentWrite32 (
> + IN UINT64 Address,
> + IN UINT32 Value
> + )
> +{
> + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
> +
> + return PciSegmentLibWriteWorker (Address, PciCfgWidthUint32, Value);
> +}
> +
> +/**
> + Reads a range of PCI configuration registers into a caller supplied buffer.
> +
> + Reads the range of PCI configuration registers specified by StartAddress and
> + Size into the buffer specified by Buffer. This function only allows the PCI
> + configuration registers from a single PCI function to be read. Size is
> + returned.
> +
> + If any reserved bits in StartAddress are set, then ASSERT().
> + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> + If Size > 0 and Buffer is NULL, then ASSERT().
> +
> + @param StartAddress The starting address that encodes the PCI Segment, Bus,
> + Device, Function and Register.
> + @param Size The size in bytes of the transfer.
> + @param Buffer The pointer to a buffer receiving the data read.
> +
> + @return Size
> +
> +**/
> +UINTN
> +EFIAPI
> +PciSegmentReadBuffer (
> + IN UINT64 StartAddress,
> + IN UINTN Size,
> + OUT VOID *Buffer
> + )
> +{
> + UINTN ReturnValue;
> +
> + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
> + ASSERT (((StartAddress & 0xFFF) + Size) <= SIZE_4KB);
> +
> + if (Size == 0) {
> + return Size;
> + }
> +
> + ASSERT (Buffer != NULL);
> +
> + //
> + // Save Size for return
> + //
> + ReturnValue = Size;
> +
> + if ((StartAddress & BIT0) != 0) {
> + //
> + // Read a byte if StartAddress is byte aligned
> + //
> + *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
> + StartAddress += sizeof (UINT8);
> + Size -= sizeof (UINT8);
> + Buffer = (UINT8*)Buffer + BIT0;
> + }
> +
> + if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
> + //
> + // Read a word if StartAddress is word aligned
> + //
> + WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
> + StartAddress += sizeof (UINT16);
> + Size -= sizeof (UINT16);
> + Buffer = (UINT16*)Buffer + BIT0;
> + }
> +
> + while (Size >= sizeof (UINT32)) {
> + //
> + // Read as many double words as possible
> + //
> + WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));
> + StartAddress += sizeof (UINT32);
> + Size -= sizeof (UINT32);
> + Buffer = (UINT32*)Buffer + BIT0;
> + }
> +
> + if (Size >= sizeof (UINT16)) {
> + //
> + // Read the last remaining word if exist
> + //
> + WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
> + StartAddress += sizeof (UINT16);
> + Size -= sizeof (UINT16);
> + Buffer = (UINT16*)Buffer + BIT0;
> + }
> +
> + if (Size >= sizeof (UINT8)) {
> + //
> + // Read the last remaining byte if exist
> + //
> + *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
> + }
> +
> + return ReturnValue;
> +}
> +
> +
> +/**
> + Copies the data in a caller supplied buffer to a specified range of PCI
> + configuration space.
> +
> + Writes the range of PCI configuration registers specified by StartAddress and
> + Size from the buffer specified by Buffer. This function only allows the PCI
> + configuration registers from a single PCI function to be written. Size is
> + returned.
> +
> + If any reserved bits in StartAddress are set, then ASSERT().
> + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> + If Size > 0 and Buffer is NULL, then ASSERT().
> +
> + @param StartAddress The starting address that encodes the PCI Segment, Bus,
> + Device, Function and Register.
> + @param Size The size in bytes of the transfer.
> + @param Buffer The pointer to a buffer containing the data to write.
> +
> + @return The parameter of Size.
> +
> +**/
> +UINTN
> +EFIAPI
> +PciSegmentWriteBuffer (
> + IN UINT64 StartAddress,
> + IN UINTN Size,
> + IN VOID *Buffer
> + )
> +{
> + UINTN ReturnValue;
> +
> + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
> + ASSERT (((StartAddress & 0xFFF) + Size) <= SIZE_4KB);
> +
> + if (Size == 0) {
> + return Size;
> + }
> +
> + ASSERT (Buffer != NULL);
> +
> + //
> + // Save Size for return
> + //
> + ReturnValue = Size;
> +
> + if ((StartAddress & BIT0) != 0) {
> + //
> + // Write a byte if StartAddress is byte aligned
> + //
> + PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);
> + StartAddress += sizeof (UINT8);
> + Size -= sizeof (UINT8);
> + Buffer = (UINT8*)Buffer + BIT0;
> + }
> +
> + if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
> + //
> + // Write a word if StartAddress is word aligned
> + //
> + PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
> + StartAddress += sizeof (UINT16);
> + Size -= sizeof (UINT16);
> + Buffer = (UINT16*)Buffer + BIT0;
> + }
> +
> + while (Size >= sizeof (UINT32)) {
> + //
> + // Write as many double words as possible
> + //
> + PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));
> + StartAddress += sizeof (UINT32);
> + Size -= sizeof (UINT32);
> + Buffer = (UINT32*)Buffer + BIT0;
> + }
> +
> + if (Size >= sizeof (UINT16)) {
> + //
> + // Write the last remaining word if exist
> + //
> + PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
> + StartAddress += sizeof (UINT16);
> + Size -= sizeof (UINT16);
> + Buffer = (UINT16*)Buffer + BIT0;
> + }
> +
> + if (Size >= sizeof (UINT8)) {
> + //
> + // Write the last remaining byte if exist
> + //
> + PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);
> + }
> +
> + return ReturnValue;
> +}
> +
> +EFI_STATUS
> +PciSegLibInit (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + return EFI_SUCCESS;
> +}
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 08/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows
2020-05-21 23:02 ` [PATCH edk2-platforms 08/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows Wasim Khan
@ 2020-05-22 9:31 ` Ard Biesheuvel
0 siblings, 0 replies; 42+ messages in thread
From: Ard Biesheuvel @ 2020-05-22 9:31 UTC (permalink / raw)
To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
leif, jon
Cc: Wasim Khan
On 5/22/20 1:02 AM, Wasim Khan wrote:
> From: Wasim Khan <wasim.khan@nxp.com>
>
> Dump ATU windows for PCIe Layerscape controller if PcdPciDebug
> is enabled.
>
> Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> ---
> .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 42 ++++++++++++++++++++++
> 1 file changed, 42 insertions(+)
>
> diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> index 1de20c621dc0..3ad526218bcf 100644
> --- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> +++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> @@ -297,6 +297,44 @@ PcieOutboundSet (
> }
>
> /**
> + Dump PCIe Layerscape ATU
> +
> + @param Pcie Address of PCIe host controller.
> +**/
> +VOID LsDumpAtu (
> + IN EFI_PHYSICAL_ADDRESS Pcie
> + )
> +{
> + UINT32 Cnt;
> + for (Cnt = 0; Cnt <= IATU_REGION_INDEX7; Cnt++) {
> + MmioWrite32 ((UINTN)Pcie + IATU_VIEWPORT_OFF,
> + (UINT32)(IATU_VIEWPORT_OUTBOUND | Cnt));
> +
> + DEBUG ((DEBUG_INFO, "iATU%d:\n",Cnt));
> + DEBUG ((DEBUG_INFO, "\tLOWER PHYS 0x%08x\n",
> + MmioRead32 ((UINTN)Pcie + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0)));
> +
> + DEBUG ((DEBUG_INFO, "\tUPPER PHYS 0x%08x\n",
> + MmioRead32 ((UINTN)Pcie + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0)));
> +
> + DEBUG ((DEBUG_INFO, "\tLOWER BUS 0x%08x\n",
> + MmioRead32 ((UINTN)Pcie + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0)));
> +
> + DEBUG ((DEBUG_INFO, "\tUPPER BUS 0x%08x\n",
> + MmioRead32 ((UINTN)Pcie + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0)));
> +
> + DEBUG ((DEBUG_INFO, "\tLIMIT 0x%08x\n",
> + MmioRead32 ((UINTN)Pcie + IATU_LIMIT_ADDR_OFF_OUTBOUND_0)));
> +
> + DEBUG ((DEBUG_INFO, "\tCR1 0x%08x\n",
> + MmioRead32 ((UINTN)Pcie + IATU_REGION_CTRL_1_OFF_OUTBOUND_0)));
> +
> + DEBUG ((DEBUG_INFO, "\tCR2 0x%08x\n",
> + MmioRead32 ((UINTN)Pcie + IATU_REGION_CTRL_2_OFF_OUTBOUND_0)));
> + }
> +}
> +
> +/**
> Function to set-up iATU windows for Layerscape PCIe controller
>
> @param Pcie Address of PCIe host controller
> @@ -410,6 +448,10 @@ PcieLsSetupAtu (
> SEG_IO_BUS,
> SEG_IO_SIZE
> );
> +
> + if (FixedPcdGetBool (PcdPciDebug) == TRUE) {
> + LsDumpAtu (Pcie);
> + }
> }
>
> /*
We already have DEBUG vs RELEASE builds, and various debug levels.
Please don't add your own DEBUG PCDs on top of that. Instead, if you
need code to only be executed in DEBUG builds (like the MmioWrite()
above), use DEBUG_CODE_BEGIN/END
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 07/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows
2020-05-21 23:02 ` [PATCH edk2-platforms 07/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows Wasim Khan
@ 2020-05-22 9:33 ` Ard Biesheuvel
0 siblings, 0 replies; 42+ messages in thread
From: Ard Biesheuvel @ 2020-05-22 9:33 UTC (permalink / raw)
To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
leif, jon
Cc: Wasim Khan
On 5/22/20 1:02 AM, Wasim Khan wrote:
> From: Wasim Khan <wasim.khan@nxp.com>
>
> Dump ATU windows for PCIe LsGen4 controller if PcdPciDebug
> is enabled.
>
> Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
> Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> ---
> .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 1 +
> .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 34 ++++++++++++++++++++++
> 2 files changed, 35 insertions(+)
>
> diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> index b777acdc103f..df1590172e15 100644
> --- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> +++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> @@ -38,6 +38,7 @@ [FixedPcd]
> gNxpQoriqLsTokenSpaceGuid.PcdNumPciController
> gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase
> gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg
> + gNxpQoriqLsTokenSpaceGuid.PcdPciDebug
>
> [Pcd]
> gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
> diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> index bacdc29d60d6..1de20c621dc0 100644
> --- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> +++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> @@ -413,6 +413,36 @@ PcieLsSetupAtu (
> }
>
> /**
> + Dump PCIe LsGen4 ATU
> +
> + @param Pcie Address of PCIe host controller.
> +**/
> +VOID LsGen4DumpAtu (
> + IN EFI_PHYSICAL_ADDRESS Pcie
> + )
> +{
> + UINT32 Cnt;
> + for (Cnt = 0; Cnt <= IATU_REGION_INDEX6; Cnt++) {
> + DEBUG ((DEBUG_INFO,"APIO WINDOW%d:\n", Cnt));
> + DEBUG ((DEBUG_INFO,"\tLOWER PHYS 0x%08x\n",
> + PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_AMAP_AXI_WIN (Cnt))));
> + DEBUG ((DEBUG_INFO,"\tUPPER PHYS 0x%08x\n",
> + PciLsGen4Read32 ((UINTN)Pcie, PAB_EXT_AXI_AMAP_AXI_WIN (Cnt))));
> + DEBUG ((DEBUG_INFO,"\tLOWER BUS 0x%08x\n",
> + PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_AMAP_PEX_WIN_L (Cnt))));
> + DEBUG ((DEBUG_INFO,"\tUPPER BUS 0x%08x\n",
> + PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_AMAP_PEX_WIN_H (Cnt))));
> + DEBUG ((DEBUG_INFO,"\tSIZE 0x%08x\n",
> + PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_AMAP_CTRL (Cnt)) &
> + (AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT)));
> + DEBUG ((DEBUG_INFO,"\tEXT_SIZE 0x%08x\n",
> + PciLsGen4Read32 ((UINTN)Pcie, PAB_EXT_AXI_AMAP_SIZE (Cnt))));
> + DEBUG ((DEBUG_INFO,"\tCTRL: 0x%08x\n",
> + PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_AMAP_CTRL (Cnt))));
> + }
> +}
> +
> +/**
> Function to set-up ATU windows for PCIe LayerscapeGen4 controller
>
> @param Pcie Address of PCIe host controller
> @@ -484,6 +514,10 @@ PcieLsGen4SetupAtu (
> Mem64Base,
> Mem64Base,
> SIZE_4GB);
> +
> + if (FixedPcdGetBool (PcdPciDebug) == TRUE) {
> + LsGen4DumpAtu (Pcie);
> + }
> }
>
> /**
>
Same remark: don't add PCDs for DEBUG, just use levels.
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 10/16] Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS Controller
2020-05-21 23:02 ` [PATCH edk2-platforms 10/16] Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS Controller Wasim Khan
@ 2020-05-22 9:36 ` Ard Biesheuvel
2020-05-24 18:32 ` Wasim Khan (OSS)
0 siblings, 1 reply; 42+ messages in thread
From: Ard Biesheuvel @ 2020-05-22 9:36 UTC (permalink / raw)
To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
leif, jon
Cc: Wasim Khan
On 5/22/20 1:02 AM, Wasim Khan wrote:
> From: Wasim Khan <wasim.khan@nxp.com>
>
> PCIe Layerscape controller can be enabled for ECAM style
> configuration access using CFG SHIFT Feature.
>
> Check for PcdPciCfgShiftEnable to decide the configuration access
> scheme to be used with PCIe LS controller.
>
> Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> ---
> Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf | 3 +++
> Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 20 ++++++++++++++++----
> 2 files changed, 19 insertions(+), 4 deletions(-)
>
> diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> index a36e79239b33..936213dc8a9d 100755
> --- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> @@ -30,3 +30,6 @@ [LibraryClasses]
>
> [FixedPcd]
> gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
> +
> +[Pcd]
> + gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
> diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> index ecd36971b753..552a425c6832 100755
> --- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> @@ -34,6 +34,8 @@ typedef enum {
> #define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
> ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
>
> +static BOOLEAN CfgShiftEnable;
> +
This is a compile time constant, right? Please try to avoid using
runtime read/write variables in that case, since it defeats the
compiler's ability to remove code that is never executed.
> STATIC
> UINT64
> PciLsCfgTarget (
> @@ -88,11 +90,20 @@ PciLsGetConfigBase (
> {
> UINT32 CfgAddr;
>
> - CfgAddr = (UINT16)Offset;
> - if (Bus) {
> - return PciLsCfgTarget (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment, Address, Segment, Bus, Offset);
> + if (CfgShiftEnable) {
> + CfgAddr = (UINT32)Address;
> + if (Bus) {
> + return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment + CfgAddr;
> + } else {
> + return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
> + }
> } else {
> - return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
> + CfgAddr = (UINT16)Offset;
> + if (Bus) {
> + return PciLsCfgTarget (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment, Address, Segment, Bus, Offset);
> + } else {
> + return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
> + }
> }
> }
>
> @@ -608,5 +619,6 @@ PciSegLibInit (
> IN EFI_SYSTEM_TABLE *SystemTable
> )
> {
> + CfgShiftEnable = CFG_SHIFT_ENABLE;
> return EFI_SUCCESS;
> }
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 11/16] Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller
2020-05-21 23:02 ` [PATCH edk2-platforms 11/16] Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller Wasim Khan
@ 2020-05-22 9:38 ` Ard Biesheuvel
2020-05-24 18:32 ` Wasim Khan (OSS)
0 siblings, 1 reply; 42+ messages in thread
From: Ard Biesheuvel @ 2020-05-22 9:38 UTC (permalink / raw)
To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
leif, jon
Cc: Wasim Khan
On 5/22/20 1:02 AM, Wasim Khan wrote:
> From: Wasim Khan <wasim.khan@nxp.com>
>
> PCIe Layerscape Gen4 controller is not ECAM complaint and have
compliant
> different PCI config space region for bus 0 (Controller space) and
> bus[0x1-0xff] on NXP SoCs.
>
> For config transactions for Bus0:
> - Config transaction address = PCIe controller address + offset
>
> For config transactions for Bus[0x1-0xff]:
> - PCIe IP requires target BDF to be written at bit[31:16] of PCIe
> outbound configuration window.
>
> PCIe LsGen4 controller uses paging mechanism to access registers.
> To access PCIe CCSR registers which are above 3KB offset, page number
> must be set in Bridge Control Register.
>
> Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
> Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> ---
> .../NXP/Library/PciSegmentLib/PciSegmentLib.inf | 1 +
> Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 60 +++++++++++++++++++++-
> 2 files changed, 60 insertions(+), 1 deletion(-)
>
> diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> index 936213dc8a9d..d6d7ea6e3b6b 100755
> --- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> @@ -33,3 +33,4 @@ [FixedPcd]
>
> [Pcd]
> gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
> + gNxpQoriqLsTokenSpaceGuid.PcdPciLsGen4Ctrl
> diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> index 552a425c6832..02a1525ef308 100755
> --- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> @@ -35,6 +35,58 @@ typedef enum {
> ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
>
> static BOOLEAN CfgShiftEnable;
> +static BOOLEAN PciLsGen4Ctrl;
> +
Another compile time constant?
> +STATIC
> +VOID
> +PcieCfgSetTarget (
> + IN EFI_PHYSICAL_ADDRESS Dbi,
> + IN UINT32 Target)
> +{
> + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_L(0), Target);
> + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_H(0), 0);
> +}
> +
> +/**
> + Function to return PCIe Physical Address(PCIe view) or Controller
> + Address(CPU view) for NXP Layerscape Gen4 SoC
> +
> + @param Address Address passed from bus layer.
> + @param Segment Segment number for Root Complex.
> + @param Offset Config space register offset.
> + @param Bus PCIe Bus number.
> +
> + @return Return PCIe CPU or Controller address.
> +
> +**/
> +STATIC
> +UINT64
> +PciLsGen4GetConfigBase (
> + IN UINT64 Address,
> + IN UINT16 Segment,
> + IN UINT16 Offset,
> + IN UINT8 Bus
> + )
> +{
> + UINT32 Target;
> +
> + if (Bus) {
Bus > 0
> + Target = ((((Address >> 20) & 0xFF) << 24) |
> + (((Address >> 15) & 0x1F) << 19) |
> + (((Address >> 12) & 0x7) << 16));
Drop the outer ()
> +
> + PcieCfgSetTarget ((PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF* Segment), Target);
> + return PCI_SEG0_MMIO_MEMBASE + Offset + PCI_BASE_DIFF * Segment;
> + } else {
> + if (Offset < INDIRECT_ADDR_BNDRY) {
> + PciLsGen4SetPg (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment, 0);
> + return (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + Offset);
> + }
> + PciLsGen4SetPg (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment, OFFSET_TO_PAGE_IDX (Offset));
> + Offset = OFFSET_TO_PAGE_ADDR (Offset);
> + return (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + Offset);
> + }
> +}
>
> STATIC
> UINT64
> @@ -129,7 +181,12 @@ PciSegmentLibGetConfigBase (
> UINT8 Bus;
>
> Bus = ((UINT32)Address >> 20) & 0xff;
> - return PciLsGetConfigBase (Address, Segment, Offset, Bus);
> +
> + if (PciLsGen4Ctrl) {
> + return PciLsGen4GetConfigBase (Address, Segment, Offset, Bus);
> + } else {
> + return PciLsGetConfigBase (Address, Segment, Offset, Bus);
> + }
> }
>
> /**
> @@ -620,5 +677,6 @@ PciSegLibInit (
> )
> {
> CfgShiftEnable = CFG_SHIFT_ENABLE;
> + PciLsGen4Ctrl = PCI_LS_GEN4_CTRL;
> return EFI_SUCCESS;
> }
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 12/16] Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264
2020-05-21 23:02 ` [PATCH edk2-platforms 12/16] Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264 Wasim Khan
@ 2020-05-22 9:39 ` Ard Biesheuvel
2020-05-24 18:32 ` Wasim Khan (OSS)
0 siblings, 1 reply; 42+ messages in thread
From: Ard Biesheuvel @ 2020-05-22 9:39 UTC (permalink / raw)
To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
leif, jon
Cc: Wasim Khan
On 5/22/20 1:02 AM, Wasim Khan wrote:
> From: Wasim Khan <wasim.khan@nxp.com>
>
> With PCIe LsGen4 controller, clearing the Bus Master Enable bit in
> Command register blocks all outbound transactions to be sent out
> in RC mode.
>
> According to PCI Express base specification, the Command register’s
> Bus Master Enable bit of a PCI Express RC controller can only
> control the forwarding of memory requests received at its root port
> in the upstream direction. In other words, clearing the Bus Master
> Enable bit must not block all outbound transactions to be sent out
> toward RC’s downstream devices. Due to this erratum, when the
> Command register’s Bus Master Enable bit is cleared, all the outbound
> transactions from the device’s internal bus masters, including but
> not limited to configuration read and write transactions, are
> terminated with the slave error (SLVERR) response status on the PCI
> Express RC controller’s internal AXI bus interface.
>
> Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> ---
> Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> index 02a1525ef308..c3bc14820ea5 100755
> --- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> @@ -39,6 +39,21 @@ static BOOLEAN PciLsGen4Ctrl;
>
> STATIC
> VOID
> +PciLsGen4SetBusMaster (
> + IN EFI_PHYSICAL_ADDRESS Dbi
> + )
> +{
> + UINT32 Val;
> +
> + /* Make sure the Master Enable bit not cleared */
Please use // style comments
> + Val = PciLsGen4Read32 ((UINTN)Dbi, PCI_COMMAND_OFFSET);
> + if (!(Val & EFI_PCI_COMMAND_BUS_MASTER)) {
> + PciLsGen4Write32 ((UINTN)Dbi, PCI_COMMAND_OFFSET, Val | EFI_PCI_COMMAND_BUS_MASTER);
> + }
> +}
> +
> +STATIC
> +VOID
> PcieCfgSetTarget (
> IN EFI_PHYSICAL_ADDRESS Dbi,
> IN UINT32 Target)
> @@ -71,6 +86,8 @@ PciLsGen4GetConfigBase (
> UINT32 Target;
>
> if (Bus) {
> + PciLsGen4SetBusMaster (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF* Segment);
> +
Can't we just set this once and never touch it? Or is that tricky?
> Target = ((((Address >> 20) & 0xFF) << 24) |
> (((Address >> 15) & 0x1F) << 19) |
> (((Address >> 12) & 0x7) << 16));
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 13/16] Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver
2020-05-21 23:02 ` [PATCH edk2-platforms 13/16] Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver Wasim Khan
@ 2020-05-22 9:42 ` Ard Biesheuvel
0 siblings, 0 replies; 42+ messages in thread
From: Ard Biesheuvel @ 2020-05-22 9:42 UTC (permalink / raw)
To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
leif, jon
Cc: Wasim Khan
On 5/22/20 1:02 AM, Wasim Khan wrote:
> From: Wasim Khan <wasim.khan@nxp.com>
>
> NXP SoC has multiple PCIe RCs and there is no fix translation
> offset between I/O port accesses and MMIO accesses.
> Add PciCpuIo2Dxe driver to implement EFI_CPU_IO2_PROTOCOL
> to add the translation for different RCs for IO access.
>
> Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
> ---
> Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf | 40 ++
> Silicon/NXP/Include/Pcie.h | 19 +
> Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c | 628 ++++++++++++++++++++++
> 3 files changed, 687 insertions(+)
> create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
> create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c
>
> diff --git a/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
> new file mode 100755
> index 000000000000..0ee470e41d5e
> --- /dev/null
> +++ b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
> @@ -0,0 +1,40 @@
> +## @file
> +# Produces the CPU I/O 2 Protocol by using the services of the I/O Library.
> +#
> +# Copyright 2018, 2020 NXP
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x0001001A
> + BASE_NAME = PciCpuIo2Dxe
> + FILE_GUID = 7bff18d7-9aae-434b-9c06-f10a7e157eac
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = PciCpuIo2Initialize
> +
> +[Sources]
> + PciCpuIo2Dxe.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + Silicon/NXP/NxpQoriqLs.dec
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + IoLib
> + UefiBootServicesTableLib
> + UefiDriverEntryPoint
> +
> +[Pcd]
> + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
> + gNxpQoriqLsTokenSpaceGuid.PcdNumPciController
> +
> +[Protocols]
> + gEfiCpuIo2ProtocolGuid ## PRODUCES
> +
> +[Depex]
> + TRUE
> diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h
> index bc35570f79bc..b561d0e3ba11 100755
> --- a/Silicon/NXP/Include/Pcie.h
> +++ b/Silicon/NXP/Include/Pcie.h
> @@ -39,6 +39,25 @@
> #define PCI_SEG0_PHY_MEM_BASE PCI_SEG0_MMIO_MEMBASE + SEG_MEM_BASE
> #define PCI_SEG0_PHY_MEM64_BASE PCI_SEG0_MMIO_MEMBASE + SEG_MEM64_BASE
> #define PCI_SEG0_PHY_IO_BASE PCI_SEG0_MMIO_MEMBASE + SEG_IO_BASE
> +#define PCI_SEG0_PORTIO_MIN 0x0
> +#define PCI_SEG0_PORTIO_MAX 0xffff
> +#define PCI_SEG0_PORTIO_OFFSET 0x0
> +#define PCI_SEG1_PORTIO_MIN 0x0
> +#define PCI_SEG1_PORTIO_MAX 0xffff
> +#define PCI_SEG1_PORTIO_OFFSET 0x10000
> +#define PCI_SEG2_PORTIO_MIN 0x0
> +#define PCI_SEG2_PORTIO_MAX 0xffff
> +#define PCI_SEG2_PORTIO_OFFSET 0x20000
> +#define PCI_SEG3_PORTIO_MIN 0x0
> +#define PCI_SEG3_PORTIO_MAX 0xffff
> +#define PCI_SEG3_PORTIO_OFFSET 0x30000
> +#define PCI_SEG4_PORTIO_MIN 0x0
> +#define PCI_SEG4_PORTIO_MAX 0xffff
> +#define PCI_SEG4_PORTIO_OFFSET 0x40000
> +#define PCI_SEG5_PORTIO_MIN 0x0
> +#define PCI_SEG5_PORTIO_MAX 0xffff
> +#define PCI_SEG5_PORTIO_OFFSET 0x50000
> +#define PCI_SEG_PORTIO_LIMIT PCI_SEG5_PORTIO_MAX + PCI_SEG5_PORTIO_OFFSET
>
> // PCIe Controller configuration
> #define NUM_PCIE_CONTROLLER FixedPcdGet32 (PcdNumPciController)
> diff --git a/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c
> new file mode 100755
> index 000000000000..17db44a8b510
> --- /dev/null
> +++ b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c
> @@ -0,0 +1,628 @@
> +/** @file
> + Produces the CPU I/O 2 Protocol.
> +
> + Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
> + Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
> + Copyright 2018-2020 NXP
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Pcie.h>
> +#include <Protocol/CpuIo2.h>
> +
> +#define MAX_IO_PORT_ADDRESS PCI_SEG_PORTIO_LIMIT
> +
> +//
> +// Handle for the CPU I/O 2 Protocol
> +//
> +STATIC EFI_HANDLE mHandle = NULL;
> +
> +//
> +// Lookup table for increment values based on transfer widths
> +//
> +STATIC CONST UINT8 mInStride[] = {
> + 1, // EfiCpuIoWidthUint8
> + 2, // EfiCpuIoWidthUint16
> + 4, // EfiCpuIoWidthUint32
> + 8, // EfiCpuIoWidthUint64
> + 0, // EfiCpuIoWidthFifoUint8
> + 0, // EfiCpuIoWidthFifoUint16
> + 0, // EfiCpuIoWidthFifoUint32
> + 0, // EfiCpuIoWidthFifoUint64
> + 1, // EfiCpuIoWidthFillUint8
> + 2, // EfiCpuIoWidthFillUint16
> + 4, // EfiCpuIoWidthFillUint32
> + 8 // EfiCpuIoWidthFillUint64
> +};
> +
> +//
> +// Lookup table for increment values based on transfer widths
> +//
> +STATIC CONST UINT8 mOutStride[] = {
> + 1, // EfiCpuIoWidthUint8
> + 2, // EfiCpuIoWidthUint16
> + 4, // EfiCpuIoWidthUint32
> + 8, // EfiCpuIoWidthUint64
> + 1, // EfiCpuIoWidthFifoUint8
> + 2, // EfiCpuIoWidthFifoUint16
> + 4, // EfiCpuIoWidthFifoUint32
> + 8, // EfiCpuIoWidthFifoUint64
> + 0, // EfiCpuIoWidthFillUint8
> + 0, // EfiCpuIoWidthFillUint16
> + 0, // EfiCpuIoWidthFillUint32
> + 0 // EfiCpuIoWidthFillUint64
> +};
> +
> +/**
> + Check parameters to a CPU I/O 2 Protocol service request.
> +
> + The I/O operations are carried out exactly as requested. The caller is responsible
> + for satisfying any alignment and I/O width restrictions that a PI System on a
> + platform might require. For example on some platforms, width requests of
> + EfiCpuIoWidthUint64 do not work.
> +
> + @param[in] MmioOperation TRUE for an MMIO operation, FALSE for I/O Port operation.
> + @param[in] Width Signifies the width of the I/O or Memory operation.
> + @param[in] Address The base address of the I/O operation.
> + @param[in] Count The number of I/O operations to perform. The number of
> + bytes moved is Width size * Count, starting at Address.
> + @param[in] Buffer For read operations, the destination buffer to store the results.
> + For write operations, the source buffer from which to write data.
> +
> + @retval EFI_SUCCESS The parameters for this request pass the checks.
> + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.
> + @retval EFI_INVALID_PARAMETER Buffer is NULL.
> + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.
> + @retval EFI_UNSUPPORTED The address range specified by Address, Width,
> + and Count is not valid for this PI system.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +CpuIoCheckParameter (
> + IN BOOLEAN MmioOperation,
> + IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
> + IN UINT64 Address,
> + IN UINTN Count,
> + IN VOID *Buffer
> + )
> +{
> + UINT64 MaxCount;
> + UINT64 Limit;
> +
> + //
> + // Check to see if Buffer is NULL
> + //
> + if (Buffer == NULL) {
> + ASSERT (FALSE);
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Check to see if Width is in the valid range
> + //
> + if ((UINT32)Width >= EfiCpuIoWidthMaximum) {
> + ASSERT (FALSE);
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // For FIFO type, the target address won't increase during the access,
> + // so treat Count as 1
> + //
> + if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
> + Count = 1;
> + }
> +
> + //
> + // Check to see if Width is in the valid range for I/O Port operations
> + //
> + Width = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
> + if (!MmioOperation && (Width == EfiCpuIoWidthUint64)) {
> + ASSERT (FALSE);
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Check to see if Address is aligned
> + //
> + if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {
> + ASSERT (FALSE);
> + return EFI_UNSUPPORTED;
> + }
> +
> + //
> + // Check to see if any address associated with this transfer exceeds the maximum
> + // allowed address. The maximum address implied by the parameters passed in is
> + // Address + Size * Count. If the following condition is met, then the transfer
> + // is not supported.
> + //
> + // Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1
> + //
> + // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count
> + // can also be the maximum integer value supported by the CPU, this range
> + // check must be adjusted to avoid all oveflow conditions.
> + //
> + Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS);
> + if (Count == 0) {
> + if (Address > Limit) {
> + ASSERT (FALSE);
> + return EFI_UNSUPPORTED;
> + }
> + } else {
> + MaxCount = RShiftU64 (Limit, Width);
> + if (MaxCount < (Count - 1)) {
> + ASSERT (FALSE);
> + return EFI_UNSUPPORTED;
> + }
> + if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
> + ASSERT (FALSE);
> + return EFI_UNSUPPORTED;
> + }
> + }
> +
> + //
> + // Check to see if Buffer is aligned
> + //
> + if (((UINTN)Buffer & ((MIN (sizeof (UINTN), mInStride[Width]) - 1))) != 0) {
> + ASSERT (FALSE);
> + return EFI_UNSUPPORTED;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Reads memory-mapped registers.
> +
> + The I/O operations are carried out exactly as requested. The caller is responsible
> + for satisfying any alignment and I/O width restrictions that a PI System on a
> + platform might require. For example on some platforms, width requests of
> + EfiCpuIoWidthUint64 do not work.
> +
> + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
> + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
> + each of the Count operations that is performed.
> +
> + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
> + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
> + incremented for each of the Count operations that is performed. The read or
> + write operation is performed Count times on the same Address.
> +
> + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
> + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
> + incremented for each of the Count operations that is performed. The read or
> + write operation is performed Count times from the first element of Buffer.
> +
> + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance.
> + @param[in] Width Signifies the width of the I/O or Memory operation.
> + @param[in] Address The base address of the I/O operation.
> + @param[in] Count The number of I/O operations to perform. The number of
> + bytes moved is Width size * Count, starting at Address.
> + @param[out] Buffer For read operations, the destination buffer to store the results.
> + For write operations, the source buffer from which to write data.
> +
> + @retval EFI_SUCCESS The data was read from or written to the PI system.
> + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.
> + @retval EFI_INVALID_PARAMETER Buffer is NULL.
> + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.
> + @retval EFI_UNSUPPORTED The address range specified by Address, Width,
> + and Count is not valid for this PI system.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +CpuMemoryServiceRead (
> + IN EFI_CPU_IO2_PROTOCOL *This,
> + IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
> + IN UINT64 Address,
> + IN UINTN Count,
> + OUT VOID *Buffer
> + )
> +{
> + EFI_STATUS Status;
> + UINT8 InStride;
> + UINT8 OutStride;
> + EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth;
> + UINT8 *Uint8Buffer;
> +
> + Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Select loop based on the width of the transfer
> + //
> + InStride = mInStride[Width];
> + OutStride = mOutStride[Width];
> + OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
> + for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
> + if (OperationWidth == EfiCpuIoWidthUint8) {
> + *Uint8Buffer = MmioRead8 ((UINTN)Address);
> + } else if (OperationWidth == EfiCpuIoWidthUint16) {
> + *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
> + } else if (OperationWidth == EfiCpuIoWidthUint32) {
> + *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
> + } else if (OperationWidth == EfiCpuIoWidthUint64) {
> + *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
> + }
> + }
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Writes memory-mapped registers.
> +
> + The I/O operations are carried out exactly as requested. The caller is responsible
> + for satisfying any alignment and I/O width restrictions that a PI System on a
> + platform might require. For example on some platforms, width requests of
> + EfiCpuIoWidthUint64 do not work.
> +
> + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
> + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
> + each of the Count operations that is performed.
> +
> + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
> + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
> + incremented for each of the Count operations that is performed. The read or
> + write operation is performed Count times on the same Address.
> +
> + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
> + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
> + incremented for each of the Count operations that is performed. The read or
> + write operation is performed Count times from the first element of Buffer.
> +
> + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance.
> + @param[in] Width Signifies the width of the I/O or Memory operation.
> + @param[in] Address The base address of the I/O operation.
> + @param[in] Count The number of I/O operations to perform. The number of
> + bytes moved is Width size * Count, starting at Address.
> + @param[in] Buffer For read operations, the destination buffer to store the results.
> + For write operations, the source buffer from which to write data.
> +
> + @retval EFI_SUCCESS The data was read from or written to the PI system.
> + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.
> + @retval EFI_INVALID_PARAMETER Buffer is NULL.
> + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.
> + @retval EFI_UNSUPPORTED The address range specified by Address, Width,
> + and Count is not valid for this PI system.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +CpuMemoryServiceWrite (
> + IN EFI_CPU_IO2_PROTOCOL *This,
> + IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
> + IN UINT64 Address,
> + IN UINTN Count,
> + IN VOID *Buffer
> + )
> +{
> + EFI_STATUS Status;
> + UINT8 InStride;
> + UINT8 OutStride;
> + EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth;
> + UINT8 *Uint8Buffer;
> +
> + Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Select loop based on the width of the transfer
> + //
> + InStride = mInStride[Width];
> + OutStride = mOutStride[Width];
> + OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
> + for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
> + if (OperationWidth == EfiCpuIoWidthUint8) {
> + MmioWrite8 ((UINTN)Address, *Uint8Buffer);
> + } else if (OperationWidth == EfiCpuIoWidthUint16) {
> + MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
> + } else if (OperationWidth == EfiCpuIoWidthUint32) {
> + MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
> + } else if (OperationWidth == EfiCpuIoWidthUint64) {
> + MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
> + }
> + }
> + return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +TranslateIoAddress (
> + IN OUT UINT64 *Address
> + )
> +{
> + UINT64 Start;
> + UINT64 End;
> + UINT64 Shift;
> + UINT64 SegIoHostAddressBase;
> +
> + SegIoHostAddressBase = PCI_SEG0_PHY_IO_BASE;
> + Start = PCI_SEG0_PORTIO_MIN + PCI_SEG0_PORTIO_OFFSET;
> + End = PCI_SEG0_PORTIO_MAX + PCI_SEG0_PORTIO_OFFSET;
> + Shift = SegIoHostAddressBase - PCI_SEG0_PORTIO_OFFSET;
> +
> + if (*Address >= Start && *Address <= End) {
> + *Address += Shift;
> + return EFI_SUCCESS;
> + }
> +
> + Start = PCI_SEG1_PORTIO_MIN + PCI_SEG1_PORTIO_OFFSET;
> + End = PCI_SEG1_PORTIO_MAX + PCI_SEG1_PORTIO_OFFSET;
> + Shift = (SegIoHostAddressBase + (PCI_BASE_DIFF * 1)) - PCI_SEG1_PORTIO_OFFSET;
> +
> + if (*Address >= Start && *Address <= End) {
> + *Address += Shift;
> + return EFI_SUCCESS;
> + }
> +
> + Start = PCI_SEG2_PORTIO_MIN + PCI_SEG2_PORTIO_OFFSET;
> + End = PCI_SEG2_PORTIO_MAX + PCI_SEG2_PORTIO_OFFSET;
> + Shift = (SegIoHostAddressBase + (PCI_BASE_DIFF * 2)) - PCI_SEG2_PORTIO_OFFSET;
> +
> + if (*Address >= Start && *Address <= End) {
> + *Address += Shift;
> + return EFI_SUCCESS;
> + }
> +
> + Start = PCI_SEG3_PORTIO_MIN + PCI_SEG3_PORTIO_OFFSET;
> + End = PCI_SEG3_PORTIO_MAX + PCI_SEG3_PORTIO_OFFSET;
> + Shift = (SegIoHostAddressBase + (PCI_BASE_DIFF * 3)) - PCI_SEG3_PORTIO_OFFSET;
> +
> + if (*Address >= Start && *Address <= End) {
> + *Address += Shift;
> + return EFI_SUCCESS;
> + }
> +
> + Start = PCI_SEG4_PORTIO_MIN + PCI_SEG4_PORTIO_OFFSET;
> + End = PCI_SEG4_PORTIO_MAX + PCI_SEG4_PORTIO_OFFSET;
> + Shift = (SegIoHostAddressBase + (PCI_BASE_DIFF * 4)) - PCI_SEG4_PORTIO_OFFSET;
> +
> + if (*Address >= Start && *Address <= End) {
> + *Address += Shift;
> + return EFI_SUCCESS;
> + }
> +
> + Start = PCI_SEG5_PORTIO_MIN + PCI_SEG5_PORTIO_OFFSET;
> + End = PCI_SEG5_PORTIO_MAX + PCI_SEG5_PORTIO_OFFSET;
> + Shift = (SegIoHostAddressBase + (PCI_BASE_DIFF * 5)) - PCI_SEG5_PORTIO_OFFSET;
> +
> + if (*Address >= Start && *Address <= End) {
> + *Address += Shift;
> + return EFI_SUCCESS;
> + }
> + ASSERT (FALSE);
> + return EFI_INVALID_PARAMETER;
> +}
> +
> +/**
> + Reads I/O registers.
> +
> + The I/O operations are carried out exactly as requested. The caller is responsible
> + for satisfying any alignment and I/O width restrictions that a PI System on a
> + platform might require. For example on some platforms, width requests of
> + EfiCpuIoWidthUint64 do not work.
> +
> + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
> + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
> + each of the Count operations that is performed.
> +
> + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
> + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
> + incremented for each of the Count operations that is performed. The read or
> + write operation is performed Count times on the same Address.
> +
> + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
> + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
> + incremented for each of the Count operations that is performed. The read or
> + write operation is performed Count times from the first element of Buffer.
> +
> + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance.
> + @param[in] Width Signifies the width of the I/O or Memory operation.
> + @param[in] Address The base address of the I/O operation.
> + @param[in] Count The number of I/O operations to perform. The number of
> + bytes moved is Width size * Count, starting at Address.
> + @param[out] Buffer For read operations, the destination buffer to store the results.
> + For write operations, the source buffer from which to write data.
> +
> + @retval EFI_SUCCESS The data was read from or written to the PI system.
> + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.
> + @retval EFI_INVALID_PARAMETER Buffer is NULL.
> + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.
> + @retval EFI_UNSUPPORTED The address range specified by Address, Width,
> + and Count is not valid for this PI system.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +CpuIoServiceRead (
> + IN EFI_CPU_IO2_PROTOCOL *This,
> + IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
> + IN UINT64 Address,
> + IN UINTN Count,
> + OUT VOID *Buffer
> + )
> +{
> + EFI_STATUS Status;
> + UINT8 InStride;
> + UINT8 OutStride;
> + EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth;
> + UINT8 *Uint8Buffer;
> +
> + Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Status = TranslateIoAddress (&Address);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Select loop based on the width of the transfer
> + //
> + InStride = mInStride[Width];
> + OutStride = mOutStride[Width];
> + OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03);
> +
> + for (Uint8Buffer = Buffer; Count > 0;
> + Address += InStride, Uint8Buffer += OutStride, Count--) {
> + if (OperationWidth == EfiCpuIoWidthUint8) {
> + *Uint8Buffer = MmioRead8 ((UINTN)Address);
> + } else if (OperationWidth == EfiCpuIoWidthUint16) {
> + *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
> + } else if (OperationWidth == EfiCpuIoWidthUint32) {
> + *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
> + }
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Write I/O registers.
> +
> + The I/O operations are carried out exactly as requested. The caller is responsible
> + for satisfying any alignment and I/O width restrictions that a PI System on a
> + platform might require. For example on some platforms, width requests of
> + EfiCpuIoWidthUint64 do not work.
> +
> + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32,
> + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for
> + each of the Count operations that is performed.
> +
> + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16,
> + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is
> + incremented for each of the Count operations that is performed. The read or
> + write operation is performed Count times on the same Address.
> +
> + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16,
> + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is
> + incremented for each of the Count operations that is performed. The read or
> + write operation is performed Count times from the first element of Buffer.
> +
> + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance.
> + @param[in] Width Signifies the width of the I/O or Memory operation.
> + @param[in] Address The base address of the I/O operation.
> + @param[in] Count The number of I/O operations to perform. The number of
> + bytes moved is Width size * Count, starting at Address.
> + @param[in] Buffer For read operations, the destination buffer to store the results.
> + For write operations, the source buffer from which to write data.
> +
> + @retval EFI_SUCCESS The data was read from or written to the PI system.
> + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.
> + @retval EFI_INVALID_PARAMETER Buffer is NULL.
> + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.
> + @retval EFI_UNSUPPORTED The address range specified by Address, Width,
> + and Count is not valid for this PI system.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +CpuIoServiceWrite (
> + IN EFI_CPU_IO2_PROTOCOL *This,
> + IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
> + IN UINT64 Address,
> + IN UINTN Count,
> + IN VOID *Buffer
> + )
> +{
> + EFI_STATUS Status;
> + UINT8 InStride;
> + UINT8 OutStride;
> + EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth;
> + UINT8 *Uint8Buffer;
> +
> + //
> + // Make sure the parameters are valid
> + //
> + Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Status = TranslateIoAddress (&Address);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Select loop based on the width of the transfer
> + //
> + InStride = mInStride[Width];
> + OutStride = mOutStride[Width];
> + OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
> +
> + for (Uint8Buffer = (UINT8 *)Buffer; Count > 0;
> + Address += InStride, Uint8Buffer += OutStride, Count--) {
> + if (OperationWidth == EfiCpuIoWidthUint8) {
> + MmioWrite8 ((UINTN)Address, *Uint8Buffer);
> + } else if (OperationWidth == EfiCpuIoWidthUint16) {
> + MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
> + } else if (OperationWidth == EfiCpuIoWidthUint32) {
> + MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
> + }
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +//
> +// CPU I/O 2 Protocol instance
> +//
> +STATIC EFI_CPU_IO2_PROTOCOL mCpuIo2 = {
> + {
> + CpuMemoryServiceRead,
> + CpuMemoryServiceWrite
> + },
> + {
> + CpuIoServiceRead,
> + CpuIoServiceWrite
> + }
> +};
> +
> +
> +/**
> + The user Entry Point for module CpuIo2Dxe. The user code starts with this function.
> +
> + @param[in] ImageHandle The firmware allocated handle for the EFI image.
> + @param[in] SystemTable A pointer to the EFI System Table.
> +
> + @retval EFI_SUCCESS The entry point is executed successfully.
> + @retval other Some error occurs when executing this entry point.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PciCpuIo2Initialize (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> +
> + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiCpuIo2ProtocolGuid);
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + &mHandle,
> + &gEfiCpuIo2ProtocolGuid, &mCpuIo2,
> + NULL
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + return Status;
> +}
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 14/16] Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg
2020-05-21 23:02 ` [PATCH edk2-platforms 14/16] Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg Wasim Khan
@ 2020-05-22 9:42 ` Ard Biesheuvel
0 siblings, 0 replies; 42+ messages in thread
From: Ard Biesheuvel @ 2020-05-22 9:42 UTC (permalink / raw)
To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
leif, jon
Cc: Wasim Khan
On 5/22/20 1:02 AM, Wasim Khan wrote:
> From: Wasim Khan <wasim.khan@nxp.com>
>
> Enable NetworkPkg for LS1043aRdb Platform.
>
> Signed-off-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
Drop the signoff please. If Meenakshi wrote the patch, make them the
author not the submitter.
> Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> ---
> Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc | 11 +++++++++++
> Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 5 +++++
> 2 files changed, 16 insertions(+)
>
> diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
> index d45fd67c03b5..8f7f9d171587 100644
> --- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
> +++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
> @@ -22,6 +22,13 @@ [Defines]
> OUTPUT_DIRECTORY = Build/LS1043aRdbPkg
> FLASH_DEFINITION = Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
>
> + #
> + # Network definition
> + #
> + DEFINE NETWORK_TLS_ENABLE = FALSE
> + DEFINE NETWORK_HTTP_BOOT_ENABLE = FALSE
> + DEFINE NETWORK_ISCSI_ENABLE = FALSE
> +
> !include Silicon/NXP/NxpQoriqLs.dsc.inc
> !include Silicon/NXP/LS1043A/LS1043A.dsc.inc
>
> @@ -54,4 +61,8 @@ [Components.common]
> Silicon/NXP/Drivers/I2cDxe/I2cDxe.inf
> Platform/NXP/LS1043aRdbPkg/Drivers/PlatformDxe/PlatformDxe.inf
>
> + #
> + # Networking stack
> + #
> +!include NetworkPkg/Network.dsc.inc
> ##
> diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
> index 931d0bb14f9b..596922221e8c 100644
> --- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
> +++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
> @@ -119,6 +119,11 @@ [FV.FvMain]
> INF EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
>
> #
> + # Networking stack
> + #
> +!include NetworkPkg/Network.fdf.inc
> +
> + #
> # FAT filesystem + GPT/MBR partitioning
> #
> INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 16/16] Platform/NXP: LS1043aRdbPkg : Increase fv image size
2020-05-21 23:02 ` [PATCH edk2-platforms 16/16] Platform/NXP: LS1043aRdbPkg : Increase fv image size Wasim Khan
@ 2020-05-22 9:44 ` Ard Biesheuvel
0 siblings, 0 replies; 42+ messages in thread
From: Ard Biesheuvel @ 2020-05-22 9:44 UTC (permalink / raw)
To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
leif, jon
Cc: Wasim Khan
On 5/22/20 1:02 AM, Wasim Khan wrote:
> From: Wasim Khan <wasim.khan@nxp.com>
>
> Increase fv image size to pass debug build.
>
> Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
> ---
> Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 8 +++++---
> 1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
> index 81142f217a63..1c160e349eb9 100644
> --- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
> +++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
> @@ -24,10 +24,12 @@
>
> [FD.LS1043ARDB_EFI]
> BaseAddress = 0x82000000|gArmTokenSpaceGuid.PcdFdBaseAddress #The base address of the FLASH Device.
> -Size = 0x00140000|gArmTokenSpaceGuid.PcdFdSize #The size in bytes of the FLASH Device
> +Size = 0x00180000|gArmTokenSpaceGuid.PcdFdSize #The size in bytes of the FLASH Device
> ErasePolarity = 1
> +
> +# This one is tricky, it must be: BlockSize * NumBlocks = Size
> BlockSize = 0x40000
> -NumBlocks = 0x5
> +NumBlocks = 0x6
>
> ################################################################################
> #
> @@ -44,7 +46,7 @@ [FD.LS1043ARDB_EFI]
> # RegionType <FV, DATA, or FILE>
> #
> ################################################################################
> -0x00000000|0x00140000
> +0x00000000|0x00180000
> gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
> FV = FVMAIN_COMPACT
>
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 00/16] Add PCIe Support
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
` (15 preceding siblings ...)
2020-05-21 23:02 ` [PATCH edk2-platforms 16/16] Platform/NXP: LS1043aRdbPkg : Increase fv image size Wasim Khan
@ 2020-05-22 9:46 ` Ard Biesheuvel
2020-05-22 10:58 ` Leif Lindholm
16 siblings, 1 reply; 42+ messages in thread
From: Ard Biesheuvel @ 2020-05-22 9:46 UTC (permalink / raw)
To: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
leif, jon
Cc: Wasim Khan
On 5/22/20 1:02 AM, Wasim Khan wrote:
> From: Wasim Khan <wasim.khan@nxp.com>
>
> Add PCIe Support for NXP Layerscape SoC which supports
> different PCIe controllers.
> Use generic PCIe drivers and wire up PciHostBridgeLib,
> PciSegmentLib and PciCpuIo2Dxe driver for controller
> specific implementation.
>
Thanks. This is looking good. Please take a look at the feedback, and
give others some time to respond as well.
In the meantime, I think we can simply merge #14 and #16 right away
(unless Leif has any objections)
> Wasim Khan (16):
> Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs.
> Silicon/NXP: LS1043A: Define PCIe related PCDs
> Silicon/NXP: Implement PciHostBridgeLib support
> Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS
> Ctrl
> Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU
> Windows
> Silicon/NXP: PciHostBridgeLib: add Workaround for A-011451
> Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows
> Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows
> Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller
> Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS
> Controller
> Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller
> Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264
> Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver
> Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg
> Platform/NXP: LS1043aRdbPkg: Enable PCIE support
> Platform/NXP: LS1043aRdbPkg : Increase fv image size
>
> Silicon/NXP/NxpQoriqLs.dec | 13 +
> Silicon/NXP/LS1043A/LS1043A.dsc.inc | 8 +
> Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc | 20 +
> Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 20 +-
> Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf | 40 +
> .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 45 ++
> .../NXP/Library/PciSegmentLib/PciSegmentLib.inf | 36 +
> Silicon/NXP/Include/Pcie.h | 231 ++++++
> Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c | 628 +++++++++++++++
> .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 842 +++++++++++++++++++++
> Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 699 +++++++++++++++++
> 11 files changed, 2579 insertions(+), 3 deletions(-)
> create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
> create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> create mode 100755 Silicon/NXP/Include/Pcie.h
> create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c
> create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 00/16] Add PCIe Support
2020-05-22 9:46 ` [PATCH edk2-platforms 00/16] Add PCIe Support Ard Biesheuvel
@ 2020-05-22 10:58 ` Leif Lindholm
2020-05-24 18:32 ` Wasim Khan (OSS)
0 siblings, 1 reply; 42+ messages in thread
From: Leif Lindholm @ 2020-05-22 10:58 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Wasim Khan, devel, meenakshi.aggarwal, vabhav.sharma, V.Sethi,
jon, Wasim Khan
On Fri, May 22, 2020 at 11:46:07 +0200, Ard Biesheuvel wrote:
> On 5/22/20 1:02 AM, Wasim Khan wrote:
> > From: Wasim Khan <wasim.khan@nxp.com>
> >
> > Add PCIe Support for NXP Layerscape SoC which supports
> > different PCIe controllers.
> > Use generic PCIe drivers and wire up PciHostBridgeLib,
> > PciSegmentLib and PciCpuIo2Dxe driver for controller
> > specific implementation.
> >
>
> Thanks. This is looking good. Please take a look at the feedback, and give
> others some time to respond as well.
>
> In the meantime, I think we can simply merge #14 and #16 right away (unless
> Leif has any objections)
(Looking at those two out of order.)
16, sure.
14 - is there any reason to do so before there is PCI to connect
network devices through?
/
Leif
>
> > Wasim Khan (16):
> > Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs.
> > Silicon/NXP: LS1043A: Define PCIe related PCDs
> > Silicon/NXP: Implement PciHostBridgeLib support
> > Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS
> > Ctrl
> > Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU
> > Windows
> > Silicon/NXP: PciHostBridgeLib: add Workaround for A-011451
> > Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows
> > Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows
> > Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller
> > Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS
> > Controller
> > Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller
> > Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264
> > Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver
> > Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg
> > Platform/NXP: LS1043aRdbPkg: Enable PCIE support
> > Platform/NXP: LS1043aRdbPkg : Increase fv image size
> >
> > Silicon/NXP/NxpQoriqLs.dec | 13 +
> > Silicon/NXP/LS1043A/LS1043A.dsc.inc | 8 +
> > Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc | 20 +
> > Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 20 +-
> > Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf | 40 +
> > .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 45 ++
> > .../NXP/Library/PciSegmentLib/PciSegmentLib.inf | 36 +
> > Silicon/NXP/Include/Pcie.h | 231 ++++++
> > Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c | 628 +++++++++++++++
> > .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 842 +++++++++++++++++++++
> > Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 699 +++++++++++++++++
> > 11 files changed, 2579 insertions(+), 3 deletions(-)
> > create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
> > create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> > create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > create mode 100755 Silicon/NXP/Include/Pcie.h
> > create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c
> > create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> > create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> >
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 01/16] Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs.
2020-05-22 9:12 ` Ard Biesheuvel
@ 2020-05-24 18:31 ` Wasim Khan (OSS)
2020-05-26 6:16 ` Ard Biesheuvel
0 siblings, 1 reply; 42+ messages in thread
From: Wasim Khan (OSS) @ 2020-05-24 18:31 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Wasim Khan (OSS), devel@edk2.groups.io, Meenakshi Aggarwal,
Vabhav Sharma, Varun Sethi, leif@nuviainc.com, jon@solid-run.com
> -----Original Message-----
> From: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Sent: Friday, May 22, 2020 2:42 PM
> To: Wasim Khan (OSS) <wasim.khan@oss.nxp.com>; devel@edk2.groups.io;
> Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>; Vabhav Sharma
> <vabhav.sharma@nxp.com>; Varun Sethi <V.Sethi@nxp.com>;
> leif@nuviainc.com; jon@solid-run.com
> Cc: Wasim Khan <wasim.khan@nxp.com>
> Subject: Re: [PATCH edk2-platforms 01/16] Silicon/NXP/NxpQoriqLs.dec: Add
> PCIe related PCDs.
>
> On 5/22/20 1:02 AM, Wasim Khan wrote:
> > From: Wasim Khan <wasim.khan@nxp.com>
> >
> > Add PCIe related PCDs.
> >
> > Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
>
> Please drop this signoff. This is not the correct way to acknowledge (co-
> )authorship.
Co-authored-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Co-authored-by: Wasim Khan <wasim.khan@nxp.com>
Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
Is this OK ?
>
> > Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> > ---
> > Silicon/NXP/NxpQoriqLs.dec | 9 +++++++++
> > 1 file changed, 9 insertions(+)
> >
> > diff --git a/Silicon/NXP/NxpQoriqLs.dec b/Silicon/NXP/NxpQoriqLs.dec
> > index 0722f59ef4f6..bafdfd9f4298 100644
> > --- a/Silicon/NXP/NxpQoriqLs.dec
> > +++ b/Silicon/NXP/NxpQoriqLs.dec
> > @@ -27,3 +27,12 @@ [Guids.common]
> > [PcdsFeatureFlag]
> >
> gNxpQoriqLsTokenSpaceGuid.PcdI2cErratumA009203|FALSE|BOOLEAN|0x0000
> 0315
> >
> >
> gNxpQoriqLsTokenSpaceGuid.PcdDcfgBigEndian|FALSE|BOOLEAN|0x00000316
> > +
> > +
> gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian|FALSE|BOOLEAN|0x0000031
> > + 7
> > +
> > +[PcdsFixedAtBuild.common]
> > + # Pcds for PCI Express
> > +
> gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr|0x0|UINT64|0x00000500
> > + gNxpQoriqLsTokenSpaceGuid.PcdNumPciController|0|UINT32|0x00000501
> > + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase|0x0|UINT32|0x00000502
> > + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg|0x0|UINT32|0x00000503
> > + gNxpQoriqLsTokenSpaceGuid.PcdPciDebug|FALSE|BOOLEAN|0x00000504
> >
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 05/16] Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU Windows
2020-05-22 9:24 ` Ard Biesheuvel
@ 2020-05-24 18:31 ` Wasim Khan (OSS)
0 siblings, 0 replies; 42+ messages in thread
From: Wasim Khan (OSS) @ 2020-05-24 18:31 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: devel@edk2.groups.io, Meenakshi Aggarwal, Vabhav Sharma,
Varun Sethi, leif@nuviainc.com, jon@solid-run.com
> -----Original Message-----
> From: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Sent: Friday, May 22, 2020 2:55 PM
> To: Wasim Khan (OSS) <wasim.khan@oss.nxp.com>; devel@edk2.groups.io;
> Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>; Vabhav Sharma
> <vabhav.sharma@nxp.com>; Varun Sethi <V.Sethi@nxp.com>;
> leif@nuviainc.com; jon@solid-run.com
> Cc: Wasim Khan <wasim.khan@nxp.com>
> Subject: Re: [PATCH edk2-platforms 05/16] Silicon/NXP: PciHostBridgeLib: Setup
> PCIe LsGen4 Controller and ATU Windows
>
> On 5/22/20 1:02 AM, Wasim Khan wrote:
> > From: Wasim Khan <wasim.khan@nxp.com>
> >
> > Setup PCIe LayerscapeGen4 controller and setup CFG, IO, MMIO and
> > MMIO64 iATU windows.
> > Check for PcdPciLsGen4Ctrl to enable LsGen4 PCIe controller.
> >
> > Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
> > Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
>
> How much overlap is there between these controllers? Does it really make sense
> to use the same PciHostBridgeLib implementation and parameterize the hell out
> of it?
>
Majorly the Window configuration part is different as both controller has different registers set.
Most of the common code is same, that’s why we want to keep a single PciHostBrigeLib.
Also, for the LX2160-Rev1 and LX2160-Rev2 PCIe controller is different, so to use the same Binary on both versions, we use single Library and based on SoC version at run time , we enable the underneath controller.
>
> > ---
> > Silicon/NXP/NxpQoriqLs.dec | 1 +
> > .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 1 +
> > Silicon/NXP/Include/Pcie.h | 120 ++++++++++
> > .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 255 +++++++++++++++++-
> ---
> > 4 files changed, 336 insertions(+), 41 deletions(-)
> >
> > diff --git a/Silicon/NXP/NxpQoriqLs.dec b/Silicon/NXP/NxpQoriqLs.dec
> > index 293fd773fd3d..8271d19ed8e5 100644
> > --- a/Silicon/NXP/NxpQoriqLs.dec
> > +++ b/Silicon/NXP/NxpQoriqLs.dec
> > @@ -39,3 +39,4 @@ [PcdsFixedAtBuild.common]
> >
> > [PcdsDynamic.common]
> >
> >
> gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable|FALSE|BOOLEAN|0x000006
> 0
> > 0
> > +
> gNxpQoriqLsTokenSpaceGuid.PcdPciLsGen4Ctrl|FALSE|BOOLEAN|0x00000601
> > diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> > b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> > index 98cfb6aee6b0..b777acdc103f 100644
> > --- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> > +++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> > @@ -41,3 +41,4 @@ [FixedPcd]
> >
> > [Pcd]
> > gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
> > + gNxpQoriqLsTokenSpaceGuid.PcdPciLsGen4Ctrl
> > diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h
> > index ae85190180e8..4c41c3585a8b 100755
> > --- a/Silicon/NXP/Include/Pcie.h
> > +++ b/Silicon/NXP/Include/Pcie.h
> > @@ -84,5 +84,125 @@
> > #define SEG_IO_BUS 0x0
> >
> > #define CFG_SHIFT_ENABLE (PcdGetBool (PcdPciCfgShiftEnable))
> > +#define PCI_LS_GEN4_CTRL (PcdGetBool (PcdPciLsGen4Ctrl))
> >
> > +// PCIe Layerscape Gen4 Controller
> > +#define GPEX_CLASSCODE 0x474
> > +#define GPEX_CLASSCODE_SHIFT 16
> > +#define GPEX_CLASSCODE_MASK 0xffff
> > +#define PAB_AXI_PIO_CTRL(Idx) (0x840 + 0x10 * Idx)
> > +#define APIO_EN 0x1
> > +#define MEM_WIN_EN 0x1 << 1
> > +#define IO_WIN_EN 0x1 << 2
> > +#define CFG_WIN_EN 0x1 << 3
> > +#define PAB_PEX_PIO_CTRL(Idx) (0x8c0 + 0x10 * Idx)
> > +#define PPIO_EN (0x1 << 0)
> > +#define PAB_PEX_PIO_STAT(Idx) (0x8c4 + 0x10 * Idx)
> > +#define PAB_PEX_PIO_MT_STAT(Idx) (0x8c8 + 0x10 * Idx)
> > +#define PEX_AMAP_CTRL_TYPE_SHIFT 0x1
> > +#define PEX_AMAP_CTRL_EN_SHIFT 0x0
> > +#define PEX_AMAP_CTRL_TYPE_MASK 0x3
> > +#define PEX_AMAP_CTRL_EN_MASK 0x1
> > +#define PAB_PEX_AMAP_CTRL(Idx) (0x4ba0 + 0x10 * Idx)
> > +#define PAB_EXT_PEX_AMAP_SIZE(Idx) (0xbef0 + 0x04 * Idx)
> > +#define PAB_PEX_AMAP_AXI_WIN(Idx) (0x4ba4 + 0x10 * Idx)
> > +#define PAB_EXT_PEX_AMAP_AXI_WIN(Idx) (0xb4a0 + 0x04 * Idx)
> > +#define PAB_PEX_AMAP_PEX_WIN_L(Idx) (0x4ba8 + 0x10 * Idx)
> > +#define PAB_PEX_AMAP_PEX_WIN_H(Idx) (0x4bac + 0x10 * Idx)
> > +#define PAB_CTRL 0x808
> > +#define PAB_CTRL_APIO_EN 0x1
> > +#define PAB_CTRL_PPIO_EN (0x1 << 1)
> > +#define PAB_CTRL_PAGE_SEL_SHIFT 13
> > +#define PAB_CTRL_PAGE_SEL_MASK 0x3f
> > +#define INDIRECT_ADDR_BNDRY 0xc00
> > +#define PAGE_IDX_SHIFT 10
> > +#define PAGE_ADDR_MASK 0x3ff
> > +#define PAB_AXI_AMAP_CTRL(Idx) (0xba0 + 0x10 * Idx)
> > +#define PAB_EXT_AXI_AMAP_SIZE(Idx) (0xbaf0 + 0x4 * Idx)
> > +#define PAB_AXI_AMAP_AXI_WIN(Idx) (0xba4 + 0x10 * Idx)
> > +#define PAB_EXT_AXI_AMAP_AXI_WIN(Idx) (0x80a0 + 0x4 * Idx)
> > +#define PAB_AXI_AMAP_PEX_WIN_L(Idx) (0xba8 + 0x10 * Idx)
> > +#define PAB_AXI_AMAP_PEX_WIN_H(Idx) (0xbac + 0x10 * Idx)
> > +#define PAB_AXI_TYPE_CFG 0x00
> > +#define PAB_AXI_TYPE_IO 0x01
> > +#define PAB_AXI_TYPE_MEM 0x02
> > +#define AXI_AMAP_CTRL_EN 0x1
> > +#define AXI_AMAP_CTRL_TYPE_SHIFT 1
> > +#define AXI_AMAP_CTRL_TYPE_MASK 0x3
> > +#define AXI_AMAP_CTRL_SIZE_SHIFT 10
> > +#define AXI_AMAP_CTRL_SIZE_MASK 0x3fffff
> > +
> > +
> > +#define OFFSET_TO_PAGE_IDX(Off) ((Off >> PAGE_IDX_SHIFT) \
> > + &
> > +PAB_CTRL_PAGE_SEL_MASK)
> > +
> > +#define OFFSET_TO_PAGE_ADDR(Off) ((Off & PAGE_ADDR_MASK) \
> > + |
> > +INDIRECT_ADDR_BNDRY)
> > +/**
> > + Function to set page for LsGen4 Ctrl
> > +
> > + @param Dbi GPEX host controller address.
> > + @param PgIdx The page index to select
> > +
> > +**/
> > +STATIC inline VOID PciLsGen4SetPg (
> > + IN EFI_PHYSICAL_ADDRESS Dbi,
> > + IN UINT8 PgIdx
> > + )
> > +{
> > + UINT32 Val;
> > + Val = MmioRead32 (Dbi + PAB_CTRL);
> > + Val &= ~(PAB_CTRL_PAGE_SEL_MASK << PAB_CTRL_PAGE_SEL_SHIFT);
> > + Val |= (PgIdx & PAB_CTRL_PAGE_SEL_MASK) <<
> PAB_CTRL_PAGE_SEL_SHIFT;
> > + MmioWrite32 (Dbi + PAB_CTRL, Val);
> > +}
> > +
> > +/**
> > + Function to read LsGen4 PCIe controller config space
> > + LsGen4 PCIe controller requires page number to be set
> > + in Bridge Control Register(PAB) for offset > 3KB.
> > +
> > + @param Dbi GPEX host controller address.
> > + @param Offset Offset to read from
> > +
> > +**/
> > +STATIC inline INTN PciLsGen4Read32 (
> > + IN EFI_PHYSICAL_ADDRESS Dbi,
> > + IN UINT32 Offset
> > + )
> > +{
> > + if (Offset < INDIRECT_ADDR_BNDRY) {
> > + PciLsGen4SetPg (Dbi, 0);
> > + return MmioRead32 (Dbi + Offset);
> > + } else {
> > + // If Offset > 3KB, paging mechanism is used
> > + // Select page index and offset within the page
> > + PciLsGen4SetPg (Dbi, OFFSET_TO_PAGE_IDX (Offset));
> > + return MmioRead32 (Dbi + OFFSET_TO_PAGE_ADDR (Offset));
> > + }
> > +}
> > +
> > +/**
> > + Function to write to LsGen4 PCIe controller config space
> > + LsGen4 PCIe controller requires page number to be set
> > + in Bridge Control Register(PAB) for offset > 3KB.
> > +
> > + @param Dbi GPEX host controller address
> > + @param Offset Offset to read from
> > +
> > +**/
> > +STATIC inline VOID PciLsGen4Write32 (
> > + IN EFI_PHYSICAL_ADDRESS Dbi,
> > + IN UINT32 Offset,
> > + IN UINT32 Value
> > + )
> > +{
> > + if (Offset < INDIRECT_ADDR_BNDRY) {
> > + PciLsGen4SetPg (Dbi, 0);
> > + MmioWrite32 (Dbi + Offset, Value);
> > + } else {
> > + PciLsGen4SetPg (Dbi, OFFSET_TO_PAGE_IDX (Offset));
> > + MmioWrite32 (Dbi + OFFSET_TO_PAGE_ADDR (Offset), Value);
> > + }
> > +}
> > #endif
> > diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> > b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> > index f92863c60868..d9944313da21 100644
> > --- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> > +++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> > @@ -201,7 +201,11 @@ PcieLinkUp (
> > UINT32 State;
> > UINT32 LtssmMask;
> >
> > - LtssmMask = 0x3f;
> > + if (PCI_LS_GEN4_CTRL) {
> > + LtssmMask = 0x7f;
> > + } else {
> > + LtssmMask = 0x3f;
> > + }
> >
> > PcieOps = GetMmioOperations (FeaturePcdGet (PcdPciLutBigEndian));
> > State = PcieOps->Read32 ((UINTN)Pcie + PCI_LUT_BASE + PCI_LUT_DBG)
> > & LtssmMask; @@ -237,38 +241,58 @@ PcieOutboundSet (
> > IN UINT64 Size
> > )
> > {
> > - // PCIe Layerscape : Outbound Window
> > - MmioWrite32 (Dbi + IATU_VIEWPORT_OFF,
> > - (UINT32)(IATU_VIEWPORT_OUTBOUND | Idx));
> > + UINT32 Val;
> >
> > - MmioWrite32 (Dbi + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0,
> > - (UINT32)Phys);
> > -
> > - MmioWrite32 (Dbi + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0,
> > - (UINT32)(Phys >> 32));
> > -
> > - MmioWrite32 (Dbi + IATU_LIMIT_ADDR_OFF_OUTBOUND_0,
> > - (UINT32)(Phys + Size - BIT0));
> > -
> > - MmioWrite32 (Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0,
> > - (UINT32)BusAddr);
> > -
> > - MmioWrite32 (Dbi + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0,
> > - (UINT32)(BusAddr >> 32));
> > -
> > - MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0,
> > - (UINT32)Type);
> > -
> > - if (CFG_SHIFT_ENABLE &&
> > - ((Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0) ||
> > - (Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1))) {
> > - MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
> > - (IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN |
> > - IATU_ENABLE_CFG_SHIFT_FEATURE)
> > - );
> > + if (PCI_LS_GEN4_CTRL) {
> > + // PCIe Layerscape Gen4: Outbound Window
> > + Size = ~(Size -1 );
> > + Val = PciLsGen4Read32 ((UINTN)Dbi, PAB_AXI_AMAP_CTRL (Idx));
> > + Val &= ~((AXI_AMAP_CTRL_TYPE_MASK << AXI_AMAP_CTRL_TYPE_SHIFT)
> |
> > + (AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT) |
> > + AXI_AMAP_CTRL_EN);
> > + Val |= ((Type & AXI_AMAP_CTRL_TYPE_MASK) <<
> AXI_AMAP_CTRL_TYPE_SHIFT) |
> > + (((UINT32)Size >> AXI_AMAP_CTRL_SIZE_SHIFT) <<
> > + AXI_AMAP_CTRL_SIZE_SHIFT) | AXI_AMAP_CTRL_EN;
> > + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_CTRL (Idx), Val);
> > + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_AXI_WIN (Idx),
> (UINT32)Phys);
> > + PciLsGen4Write32 ((UINTN)Dbi, PAB_EXT_AXI_AMAP_AXI_WIN (Idx), Phys
> >> 32);
> > + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_L (Idx),
> (UINT32)BusAddr);
> > + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_H (Idx),
> BusAddr >> 32);
> > + PciLsGen4Write32 ((UINTN)Dbi, PAB_EXT_AXI_AMAP_SIZE (Idx), Size
> > + >> 32);
> > } else {
> > - MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
> > - IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
> > + // PCIe Layerscape : Outbound Window
> > + MmioWrite32 (Dbi + IATU_VIEWPORT_OFF,
> > + (UINT32)(IATU_VIEWPORT_OUTBOUND | Idx));
> > +
> > + MmioWrite32 (Dbi + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0,
> > + (UINT32)Phys);
> > +
> > + MmioWrite32 (Dbi + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0,
> > + (UINT32)(Phys >> 32));
> > +
> > + MmioWrite32 (Dbi + IATU_LIMIT_ADDR_OFF_OUTBOUND_0,
> > + (UINT32)(Phys + Size - BIT0));
> > +
> > + MmioWrite32 (Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0,
> > + (UINT32)BusAddr);
> > +
> > + MmioWrite32 (Dbi + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0,
> > + (UINT32)(BusAddr >> 32));
> > +
> > + MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0,
> > + (UINT32)Type);
> > +
> > + if (CFG_SHIFT_ENABLE &&
> > + ((Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0) ||
> > + (Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1))) {
> > + MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
> > + (IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN |
> > + IATU_ENABLE_CFG_SHIFT_FEATURE)
> > + );
> > + } else {
> > + MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0,
> > + IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN);
> > + }
> > }
> > }
> >
> > @@ -387,6 +411,124 @@ PcieLsSetupAtu (
> > SEG_IO_SIZE
> > );
> > }
> > +
> > +/**
> > + Function to set-up ATU windows for PCIe LayerscapeGen4 controller
> > +
> > + @param Pcie Address of PCIe host controller
> > + @param Cfg0Base PCIe controller phy address Type0 Configuration Space.
> > + @param Cfg1Base PCIe controller phy address Type1 Configuration Space.
> > + @param MemBase PCIe controller phy address Memory Space.
> > + @param Mem64Base PCIe controller phy address MMIO64 Space.
> > + @param IoBase PCIe controller phy address IO Space.
> > +**/
> > +STATIC
> > +VOID
> > +PcieLsGen4SetupAtu (
> > + IN EFI_PHYSICAL_ADDRESS Pcie,
> > + IN EFI_PHYSICAL_ADDRESS Cfg0Base,
> > + IN EFI_PHYSICAL_ADDRESS Cfg1Base,
> > + IN EFI_PHYSICAL_ADDRESS MemBase,
> > + IN EFI_PHYSICAL_ADDRESS Mem64Base,
> > + IN EFI_PHYSICAL_ADDRESS IoBase
> > + )
> > +{
> > + // ATU : OUTBOUND WINDOW 1 : CFG0
> > + PcieOutboundSet (Pcie, IATU_REGION_INDEX0,
> > + PAB_AXI_TYPE_CFG,
> > + Cfg0Base,
> > + SEG_CFG_BUS,
> > + SEG_CFG_SIZE);
> > +
> > + // ATU : OUTBOUND WINDOW 2 : IO
> > + PcieOutboundSet (Pcie, IATU_REGION_INDEX1,
> > + PAB_AXI_TYPE_IO,
> > + IoBase,
> > + SEG_IO_BUS,
> > + SEG_IO_SIZE);
> > +
> > + // ATU : OUTBOUND WINDOW 3 : MEM
> > + PcieOutboundSet (Pcie, IATU_REGION_INDEX2,
> > + PAB_AXI_TYPE_MEM,
> > + MemBase,
> > + SEG_MEM_BUS,
> > + SEG_MEM_SIZE);
> > +
> > + // ATU : OUTBOUND WINDOW 4 : MMIO64 PcieOutboundSet (Pcie,
> > + IATU_REGION_INDEX3,
> > + PAB_AXI_TYPE_MEM,
> > + Mem64Base,
> > + Mem64Base,
> > + SIZE_4GB); Mem64Base += SIZE_4GB;
> > +
> > + // ATU : OUTBOUND WINDOW 5 : MMIO64 PcieOutboundSet (Pcie,
> > + IATU_REGION_INDEX4,
> > + PAB_AXI_TYPE_MEM,
> > + Mem64Base,
> > + Mem64Base,
> > + SIZE_4GB); Mem64Base += SIZE_4GB;
> > +
> > + // ATU : OUTBOUND WINDOW 6 : MMIO64 PcieOutboundSet (Pcie,
> > + IATU_REGION_INDEX5,
> > + PAB_AXI_TYPE_MEM,
> > + Mem64Base,
> > + Mem64Base,
> > + SIZE_4GB); Mem64Base += SIZE_4GB;
> > +
> > + // ATU : OUTBOUND WINDOW 7 : MMIO64
> > + PcieOutboundSet (Pcie, IATU_REGION_INDEX6,
> > + PAB_AXI_TYPE_MEM,
> > + Mem64Base,
> > + Mem64Base,
> > + SIZE_4GB); }
> > +
> > +/**
> > + Function to set-up PCIe inbound window
> > +
> > + @param Pcie Address of PCIe host controller.
> > + @param Idx Index of inbound window.
> > + @param Type Type(Cfg/Mem/IO) of iATU outbound window.
> > + @param Phys PCIe controller phy address for inbound window.
> > + @param BusAdr PCIe controller bus address for inbound window.
> > + @param Size Window size
> > +
> > +**/
> > +
> > +STATIC
> > +VOID
> > +PciSetupInBoundWin (
> > + IN EFI_PHYSICAL_ADDRESS Pcie,
> > + IN UINT32 Idx,
> > + IN UINT32 Type,
> > + IN UINT64 Phys,
> > + IN UINT64 BusAddr,
> > + IN UINT64 Size)
> > +{
> > + UINT32 Val;
> > + UINT64 WinSize;
> > +
> > + if (PCI_LS_GEN4_CTRL) {
> > + Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_PEX_AMAP_CTRL(Idx));
> > + Val &= ~(PEX_AMAP_CTRL_TYPE_MASK << PEX_AMAP_CTRL_TYPE_SHIFT);
> > + Val &= ~(PEX_AMAP_CTRL_EN_MASK << PEX_AMAP_CTRL_EN_SHIFT);
> > + Val = (Val | (Type << PEX_AMAP_CTRL_TYPE_SHIFT));
> > + Val = (Val | (1 << PEX_AMAP_CTRL_EN_SHIFT));
> > +
> > + WinSize = ~(Size - 1);
> > + PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_CTRL(Idx),
> > + (Val | (UINT32)WinSize));
> > + PciLsGen4Write32 ((UINTN)Pcie, PAB_EXT_PEX_AMAP_SIZE(Idx),
> (WinSize>>32));
> > + PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_AXI_WIN(Idx),
> (UINT32)Phys);
> > + PciLsGen4Write32 ((UINTN)Pcie, PAB_EXT_PEX_AMAP_AXI_WIN(Idx),
> (Phys>>32));
> > + PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_PEX_WIN_L(Idx),
> (UINT32)BusAddr);
> > + PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_PEX_WIN_H(Idx),
> > +(BusAddr >>32));
> > + }
> > +}
> > +
> > /**
> > Helper function to set-up PCIe controller
> >
> > @@ -411,16 +553,47 @@ PcieSetupCntrl (
> > {
> > UINT32 Val;
> >
> > - // PCIe Layerscape Controller Setup
> > - PcieLsSetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base,
> > IoBase);
> > -
> > - // Program Class code for Layerscape PCIe controller
> > - MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 1);
> > - Val = MmioRead32 ((UINTN)Pcie + PCI_CLASS_DEVICE);
> > - Val &= ~(CLASS_CODE_MASK << CLASS_CODE_SHIFT);
> > - Val |= (PCI_CLASS_BRIDGE_PCI << CLASS_CODE_SHIFT);
> > - MmioWrite32 ((UINTN)Pcie + PCI_CLASS_DEVICE, Val);
> > - MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 0);
> > + if (PCI_LS_GEN4_CTRL) {
> > + // PCIe LsGen4 Controller Setup
> > +
> > + //Fix Class Code
> > + Val = PciLsGen4Read32 ((UINTN)Pcie, GPEX_CLASSCODE);
> > + Val &= ~(GPEX_CLASSCODE_MASK << GPEX_CLASSCODE_SHIFT);
> > + Val |= PCI_CLASS_BRIDGE_PCI << GPEX_CLASSCODE_SHIFT;
> > + PciLsGen4Write32 ((UINTN)Pcie, GPEX_CLASSCODE, Val);
> > +
> > + // Enable APIO and Memory/IO/CFG Windows
> > + Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_PIO_CTRL (0));
> > + Val |= APIO_EN | MEM_WIN_EN | IO_WIN_EN | CFG_WIN_EN;
> > + PciLsGen4Write32 ((UINTN)Pcie, PAB_AXI_PIO_CTRL (0), Val);
> > +
> > + // LsGen4 Inbound Window Setup
> > + PciSetupInBoundWin (Pcie, 0, PAB_AXI_TYPE_MEM, 0 , 0, SIZE_1TB);
> > +
> > + // LsGen4 Outbound Window Setup
> > + PcieLsGen4SetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base,
> > + IoBase);
> > +
> > + // Enable AMBA & PEX PIO
> > + Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_CTRL);
> > + Val |= PAB_CTRL_APIO_EN | PAB_CTRL_PPIO_EN;
> > + PciLsGen4Write32 ((UINTN)Pcie, PAB_CTRL, Val);
> > +
> > + Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_PEX_PIO_CTRL(0));
> > + Val |= PPIO_EN;
> > + PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_PIO_CTRL(0), Val);
> > +
> > + } else {
> > + // PCIe Layerscape Controller Setup
> > + PcieLsSetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base,
> > + IoBase);
> > +
> > + // Program Class code for Layerscape PCIe controller
> > + MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 1);
> > + Val = MmioRead32 ((UINTN)Pcie + PCI_CLASS_DEVICE);
> > + Val &= ~(CLASS_CODE_MASK << CLASS_CODE_SHIFT);
> > + Val |= (PCI_CLASS_BRIDGE_PCI << CLASS_CODE_SHIFT);
> > + MmioWrite32 ((UINTN)Pcie + PCI_CLASS_DEVICE, Val);
> > + MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 0); }
> > }
> >
> > /**
> >
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 09/16] Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller
2020-05-22 9:29 ` Ard Biesheuvel
@ 2020-05-24 18:32 ` Wasim Khan (OSS)
2020-05-25 4:30 ` Jon Nettleton
0 siblings, 1 reply; 42+ messages in thread
From: Wasim Khan (OSS) @ 2020-05-24 18:32 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: devel@edk2.groups.io, Meenakshi Aggarwal, Vabhav Sharma,
Varun Sethi, leif@nuviainc.com, jon@solid-run.com
> -----Original Message-----
> From: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Sent: Friday, May 22, 2020 3:00 PM
> To: Wasim Khan (OSS) <wasim.khan@oss.nxp.com>; devel@edk2.groups.io;
> Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>; Vabhav Sharma
> <vabhav.sharma@nxp.com>; Varun Sethi <V.Sethi@nxp.com>;
> leif@nuviainc.com; jon@solid-run.com
> Cc: Wasim Khan <wasim.khan@nxp.com>
> Subject: Re: [PATCH edk2-platforms 09/16] Silicon/NXP: Implement
> PciSegmentLib for PCIe Layerscape Controller
>
> On 5/22/20 1:02 AM, Wasim Khan wrote:
> > From: Wasim Khan <wasim.khan@nxp.com>
> >
> > We have different PCI config space region for bus 0 (Controller space)
> > and bus[0x1-0xff] on NXP SoCs with PCIe LS controller.
> > Add PciSegmentLib for PCIe LS controller.
> >
> > For config transactions for Bus0:
> > - Config transaction address = PCIe controller address + offset
> >
> > For config transactions for Bus[0x1-0xff]:
> > - PCIe IP requires target BDF to be written at bit[31:16] of PCIe
> > type0/type1 outbound window.
> > - Config transaction address = PCIe config space address + offset
> >
> > Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
> > Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> > ---
> > .../NXP/Library/PciSegmentLib/PciSegmentLib.inf | 32 ++
> > Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 612
> +++++++++++++++++++++
> > 2 files changed, 644 insertions(+)
> > create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> >
> > diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > new file mode 100755
> > index 000000000000..a36e79239b33
> > --- /dev/null
> > +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > @@ -0,0 +1,32 @@
> > +## @file
> > +# PCI Segment Library for NXP SoCs with multiple RCs # # Copyright
> > +2018-2020 NXP # # SPDX-License-Identifier: BSD-2-Clause-Patent ##
> > +
> > +[Defines]
> > + INF_VERSION = 0x0001001A
> > + BASE_NAME = PciSegmentLib
> > + FILE_GUID = c9f59261-5a60-4a4c-82f6-1f520442e100
> > + MODULE_TYPE = DXE_DRIVER
>
> Can this be BASE ?
>
No, we need constructor function PciSegLibInit() which requires it to be DXE_DRIVER.
> > + VERSION_STRING = 1.0
> > + LIBRARY_CLASS = PciSegmentLib|DXE_DRIVER
> > + CONSTRUCTOR = PciSegLibInit
> > +
> > +[Sources]
> > + PciSegmentLib.c
> > +
> > +[Packages]
> > + MdePkg/MdePkg.dec
> > + Silicon/NXP/NxpQoriqLs.dec
> > +
> > +[LibraryClasses]
> > + BaseLib
> > + DebugLib
> > + IoLib
> > + PcdLib
> > +
> > +[FixedPcd]
> > + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
> > diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > new file mode 100755
> > index 000000000000..ecd36971b753
> > --- /dev/null
> > +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > @@ -0,0 +1,612 @@
> > +/** @file
> > + PCI Segment Library for NXP SoCs with multiple RCs
> > +
> > + Copyright 2018-2020 NXP
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include <PiDxe.h>
> > +#include <Base.h> #include <IndustryStandard/Pci22.h> #include
> > +<Library/PciSegmentLib.h> #include <Library/BaseLib.h> #include
> > +<Library/DebugLib.h> #include <Library/IoLib.h> #include
> > +<Library/MemoryAllocationLib.h> #include <Library/PcdLib.h> #include
> > +<Pcie.h>
> > +
> > +typedef enum {
> > + PciCfgWidthUint8 = 0,
> > + PciCfgWidthUint16,
> > + PciCfgWidthUint32,
> > + PciCfgWidthMax
> > +} PCI_CFG_WIDTH;
> > +
> > +/**
> > + Assert the validity of a PCI Segment address.
> > + A valid PCI Segment address should not contain 1's in bits 28..31
> > +and 48..63
> > +
> > + @param A The address to validate.
> > + @param M Additional bits to assert to be zero.
> > +
> > +**/
> > +#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
> > + ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
> > +
> > +STATIC
> > +UINT64
> > +PciLsCfgTarget (
> > + IN EFI_PHYSICAL_ADDRESS Dbi,
> > + IN UINT64 Address,
> > + IN UINT16 Segment,
> > + IN UINT8 Bus,
> > + IN UINT16 Offset
> > + )
> > +{
> > + UINT32 Target;
> > +
> > + Target = ((((Address >> 20) & 0xFF) << 24) |
> > + (((Address >> 15) & 0x1F) << 19) |
> > + (((Address >> 12) & 0x7) << 16));
>
> You can drop the outer () here
>
OK
> > +
> > + if (Bus > 1) {
> > + MmioWrite32 ((UINTN)Dbi + IATU_VIEWPORT_OFF,
> > + IATU_VIEWPORT_OUTBOUND | IATU_REGION_INDEX1); } else {
> > + MmioWrite32 ((UINTN)Dbi + IATU_VIEWPORT_OFF,
> > + IATU_VIEWPORT_OUTBOUND | IATU_REGION_INDEX0); }
> > +
> > + MmioWrite32 ((UINTN)Dbi +
> IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0,
> > + Target);
> > +
> > + if (Bus > 1) {
> > + return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment +
> > + SEG_CFG_SIZE + Offset; } else {
> > + return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment + Offset;
> > + }
>
> OK, so this is the version for the IP that does not implement ECAM shift, right?
No, PCIe Layerscape support both mechanism ECAM & Non-ECAM (with exception of bus 0).
PCIe LSGen4 controller does not support ECAM at all , which is part of patch #11
>
> > +}
> > +
> > +/**
> > + Function to return PCIe Physical Address(PCIe view) or Controller
> > + Address(CPU view) for different RCs
> > +
> > + @param Address Address passed from bus layer.
> > + @param Segment Segment number for Root Complex.
> > + @param Offset Config space register offset.
> > + @param Bus PCIe Bus number.
> > +
> > + @return Return PCIe CPU or Controller address.
> > +
> > +**/
> > +STATIC
> > +UINT64
> > +PciLsGetConfigBase (
> > + IN UINT64 Address,
> > + IN UINT16 Segment,
> > + IN UINT16 Offset,
> > + IN UINT8 Bus
> > + )
> > +{
> > + UINT32 CfgAddr;
> > +
> > + CfgAddr = (UINT16)Offset;
> > + if (Bus) {
>
> Please use Bus > 0 here
OK
>
> > + return PciLsCfgTarget (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF *
> > +Segment, Address, Segment, Bus, Offset);
> > + } else {
> > + return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
> > + }
> > +}
> > +
> > +/**
> > + Function to return PCIe Physical Address(PCIe view) or Controller
> > + Address(CPU view) for different RCs
> > +
> > + @param Address Address passed from bus layer.
> > + @param Segment Segment number for Root Complex.
> > + @param Offset Config space register offset.
> > +
> > + @return Return PCIe CPU or Controller address.
> > +
> > +**/
> > +STATIC
> > +UINT64
> > +PciSegmentLibGetConfigBase (
> > + IN UINT64 Address,
> > + IN UINT16 Segment,
> > + IN UINT16 Offset
> > + )
> > +{
> > + UINT8 Bus;
> > +
> > + Bus = ((UINT32)Address >> 20) & 0xff;
> > + return PciLsGetConfigBase (Address, Segment, Offset, Bus); }
> > +
> > +/**
> > + Internal worker function to read a PCI configuration register.
> > +
> > + @param Address The address that encodes the Segment, PCI Bus, Device,
> > + Function and Register.
> > + @param Width The width of data to read
> > +
> > + @return The value read from the PCI configuration register.
> > +
> > +**/
> > +STATIC
> > +UINT32
> > +PciSegmentLibReadWorker (
> > + IN UINT64 Address,
> > + IN PCI_CFG_WIDTH Width
> > + )
> > +{
> > + UINT64 Base;
> > + UINT16 Offset;
> > + UINT16 Segment;
> > +
> > + Segment = (Address >> 32);
> > + Offset = (Address & 0xfff );
> > +
> > + Base = PciSegmentLibGetConfigBase (Address, Segment, Offset);
> > +
> > + // ignore devices > 0 on bus 0
> > + if ((Address & 0xff00000) == 0 && (Address & 0xf8000) != 0) {
> > + return MAX_UINT32;
> > + }
> > +
> > + // ignore device > 0 on bus 1
> > + if ((Address & 0xfe00000) == 0 && (Address & 0xf8000) != 0) {
> > + return MAX_UINT32;
> > + }
> > +
> > + switch (Width) {
> > + case PciCfgWidthUint8:
> > + return MmioRead8 (Base);
> > + case PciCfgWidthUint16:
> > + return MmioRead16 (Base);
> > + case PciCfgWidthUint32:
> > + return MmioRead32 (Base);
> > + default:
> > + ASSERT (FALSE);
> > + }
> > +
> > + return CHAR_NULL;
> > +}
> > +
> > +/**
> > + Internal worker function to writes a PCI configuration register.
> > +
> > + @param Address The address that encodes the Segment, PCI Bus, Device,
> > + Function and Register.
> > + @param Width The width of data to write
> > + @param Data The value to write.
> > +
> > + @return The value written to the PCI configuration register.
> > +
> > +**/
> > +STATIC
> > +UINT32
> > +PciSegmentLibWriteWorker (
> > + IN UINT64 Address,
> > + IN PCI_CFG_WIDTH Width,
> > + IN UINT32 Data
> > + )
> > +{
> > + UINT64 Base;
> > + UINT32 Offset;
> > + UINT16 Segment;
> > +
> > + Segment = (Address >> 32);
> > + Offset = (Address & 0xfff );
> > +
> > + Base = PciSegmentLibGetConfigBase (Address, Segment, Offset);
> > +
> > + // ignore devices > 0 on bus 0
> > + if ((Address & 0xff00000) == 0 && (Address & 0xf8000) != 0) {
> > + return Data;
> > + }
> > +
> > + // ignore device > 0 on bus 1
> > + if ((Address & 0xfe00000) == 0 && (Address & 0xf8000) != 0) {
> > + return MAX_UINT32;
> > + }
> > +
> > + switch (Width) {
> > + case PciCfgWidthUint8:
> > + MmioWrite8 (Base , Data);
> > + break;
> > + case PciCfgWidthUint16:
> > + MmioWrite16 (Base , Data);
> > + break;
> > + case PciCfgWidthUint32:
> > + MmioWrite32 (Base , Data);
> > + break;
> > + default:
> > + ASSERT (FALSE);
> > + }
> > +
> > + return Data;
> > +}
> > +
> > +/**
> > + Register a PCI device so PCI configuration registers may be
> > +accessed after
> > + SetVirtualAddressMap().
> > +
> > + If any reserved bits in Address are set, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> > + Function and Register.
> > +
> > + @retval RETURN_SUCCESS The PCI device was registered for runtime
> access.
> > + @retval RETURN_UNSUPPORTED An attempt was made to call this
> function
> > + after ExitBootServices().
> > + @retval RETURN_UNSUPPORTED The resources required to access the
> PCI device
> > + at runtime could not be mapped.
> > + @retval RETURN_OUT_OF_RESOURCES There are not enough resources
> available to
> > + complete the registration.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +PciSegmentRegisterForRuntimeAccess (
> > + IN UINTN Address
> > + )
> > +{
> > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> > + return RETURN_UNSUPPORTED;
> > +}
> > +
> > +/**
> > + Reads an 8-bit PCI configuration register.
> > +
> > + Reads and returns the 8-bit PCI configuration register specified by Address.
> > +
> > + If any reserved bits in Address are set, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Segment, Bus, Device,
> Function,
> > + and Register.
> > +
> > + @return The 8-bit PCI configuration register specified by Address.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciSegmentRead8 (
> > + IN UINT64 Address
> > + )
> > +{
> > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> > +
> > + return (UINT8) PciSegmentLibReadWorker (Address, PciCfgWidthUint8);
> > +}
> > +
> > +/**
> > + Writes an 8-bit PCI configuration register.
> > +
> > + Writes the 8-bit PCI configuration register specified by Address with the
> value specified by Value.
> > + Value is returned. This function must guarantee that all PCI read and write
> operations are serialized.
> > +
> > + If any reserved bits in Address are set, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Segment, Bus, Device,
> Function, and Register.
> > + @param Value The value to write.
> > +
> > + @return The value written to the PCI configuration register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciSegmentWrite8 (
> > + IN UINT64 Address,
> > + IN UINT8 Value
> > + )
> > +{
> > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> > +
> > + return (UINT8) PciSegmentLibWriteWorker (Address, PciCfgWidthUint8,
> > +Value); }
> > +
> > +/**
> > + Reads a 16-bit PCI configuration register.
> > +
> > + Reads and returns the 16-bit PCI configuration register specified by Address.
> > +
> > + If any reserved bits in Address are set, then ASSERT().
> > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Segment, Bus, Device,
> Function, and Register.
> > +
> > + @return The 16-bit PCI configuration register specified by Address.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciSegmentRead16 (
> > + IN UINT64 Address
> > + )
> > +{
> > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
> > +
> > + return (UINT16) PciSegmentLibReadWorker (Address,
> > +PciCfgWidthUint16); }
> > +
> > +/**
> > + Writes a 16-bit PCI configuration register.
> > +
> > + Writes the 16-bit PCI configuration register specified by Address
> > + with the value specified by Value.
> > +
> > + Value is returned.
> > +
> > + If any reserved bits in Address are set, then ASSERT().
> > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Segment, Bus, Device,
> Function, and Register.
> > + @param Value The value to write.
> > +
> > + @return The parameter of Value.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciSegmentWrite16 (
> > + IN UINT64 Address,
> > + IN UINT16 Value
> > + )
> > +{
> > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
> > +
> > + return (UINT16) PciSegmentLibWriteWorker (Address,
> > +PciCfgWidthUint16, Value); }
> > +
> > +/**
> > + Reads a 32-bit PCI configuration register.
> > +
> > + Reads and returns the 32-bit PCI configuration register specified by Address.
> > +
> > + If any reserved bits in Address are set, then ASSERT().
> > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Segment, Bus, Device,
> Function,
> > + and Register.
> > +
> > + @return The 32-bit PCI configuration register specified by Address.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciSegmentRead32 (
> > + IN UINT64 Address
> > + )
> > +{
> > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
> > +
> > + return PciSegmentLibReadWorker (Address, PciCfgWidthUint32); }
> > +
> > +/**
> > + Writes a 32-bit PCI configuration register.
> > +
> > + Writes the 32-bit PCI configuration register specified by Address
> > + with the value specified by Value.
> > +
> > + Value is returned.
> > +
> > + If any reserved bits in Address are set, then ASSERT().
> > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Segment, Bus, Device,
> > + Function, and Register.
> > + @param Value The value to write.
> > +
> > + @return The parameter of Value.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciSegmentWrite32 (
> > + IN UINT64 Address,
> > + IN UINT32 Value
> > + )
> > +{
> > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
> > +
> > + return PciSegmentLibWriteWorker (Address, PciCfgWidthUint32,
> > +Value); }
> > +
> > +/**
> > + Reads a range of PCI configuration registers into a caller supplied buffer.
> > +
> > + Reads the range of PCI configuration registers specified by
> > + StartAddress and Size into the buffer specified by Buffer. This
> > + function only allows the PCI configuration registers from a single
> > + PCI function to be read. Size is returned.
> > +
> > + If any reserved bits in StartAddress are set, then ASSERT().
> > + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> > + If Size > 0 and Buffer is NULL, then ASSERT().
> > +
> > + @param StartAddress The starting address that encodes the PCI Segment,
> Bus,
> > + Device, Function and Register.
> > + @param Size The size in bytes of the transfer.
> > + @param Buffer The pointer to a buffer receiving the data read.
> > +
> > + @return Size
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +PciSegmentReadBuffer (
> > + IN UINT64 StartAddress,
> > + IN UINTN Size,
> > + OUT VOID *Buffer
> > + )
> > +{
> > + UINTN ReturnValue;
> > +
> > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0); ASSERT
> > + (((StartAddress & 0xFFF) + Size) <= SIZE_4KB);
> > +
> > + if (Size == 0) {
> > + return Size;
> > + }
> > +
> > + ASSERT (Buffer != NULL);
> > +
> > + //
> > + // Save Size for return
> > + //
> > + ReturnValue = Size;
> > +
> > + if ((StartAddress & BIT0) != 0) {
> > + //
> > + // Read a byte if StartAddress is byte aligned
> > + //
> > + *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
> > + StartAddress += sizeof (UINT8);
> > + Size -= sizeof (UINT8);
> > + Buffer = (UINT8*)Buffer + BIT0;
> > + }
> > +
> > + if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
> > + //
> > + // Read a word if StartAddress is word aligned
> > + //
> > + WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
> > + StartAddress += sizeof (UINT16);
> > + Size -= sizeof (UINT16);
> > + Buffer = (UINT16*)Buffer + BIT0;
> > + }
> > +
> > + while (Size >= sizeof (UINT32)) {
> > + //
> > + // Read as many double words as possible
> > + //
> > + WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));
> > + StartAddress += sizeof (UINT32);
> > + Size -= sizeof (UINT32);
> > + Buffer = (UINT32*)Buffer + BIT0;
> > + }
> > +
> > + if (Size >= sizeof (UINT16)) {
> > + //
> > + // Read the last remaining word if exist
> > + //
> > + WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
> > + StartAddress += sizeof (UINT16);
> > + Size -= sizeof (UINT16);
> > + Buffer = (UINT16*)Buffer + BIT0;
> > + }
> > +
> > + if (Size >= sizeof (UINT8)) {
> > + //
> > + // Read the last remaining byte if exist
> > + //
> > + *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress); }
> > +
> > + return ReturnValue;
> > +}
> > +
> > +
> > +/**
> > + Copies the data in a caller supplied buffer to a specified range of
> > +PCI
> > + configuration space.
> > +
> > + Writes the range of PCI configuration registers specified by
> > + StartAddress and Size from the buffer specified by Buffer. This
> > + function only allows the PCI configuration registers from a single
> > + PCI function to be written. Size is returned.
> > +
> > + If any reserved bits in StartAddress are set, then ASSERT().
> > + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> > + If Size > 0 and Buffer is NULL, then ASSERT().
> > +
> > + @param StartAddress The starting address that encodes the PCI Segment,
> Bus,
> > + Device, Function and Register.
> > + @param Size The size in bytes of the transfer.
> > + @param Buffer The pointer to a buffer containing the data to write.
> > +
> > + @return The parameter of Size.
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +PciSegmentWriteBuffer (
> > + IN UINT64 StartAddress,
> > + IN UINTN Size,
> > + IN VOID *Buffer
> > + )
> > +{
> > + UINTN ReturnValue;
> > +
> > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0); ASSERT
> > + (((StartAddress & 0xFFF) + Size) <= SIZE_4KB);
> > +
> > + if (Size == 0) {
> > + return Size;
> > + }
> > +
> > + ASSERT (Buffer != NULL);
> > +
> > + //
> > + // Save Size for return
> > + //
> > + ReturnValue = Size;
> > +
> > + if ((StartAddress & BIT0) != 0) {
> > + //
> > + // Write a byte if StartAddress is byte aligned
> > + //
> > + PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);
> > + StartAddress += sizeof (UINT8);
> > + Size -= sizeof (UINT8);
> > + Buffer = (UINT8*)Buffer + BIT0;
> > + }
> > +
> > + if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
> > + //
> > + // Write a word if StartAddress is word aligned
> > + //
> > + PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
> > + StartAddress += sizeof (UINT16);
> > + Size -= sizeof (UINT16);
> > + Buffer = (UINT16*)Buffer + BIT0;
> > + }
> > +
> > + while (Size >= sizeof (UINT32)) {
> > + //
> > + // Write as many double words as possible
> > + //
> > + PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));
> > + StartAddress += sizeof (UINT32);
> > + Size -= sizeof (UINT32);
> > + Buffer = (UINT32*)Buffer + BIT0;
> > + }
> > +
> > + if (Size >= sizeof (UINT16)) {
> > + //
> > + // Write the last remaining word if exist
> > + //
> > + PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
> > + StartAddress += sizeof (UINT16);
> > + Size -= sizeof (UINT16);
> > + Buffer = (UINT16*)Buffer + BIT0;
> > + }
> > +
> > + if (Size >= sizeof (UINT8)) {
> > + //
> > + // Write the last remaining byte if exist
> > + //
> > + PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer); }
> > +
> > + return ReturnValue;
> > +}
> > +
> > +EFI_STATUS
> > +PciSegLibInit (
> > + IN EFI_HANDLE ImageHandle,
> > + IN EFI_SYSTEM_TABLE *SystemTable
> > + )
> > +{
> > + return EFI_SUCCESS;
> > +}
> >
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 10/16] Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS Controller
2020-05-22 9:36 ` Ard Biesheuvel
@ 2020-05-24 18:32 ` Wasim Khan (OSS)
0 siblings, 0 replies; 42+ messages in thread
From: Wasim Khan (OSS) @ 2020-05-24 18:32 UTC (permalink / raw)
To: Ard Biesheuvel, Wasim Khan (OSS), devel@edk2.groups.io,
Meenakshi Aggarwal, Vabhav Sharma, Varun Sethi, leif@nuviainc.com,
jon@solid-run.com
> -----Original Message-----
> From: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Sent: Friday, May 22, 2020 3:06 PM
> To: Wasim Khan (OSS) <wasim.khan@oss.nxp.com>; devel@edk2.groups.io;
> Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>; Vabhav Sharma
> <vabhav.sharma@nxp.com>; Varun Sethi <V.Sethi@nxp.com>;
> leif@nuviainc.com; jon@solid-run.com
> Cc: Wasim Khan <wasim.khan@nxp.com>
> Subject: Re: [PATCH edk2-platforms 10/16] Silicon/NXP: PciSegmentLib: Add
> ECAM config support for PCIe LS Controller
>
> On 5/22/20 1:02 AM, Wasim Khan wrote:
> > From: Wasim Khan <wasim.khan@nxp.com>
> >
> > PCIe Layerscape controller can be enabled for ECAM style configuration
> > access using CFG SHIFT Feature.
> >
> > Check for PcdPciCfgShiftEnable to decide the configuration access
> > scheme to be used with PCIe LS controller.
> >
> > Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> > ---
> > Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf | 3 +++
> > Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 20
> ++++++++++++++++----
> > 2 files changed, 19 insertions(+), 4 deletions(-)
> >
> > diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > index a36e79239b33..936213dc8a9d 100755
> > --- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > @@ -30,3 +30,6 @@ [LibraryClasses]
> >
> > [FixedPcd]
> > gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
> > +
> > +[Pcd]
> > + gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
> > diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > index ecd36971b753..552a425c6832 100755
> > --- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > @@ -34,6 +34,8 @@ typedef enum {
> > #define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
> > ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
> >
> > +static BOOLEAN CfgShiftEnable;
> > +
>
> This is a compile time constant, right? Please try to avoid using runtime
> read/write variables in that case, since it defeats the compiler's ability to
> remove code that is never executed.
We are initializing CfgShiftEnable with PcdPciCfgShiftEnable (dynamic PCD).
We indent to enable/disable this support at run time so that without recompiling the firmware, we can turn on/off this feature.
>
>
> > STATIC
> > UINT64
> > PciLsCfgTarget (
> > @@ -88,11 +90,20 @@ PciLsGetConfigBase (
> > {
> > UINT32 CfgAddr;
> >
> > - CfgAddr = (UINT16)Offset;
> > - if (Bus) {
> > - return PciLsCfgTarget (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF *
> Segment, Address, Segment, Bus, Offset);
> > + if (CfgShiftEnable) {
> > + CfgAddr = (UINT32)Address;
> > + if (Bus) {
> > + return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment +
> CfgAddr;
> > + } else {
> > + return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
> > + }
> > } else {
> > - return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
> > + CfgAddr = (UINT16)Offset;
> > + if (Bus) {
> > + return PciLsCfgTarget (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF *
> Segment, Address, Segment, Bus, Offset);
> > + } else {
> > + return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
> > + }
> > }
> > }
> >
> > @@ -608,5 +619,6 @@ PciSegLibInit (
> > IN EFI_SYSTEM_TABLE *SystemTable
> > )
> > {
> > + CfgShiftEnable = CFG_SHIFT_ENABLE;
> > return EFI_SUCCESS;
> > }
> >
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 11/16] Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller
2020-05-22 9:38 ` Ard Biesheuvel
@ 2020-05-24 18:32 ` Wasim Khan (OSS)
0 siblings, 0 replies; 42+ messages in thread
From: Wasim Khan (OSS) @ 2020-05-24 18:32 UTC (permalink / raw)
To: Ard Biesheuvel, Wasim Khan (OSS), devel@edk2.groups.io,
Meenakshi Aggarwal, Vabhav Sharma, Varun Sethi, leif@nuviainc.com,
jon@solid-run.com
> -----Original Message-----
> From: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Sent: Friday, May 22, 2020 3:08 PM
> To: Wasim Khan (OSS) <wasim.khan@oss.nxp.com>; devel@edk2.groups.io;
> Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>; Vabhav Sharma
> <vabhav.sharma@nxp.com>; Varun Sethi <V.Sethi@nxp.com>;
> leif@nuviainc.com; jon@solid-run.com
> Cc: Wasim Khan <wasim.khan@nxp.com>
> Subject: Re: [PATCH edk2-platforms 11/16] Silicon/NXP: PciSegmentLib: Add
> support PCIe LsGen4 Controller
>
> On 5/22/20 1:02 AM, Wasim Khan wrote:
> > From: Wasim Khan <wasim.khan@nxp.com>
> >
> > PCIe Layerscape Gen4 controller is not ECAM complaint and have
>
> compliant
OK
>
> > different PCI config space region for bus 0 (Controller space) and
> > bus[0x1-0xff] on NXP SoCs.
> >
> > For config transactions for Bus0:
> > - Config transaction address = PCIe controller address + offset
> >
> > For config transactions for Bus[0x1-0xff]:
> > - PCIe IP requires target BDF to be written at bit[31:16] of PCIe
> > outbound configuration window.
> >
> > PCIe LsGen4 controller uses paging mechanism to access registers.
> > To access PCIe CCSR registers which are above 3KB offset, page number
> > must be set in Bridge Control Register.
> >
> > Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
> > Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> > ---
> > .../NXP/Library/PciSegmentLib/PciSegmentLib.inf | 1 +
> > Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 60
> +++++++++++++++++++++-
> > 2 files changed, 60 insertions(+), 1 deletion(-)
> >
> > diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > index 936213dc8a9d..d6d7ea6e3b6b 100755
> > --- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > @@ -33,3 +33,4 @@ [FixedPcd]
> >
> > [Pcd]
> > gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable
> > + gNxpQoriqLsTokenSpaceGuid.PcdPciLsGen4Ctrl
> > diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > index 552a425c6832..02a1525ef308 100755
> > --- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > @@ -35,6 +35,58 @@ typedef enum {
> > ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
> >
> > static BOOLEAN CfgShiftEnable;
> > +static BOOLEAN PciLsGen4Ctrl;
> > +
>
> Another compile time constant?
We are initializing PciLsGen4Ctrl with PcdPciLsGen4Ctrl (dynamic PCD).
Based on SoC version, PcdPciLsGen4Ctrl will be set to true for LSGen4 controller (default false).
Support to update these PCDs will come later (Actual use case will be with LX2160 SoC).
>
> > +STATIC
> > +VOID
> > +PcieCfgSetTarget (
> > + IN EFI_PHYSICAL_ADDRESS Dbi,
> > + IN UINT32 Target)
> > +{
> > + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_L(0), Target);
> > + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_H(0), 0); }
> > +
> > +/**
> > + Function to return PCIe Physical Address(PCIe view) or Controller
> > + Address(CPU view) for NXP Layerscape Gen4 SoC
> > +
> > + @param Address Address passed from bus layer.
> > + @param Segment Segment number for Root Complex.
> > + @param Offset Config space register offset.
> > + @param Bus PCIe Bus number.
> > +
> > + @return Return PCIe CPU or Controller address.
> > +
> > +**/
> > +STATIC
> > +UINT64
> > +PciLsGen4GetConfigBase (
> > + IN UINT64 Address,
> > + IN UINT16 Segment,
> > + IN UINT16 Offset,
> > + IN UINT8 Bus
> > + )
> > +{
> > + UINT32 Target;
> > +
> > + if (Bus) {
>
> Bus > 0
>
> > + Target = ((((Address >> 20) & 0xFF) << 24) |
> > + (((Address >> 15) & 0x1F) << 19) |
> > + (((Address >> 12) & 0x7) << 16));
>
> Drop the outer ()
>
> > +
> > + PcieCfgSetTarget ((PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF* Segment),
> Target);
> > + return PCI_SEG0_MMIO_MEMBASE + Offset + PCI_BASE_DIFF * Segment;
> > + } else {
> > + if (Offset < INDIRECT_ADDR_BNDRY) {
> > + PciLsGen4SetPg (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment,
> 0);
> > + return (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + Offset);
> > + }
> > + PciLsGen4SetPg (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment,
> OFFSET_TO_PAGE_IDX (Offset));
> > + Offset = OFFSET_TO_PAGE_ADDR (Offset);
> > + return (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment +
> > +Offset);
> > + }
> > +}
> >
> > STATIC
> > UINT64
> > @@ -129,7 +181,12 @@ PciSegmentLibGetConfigBase (
> > UINT8 Bus;
> >
> > Bus = ((UINT32)Address >> 20) & 0xff;
> > - return PciLsGetConfigBase (Address, Segment, Offset, Bus);
> > +
> > + if (PciLsGen4Ctrl) {
> > + return PciLsGen4GetConfigBase (Address, Segment, Offset, Bus); }
> > + else {
> > + return PciLsGetConfigBase (Address, Segment, Offset, Bus); }
> > }
> >
> > /**
> > @@ -620,5 +677,6 @@ PciSegLibInit (
> > )
> > {
> > CfgShiftEnable = CFG_SHIFT_ENABLE;
> > + PciLsGen4Ctrl = PCI_LS_GEN4_CTRL;
> > return EFI_SUCCESS;
> > }
> >
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 12/16] Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264
2020-05-22 9:39 ` Ard Biesheuvel
@ 2020-05-24 18:32 ` Wasim Khan (OSS)
0 siblings, 0 replies; 42+ messages in thread
From: Wasim Khan (OSS) @ 2020-05-24 18:32 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: devel@edk2.groups.io, Meenakshi Aggarwal, Vabhav Sharma,
Varun Sethi, leif@nuviainc.com, jon@solid-run.com
> -----Original Message-----
> From: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Sent: Friday, May 22, 2020 3:10 PM
> To: Wasim Khan (OSS) <wasim.khan@oss.nxp.com>; devel@edk2.groups.io;
> Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>; Vabhav Sharma
> <vabhav.sharma@nxp.com>; Varun Sethi <V.Sethi@nxp.com>;
> leif@nuviainc.com; jon@solid-run.com
> Cc: Wasim Khan <wasim.khan@nxp.com>
> Subject: Re: [PATCH edk2-platforms 12/16] Silicon/NXP: PciSegmentLib:
> LsGen4Ctrl: Add Workaround for A-011264
>
> On 5/22/20 1:02 AM, Wasim Khan wrote:
> > From: Wasim Khan <wasim.khan@nxp.com>
> >
> > With PCIe LsGen4 controller, clearing the Bus Master Enable bit in
> > Command register blocks all outbound transactions to be sent out in RC
> > mode.
> >
> > According to PCI Express base specification, the Command register’s
> > Bus Master Enable bit of a PCI Express RC controller can only control
> > the forwarding of memory requests received at its root port in the
> > upstream direction. In other words, clearing the Bus Master Enable bit
> > must not block all outbound transactions to be sent out toward RC’s
> > downstream devices. Due to this erratum, when the Command register’s
> > Bus Master Enable bit is cleared, all the outbound transactions from
> > the device’s internal bus masters, including but not limited to
> > configuration read and write transactions, are terminated with the
> > slave error (SLVERR) response status on the PCI Express RC
> > controller’s internal AXI bus interface.
> >
> > Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> > ---
> > Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 17
> +++++++++++++++++
> > 1 file changed, 17 insertions(+)
> >
> > diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > index 02a1525ef308..c3bc14820ea5 100755
> > --- a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > @@ -39,6 +39,21 @@ static BOOLEAN PciLsGen4Ctrl;
> >
> > STATIC
> > VOID
> > +PciLsGen4SetBusMaster (
> > + IN EFI_PHYSICAL_ADDRESS Dbi
> > + )
> > +{
> > + UINT32 Val;
> > +
> > + /* Make sure the Master Enable bit not cleared */
>
> Please use // style comments
OK
>
> > + Val = PciLsGen4Read32 ((UINTN)Dbi, PCI_COMMAND_OFFSET);
> > + if (!(Val & EFI_PCI_COMMAND_BUS_MASTER)) {
> > + PciLsGen4Write32 ((UINTN)Dbi, PCI_COMMAND_OFFSET, Val |
> > +EFI_PCI_COMMAND_BUS_MASTER);
> > + }
> > +}
> > +
> > +STATIC
> > +VOID
> > PcieCfgSetTarget (
> > IN EFI_PHYSICAL_ADDRESS Dbi,
> > IN UINT32 Target)
> > @@ -71,6 +86,8 @@ PciLsGen4GetConfigBase (
> > UINT32 Target;
> >
> > if (Bus) {
> > + PciLsGen4SetBusMaster (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF*
> > + Segment);
> > +
>
> Can't we just set this once and never touch it? Or is that tricky?
Yes, it's a bit tricky . I checked that we are getting multiple calls when BusMaster is zero.
As per the Errata, we must ensure that Bus Master is never zero so I am always checking the Bus Master bit , and set to 1 , when zero.
>
>
> > Target = ((((Address >> 20) & 0xFF) << 24) |
> > (((Address >> 15) & 0x1F) << 19) |
> > (((Address >> 12) & 0x7) << 16));
> >
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 00/16] Add PCIe Support
2020-05-22 10:58 ` Leif Lindholm
@ 2020-05-24 18:32 ` Wasim Khan (OSS)
0 siblings, 0 replies; 42+ messages in thread
From: Wasim Khan (OSS) @ 2020-05-24 18:32 UTC (permalink / raw)
To: Leif Lindholm, Ard Biesheuvel
Cc: Wasim Khan (OSS), devel@edk2.groups.io, Meenakshi Aggarwal,
Vabhav Sharma, Varun Sethi, jon@solid-run.com
> -----Original Message-----
> From: Leif Lindholm <leif@nuviainc.com>
> Sent: Friday, May 22, 2020 4:29 PM
> To: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Cc: Wasim Khan (OSS) <wasim.khan@oss.nxp.com>; devel@edk2.groups.io;
> Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>; Vabhav Sharma
> <vabhav.sharma@nxp.com>; Varun Sethi <V.Sethi@nxp.com>; jon@solid-
> run.com; Wasim Khan <wasim.khan@nxp.com>
> Subject: Re: [PATCH edk2-platforms 00/16] Add PCIe Support
>
> On Fri, May 22, 2020 at 11:46:07 +0200, Ard Biesheuvel wrote:
> > On 5/22/20 1:02 AM, Wasim Khan wrote:
> > > From: Wasim Khan <wasim.khan@nxp.com>
> > >
> > > Add PCIe Support for NXP Layerscape SoC which supports different
> > > PCIe controllers.
> > > Use generic PCIe drivers and wire up PciHostBridgeLib, PciSegmentLib
> > > and PciCpuIo2Dxe driver for controller specific implementation.
> > >
> >
> > Thanks. This is looking good. Please take a look at the feedback, and
> > give others some time to respond as well.
> >
Thank you so much Ard for your review and comments.
I have incorporated all your comments and waiting to push the V2 once I close on the some open items.
> > In the meantime, I think we can simply merge #14 and #16 right away
> > (unless Leif has any objections)
>
> (Looking at those two out of order.)
> 16, sure.
> 14 - is there any reason to do so before there is PCI to connect network devices
> through?
>
> /
> Leif
>
> >
> > > Wasim Khan (16):
> > > Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs.
> > > Silicon/NXP: LS1043A: Define PCIe related PCDs
> > > Silicon/NXP: Implement PciHostBridgeLib support
> > > Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS
> > > Ctrl
> > > Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU
> > > Windows
> > > Silicon/NXP: PciHostBridgeLib: add Workaround for A-011451
> > > Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows
> > > Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows
> > > Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller
> > > Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS
> > > Controller
> > > Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller
> > > Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264
> > > Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver
> > > Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg
> > > Platform/NXP: LS1043aRdbPkg: Enable PCIE support
> > > Platform/NXP: LS1043aRdbPkg : Increase fv image size
> > >
> > > Silicon/NXP/NxpQoriqLs.dec | 13 +
> > > Silicon/NXP/LS1043A/LS1043A.dsc.inc | 8 +
> > > Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc | 20 +
> > > Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 20 +-
> > > Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf | 40 +
> > > .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 45 ++
> > > .../NXP/Library/PciSegmentLib/PciSegmentLib.inf | 36 +
> > > Silicon/NXP/Include/Pcie.h | 231 ++++++
> > > Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c | 628
> +++++++++++++++
> > > .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 842
> +++++++++++++++++++++
> > > Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 699
> +++++++++++++++++
> > > 11 files changed, 2579 insertions(+), 3 deletions(-)
> > > create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
> > > create mode 100644
> Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> > > create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > > create mode 100755 Silicon/NXP/Include/Pcie.h
> > > create mode 100755 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c
> > > create mode 100644
> Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c
> > > create mode 100755
> > > Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > >
> >
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 09/16] Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller
2020-05-24 18:32 ` Wasim Khan (OSS)
@ 2020-05-25 4:30 ` Jon Nettleton
2020-05-25 15:21 ` Wasim Khan (OSS)
0 siblings, 1 reply; 42+ messages in thread
From: Jon Nettleton @ 2020-05-25 4:30 UTC (permalink / raw)
To: Wasim Khan (OSS)
Cc: Ard Biesheuvel, devel@edk2.groups.io, Meenakshi Aggarwal,
Vabhav Sharma, Varun Sethi, leif@nuviainc.com
On Sun, May 24, 2020 at 8:32 PM Wasim Khan (OSS) <wasim.khan@oss.nxp.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Ard Biesheuvel <ard.biesheuvel@arm.com>
> > Sent: Friday, May 22, 2020 3:00 PM
> > To: Wasim Khan (OSS) <wasim.khan@oss.nxp.com>; devel@edk2.groups.io;
> > Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>; Vabhav Sharma
> > <vabhav.sharma@nxp.com>; Varun Sethi <V.Sethi@nxp.com>;
> > leif@nuviainc.com; jon@solid-run.com
> > Cc: Wasim Khan <wasim.khan@nxp.com>
> > Subject: Re: [PATCH edk2-platforms 09/16] Silicon/NXP: Implement
> > PciSegmentLib for PCIe Layerscape Controller
> >
> > On 5/22/20 1:02 AM, Wasim Khan wrote:
> > > From: Wasim Khan <wasim.khan@nxp.com>
> > >
> > > We have different PCI config space region for bus 0 (Controller space)
> > > and bus[0x1-0xff] on NXP SoCs with PCIe LS controller.
> > > Add PciSegmentLib for PCIe LS controller.
> > >
> > > For config transactions for Bus0:
> > > - Config transaction address = PCIe controller address + offset
> > >
> > > For config transactions for Bus[0x1-0xff]:
> > > - PCIe IP requires target BDF to be written at bit[31:16] of PCIe
> > > type0/type1 outbound window.
> > > - Config transaction address = PCIe config space address + offset
> > >
> > > Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
> > > Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> > > ---
> > > .../NXP/Library/PciSegmentLib/PciSegmentLib.inf | 32 ++
> > > Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 612
> > +++++++++++++++++++++
> > > 2 files changed, 644 insertions(+)
> > > create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > > create mode 100755 Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > >
> > > diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > > b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > > new file mode 100755
> > > index 000000000000..a36e79239b33
> > > --- /dev/null
> > > +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > > @@ -0,0 +1,32 @@
> > > +## @file
> > > +# PCI Segment Library for NXP SoCs with multiple RCs # # Copyright
> > > +2018-2020 NXP # # SPDX-License-Identifier: BSD-2-Clause-Patent ##
> > > +
> > > +[Defines]
> > > + INF_VERSION = 0x0001001A
> > > + BASE_NAME = PciSegmentLib
> > > + FILE_GUID = c9f59261-5a60-4a4c-82f6-1f520442e100
> > > + MODULE_TYPE = DXE_DRIVER
> >
> > Can this be BASE ?
> >
>
> No, we need constructor function PciSegLibInit() which requires it to be DXE_DRIVER.
>
> > > + VERSION_STRING = 1.0
> > > + LIBRARY_CLASS = PciSegmentLib|DXE_DRIVER
> > > + CONSTRUCTOR = PciSegLibInit
> > > +
> > > +[Sources]
> > > + PciSegmentLib.c
> > > +
> > > +[Packages]
> > > + MdePkg/MdePkg.dec
> > > + Silicon/NXP/NxpQoriqLs.dec
> > > +
> > > +[LibraryClasses]
> > > + BaseLib
> > > + DebugLib
> > > + IoLib
> > > + PcdLib
> > > +
> > > +[FixedPcd]
> > > + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
> > > diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > > b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > > new file mode 100755
> > > index 000000000000..ecd36971b753
> > > --- /dev/null
> > > +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > > @@ -0,0 +1,612 @@
> > > +/** @file
> > > + PCI Segment Library for NXP SoCs with multiple RCs
> > > +
> > > + Copyright 2018-2020 NXP
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include <PiDxe.h>
> > > +#include <Base.h> #include <IndustryStandard/Pci22.h> #include
> > > +<Library/PciSegmentLib.h> #include <Library/BaseLib.h> #include
> > > +<Library/DebugLib.h> #include <Library/IoLib.h> #include
> > > +<Library/MemoryAllocationLib.h> #include <Library/PcdLib.h> #include
> > > +<Pcie.h>
> > > +
> > > +typedef enum {
> > > + PciCfgWidthUint8 = 0,
> > > + PciCfgWidthUint16,
> > > + PciCfgWidthUint32,
> > > + PciCfgWidthMax
> > > +} PCI_CFG_WIDTH;
> > > +
> > > +/**
> > > + Assert the validity of a PCI Segment address.
> > > + A valid PCI Segment address should not contain 1's in bits 28..31
> > > +and 48..63
> > > +
> > > + @param A The address to validate.
> > > + @param M Additional bits to assert to be zero.
> > > +
> > > +**/
> > > +#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
> > > + ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
> > > +
> > > +STATIC
> > > +UINT64
> > > +PciLsCfgTarget (
> > > + IN EFI_PHYSICAL_ADDRESS Dbi,
> > > + IN UINT64 Address,
> > > + IN UINT16 Segment,
> > > + IN UINT8 Bus,
> > > + IN UINT16 Offset
> > > + )
> > > +{
> > > + UINT32 Target;
> > > +
> > > + Target = ((((Address >> 20) & 0xFF) << 24) |
> > > + (((Address >> 15) & 0x1F) << 19) |
> > > + (((Address >> 12) & 0x7) << 16));
> >
> > You can drop the outer () here
> >
>
> OK
>
> > > +
> > > + if (Bus > 1) {
> > > + MmioWrite32 ((UINTN)Dbi + IATU_VIEWPORT_OFF,
> > > + IATU_VIEWPORT_OUTBOUND | IATU_REGION_INDEX1); } else {
> > > + MmioWrite32 ((UINTN)Dbi + IATU_VIEWPORT_OFF,
> > > + IATU_VIEWPORT_OUTBOUND | IATU_REGION_INDEX0); }
> > > +
> > > + MmioWrite32 ((UINTN)Dbi +
> > IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0,
> > > + Target);
> > > +
> > > + if (Bus > 1) {
> > > + return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment +
> > > + SEG_CFG_SIZE + Offset; } else {
> > > + return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment + Offset;
> > > + }
> >
> > OK, so this is the version for the IP that does not implement ECAM shift, right?
>
> No, PCIe Layerscape support both mechanism ECAM & Non-ECAM (with exception of bus 0).
> PCIe LSGen4 controller does not support ECAM at all , which is part of patch #11
>
Well this isn't completely true. It doesn't support ECAM natively on
the controller, but it can be configured to represent a proper ECAM
view with the config shift model we are using on the Rev 2 silicon. I
have a functional test patch, but that shouldn't be something to hold
up this patch set. I will submit that work separately and we can
discuss the implementation at that time.
> >
> > > +}
> > > +
> > > +/**
> > > + Function to return PCIe Physical Address(PCIe view) or Controller
> > > + Address(CPU view) for different RCs
> > > +
> > > + @param Address Address passed from bus layer.
> > > + @param Segment Segment number for Root Complex.
> > > + @param Offset Config space register offset.
> > > + @param Bus PCIe Bus number.
> > > +
> > > + @return Return PCIe CPU or Controller address.
> > > +
> > > +**/
> > > +STATIC
> > > +UINT64
> > > +PciLsGetConfigBase (
> > > + IN UINT64 Address,
> > > + IN UINT16 Segment,
> > > + IN UINT16 Offset,
> > > + IN UINT8 Bus
> > > + )
> > > +{
> > > + UINT32 CfgAddr;
> > > +
> > > + CfgAddr = (UINT16)Offset;
> > > + if (Bus) {
> >
> > Please use Bus > 0 here
>
> OK
>
> >
> > > + return PciLsCfgTarget (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF *
> > > +Segment, Address, Segment, Bus, Offset);
> > > + } else {
> > > + return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment + CfgAddr;
> > > + }
> > > +}
> > > +
> > > +/**
> > > + Function to return PCIe Physical Address(PCIe view) or Controller
> > > + Address(CPU view) for different RCs
> > > +
> > > + @param Address Address passed from bus layer.
> > > + @param Segment Segment number for Root Complex.
> > > + @param Offset Config space register offset.
> > > +
> > > + @return Return PCIe CPU or Controller address.
> > > +
> > > +**/
> > > +STATIC
> > > +UINT64
> > > +PciSegmentLibGetConfigBase (
> > > + IN UINT64 Address,
> > > + IN UINT16 Segment,
> > > + IN UINT16 Offset
> > > + )
> > > +{
> > > + UINT8 Bus;
> > > +
> > > + Bus = ((UINT32)Address >> 20) & 0xff;
> > > + return PciLsGetConfigBase (Address, Segment, Offset, Bus); }
> > > +
> > > +/**
> > > + Internal worker function to read a PCI configuration register.
> > > +
> > > + @param Address The address that encodes the Segment, PCI Bus, Device,
> > > + Function and Register.
> > > + @param Width The width of data to read
> > > +
> > > + @return The value read from the PCI configuration register.
> > > +
> > > +**/
> > > +STATIC
> > > +UINT32
> > > +PciSegmentLibReadWorker (
> > > + IN UINT64 Address,
> > > + IN PCI_CFG_WIDTH Width
> > > + )
> > > +{
> > > + UINT64 Base;
> > > + UINT16 Offset;
> > > + UINT16 Segment;
> > > +
> > > + Segment = (Address >> 32);
> > > + Offset = (Address & 0xfff );
> > > +
> > > + Base = PciSegmentLibGetConfigBase (Address, Segment, Offset);
> > > +
> > > + // ignore devices > 0 on bus 0
> > > + if ((Address & 0xff00000) == 0 && (Address & 0xf8000) != 0) {
> > > + return MAX_UINT32;
> > > + }
> > > +
> > > + // ignore device > 0 on bus 1
> > > + if ((Address & 0xfe00000) == 0 && (Address & 0xf8000) != 0) {
> > > + return MAX_UINT32;
> > > + }
> > > +
> > > + switch (Width) {
> > > + case PciCfgWidthUint8:
> > > + return MmioRead8 (Base);
> > > + case PciCfgWidthUint16:
> > > + return MmioRead16 (Base);
> > > + case PciCfgWidthUint32:
> > > + return MmioRead32 (Base);
> > > + default:
> > > + ASSERT (FALSE);
> > > + }
> > > +
> > > + return CHAR_NULL;
> > > +}
> > > +
> > > +/**
> > > + Internal worker function to writes a PCI configuration register.
> > > +
> > > + @param Address The address that encodes the Segment, PCI Bus, Device,
> > > + Function and Register.
> > > + @param Width The width of data to write
> > > + @param Data The value to write.
> > > +
> > > + @return The value written to the PCI configuration register.
> > > +
> > > +**/
> > > +STATIC
> > > +UINT32
> > > +PciSegmentLibWriteWorker (
> > > + IN UINT64 Address,
> > > + IN PCI_CFG_WIDTH Width,
> > > + IN UINT32 Data
> > > + )
> > > +{
> > > + UINT64 Base;
> > > + UINT32 Offset;
> > > + UINT16 Segment;
> > > +
> > > + Segment = (Address >> 32);
> > > + Offset = (Address & 0xfff );
> > > +
> > > + Base = PciSegmentLibGetConfigBase (Address, Segment, Offset);
> > > +
> > > + // ignore devices > 0 on bus 0
> > > + if ((Address & 0xff00000) == 0 && (Address & 0xf8000) != 0) {
> > > + return Data;
> > > + }
> > > +
> > > + // ignore device > 0 on bus 1
> > > + if ((Address & 0xfe00000) == 0 && (Address & 0xf8000) != 0) {
> > > + return MAX_UINT32;
> > > + }
> > > +
> > > + switch (Width) {
> > > + case PciCfgWidthUint8:
> > > + MmioWrite8 (Base , Data);
> > > + break;
> > > + case PciCfgWidthUint16:
> > > + MmioWrite16 (Base , Data);
> > > + break;
> > > + case PciCfgWidthUint32:
> > > + MmioWrite32 (Base , Data);
> > > + break;
> > > + default:
> > > + ASSERT (FALSE);
> > > + }
> > > +
> > > + return Data;
> > > +}
> > > +
> > > +/**
> > > + Register a PCI device so PCI configuration registers may be
> > > +accessed after
> > > + SetVirtualAddressMap().
> > > +
> > > + If any reserved bits in Address are set, then ASSERT().
> > > +
> > > + @param Address The address that encodes the PCI Bus, Device,
> > > + Function and Register.
> > > +
> > > + @retval RETURN_SUCCESS The PCI device was registered for runtime
> > access.
> > > + @retval RETURN_UNSUPPORTED An attempt was made to call this
> > function
> > > + after ExitBootServices().
> > > + @retval RETURN_UNSUPPORTED The resources required to access the
> > PCI device
> > > + at runtime could not be mapped.
> > > + @retval RETURN_OUT_OF_RESOURCES There are not enough resources
> > available to
> > > + complete the registration.
> > > +
> > > +**/
> > > +RETURN_STATUS
> > > +EFIAPI
> > > +PciSegmentRegisterForRuntimeAccess (
> > > + IN UINTN Address
> > > + )
> > > +{
> > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> > > + return RETURN_UNSUPPORTED;
> > > +}
> > > +
> > > +/**
> > > + Reads an 8-bit PCI configuration register.
> > > +
> > > + Reads and returns the 8-bit PCI configuration register specified by Address.
> > > +
> > > + If any reserved bits in Address are set, then ASSERT().
> > > +
> > > + @param Address The address that encodes the PCI Segment, Bus, Device,
> > Function,
> > > + and Register.
> > > +
> > > + @return The 8-bit PCI configuration register specified by Address.
> > > +
> > > +**/
> > > +UINT8
> > > +EFIAPI
> > > +PciSegmentRead8 (
> > > + IN UINT64 Address
> > > + )
> > > +{
> > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> > > +
> > > + return (UINT8) PciSegmentLibReadWorker (Address, PciCfgWidthUint8);
> > > +}
> > > +
> > > +/**
> > > + Writes an 8-bit PCI configuration register.
> > > +
> > > + Writes the 8-bit PCI configuration register specified by Address with the
> > value specified by Value.
> > > + Value is returned. This function must guarantee that all PCI read and write
> > operations are serialized.
> > > +
> > > + If any reserved bits in Address are set, then ASSERT().
> > > +
> > > + @param Address The address that encodes the PCI Segment, Bus, Device,
> > Function, and Register.
> > > + @param Value The value to write.
> > > +
> > > + @return The value written to the PCI configuration register.
> > > +
> > > +**/
> > > +UINT8
> > > +EFIAPI
> > > +PciSegmentWrite8 (
> > > + IN UINT64 Address,
> > > + IN UINT8 Value
> > > + )
> > > +{
> > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> > > +
> > > + return (UINT8) PciSegmentLibWriteWorker (Address, PciCfgWidthUint8,
> > > +Value); }
> > > +
> > > +/**
> > > + Reads a 16-bit PCI configuration register.
> > > +
> > > + Reads and returns the 16-bit PCI configuration register specified by Address.
> > > +
> > > + If any reserved bits in Address are set, then ASSERT().
> > > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > > +
> > > + @param Address The address that encodes the PCI Segment, Bus, Device,
> > Function, and Register.
> > > +
> > > + @return The 16-bit PCI configuration register specified by Address.
> > > +
> > > +**/
> > > +UINT16
> > > +EFIAPI
> > > +PciSegmentRead16 (
> > > + IN UINT64 Address
> > > + )
> > > +{
> > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
> > > +
> > > + return (UINT16) PciSegmentLibReadWorker (Address,
> > > +PciCfgWidthUint16); }
> > > +
> > > +/**
> > > + Writes a 16-bit PCI configuration register.
> > > +
> > > + Writes the 16-bit PCI configuration register specified by Address
> > > + with the value specified by Value.
> > > +
> > > + Value is returned.
> > > +
> > > + If any reserved bits in Address are set, then ASSERT().
> > > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > > +
> > > + @param Address The address that encodes the PCI Segment, Bus, Device,
> > Function, and Register.
> > > + @param Value The value to write.
> > > +
> > > + @return The parameter of Value.
> > > +
> > > +**/
> > > +UINT16
> > > +EFIAPI
> > > +PciSegmentWrite16 (
> > > + IN UINT64 Address,
> > > + IN UINT16 Value
> > > + )
> > > +{
> > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
> > > +
> > > + return (UINT16) PciSegmentLibWriteWorker (Address,
> > > +PciCfgWidthUint16, Value); }
> > > +
> > > +/**
> > > + Reads a 32-bit PCI configuration register.
> > > +
> > > + Reads and returns the 32-bit PCI configuration register specified by Address.
> > > +
> > > + If any reserved bits in Address are set, then ASSERT().
> > > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > > +
> > > + @param Address The address that encodes the PCI Segment, Bus, Device,
> > Function,
> > > + and Register.
> > > +
> > > + @return The 32-bit PCI configuration register specified by Address.
> > > +
> > > +**/
> > > +UINT32
> > > +EFIAPI
> > > +PciSegmentRead32 (
> > > + IN UINT64 Address
> > > + )
> > > +{
> > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
> > > +
> > > + return PciSegmentLibReadWorker (Address, PciCfgWidthUint32); }
> > > +
> > > +/**
> > > + Writes a 32-bit PCI configuration register.
> > > +
> > > + Writes the 32-bit PCI configuration register specified by Address
> > > + with the value specified by Value.
> > > +
> > > + Value is returned.
> > > +
> > > + If any reserved bits in Address are set, then ASSERT().
> > > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > > +
> > > + @param Address The address that encodes the PCI Segment, Bus, Device,
> > > + Function, and Register.
> > > + @param Value The value to write.
> > > +
> > > + @return The parameter of Value.
> > > +
> > > +**/
> > > +UINT32
> > > +EFIAPI
> > > +PciSegmentWrite32 (
> > > + IN UINT64 Address,
> > > + IN UINT32 Value
> > > + )
> > > +{
> > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
> > > +
> > > + return PciSegmentLibWriteWorker (Address, PciCfgWidthUint32,
> > > +Value); }
> > > +
> > > +/**
> > > + Reads a range of PCI configuration registers into a caller supplied buffer.
> > > +
> > > + Reads the range of PCI configuration registers specified by
> > > + StartAddress and Size into the buffer specified by Buffer. This
> > > + function only allows the PCI configuration registers from a single
> > > + PCI function to be read. Size is returned.
> > > +
> > > + If any reserved bits in StartAddress are set, then ASSERT().
> > > + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> > > + If Size > 0 and Buffer is NULL, then ASSERT().
> > > +
> > > + @param StartAddress The starting address that encodes the PCI Segment,
> > Bus,
> > > + Device, Function and Register.
> > > + @param Size The size in bytes of the transfer.
> > > + @param Buffer The pointer to a buffer receiving the data read.
> > > +
> > > + @return Size
> > > +
> > > +**/
> > > +UINTN
> > > +EFIAPI
> > > +PciSegmentReadBuffer (
> > > + IN UINT64 StartAddress,
> > > + IN UINTN Size,
> > > + OUT VOID *Buffer
> > > + )
> > > +{
> > > + UINTN ReturnValue;
> > > +
> > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0); ASSERT
> > > + (((StartAddress & 0xFFF) + Size) <= SIZE_4KB);
> > > +
> > > + if (Size == 0) {
> > > + return Size;
> > > + }
> > > +
> > > + ASSERT (Buffer != NULL);
> > > +
> > > + //
> > > + // Save Size for return
> > > + //
> > > + ReturnValue = Size;
> > > +
> > > + if ((StartAddress & BIT0) != 0) {
> > > + //
> > > + // Read a byte if StartAddress is byte aligned
> > > + //
> > > + *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
> > > + StartAddress += sizeof (UINT8);
> > > + Size -= sizeof (UINT8);
> > > + Buffer = (UINT8*)Buffer + BIT0;
> > > + }
> > > +
> > > + if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
> > > + //
> > > + // Read a word if StartAddress is word aligned
> > > + //
> > > + WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
> > > + StartAddress += sizeof (UINT16);
> > > + Size -= sizeof (UINT16);
> > > + Buffer = (UINT16*)Buffer + BIT0;
> > > + }
> > > +
> > > + while (Size >= sizeof (UINT32)) {
> > > + //
> > > + // Read as many double words as possible
> > > + //
> > > + WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));
> > > + StartAddress += sizeof (UINT32);
> > > + Size -= sizeof (UINT32);
> > > + Buffer = (UINT32*)Buffer + BIT0;
> > > + }
> > > +
> > > + if (Size >= sizeof (UINT16)) {
> > > + //
> > > + // Read the last remaining word if exist
> > > + //
> > > + WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
> > > + StartAddress += sizeof (UINT16);
> > > + Size -= sizeof (UINT16);
> > > + Buffer = (UINT16*)Buffer + BIT0;
> > > + }
> > > +
> > > + if (Size >= sizeof (UINT8)) {
> > > + //
> > > + // Read the last remaining byte if exist
> > > + //
> > > + *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress); }
> > > +
> > > + return ReturnValue;
> > > +}
> > > +
> > > +
> > > +/**
> > > + Copies the data in a caller supplied buffer to a specified range of
> > > +PCI
> > > + configuration space.
> > > +
> > > + Writes the range of PCI configuration registers specified by
> > > + StartAddress and Size from the buffer specified by Buffer. This
> > > + function only allows the PCI configuration registers from a single
> > > + PCI function to be written. Size is returned.
> > > +
> > > + If any reserved bits in StartAddress are set, then ASSERT().
> > > + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> > > + If Size > 0 and Buffer is NULL, then ASSERT().
> > > +
> > > + @param StartAddress The starting address that encodes the PCI Segment,
> > Bus,
> > > + Device, Function and Register.
> > > + @param Size The size in bytes of the transfer.
> > > + @param Buffer The pointer to a buffer containing the data to write.
> > > +
> > > + @return The parameter of Size.
> > > +
> > > +**/
> > > +UINTN
> > > +EFIAPI
> > > +PciSegmentWriteBuffer (
> > > + IN UINT64 StartAddress,
> > > + IN UINTN Size,
> > > + IN VOID *Buffer
> > > + )
> > > +{
> > > + UINTN ReturnValue;
> > > +
> > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0); ASSERT
> > > + (((StartAddress & 0xFFF) + Size) <= SIZE_4KB);
> > > +
> > > + if (Size == 0) {
> > > + return Size;
> > > + }
> > > +
> > > + ASSERT (Buffer != NULL);
> > > +
> > > + //
> > > + // Save Size for return
> > > + //
> > > + ReturnValue = Size;
> > > +
> > > + if ((StartAddress & BIT0) != 0) {
> > > + //
> > > + // Write a byte if StartAddress is byte aligned
> > > + //
> > > + PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);
> > > + StartAddress += sizeof (UINT8);
> > > + Size -= sizeof (UINT8);
> > > + Buffer = (UINT8*)Buffer + BIT0;
> > > + }
> > > +
> > > + if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
> > > + //
> > > + // Write a word if StartAddress is word aligned
> > > + //
> > > + PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
> > > + StartAddress += sizeof (UINT16);
> > > + Size -= sizeof (UINT16);
> > > + Buffer = (UINT16*)Buffer + BIT0;
> > > + }
> > > +
> > > + while (Size >= sizeof (UINT32)) {
> > > + //
> > > + // Write as many double words as possible
> > > + //
> > > + PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));
> > > + StartAddress += sizeof (UINT32);
> > > + Size -= sizeof (UINT32);
> > > + Buffer = (UINT32*)Buffer + BIT0;
> > > + }
> > > +
> > > + if (Size >= sizeof (UINT16)) {
> > > + //
> > > + // Write the last remaining word if exist
> > > + //
> > > + PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
> > > + StartAddress += sizeof (UINT16);
> > > + Size -= sizeof (UINT16);
> > > + Buffer = (UINT16*)Buffer + BIT0;
> > > + }
> > > +
> > > + if (Size >= sizeof (UINT8)) {
> > > + //
> > > + // Write the last remaining byte if exist
> > > + //
> > > + PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer); }
> > > +
> > > + return ReturnValue;
> > > +}
> > > +
> > > +EFI_STATUS
> > > +PciSegLibInit (
> > > + IN EFI_HANDLE ImageHandle,
> > > + IN EFI_SYSTEM_TABLE *SystemTable
> > > + )
> > > +{
> > > + return EFI_SUCCESS;
> > > +}
> > >
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 09/16] Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller
2020-05-25 4:30 ` Jon Nettleton
@ 2020-05-25 15:21 ` Wasim Khan (OSS)
0 siblings, 0 replies; 42+ messages in thread
From: Wasim Khan (OSS) @ 2020-05-25 15:21 UTC (permalink / raw)
To: Jon Nettleton, Wasim Khan (OSS)
Cc: Ard Biesheuvel, devel@edk2.groups.io, Meenakshi Aggarwal,
Vabhav Sharma, Varun Sethi, leif@nuviainc.com
> -----Original Message-----
> From: Jon Nettleton <jon@solid-run.com>
> Sent: Monday, May 25, 2020 10:00 AM
> To: Wasim Khan (OSS) <wasim.khan@oss.nxp.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>; devel@edk2.groups.io;
> Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>; Vabhav Sharma
> <vabhav.sharma@nxp.com>; Varun Sethi <V.Sethi@nxp.com>;
> leif@nuviainc.com
> Subject: Re: [PATCH edk2-platforms 09/16] Silicon/NXP: Implement
> PciSegmentLib for PCIe Layerscape Controller
>
> On Sun, May 24, 2020 at 8:32 PM Wasim Khan (OSS)
> <wasim.khan@oss.nxp.com> wrote:
> >
> >
> >
> > > -----Original Message-----
> > > From: Ard Biesheuvel <ard.biesheuvel@arm.com>
> > > Sent: Friday, May 22, 2020 3:00 PM
> > > To: Wasim Khan (OSS) <wasim.khan@oss.nxp.com>; devel@edk2.groups.io;
> > > Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>; Vabhav Sharma
> > > <vabhav.sharma@nxp.com>; Varun Sethi <V.Sethi@nxp.com>;
> > > leif@nuviainc.com; jon@solid-run.com
> > > Cc: Wasim Khan <wasim.khan@nxp.com>
> > > Subject: Re: [PATCH edk2-platforms 09/16] Silicon/NXP: Implement
> > > PciSegmentLib for PCIe Layerscape Controller
> > >
> > > On 5/22/20 1:02 AM, Wasim Khan wrote:
> > > > From: Wasim Khan <wasim.khan@nxp.com>
> > > >
> > > > We have different PCI config space region for bus 0 (Controller
> > > > space) and bus[0x1-0xff] on NXP SoCs with PCIe LS controller.
> > > > Add PciSegmentLib for PCIe LS controller.
> > > >
> > > > For config transactions for Bus0:
> > > > - Config transaction address = PCIe controller address + offset
> > > >
> > > > For config transactions for Bus[0x1-0xff]:
> > > > - PCIe IP requires target BDF to be written at bit[31:16] of PCIe
> > > > type0/type1 outbound window.
> > > > - Config transaction address = PCIe config space address +
> > > > offset
> > > >
> > > > Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
> > > > Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
> > > > ---
> > > > .../NXP/Library/PciSegmentLib/PciSegmentLib.inf | 32 ++
> > > > Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c | 612
> > > +++++++++++++++++++++
> > > > 2 files changed, 644 insertions(+)
> > > > create mode 100755
> Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > > > create mode 100755
> > > > Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > > >
> > > > diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > > > b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > > > new file mode 100755
> > > > index 000000000000..a36e79239b33
> > > > --- /dev/null
> > > > +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.inf
> > > > @@ -0,0 +1,32 @@
> > > > +## @file
> > > > +# PCI Segment Library for NXP SoCs with multiple RCs # #
> > > > +Copyright
> > > > +2018-2020 NXP # # SPDX-License-Identifier: BSD-2-Clause-Patent
> > > > +##
> > > > +
> > > > +[Defines]
> > > > + INF_VERSION = 0x0001001A
> > > > + BASE_NAME = PciSegmentLib
> > > > + FILE_GUID = c9f59261-5a60-4a4c-82f6-1f520442e100
> > > > + MODULE_TYPE = DXE_DRIVER
> > >
> > > Can this be BASE ?
> > >
> >
> > No, we need constructor function PciSegLibInit() which requires it to be
> DXE_DRIVER.
> >
> > > > + VERSION_STRING = 1.0
> > > > + LIBRARY_CLASS = PciSegmentLib|DXE_DRIVER
> > > > + CONSTRUCTOR = PciSegLibInit
> > > > +
> > > > +[Sources]
> > > > + PciSegmentLib.c
> > > > +
> > > > +[Packages]
> > > > + MdePkg/MdePkg.dec
> > > > + Silicon/NXP/NxpQoriqLs.dec
> > > > +
> > > > +[LibraryClasses]
> > > > + BaseLib
> > > > + DebugLib
> > > > + IoLib
> > > > + PcdLib
> > > > +
> > > > +[FixedPcd]
> > > > + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
> > > > diff --git a/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > > > b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > > > new file mode 100755
> > > > index 000000000000..ecd36971b753
> > > > --- /dev/null
> > > > +++ b/Silicon/NXP/Library/PciSegmentLib/PciSegmentLib.c
> > > > @@ -0,0 +1,612 @@
> > > > +/** @file
> > > > + PCI Segment Library for NXP SoCs with multiple RCs
> > > > +
> > > > + Copyright 2018-2020 NXP
> > > > +
> > > > + SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include
> > > > +<PiDxe.h> #include <Base.h> #include <IndustryStandard/Pci22.h>
> > > > +#include <Library/PciSegmentLib.h> #include <Library/BaseLib.h>
> > > > +#include <Library/DebugLib.h> #include <Library/IoLib.h> #include
> > > > +<Library/MemoryAllocationLib.h> #include <Library/PcdLib.h>
> > > > +#include <Pcie.h>
> > > > +
> > > > +typedef enum {
> > > > + PciCfgWidthUint8 = 0,
> > > > + PciCfgWidthUint16,
> > > > + PciCfgWidthUint32,
> > > > + PciCfgWidthMax
> > > > +} PCI_CFG_WIDTH;
> > > > +
> > > > +/**
> > > > + Assert the validity of a PCI Segment address.
> > > > + A valid PCI Segment address should not contain 1's in bits
> > > > +28..31 and 48..63
> > > > +
> > > > + @param A The address to validate.
> > > > + @param M Additional bits to assert to be zero.
> > > > +
> > > > +**/
> > > > +#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
> > > > + ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
> > > > +
> > > > +STATIC
> > > > +UINT64
> > > > +PciLsCfgTarget (
> > > > + IN EFI_PHYSICAL_ADDRESS Dbi,
> > > > + IN UINT64 Address,
> > > > + IN UINT16 Segment,
> > > > + IN UINT8 Bus,
> > > > + IN UINT16 Offset
> > > > + )
> > > > +{
> > > > + UINT32 Target;
> > > > +
> > > > + Target = ((((Address >> 20) & 0xFF) << 24) |
> > > > + (((Address >> 15) & 0x1F) << 19) |
> > > > + (((Address >> 12) & 0x7) << 16));
> > >
> > > You can drop the outer () here
> > >
> >
> > OK
> >
> > > > +
> > > > + if (Bus > 1) {
> > > > + MmioWrite32 ((UINTN)Dbi + IATU_VIEWPORT_OFF,
> > > > + IATU_VIEWPORT_OUTBOUND | IATU_REGION_INDEX1); } else {
> > > > + MmioWrite32 ((UINTN)Dbi + IATU_VIEWPORT_OFF,
> > > > + IATU_VIEWPORT_OUTBOUND | IATU_REGION_INDEX0); }
> > > > +
> > > > + MmioWrite32 ((UINTN)Dbi +
> > > IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0,
> > > > + Target);
> > > > +
> > > > + if (Bus > 1) {
> > > > + return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment +
> > > > + SEG_CFG_SIZE + Offset; } else {
> > > > + return PCI_SEG0_MMIO_MEMBASE + PCI_BASE_DIFF * Segment +
> > > > + Offset; }
> > >
> > > OK, so this is the version for the IP that does not implement ECAM shift,
> right?
> >
> > No, PCIe Layerscape support both mechanism ECAM & Non-ECAM (with
> exception of bus 0).
> > PCIe LSGen4 controller does not support ECAM at all , which is part of
> > patch #11
> >
>
> Well this isn't completely true. It doesn't support ECAM natively on the
> controller, but it can be configured to represent a proper ECAM view with the
> config shift model we are using on the Rev 2 silicon. I have a functional test
> patch, but that shouldn't be something to hold up this patch set. I will submit
> that work separately and we can discuss the implementation at that time.
Thanks Jon for brining this point.
I meant ECAM support at controller level (HW) . Yes, will discuss the implementation.
>
> > >
> > > > +}
> > > > +
> > > > +/**
> > > > + Function to return PCIe Physical Address(PCIe view) or
> > > > +Controller
> > > > + Address(CPU view) for different RCs
> > > > +
> > > > + @param Address Address passed from bus layer.
> > > > + @param Segment Segment number for Root Complex.
> > > > + @param Offset Config space register offset.
> > > > + @param Bus PCIe Bus number.
> > > > +
> > > > + @return Return PCIe CPU or Controller address.
> > > > +
> > > > +**/
> > > > +STATIC
> > > > +UINT64
> > > > +PciLsGetConfigBase (
> > > > + IN UINT64 Address,
> > > > + IN UINT16 Segment,
> > > > + IN UINT16 Offset,
> > > > + IN UINT8 Bus
> > > > + )
> > > > +{
> > > > + UINT32 CfgAddr;
> > > > +
> > > > + CfgAddr = (UINT16)Offset;
> > > > + if (Bus) {
> > >
> > > Please use Bus > 0 here
> >
> > OK
> >
> > >
> > > > + return PciLsCfgTarget (PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF
> > > > +* Segment, Address, Segment, Bus, Offset);
> > > > + } else {
> > > > + return PCI_SEG0_DBI_BASE + PCI_DBI_SIZE_DIFF * Segment +
> > > > +CfgAddr;
> > > > + }
> > > > +}
> > > > +
> > > > +/**
> > > > + Function to return PCIe Physical Address(PCIe view) or
> > > > +Controller
> > > > + Address(CPU view) for different RCs
> > > > +
> > > > + @param Address Address passed from bus layer.
> > > > + @param Segment Segment number for Root Complex.
> > > > + @param Offset Config space register offset.
> > > > +
> > > > + @return Return PCIe CPU or Controller address.
> > > > +
> > > > +**/
> > > > +STATIC
> > > > +UINT64
> > > > +PciSegmentLibGetConfigBase (
> > > > + IN UINT64 Address,
> > > > + IN UINT16 Segment,
> > > > + IN UINT16 Offset
> > > > + )
> > > > +{
> > > > + UINT8 Bus;
> > > > +
> > > > + Bus = ((UINT32)Address >> 20) & 0xff; return
> > > > + PciLsGetConfigBase (Address, Segment, Offset, Bus); }
> > > > +
> > > > +/**
> > > > + Internal worker function to read a PCI configuration register.
> > > > +
> > > > + @param Address The address that encodes the Segment, PCI Bus,
> Device,
> > > > + Function and Register.
> > > > + @param Width The width of data to read
> > > > +
> > > > + @return The value read from the PCI configuration register.
> > > > +
> > > > +**/
> > > > +STATIC
> > > > +UINT32
> > > > +PciSegmentLibReadWorker (
> > > > + IN UINT64 Address,
> > > > + IN PCI_CFG_WIDTH Width
> > > > + )
> > > > +{
> > > > + UINT64 Base;
> > > > + UINT16 Offset;
> > > > + UINT16 Segment;
> > > > +
> > > > + Segment = (Address >> 32);
> > > > + Offset = (Address & 0xfff );
> > > > +
> > > > + Base = PciSegmentLibGetConfigBase (Address, Segment, Offset);
> > > > +
> > > > + // ignore devices > 0 on bus 0
> > > > + if ((Address & 0xff00000) == 0 && (Address & 0xf8000) != 0) {
> > > > + return MAX_UINT32;
> > > > + }
> > > > +
> > > > + // ignore device > 0 on bus 1
> > > > + if ((Address & 0xfe00000) == 0 && (Address & 0xf8000) != 0) {
> > > > + return MAX_UINT32;
> > > > + }
> > > > +
> > > > + switch (Width) {
> > > > + case PciCfgWidthUint8:
> > > > + return MmioRead8 (Base);
> > > > + case PciCfgWidthUint16:
> > > > + return MmioRead16 (Base);
> > > > + case PciCfgWidthUint32:
> > > > + return MmioRead32 (Base);
> > > > + default:
> > > > + ASSERT (FALSE);
> > > > + }
> > > > +
> > > > + return CHAR_NULL;
> > > > +}
> > > > +
> > > > +/**
> > > > + Internal worker function to writes a PCI configuration register.
> > > > +
> > > > + @param Address The address that encodes the Segment, PCI Bus,
> Device,
> > > > + Function and Register.
> > > > + @param Width The width of data to write
> > > > + @param Data The value to write.
> > > > +
> > > > + @return The value written to the PCI configuration register.
> > > > +
> > > > +**/
> > > > +STATIC
> > > > +UINT32
> > > > +PciSegmentLibWriteWorker (
> > > > + IN UINT64 Address,
> > > > + IN PCI_CFG_WIDTH Width,
> > > > + IN UINT32 Data
> > > > + )
> > > > +{
> > > > + UINT64 Base;
> > > > + UINT32 Offset;
> > > > + UINT16 Segment;
> > > > +
> > > > + Segment = (Address >> 32);
> > > > + Offset = (Address & 0xfff );
> > > > +
> > > > + Base = PciSegmentLibGetConfigBase (Address, Segment, Offset);
> > > > +
> > > > + // ignore devices > 0 on bus 0
> > > > + if ((Address & 0xff00000) == 0 && (Address & 0xf8000) != 0) {
> > > > + return Data;
> > > > + }
> > > > +
> > > > + // ignore device > 0 on bus 1
> > > > + if ((Address & 0xfe00000) == 0 && (Address & 0xf8000) != 0) {
> > > > + return MAX_UINT32;
> > > > + }
> > > > +
> > > > + switch (Width) {
> > > > + case PciCfgWidthUint8:
> > > > + MmioWrite8 (Base , Data);
> > > > + break;
> > > > + case PciCfgWidthUint16:
> > > > + MmioWrite16 (Base , Data);
> > > > + break;
> > > > + case PciCfgWidthUint32:
> > > > + MmioWrite32 (Base , Data);
> > > > + break;
> > > > + default:
> > > > + ASSERT (FALSE);
> > > > + }
> > > > +
> > > > + return Data;
> > > > +}
> > > > +
> > > > +/**
> > > > + Register a PCI device so PCI configuration registers may be
> > > > +accessed after
> > > > + SetVirtualAddressMap().
> > > > +
> > > > + If any reserved bits in Address are set, then ASSERT().
> > > > +
> > > > + @param Address The address that encodes the PCI Bus,
> Device,
> > > > + Function and Register.
> > > > +
> > > > + @retval RETURN_SUCCESS The PCI device was registered for
> runtime
> > > access.
> > > > + @retval RETURN_UNSUPPORTED An attempt was made to call this
> > > function
> > > > + after ExitBootServices().
> > > > + @retval RETURN_UNSUPPORTED The resources required to access
> the
> > > PCI device
> > > > + at runtime could not be mapped.
> > > > + @retval RETURN_OUT_OF_RESOURCES There are not enough
> resources
> > > available to
> > > > + complete the registration.
> > > > +
> > > > +**/
> > > > +RETURN_STATUS
> > > > +EFIAPI
> > > > +PciSegmentRegisterForRuntimeAccess (
> > > > + IN UINTN Address
> > > > + )
> > > > +{
> > > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> > > > + return RETURN_UNSUPPORTED;
> > > > +}
> > > > +
> > > > +/**
> > > > + Reads an 8-bit PCI configuration register.
> > > > +
> > > > + Reads and returns the 8-bit PCI configuration register specified by
> Address.
> > > > +
> > > > + If any reserved bits in Address are set, then ASSERT().
> > > > +
> > > > + @param Address The address that encodes the PCI Segment, Bus,
> Device,
> > > Function,
> > > > + and Register.
> > > > +
> > > > + @return The 8-bit PCI configuration register specified by Address.
> > > > +
> > > > +**/
> > > > +UINT8
> > > > +EFIAPI
> > > > +PciSegmentRead8 (
> > > > + IN UINT64 Address
> > > > + )
> > > > +{
> > > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> > > > +
> > > > + return (UINT8) PciSegmentLibReadWorker (Address,
> > > > +PciCfgWidthUint8); }
> > > > +
> > > > +/**
> > > > + Writes an 8-bit PCI configuration register.
> > > > +
> > > > + Writes the 8-bit PCI configuration register specified by
> > > > + Address with the
> > > value specified by Value.
> > > > + Value is returned. This function must guarantee that all PCI
> > > > + read and write
> > > operations are serialized.
> > > > +
> > > > + If any reserved bits in Address are set, then ASSERT().
> > > > +
> > > > + @param Address The address that encodes the PCI Segment, Bus,
> Device,
> > > Function, and Register.
> > > > + @param Value The value to write.
> > > > +
> > > > + @return The value written to the PCI configuration register.
> > > > +
> > > > +**/
> > > > +UINT8
> > > > +EFIAPI
> > > > +PciSegmentWrite8 (
> > > > + IN UINT64 Address,
> > > > + IN UINT8 Value
> > > > + )
> > > > +{
> > > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> > > > +
> > > > + return (UINT8) PciSegmentLibWriteWorker (Address,
> > > > +PciCfgWidthUint8, Value); }
> > > > +
> > > > +/**
> > > > + Reads a 16-bit PCI configuration register.
> > > > +
> > > > + Reads and returns the 16-bit PCI configuration register specified by
> Address.
> > > > +
> > > > + If any reserved bits in Address are set, then ASSERT().
> > > > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > > > +
> > > > + @param Address The address that encodes the PCI Segment, Bus,
> Device,
> > > Function, and Register.
> > > > +
> > > > + @return The 16-bit PCI configuration register specified by Address.
> > > > +
> > > > +**/
> > > > +UINT16
> > > > +EFIAPI
> > > > +PciSegmentRead16 (
> > > > + IN UINT64 Address
> > > > + )
> > > > +{
> > > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
> > > > +
> > > > + return (UINT16) PciSegmentLibReadWorker (Address,
> > > > +PciCfgWidthUint16); }
> > > > +
> > > > +/**
> > > > + Writes a 16-bit PCI configuration register.
> > > > +
> > > > + Writes the 16-bit PCI configuration register specified by
> > > > + Address with the value specified by Value.
> > > > +
> > > > + Value is returned.
> > > > +
> > > > + If any reserved bits in Address are set, then ASSERT().
> > > > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > > > +
> > > > + @param Address The address that encodes the PCI Segment, Bus,
> Device,
> > > Function, and Register.
> > > > + @param Value The value to write.
> > > > +
> > > > + @return The parameter of Value.
> > > > +
> > > > +**/
> > > > +UINT16
> > > > +EFIAPI
> > > > +PciSegmentWrite16 (
> > > > + IN UINT64 Address,
> > > > + IN UINT16 Value
> > > > + )
> > > > +{
> > > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
> > > > +
> > > > + return (UINT16) PciSegmentLibWriteWorker (Address,
> > > > +PciCfgWidthUint16, Value); }
> > > > +
> > > > +/**
> > > > + Reads a 32-bit PCI configuration register.
> > > > +
> > > > + Reads and returns the 32-bit PCI configuration register specified by
> Address.
> > > > +
> > > > + If any reserved bits in Address are set, then ASSERT().
> > > > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > > > +
> > > > + @param Address The address that encodes the PCI Segment, Bus,
> Device,
> > > Function,
> > > > + and Register.
> > > > +
> > > > + @return The 32-bit PCI configuration register specified by Address.
> > > > +
> > > > +**/
> > > > +UINT32
> > > > +EFIAPI
> > > > +PciSegmentRead32 (
> > > > + IN UINT64 Address
> > > > + )
> > > > +{
> > > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
> > > > +
> > > > + return PciSegmentLibReadWorker (Address, PciCfgWidthUint32); }
> > > > +
> > > > +/**
> > > > + Writes a 32-bit PCI configuration register.
> > > > +
> > > > + Writes the 32-bit PCI configuration register specified by
> > > > + Address with the value specified by Value.
> > > > +
> > > > + Value is returned.
> > > > +
> > > > + If any reserved bits in Address are set, then ASSERT().
> > > > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > > > +
> > > > + @param Address The address that encodes the PCI Segment, Bus,
> Device,
> > > > + Function, and Register.
> > > > + @param Value The value to write.
> > > > +
> > > > + @return The parameter of Value.
> > > > +
> > > > +**/
> > > > +UINT32
> > > > +EFIAPI
> > > > +PciSegmentWrite32 (
> > > > + IN UINT64 Address,
> > > > + IN UINT32 Value
> > > > + )
> > > > +{
> > > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
> > > > +
> > > > + return PciSegmentLibWriteWorker (Address, PciCfgWidthUint32,
> > > > +Value); }
> > > > +
> > > > +/**
> > > > + Reads a range of PCI configuration registers into a caller supplied buffer.
> > > > +
> > > > + Reads the range of PCI configuration registers specified by
> > > > + StartAddress and Size into the buffer specified by Buffer. This
> > > > + function only allows the PCI configuration registers from a
> > > > + single PCI function to be read. Size is returned.
> > > > +
> > > > + If any reserved bits in StartAddress are set, then ASSERT().
> > > > + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> > > > + If Size > 0 and Buffer is NULL, then ASSERT().
> > > > +
> > > > + @param StartAddress The starting address that encodes the PCI
> > > > + Segment,
> > > Bus,
> > > > + Device, Function and Register.
> > > > + @param Size The size in bytes of the transfer.
> > > > + @param Buffer The pointer to a buffer receiving the data read.
> > > > +
> > > > + @return Size
> > > > +
> > > > +**/
> > > > +UINTN
> > > > +EFIAPI
> > > > +PciSegmentReadBuffer (
> > > > + IN UINT64 StartAddress,
> > > > + IN UINTN Size,
> > > > + OUT VOID *Buffer
> > > > + )
> > > > +{
> > > > + UINTN ReturnValue;
> > > > +
> > > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0); ASSERT
> > > > + (((StartAddress & 0xFFF) + Size) <= SIZE_4KB);
> > > > +
> > > > + if (Size == 0) {
> > > > + return Size;
> > > > + }
> > > > +
> > > > + ASSERT (Buffer != NULL);
> > > > +
> > > > + //
> > > > + // Save Size for return
> > > > + //
> > > > + ReturnValue = Size;
> > > > +
> > > > + if ((StartAddress & BIT0) != 0) {
> > > > + //
> > > > + // Read a byte if StartAddress is byte aligned
> > > > + //
> > > > + *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
> > > > + StartAddress += sizeof (UINT8);
> > > > + Size -= sizeof (UINT8);
> > > > + Buffer = (UINT8*)Buffer + BIT0; }
> > > > +
> > > > + if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
> > > > + //
> > > > + // Read a word if StartAddress is word aligned
> > > > + //
> > > > + WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
> > > > + StartAddress += sizeof (UINT16);
> > > > + Size -= sizeof (UINT16);
> > > > + Buffer = (UINT16*)Buffer + BIT0; }
> > > > +
> > > > + while (Size >= sizeof (UINT32)) {
> > > > + //
> > > > + // Read as many double words as possible
> > > > + //
> > > > + WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));
> > > > + StartAddress += sizeof (UINT32);
> > > > + Size -= sizeof (UINT32);
> > > > + Buffer = (UINT32*)Buffer + BIT0; }
> > > > +
> > > > + if (Size >= sizeof (UINT16)) {
> > > > + //
> > > > + // Read the last remaining word if exist
> > > > + //
> > > > + WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
> > > > + StartAddress += sizeof (UINT16);
> > > > + Size -= sizeof (UINT16);
> > > > + Buffer = (UINT16*)Buffer + BIT0; }
> > > > +
> > > > + if (Size >= sizeof (UINT8)) {
> > > > + //
> > > > + // Read the last remaining byte if exist
> > > > + //
> > > > + *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
> > > > + }
> > > > +
> > > > + return ReturnValue;
> > > > +}
> > > > +
> > > > +
> > > > +/**
> > > > + Copies the data in a caller supplied buffer to a specified
> > > > +range of PCI
> > > > + configuration space.
> > > > +
> > > > + Writes the range of PCI configuration registers specified by
> > > > + StartAddress and Size from the buffer specified by Buffer. This
> > > > + function only allows the PCI configuration registers from a
> > > > + single PCI function to be written. Size is returned.
> > > > +
> > > > + If any reserved bits in StartAddress are set, then ASSERT().
> > > > + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> > > > + If Size > 0 and Buffer is NULL, then ASSERT().
> > > > +
> > > > + @param StartAddress The starting address that encodes the PCI
> > > > + Segment,
> > > Bus,
> > > > + Device, Function and Register.
> > > > + @param Size The size in bytes of the transfer.
> > > > + @param Buffer The pointer to a buffer containing the data to write.
> > > > +
> > > > + @return The parameter of Size.
> > > > +
> > > > +**/
> > > > +UINTN
> > > > +EFIAPI
> > > > +PciSegmentWriteBuffer (
> > > > + IN UINT64 StartAddress,
> > > > + IN UINTN Size,
> > > > + IN VOID *Buffer
> > > > + )
> > > > +{
> > > > + UINTN ReturnValue;
> > > > +
> > > > + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0); ASSERT
> > > > + (((StartAddress & 0xFFF) + Size) <= SIZE_4KB);
> > > > +
> > > > + if (Size == 0) {
> > > > + return Size;
> > > > + }
> > > > +
> > > > + ASSERT (Buffer != NULL);
> > > > +
> > > > + //
> > > > + // Save Size for return
> > > > + //
> > > > + ReturnValue = Size;
> > > > +
> > > > + if ((StartAddress & BIT0) != 0) {
> > > > + //
> > > > + // Write a byte if StartAddress is byte aligned
> > > > + //
> > > > + PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);
> > > > + StartAddress += sizeof (UINT8);
> > > > + Size -= sizeof (UINT8);
> > > > + Buffer = (UINT8*)Buffer + BIT0; }
> > > > +
> > > > + if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
> > > > + //
> > > > + // Write a word if StartAddress is word aligned
> > > > + //
> > > > + PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
> > > > + StartAddress += sizeof (UINT16);
> > > > + Size -= sizeof (UINT16);
> > > > + Buffer = (UINT16*)Buffer + BIT0; }
> > > > +
> > > > + while (Size >= sizeof (UINT32)) {
> > > > + //
> > > > + // Write as many double words as possible
> > > > + //
> > > > + PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));
> > > > + StartAddress += sizeof (UINT32);
> > > > + Size -= sizeof (UINT32);
> > > > + Buffer = (UINT32*)Buffer + BIT0; }
> > > > +
> > > > + if (Size >= sizeof (UINT16)) {
> > > > + //
> > > > + // Write the last remaining word if exist
> > > > + //
> > > > + PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
> > > > + StartAddress += sizeof (UINT16);
> > > > + Size -= sizeof (UINT16);
> > > > + Buffer = (UINT16*)Buffer + BIT0; }
> > > > +
> > > > + if (Size >= sizeof (UINT8)) {
> > > > + //
> > > > + // Write the last remaining byte if exist
> > > > + //
> > > > + PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer); }
> > > > +
> > > > + return ReturnValue;
> > > > +}
> > > > +
> > > > +EFI_STATUS
> > > > +PciSegLibInit (
> > > > + IN EFI_HANDLE ImageHandle,
> > > > + IN EFI_SYSTEM_TABLE *SystemTable
> > > > + )
> > > > +{
> > > > + return EFI_SUCCESS;
> > > > +}
> > > >
> >
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH edk2-platforms 01/16] Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs.
2020-05-24 18:31 ` Wasim Khan (OSS)
@ 2020-05-26 6:16 ` Ard Biesheuvel
0 siblings, 0 replies; 42+ messages in thread
From: Ard Biesheuvel @ 2020-05-26 6:16 UTC (permalink / raw)
To: Wasim Khan (OSS)
Cc: devel@edk2.groups.io, Meenakshi Aggarwal, Vabhav Sharma,
Varun Sethi, leif@nuviainc.com, jon@solid-run.com
On 5/24/20 8:31 PM, Wasim Khan (OSS) wrote:
>
>
>> -----Original Message-----
>> From: Ard Biesheuvel <ard.biesheuvel@arm.com>
>> Sent: Friday, May 22, 2020 2:42 PM
>> To: Wasim Khan (OSS) <wasim.khan@oss.nxp.com>; devel@edk2.groups.io;
>> Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>; Vabhav Sharma
>> <vabhav.sharma@nxp.com>; Varun Sethi <V.Sethi@nxp.com>;
>> leif@nuviainc.com; jon@solid-run.com
>> Cc: Wasim Khan <wasim.khan@nxp.com>
>> Subject: Re: [PATCH edk2-platforms 01/16] Silicon/NXP/NxpQoriqLs.dec: Add
>> PCIe related PCDs.
>>
>> On 5/22/20 1:02 AM, Wasim Khan wrote:
>>> From: Wasim Khan <wasim.khan@nxp.com>
>>>
>>> Add PCIe related PCDs.
>>>
>>> Signed-off-by: Vabhav Sharma <vabhav.sharma@nxp.com>
>>
>> Please drop this signoff. This is not the correct way to acknowledge (co-
>> )authorship.
>
> Co-authored-by: Vabhav Sharma <vabhav.sharma@nxp.com>
> Co-authored-by: Wasim Khan <wasim.khan@nxp.com>
> Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
>
> Is this OK ?
>
Yes that is fine.
>>
>>> Signed-off-by: Wasim Khan <wasim.khan@nxp.com>
>>> ---
>>> Silicon/NXP/NxpQoriqLs.dec | 9 +++++++++
>>> 1 file changed, 9 insertions(+)
>>>
>>> diff --git a/Silicon/NXP/NxpQoriqLs.dec b/Silicon/NXP/NxpQoriqLs.dec
>>> index 0722f59ef4f6..bafdfd9f4298 100644
>>> --- a/Silicon/NXP/NxpQoriqLs.dec
>>> +++ b/Silicon/NXP/NxpQoriqLs.dec
>>> @@ -27,3 +27,12 @@ [Guids.common]
>>> [PcdsFeatureFlag]
>>>
>> gNxpQoriqLsTokenSpaceGuid.PcdI2cErratumA009203|FALSE|BOOLEAN|0x0000
>> 0315
>>>
>>>
>> gNxpQoriqLsTokenSpaceGuid.PcdDcfgBigEndian|FALSE|BOOLEAN|0x00000316
>>> +
>>> +
>> gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian|FALSE|BOOLEAN|0x0000031
>>> + 7
>>> +
>>> +[PcdsFixedAtBuild.common]
>>> + # Pcds for PCI Express
>>> +
>> gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr|0x0|UINT64|0x00000500
>>> + gNxpQoriqLsTokenSpaceGuid.PcdNumPciController|0|UINT32|0x00000501
>>> + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase|0x0|UINT32|0x00000502
>>> + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg|0x0|UINT32|0x00000503
>>> + gNxpQoriqLsTokenSpaceGuid.PcdPciDebug|FALSE|BOOLEAN|0x00000504
>>>
>
^ permalink raw reply [flat|nested] 42+ messages in thread
end of thread, other threads:[~2020-05-26 6:16 UTC | newest]
Thread overview: 42+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-05-21 23:02 [PATCH edk2-platforms 00/16] Add PCIe Support Wasim Khan
2020-05-21 23:02 ` [PATCH edk2-platforms 01/16] Silicon/NXP/NxpQoriqLs.dec: Add PCIe related PCDs Wasim Khan
2020-05-22 9:12 ` Ard Biesheuvel
2020-05-24 18:31 ` Wasim Khan (OSS)
2020-05-26 6:16 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 02/16] Silicon/NXP: LS1043A: Define " Wasim Khan
2020-05-21 23:02 ` [PATCH edk2-platforms 03/16] Silicon/NXP: Implement PciHostBridgeLib support Wasim Khan
2020-05-22 9:20 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 04/16] Silicon/NXP: PciHostBridgeLib: CFG Shift feature support for PCIeLS Ctrl Wasim Khan
2020-05-22 9:22 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 05/16] Silicon/NXP: PciHostBridgeLib: Setup PCIe LsGen4 Controller and ATU Windows Wasim Khan
2020-05-22 9:24 ` Ard Biesheuvel
2020-05-24 18:31 ` Wasim Khan (OSS)
2020-05-21 23:02 ` [PATCH edk2-platforms 06/16] Silicon/NXP: PciHostBridgeLib: add Workaround for A-011451 Wasim Khan
2020-05-21 23:02 ` [PATCH edk2-platforms 07/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale Gen4 ATU windows Wasim Khan
2020-05-22 9:33 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 08/16] Silicon/NXP: PciHostBridgeLib: Dump Layerscale iATU windows Wasim Khan
2020-05-22 9:31 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 09/16] Silicon/NXP: Implement PciSegmentLib for PCIe Layerscape Controller Wasim Khan
2020-05-22 9:29 ` Ard Biesheuvel
2020-05-24 18:32 ` Wasim Khan (OSS)
2020-05-25 4:30 ` Jon Nettleton
2020-05-25 15:21 ` Wasim Khan (OSS)
2020-05-21 23:02 ` [PATCH edk2-platforms 10/16] Silicon/NXP: PciSegmentLib: Add ECAM config support for PCIe LS Controller Wasim Khan
2020-05-22 9:36 ` Ard Biesheuvel
2020-05-24 18:32 ` Wasim Khan (OSS)
2020-05-21 23:02 ` [PATCH edk2-platforms 11/16] Silicon/NXP: PciSegmentLib: Add support PCIe LsGen4 Controller Wasim Khan
2020-05-22 9:38 ` Ard Biesheuvel
2020-05-24 18:32 ` Wasim Khan (OSS)
2020-05-21 23:02 ` [PATCH edk2-platforms 12/16] Silicon/NXP: PciSegmentLib: LsGen4Ctrl: Add Workaround for A-011264 Wasim Khan
2020-05-22 9:39 ` Ard Biesheuvel
2020-05-24 18:32 ` Wasim Khan (OSS)
2020-05-21 23:02 ` [PATCH edk2-platforms 13/16] Silicon/NXP/Drivers: Implement PciCpuIo2Dxe Driver Wasim Khan
2020-05-22 9:42 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 14/16] Platform/NXP: LS1043aRdbPkg: Enable NetworkPkg Wasim Khan
2020-05-22 9:42 ` Ard Biesheuvel
2020-05-21 23:02 ` [PATCH edk2-platforms 15/16] Platform/NXP: LS1043aRdbPkg: Enable PCIE support Wasim Khan
2020-05-21 23:02 ` [PATCH edk2-platforms 16/16] Platform/NXP: LS1043aRdbPkg : Increase fv image size Wasim Khan
2020-05-22 9:44 ` Ard Biesheuvel
2020-05-22 9:46 ` [PATCH edk2-platforms 00/16] Add PCIe Support Ard Biesheuvel
2020-05-22 10:58 ` Leif Lindholm
2020-05-24 18:32 ` Wasim Khan (OSS)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox