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
This commit is contained in:
parent
de867427d8
commit
a2862b1169
@ -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 */
|
||||
|
@ -534,6 +534,141 @@ cap_pciaf(int fd, struct pci_conf *p, uint8_t ptr)
|
||||
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user