From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=92.121.34.13; helo=inva020.nxp.com; envelope-from=meenakshi.aggarwal@nxp.com; receiver=edk2-devel@lists.01.org Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id D2AC121A00AE6 for ; Wed, 28 Nov 2018 01:16:32 -0800 (PST) Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 8F9201A032E; Wed, 28 Nov 2018 10:16:31 +0100 (CET) Received: from inv0113.in-blr01.nxp.com (inv0113.in-blr01.nxp.com [165.114.116.118]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id DB2A51A030F; Wed, 28 Nov 2018 10:16:30 +0100 (CET) Received: from uefi-OptiPlex-790.ap.freescale.net (uefi-OptiPlex-790.ap.freescale.net [10.232.132.78]) by inv0113.in-blr01.nxp.com (Postfix) with ESMTP id 41DDF35F; Wed, 28 Nov 2018 14:46:30 +0530 (IST) From: Meenakshi Aggarwal To: ard.biesheuvel@linaro.org, leif.lindholm@linaro.org, michael.d.kinney@intel.com, edk2-devel@lists.01.org Date: Wed, 28 Nov 2018 20:31:49 +0530 Message-Id: <1543417315-5763-36-git-send-email-meenakshi.aggarwal@nxp.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1543417315-5763-1-git-send-email-meenakshi.aggarwal@nxp.com> References: <1518771035-6733-1-git-send-email-meenakshi.aggarwal@nxp.com> <1543417315-5763-1-git-send-email-meenakshi.aggarwal@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [PATCH edk2-platforms 35/41] Silicon/NXP: Implement PciHostBridgeLib support X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Nov 2018 09:16:33 -0000 From: Vabhav Implement the library that exposes the PCIe root complexes to the generic PCI host bridge driver,Putting SoC Specific low level init code for the RCs. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Vabhav --- .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 639 +++++++++++++++++++++ .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 51 ++ 2 files changed, 690 insertions(+) create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c create mode 100644 Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c new file mode 100644 index 0000000..a543d7d --- /dev/null +++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c @@ -0,0 +1,639 @@ +/** @file + PCI Host Bridge Library instance for NXP SoCs + + Copyright 2018 NXP + + This program and the accompanying materials are licensed and made available + under the terms and conditions of the BSD License which accompanies this + distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + } + } + } +}; + +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]; + +/** + Function to set-up iATU outbound window for PCIe controller + + @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 Pcie Size of PCIe controller space(Cfg0/Cfg1/Mem/IO). + +**/ +STATIC +VOID +PcieIatuOutboundSet ( + IN EFI_PHYSICAL_ADDRESS Dbi, + IN UINT32 Idx, + IN UINT32 Type, + IN UINT64 Phys, + IN UINT64 BusAddr, + IN UINT64 Size + ) +{ + 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 check PCIe controller LTSSM state + + @param Pcie Address of PCIe host controller. + +**/ +STATIC +INTN +PcieLinkState ( + IN EFI_PHYSICAL_ADDRESS Pcie + ) +{ + UINT32 State; + + // + // Reading PCIe controller LTSSM state + // + if (FeaturePcdGet (PcdPciLutBigEndian)) { + State = SwapMmioRead32 ((UINTN)Pcie + PCI_LUT_BASE + PCI_LUT_DBG) & + LTSSM_STATE_MASK; + } else { + State = MmioRead32 ((UINTN)Pcie + PCI_LUT_BASE + PCI_LUT_DBG) & + LTSSM_STATE_MASK; + } + + if (State < LTSSM_PCIE_L0) { + DEBUG ((DEBUG_INFO," Pcie Link error. LTSSM=0x%2x\n", State)); + return EFI_SUCCESS; + } + + return EFI_UNSUPPORTED; +} + +/** + Helper function to check PCIe link state + + @param Pcie Address of PCIe host controller. + +**/ +STATIC +INTN +PcieLinkUp ( + IN EFI_PHYSICAL_ADDRESS Pcie + ) +{ + INTN State; + UINT32 Cap; + + State = PcieLinkState (Pcie); + if (State) { + return State; + } + + // + // Try to download speed to gen1 + // + Cap = MmioRead32 ((UINTN)Pcie + PCI_LINK_CAP); + MmioWrite32 ((UINTN)Pcie + PCI_LINK_CAP, (UINT32)(Cap & (~PCI_LINK_SPEED_MASK)) | BIT0); + State = PcieLinkState (Pcie); + if (State) { + return State; + } + + MmioWrite32 ((UINTN)Pcie + PCI_LINK_CAP, Cap); + + return EFI_SUCCESS; +} + +/** + This function checks whether PCIe is enabled or not + depending upon SoC serdes protocol map + + @param PcieNum PCIe number. + + @return The PCIe number enabled in map. + @return FALSE PCIe number is disabled in map. + +**/ +STATIC +BOOLEAN +IsPcieNumEnabled( + IN UINTN PcieNum + ) +{ + UINT64 SerDes1ProtocolMap; + + SerDes1ProtocolMap = 0x0; + + // + // Reading serdes map + // + GetSerdesProtocolMaps (&SerDes1ProtocolMap); + + // + // Verify serdes line is configured in the map + // + if (PcieNum < NUM_PCIE_CONTROLLER) { + return IsSerDesLaneProtocolConfigured (SerDes1ProtocolMap, (PcieNum + BIT0)); + } else { + DEBUG ((DEBUG_ERROR, "Device not supported\n")); + } + + return FALSE; +} + +/** + Function to set-up iATU outbound window for 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 in MMIO32 Memory Space. + @param Mem64Base PCIe controller phy address in MMIO64 Memory Space. + @param IoBase PCIe controller phy address IO Space. +**/ +STATIC +VOID +PcieSetupAtu ( + 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 + ) +{ + + // + // iATU : OUTBOUND WINDOW 0 : CFG0 + // + PcieIatuOutboundSet (Pcie, IATU_REGION_INDEX0, + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0, + Cfg0Base, + SEG_CFG_BUS, + SEG_CFG_SIZE); + + // + // iATU : OUTBOUND WINDOW 1 : CFG1 + PcieIatuOutboundSet (Pcie, IATU_REGION_INDEX1, + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1, + Cfg1Base, + SEG_CFG_BUS, + SEG_CFG_SIZE); + // + // iATU 2 : OUTBOUND WINDOW 2 : MMIO32 + // + PcieIatuOutboundSet (Pcie, IATU_REGION_INDEX2, + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM | BIT12, + MemBase, + SEG_MEM_BUS, + SEG_MEM_SIZE); + + // + // iATU 3 : OUTBOUND WINDOW 3: IO + // + PcieIatuOutboundSet (Pcie, IATU_REGION_INDEX3, + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_IO, + IoBase, + SEG_IO_BUS, + SEG_IO_SIZE); + // + // iATU 4 : OUTBOUND WINDOW 4 : MMIO64 + // + PcieIatuOutboundSet (Pcie, IATU_REGION_INDEX4, + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM, + Mem64Base, + SEG_MEM64_BASE, + MEM64_LIMIT); + + if (FeaturePcdGet (PcdPciDebug) == TRUE) { + INTN Cnt; + UINTN AddrTemp; + + for (Cnt = 0; Cnt <= IATU_REGION_INDEX4; Cnt++) { + MmioWrite32 ((UINTN)Pcie + IATU_VIEWPORT_OFF, + (UINT32)(IATU_VIEWPORT_OUTBOUND | Cnt)); + DEBUG ((DEBUG_INFO,"iATU%d:\n", Cnt)); + AddrTemp = (UINTN)((UINTN)Pcie + IATU_VIEWPORT_OFF); + DEBUG ((DEBUG_INFO,"iATU%d VIEWPORT REG Addr:%08lx Val:%08lx\n", + Cnt, AddrTemp, MmioRead32 (AddrTemp))); + DEBUG ((DEBUG_INFO,"iATU%d VIEWPORT REG:%08lx\n", + Cnt, MmioRead32 ((UINTN)Pcie + IATU_VIEWPORT_OFF))); + 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))); + } + } +} + +/** + 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 MMIO32 Memory Space. + @param Mem64Base PCIe controller phy address MMIO64 Memory 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 + ) +{ + // + // iATU outbound set-up + // + PcieSetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase); + + // + // program correct class for RC + // + MmioWrite32 ((UINTN)Pcie + PCI_BASE_ADDRESS_0, (BIT0 - BIT0)); + MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, (UINT32)BIT0); + MmioWrite32 ((UINTN)Pcie + PCI_CLASS_DEVICE, (UINT32)PCI_CLASS_BRIDGE_PCI); + MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, (UINT32)(BIT0 - BIT0)); +} + +/** + 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; + INTN LinkUp; + 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]; + UINT8 PciEnabled[NUM_PCIE_CONTROLLER]; + + *Count = 0; + + // + // Filling local array for + // PCIe controller Physical address space for Cfg0,Cfg1,Mem,IO + // Host Contoller address + // + for (Idx = 0; Idx < NUM_PCIE_CONTROLLER; Idx++) { + PciPhyMemAddr[Idx] = PCI_SEG0_PHY_MEM_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); + PciPhyMem64Addr[Idx] = PCI_SEG0_PHY_MEM64_BASE + (PCI_BASE_DIFF * Idx); + Regs[Idx] = PCI_SEG0_DBI_BASE + (PCI_DBI_SIZE_DIFF * Idx); + } + + if (FeaturePcdGet (PcdPciDebug) == TRUE) { + DEBUG ((DEBUG_INFO, "In PCIE_INFO: %d\n", Idx)); + DEBUG ((DEBUG_INFO, "PciNum:%d Info PCIe Controller Address: %016llx\n", + Idx, + Regs[Idx])); + DEBUG ((DEBUG_INFO, "Info CFG Values: %016llx:%016llx\n", + (UINT64)PciPhyCfg0Addr[Idx], + (UINT64)PciPhyCfg1Addr[Idx])); + DEBUG ((DEBUG_INFO, "Info Mem Values: %016llx\n", + (UINT64)PciPhyMemAddr[Idx])); + DEBUG ((DEBUG_INFO, "Info IO Values: %016llx\n", + (UINT64)PciPhyIoAddr[Idx])); + DEBUG ((DEBUG_INFO, "Info Mem64 Values: %016llx\n", + (UINT64)PciPhyMem64Addr[Idx])); + } + + for (Idx = 0; Idx < NUM_PCIE_CONTROLLER; Idx++) { + // + // Verify PCIe controller is enabled in Soc Serdes Map + // + if (!IsPcieNumEnabled (Idx)) { + DEBUG ((DEBUG_ERROR, "PCIE%d is disabled\n", (Idx + BIT0))); + // + // Continue with other PCIe controller + // + continue; + } + DEBUG ((DEBUG_INFO, "PCIE%d is Enabled\n", Idx + BIT0)); + + // + // Verify PCIe controller LTSSM state + // + LinkUp = PcieLinkUp(Regs[Idx]); + if (!LinkUp) { + // + // Let the user know there's no PCIe link + // + DEBUG ((DEBUG_INFO,"no link, regs @ 0x%lx\n", Regs[Idx])); + // + // Continue with other PCIe controller + // + continue; + } + DEBUG ((DEBUG_INFO, "PCIE%d Passed Linkup Phase\n", Idx + BIT0)); + + // + // Function to set up address translation unit outbound window for + // PCIe Controller + // + PcieSetupCntrl (Regs[Idx], + PciPhyCfg0Addr[Idx], + PciPhyCfg1Addr[Idx], + PciPhyMemAddr[Idx], + PciPhyMem64Addr[Idx], + PciPhyIoAddr[Idx]); + // + // Local array to index all enable PCIe controllers + // + PciEnabled[*Count] = Idx; + + *Count += BIT0; + } + + if (*Count == 0) { + return NULL; + } else { + for (Loop = 0; Loop < *Count; Loop++) { + mPciRootBridges[Loop].Segment = PciEnabled[Loop]; + 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 - + (PciEnabled[Loop] * + SEG_IO_SIZE) + 1; + mPciRootBridges[Loop].Mem.Base = PCI_SEG_MMIO32_MIN; + mPciRootBridges[Loop].Mem.Limit = PCI_SEG_MMIO32_MAX; + mPciRootBridges[Loop].Mem.Translation = MAX_UINT64 - + (PciEnabled[Loop] * + PCI_SEG_MMIO32_DIFF) + 1; + mPciRootBridges[Loop].MemAbove4G.Base = PciPhyMemAddr[PciEnabled[Loop]]; + mPciRootBridges[Loop].MemAbove4G.Limit = PciPhyMemAddr[PciEnabled[Loop]] + + PCI_SEG_MMIO64_MAX_DIFF; + // + // No separate ranges for prefetchable and non-prefetchable BARs + // + 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[PciEnabled[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; +} diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf new file mode 100644 index 0000000..4f1c4d2 --- /dev/null +++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf @@ -0,0 +1,51 @@ +## @file +# PCI Host Bridge Library instance for NXP ARM SOC +# +# Copyright 2018 NXP +# +# This program and the accompanying materials are licensed and made available +# under the terms and conditions of the BSD License which accompanies this +# distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR +# IMPLIED. +# +# +## + +[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 + Silicon/NXP/NxpQoriqLs.dec + +[LibraryClasses] + DebugLib + DevicePathLib + IoAccessLib + MemoryAllocationLib + PcdLib + SocLib + UefiBootServicesTableLib + +[Pcd] + gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian + gNxpQoriqLsTokenSpaceGuid.PcdNumPciController + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp2BaseAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp3BaseAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp4BaseAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciDebug -- 1.9.1