From patchwork Mon Dec 20 15:54:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 12688169 X-Patchwork-Delegate: bhelgaas@google.com 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48311C433EF for ; Mon, 20 Dec 2021 15:55:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237503AbhLTPzT (ORCPT ); Mon, 20 Dec 2021 10:55:19 -0500 Received: from dfw.source.kernel.org ([139.178.84.217]:45210 "EHLO dfw.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237502AbhLTPzT (ORCPT ); Mon, 20 Dec 2021 10:55:19 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id BC602611DF for ; Mon, 20 Dec 2021 15:55:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 00140C36AE5; Mon, 20 Dec 2021 15:55:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1640015718; bh=HF3h4z3qkbQ4eaFsuVo4AJ/cKjp2Rsn5kvqg2b92TQI=; h=From:To:Subject:Date:From; b=iSUqvoIdVRkkw7axdM7h3LLWw8e83sGu61beAmbNmTSQj681vIqwtg5F+/GH4a48y 4U+Jlxzng4FNxNnBvIwkInrzPkGij2waCjnQWkp+FVHszOyVX/wVFb+dQWSd1Jq2Ll qN6fYs0zJ2Y4PXLCE2DHoGwfmkAF5AkBGDZcbAq0OWlHrblFxH9Sje8r/OvJsSH5/j vGpod5WdyUTTIxYY0qCjjIEhEbn/3+ugEhnNYJJA8XjhcXgo2KiZJb0eWhmIf0J9wT SnG6GMFprWyiiV4yxWmBKq9vwj8jH17HY4TwxhgJtF/T8aOjoI6H1DoBkUchmF9Nca 0/JKVB94CCgBA== Received: by pali.im (Postfix) id 0B69287B; Mon, 20 Dec 2021 16:55:15 +0100 (CET) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: Martin Mares , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Matthew Wilcox , linux-pci@vger.kernel.org Subject: [PATCH pciutils 1/4] lspci: Show 16/32/64 bit width for address ranges behind bridge Date: Mon, 20 Dec 2021 16:54:45 +0100 Message-Id: <20211220155448.1233-1-pali@kernel.org> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Type of address range is encoded in lower bits. --- lspci.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lspci.c b/lspci.c index aba2745a9192..17649a0540fa 100644 --- a/lspci.c +++ b/lspci.c @@ -374,12 +374,12 @@ show_size(u64 x) } static void -show_range(char *prefix, u64 base, u64 limit, int is_64bit) +show_range(char *prefix, u64 base, u64 limit, int bits) { printf("%s:", prefix); if (base <= limit || verbose > 2) { - if (is_64bit) + if (bits > 32) printf(" %016" PCI_U64_FMT_X "-%016" PCI_U64_FMT_X, base, limit); else printf(" %08x-%08x", (unsigned) base, (unsigned) limit); @@ -388,6 +388,7 @@ show_range(char *prefix, u64 base, u64 limit, int is_64bit) show_size(limit - base + 1); else printf(" [disabled]"); + printf(" [%d-bit]", bits); putchar('\n'); } @@ -578,7 +579,7 @@ show_htype1(struct device *d) io_base |= (get_conf_word(d, PCI_IO_BASE_UPPER16) << 16); io_limit |= (get_conf_word(d, PCI_IO_LIMIT_UPPER16) << 16); } - show_range("\tI/O behind bridge", io_base, io_limit+0xfff, 0); + show_range("\tI/O behind bridge", io_base, io_limit+0xfff, (io_type == PCI_IO_RANGE_TYPE_32) ? 32 : 16); } if (mem_type != (mem_limit & PCI_MEMORY_RANGE_TYPE_MASK) || @@ -588,7 +589,7 @@ show_htype1(struct device *d) { mem_base = (mem_base & PCI_MEMORY_RANGE_MASK) << 16; mem_limit = (mem_limit & PCI_MEMORY_RANGE_MASK) << 16; - show_range("\tMemory behind bridge", mem_base, mem_limit + 0xfffff, 0); + show_range("\tMemory behind bridge", mem_base, mem_limit + 0xfffff, 32); } if (pref_type != (pref_limit & PCI_PREF_RANGE_TYPE_MASK) || @@ -603,7 +604,7 @@ show_htype1(struct device *d) pref_base_64 |= (u64) get_conf_long(d, PCI_PREF_BASE_UPPER32) << 32; pref_limit_64 |= (u64) get_conf_long(d, PCI_PREF_LIMIT_UPPER32) << 32; } - show_range("\tPrefetchable memory behind bridge", pref_base_64, pref_limit_64 + 0xfffff, (pref_type == PCI_PREF_RANGE_TYPE_64)); + show_range("\tPrefetchable memory behind bridge", pref_base_64, pref_limit_64 + 0xfffff, (pref_type == PCI_PREF_RANGE_TYPE_64) ? 64 : 32); } if (verbose > 1) From patchwork Mon Dec 20 15:54:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 12688171 X-Patchwork-Delegate: bhelgaas@google.com 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B9C5C433FE for ; Mon, 20 Dec 2021 15:55:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237502AbhLTPzT (ORCPT ); Mon, 20 Dec 2021 10:55:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50216 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231790AbhLTPzT (ORCPT ); Mon, 20 Dec 2021 10:55:19 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18C61C061574 for ; Mon, 20 Dec 2021 07:55:19 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id AAF7D611F9 for ; Mon, 20 Dec 2021 15:55:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E2348C36AE7; Mon, 20 Dec 2021 15:55:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1640015718; bh=oqc0GOf2gWxFxNbGatLX3dSDjwrvM0cZ3p6+/fjmhNg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=XMQYOiXBjC4PIj6fEjkrSNRVSSNPEJvm4LJBUZ9w6B9xTbuJ9+BheBP3ooZL155mD ddpploF2g2RokTbQDRjNUqQ+jCmoUZb7CyUoITb7qZt6GgBxQoL0rgEjibXZcu2UYH LTj+qGCOuSmTf0yjcrhhCL1dSKqUmbFIk6LMqeukMbAdSdIDSLRRXSg8+GocFCUsMp Q6AdREteG4P9XdtnBP60Yrtgks6pIpMUFNZoG/7ujkW6nRIZrss20u5jBrRfwiHFTi UWqTIeFz+e0PwYhrEOZrPQRFOCpd422dIhDuVzwilzqxl3NSaWcJt/dCV+l7T11PF4 WlIAEsa7vIhBg== Received: by pali.im (Postfix) id 732D82860; Mon, 20 Dec 2021 16:55:15 +0100 (CET) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: Martin Mares , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Matthew Wilcox , linux-pci@vger.kernel.org Subject: [PATCH pciutils 2/4] lspci: Simplify printing range in show_range() Date: Mon, 20 Dec 2021 16:54:46 +0100 Message-Id: <20211220155448.1233-2-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20211220155448.1233-1-pali@kernel.org> References: <20211220155448.1233-1-pali@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Use just one printf() call with width format argument based on number of bits. --- lspci.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lspci.c b/lspci.c index 17649a0540fa..67ac19b61a29 100644 --- a/lspci.c +++ b/lspci.c @@ -378,12 +378,7 @@ show_range(char *prefix, u64 base, u64 limit, int bits) { printf("%s:", prefix); if (base <= limit || verbose > 2) - { - if (bits > 32) - printf(" %016" PCI_U64_FMT_X "-%016" PCI_U64_FMT_X, base, limit); - else - printf(" %08x-%08x", (unsigned) base, (unsigned) limit); - } + printf(" %0*" PCI_U64_FMT_X "-%0*" PCI_U64_FMT_X, (bits+3)/4, base, (bits+3)/4, limit); if (base <= limit) show_size(limit - base + 1); else From patchwork Mon Dec 20 15:54:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 12688175 X-Patchwork-Delegate: bhelgaas@google.com 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A0D5C433EF for ; Mon, 20 Dec 2021 15:55:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237536AbhLTPzW (ORCPT ); Mon, 20 Dec 2021 10:55:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50228 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237526AbhLTPzV (ORCPT ); Mon, 20 Dec 2021 10:55:21 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2B0FFC061574 for ; Mon, 20 Dec 2021 07:55:21 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id DBF2FB80ED8 for ; Mon, 20 Dec 2021 15:55:19 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 45F89C36AEC; Mon, 20 Dec 2021 15:55:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1640015718; bh=Oo9PjbLKtu4clAaya9aDZlITnMBZcc+oKWjQcMGljuQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=nkuky35Oxr4fY0WtjqqhQ4PUihDZOp2MMS7utbPI1WmYKeg7XjA5d0Oojv/nXRphS VcXAEpQ3BAywBw+3krGEhoDYrHEWMEbezjXDJaW4Uy3pL1TbagPNIbCD6os9ifBxta 8fgu4nEQ0JUorB+lje4YvZVTjs77UCqChZDbOgP2ThyEAf7zacwdrfnaEuURwxJREC orAgVUDMGXozbDGLPI8+W6Rh7TZrJSFF8AunyHjAQlHp9qZp36M66OsQ+75YLrsCpB VX7G4oe5wTX+Kf+NIIZg1l546g2IvQ9f7jAMyBEaTNawPwPZJIFkew4+BRsYN8qeF1 OlfkOdfLtXCEw== Received: by pali.im (Postfix) id F20E7286C; Mon, 20 Dec 2021 16:55:15 +0100 (CET) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: Martin Mares , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Matthew Wilcox , linux-pci@vger.kernel.org Subject: [PATCH pciutils 3/4] libpci: Add support for filling bridge resources Date: Mon, 20 Dec 2021 16:54:47 +0100 Message-Id: <20211220155448.1233-3-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20211220155448.1233-1-pali@kernel.org> References: <20211220155448.1233-1-pali@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Extend libpci API and ABI to fill bridge resources from sysfs. --- lib/access.c | 20 +++++++++++--------- lib/caps.c | 2 +- lib/filter.c | 2 +- lib/internal.h | 1 + lib/libpci.ver | 5 +++++ lib/pci.h | 4 ++++ lib/sysfs.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ 7 files changed, 65 insertions(+), 17 deletions(-) diff --git a/lib/access.c b/lib/access.c index b257849a685e..a33e067e2389 100644 --- a/lib/access.c +++ b/lib/access.c @@ -189,7 +189,7 @@ pci_reset_properties(struct pci_dev *d) } int -pci_fill_info_v35(struct pci_dev *d, int flags) +pci_fill_info_v38(struct pci_dev *d, int flags) { unsigned int uflags = flags; if (uflags & PCI_FILL_RESCAN) @@ -203,19 +203,21 @@ pci_fill_info_v35(struct pci_dev *d, int flags) } /* In version 3.1, pci_fill_info got new flags => versioned alias */ -/* In versions 3.2, 3.3, 3.4 and 3.5, the same has happened */ -STATIC_ALIAS(int pci_fill_info(struct pci_dev *d, int flags), pci_fill_info_v35(d, flags)); -DEFINE_ALIAS(int pci_fill_info_v30(struct pci_dev *d, int flags), pci_fill_info_v35); -DEFINE_ALIAS(int pci_fill_info_v31(struct pci_dev *d, int flags), pci_fill_info_v35); -DEFINE_ALIAS(int pci_fill_info_v32(struct pci_dev *d, int flags), pci_fill_info_v35); -DEFINE_ALIAS(int pci_fill_info_v33(struct pci_dev *d, int flags), pci_fill_info_v35); -DEFINE_ALIAS(int pci_fill_info_v34(struct pci_dev *d, int flags), pci_fill_info_v35); +/* In versions 3.2, 3.3, 3.4, 3.5 and 3.8, the same has happened */ +STATIC_ALIAS(int pci_fill_info(struct pci_dev *d, int flags), pci_fill_info_v38(d, flags)); +DEFINE_ALIAS(int pci_fill_info_v30(struct pci_dev *d, int flags), pci_fill_info_v38); +DEFINE_ALIAS(int pci_fill_info_v31(struct pci_dev *d, int flags), pci_fill_info_v38); +DEFINE_ALIAS(int pci_fill_info_v32(struct pci_dev *d, int flags), pci_fill_info_v38); +DEFINE_ALIAS(int pci_fill_info_v33(struct pci_dev *d, int flags), pci_fill_info_v38); +DEFINE_ALIAS(int pci_fill_info_v34(struct pci_dev *d, int flags), pci_fill_info_v38); +DEFINE_ALIAS(int pci_fill_info_v35(struct pci_dev *d, int flags), pci_fill_info_v38); SYMBOL_VERSION(pci_fill_info_v30, pci_fill_info@LIBPCI_3.0); SYMBOL_VERSION(pci_fill_info_v31, pci_fill_info@LIBPCI_3.1); SYMBOL_VERSION(pci_fill_info_v32, pci_fill_info@LIBPCI_3.2); SYMBOL_VERSION(pci_fill_info_v33, pci_fill_info@LIBPCI_3.3); SYMBOL_VERSION(pci_fill_info_v34, pci_fill_info@LIBPCI_3.4); -SYMBOL_VERSION(pci_fill_info_v35, pci_fill_info@@LIBPCI_3.5); +SYMBOL_VERSION(pci_fill_info_v35, pci_fill_info@LIBPCI_3.5); +SYMBOL_VERSION(pci_fill_info_v38, pci_fill_info@@LIBPCI_3.8); void pci_setup_cache(struct pci_dev *d, byte *cache, int len) diff --git a/lib/caps.c b/lib/caps.c index c3b918059fe1..70a41b836e31 100644 --- a/lib/caps.c +++ b/lib/caps.c @@ -129,7 +129,7 @@ pci_find_cap_nr(struct pci_dev *d, unsigned int id, unsigned int type, unsigned int target = (cap_number ? *cap_number : 0); unsigned int index = 0; - pci_fill_info_v35(d, ((type == PCI_CAP_NORMAL) ? PCI_FILL_CAPS : PCI_FILL_EXT_CAPS)); + pci_fill_info_v38(d, ((type == PCI_CAP_NORMAL) ? PCI_FILL_CAPS : PCI_FILL_EXT_CAPS)); for (c=d->first_cap; c; c=c->next) { diff --git a/lib/filter.c b/lib/filter.c index 573fb2810363..195f813193c4 100644 --- a/lib/filter.c +++ b/lib/filter.c @@ -129,7 +129,7 @@ pci_filter_match_v33(struct pci_filter *f, struct pci_dev *d) return 0; if (f->device >= 0 || f->vendor >= 0) { - pci_fill_info_v35(d, PCI_FILL_IDENT); + pci_fill_info_v38(d, PCI_FILL_IDENT); if ((f->device >= 0 && f->device != d->device_id) || (f->vendor >= 0 && f->vendor != d->vendor_id)) return 0; diff --git a/lib/internal.h b/lib/internal.h index 17c27e194a29..4df8dd70c2c6 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -74,6 +74,7 @@ int pci_fill_info_v32(struct pci_dev *, int flags) VERSIONED_ABI; int pci_fill_info_v33(struct pci_dev *, int flags) VERSIONED_ABI; int pci_fill_info_v34(struct pci_dev *, int flags) VERSIONED_ABI; int pci_fill_info_v35(struct pci_dev *, int flags) VERSIONED_ABI; +int pci_fill_info_v38(struct pci_dev *, int flags) VERSIONED_ABI; struct pci_property { struct pci_property *next; diff --git a/lib/libpci.ver b/lib/libpci.ver index e20c3f581c71..73f7fa71e357 100644 --- a/lib/libpci.ver +++ b/lib/libpci.ver @@ -82,3 +82,8 @@ LIBPCI_3.7 { global: pci_find_cap_nr; }; + +LIBPCI_3.8 { + global: + pci_fill_info; +}; diff --git a/lib/pci.h b/lib/pci.h index 814247691086..0ec7f211ca24 100644 --- a/lib/pci.h +++ b/lib/pci.h @@ -142,6 +142,9 @@ struct pci_dev { pciaddr_t flags[6]; /* PCI_IORESOURCE_* flags for regions */ pciaddr_t rom_flags; /* PCI_IORESOURCE_* flags for expansion ROM */ int domain; /* PCI domain (host bridge) */ + pciaddr_t bridge_base_addr[4]; /* Bridge base addresses (without flags) */ + pciaddr_t bridge_size[4]; /* Bridge sizes */ + pciaddr_t bridge_flags[4]; /* PCI_IORESOURCE_* flags for bridge addresses */ /* Fields used internally */ struct pci_access *access; @@ -205,6 +208,7 @@ char *pci_get_string_property(struct pci_dev *d, u32 prop) PCI_ABI; #define PCI_FILL_IO_FLAGS 0x1000 #define PCI_FILL_DT_NODE 0x2000 /* Device tree node */ #define PCI_FILL_IOMMU_GROUP 0x4000 +#define PCI_FILL_BRIDGE_BASES 0x8000 #define PCI_FILL_RESCAN 0x00010000 void pci_setup_cache(struct pci_dev *, u8 *cache, int len) PCI_ABI; diff --git a/lib/sysfs.c b/lib/sysfs.c index fb6424105e84..7c157a2688ad 100644 --- a/lib/sysfs.c +++ b/lib/sysfs.c @@ -148,19 +148,22 @@ sysfs_get_value(struct pci_dev *d, char *object, int mandatory) return -1; } -static void +static unsigned int sysfs_get_resources(struct pci_dev *d) { struct pci_access *a = d->access; char namebuf[OBJNAMELEN], buf[256]; + struct { pciaddr_t flags, base_addr, size; } lines[10]; + unsigned int done; FILE *file; int i; + done = 0; sysfs_obj_name(d, "resource", namebuf); file = fopen(namebuf, "r"); if (!file) a->error("Cannot open %s: %s", namebuf, strerror(errno)); - for (i = 0; i < 7; i++) + for (i = 0; i < 7+6+4+1; i++) { unsigned long long start, end, size, flags; if (!fgets(buf, sizeof(buf), file)) @@ -177,16 +180,50 @@ sysfs_get_resources(struct pci_dev *d) flags &= PCI_ADDR_FLAG_MASK; d->base_addr[i] = start | flags; d->size[i] = size; + done |= PCI_FILL_BASES | PCI_FILL_SIZES | PCI_FILL_IO_FLAGS; } - else + else if (i == 6) { d->rom_flags = flags; flags &= PCI_ADDR_FLAG_MASK; d->rom_base_addr = start | flags; d->rom_size = size; + done |= PCI_FILL_ROM_BASE; } + else if (i < 7+6+4) + { + /* + * If kernel was compiled without CONFIG_PCI_IOV option then after + * the ROM line for configured bridge device (that which had set + * subordinary bus number to non-zero value) are four additional lines + * which describe resources behind bridge. For PCI-to-PCI bridges they + * are: IO, MEM, PREFMEM and empty. For CardBus bridges they are: IO0, + * IO1, MEM0 and MEM1. For unconfigured bridges and other devices + * there is no additional line after the ROM line. If kernel was + * compiled with CONFIG_PCI_IOV option then after the ROM line and + * before the first bridge resource line are six additional lines + * which describe IOV resources. Read all remaining lines in resource + * file and based on the number of remaining lines (0, 4, 6, 10) parse + * resources behind bridge. + */ + lines[i-7].flags = flags; + lines[i-7].base_addr = start; + lines[i-7].size = size; + } + } + if (i == 7+4 || i == 7+6+4) + { + int offset = (i == 7+6+4) ? 6 : 0; + for (i = 0; i < 4; i++) + { + d->bridge_flags[i] = lines[offset+i].flags; + d->bridge_base_addr[i] = lines[offset+i].base_addr; + d->bridge_size[i] = lines[offset+i].size; + } + done |= PCI_FILL_BRIDGE_BASES; } fclose(file); + return done; } static void sysfs_scan(struct pci_access *a) @@ -316,10 +353,9 @@ sysfs_fill_info(struct pci_dev *d, unsigned int flags) d->irq = sysfs_get_value(d, "irq", 1); done |= PCI_FILL_IRQ; } - if (flags & (PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES | PCI_FILL_IO_FLAGS)) + if (flags & (PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES | PCI_FILL_IO_FLAGS | PCI_FILL_BRIDGE_BASES)) { - sysfs_get_resources(d); - done |= PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES | PCI_FILL_IO_FLAGS; + done |= sysfs_get_resources(d); } } From patchwork Mon Dec 20 15:54:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 12688173 X-Patchwork-Delegate: bhelgaas@google.com 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 99BAEC4332F for ; Mon, 20 Dec 2021 15:55:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237493AbhLTPzU (ORCPT ); Mon, 20 Dec 2021 10:55:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50222 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237485AbhLTPzU (ORCPT ); Mon, 20 Dec 2021 10:55:20 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3ADE7C061574 for ; Mon, 20 Dec 2021 07:55:20 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id CDD4F611F9 for ; Mon, 20 Dec 2021 15:55:19 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E06DDC36AEA; Mon, 20 Dec 2021 15:55:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1640015719; bh=T05/YNjPFDghICfDXkICo0Bm+dd7+FNtzHl70nXgzvY=; h=From:To:Subject:Date:In-Reply-To:References:From; b=cWIjyk8bgKzxm+UmeyXR3NtxHgaGxmdlGKKWs+nUjwTvGboPNQKtec3l+c/yPAEF3 aGo8aSn5Iyqg0rWSGpWI5r2Kiy+fxvsVXxAlo001EAc/a4PveJF2oo2OKQo2nrFzP4 o82irEZOeQ0Db/P7IsUWmKqSvGj7ADTDrYUDNIyVt1BFT4Rp9M/roZq40XArKLpi5E dIrTEinlKnYyU70Taq75V+wOaOkl96akd2o+hOjZ7h0xzxq7W51vcKbj1LQuXM9CUe XloIAoEBIr/XMmf2i/33DNx/XOAqHsa1h/r6BWF3CPbbhxjnNpbh8y8uc8EsAxc4D8 n/mLTAbXKDZOQ== Received: by pali.im (Postfix) id 85FF92879; Mon, 20 Dec 2021 16:55:16 +0100 (CET) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: Martin Mares , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Matthew Wilcox , linux-pci@vger.kernel.org Subject: [PATCH pciutils 4/4] lspci: Use PCI_FILL_BRIDGE_BASES to detect if range behind bridge is disabled or unsupported Date: Mon, 20 Dec 2021 16:54:48 +0100 Message-Id: <20211220155448.1233-4-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20211220155448.1233-1-pali@kernel.org> References: <20211220155448.1233-1-pali@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Show resources behind bridge as reported by PCI_FILL_BRIDGE_BASES. I/O or Prefetchable memory behind bridge is unsupported by bridge if both base and limit bridge registers are read-only and returns zero. So if base and limit registers returns zero (which is valid enabled range) and kernel reports that particular resource is disabled it means that resource is unsupported. Both I/O or Prefetchable memory resources are only optional. --- lspci.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/lspci.c b/lspci.c index 67ac19b61a29..d14d1b9185d6 100644 --- a/lspci.c +++ b/lspci.c @@ -374,12 +374,12 @@ show_size(u64 x) } static void -show_range(char *prefix, u64 base, u64 limit, int bits) +show_range(char *prefix, u64 base, u64 limit, int bits, int disabled) { printf("%s:", prefix); if (base <= limit || verbose > 2) printf(" %0*" PCI_U64_FMT_X "-%0*" PCI_U64_FMT_X, (bits+3)/4, base, (bits+3)/4, limit); - if (base <= limit) + if (!disabled && base <= limit) show_size(limit - base + 1); else printf(" [disabled]"); @@ -543,6 +543,7 @@ show_htype0(struct device *d) static void show_htype1(struct device *d) { + struct pci_dev *p = d->dev; u32 io_base = get_conf_byte(d, PCI_IO_BASE); u32 io_limit = get_conf_byte(d, PCI_IO_LIMIT); u32 io_type = io_base & PCI_IO_RANGE_TYPE_MASK; @@ -554,6 +555,10 @@ show_htype1(struct device *d) u32 pref_type = pref_base & PCI_PREF_RANGE_TYPE_MASK; word sec_stat = get_conf_word(d, PCI_SEC_STATUS); word brc = get_conf_word(d, PCI_BRIDGE_CONTROL); + int io_disabled = (p->known_fields & PCI_FILL_BRIDGE_BASES) && !p->bridge_size[0]; + int mem_disabled = (p->known_fields & PCI_FILL_BRIDGE_BASES) && !p->bridge_size[1]; + int pref_disabled = (p->known_fields & PCI_FILL_BRIDGE_BASES) && !p->bridge_size[2]; + int io_bits, pref_bits; show_bases(d, 2); printf("\tBus: primary=%02x, secondary=%02x, subordinate=%02x, sec-latency=%d\n", @@ -562,7 +567,15 @@ show_htype1(struct device *d) get_conf_byte(d, PCI_SUBORDINATE_BUS), get_conf_byte(d, PCI_SEC_LATENCY_TIMER)); - if (io_type != (io_limit & PCI_IO_RANGE_TYPE_MASK) || + if ((p->known_fields & PCI_FILL_BRIDGE_BASES) && !io_disabled) + { + io_base = p->bridge_base_addr[0] & PCI_IO_RANGE_MASK; + io_limit = io_base + p->bridge_size[0] - 1; + io_type = p->bridge_base_addr[0] & PCI_IO_RANGE_TYPE_MASK; + io_bits = (io_type == PCI_IO_RANGE_TYPE_32) ? 32 : 16; + show_range("\tI/O behind bridge", io_base, io_limit, io_bits, io_disabled); + } + else if (io_type != (io_limit & PCI_IO_RANGE_TYPE_MASK) || (io_type != PCI_IO_RANGE_TYPE_16 && io_type != PCI_IO_RANGE_TYPE_32)) printf("\t!!! Unknown I/O range types %x/%x\n", io_base, io_limit); else @@ -574,20 +587,40 @@ show_htype1(struct device *d) io_base |= (get_conf_word(d, PCI_IO_BASE_UPPER16) << 16); io_limit |= (get_conf_word(d, PCI_IO_LIMIT_UPPER16) << 16); } - show_range("\tI/O behind bridge", io_base, io_limit+0xfff, (io_type == PCI_IO_RANGE_TYPE_32) ? 32 : 16); + /* I/O is unsupported if both base and limit are zeros and resource is disabled */ + if (!(io_base == 0x0 && io_limit == 0x0 && io_disabled)) + { + io_limit += 0xfff; + io_bits = (io_type == PCI_IO_RANGE_TYPE_32) ? 32 : 16; + show_range("\tI/O behind bridge", io_base, io_limit, io_bits, io_disabled); + } } - if (mem_type != (mem_limit & PCI_MEMORY_RANGE_TYPE_MASK) || + if ((p->known_fields & PCI_FILL_BRIDGE_BASES) && !mem_disabled) + { + mem_base = p->bridge_base_addr[1] & PCI_MEMORY_RANGE_MASK; + mem_limit = mem_base + p->bridge_size[1] - 1; + show_range("\tMemory behind bridge", mem_base, mem_limit, 32, mem_disabled); + } + else if (mem_type != (mem_limit & PCI_MEMORY_RANGE_TYPE_MASK) || mem_type) printf("\t!!! Unknown memory range types %x/%x\n", mem_base, mem_limit); else { mem_base = (mem_base & PCI_MEMORY_RANGE_MASK) << 16; mem_limit = (mem_limit & PCI_MEMORY_RANGE_MASK) << 16; - show_range("\tMemory behind bridge", mem_base, mem_limit + 0xfffff, 32); + show_range("\tMemory behind bridge", mem_base, mem_limit + 0xfffff, 32, mem_disabled); } - if (pref_type != (pref_limit & PCI_PREF_RANGE_TYPE_MASK) || + if ((p->known_fields & PCI_FILL_BRIDGE_BASES) && !pref_disabled) + { + u64 pref_base_64 = p->bridge_base_addr[2] & PCI_MEMORY_RANGE_MASK; + u64 pref_limit_64 = pref_base_64 + p->bridge_size[2] - 1; + pref_type = p->bridge_base_addr[2] & PCI_MEMORY_RANGE_TYPE_MASK; + pref_bits = (pref_type == PCI_PREF_RANGE_TYPE_64) ? 64 : 32; + show_range("\tPrefetchable memory behind bridge", pref_base_64, pref_limit_64, pref_bits, pref_disabled); + } + else if (pref_type != (pref_limit & PCI_PREF_RANGE_TYPE_MASK) || (pref_type != PCI_PREF_RANGE_TYPE_32 && pref_type != PCI_PREF_RANGE_TYPE_64)) printf("\t!!! Unknown prefetchable memory range types %x/%x\n", pref_base, pref_limit); else @@ -599,7 +632,13 @@ show_htype1(struct device *d) pref_base_64 |= (u64) get_conf_long(d, PCI_PREF_BASE_UPPER32) << 32; pref_limit_64 |= (u64) get_conf_long(d, PCI_PREF_LIMIT_UPPER32) << 32; } - show_range("\tPrefetchable memory behind bridge", pref_base_64, pref_limit_64 + 0xfffff, (pref_type == PCI_PREF_RANGE_TYPE_64) ? 64 : 32); + /* Prefetchable memory is unsupported if both base and limit are zeros and resource is disabled */ + if (!(pref_base_64 == 0x0 && pref_limit_64 == 0x0 && pref_disabled)) + { + pref_limit_64 += 0xfffff; + pref_bits = (pref_type == PCI_PREF_RANGE_TYPE_64) ? 64 : 32; + show_range("\tPrefetchable memory behind bridge", pref_base_64, pref_limit_64, pref_bits, pref_disabled); + } } if (verbose > 1) @@ -726,7 +765,8 @@ show_verbose(struct device *d) show_terse(d); pci_fill_info(p, PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES | - PCI_FILL_PHYS_SLOT | PCI_FILL_NUMA_NODE | PCI_FILL_DT_NODE | PCI_FILL_IOMMU_GROUP); + PCI_FILL_PHYS_SLOT | PCI_FILL_NUMA_NODE | PCI_FILL_DT_NODE | PCI_FILL_IOMMU_GROUP | + PCI_FILL_BRIDGE_BASES); irq = p->irq; switch (htype)