From patchwork Sat Dec 12 01:15:21 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Daney X-Patchwork-Id: 7833491 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A4669BEEE1 for ; Sat, 12 Dec 2015 01:15:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 650B720454 for ; Sat, 12 Dec 2015 01:15:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 073522041E for ; Sat, 12 Dec 2015 01:15:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754113AbbLLBP3 (ORCPT ); Fri, 11 Dec 2015 20:15:29 -0500 Received: from mail-ig0-f179.google.com ([209.85.213.179]:33295 "EHLO mail-ig0-f179.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751029AbbLLBP2 (ORCPT ); Fri, 11 Dec 2015 20:15:28 -0500 Received: by mail-ig0-f179.google.com with SMTP id mv3so51279040igc.0 for ; Fri, 11 Dec 2015 17:15:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=KxXxunwpUi337ZdMtxvR+IhcmYNkrlyDvlZ0ElJLII8=; b=bgGNSeexg/IgBIOC5PKF+5mrE/uJuqqnZiHswziXVnpwnW8O/Qvx8G+NoM6+sFGPKm X1OR9Nu/gA77dKOXh95XfVyzVQfHt6UXIfQ3tFI+4KIf+vimhuDW0m5vB4Lu1cu2hIPg 7FgmALhZkjEPgsEj+K/SjjXEtMasxADCv/d4eV2CxP54VXQE7kuMqsRoY1bnQlpE935S YlZmR4A0ImNvE1wqyZ7S0bkQzo1vuc44EnjFFRW2CnXSjVTKOPlxbCZkHtdx2AWY65N5 WbL7gHEZD3Xg8BtTG7i0MxurZBL8czh82JfO9la3WB+kU78MDt9uMfZjezN/weMACmRc HUoA== X-Received: by 10.50.55.66 with SMTP id q2mr6724959igp.97.1449882927724; Fri, 11 Dec 2015 17:15:27 -0800 (PST) Received: from dl.caveonetworks.com ([64.2.3.194]) by smtp.gmail.com with ESMTPSA id v85sm7894854ioi.20.2015.12.11.17.15.25 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 11 Dec 2015 17:15:25 -0800 (PST) Received: from dl.caveonetworks.com (localhost.localdomain [127.0.0.1]) by dl.caveonetworks.com (8.14.5/8.14.5) with ESMTP id tBC1FOZB005198; Fri, 11 Dec 2015 17:15:24 -0800 Received: (from ddaney@localhost) by dl.caveonetworks.com (8.14.5/8.14.5/Submit) id tBC1FOIU005197; Fri, 11 Dec 2015 17:15:24 -0800 From: David Daney To: Martin Mares Cc: Bjorn Helgaas , linux-pci@vger.kernel.org, "Sean O. Stalley" , David Daney Subject: [PATCH v2] Add lspci support for Enhanced Allocation Capability. Date: Fri, 11 Dec 2015 17:15:21 -0800 Message-Id: <1449882921-5165-1-git-send-email-ddaney.cavm@gmail.com> X-Mailer: git-send-email 1.7.11.7 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: David Daney The PCISIG recently added the Enhanced Allocation Capability. Decode it in lspci. --- The specification is currently located here: https://pcisig.com/sites/default/files/specification_documents/ECN_Enhanced_Allocation_23_Oct_2014_Final.pdf Bjorn Helgaas recently merged Linux kernel support for EA, and Cavium ThunderX processors have implemented it. This patch gives us a pretty view of the capability structure. Changes from v1: Add and use more symbolic names. Use FLAG() macro where appropiate. Read subordinate bus number from proper offset. Thanks, David Daney lib/header.h | 8 ++++ ls-caps.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) diff --git a/lib/header.h b/lib/header.h index f7cdee7..b8f7dc1 100644 --- a/lib/header.h +++ b/lib/header.h @@ -203,6 +203,7 @@ #define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ #define PCI_CAP_ID_SATA 0x12 /* Serial-ATA HBA */ #define PCI_CAP_ID_AF 0x13 /* Advanced features of PCI devices integrated in PCIe root cplx */ +#define PCI_CAP_ID_EA 0x14 /* Enhanced Allocation */ #define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */ #define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */ #define PCI_CAP_SIZEOF 4 @@ -906,6 +907,13 @@ #define PCI_SATA_HBA_BARS 4 #define PCI_SATA_HBA_REG0 8 +/* Enhanced Allocation (EA) */ +#define PCI_EA_CAP_TYPE1_SECONDARY 4 +#define PCI_EA_CAP_TYPE1_SUBORDINATE 5 +/* EA Entry header */ +#define PCI_EA_CAP_ENT_WRITABLE 0x40000000 /* Writable: 1 = RW, 0 = HwInit */ +#define PCI_EA_CAP_ENT_ENABLE 0x80000000 /* Enable for this entry */ + /*** Definitions of extended capabilities ***/ /* Advanced Error Reporting */ diff --git a/ls-caps.c b/ls-caps.c index c145ed6..f66b3e6 100644 --- a/ls-caps.c +++ b/ls-caps.c @@ -1254,6 +1254,143 @@ cap_sata_hba(struct device *d, int where, int cap) printf(" BAR??%d\n", bar); } +static const char *cap_ea_property(int p) +{ + switch (p) { + case 0x00: + return "memory space, non-prefetchable"; + case 0x01: + return "memory space, prefetchable"; + case 0x02: + return "I/O space"; + case 0x03: + return "VF memory space, prefetchable"; + case 0x04: + return "VF memory space, non-prefetchable"; + case 0x05: + return "allocation behind bridge, non-prefetchable memory"; + case 0x06: + return "allocation behind bridge, prefetchable memory"; + case 0x07: + return "allocation behind bridge, I/O space"; + case 0xfd: + return "memory space resource unavailable for use"; + case 0xfe: + return "I/O space resource unavailable for use"; + case 0xff: + return "entry unavailable for use"; + default: + return "reserved"; + } +} + +static void cap_ea(struct device *d, int where, int cap) +{ + int entry; + int entry_base = where + 4; + int num_entries = BITS(cap, 0, 6); + u8 htype = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f; + + printf("Enhanced Allocation: Num Entries=%u", num_entries); + if (htype == PCI_HEADER_TYPE_BRIDGE) { + byte fixed_sub, fixed_sec; + + entry_base += 4; + if (!config_fetch(d, where + 4, 2)) { + printf("\n"); + return; + } + fixed_sec = get_conf_byte(d, where + PCI_EA_CAP_TYPE1_SECONDARY); + fixed_sub = get_conf_byte(d, where + PCI_EA_CAP_TYPE1_SUBORDINATE); + printf(", secondary=%d, subordinate=%d", fixed_sec, fixed_sub); + } + printf("\n"); + if (verbose < 2) + return; + + for (entry = 0; entry < num_entries; entry++) { + int max_offset_high_pos, has_base_high, has_max_offset_high; + u32 entry_header; + u32 base, max_offset; + int es, bei, pp, sp; + + if (!config_fetch(d, entry_base, 4)) + return; + entry_header = get_conf_long(d, entry_base); + es = BITS(entry_header, 0, 3); + bei = BITS(entry_header, 4, 4); + pp = BITS(entry_header, 8, 8); + sp = BITS(entry_header, 16, 8); + if (!config_fetch(d, entry_base + 4, es * 4)) + return; + printf("\t\tEntry-%u: Enable%c Writable%c Entry Size: %u\n", entry, + FLAG(entry_header, PCI_EA_CAP_ENT_ENABLE), + FLAG(entry_header, PCI_EA_CAP_ENT_WRITABLE), es); + printf("\t\t\t BAR Equivalent Indicator (BEI): "); + switch (bei) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + printf("BAR%u", bei); + break; + case 6: + printf("Resource behind function"); + break; + case 7: + printf("Not Indicated"); + break; + case 8: + printf("Expansion ROM"); + break; + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + printf("VF-BAR%u", bei - 9); + break; + default: + printf("Reserved"); + break; + } + printf("\n"); + printf("\t\t\t Primary Properties (PP): %s\n", cap_ea_property(pp)); + printf("\t\t\t Secondary Properties (SP): %s\n", cap_ea_property(sp)); + + base = get_conf_long(d, entry_base + 4); + has_base_high = ((base & 2) != 0); + base &= ~3; + + max_offset = get_conf_long(d, entry_base + 8); + has_max_offset_high = ((max_offset & 2) != 0); + max_offset |= 3; + max_offset_high_pos = entry_base + 12; + + printf("\t\t\t Base: "); + if (has_base_high) { + u32 base_high = get_conf_long(d, entry_base + 12); + + printf("%x", base_high); + max_offset_high_pos += 4; + } + printf("%08x\n", base); + + printf("\t\t\t Max Offset: "); + if (has_max_offset_high) { + u32 max_offset_high = get_conf_long(d, max_offset_high_pos); + + printf("%x", max_offset_high); + } + printf("%08x\n", max_offset); + + entry_base += 4 + 4 * es; + } +} + void show_caps(struct device *d, int where) { @@ -1348,6 +1485,9 @@ show_caps(struct device *d, int where) case PCI_CAP_ID_AF: cap_af(d, where); break; + case PCI_CAP_ID_EA: + cap_ea(d, where, cap); + break; default: printf("#%02x [%04x]\n", id, cap); }