From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-x22a.google.com (mail-wr0-x22a.google.com [IPv6:2a00:1450:400c:c0c::22a]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 659B720958BCF for ; Mon, 11 Sep 2017 07:19:17 -0700 (PDT) Received: by mail-wr0-x22a.google.com with SMTP id k20so14986350wre.4 for ; Mon, 11 Sep 2017 07:22:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=yifDubA+0O9RMPMIZqtl7JNyXiFGLu1I3h+FqCQw844=; b=Wl7qtBuJFL+eLNElGXM4mKnUryY0k7nANKlAvQMiFeH1hgNPQjsVtGz1aTXK1+NAcu l4j2RYpffNeaoaVii/bIgSX+y2I709iVYLjSj4T/E3Bh1X25ir/XG10HHklyfv2lVlBb hz5P6IhsfmutC50ZNxLpkjQHm6lCJcCXqe0tg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=yifDubA+0O9RMPMIZqtl7JNyXiFGLu1I3h+FqCQw844=; b=ns0oYTWVl1VpOeGjd0UZAr+quQ0GAjeV9OvFM59FDi7bgIqzyj7KSignkxsUBuflSM 0nKuoT9mXUnNkMUOTZlBnpoCuwNtGuqY8jLVXMDSWKIsx2fLaLULvlF4+kcGcAC9RjU+ Zhq0q48ONDBb7lQD10HO3HpNSigzbn5zs9pS2riqA36wpawDjwktlfMQ1nApN0CtjWxV RNyldiGYAyYrTOw26QVjf6fIwDnkE9z3zednPRO/OM38Tb637gNAgDC0xQ4yzz8x1hFL iYKhFdGNxKYCa+bdZ0PdbfAoGlGLwd0KLtP1bodO/CmnKHHXd7z3f4Rp5vTu6+Y3e0Mb eu4Q== X-Gm-Message-State: AHPjjUjqbfxdLrsbFOyPSdi9YJ7a5XEaU0118FVpJAj0joW3lRYQ7h6c lJ9WC796ICJuyHQl X-Google-Smtp-Source: ADKCNb5hcX1v+bDPuKmI8ivK5pfFcKHq41dVAd5Nld7+OwWzwXS5p0Xc2ZKMbp95SnlVrl6PvfER4Q== X-Received: by 10.223.185.9 with SMTP id k9mr8904697wrf.265.1505139731299; Mon, 11 Sep 2017 07:22:11 -0700 (PDT) Received: from bivouac.eciton.net (bivouac.eciton.net. [2a00:1098:0:86:1000:23:0:2]) by smtp.gmail.com with ESMTPSA id k11sm6634057wrc.90.2017.09.11.07.22.10 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 11 Sep 2017 07:22:10 -0700 (PDT) Date: Mon, 11 Sep 2017 15:22:08 +0100 From: Leif Lindholm To: Ard Biesheuvel Cc: edk2-devel@lists.01.org, methavanitpong.pipat@socionext.com, masahisa.kojima@linaro.org, masami.hiramatsu@linaro.org Message-ID: <20170911142208.h2ndb7od4tkjvu32@bivouac.eciton.net> References: <20170908182315.9591-1-ard.biesheuvel@linaro.org> <20170908182315.9591-6-ard.biesheuvel@linaro.org> MIME-Version: 1.0 In-Reply-To: <20170908182315.9591-6-ard.biesheuvel@linaro.org> User-Agent: NeoMutt/20170113 (1.7.2) Subject: Re: [PATCH edk2-platforms 05/14] Silicon/Synquacer: implement PciHostBridgeLib support X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Sep 2017 14:19:18 -0000 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Fri, Sep 08, 2017 at 07:23:06PM +0100, Ard Biesheuvel wrote: > Implement the glue library that exposes the PCIe root complexes to > the generic PCI host bridge driver. Since that driver is the first > one to access the PCI config space, put the low level init code for > the RCs into this library's constructor. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ard Biesheuvel > --- > Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.c | 223 ++++++++++++ > Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.inf | 50 +++ > Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLibConstructor.c | 383 ++++++++++++++++++++ > 3 files changed, 656 insertions(+) > > diff --git a/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.c b/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.c > new file mode 100644 > index 000000000000..10ddaac3b924 > --- /dev/null > +++ b/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.c > @@ -0,0 +1,223 @@ > +/** @file > + PCI Host Bridge Library instance for Socionext Synquacer ARM SOC > + > + Copyright (c) 2017, Linaro Ltd. All rights reserved.
> + > + 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 The above is well enough sorted that I'd let it slip, but it isn't flawless. > + > +#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) Shift the spaces after (UINT8) to after sizeof? > + } > + }, > + EISA_PNP_ID(0x0A08), // PCI Express Space before (? Why don't we have that 0x0a08 in a central header? > + 0 > + }, > + > + { > + 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) Shift the spaces after (UINT8) to after sizeof? > + } > + }, > + EISA_PNP_ID(0x0A08), // PCI Express Same as above. > + 1 > + }, > + > + { > + END_DEVICE_PATH_TYPE, > + END_ENTIRE_DEVICE_PATH_SUBTYPE, > + { > + END_DEVICE_PATH_LENGTH, > + 0 > + } > + } > + } > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED > +CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = { > + L"Mem", L"I/O", L"Bus" > +}; > + > +STATIC PCI_ROOT_BRIDGE mPciRootBridges[] = { > + { > + 0, // Segment > + 0, // Supports > + 0, // Attributes > + TRUE, // DmaAbove4G > + FALSE, // NoExtendedConfigSpace > + FALSE, // ResourceAssigned > + EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | > + EFI_PCI_HOST_BRIDGE_MEM64_DECODE, // AllocationAttributes > + { SYNQUACER_PCI_SEG0_BUSNUM_MIN, > + SYNQUACER_PCI_SEG0_BUSNUM_MAX }, // Bus > + { SYNQUACER_PCI_SEG0_PORTIO_MIN, > + SYNQUACER_PCI_SEG0_PORTIO_MAX }, // Io > + { SYNQUACER_PCI_SEG0_MMIO32_MIN, > + SYNQUACER_PCI_SEG0_MMIO32_MAX }, // Mem > + { SYNQUACER_PCI_SEG0_MMIO64_MIN, > + SYNQUACER_PCI_SEG0_MMIO64_MAX }, // MemAbove4G > + { MAX_UINT64, 0x0 }, // PMem > + { MAX_UINT64, 0x0 }, // PMemAbove4G > + (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[0] > + }, { > + 1, // Segment > + 0, // Supports > + 0, // Attributes > + TRUE, // DmaAbove4G > + FALSE, // NoExtendedConfigSpace > + FALSE, // ResourceAssigned > + EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | > + EFI_PCI_HOST_BRIDGE_MEM64_DECODE, // AllocationAttributes > + { SYNQUACER_PCI_SEG1_BUSNUM_MIN, > + SYNQUACER_PCI_SEG1_BUSNUM_MAX }, // Bus > + { SYNQUACER_PCI_SEG1_PORTIO_MIN, > + SYNQUACER_PCI_SEG1_PORTIO_MAX }, // Io > + { SYNQUACER_PCI_SEG1_MMIO32_MIN, > + SYNQUACER_PCI_SEG1_MMIO32_MAX }, // Mem > + { SYNQUACER_PCI_SEG1_MMIO64_MIN, > + SYNQUACER_PCI_SEG1_MMIO64_MAX }, // MemAbove4G > + { MAX_UINT64, 0x0 }, // PMem > + { MAX_UINT64, 0x0 }, // PMemAbove4G > + (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[1] > + } > +}; > + > +/** > + 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 ( > + OUT UINTN *Count > + ) > +{ > + *Count = ARRAY_SIZE (mPciRootBridges); > + > + 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 < > + (sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr) / > + sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr[0]) > + ) > + ); Replace with ARRAY_SIZE? > + 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 > + ); > + } > +} > diff --git a/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.inf b/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.inf > new file mode 100644 > index 000000000000..cfa9b2fc1c07 > --- /dev/null > +++ b/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLib.inf > @@ -0,0 +1,50 @@ > +## @file > +# PCI Host Bridge Library instance for Socionext Synquacer ARM SOC > +# > +# Copyright (c) 2017, Linaro Ltd. All rights reserved.
> +# > +# 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 = 0x00010019 > + BASE_NAME = SynquacerPciHostBridgeLib > + FILE_GUID = fdc92446-65bc-4f86-b4a0-014a2119a732 > + MODULE_TYPE = DXE_DRIVER > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = PciHostBridgeLib|DXE_DRIVER > + CONSTRUCTOR = SynquacerPciHostBridgeLibConstructor > + > +# > +# The following information is for reference only and not required by the build > +# tools. > +# > +# VALID_ARCHITECTURES = AARCH64 Do we only have AArch64 support for this specific component? > +# > + > +[Sources] > + SynquacerPciHostBridgeLib.c > + SynquacerPciHostBridgeLibConstructor.c > + > +[Packages] > + ArmPkg/ArmPkg.dec > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + Silicon/Socionext/Synquacer/Synquacer.dec > + > +[LibraryClasses] > + ArmLib > + DebugLib > + DevicePathLib > + MemoryAllocationLib > + > +[FixedPcd] > + gArmTokenSpaceGuid.PcdPciIoTranslation > diff --git a/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLibConstructor.c b/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLibConstructor.c > new file mode 100644 > index 000000000000..b3acca32070f > --- /dev/null > +++ b/Silicon/Socionext/Synquacer/Library/SynquacerPciHostBridgeLib/SynquacerPciHostBridgeLibConstructor.c > @@ -0,0 +1,383 @@ > +/** @file > + PCI Host Bridge Library instance for Socionext Synquacer ARM SOC > + > + Copyright (c) 2017, Linaro Ltd. All rights reserved.
> + > + 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 > + > +#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 CORE_CONTROL 0x000 > +#define APP_LTSSM_ENABLE BIT4 > +#define DEVICE_TYPE (BIT3 | BIT2 | BIT1 | BIT0) > + > +#define AXI_CLK_STOP 0x004 > +#define DBI_ACLK_STOP BIT8 > +#define SLV_ACLK_STOP BIT4 > +#define MSTR_ACLK_STOP BIT0 > +#define DBI_CSYSREQ_REG BIT9 > +#define SLV_CSYSREQ_REG BIT5 > +#define MSTR_CSYSREQ_REG BIT1 > + > +#define RESET_CONTROL_1 0x00C > +#define PERST_N_O_REG BIT5 > +#define PERST_N_I_REG BIT4 > +#define BUTTON_RST_N_REG BIT1 > +#define PWUP_RST_N_REG BIT0 > + > +#define RESET_CONTROL_2 0x010 > + > +#define RESET_SELECT_1 0x014 > +#define SQU_RST_SEL BIT29 > +#define PHY_RST_SEL BIT28 > +#define PWR_RST_SEL BIT24 > +#define STI_RST_SEL BIT20 > +#define N_STI_RST_SEL BIT16 > +#define CORE_RST_SEL BIT12 > +#define PERST_SEL BIT4 > +#define BUTTON_RST_SEL BIT1 > +#define PWUP_RST_SEL BIT0 > + > +#define RESET_SELECT_2 0x018 > +#define DBI_ARST_SEL BIT8 > +#define SLV_ARST_SEL BIT4 > +#define MSTR_ARST_SEL BIT0 > + > +#define EM_CONTROL 0x030 > +#define PRE_DET_STT_REG BIT4 > + > +#define EM_SELECT 0x034 > +#define PRE_DET_STT_SEL BIT4 > + > +#define PM_CONTROL_2 0x050 > +#define SYS_AUX_PWR_DET BIT8 > + > +#define PHY_CONFIG_COM_6 0x114 > +#define PIPE_PORT_SEL (BIT1 | BIT0) > + > +#define LINK_MONITOR 0x210 > +#define SMLH_LINK_UP BIT0 > + > +#define LINK_CAPABILITIES_REG 0x07C > +#define PCIE_CAP_MAX_LINK_WIDTH (BIT7 | BIT6 | BIT5 | BIT4) > +#define PCIE_CAP_MAX_LINK_SPEED (BIT3 | BIT2 | BIT1 | BIT0) > + > +#define LINK_CONTROL_LINK_STATUS_REG 0x080 > +#define PCIE_CAP_NEGO_LINK_WIDTH (BIT23 | BIT22 | BIT21 | BIT20) > +#define PCIE_CAP_LINK_SPEED (BIT19 | BIT18 | BIT17 | BIT16) > + > +#define TYPE1_CLASS_CODE_REV_ID_REG 0x008 > +#define BASE_CLASS_CODE 0xFF000000 > +#define BASE_CLASS_CODE_VALUE 0x06 > +#define SUBCLASS_CODE 0x00FF0000 > +#define SUBCLASS_CODE_VALUE 0x04 > +#define PROGRAM_INTERFACE 0x0000FF00 > +#define PROGRAM_INTERFACE_VALUE 0x00 > + > +#define MISC_CONTROL_1_OFF 0x8BC > +#define DBI_RO_WR_EN BIT0 > + > +STATIC > +VOID > +ConfigureWindow ( > + IN EFI_PHYSICAL_ADDRESS DbiBase, > + IN UINTN Index, > + IN UINT64 CpuBase, > + IN UINT64 PciBase, > + IN UINT64 Size, > + IN UINTN Type, > + IN UINTN EnableFlags > + ) > +{ > + ArmDataMemoryBarrier (); > + > + MmioWrite32 (DbiBase + IATU_VIEWPORT_OFF, > + IATU_VIEWPORT_OUTBOUND | IATU_VIEWPORT_REGION_INDEX (Index)); > + > + ArmDataMemoryBarrier (); > + > + MmioWrite32 (DbiBase + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0, > + (UINT32)(CpuBase & 0xFFFFFFFF)); > + MmioWrite32 (DbiBase + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0, > + (UINT32)(CpuBase >> 32)); > + MmioWrite32 (DbiBase + IATU_LIMIT_ADDR_OFF_OUTBOUND_0, > + (UINT32)(CpuBase + Size - 1)); > + MmioWrite32 (DbiBase + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0, > + (UINT32)(PciBase & 0xFFFFFFFF)); > + MmioWrite32 (DbiBase + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0, > + (UINT32)(PciBase >> 32)); > + MmioWrite32 (DbiBase + IATU_REGION_CTRL_1_OFF_OUTBOUND_0, > + Type); > + MmioWrite32 (DbiBase + IATU_REGION_CTRL_2_OFF_OUTBOUND_0, > + IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN | EnableFlags); No barrier needed here? > +} > + > +STATIC > +VOID > +SnPcieSetData ( > + EFI_PHYSICAL_ADDRESS Base, > + UINT32 Offset, > + UINT32 Mask, > + UINT32 In > + ) > +{ > + UINT32 Data; > + UINT32 Shift; > + > + Shift = 1; > + if (In) { > + while (!(Mask & Shift)) { > + Shift <<= 1; } / Leif > + Data = (MmioRead32 (Base + Offset) & ~Mask) | (In * Shift); > + } else { > + Data = MmioRead32 (Base + Offset) & ~Mask; > + } > + > + MmioWrite32 (Base + Offset, Data); > +} > + > +STATIC > +UINT32 > +SnPcieReadData ( > + EFI_PHYSICAL_ADDRESS Base, > + UINT32 Offset, > + UINT32 Mask > + ) > +{ > + UINT32 Shift; > + > + Shift = 0; > + while (!(Mask & 1)) { > + Mask >>= 1; > + Shift++; > + } > + > + return (MmioRead32 (Base + Offset) >> Shift) & Mask; > +} > + > +STATIC > +VOID > +SnDbiRoWrEn ( > + IN EFI_PHYSICAL_ADDRESS DbiBase, > + IN INTN MaxLinkWidth, > + IN INTN MaxLinkSpeed > + ) > +{ > + SnPcieSetData (DbiBase, MISC_CONTROL_1_OFF, DBI_RO_WR_EN, 1); > + > + SnPcieSetData (DbiBase, LINK_CAPABILITIES_REG, PCIE_CAP_MAX_LINK_WIDTH, MaxLinkWidth); > + SnPcieSetData (DbiBase, LINK_CAPABILITIES_REG, PCIE_CAP_MAX_LINK_SPEED, MaxLinkSpeed); > + > + SnPcieSetData (DbiBase, TYPE1_CLASS_CODE_REV_ID_REG, BASE_CLASS_CODE, BASE_CLASS_CODE_VALUE); > + SnPcieSetData (DbiBase, TYPE1_CLASS_CODE_REV_ID_REG, SUBCLASS_CODE, SUBCLASS_CODE_VALUE); > + SnPcieSetData (DbiBase, TYPE1_CLASS_CODE_REV_ID_REG, PROGRAM_INTERFACE, PROGRAM_INTERFACE_VALUE); > + > + SnPcieSetData (DbiBase, MISC_CONTROL_1_OFF, DBI_RO_WR_EN, 0); > +} > + > +STATIC > +VOID > +PciInitController ( > + IN EFI_PHYSICAL_ADDRESS ExsBase, > + IN EFI_PHYSICAL_ADDRESS DbiBase, > + IN EFI_PHYSICAL_ADDRESS ConfigBase, > + IN CONST PCI_ROOT_BRIDGE *RootBridge > + ) > +{ > + SnPcieSetData (ExsBase, EM_SELECT, PRE_DET_STT_SEL, 0); > + SnPcieSetData (ExsBase, EM_CONTROL, PRE_DET_STT_REG, 0); > + SnPcieSetData (ExsBase, EM_CONTROL, PRE_DET_STT_REG, 1); > + > + // 1: Assert all PHY / LINK resets > + SnPcieSetData (ExsBase, RESET_SELECT_1 , PERST_SEL , 0); > + SnPcieSetData (ExsBase, RESET_CONTROL_1, PERST_N_I_REG , 0); > + SnPcieSetData (ExsBase, RESET_CONTROL_1, PERST_N_O_REG , 0); > + > + // Device Reset(PERST#) is effective afrer Set device_type (RC) > + SnPcieSetData (ExsBase, RESET_SELECT_1 , PWUP_RST_SEL , 0); > + SnPcieSetData (ExsBase, RESET_CONTROL_1, PWUP_RST_N_REG, 0); > + SnPcieSetData (ExsBase, RESET_SELECT_1 , BUTTON_RST_SEL , 0); > + SnPcieSetData (ExsBase, RESET_CONTROL_1, BUTTON_RST_N_REG, 0); > + SnPcieSetData (ExsBase, RESET_SELECT_1 , PWR_RST_SEL , 1); > + SnPcieSetData (ExsBase, RESET_SELECT_2 , MSTR_ARST_SEL , 1); > + SnPcieSetData (ExsBase, RESET_SELECT_2 , SLV_ARST_SEL , 1); > + SnPcieSetData (ExsBase, RESET_SELECT_2 , DBI_ARST_SEL , 1); > + SnPcieSetData (ExsBase, RESET_SELECT_1 , CORE_RST_SEL , 1); > + SnPcieSetData (ExsBase, RESET_SELECT_1 , STI_RST_SEL , 1); > + SnPcieSetData (ExsBase, RESET_SELECT_1 , N_STI_RST_SEL , 1); > + SnPcieSetData (ExsBase, RESET_SELECT_1 , SQU_RST_SEL , 1); > + SnPcieSetData (ExsBase, RESET_SELECT_1 , PHY_RST_SEL , 1); > + > + // 2: Set P_app_ltssm_enable='0' for reprogramming before linkup. > + SnPcieSetData (ExsBase, CORE_CONTROL, APP_LTSSM_ENABLE, 0); > + > + // 3: Set device_type (RC) > + SnPcieSetData (ExsBase, CORE_CONTROL, DEVICE_TYPE, 4); > + > + // 4: Set Bifurcation 1=disable 4=able > + // 5: Supply Reference (It has executed) > + // 6: Wait for 10usec (Reference Clocks is stable) > + // 7 De assert PERST# */ > + SnPcieSetData (ExsBase, RESET_CONTROL_1, PERST_N_I_REG, 1); > + SnPcieSetData (ExsBase, RESET_CONTROL_1, PERST_N_O_REG, 1); > + > + // 8 Assert SYS_AUX_PWR_DET > + SnPcieSetData(ExsBase, PM_CONTROL_2, SYS_AUX_PWR_DET, 1); > + > + // 9 Supply following clocks > + SnPcieSetData (ExsBase, AXI_CLK_STOP, MSTR_CSYSREQ_REG, 1); > + SnPcieSetData (ExsBase, AXI_CLK_STOP, MSTR_ACLK_STOP, 0); > + SnPcieSetData (ExsBase, AXI_CLK_STOP, SLV_CSYSREQ_REG, 1); > + SnPcieSetData (ExsBase, AXI_CLK_STOP, SLV_ACLK_STOP, 0); > + SnPcieSetData (ExsBase, AXI_CLK_STOP, DBI_CSYSREQ_REG, 1); > + SnPcieSetData (ExsBase, AXI_CLK_STOP, DBI_ACLK_STOP, 0); > + > + // 10 De assert PHY reset > + // 11 De assert LINK's PMC reset > + SnPcieSetData (ExsBase, RESET_CONTROL_1, PWUP_RST_N_REG, 1); > + SnPcieSetData (ExsBase, RESET_CONTROL_1, BUTTON_RST_N_REG, 1); > + // 12 PHY auto > + // 13 Wrapper auto > + // 14-17 PHY auto > + // 18 Wrapper auto > + // 19 Update registers through DBI AXI Slave interface > + SnDbiRoWrEn (DbiBase, 4 /* lanes */, /* Gen */ 2); > + > + // > + // ECAM shift mode uses bits [27:12] of the untranslated address as > + // B/D/F identifiers. This only works as expected if the base of the > + // region is aligned to 256 MB, or the effective bus numbers will be > + // out of sync with the bus base and limit values we chose. > + // > + ASSERT ((ConfigBase % SIZE_256MB) == RootBridge->Bus.Base * SIZE_1MB); > + > + MmioOr32 (DbiBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_IO_SPACE | > + EFI_PCI_COMMAND_MEMORY_SPACE | > + EFI_PCI_COMMAND_BUS_MASTER); > + > + // Region 0: MMIO32 range > + ConfigureWindow (DbiBase, 0, > + RootBridge->Mem.Base, > + RootBridge->Mem.Base, > + RootBridge->Mem.Limit - RootBridge->Mem.Base + 1, > + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM, > + 0); > + > + // Region 1: Type 0 config space > + ConfigureWindow (DbiBase, 1, > + ConfigBase + RootBridge->Bus.Base * SIZE_1MB, > + 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 (DbiBase, 2, > + ConfigBase + RootBridge->Bus.Base * SIZE_1MB + SIZE_64KB, > + 0x0, > + (RootBridge->Bus.Limit - RootBridge->Bus.Base + 1) * SIZE_1MB - SIZE_64KB, > + 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 (DbiBase, 3, > + FixedPcdGet32 (PcdPciIoTranslation) + RootBridge->Io.Base, > + RootBridge->Io.Base, > + RootBridge->Io.Limit - RootBridge->Io.Base + 1, > + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_IO, > + 0); > + > + // Region 4: MMIO64 range > + ConfigureWindow (DbiBase, 4, > + RootBridge->MemAbove4G.Base, > + RootBridge->MemAbove4G.Base, > + RootBridge->MemAbove4G.Limit - RootBridge->MemAbove4G.Base + 1, > + IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_MEM, > + 0); > + > + // enable link > + if (SnPcieReadData (ExsBase, CORE_CONTROL, APP_LTSSM_ENABLE) == 0) { > + SnPcieSetData (ExsBase, CORE_CONTROL, APP_LTSSM_ENABLE, 1); > + } > +} > + > +STATIC CONST struct { > + EFI_PHYSICAL_ADDRESS DbiBase; > + EFI_PHYSICAL_ADDRESS ExsBase; > + EFI_PHYSICAL_ADDRESS ConfigBase; > +} mBaseAddresses [] = { > + { > + SYNQUACER_PCI_SEG0_DBI_BASE, > + SYNQUACER_PCI_SEG0_EXS_BASE, > + SYNQUACER_PCI_SEG0_CONFIG_BASE > + }, > + { > + SYNQUACER_PCI_SEG1_DBI_BASE, > + SYNQUACER_PCI_SEG1_EXS_BASE, > + SYNQUACER_PCI_SEG1_CONFIG_BASE > + }, > +}; > + > + > +EFI_STATUS > +EFIAPI > +SynquacerPciHostBridgeLibConstructor ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + PCI_ROOT_BRIDGE *RootBridges; > + UINTN Count; > + UINTN Idx; > + > + RootBridges = PciHostBridgeGetRootBridges (&Count); > + ASSERT (Count == ARRAY_SIZE(mBaseAddresses)); > + if (Count != ARRAY_SIZE(mBaseAddresses)) { > + return EFI_INVALID_PARAMETER; > + } > + > + for (Idx = 0; Idx < Count; Idx++) { > + PciInitController (mBaseAddresses[Idx].ExsBase, > + mBaseAddresses[Idx].DbiBase, > + mBaseAddresses[Idx].ConfigBase, > + &RootBridges[Idx]); > + } > + > + return EFI_SUCCESS; > +} > + > -- > 2.11.0 >