Module Name: src Committed By: msaitoh Date: Thu Nov 12 12:17:59 UTC 2015
Modified Files: src/sys/dev/pci: pci_subr.c pcireg.h Log Message: - Restore pci_subr.c rev. 1.135's change in pci_conf_print_caplist(). As wrote in the comment, HyperTransport capability appears multiple times. pci_conf_cap() reruns only the first entry, so it can't be used here. - Try to decode HyperTransport capability. Currently, the capability type of each HyperTransport capability is printed and only the MSI Mapping capability is decoded. - Style change. To generate a diff of this commit: cvs rdiff -u -r1.140 -r1.141 src/sys/dev/pci/pci_subr.c cvs rdiff -u -r1.107 -r1.108 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.140 src/sys/dev/pci/pci_subr.c:1.141 --- src/sys/dev/pci/pci_subr.c:1.140 Fri Oct 30 20:03:45 2015 +++ src/sys/dev/pci/pci_subr.c Thu Nov 12 12:17:59 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: pci_subr.c,v 1.140 2015/10/30 20:03:45 msaitoh Exp $ */ +/* $NetBSD: pci_subr.c,v 1.141 2015/11/12 12:17:59 msaitoh 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.140 2015/10/30 20:03:45 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.141 2015/11/12 12:17:59 msaitoh Exp $"); #ifdef _KERNEL_OPT #include "opt_pci.h" @@ -1232,7 +1232,96 @@ pci_conf_print_pcix_cap(const pcireg_t * } } -/* XXX pci_conf_print_ldt_cap */ +/* pci_conf_print_ht_slave_cap */ +/* pci_conf_print_ht_host_cap */ +/* pci_conf_print_ht_switch_cap */ +/* pci_conf_print_ht_intr_cap */ +/* pci_conf_print_ht_revid_cap */ +/* pci_conf_print_ht_unitid_cap */ +/* pci_conf_print_ht_extcnf_cap */ +/* pci_conf_print_ht_addrmap_cap */ +/* pci_conf_print_ht_msimap_cap */ + +static void +pci_conf_print_ht_msimap_cap(const pcireg_t *regs, int capoff) +{ + pcireg_t val; + uint32_t lo, hi; + + /* + * Print the rest of the command register bits. Others are + * printed in pci_conf_print_ht_cap(). + */ + val = regs[o2i(capoff + PCI_HT_CMD)]; + onoff("Enable", val, PCI_HT_MSI_ENABLED); + onoff("Fixed", val, PCI_HT_MSI_FIXED); + + lo = regs[o2i(capoff + PCI_HT_MSI_ADDR_LO)]; + hi = regs[o2i(capoff + PCI_HT_MSI_ADDR_HI)]; + printf(" Address Low register: 0x%08x\n", lo); + printf(" Address high register: 0x%08x\n", hi); + printf(" Address: 0x%016" PRIx64 "\n", + (uint64_t)hi << 32 | (lo & PCI_HT_MSI_ADDR_LO_MASK)); +} + +/* pci_conf_print_ht_droute_cap */ +/* pci_conf_print_ht_vcset_cap */ +/* pci_conf_print_ht_retry_cap */ +/* pci_conf_print_ht_x86enc_cap */ +/* pci_conf_print_ht_gen3_cap */ +/* pci_conf_print_ht_fle_cap */ +/* pci_conf_print_ht_pm_cap */ +/* pci_conf_print_ht_hnc_cap */ + +static const struct ht_types { + pcireg_t cap; + const char *name; + void (*printfunc)(const pcireg_t *, int); +} ht_captab[] = { + {PCI_HT_CAP_SLAVE, "Slave or Primary Interface", NULL }, + {PCI_HT_CAP_HOST, "Host or Secondary Interface", NULL }, + {PCI_HT_CAP_SWITCH, "Switch", NULL }, + {PCI_HT_CAP_INTERRUPT, "Interrupt Discovery and Configuration", NULL}, + {PCI_HT_CAP_REVID, "Revision ID", NULL }, + {PCI_HT_CAP_UNITID_CLUMP, "UnitID Clumping", NULL }, + {PCI_HT_CAP_EXTCNFSPACE, "Extended Configuration Space Access", NULL }, + {PCI_HT_CAP_ADDRMAP, "Address Mapping", NULL }, + {PCI_HT_CAP_MSIMAP, "MSI Mapping", pci_conf_print_ht_msimap_cap }, + {PCI_HT_CAP_DIRECTROUTE, "Direct Route", NULL }, + {PCI_HT_CAP_VCSET, "VCSet", NULL }, + {PCI_HT_CAP_RETRYMODE, "Retry Mode", NULL }, + {PCI_HT_CAP_X86ENCODE, "X86 Encoding", NULL }, + {PCI_HT_CAP_GEN3, "Gen3", NULL }, + {PCI_HT_CAP_FLE, "Function-Level Extension", NULL }, + {PCI_HT_CAP_PM, "Power Management", NULL }, + {PCI_HT_CAP_HIGHNODECNT, "High Node Count", NULL }, +}; + +static void +pci_conf_print_ht_cap(const pcireg_t *regs, int capoff) +{ + pcireg_t val, foundcap; + unsigned int off; + + val = regs[o2i(capoff + PCI_HT_CMD)]; + + printf("\n HyperTransport Capability Register at 0x%02x\n", capoff); + + printf(" Command register: 0x%04x\n", val >> 16); + foundcap = PCI_HT_CAP(val); + for (off = 0; off < __arraycount(ht_captab); off++) { + if (ht_captab[off].cap == foundcap) + break; + } + printf(" Capability Type: 0x%02x ", foundcap); + if (off >= __arraycount(ht_captab)) { + printf("(unknown)\n"); + return; + } + printf("(%s)\n", ht_captab[off].name); + if (ht_captab[off].printfunc != NULL) + ht_captab[off].printfunc(regs, off); +} static void pci_conf_print_vendspec_cap(const pcireg_t *regs, int capoff) @@ -1887,7 +1976,7 @@ static struct { { PCI_CAP_MSI, "MSI", pci_conf_print_msi_cap }, { PCI_CAP_CPCI_HOTSWAP, "CompactPCI Hot-swapping", NULL }, { PCI_CAP_PCIX, "PCI-X", pci_conf_print_pcix_cap }, - { PCI_CAP_LDT, "HyperTransport", NULL }, + { PCI_CAP_LDT, "HyperTransport", pci_conf_print_ht_cap }, { PCI_CAP_VENDSPEC, "Vendor-specific", pci_conf_print_vendspec_cap }, { PCI_CAP_DEBUGPORT, "Debug Port", pci_conf_print_debugport_cap }, @@ -1911,8 +2000,7 @@ pci_conf_find_cap(const pcireg_t *regs, int off; for (off = PCI_CAPLIST_PTR(regs[o2i(capoff)]); - off != 0; - off = PCI_CAPLIST_NEXT(rval)) { + off != 0; off = PCI_CAPLIST_NEXT(rval)) { rval = regs[o2i(off)]; if (capid == PCI_CAPLIST_CAP(rval)) { if (offsetp != NULL) @@ -1942,8 +2030,7 @@ pci_conf_print_caplist( /* Print capability register's offset and the type first */ for (off = PCI_CAPLIST_PTR(regs[o2i(capoff)]); - off != 0; - off = PCI_CAPLIST_NEXT(regs[o2i(off)])) { + off != 0; off = PCI_CAPLIST_NEXT(regs[o2i(off)])) { rval = regs[o2i(off)]; printf(" Capability register at 0x%02x\n", off); @@ -1971,11 +2058,21 @@ pci_conf_print_caplist( * the same. This is required because some capabilities * appear multiple times (e.g. HyperTransport capability). */ +#if 0 if (pci_conf_find_cap(regs, capoff, i, &off)) { rval = regs[o2i(off)]; if (pci_captab[i].printfunc != NULL) pci_captab[i].printfunc(regs, off); } +#else + for (off = PCI_CAPLIST_PTR(regs[o2i(capoff)]); + off != 0; off = PCI_CAPLIST_NEXT(regs[o2i(off)])) { + rval = regs[o2i(off)]; + if ((PCI_CAPLIST_CAP(rval) == i) + && (pci_captab[i].printfunc != NULL)) + pci_captab[i].printfunc(regs, off); + } +#endif } } Index: src/sys/dev/pci/pcireg.h diff -u src/sys/dev/pci/pcireg.h:1.107 src/sys/dev/pci/pcireg.h:1.108 --- src/sys/dev/pci/pcireg.h:1.107 Thu Nov 12 12:08:13 2015 +++ src/sys/dev/pci/pcireg.h Thu Nov 12 12:17:59 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: pcireg.h,v 1.107 2015/11/12 12:08:13 msaitoh Exp $ */ +/* $NetBSD: pcireg.h,v 1.108 2015/11/12 12:17:59 msaitoh Exp $ */ /* * Copyright (c) 1995, 1996, 1999, 2000 @@ -783,8 +783,6 @@ typedef u_int8_t pci_revision_t; #define PCI_HT_CMD 0x00 /* Capability List & Command Register */ #define PCI_HT_CMD_MASK __BITS(31, 16) -#define PCI_HT_MSI_ENABLED __BIT(16) -#define PCI_HT_MSI_FIXED __BIT(17) #define PCI_HT_CAP(cr) ((((cr) >> 27) < 0x08) ? \ (((cr) >> 27) & 0x1c) : (((cr) >> 27) & 0x1f)) #define PCI_HT_CAPMASK __BITS(31, 27) @@ -806,9 +804,19 @@ typedef u_int8_t pci_revision_t; #define PCI_HT_CAP_PM 0b11100 #define PCI_HT_CAP_HIGHNODECNT 0b11101 -#define PCI_HT_MSI_ADDR_LO 0x04 -#define PCI_HT_MSI_ADDR_HI 0x08 +/* + * HT Cap ID: 0b10101 + * MSI Mapping + */ + +/* Command register bits (31-16)*/ +#define PCI_HT_MSI_ENABLED __BIT(16) +#define PCI_HT_MSI_FIXED __BIT(17) + +#define PCI_HT_MSI_ADDR_LO 0x04 /* Address register (low) */ +#define PCI_HT_MSI_ADDR_LO_MASK __BITS(31, 20) #define PCI_HT_MSI_FIXED_ADDR 0xfee00000UL +#define PCI_HT_MSI_ADDR_HI 0x08 /* Address Register (high) */ /* * Capability ID: 0x09