From owner-svn-src-head@freebsd.org Fri Feb 26 08:35:06 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 86136AB5EA1; Fri, 26 Feb 2016 08:35:06 +0000 (UTC) (envelope-from wma@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 47FAD1D36; Fri, 26 Feb 2016 08:35:06 +0000 (UTC) (envelope-from wma@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u1Q8Z5pI088498; Fri, 26 Feb 2016 08:35:05 GMT (envelope-from wma@FreeBSD.org) Received: (from wma@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u1Q8Z5KT088496; Fri, 26 Feb 2016 08:35:05 GMT (envelope-from wma@FreeBSD.org) Message-Id: <201602260835.u1Q8Z5KT088496@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: wma set sender to wma@FreeBSD.org using -f From: Wojciech Macek Date: Fri, 26 Feb 2016 08:35:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r296081 - in head: sys/dev/pci usr.sbin/pciconf X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Feb 2016 08:35:06 -0000 Author: wma Date: Fri Feb 26 08:35:04 2016 New Revision: 296081 URL: https://svnweb.freebsd.org/changeset/base/296081 Log: Add support for Enhanced Allocation in pciconf * Modified pciconf to print EA capability structure * Added register description to pcireg.h Obtained from: Semihalf Sponsored by: Cavium Approved by: cognet (mentor) Reviewed by: jhb Differential revision: https://reviews.freebsd.org/D5440 Modified: head/sys/dev/pci/pcireg.h head/usr.sbin/pciconf/cap.c Modified: head/sys/dev/pci/pcireg.h ============================================================================== --- head/sys/dev/pci/pcireg.h Fri Feb 26 08:16:44 2016 (r296080) +++ head/sys/dev/pci/pcireg.h Fri Feb 26 08:35:04 2016 (r296081) @@ -146,6 +146,7 @@ #define PCIY_MSIX 0x11 /* MSI-X */ #define PCIY_SATA 0x12 /* SATA */ #define PCIY_PCIAF 0x13 /* PCI Advanced Features */ +#define PCIY_EA 0x14 /* PCI Extended Allocation */ /* Extended Capability Register Fields */ @@ -586,6 +587,52 @@ #define PCIR_MSI_MASK 0x10 #define PCIR_MSI_PENDING 0x14 +/* PCI Enhanced Allocation registers */ +#define PCIR_EA_NUM_ENT 2 /* Number of Capability Entries */ +#define PCIM_EA_NUM_ENT_MASK 0x3f /* Num Entries Mask */ +#define PCIR_EA_FIRST_ENT 4 /* First EA Entry in List */ +#define PCIR_EA_FIRST_ENT_BRIDGE 8 /* First EA Entry for Bridges */ +#define PCIM_EA_ES 0x00000007 /* Entry Size */ +#define PCIM_EA_BEI 0x000000f0 /* BAR Equivalent Indicator */ +#define PCIM_EA_BEI_OFFSET 4 +/* 0-5 map to BARs 0-5 respectively */ +#define PCIM_EA_BEI_BAR_0 0 +#define PCIM_EA_BEI_BAR_5 5 +#define PCIM_EA_BEI_BAR(x) (((x) >> PCIM_EA_BEI_OFFSET) & 0xf) +#define PCIM_EA_BEI_BRIDGE 0x6 /* Resource behind bridge */ +#define PCIM_EA_BEI_ENI 0x7 /* Equivalent Not Indicated */ +#define PCIM_EA_BEI_ROM 0x8 /* Expansion ROM */ +/* 9-14 map to VF BARs 0-5 respectively */ +#define PCIM_EA_BEI_VF_BAR_0 9 +#define PCIM_EA_BEI_VF_BAR_5 14 +#define PCIM_EA_BEI_RESERVED 0xf /* Reserved - Treat like ENI */ +#define PCIM_EA_PP 0x0000ff00 /* Primary Properties */ +#define PCIM_EA_PP_OFFSET 8 +#define PCIM_EA_SP_OFFSET 16 +#define PCIM_EA_SP 0x00ff0000 /* Secondary Properties */ +#define PCIM_EA_P_MEM 0x00 /* Non-Prefetch Memory */ +#define PCIM_EA_P_MEM_PREFETCH 0x01 /* Prefetchable Memory */ +#define PCIM_EA_P_IO 0x02 /* I/O Space */ +#define PCIM_EA_P_VF_MEM_PREFETCH 0x03 /* VF Prefetchable Memory */ +#define PCIM_EA_P_VF_MEM 0x04 /* VF Non-Prefetch Memory */ +#define PCIM_EA_P_BRIDGE_MEM 0x05 /* Bridge Non-Prefetch Memory */ +#define PCIM_EA_P_BRIDGE_MEM_PREFETCH 0x06 /* Bridge Prefetchable Memory */ +#define PCIM_EA_P_BRIDGE_IO 0x07 /* Bridge I/O Space */ +/* 0x08-0xfc reserved */ +#define PCIM_EA_P_MEM_RESERVED 0xfd /* Reserved Memory */ +#define PCIM_EA_P_IO_RESERVED 0xfe /* Reserved I/O Space */ +#define PCIM_EA_P_UNAVAILABLE 0xff /* Entry Unavailable */ +#define PCIM_EA_WRITABLE 0x40000000 /* Writable: 1 = RW, 0 = HwInit */ +#define PCIM_EA_ENABLE 0x80000000 /* Enable for this entry */ +#define PCIM_EA_BASE 4 /* Base Address Offset */ +#define PCIM_EA_MAX_OFFSET 8 /* MaxOffset (resource length) */ +/* bit 0 is reserved */ +#define PCIM_EA_IS_64 0x00000002 /* 64-bit field flag */ +#define PCIM_EA_FIELD_MASK 0xfffffffc /* For Base & Max Offset */ +/* Bridge config register */ +#define PCIM_EA_SEC_NR(reg) ((reg) & 0xff) +#define PCIM_EA_SUB_NR(reg) (((reg) >> 8) & 0xff) + /* PCI-X definitions */ /* For header type 0 devices */ Modified: head/usr.sbin/pciconf/cap.c ============================================================================== --- head/usr.sbin/pciconf/cap.c Fri Feb 26 08:16:44 2016 (r296080) +++ head/usr.sbin/pciconf/cap.c Fri Feb 26 08:35:04 2016 (r296081) @@ -534,6 +534,141 @@ cap_pciaf(int fd, struct pci_conf *p, ui cap & PCIM_PCIAFCAP_TP ? " TP" : ""); } +static const char * +ea_bei_to_name(uint8_t bei) +{ + static const char *barstr[] = { + "BAR0", "BAR1", "BAR2", "BAR3", "BAR4", "BAR5" + }; + static const char *vfbarstr[] = { + "VFBAR0", "VFBAR1", "VFBAR2", "VFBAR3", "VFBAR4", "VFBAR5" + }; + + if ((bei >= PCIM_EA_BEI_BAR_0) && (bei <= PCIM_EA_BEI_BAR_5)) + return (barstr[bei - PCIM_EA_BEI_BAR_0]); + if ((bei >= PCIM_EA_BEI_VF_BAR_0) && (bei <= PCIM_EA_BEI_VF_BAR_5)) + return (vfbarstr[bei - PCIM_EA_BEI_VF_BAR_0]); + + switch (bei) { + case PCIM_EA_BEI_BRIDGE: + return "BRIDGE"; + case PCIM_EA_BEI_ENI: + return "ENI"; + case PCIM_EA_BEI_ROM: + return "ROM"; + case PCIM_EA_BEI_RESERVED: + default: + return "RSVD"; + } +} + +static const char * +ea_prop_to_name(uint8_t prop) +{ + + switch (prop) { + case PCIM_EA_P_MEM: + return "Non-Prefetchable Memory"; + case PCIM_EA_P_MEM_PREFETCH: + return "Prefetchable Memory"; + case PCIM_EA_P_IO: + return "I/O Space"; + case PCIM_EA_P_VF_MEM_PREFETCH: + return "VF Prefetchable Memory"; + case PCIM_EA_P_VF_MEM: + return "VF Non-Prefetchable Memory"; + case PCIM_EA_P_BRIDGE_MEM: + return "Bridge Non-Prefetchable Memory"; + case PCIM_EA_P_BRIDGE_MEM_PREFETCH: + return "Bridge Prefetchable Memory"; + case PCIM_EA_P_BRIDGE_IO: + return "Bridge I/O Space"; + case PCIM_EA_P_MEM_RESERVED: + return "Reserved Memory"; + case PCIM_EA_P_IO_RESERVED: + return "Reserved I/O Space"; + case PCIM_EA_P_UNAVAILABLE: + return "Unavailable"; + default: + return "Reserved"; + } +} + +static void +cap_ea(int fd, struct pci_conf *p, uint8_t ptr) +{ + int num_ent; + int a, b; + uint32_t bei; + uint32_t val; + int ent_size; + uint32_t dw[4]; + uint32_t flags, flags_pp, flags_sp; + uint64_t base, max_offset; + uint8_t fixed_sub_bus_nr, fixed_sec_bus_nr; + + /* Determine the number of entries */ + num_ent = read_config(fd, &p->pc_sel, ptr + PCIR_EA_NUM_ENT, 2); + num_ent &= PCIM_EA_NUM_ENT_MASK; + + printf("PCI Enhanced Allocation (%d entries)", num_ent); + + /* Find the first entry to care of */ + ptr += PCIR_EA_FIRST_ENT; + + /* Print BUS numbers for bridges */ + if ((p->pc_hdr & PCIM_HDRTYPE) == PCIM_HDRTYPE_BRIDGE) { + val = read_config(fd, &p->pc_sel, ptr, 4); + + fixed_sec_bus_nr = PCIM_EA_SEC_NR(val); + fixed_sub_bus_nr = PCIM_EA_SUB_NR(val); + + printf("\n\t\t BRIDGE, sec bus [%d], sub bus [%d]", + fixed_sec_bus_nr, fixed_sub_bus_nr); + ptr += 4; + } + + for (a = 0; a < num_ent; a++) { + /* Read a number of dwords in the entry */ + val = read_config(fd, &p->pc_sel, ptr, 4); + ptr += 4; + ent_size = (val & PCIM_EA_ES); + + for (b = 0; b < ent_size; b++) { + dw[b] = read_config(fd, &p->pc_sel, ptr, 4); + ptr += 4; + } + + flags = val; + flags_pp = (flags & PCIM_EA_PP) >> PCIM_EA_PP_OFFSET; + flags_sp = (flags & PCIM_EA_SP) >> PCIM_EA_SP_OFFSET; + bei = (PCIM_EA_BEI & val) >> PCIM_EA_BEI_OFFSET; + + base = dw[0] & PCIM_EA_FIELD_MASK; + max_offset = dw[1] | ~PCIM_EA_FIELD_MASK; + b = 2; + if (((dw[0] & PCIM_EA_IS_64) != 0) && (b < ent_size)) { + base |= (uint64_t)dw[b] << 32UL; + b++; + } + if (((dw[1] & PCIM_EA_IS_64) != 0) + && (b < ent_size)) { + max_offset |= (uint64_t)dw[b] << 32UL; + b++; + } + + printf("\n\t\t [%d] %s, %s, %s, base [0x%lx], size [0x%lx]" + "\n\t\t\tPrimary properties [0x%x] (%s)" + "\n\t\t\tSecondary properties [0x%x] (%s)", + bei, ea_bei_to_name(bei), + (flags & PCIM_EA_ENABLE ? "Enabled" : "Disabled"), + (flags & PCIM_EA_WRITABLE ? "Writable" : "Read-only"), + base, max_offset + 1, + flags_pp, ea_prop_to_name(flags_pp), + flags_sp, ea_prop_to_name(flags_sp)); + } +} + void list_caps(int fd, struct pci_conf *p) { @@ -605,6 +740,9 @@ list_caps(int fd, struct pci_conf *p) case PCIY_PCIAF: cap_pciaf(fd, p, ptr); break; + case PCIY_EA: + cap_ea(fd, p, ptr); + break; default: printf("unknown"); break;