From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3E5DCC433FE for ; Thu, 21 Apr 2022 16:13:55 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id E3EBB83ECF; Thu, 21 Apr 2022 18:12:18 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="gdNsFDPE"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id A818083EA3; Thu, 21 Apr 2022 18:11:52 +0200 (CEST) Received: from mail-wm1-x349.google.com (mail-wm1-x349.google.com [IPv6:2a00:1450:4864:20::349]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 9308383E80 for ; Thu, 21 Apr 2022 18:11:48 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=3RIJhYgYKBucJbLdUUPXXPUN.LXVd-KXXcURbcb.MNWg.MN@flex--ascull.bounces.google.com Received: by mail-wm1-x349.google.com with SMTP id q188-20020a1c43c5000000b003928f679c42so2513737wma.5 for ; Thu, 21 Apr 2022 09:11:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=DGwJoJKDZShvR3eNXfF2x3WBR1ulvMT+r6nyVMEKxoA=; b=gdNsFDPEKoUBUxuygLmoq/ddmDkPWBwQPXHJA5A8ts6NDOlkUF2p9+JNdcwarvsEK/ cQOUE4sOK0xu55GDqtqvxj/dWVTPgvOeXA7MocI+r9SfR2nEhCzQbx0M+j4WlMu9vwcY fTDLHBAS3weV7/TgPM3/D6dH/88cnE3W3zxFHSzV+HXyhbwUb4Pd7/dI6xhTd/1mTfYC 86nvmRMA6e3Vz4Ex0WrHNRtxkKQk8ziMJRgfHiWs+TgB6cJQqTgJmP37YicKuwnsZ9bK IO5NFPXSxlQjCoxDkxJrrWdfVYbHizyvVdK8YT5Ydx5eccmcKv+r3W0NnhQkqcvt9kpd opAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=DGwJoJKDZShvR3eNXfF2x3WBR1ulvMT+r6nyVMEKxoA=; b=hm4y6+JSbfb1ZZbIDWqXDkqzpa3xZ/EHF3Q5/14PD5LWTV6/STbAcl/9Qcg+a0a04F 3fw6DKLJd1kNqPW2OUzzmCLFYZxflRfIlztTYrEgEwL5i2T7pD1sY3jBOzBb43zmF3Ju zay/ABeGmEqRP3Z7CJIVsUy05S7Gjzry8tkUfEZrQSEtdBcHrN7TENB7ZvDCa0i70Zdw IfHHg4C23OO8+ECkcg5uq2uRHWTZyOJ7ugmxtx7hAqxoJhhFehg20ntEA3XPBr1c1RwP b7kgPF0zml7gpm9kDCo2qURqkArvc3PEm84VSA1BS0EZF1A79Q/dGN6QVvQ7shLSwfBR 4VAQ== X-Gm-Message-State: AOAM530sJtEP5FQLTimtTGRZenVbeQfO4zRKJMuEQSELWjEQGASUrW1J bpYgpOO4JqRClXNxsT9qrlLpi/RbUa6tqo7QATUvs/2MsLJsae2uxFHCMcIGd4Dqqi7I8959pKu bvnyBBTmKzgGMDk6QXnZGaKKLU/pYyIcYUjShcCb0rxaaWLl8QjUyeq0abaw= X-Google-Smtp-Source: ABdhPJw5VZ1/JwmFYkdRO9ks6yLE0pBhaIT6a6yD9WAqIiMeZaP6Ne5jDfNToBsc20WVtpNxM2nyS74QO5o= X-Received: from ascull.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:1510]) (user=ascull job=sendgmr) by 2002:a05:6000:1f97:b0:20a:bb9d:c82d with SMTP id bw23-20020a0560001f9700b0020abb9dc82dmr368729wrb.302.1650557508067; Thu, 21 Apr 2022 09:11:48 -0700 (PDT) Date: Thu, 21 Apr 2022 16:11:11 +0000 In-Reply-To: <20220421161116.1202023-1-ascull@google.com> Message-Id: <20220421161116.1202023-14-ascull@google.com> Mime-Version: 1.0 References: <20220421161116.1202023-1-ascull@google.com> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog Subject: [PATCH v3 13/18] pci: Match region flags using a mask From: Andrew Scull To: u-boot@lists.denx.de Cc: sjg@chromium.org, bmeng.cn@gmail.com, trini@konsulko.com, Andrew Scull Content-Type: text/plain; charset="UTF-8" X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean When converting addresses, apply a mask to the region flags during lookup. This allows the caller to specify which flags are important and which are not, for example to exclude system memory regions. The behaviour of the function is changed such that they don't preferentially search for a non-system memory region. However, system memory regions are added after other regions in decode_regions() leading to a similar outcome. Signed-off-by: Andrew Scull Reviewed-by: Bin Meng region_count == 0) { - *pa = bus_addr; - return 0; - } + /* The root controller has the region information */ + ctlr = pci_get_controller(dev); + hose = dev_get_uclass_priv(ctlr); + + if (hose->region_count == 0) + return bus_addr; for (i = 0; i < hose->region_count; i++) { res = &hose->regions[i]; - if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0) - continue; - - if (res->flags & skip_mask) + if ((res->flags & mask) != flags) continue; if (bus_addr < res->bus_start) @@ -1423,69 +1423,34 @@ static int _dm_pci_bus_to_phys(struct udevice *ctlr, pci_addr_t bus_addr, if (len > res->size - offset) continue; - *pa = res->phys_start + offset; - return 0; + return res->phys_start + offset; } - return 1; + puts("pci_hose_bus_to_phys: invalid physical address\n"); + return 0; } -phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t bus_addr, - size_t len, unsigned long flags) +pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t phys_addr, + size_t len, unsigned long mask, + unsigned long flags) { - phys_addr_t phys_addr = 0; struct udevice *ctlr; - int ret; - - /* The root controller has the region information */ - ctlr = pci_get_controller(dev); - - /* - * if PCI_REGION_MEM is set we do a two pass search with preference - * on matches that don't have PCI_REGION_SYS_MEMORY set - */ - if ((flags & PCI_REGION_TYPE) == PCI_REGION_MEM) { - ret = _dm_pci_bus_to_phys(ctlr, bus_addr, len, - flags, PCI_REGION_SYS_MEMORY, - &phys_addr); - if (!ret) - return phys_addr; - } - - ret = _dm_pci_bus_to_phys(ctlr, bus_addr, len, flags, 0, &phys_addr); - - if (ret) - puts("pci_hose_bus_to_phys: invalid physical address\n"); - - return phys_addr; -} - -static int _dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t phys_addr, - size_t len, unsigned long flags, - unsigned long skip_mask, pci_addr_t *ba) -{ + struct pci_controller *hose; struct pci_region *res; - struct udevice *ctlr; phys_addr_t offset; int i; - struct pci_controller *hose; /* The root controller has the region information */ ctlr = pci_get_controller(dev); hose = dev_get_uclass_priv(ctlr); - if (hose->region_count == 0) { - *ba = phys_addr; - return 0; - } + if (hose->region_count == 0) + return phys_addr; for (i = 0; i < hose->region_count; i++) { res = &hose->regions[i]; - if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0) - continue; - - if (res->flags & skip_mask) + if ((res->flags & mask) != flags) continue; if (phys_addr < res->phys_start) @@ -1498,36 +1463,11 @@ static int _dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t phys_addr, if (len > res->size - offset) continue; - *ba = res->bus_start + offset; - return 0; - } - - return 1; -} - -pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t phys_addr, - size_t len, unsigned long flags) -{ - pci_addr_t bus_addr = 0; - int ret; - - /* - * if PCI_REGION_MEM is set we do a two pass search with preference - * on matches that don't have PCI_REGION_SYS_MEMORY set - */ - if ((flags & PCI_REGION_TYPE) == PCI_REGION_MEM) { - ret = _dm_pci_phys_to_bus(dev, phys_addr, len, flags, - PCI_REGION_SYS_MEMORY, &bus_addr); - if (!ret) - return bus_addr; + return res->bus_start + offset; } - ret = _dm_pci_phys_to_bus(dev, phys_addr, len, flags, 0, &bus_addr); - - if (ret) - puts("pci_hose_phys_to_bus: invalid physical address\n"); - - return bus_addr; + puts("pci_hose_phys_to_bus: invalid physical address\n"); + return 0; } static phys_addr_t dm_pci_map_ea_virt(struct udevice *dev, int ea_off, diff --git a/include/pci.h b/include/pci.h index 5175c7ea2f..0a6b7a6f4b 100644 --- a/include/pci.h +++ b/include/pci.h @@ -1318,11 +1318,12 @@ u32 dm_pci_read_bar32(const struct udevice *dev, int barnum); * @dev: Device containing the PCI address * @addr: PCI address to convert * @len: Length of the address range + * @mask: Mask to match flags for the region type * @flags: Flags for the region type (PCI_REGION_...) * Return: physical address corresponding to that PCI bus address */ phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t addr, size_t len, - unsigned long flags); + unsigned long mask, unsigned long flags); /** * dm_pci_phys_to_bus() - convert a physical address to a PCI bus address @@ -1330,11 +1331,12 @@ phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t addr, size_t len, * @dev: Device containing the bus address * @addr: Physical address to convert * @len: Length of the address range + * @mask: Mask to match flags for the region type * @flags: Flags for the region type (PCI_REGION_...) * Return: PCI bus address corresponding to that physical address */ pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr, size_t len, - unsigned long flags); + unsigned long mask, unsigned long flags); /** * dm_pci_map_bar() - get a virtual address associated with a BAR region @@ -1458,19 +1460,19 @@ int dm_pci_find_ext_capability(struct udevice *dev, int cap); int dm_pci_flr(struct udevice *dev); #define dm_pci_virt_to_bus(dev, addr, flags) \ - dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), 0, (flags)) + dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), 0, PCI_REGION_TYPE, (flags)) #define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \ - map_physmem(dm_pci_bus_to_phys(dev, (addr), (len), (flags)), \ + map_physmem(dm_pci_bus_to_phys(dev, (addr), (len), PCI_REGION_TYPE, (flags)), \ (len), (map_flags)) #define dm_pci_phys_to_mem(dev, addr) \ - dm_pci_phys_to_bus((dev), (addr), 0, PCI_REGION_MEM) + dm_pci_phys_to_bus((dev), (addr), 0, PCI_REGION_TYPE, PCI_REGION_MEM) #define dm_pci_mem_to_phys(dev, addr) \ - dm_pci_bus_to_phys((dev), (addr), 0, PCI_REGION_MEM) + dm_pci_bus_to_phys((dev), (addr), 0, PCI_REGION_TYPE, PCI_REGION_MEM) #define dm_pci_phys_to_io(dev, addr) \ - dm_pci_phys_to_bus((dev), (addr), 0, PCI_REGION_IO) + dm_pci_phys_to_bus((dev), (addr), 0, PCI_REGION_TYPE, PCI_REGION_IO) #define dm_pci_io_to_phys(dev, addr) \ - dm_pci_bus_to_phys((dev), (addr), 0, PCI_REGION_IO) + dm_pci_bus_to_phys((dev), (addr), 0, PCI_REGION_TYPE, PCI_REGION_IO) #define dm_pci_virt_to_mem(dev, addr) \ dm_pci_virt_to_bus((dev), (addr), PCI_REGION_MEM) diff --git a/test/dm/pci.c b/test/dm/pci.c index 9ae7840bdd..3b4bd652fb 100644 --- a/test/dm/pci.c +++ b/test/dm/pci.c @@ -383,45 +383,47 @@ DM_TEST(dm_test_pci_region_multi, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); */ static int dm_test_pci_bus_to_phys(struct unit_test_state *uts) { + unsigned long mask = PCI_REGION_TYPE; + unsigned long flags = PCI_REGION_MEM; struct udevice *dev; phys_addr_t phys_addr; ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x08, 0), &dev)); /* Before any of the ranges. */ - phys_addr = dm_pci_bus_to_phys(dev, 0x20000000, 0x400, PCI_REGION_MEM); + phys_addr = dm_pci_bus_to_phys(dev, 0x20000000, 0x400, mask, flags); ut_asserteq(0, phys_addr); /* Identity range: whole, start, mid, end */ - phys_addr = dm_pci_bus_to_phys(dev, 0x2ffff000, 0x2000, PCI_REGION_MEM); + phys_addr = dm_pci_bus_to_phys(dev, 0x2ffff000, 0x2000, mask, flags); ut_asserteq(0, phys_addr); - phys_addr = dm_pci_bus_to_phys(dev, 0x30000000, 0x2000, PCI_REGION_MEM); + phys_addr = dm_pci_bus_to_phys(dev, 0x30000000, 0x2000, mask, flags); ut_asserteq(0x30000000, phys_addr); - phys_addr = dm_pci_bus_to_phys(dev, 0x30000000, 0x1000, PCI_REGION_MEM); + phys_addr = dm_pci_bus_to_phys(dev, 0x30000000, 0x1000, mask, flags); ut_asserteq(0x30000000, phys_addr); - phys_addr = dm_pci_bus_to_phys(dev, 0x30000abc, 0x12, PCI_REGION_MEM); + phys_addr = dm_pci_bus_to_phys(dev, 0x30000abc, 0x12, mask, flags); ut_asserteq(0x30000abc, phys_addr); - phys_addr = dm_pci_bus_to_phys(dev, 0x30000800, 0x1800, PCI_REGION_MEM); + phys_addr = dm_pci_bus_to_phys(dev, 0x30000800, 0x1800, mask, flags); ut_asserteq(0x30000800, phys_addr); - phys_addr = dm_pci_bus_to_phys(dev, 0x30008000, 0x1801, PCI_REGION_MEM); + phys_addr = dm_pci_bus_to_phys(dev, 0x30008000, 0x1801, mask, flags); ut_asserteq(0, phys_addr); /* Translated range: whole, start, mid, end */ - phys_addr = dm_pci_bus_to_phys(dev, 0x30fff000, 0x2000, PCI_REGION_MEM); + phys_addr = dm_pci_bus_to_phys(dev, 0x30fff000, 0x2000, mask, flags); ut_asserteq(0, phys_addr); - phys_addr = dm_pci_bus_to_phys(dev, 0x31000000, 0x2000, PCI_REGION_MEM); + phys_addr = dm_pci_bus_to_phys(dev, 0x31000000, 0x2000, mask, flags); ut_asserteq(0x3e000000, phys_addr); - phys_addr = dm_pci_bus_to_phys(dev, 0x31000000, 0x1000, PCI_REGION_MEM); + phys_addr = dm_pci_bus_to_phys(dev, 0x31000000, 0x1000, mask, flags); ut_asserteq(0x3e000000, phys_addr); - phys_addr = dm_pci_bus_to_phys(dev, 0x31000abc, 0x12, PCI_REGION_MEM); + phys_addr = dm_pci_bus_to_phys(dev, 0x31000abc, 0x12, mask, flags); ut_asserteq(0x3e000abc, phys_addr); - phys_addr = dm_pci_bus_to_phys(dev, 0x31000800, 0x1800, PCI_REGION_MEM); + phys_addr = dm_pci_bus_to_phys(dev, 0x31000800, 0x1800, mask, flags); ut_asserteq(0x3e000800, phys_addr); - phys_addr = dm_pci_bus_to_phys(dev, 0x31008000, 0x1801, PCI_REGION_MEM); + phys_addr = dm_pci_bus_to_phys(dev, 0x31008000, 0x1801, mask, flags); ut_asserteq(0, phys_addr); /* Beyond all of the ranges. */ - phys_addr = dm_pci_bus_to_phys(dev, 0x32000000, 0x400, PCI_REGION_MEM); + phys_addr = dm_pci_bus_to_phys(dev, 0x32000000, 0x400, mask, flags); ut_asserteq(0, phys_addr); return 0; @@ -434,45 +436,47 @@ DM_TEST(dm_test_pci_bus_to_phys, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); */ static int dm_test_pci_phys_to_bus(struct unit_test_state *uts) { + unsigned long mask = PCI_REGION_TYPE; + unsigned long flags = PCI_REGION_MEM; struct udevice *dev; pci_addr_t pci_addr; ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(1, 0x08, 0), &dev)); /* Before any of the ranges. */ - pci_addr = dm_pci_phys_to_bus(dev, 0x20000000, 0x400, PCI_REGION_MEM); + pci_addr = dm_pci_phys_to_bus(dev, 0x20000000, 0x400, mask, flags); ut_asserteq(0, pci_addr); /* Identity range: partial overlap, whole, start, mid, end */ - pci_addr = dm_pci_phys_to_bus(dev, 0x2ffff000, 0x2000, PCI_REGION_MEM); + pci_addr = dm_pci_phys_to_bus(dev, 0x2ffff000, 0x2000, mask, flags); ut_asserteq(0, pci_addr); - pci_addr = dm_pci_phys_to_bus(dev, 0x30000000, 0x2000, PCI_REGION_MEM); + pci_addr = dm_pci_phys_to_bus(dev, 0x30000000, 0x2000, mask, flags); ut_asserteq(0x30000000, pci_addr); - pci_addr = dm_pci_phys_to_bus(dev, 0x30000000, 0x1000, PCI_REGION_MEM); + pci_addr = dm_pci_phys_to_bus(dev, 0x30000000, 0x1000, mask, flags); ut_asserteq(0x30000000, pci_addr); - pci_addr = dm_pci_phys_to_bus(dev, 0x30000abc, 0x12, PCI_REGION_MEM); + pci_addr = dm_pci_phys_to_bus(dev, 0x30000abc, 0x12, mask, flags); ut_asserteq(0x30000abc, pci_addr); - pci_addr = dm_pci_phys_to_bus(dev, 0x30000800, 0x1800, PCI_REGION_MEM); + pci_addr = dm_pci_phys_to_bus(dev, 0x30000800, 0x1800, mask, flags); ut_asserteq(0x30000800, pci_addr); - pci_addr = dm_pci_phys_to_bus(dev, 0x30008000, 0x1801, PCI_REGION_MEM); + pci_addr = dm_pci_phys_to_bus(dev, 0x30008000, 0x1801, mask, flags); ut_asserteq(0, pci_addr); /* Translated range: partial overlap, whole, start, mid, end */ - pci_addr = dm_pci_phys_to_bus(dev, 0x3dfff000, 0x2000, PCI_REGION_MEM); + pci_addr = dm_pci_phys_to_bus(dev, 0x3dfff000, 0x2000, mask, flags); ut_asserteq(0, pci_addr); - pci_addr = dm_pci_phys_to_bus(dev, 0x3e000000, 0x2000, PCI_REGION_MEM); + pci_addr = dm_pci_phys_to_bus(dev, 0x3e000000, 0x2000, mask, flags); ut_asserteq(0x31000000, pci_addr); - pci_addr = dm_pci_phys_to_bus(dev, 0x3e000000, 0x1000, PCI_REGION_MEM); + pci_addr = dm_pci_phys_to_bus(dev, 0x3e000000, 0x1000, mask, flags); ut_asserteq(0x31000000, pci_addr); - pci_addr = dm_pci_phys_to_bus(dev, 0x3e000abc, 0x12, PCI_REGION_MEM); + pci_addr = dm_pci_phys_to_bus(dev, 0x3e000abc, 0x12, mask, flags); ut_asserteq(0x31000abc, pci_addr); - pci_addr = dm_pci_phys_to_bus(dev, 0x3e000800, 0x1800, PCI_REGION_MEM); + pci_addr = dm_pci_phys_to_bus(dev, 0x3e000800, 0x1800, mask, flags); ut_asserteq(0x31000800, pci_addr); - pci_addr = dm_pci_phys_to_bus(dev, 0x3e008000, 0x1801, PCI_REGION_MEM); + pci_addr = dm_pci_phys_to_bus(dev, 0x3e008000, 0x1801, mask, flags); ut_asserteq(0, pci_addr); /* Beyond all of the ranges. */ - pci_addr = dm_pci_phys_to_bus(dev, 0x3f000000, 0x400, PCI_REGION_MEM); + pci_addr = dm_pci_phys_to_bus(dev, 0x3f000000, 0x400, mask, flags); ut_asserteq(0, pci_addr); return 0; -- 2.36.0.rc2.479.g8af0fa9b8e-goog