From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-x22c.google.com (mail-wm0-x22c.google.com [IPv6:2a00:1450:400c:c09::22c]) (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 3B50C1A1E66 for ; Fri, 2 Sep 2016 11:16:10 -0700 (PDT) Received: by mail-wm0-x22c.google.com with SMTP id 1so44180978wmz.1 for ; Fri, 02 Sep 2016 11:16:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=pBqLd7yr14vvKCuJAJXZhZ7y94Oe8/r/h4/YuBskvhs=; b=M7E+1ObKu90MI57DgkEeaCjnqXuW3QYw3QlNbxCV4il01lcFbn54Ao6ijPs0ZCUtYu 4+zVJFIKdH+ARrmg+tH2roPOFqlPO8MrRnPCDcs4smDonkiAcIy/lKrxeyvO/ulA2f9M QwOqsFWxNX6ivJgLMwsjGvNK5zOixhoCVOTk8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=pBqLd7yr14vvKCuJAJXZhZ7y94Oe8/r/h4/YuBskvhs=; b=V0CXs2Nky2Fc3AkHDHJYSH0CXF2BOYeJYph27hq7nDqrdJz68OBYCdguO7AKRY6c27 mKwQ9Qw2lrXDJI8V/VyUheHy65Eb2+42zqwPqDUk09/ivvL2u6iqO5aNWXLOoh5Ao3N3 nOoqK/slLETC18hQqjRsZV+8Fe+sI1pnWaR+t9GzygT+W+BPE6RjSJoWJg+uR9CFSltn QyvUKMw7kQoaf3ZvVZ+Rk5bGoXVLAPAbzL11xml7doxECV9B8zCV8DVryVvixeovrGpo i/by6OLHVtHPtb2+VUEYxaCqDbFfB1gRiavxJZV1ENbx3/wW1xtOJSUtJIWt9Lf/9C2u /+vA== X-Gm-Message-State: AE9vXwMUgKgf0PI2qMHOwFZpgiInD+JO0g2P0LR0M8q63Dhrc9CuGl4mnQTMK0YcFbYYoxvl X-Received: by 10.28.189.195 with SMTP id n186mr4726288wmf.106.1472840168709; Fri, 02 Sep 2016 11:16:08 -0700 (PDT) Received: from localhost.localdomain ([160.165.63.90]) by smtp.gmail.com with ESMTPSA id id1sm11559152wjb.21.2016.09.02.11.16.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 02 Sep 2016 11:16:08 -0700 (PDT) From: Ard Biesheuvel To: edk2-devel@lists.01.org Cc: lersek@redhat.com, Ard Biesheuvel Date: Fri, 2 Sep 2016 19:15:55 +0100 Message-Id: <1472840159-28957-3-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1472840159-28957-1-git-send-email-ard.biesheuvel@linaro.org> References: <1472840159-28957-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [PATCH v3 2/6] ArmVirtPkg/FdtPciPcdProducerLib: add handling of PcdPciIoTranslation X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 02 Sep 2016 18:16:10 -0000 Add handling of the PcdPciIoTranslation PCD, so that modules that include this library via NULL resolution are guaranteed that it will be set before they reference it. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel Reviewed-by: Laszlo Ersek Ref: https://tianocore.acgmultimedia.com/show_bug.cgi?id=65 --- ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c | 108 ++++++++++++++++++-- ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf | 2 + 2 files changed, 100 insertions(+), 10 deletions(-) diff --git a/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c b/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c index cc60940d487c..10b47560cb9c 100644 --- a/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c +++ b/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c @@ -22,6 +22,68 @@ #include +// +// We expect the "ranges" property of "pci-host-ecam-generic" to consist of +// records like this. +// +#pragma pack (1) +typedef struct { + UINT32 Type; + UINT64 ChildBase; + UINT64 CpuBase; + UINT64 Size; +} DTB_PCI_HOST_RANGE_RECORD; +#pragma pack () + +#define DTB_PCI_HOST_RANGE_RELOCATABLE BIT31 +#define DTB_PCI_HOST_RANGE_PREFETCHABLE BIT30 +#define DTB_PCI_HOST_RANGE_ALIASED BIT29 +#define DTB_PCI_HOST_RANGE_MMIO32 BIT25 +#define DTB_PCI_HOST_RANGE_MMIO64 (BIT25 | BIT24) +#define DTB_PCI_HOST_RANGE_IO BIT24 +#define DTB_PCI_HOST_RANGE_TYPEMASK (BIT31 | BIT30 | BIT29 | BIT25 | BIT24) + +STATIC +RETURN_STATUS +GetPciIoTranslation ( + IN FDT_CLIENT_PROTOCOL *FdtClient, + IN INT32 Node, + OUT UINT64 *IoTranslation + ) +{ + UINT32 RecordIdx; + CONST VOID *Prop; + UINT32 Len; + EFI_STATUS Status; + UINT64 IoBase; + + // + // Iterate over "ranges". + // + Status = FdtClient->GetNodeProperty (FdtClient, Node, "ranges", &Prop, &Len); + if (EFI_ERROR (Status) || Len == 0 || + Len % sizeof (DTB_PCI_HOST_RANGE_RECORD) != 0) { + DEBUG ((EFI_D_ERROR, "%a: 'ranges' not found or invalid\n", __FUNCTION__)); + return RETURN_PROTOCOL_ERROR; + } + + for (RecordIdx = 0; RecordIdx < Len / sizeof (DTB_PCI_HOST_RANGE_RECORD); + ++RecordIdx) { + CONST DTB_PCI_HOST_RANGE_RECORD *Record; + UINT32 Type; + + Record = (CONST DTB_PCI_HOST_RANGE_RECORD *)Prop + RecordIdx; + Type = SwapBytes32 (Record->Type) & DTB_PCI_HOST_RANGE_TYPEMASK; + if (Type == DTB_PCI_HOST_RANGE_IO) { + IoBase = SwapBytes64 (Record->ChildBase); + *IoTranslation = SwapBytes64 (Record->CpuBase) - IoBase; + + return RETURN_SUCCESS; + } + } + return RETURN_NOT_FOUND; +} + RETURN_STATUS EFIAPI FdtPciPcdProducerLibConstructor ( @@ -31,11 +93,21 @@ FdtPciPcdProducerLibConstructor ( UINT64 PciExpressBaseAddress; FDT_CLIENT_PROTOCOL *FdtClient; CONST UINT64 *Reg; - UINT32 RegElemSize, RegSize; + UINT32 RegSize; EFI_STATUS Status; + INT32 Node; + RETURN_STATUS RetStatus; + UINT64 IoTranslation; PciExpressBaseAddress = PcdGet64 (PcdPciExpressBaseAddress); if (PciExpressBaseAddress != MAX_UINT64) { + // + // Assume that the fact that PciExpressBaseAddress has been changed from + // its default value of MAX_UINT64 implies that this code has been + // executed already, in the context of another module. That means we can + // assume that PcdPciIoTranslation has been discovered from the DT node + // as well. + // return EFI_SUCCESS; } @@ -43,17 +115,33 @@ FdtPciPcdProducerLibConstructor ( (VOID **)&FdtClient); ASSERT_EFI_ERROR (Status); - Status = FdtClient->FindCompatibleNodeReg (FdtClient, - "pci-host-ecam-generic", (CONST VOID **)&Reg, - &RegElemSize, &RegSize); + PciExpressBaseAddress = 0; + Status = FdtClient->FindCompatibleNode (FdtClient, "pci-host-ecam-generic", + &Node); + + if (!EFI_ERROR (Status)) { + Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg", + (CONST VOID **)&Reg, &RegSize); + + if (!EFI_ERROR (Status) && RegSize == 2 * sizeof (UINT64)) { + PciExpressBaseAddress = SwapBytes64 (*Reg); - if (EFI_ERROR (Status)) { - PciExpressBaseAddress = 0; - } else { - ASSERT (RegElemSize == sizeof (UINT64)); - PciExpressBaseAddress = SwapBytes64 (*Reg); + PcdSetBool (PcdPciDisableBusEnumeration, FALSE); - PcdSetBool (PcdPciDisableBusEnumeration, FALSE); + RetStatus = GetPciIoTranslation (FdtClient, Node, &IoTranslation); + if (!RETURN_ERROR (RetStatus)) { + PcdSet64 (PcdPciIoTranslation, IoTranslation); + } else { + // + // Support for I/O BARs is not mandatory, and so it does not make sense + // to abort in the general case. So leave it up to the actual driver to + // complain about this if it wants to, and just issue a warning here. + // + DEBUG ((EFI_D_WARN, + "%a: 'pci-host-ecam-generic' device encountered with no I/O range\n", + __FUNCTION__)); + } + } } PcdSet64 (PcdPciExpressBaseAddress, PciExpressBaseAddress); diff --git a/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf b/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf index 1ba71abea78a..cd138fa1aa6e 100644 --- a/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf +++ b/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf @@ -26,6 +26,7 @@ [Sources] FdtPciPcdProducerLib.c [Packages] + ArmPkg/ArmPkg.dec ArmVirtPkg/ArmVirtPkg.dec MdeModulePkg/MdeModulePkg.dec MdePkg/MdePkg.dec @@ -40,6 +41,7 @@ [Protocols] gFdtClientProtocolGuid ## CONSUMES [Pcd] + gArmTokenSpaceGuid.PcdPciIoTranslation ## PRODUCES gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## PRODUCES gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration ## PRODUCES -- 2.7.4