From patchwork Wed Aug 31 17:59:35 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 75106 Delivered-To: patch@linaro.org Received: by 10.140.29.52 with SMTP id a49csp461889qga; Wed, 31 Aug 2016 10:59:54 -0700 (PDT) X-Received: by 10.98.9.194 with SMTP id 63mr19207653pfj.56.1472666394211; Wed, 31 Aug 2016 10:59:54 -0700 (PDT) Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id e64si831936pfg.292.2016.08.31.10.59.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 31 Aug 2016 10:59:54 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 6785D1A1E00; Wed, 31 Aug 2016 10:59:53 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-wm0-x231.google.com (mail-wm0-x231.google.com [IPv6:2a00:1450:400c:c09::231]) (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 334EE1A1E00 for ; Wed, 31 Aug 2016 10:59:52 -0700 (PDT) Received: by mail-wm0-x231.google.com with SMTP id 1so54721286wmz.1 for ; Wed, 31 Aug 2016 10:59:52 -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=8WZcxEPOMtV30wzTtSQoXewT74wU/1EnrokUDpUUP88=; b=bEgrtM6n9DeRbAyr5agy6qAlrslYz/Yy5fakrcLiJnoQou9OR6XRwXwdmcNiLw3Lbi 8++dG7gWOW1HtgmWQjXzpwYqR465LF2snZshjEFhQfj674nvL3/5IDp3+RZZroQELPGl HxnzQoVRhuSNu/eOiQ9InEeCHCHItiA+LRBIk= 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=8WZcxEPOMtV30wzTtSQoXewT74wU/1EnrokUDpUUP88=; b=D0t4jPSGbrQZfDClWbXUg/7/uKsglnEb04q1FNJvjbVtBUKDK5+863P0tqg8OmzJtJ P+83bTlC6VrXcStObwolLIdo4jKnmmuvdrJsF3d2YtaMCYC4Ti2ZN+wnwW3bRVqoRLO4 hi2E5JayzcspicxhH4x4ZYFyOiZVfdBEZK88A8n+LidS0MyLzxIkMaAJHRcyZYfdKK5R tNgnAH7z/H1OoUf/ADecsjMvE4XVyiUnhkw558EpVBLzFPAS8IN8cbZwQanKsGL/Pd5w I8y3ah7GEQ3aZG9NnjNLD44cdw+Hwar7gqUpCW7NRuepBTUowgdP4BlBbfs9eT8g38pr 5SUQ== X-Gm-Message-State: AE9vXwPCuuGqxdkv0a3GJCruJEcgxZaSNDlH0EupKzPJu1UO0MVclrv1EZHBSuud2BjHLZcZ X-Received: by 10.28.65.84 with SMTP id o81mr10498740wma.83.1472666390738; Wed, 31 Aug 2016 10:59:50 -0700 (PDT) Received: from localhost.localdomain ([105.151.173.94]) by smtp.gmail.com with ESMTPSA id d62sm10118417wmd.7.2016.08.31.10.59.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 31 Aug 2016 10:59:50 -0700 (PDT) From: Ard Biesheuvel To: edk2-devel@lists.01.org, lersek@redhat.com Date: Wed, 31 Aug 2016 18:59:35 +0100 Message-Id: <1472666379-25426-3-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1472666379-25426-1-git-send-email-ard.biesheuvel@linaro.org> References: <1472666379-25426-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v2 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: , Cc: leif.lindholm@linaro.org, Ard Biesheuvel MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" 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 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(-) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel Reviewed-by: Laszlo Ersek diff --git a/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c b/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c index cc60940d487c..862ee227fffa 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