From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=pass header.i=@semihalf-com.20150623.gappssmtp.com header.s=20150623 header.b=sJQtafOH; spf=none, err=SPF record not found (domain: semihalf.com, ip: 209.85.160.194, mailfrom: mw@semihalf.com) Received: from mail-qt1-f194.google.com (mail-qt1-f194.google.com [209.85.160.194]) by groups.io with SMTP; Sun, 12 May 2019 04:41:24 -0700 Received: by mail-qt1-f194.google.com with SMTP id o7so11740676qtp.4 for ; Sun, 12 May 2019 04:41:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=pn+tXJ59/kwJvBkaCJF1UnbNSjMOxiM4Nkwo8Lu/njw=; b=sJQtafOHknTZeoaiao0dRA8yhHpJJQk5d3EWudml4CYlKflPuUQhxMF0+v4yX1CJiA cf01q1neWPYvroyGTqJQBVshWccdZ/3dRBZnqu5A5LImtrJctQDnW2cF8xyjcexyz5BT lXMHAiWgIuZF9H6BAspgR8FrQdOAh4+Q+uPN4Pukrrh/X88me56t60o9KGxqLYGg6mrL 7C2vQEa2ioTBTzkTpypve7DjJX9iby18K1el9gvfIcmCgsTHoSporGt3RC9mBo1y8LoR H5yoUUr7TJ74AAzg/A99wAP1U3oKQ0GqIE8aU/LRlUg3FdeB2mr8bvZMIa0hmm6pm0PS nPSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=pn+tXJ59/kwJvBkaCJF1UnbNSjMOxiM4Nkwo8Lu/njw=; b=cvboqNq25t4mWTmaCkc3+WnxL6VVKJK9JRPJFj9B+fpyaAnGLpymtHnmEGceo/252k UnwCtVbEN4yVUGTBzRncZFpuimn1LnYYXJKss7tt8sQaNlKUTU3FXIaINpvTP79ZBH2o qSEq+HItPP6xbi0/WuzRyr+TrNVEdPoqQAYvFlpaGyDVboStZ+ODDVpZZ+18Uqn/HdAQ WeQuqgdDfS7CEF97FhEIP12ld1LdsZ0MPkdw1WdG/miYzyRFwjKqPWIavGHJeiST0o+A a+o+2AmWO9rSnNxF8b1vn4IKU/kZW9XXQ7LY3KFV1p7/vYycArVOs7Cxajb9T+A2TIdN Gyew== X-Gm-Message-State: APjAAAXOudN0R9NOxC/YRhQEa8R5ubRDQMrmsjb79pK+NQjiNa+i/Id+ 5jp9dK+W4MWP8IH2Sw8FAYMNrLODoJemz5KWU5oblw== X-Google-Smtp-Source: APXvYqwcLu5N6upR+5bRzkuCfI2HvKdicdsZI4wjhDmtDdEsW7cjACtCkxcbT5ZKbJo8a57/gHotojjT+v/KH06Z75M= X-Received: by 2002:ac8:1ab6:: with SMTP id x51mr18515518qtj.42.1557661283494; Sun, 12 May 2019 04:41:23 -0700 (PDT) MIME-Version: 1.0 References: <1557395622-32425-1-git-send-email-mw@semihalf.com> <1557395622-32425-8-git-send-email-mw@semihalf.com> <20190510155020.ch5xrdyld2cykclo@bivouac.eciton.net> In-Reply-To: <20190510155020.ch5xrdyld2cykclo@bivouac.eciton.net> From: "Marcin Wojtas" Date: Sun, 12 May 2019 13:41:11 +0200 Message-ID: Subject: Re: [edk2-platforms: PATCH 07/14] Marvell/Armada7k8k: Implement PciHostBridgeLib To: Leif Lindholm Cc: edk2-devel-groups-io , Ard Biesheuvel , "jsd@semihalf.com" , Grzegorz Jaszczyk , Kostya Porotchkin , Jici Gao , Rebecca Cran , Mark Kettenis Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Leif, pt., 10 maj 2019 o 17:50 Leif Lindholm napisa=C5= =82(a): > > On Thu, May 09, 2019 at 11:53:35AM +0200, Marcin Wojtas wrote: > > Add an implementation of the PciHostBridgeLib glue library that > > describes the PCIe RC on this SoC so that the generic PCI host bridge > > driver can attach to it. > > > > This includes a constructor which performs the SoC specific init and > > training sequences. > > > > This patch is based on work of Ard Biesheuvel > > and Jing Hua / > > > > Contributed-under: TianoCore Contribution Agreement 1.1 > > Signed-off-by: Marcin Wojtas > > --- > > Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/PciHostB= ridgeLib.inf | 52 +++ > > Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/PciHostB= ridgeLibConstructor.h | 95 ++++++ > > Since you so helpfully gave me a link to your branch, I can tell that > Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/PciHostBrid= geLibConstructor.h > has incorrect line endings. If you could address for v2, that would be > most appreciated. > > > Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/PciHostB= ridgeLib.c | 244 +++++++++++++++ > > Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/PciHostB= ridgeLibConstructor.c | 330 ++++++++++++++++++++ > > 4 files changed, 721 insertions(+) > > create mode 100644 Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHos= tBridgeLib/PciHostBridgeLib.inf > > create mode 100644 Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHos= tBridgeLib/PciHostBridgeLibConstructor.h > > create mode 100644 Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHos= tBridgeLib/PciHostBridgeLib.c > > create mode 100644 Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHos= tBridgeLib/PciHostBridgeLibConstructor.c > > > > diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridge= Lib/PciHostBridgeLib.inf b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPci= HostBridgeLib/PciHostBridgeLib.inf > > new file mode 100644 > > index 0000000..e46f71d > > --- /dev/null > > +++ b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/Pci= HostBridgeLib.inf > > @@ -0,0 +1,52 @@ > > +## @file > > +# PCI Host Bridge Library instance for Marvell Armada 7k/8k SOC > > +# > > +# Copyright (c) 2017, Linaro Ltd. All rights reserved.
> > +# Copyright (c) 2019 Marvell International Ltd. All rights reserved.<= BR> > > +# > > +# This program and the accompanying materials are licensed and made a= vailable > > +# 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" BASI= S, > > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS O= R > > +# IMPLIED. > > +# > > +# > > +## > > + > > +[Defines] > > + INF_VERSION =3D 0x0001001B > > + BASE_NAME =3D Armada7k8kPciHostBridgeLib > > + FILE_GUID =3D 7f989c9d-02a0-4348-8aeb-ab2e1566f= b18 > > + MODULE_TYPE =3D DXE_DRIVER > > + VERSION_STRING =3D 1.0 > > + LIBRARY_CLASS =3D PciHostBridgeLib|DXE_DRIVER > > + CONSTRUCTOR =3D Armada7k8kPciHostBridgeLibConstru= ctor > > + > > +[Sources] > > + PciHostBridgeLib.c > > + PciHostBridgeLibConstructor.c > > + > > +[Packages] > > + ArmPkg/ArmPkg.dec > > + EmbeddedPkg/EmbeddedPkg.dec > > + MdeModulePkg/MdeModulePkg.dec > > + MdePkg/MdePkg.dec > > + Silicon/Marvell/Marvell.dec > > + > > +[LibraryClasses] > > + ArmLib > > + ArmadaSoCDescLib > > + DebugLib > > + DevicePathLib > > + MemoryAllocationLib > > + MvGpioLib > > + UefiBootServicesTableLib > > + > > +[Protocols] > > + gEmbeddedGpioProtocolGuid > > + gMarvellBoardDescProtocolGuid > > + > > +[Depex] > > + gMarvellPlatformInitCompleteProtocolGuid > > diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridge= Lib/PciHostBridgeLibConstructor.h b/Silicon/Marvell/Armada7k8k/Library/Arma= da7k8kPciHostBridgeLib/PciHostBridgeLibConstructor.h > > new file mode 100644 > > index 0000000..ff9d919 > > --- /dev/null > > +++ b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/Pci= HostBridgeLibConstructor.h > > @@ -0,0 +1,95 @@ > > +/** @file > > + PCI Host Bridge Library instance for Marvell 70x0/80x0 > > + > > + Copyright (c) 2017, Linaro Ltd. All rights reserved.
> > + Copyright (c) 2019 Marvell International Ltd. All rights reserved. > > + > > + This program and the accompanying materials are licensed and made av= ailable > > + 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= . > > + > > +**/ > > +#ifndef __PCI_HOST_BRIDGE_LIB_CONSTRUCTOR_H__ > > +#define __PCI_HOST_BRIDGE_LIB_CONSTRUCTOR_H__ > > + > > +#define IATU_VIEWPORT_OFF 0x900 > > +#define IATU_VIEWPORT_INBOUND BIT31 > > +#define IATU_VIEWPORT_OUTBOUND 0 > > +#define IATU_VIEWPORT_REGION_INDEX(Idx) ((Idx) & 7= ) > > + > > +#define IATU_REGION_CTRL_1_OFF_OUTBOUND_0 0x904 > > +#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_CTRL_2_OFF_OUTBOUND_0 0x908 > > +#define IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN BIT31 > > +#define IATU_REGION_CTRL_2_OFF_OUTBOUND_0_CFG_SHIFT_MODE BIT28 > > + > > +#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 PORT_LINK_CTRL_OFF 0x710 > > +#define PORT_LINK_CTRL_OFF_LINK_CAPABLE_x1 (0x01 << 1= 6) > > +#define PORT_LINK_CTRL_OFF_LINK_CAPABLE_x2 (0x03 << 1= 6) > > +#define PORT_LINK_CTRL_OFF_LINK_CAPABLE_x4 (0x07 << 1= 6) > > +#define PORT_LINK_CTRL_OFF_LINK_CAPABLE_x8 (0x0f << 1= 6) > > +#define PORT_LINK_CTRL_OFF_LINK_CAPABLE_x16 (0x1f << 1= 6) > > +#define PORT_LINK_CTRL_OFF_LINK_CAPABLE_MASK (0x3f << 1= 6) > > + > > +#define GEN2_CTRL_OFF 0x80c > > +#define GEN2_CTRL_OFF_NUM_OF_LANES(n) (((n) & 0x= 1f) << 8) > > +#define GEN2_CTRL_OFF_NUM_OF_LANES_MASK (0x1f << 8= ) > > +#define GEN2_CTRL_OFF_DIRECT_SPEED_CHANGE BIT17 > > + > > +#define PCIE_GLOBAL_CTRL_OFFSET 0x8000 > > +#define PCIE_GLOBAL_APP_LTSSM_EN BIT2 > > +#define PCIE_GLOBAL_CTRL_DEVICE_TYPE_RC (0x4 << 4) > > +#define PCIE_GLOBAL_CTRL_DEVICE_TYPE_MASK (0xF << 4) > > + > > +#define PCIE_GLOBAL_STATUS_REG 0x8008 > > +#define PCIE_GLOBAL_STATUS_RDLH_LINK_UP BIT1 > > +#define PCIE_GLOBAL_STATUS_PHY_LINK_UP BIT9 > > + > > +#define PCIE_PM_STATUS 0x8014 > > +#define PCIE_PM_LTSSM_STAT_MASK (0x3f << 3= ) > > + > > +#define PCIE_GLOBAL_INT_MASK1_REG 0x8020 > > +#define PCIE_INT_A_ASSERT_MASK BIT9 > > +#define PCIE_INT_B_ASSERT_MASK BIT10 > > +#define PCIE_INT_C_ASSERT_MASK BIT11 > > +#define PCIE_INT_D_ASSERT_MASK BIT12 > > + > > +#define PCIE_ARCACHE_TRC_REG 0x8050 > > +#define PCIE_AWCACHE_TRC_REG 0x8054 > > +#define PCIE_ARUSER_REG 0x805C > > +#define PCIE_AWUSER_REG 0x8060 > > + > > +#define ARCACHE_DEFAULT_VALUE 0x3511 > > +#define AWCACHE_DEFAULT_VALUE 0x5311 > > + > > +#define AX_USER_DOMAIN_INNER_SHAREABLE (0x1 << 4) > > +#define AX_USER_DOMAIN_OUTER_SHAREABLE (0x2 << 4) > > +#define AX_USER_DOMAIN_MASK (0x3 << 4) > > + > > +#define PCIE_LINK_CAPABILITY 0x7C > > +#define PCIE_LINK_CTL_2 0xA0 > > +#define TARGET_LINK_SPEED_MASK 0xF > > +#define LINK_SPEED_GEN_1 0x1 > > +#define LINK_SPEED_GEN_2 0x2 > > +#define LINK_SPEED_GEN_3 0x3 > > + > > +#define PCIE_GEN3_EQU_CTRL 0x8A8 > > +#define GEN3_EQU_EVAL_2MS_DISABLE BIT5 > > + > > +#define PCIE_LINK_UP_TIMEOUT_US 40000 > > + > > +#endif > > diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridge= Lib/PciHostBridgeLib.c b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHo= stBridgeLib/PciHostBridgeLib.c > > new file mode 100644 > > index 0000000..ff6288c > > --- /dev/null > > +++ b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/Pci= HostBridgeLib.c > > @@ -0,0 +1,244 @@ > > +/** @file > > + PCI Host Bridge Library instance for Marvell Armada 70x0/80x0 > > + > > + Copyright (c) 2017, Linaro Ltd. All rights reserved.
> > + Copyright (c) 2019 Marvell International Ltd. All rights reserved. > > + > > + This program and the accompanying materials are licensed and made av= ailable > > + 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 > > + > > +#pragma pack(1) > > +typedef struct { > > + ACPI_HID_DEVICE_PATH AcpiDevicePath; > > + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; > > +} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH; > > +#pragma pack () > > + > > +STATIC EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath =3D= { > > + { > > + { > > + ACPI_DEVICE_PATH, > > + ACPI_DP, > > + { > > + (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), > > + (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) > > Drop space after (UINT8), x2. > > > + } > > + }, > > + EISA_PNP_ID(0x0A08), // PCI Express > > Space before (. > > > + 0 > > + }, > > + > > + { > > + END_DEVICE_PATH_TYPE, > > + END_ENTIRE_DEVICE_PATH_SUBTYPE, > > + { > > + END_DEVICE_PATH_LENGTH, > > + 0 > > + } > > + } > > +}; > > + > > +GLOBAL_REMOVE_IF_UNREFERENCED > > +CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] =3D { > > + L"Mem", L"I/O", L"Bus" > > +}; > > + > > +/** > > + 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. > > + The array should be passed into PciHostBridgeFreeRootBridges= () > > + when it's not used. > > + > > +**/ > > +PCI_ROOT_BRIDGE * > > +EFIAPI > > +PciHostBridgeGetRootBridges ( > > + UINTN *Count > > + ) > > +{ > > + MARVELL_BOARD_DESC_PROTOCOL *BoardDescriptionProtocol; > > + MV_BOARD_PCIE_DESCRIPTION *BoardPcieDescription; > > + MV_PCIE_CONTROLLER *PcieController; > > + PCI_ROOT_BRIDGE *PciRootBridges; > > + PCI_ROOT_BRIDGE *RootBridge; > > + EFI_STATUS Status; > > + UINTN Index; > > + > > + *Count =3D 0; > > + > > + /* Obtain list of available controllers */ > > + Status =3D gBS->LocateProtocol (&gMarvellBoardDescProtocolGuid, > > + NULL, > > + (VOID **)&BoardDescriptionProtocol); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, > > + "%a: Cannot locate BoardDesc protocol\n", > > + __FUNCTION__)); > > + return NULL; > > + } > > + > > + Status =3D BoardDescriptionProtocol->PcieDescriptionGet ( > > + BoardDescriptionProtocol, > > + &BoardPcieDescription); > > + if (Status =3D=3D EFI_NOT_FOUND) { > > + /* No controllers used on the platform, exit silently */ > > + return NULL; > > + } else if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, > > + "%a: Cannot get Pcie board desc from BoardDesc protocol\n", > > + __FUNCTION__)); > > + return NULL; > > + } > > + > > + /* Assign return values */ > > + PciRootBridges =3D AllocateZeroPool (BoardPcieDescription->PcieContr= ollerCount * > > + sizeof (PCI_ROOT_BRIDGE)); > > + if (PciRootBridges =3D=3D NULL) { > > + DEBUG ((DEBUG_ERROR, "%a: Fail to allocate resources\n", __FUNCTIO= N__)); > > + return NULL; > > + } > > + > > + *Count =3D BoardPcieDescription->PcieControllerCount; > > + RootBridge =3D PciRootBridges; > > + > > + /* Fill information of all root bridge instances */ > > + for (Index =3D 0; Index < *Count; Index++, RootBridge++) { > > + > > + PcieController =3D &(BoardPcieDescription->PcieControllers[Index])= ; > > + > > + RootBridge->Segment =3D 0; > > + RootBridge->Supports =3D 0; > > + RootBridge->Attributes =3D RootBridge->Supports; > > + > > + RootBridge->DmaAbove4G =3D FALSE; > > + > > + RootBridge->AllocationAttributes =3D EFI_PCI_HOST_BRIDGE_COMBINE_= MEM_PMEM | > > + EFI_PCI_HOST_BRIDGE_MEM64_DECO= DE; > > + > > + RootBridge->Bus.Base =3D PcieController->PcieBusMin; > > + RootBridge->Bus.Limit =3D PcieController->PcieBusMax; > > + RootBridge->Io.Base =3D PcieController->PcieIoWinBase; > > + RootBridge->Io.Limit =3D PcieController->PcieIoWinBase + > > + PcieController->PcieIoWinSize - 1; > > + RootBridge->Mem.Base =3D PcieController->PcieMmio32WinBase; > > + RootBridge->Mem.Limit =3D PcieController->PcieMmio32WinBase + > > + PcieController->PcieMmio32WinSize - 1; > > + RootBridge->MemAbove4G.Base =3D PcieController->PcieMmio64WinBase; > > + RootBridge->MemAbove4G.Limit =3D PcieController->PcieMmio64WinBase= + > > + PcieController->PcieMmio64WinSize -= 1; > > + > > + /* No separate ranges for prefetchable and non-prefetchable BARs *= / > > + RootBridge->PMem.Base =3D MAX_UINT64; > > + RootBridge->PMem.Limit =3D 0; > > + RootBridge->PMemAbove4G.Base =3D MAX_UINT64; > > + RootBridge->PMemAbove4G.Limit =3D 0; > > + > > + ASSERT (PcieController->PcieMmio64Translation =3D=3D 0); > > + ASSERT (PcieController->PcieMmio32Translation =3D=3D 0); > > + > > + RootBridge->NoExtendedConfigSpace =3D FALSE; > > + > > + RootBridge->DevicePath =3D (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRoo= tBridgeDevicePath; > > + } > > + > > + return PciRootBridges; > > +} > > + > > +/** > > + Free the root bridge instances array returned from PciHostBridgeGetR= ootBridges(). > > + > > + @param Bridges The root bridge instances array. > > + @param Count The count of the array. > > + > > +**/ > > +VOID > > +EFIAPI > > +PciHostBridgeFreeRootBridges ( > > + PCI_ROOT_BRIDGE *Bridges, > > + UINTN Count > > + ) > > +{ > > + FreePool (Bridges); > > +} > > + > > +/** > > + 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 e= ach root > > + bridge is terminated with END descriptor and= an > > + additional END is appended indicating the en= d of the > > + entire resources. The resource descriptor fi= eld > > + values follow the description in > > + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROT= OCOL > > + .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 =3D 0; > > + Descriptor =3D (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; > > Drop space after "*)". > > > + > > + while (Descriptor->Desc =3D=3D ACPI_ADDRESS_SPACE_DESCRIPTOR) { > > + > > + DEBUG ((DEBUG_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++)); > > + > > + for (; Descriptor->Desc =3D=3D ACPI_ADDRESS_SPACE_DESCRIPTOR; Desc= riptor++) { > > + ASSERT (Descriptor->ResType < > > + (sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr) / > > + sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr[0]))); > > + > > + DEBUG ((DEBUG_ERROR, > > + " %s: Length/Alignment =3D 0x%lx / 0x%lx\n", > > + mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType], > > + Descriptor->AddrLen, Descriptor->AddrRangeMax)); > > + > > + if (Descriptor->ResType =3D=3D ACPI_ADDRESS_SPACE_TYPE_MEM) { > > + DEBUG ((DEBUG_ERROR, > > + " Granularity/SpecificFlag =3D %ld / %02x%s\n", > > + Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag, > > + ((Descriptor->SpecificFlag & > > + EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHA= BLE) !=3D 0) ? > > + L" (Prefetchable)" : L"")); > > This ternary is quite an effort to parse. I think a temporary > variable for the retult of the & operation would improve this > substantially. > > Alternatively, the wrapping and indentation used in > Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPc= iHostBridgeLib.c > is a lot easier to read. > > > + } > > + } > > + /* Skip the END descriptor for root bridge */ > > + ASSERT (Descriptor->Desc =3D=3D ACPI_END_TAG_DESCRIPTOR); > > + Descriptor =3D (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)( > > + (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1); > > + } > > +} > > diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridge= Lib/PciHostBridgeLibConstructor.c b/Silicon/Marvell/Armada7k8k/Library/Arma= da7k8kPciHostBridgeLib/PciHostBridgeLibConstructor.c > > new file mode 100644 > > index 0000000..ced2c12 > > --- /dev/null > > +++ b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/Pci= HostBridgeLibConstructor.c > > @@ -0,0 +1,330 @@ > > +/** @file > > + PCI Host Bridge Library instance for Marvell 70x0/80x0 > > + > > + Copyright (c) 2017, Linaro Ltd. All rights reserved.
> > + Copyright (c) 2019 Marvell International Ltd. All rights reserved. > > + > > + This program and the accompanying materials are licensed and made av= ailable > > + 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 "PciHostBridgeLibConstructor.h" > > + > > +/** > > + This function configures PCIE controllers IATU windows. > > + > > + @param [in] PcieBaseAddress PCIE controller base address. > > + @param [in] Index IATU window index. > > + @param [in] CpuBase Address from the CPU perspective. > > + @param [in] PciBase Target PCIE address. > > + @param [in] Size IATU window size. > > + @param [in] Type IATU window type. > > + @param [in] EnableFlags Extra configuration flags. > > + > > + @retval none > > + > > +**/ > > +STATIC > > +VOID > > +ConfigureWindow ( > > + IN EFI_PHYSICAL_ADDRESS PcieBaseAddress, > > + IN UINTN Index, > > + IN UINT64 CpuBase, > > + IN UINT64 PciBase, > > + IN UINT64 Size, > > + IN UINTN Type, > > + IN UINTN EnableFlags > > + ) > > +{ > > + ArmDataMemoryBarrier (); > > + > > + MmioWrite32 (PcieBaseAddress + IATU_VIEWPORT_OFF, > > + IATU_VIEWPORT_OUTBOUND | IATU_VIEWPORT_REGION_INDEX (Index)); > > + > > + ArmDataMemoryBarrier (); > > + > > + MmioWrite32 (PcieBaseAddress + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0, > > + (UINT32)(CpuBase & 0xFFFFFFFF)); > > + MmioWrite32 (PcieBaseAddress + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0, > > + (UINT32)(CpuBase >> 32)); > > + MmioWrite32 (PcieBaseAddress + IATU_LIMIT_ADDR_OFF_OUTBOUND_0, > > + (UINT32)(CpuBase + Size - 1)); > > + MmioWrite32 (PcieBaseAddress + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0, > > + (UINT32)(PciBase & 0xFFFFFFFF)); > > + MmioWrite32 (PcieBaseAddress + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0= , > > + (UINT32)(PciBase >> 32)); > > + MmioWrite32 (PcieBaseAddress + IATU_REGION_CTRL_1_OFF_OUTBOUND_0, > > + Type); > > + MmioWrite32 (PcieBaseAddress + IATU_REGION_CTRL_2_OFF_OUTBOUND_0, > > + IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN | EnableFlags); > > +} > > + > > +/** > > + Perform PCIE slot reset using external GPIO pin. > > + > > + @param [in] PcieBaseAddress PCIE controller base address. > > + > > + @retval none > > + > > +**/ > > +STATIC > > +VOID > > +WaitForLink ( > > + IN EFI_PHYSICAL_ADDRESS PcieBaseAddress > > + ) > > +{ > > + UINT32 Mask; > > + UINT32 Status; > > + UINT32 Timeout; > > + > > + if (!(MmioRead32 (PcieBaseAddress + PCIE_PM_STATUS) & PCIE_PM_LTSSM_= STAT_MASK)) { > > + DEBUG ((DEBUG_INIT, "%a: no PCIE device detected\n", __FUNCTION__)= ); > > + return; > > + } > > + > > + /* Wait for the link to establish itself */ > > + DEBUG ((DEBUG_INIT, "%a: waiting for PCIE link\n", __FUNCTION__)); > > + > > + Mask =3D PCIE_GLOBAL_STATUS_RDLH_LINK_UP | PCIE_GLOBAL_STATUS_PHY_LI= NK_UP; > > + Timeout =3D PCIE_LINK_UP_TIMEOUT_US / 10; > > + do { > > + Status =3D MmioRead32 (PcieBaseAddress + PCIE_GLOBAL_STATUS_REG); > > + if ((Status & Mask) =3D=3D Mask) { > > + DEBUG ((DEBUG_ERROR, "pcie@0x%x link UP\n", PcieBaseAddress)); > > + break; > > + } > > + gBS->Stall (10); > > Why this Stall? > Do we need a MemoryFence ()? The stall is added in order to not to poll the link status too often in the loop. I will add a comment. > > > + } while (Timeout--); > > +} > > + > > +/** > > + Perform PCIE slot reset using external GPIO pin. > > + > > + @param [in] *PcieResetGpio GPIO pin description. > > + > > + @retval EFI_SUCEESS PCIE slot reset succeeded. > > + @retval Other Return error status. > > + > > +**/ > > +STATIC > > +EFI_STATUS > > +ResetPcieSlot ( > > + IN MV_GPIO_PIN *PcieResetGpio > > + ) > > +{ > > + EMBEDDED_GPIO_MODE Mode; > > + EMBEDDED_GPIO_PIN GpioPin; > > + EMBEDDED_GPIO *GpioProtocol; > > + EFI_STATUS Status; > > + > > + /* Get GPIO protocol */ > > + Status =3D MvGpioGetProtocol (PcieResetGpio->ControllerType, &GpioPr= otocol); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "%a: Unable to find GPIO protocol\n", __FUNCT= ION__)); > > + return Status; > > + } > > + > > + GpioPin =3D GPIO (PcieResetGpio->ControllerId, PcieResetGpio->PinNum= ber), > > + > > + /* Reset the slot by toggling the GPIO pin */ > > + Mode =3D PcieResetGpio->ActiveHigh ? GPIO_MODE_OUTPUT_1 : GPIO_MODE_= OUTPUT_0; > > + Status =3D GpioProtocol->Set (GpioProtocol, GpioPin, Mode); > > + gBS->Stall (10 * 1000); > > Why this Stall? > Do we need a MemoryFence ()? > > > + > > + Mode =3D PcieResetGpio->ActiveHigh ? GPIO_MODE_OUTPUT_0 : GPIO_MODE_= OUTPUT_1; > > + Status =3D GpioProtocol->Set (GpioProtocol, GpioPin, Mode); > > + gBS->Stall (20 * 1000); > > Why this Stall? > Do we need a MemoryFence ()? > I will add memory fence and add comments around stalls for justification. Best regards, Marcin > / > Leif > > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + Obtain resources and perform a low-level PCIE controllers > > + configuration. > > + > > + @param [in] ImageHandle The image handle. > > + @param [in] *SystemTable The system table. > > + > > + @retval EFI_SUCEESS PCIE configuration successful. > > + @retval Other Return error status. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +Armada7k8kPciHostBridgeLibConstructor ( > > + IN EFI_HANDLE ImageHandle, > > + IN EFI_SYSTEM_TABLE *SystemTable > > + ) > > +{ > > + MARVELL_BOARD_DESC_PROTOCOL *BoardDescriptionProtocol; > > + MV_BOARD_PCIE_DESCRIPTION *BoardPcieDescription; > > + MV_PCIE_CONTROLLER *PcieController; > > + EFI_PHYSICAL_ADDRESS PcieBaseAddress; > > + EFI_STATUS Status; > > + UINTN Index; > > + > > + /* Obtain list of available controllers */ > > + Status =3D gBS->LocateProtocol (&gMarvellBoardDescProtocolGuid, > > + NULL, > > + (VOID **)&BoardDescriptionProtocol); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, > > + "%a: Cannot locate BoardDesc protocol\n", > > + __FUNCTION__)); > > + return EFI_DEVICE_ERROR; > > + } > > + > > + Status =3D BoardDescriptionProtocol->PcieDescriptionGet ( > > + BoardDescriptionProtocol, > > + &BoardPcieDescription); > > + if (Status =3D=3D EFI_NOT_FOUND) { > > + /* No controllers used on the platform, exit silently */ > > + return EFI_SUCCESS; > > + } else if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, > > + "%a: Cannot get Pcie board desc from BoardDesc protocol\n", > > + __FUNCTION__)); > > + return EFI_DEVICE_ERROR; > > + } > > + > > + for (Index =3D 0; Index < BoardPcieDescription->PcieControllerCount;= Index++) { > > + > > + PcieController =3D &(BoardPcieDescription->PcieControllers[Index])= ; > > + > > + ASSERT (PcieController->PcieBusMin =3D=3D 0); > > + ASSERT (PcieController->ConfigSpaceAddress % SIZE_256MB =3D=3D 0); > > + > > + if (PcieController->HaveResetGpio =3D=3D TRUE) { > > + /* Reset PCIE slot */ > > + Status =3D ResetPcieSlot (&PcieController->PcieResetGpio); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, > > + "%a: Cannot reset Pcie Slot\n", > > + __FUNCTION__)); > > + return EFI_DEVICE_ERROR; > > + } > > + } > > + > > + /* Low level PCIE controller configuration */ > > + PcieBaseAddress =3D PcieController->PcieBaseAddress; > > + > > + MmioAndThenOr32 (PcieBaseAddress + PORT_LINK_CTRL_OFF, > > + ~PORT_LINK_CTRL_OFF_LINK_CAPABLE_MASK, > > + PORT_LINK_CTRL_OFF_LINK_CAPABLE_x4); > > + > > + MmioAndThenOr32 (PcieBaseAddress + GEN2_CTRL_OFF, > > + ~GEN2_CTRL_OFF_NUM_OF_LANES_MASK, > > + GEN2_CTRL_OFF_NUM_OF_LANES(4) | GEN2_CTRL_OFF_DIRECT_SPEED_CHANG= E); > > + > > + MmioAndThenOr32 (PcieBaseAddress + PCIE_GLOBAL_CTRL_OFFSET, > > + ~(PCIE_GLOBAL_CTRL_DEVICE_TYPE_MASK | PCIE_GLOBAL_APP_LTSSM_EN), > > + PCIE_GLOBAL_CTRL_DEVICE_TYPE_RC); > > + > > + MmioWrite32 (PcieBaseAddress + PCIE_ARCACHE_TRC_REG, > > + ARCACHE_DEFAULT_VALUE); > > + > > + MmioWrite32 (PcieBaseAddress + PCIE_AWCACHE_TRC_REG, > > + AWCACHE_DEFAULT_VALUE); > > + > > + MmioAndThenOr32 (PcieBaseAddress + PCIE_ARUSER_REG, > > + ~AX_USER_DOMAIN_MASK, > > + AX_USER_DOMAIN_OUTER_SHAREABLE); > > + > > + MmioAndThenOr32 (PcieBaseAddress + PCIE_AWUSER_REG, > > + ~AX_USER_DOMAIN_MASK, > > + AX_USER_DOMAIN_OUTER_SHAREABLE); > > + > > + MmioAndThenOr32 (PcieBaseAddress + PCIE_LINK_CTL_2, > > + ~TARGET_LINK_SPEED_MASK, > > + LINK_SPEED_GEN_3); > > + > > + MmioAndThenOr32 (PcieBaseAddress + PCIE_LINK_CAPABILITY, > > + ~TARGET_LINK_SPEED_MASK, > > + LINK_SPEED_GEN_3); > > + > > + MmioOr32 (PcieBaseAddress + PCIE_GEN3_EQU_CTRL, > > + GEN3_EQU_EVAL_2MS_DISABLE); > > + > > + MmioOr32 (PcieBaseAddress + PCIE_GLOBAL_CTRL_OFFSET, > > + PCIE_GLOBAL_APP_LTSSM_EN); > > + > > + /* Region 0: MMIO32 range */ > > + ConfigureWindow (PcieBaseAddress, > > + 0, > > + PcieController->PcieMmio32WinBase, > > + PcieController->PcieMmio32WinBase, > > + PcieController->PcieMmio32WinSize, > > + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM, > > + 0); > > + > > + /* Region 1: Type 0 config space */ > > + ConfigureWindow (PcieBaseAddress, > > + 1, > > + PcieController->ConfigSpaceAddress, > > + 0x0, > > + SIZE_64KB, > > + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0, > > + IATU_REGION_CTRL_2_OFF_OUTBOUND_0_CFG_SHIFT_MODE); > > + > > + /* Region 2: Type 1 config space */ > > + ConfigureWindow (PcieBaseAddress, > > + 2, > > + PcieController->ConfigSpaceAddress + SIZE_64KB, > > + 0x0, > > + PcieController->PcieBusMax * SIZE_1MB, > > + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1, > > + IATU_REGION_CTRL_2_OFF_OUTBOUND_0_CFG_SHIFT_MODE); > > + > > + /* Region 3: port I/O range */ > > + ConfigureWindow (PcieBaseAddress, > > + 3, > > + PcieController->PcieIoTranslation, > > + PcieController->PcieIoWinBase, > > + PcieController->PcieIoWinSize, > > + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_IO, > > + 0); > > + > > + /* Region 4: MMIO64 range */ > > + ConfigureWindow (PcieBaseAddress, > > + 4, > > + PcieController->PcieMmio64WinBase, > > + PcieController->PcieMmio64WinBase, > > + PcieController->PcieMmio64WinSize, > > + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM, > > + 0); > > + > > + MmioOr32 (PcieBaseAddress + PCIE_GLOBAL_INT_MASK1_REG, > > + PCIE_INT_A_ASSERT_MASK | > > + PCIE_INT_B_ASSERT_MASK | > > + PCIE_INT_C_ASSERT_MASK | > > + PCIE_INT_D_ASSERT_MASK); > > + > > + WaitForLink (PcieBaseAddress); > > + > > + /* Enable the RC */ > > + MmioOr32 (PcieBaseAddress + PCI_COMMAND_OFFSET, > > + EFI_PCI_COMMAND_IO_SPACE | > > + EFI_PCI_COMMAND_MEMORY_SPACE | > > + EFI_PCI_COMMAND_BUS_MASTER); > > + } > > + > > + return EFI_SUCCESS; > > +} > > -- > > 2.7.4 > >