Module Name: src Committed By: martin Date: Tue Dec 4 11:29:41 UTC 2018
Modified Files: src/sys/dev/pci [netbsd-8]: pci_subr.c pcireg.h Log Message: Pull up following revision(s) (requested by msaitoh in ticket #1118): sys/dev/pci/pci_subr.c: revision 1.210 sys/dev/pci/pci_subr.c: revision 1.207 sys/dev/pci/pcireg.h: revision 1.143 sys/dev/pci/pci_subr.c: revision 1.208 sys/dev/pci/pcireg.h: revision 1.144 sys/dev/pci/pci_subr.c: revision 1.209 sys/dev/pci/pcireg.h: revision 1.145 sys/dev/pci/pcireg.h: revision 1.146 Decode PCI Enhanced Allocation. The register offset of the mask and pending register is depend on the 64bit address capable bit, so fix the definition of PCI MSI vector mask and pending register. This problem was not a real bug because PCI_MSI{MASK,PENDING} were not used from anywhere. The downstream port of PCIe switch is not a root port, so don't print root port related register. For example, Intel 63xxESB controller's downstream port device was printed by pcictl(8) with this bug: ----------------------------- PCI configuration registers: Common header: 0x00: 0x35108086 0x00100147 0x06040001 0x00010010 Vendor Name: Intel (0x8086) Device Name: 63xxESB PCI Express Downstream Port #1 (0x3510) (snip) Capability register at 0x44 <============= type: 0x10 (PCI Express) Capability register at 0x60 <============= 0x60 - 0x44 = 0x1c type: 0x05 (MSI) Capability register at 0x70 type: 0x01 (Power Management) Capability register at 0x80 type: 0x0d (Subsystem vendor ID) (snip) PCI Message Signaled Interrupt Message Control register: 0x0080 MSI Enabled: off Multiple Message Capable: no (1 vector) Multiple Message Enabled: off (1 vector) 64 Bit Address Capable: on Per-Vector Masking Capable: off Extended Message Data Capable: off Extended Message Data Enable: off Message Address (lower) register: 0x00000000 Message Address (upper) register: 0x00000000 Message Data register: 0x0000 (snip) PCI Express Capabilities Register (snip) Root Control Register: 0x7005 <=== 0x7005 is the first two byte SERR on Correctable Error Enable: on of the MSI capability structure SERR on Non-Fatal Error Enable: off SERR on Fatal Error Enable: on PME Interrupt Enable: off CRS Software Visibility Enable: off Root Capability Register: 0x0080 CRS Software Visibility: off Root Status Register: 0x00000000 PME Requester ID: 0x0000 PME was asserted: off another PME is pending: off Device-dependent header: 0x40: 0x00c00000 0x00616010 0x00000001 0x00005026 | |<- PCIe | 0x50: 0x0203f441 0x10010020 0x00000000 0x004803c0 | ->| 0x60: 0x00807005 0x00000000 0x00000000 0x00000000 |<- MSI ->| 0x70: 0xc8028001 0x00000100 0x00000000 0x00000000 |<- PM ->| 0x80: 0x0000000d 0x00000000 0x00000000 0x00000000 |<- subsystem ID | -------------------------------------- Add new macro PCIE_HAS_ROOTREGS(pcie_devtype) and use it. No functional change. Add new PCIE_HAS_LINKREGS(pcie_devtype) and use it. No functional change. To generate a diff of this commit: cvs rdiff -u -r1.183.2.8 -r1.183.2.9 src/sys/dev/pci/pci_subr.c cvs rdiff -u -r1.130.2.7 -r1.130.2.8 src/sys/dev/pci/pcireg.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/pci_subr.c diff -u src/sys/dev/pci/pci_subr.c:1.183.2.8 src/sys/dev/pci/pci_subr.c:1.183.2.9 --- src/sys/dev/pci/pci_subr.c:1.183.2.8 Tue Oct 30 09:32:32 2018 +++ src/sys/dev/pci/pci_subr.c Tue Dec 4 11:29:41 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: pci_subr.c,v 1.183.2.8 2018/10/30 09:32:32 sborrill Exp $ */ +/* $NetBSD: pci_subr.c,v 1.183.2.9 2018/12/04 11:29:41 martin Exp $ */ /* * Copyright (c) 1997 Zubin D. Dittia. All rights reserved. @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.183.2.8 2018/10/30 09:32:32 sborrill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.183.2.9 2018/12/04 11:29:41 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_pci.h" @@ -1756,9 +1756,8 @@ pci_conf_print_pcie_cap(const pcireg_t * { pcireg_t reg; /* for each register */ pcireg_t val; /* for each bitfield */ - bool check_link = true; bool check_slot = false; - bool check_rootport = false; + unsigned int pcie_devtype; bool check_upstreamport = false; unsigned int pciever; unsigned int i; @@ -1770,7 +1769,8 @@ pci_conf_print_pcie_cap(const pcireg_t * pciever = (unsigned int)(PCIE_XCAP_VER(reg)); printf(" Capability version: %u\n", pciever); printf(" Device type: "); - switch (PCIE_XCAP_TYPE(reg)) { + pcie_devtype = PCIE_XCAP_TYPE(reg); + switch (pcie_devtype) { case PCIE_XCAP_TYPE_PCIE_DEV: /* 0x0 */ printf("PCI Express Endpoint device\n"); check_upstreamport = true; @@ -1782,7 +1782,6 @@ pci_conf_print_pcie_cap(const pcireg_t * case PCIE_XCAP_TYPE_ROOT: /* 0x4 */ printf("Root Port of PCI Express Root Complex\n"); check_slot = true; - check_rootport = true; break; case PCIE_XCAP_TYPE_UP: /* 0x5 */ printf("Upstream Port of PCI Express Switch\n"); @@ -1791,7 +1790,6 @@ pci_conf_print_pcie_cap(const pcireg_t * case PCIE_XCAP_TYPE_DOWN: /* 0x6 */ printf("Downstream Port of PCI Express Switch\n"); check_slot = true; - check_rootport = true; break; case PCIE_XCAP_TYPE_PCIE2PCI: /* 0x7 */ printf("PCI Express to PCI/PCI-X Bridge\n"); @@ -1804,12 +1802,9 @@ pci_conf_print_pcie_cap(const pcireg_t * break; case PCIE_XCAP_TYPE_ROOT_INTEP: /* 0x9 */ printf("Root Complex Integrated Endpoint\n"); - check_link = false; break; case PCIE_XCAP_TYPE_ROOT_EVNTC: /* 0xa */ printf("Root Complex Event Collector\n"); - check_link = false; - check_rootport = true; break; default: printf("unknown\n"); @@ -1886,7 +1881,7 @@ pci_conf_print_pcie_cap(const pcireg_t * onoff("Transaction Pending", reg, PCIE_DCSR_TRANSACTION_PND); onoff("Emergency Power Reduction Detected", reg, PCIE_DCSR_EMGPWRREDD); - if (check_link) { + if (PCIE_HAS_LINKREGS(pcie_devtype)) { /* Link Capability Register */ reg = regs[o2i(capoff + PCIE_LCAP)]; printf(" Link Capabilities Register: 0x%08x\n", reg); @@ -2082,7 +2077,7 @@ pci_conf_print_pcie_cap(const pcireg_t * onoff("Data Link Layer State Changed", reg, PCIE_SLCSR_LACS); } - if (check_rootport == true) { + if (PCIE_HAS_ROOTREGS(pcie_devtype)) { /* Root Control Register */ reg = regs[o2i(capoff + PCIE_RCR)]; printf(" Root Control Register: 0x%04x\n", reg & 0xffff); @@ -2237,7 +2232,7 @@ pci_conf_print_pcie_cap(const pcireg_t * } onoff("End-End TLP Prefix Blocking on", reg, PCIE_DCSR2_EETLP); - if (check_link) { + if (PCIE_HAS_LINKREGS(pcie_devtype)) { bool drs_supported = false; /* Link Capability 2 */ @@ -2409,7 +2404,167 @@ pci_conf_print_pciaf_cap(const pcireg_t onoff("Transaction Pending", reg, PCI_AFSR_TP); } -/* XXX pci_conf_print_ea_cap */ +static void +pci_conf_print_ea_cap_prop(unsigned int prop) +{ + + switch (prop) { + case PCI_EA_PROP_MEM_NONPREF: + printf("Memory Space, Non-Prefetchable\n"); + break; + case PCI_EA_PROP_MEM_PREF: + printf("Memory Space, Prefetchable\n"); + break; + case PCI_EA_PROP_IO: + printf("I/O Space\n"); + break; + case PCI_EA_PROP_VF_MEM_NONPREF: + printf("Resorce for VF use, Memory Space, Non-Prefetchable\n"); + break; + case PCI_EA_PROP_VF_MEM_PREF: + printf("Resorce for VF use, Memory Space, Prefetch\n"); + break; + case PCI_EA_PROP_BB_MEM_NONPREF: + printf("Behind the Bridge, Memory Space, Non-Pref\n"); + break; + case PCI_EA_PROP_BB_MEM_PREF: + printf("Behind the Bridge, Memory Space. Prefetchable\n"); + break; + case PCI_EA_PROP_BB_IO: + printf("Behind Bridge, I/O Space\n"); + break; + case PCI_EA_PROP_MEM_UNAVAIL: + printf("Memory Space Unavailable\n"); + break; + case PCI_EA_PROP_IO_UNAVAIL: + printf("IO Space Unavailable\n"); + break; + case PCI_EA_PROP_UNAVAIL: + printf("Entry Unavailable for use\n"); + break; + default: + printf("Reserved\n"); + break; + } +} + +static void +pci_conf_print_ea_cap(const pcireg_t *regs, int capoff) +{ + pcireg_t reg, reg2; + unsigned int entries, entoff, i; + + printf("\n Enhanced Allocation Capability Register\n"); + + reg = regs[o2i(capoff + PCI_EA_CAP1)]; + printf(" EA Num Entries register: 0x%04x\n", reg >> 16); + entries = __SHIFTOUT(reg, PCI_EA_CAP1_NUMENTRIES); + printf(" EA Num Entries: %u\n", entries); + + /* Type 1 only */ + if (PCI_HDRTYPE_TYPE(regs[o2i(PCI_BHLC_REG)]) == PCI_HDRTYPE_PPB) { + reg = regs[o2i(capoff + PCI_EA_CAP2)]; + printf(" EA Capability Second register: 0x%08x\n", reg); + printf(" Fixed Secondary Bus Number: %hhu\n", + (unsigned char)__SHIFTOUT(reg, PCI_EA_CAP2_SECONDARY)); + printf(" Fixed Subordinate Bus Number: %hhu\n", + (unsigned char)__SHIFTOUT(reg, PCI_EA_CAP2_SUBORDINATE)); + entoff = capoff + 8; + } else + entoff = capoff + 4; + + for (i = 0; i < entries; i++) { + uint64_t base, offset; + bool baseis64, offsetis64; + unsigned int bei, entry_size; + + printf(" Entry %u:\n", i); + /* The first DW */ + reg = regs[o2i(entoff)]; + printf(" The first register: 0x%08x\n", reg); + entry_size = __SHIFTOUT(reg, PCI_EA_ES); + printf(" Entry size: %u\n", entry_size); + printf(" BAR Equivalent Indicator: "); + bei = __SHIFTOUT(reg, PCI_EA_BEI); + switch (bei) { + case PCI_EA_BEI_BAR0: + case PCI_EA_BEI_BAR1: + case PCI_EA_BEI_BAR2: + case PCI_EA_BEI_BAR3: + case PCI_EA_BEI_BAR4: + case PCI_EA_BEI_BAR5: + printf("BAR %u\n", bei - PCI_EA_BEI_BAR0); + break; + case PCI_EA_BEI_BEHIND: + printf("Behind the function\n"); + break; + case PCI_EA_BEI_NOTIND: + printf("Not Indicated\n"); + break; + case PCI_EA_BEI_EXPROM: + printf("Expansion ROM\n"); + break; + case PCI_EA_BEI_VFBAR0: + case PCI_EA_BEI_VFBAR1: + case PCI_EA_BEI_VFBAR2: + case PCI_EA_BEI_VFBAR3: + case PCI_EA_BEI_VFBAR4: + case PCI_EA_BEI_VFBAR5: + printf("VF BAR %u\n", bei - PCI_EA_BEI_VFBAR0); + break; + case PCI_EA_BEI_RESERVED: + default: + printf("Reserved\n"); + break; + } + + printf(" Primary Properties: "); + pci_conf_print_ea_cap_prop(__SHIFTOUT(reg, PCI_EA_PP)); + printf(" Secondary Properties: "); + pci_conf_print_ea_cap_prop(__SHIFTOUT(reg, PCI_EA_SP)); + onoff("Writable", reg, PCI_EA_W); + onoff("Enable for this entry", reg, PCI_EA_E); + + if (entry_size == 0) { + entoff += 4; + continue; + } + + /* Base addr */ + reg = regs[o2i(entoff + 4)]; + base = reg & PCI_EA_LOWMASK; + baseis64 = reg & PCI_EA_BASEMAXOFFSET_64BIT; + printf(" Base Address Register Low: 0x%08x\n", reg); + if (baseis64) { + /* 64bit */ + reg2 = regs[o2i(entoff + 12)]; + printf(" Base Address Register high: 0x%08x\n", + reg2); + base |= (uint64_t)reg2 << 32; + } + + /* Offset addr */ + reg = regs[o2i(entoff + 8)]; + offset = reg & PCI_EA_LOWMASK; + offsetis64 = reg & PCI_EA_BASEMAXOFFSET_64BIT; + printf(" Max Offset Register Low: 0x%08x\n", reg); + if (offsetis64) { + /* 64bit */ + reg2 = regs[o2i(entoff + (baseis64 ? 16 : 12))]; + printf(" Max Offset Register high: 0x%08x\n", + reg2); + offset |= (uint64_t)reg2 << 32; + } + + printf(" range: 0x%016" PRIx64 "-0x%016" PRIx64 + "\n", base, base + offset); + + entoff += 4; + entoff += baseis64 ? 8 : 4; + entoff += offsetis64 ? 8 : 4; + } +} + /* XXX pci_conf_print_fpb_cap */ static struct { @@ -2439,7 +2594,7 @@ static struct { { PCI_CAP_MSIX, "MSI-X", pci_conf_print_msix_cap }, { PCI_CAP_SATA, "SATA", pci_conf_print_sata_cap }, { PCI_CAP_PCIAF, "Advanced Features", pci_conf_print_pciaf_cap}, - { PCI_CAP_EA, "Enhanced Allocation", NULL }, + { PCI_CAP_EA, "Enhanced Allocation", pci_conf_print_ea_cap }, { PCI_CAP_FPB, "Flattening Portal Bridge", NULL } }; Index: src/sys/dev/pci/pcireg.h diff -u src/sys/dev/pci/pcireg.h:1.130.2.7 src/sys/dev/pci/pcireg.h:1.130.2.8 --- src/sys/dev/pci/pcireg.h:1.130.2.7 Tue Oct 30 09:32:32 2018 +++ src/sys/dev/pci/pcireg.h Tue Dec 4 11:29:41 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: pcireg.h,v 1.130.2.7 2018/10/30 09:32:32 sborrill Exp $ */ +/* $NetBSD: pcireg.h,v 1.130.2.8 2018/12/04 11:29:41 martin Exp $ */ /* * Copyright (c) 1995, 1996, 1999, 2000 @@ -671,8 +671,12 @@ typedef u_int8_t pci_revision_t; #define PCI_MSI_MDATA64 0xc /* 64-bit Message Data Register * offset */ -#define PCI_MSI_MASK 0x10 /* Vector Mask register */ -#define PCI_MSI_PENDING 0x14 /* Vector Pending register */ + +#define PCI_MSI_MASK 0x0c /* Vector Mask register */ +#define PCI_MSI_MASK64 0x10 /* 64-bit Vector Mask register */ + +#define PCI_MSI_PENDING 0x10 /* Vector Pending register */ +#define PCI_MSI_PENDING64 0x14 /* 64-bit Vector Pending register */ #define PCI_MSI_CTL_MASK __BITS(31, 16) #define PCI_MSI_CTL_EXTMDATA_EN __SHIFTIN(__BIT(10), PCI_MSI_CTL_MASK) @@ -1150,6 +1154,18 @@ typedef u_int8_t pci_revision_t; #define PCIE_SLCSR2 0x38 /* Slot Control & Status 2 Register */ /* + * Other than Root Complex Integrated Endpoint and Root Complex Event Collector + * have link related registers. + */ +#define PCIE_HAS_LINKREGS(type) (((type) != PCIE_XCAP_TYPE_ROOT_INTEP) && \ + ((type) != PCIE_XCAP_TYPE_ROOT_EVNTC)) + +/* Only root port and root complex event collector have PCIE_RCR & PCIE_RSR */ +#define PCIE_HAS_ROOTREGS(type) (((type) == PCIE_XCAP_TYPE_ROOT) || \ + ((type) == PCIE_XCAP_TYPE_ROOT_EVNTC)) + + +/* * Capability ID: 0x11 * MSIX */ @@ -1866,6 +1882,54 @@ struct pci_rom { * Extended capability ID: 0x0014 * Enhanced Allocation */ +#define PCI_EA_CAP1 0x00 /* Capability First */ +#define PCI_EA_CAP1_NUMENTRIES __BITS(21, 16) /* Num Entries */ +#define PCI_EA_CAP2 0x04 /* Capability Second (for type1) */ +#define PCI_EA_CAP2_SECONDARY __BITS(7, 0) /* Fixed Secondary Bus No. */ +#define PCI_EA_CAP2_SUBORDINATE __BITS(15, 8) /* Fixed Subordinate Bus No. */ + +/* Bit definitions for the first DW of each entry */ +#define PCI_EA_ES __BITS(2, 0) /* Entry Size */ +#define PCI_EA_BEI __BITS(7, 4) /* BAR Equivalent Indicator */ +#define PCI_EA_BEI_BAR0 0 /* BAR0 (10h) */ +#define PCI_EA_BEI_BAR1 1 /* BAR1 (14h) */ +#define PCI_EA_BEI_BAR2 2 /* BAR2 (18h) */ +#define PCI_EA_BEI_BAR3 3 /* BAR3 (1ch) */ +#define PCI_EA_BEI_BAR4 4 /* BAR4 (20h) */ +#define PCI_EA_BEI_BAR5 5 /* BAR5 (24h) */ +#define PCI_EA_BEI_BEHIND 6 /* Behind the function (for type1) */ +#define PCI_EA_BEI_NOTIND 7 /* Not Indicated */ +#define PCI_EA_BEI_EXPROM 8 /* Expansion ROM */ +#define PCI_EA_BEI_VFBAR0 9 /* VF BAR0 */ +#define PCI_EA_BEI_VFBAR1 10 /* VF BAR1 */ +#define PCI_EA_BEI_VFBAR2 11 /* VF BAR2 */ +#define PCI_EA_BEI_VFBAR3 12 /* VF BAR3 */ +#define PCI_EA_BEI_VFBAR4 13 /* VF BAR4 */ +#define PCI_EA_BEI_VFBAR5 14 /* VF BAR5 */ +#define PCI_EA_BEI_RESERVED 15 /* Reserved (treat as Not Indicated) */ + +#define PCI_EA_PP __BITS(15, 8) /* Primary Properties */ +#define PCI_EA_SP __BITS(23, 16) /* Secondary Properties */ +/* PP and SP's values */ +#define PCI_EA_PROP_MEM_NONPREF 0x00 /* Memory Space, Non-Prefetchable */ +#define PCI_EA_PROP_MEM_PREF 0x01 /* Memory Space, Prefetchable */ +#define PCI_EA_PROP_IO 0x02 /* I/O Space */ +#define PCI_EA_PROP_VF_MEM_NONPREF 0x03 /* Resorce for VF use. Mem. Non-Pref */ +#define PCI_EA_PROP_VF_MEM_PREF 0x04 /* Resorce for VF use. Mem. Prefetch */ +#define PCI_EA_PROP_BB_MEM_NONPREF 0x05 /* Behind Bridge: MEM. Non-Pref */ +#define PCI_EA_PROP_BB_MEM_PREF 0x06 /* Behind Bridge: MEM. Prefetch */ +#define PCI_EA_PROP_BB_IO 0x07 /* Behind Bridge: I/O Space */ +#define PCI_EA_PROP_MEM_UNAVAIL 0xfd /* Memory Space Unavailable */ +#define PCI_EA_PROP_IO_UNAVAIL 0xfe /* IO Space Unavailable */ +#define PCI_EA_PROP_UNAVAIL 0xff /* Entry Unavailable for use */ + +#define PCI_EA_W __BIT(30) /* Writable */ +#define PCI_EA_E __BIT(31) /* Enable for this entry */ + +#define PCI_EA_LOWMASK __BITS(31, 2) /* Low register's mask */ +#define PCI_EA_BASEMAXOFFSET_S __BIT(1) /* Field Size */ +#define PCI_EA_BASEMAXOFFSET_64BIT __BIT(1) /* 64bit */ +#define PCI_EA_BASEMAXOFFSET_32BIT 0 /* 32bit */ /* * Extended capability ID: 0x0015