svn commit: r296081 - in head: sys/dev/pci usr.sbin/pciconf
Wojciech Macek
wma at FreeBSD.org
Fri Feb 26 08:35:06 UTC 2016
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;
More information about the svn-src-head
mailing list