Module Name: src Committed By: msaitoh Date: Fri May 30 03:42:38 UTC 2014
Modified Files: src/sys/dev/pci: pci_subr.c pcireg.h Log Message: - Add PCI-X capability stuff. - remove extra ':' in pci_conf_print_pcie_cap() - Add comments. To generate a diff of this commit: cvs rdiff -u -r1.121 -r1.122 src/sys/dev/pci/pci_subr.c cvs rdiff -u -r1.93 -r1.94 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.121 src/sys/dev/pci/pci_subr.c:1.122 --- src/sys/dev/pci/pci_subr.c:1.121 Tue May 27 16:50:31 2014 +++ src/sys/dev/pci/pci_subr.c Fri May 30 03:42:38 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: pci_subr.c,v 1.121 2014/05/27 16:50:31 msaitoh Exp $ */ +/* $NetBSD: pci_subr.c,v 1.122 2014/05/30 03:42:38 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.121 2014/05/27 16:50:31 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.122 2014/05/30 03:42:38 msaitoh Exp $"); #ifdef _KERNEL_OPT #include "opt_pci.h" @@ -1117,7 +1117,109 @@ pci_conf_print_msi_cap(const pcireg_t *r } /* XXX pci_conf_print_cpci_hostwap_cap */ -/* XXX pci_conf_print_pcix_cap */ + +/* + * For both command register and status register. + * The argument "idx" is index number (0 to 7). + */ +static int +pcix_split_trans(unsigned int idx) +{ + static int table[8] = { + 1, 2, 3, 4, 8, 12, 16, 32 + }; + + if (idx >= __arraycount(table)) + return -1; + return table[idx]; +} + +static void +pci_conf_print_pcix_cap(const pcireg_t *regs, int capoff) +{ + pcireg_t reg; + int isbridge; + int i; + + isbridge = (PCI_HDRTYPE_TYPE(regs[o2i(PCI_BHLC_REG)]) + & PCI_HDRTYPE_PPB) != 0 ? 1 : 0; + printf("\n PCI-X %s Capabilities Register\n", + isbridge ? "Bridge" : "Non-bridge"); + + reg = regs[o2i(capoff)]; + if (isbridge != 0) { + printf(" Secondary status register: 0x%04x\n", + (reg & 0xffff0000) >> 16); + onoff("64bit device", reg, PCIX_STATUS_64BIT); + onoff("133MHz capable", reg, PCIX_STATUS_133); + onoff("Split completion discarded", reg, PCIX_STATUS_SPLDISC); + onoff("Unexpected split completion", reg, PCIX_STATUS_SPLUNEX); + onoff("Split completion overrun", reg, PCIX_BRIDGE_ST_SPLOVRN); + onoff("Split request delayed", reg, PCIX_BRIDGE_ST_SPLRQDL); + printf(" Secondary clock frequency: 0x%x\n", + (reg & PCIX_BRIDGE_2NDST_CLKF) + >> PCIX_BRIDGE_2NDST_CLKF_SHIFT); + printf(" Version: 0x%x\n", + (reg & PCIX_BRIDGE_2NDST_VER_MASK) + >> PCIX_BRIDGE_2NDST_VER_SHIFT); + onoff("266MHz capable", reg, PCIX_BRIDGE_ST_266); + onoff("533MHz capable", reg, PCIX_BRIDGE_ST_533); + } else { + printf(" Command register: 0x%04x\n", + (reg & 0xffff0000) >> 16); + onoff("Data Parity Error Recovery", reg, + PCIX_CMD_PERR_RECOVER); + onoff("Enable Relaxed Ordering", reg, PCIX_CMD_RELAXED_ORDER); + printf(" Maximum Burst Read Count: %u\n", + PCIX_CMD_BYTECNT(reg)); + printf(" Maximum Split Transactions: %d\n", + pcix_split_trans((reg & PCIX_CMD_SPLTRANS_MASK) + >> PCIX_CMD_SPLTRANS_SHIFT)); + } + reg = regs[o2i(capoff+PCIX_STATUS)]; /* Or PCIX_BRIDGE_PRI_STATUS */ + printf(" %sStatus register: 0x%08x\n", + isbridge ? "Bridge " : "", reg); + printf(" Function: %d\n", PCIX_STATUS_FN(reg)); + printf(" Device: %d\n", PCIX_STATUS_DEV(reg)); + printf(" Bus: %d\n", PCIX_STATUS_BUS(reg)); + onoff("64bit device", reg, PCIX_STATUS_64BIT); + onoff("133MHz capable", reg, PCIX_STATUS_133); + onoff("Split completion discarded", reg, PCIX_STATUS_SPLDISC); + onoff("Unexpected split completion", reg, PCIX_STATUS_SPLUNEX); + if (isbridge != 0) { + onoff("Split completion overrun", reg, PCIX_BRIDGE_ST_SPLOVRN); + onoff("Split request delayed", reg, PCIX_BRIDGE_ST_SPLRQDL); + } else { + onoff2("Device Complexity", reg, PCIX_STATUS_DEVCPLX, + "bridge device", "simple device"); + printf(" Designed max memory read byte count: %d\n", + 512 << ((reg & PCIX_STATUS_MAXB_MASK) + >> PCIX_STATUS_MAXB_SHIFT)); + printf(" Designed max outstanding split transaction: %d\n", + pcix_split_trans((reg & PCIX_STATUS_MAXST_MASK) + >> PCIX_STATUS_MAXST_SHIFT)); + printf(" MAX cumulative Read Size: %u\n", + 8 << ((reg & 0x1c000000) >> PCIX_STATUS_MAXRS_SHIFT)); + onoff("Received split completion error", reg, + PCIX_STATUS_SCERR); + } + onoff("266MHz capable", reg, PCIX_STATUS_266); + onoff("533MHz capable", reg, PCIX_STATUS_533); + + if (isbridge == 0) + return; + + /* Only for bridge */ + for (i = 0; i < 2; i++) { + reg = regs[o2i(capoff+PCIX_BRIDGE_UP_STCR + (4 * i))]; + printf(" %s split transaction control register: 0x%08x\n", + (i == 0) ? "Upstream" : "Downstream", reg); + printf(" Capacity: %d\n", reg & PCIX_BRIDGE_STCAP); + printf(" Commitment Limit: %d\n", + (reg & PCIX_BRIDGE_STCLIM) >> PCIX_BRIDGE_STCLIM_SHIFT); + } +} + /* XXX pci_conf_print_ldt_cap */ /* XXX pci_conf_print_vendspec_cap */ @@ -1329,8 +1431,8 @@ pci_conf_print_pcie_cap(const pcireg_t * pci_print_pcie_L0s_latency((reg & PCIE_DCAP_L0S_LATENCY) >> 6); printf(" Endpoint L1 Acceptable Latency: "); pci_print_pcie_L1_latency((reg & PCIE_DCAP_L1_LATENCY) >> 9); - onoff("Attention Button Present:", reg, PCIE_DCAP_ATTN_BUTTON); - onoff("Attention Indicator Present:", reg, PCIE_DCAP_ATTN_IND); + onoff("Attention Button Present", reg, PCIE_DCAP_ATTN_BUTTON); + onoff("Attention Indicator Present", reg, PCIE_DCAP_ATTN_IND); onoff("Power Indicator Present", reg, PCIE_DCAP_PWR_IND); onoff("Role-Based Error Report", reg, PCIE_DCAP_ROLE_ERR_RPT); printf(" Captured Slot Power Limit Value: %d\n", @@ -1745,8 +1847,8 @@ pci_conf_print_caplist( { int off; pcireg_t rval; - int pcie_off = -1, pcipm_off = -1, msi_off = -1, vendspec_off = -1; - int msix_off = -1; + int pcie_off = -1, pcipm_off = -1, msi_off = -1, pcix_off = -1; + int vendspec_off = -1, msix_off = -1; int debugport_off = -1, subsystem_off = -1, pciaf_off = -1; for (off = PCI_CAPLIST_PTR(regs[o2i(capoff)]); @@ -1784,6 +1886,7 @@ pci_conf_print_caplist( printf("CompactPCI Hot-swapping"); break; case PCI_CAP_PCIX: + pcix_off = off; printf("PCI-X"); break; case PCI_CAP_LDT: @@ -1841,7 +1944,8 @@ pci_conf_print_caplist( if (msi_off != -1) pci_conf_print_msi_cap(regs, msi_off); /* XXX CPCI_HOTSWAP */ - /* XXX PCIX */ + if (pcix_off != -1) + pci_conf_print_pcix_cap(regs, pcix_off); /* XXX LDT */ if (vendspec_off != -1) pci_conf_print_vendspec_cap(regs, vendspec_off); Index: src/sys/dev/pci/pcireg.h diff -u src/sys/dev/pci/pcireg.h:1.93 src/sys/dev/pci/pcireg.h:1.94 --- src/sys/dev/pci/pcireg.h:1.93 Tue May 27 16:26:15 2014 +++ src/sys/dev/pci/pcireg.h Fri May 30 03:42:38 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: pcireg.h,v 1.93 2014/05/27 16:26:15 msaitoh Exp $ */ +/* $NetBSD: pcireg.h,v 1.94 2014/05/30 03:42:38 msaitoh Exp $ */ /* * Copyright (c) 1995, 1996, 1999, 2000 @@ -640,8 +640,14 @@ typedef u_int8_t pci_revision_t; /* * Capability ID: 0x07 * PCI-X capability. + * + * PCI-X capability register has two different layouts. One is for bridge + * function. Another is for non-bridge functions. */ + +/* For non-bridge functions */ + /* * Command. 16 bits at offset 2 (e.g. upper 16 bits of the first 32-bit * word at the capability; the lower 16 bits are the capability ID and @@ -651,21 +657,24 @@ typedef u_int8_t pci_revision_t; * as 32-bit values, offset and shifted appropriately. Make sure you perform * the appropriate R/M/W cycles! */ -#define PCIX_CMD 0x00 +#define PCIX_CMD 0x00 #define PCIX_CMD_PERR_RECOVER 0x00010000 #define PCIX_CMD_RELAXED_ORDER 0x00020000 #define PCIX_CMD_BYTECNT_MASK 0x000c0000 #define PCIX_CMD_BYTECNT_SHIFT 18 -#define PCIX_CMD_BCNT_512 0x00000000 -#define PCIX_CMD_BCNT_1024 0x00040000 -#define PCIX_CMD_BCNT_2048 0x00080000 -#define PCIX_CMD_BCNT_4096 0x000c0000 +#define PCIX_CMD_BYTECNT(reg) \ + (512 << (((reg) & PCIX_CMD_BYTECNT_MASK) >> PCIX_CMD_BYTECNT_SHIFT)) +#define PCIX_CMD_BCNT_512 0x00000000 +#define PCIX_CMD_BCNT_1024 0x00040000 +#define PCIX_CMD_BCNT_2048 0x00080000 +#define PCIX_CMD_BCNT_4096 0x000c0000 #define PCIX_CMD_SPLTRANS_MASK 0x00700000 -#define PCIX_CMD_SPLTRANS_1 0x00000000 -#define PCIX_CMD_SPLTRANS_2 0x00100000 -#define PCIX_CMD_SPLTRANS_3 0x00200000 -#define PCIX_CMD_SPLTRANS_4 0x00300000 -#define PCIX_CMD_SPLTRANS_8 0x00400000 +#define PCIX_CMD_SPLTRANS_SHIFT 20 +#define PCIX_CMD_SPLTRANS_1 0x00000000 +#define PCIX_CMD_SPLTRANS_2 0x00100000 +#define PCIX_CMD_SPLTRANS_3 0x00200000 +#define PCIX_CMD_SPLTRANS_4 0x00300000 +#define PCIX_CMD_SPLTRANS_8 0x00400000 #define PCIX_CMD_SPLTRANS_12 0x00500000 #define PCIX_CMD_SPLTRANS_16 0x00600000 #define PCIX_CMD_SPLTRANS_32 0x00700000 @@ -673,31 +682,40 @@ typedef u_int8_t pci_revision_t; /* * Status. 32 bits at offset 4. */ -#define PCIX_STATUS 0x04 -#define PCIX_STATUS_FN_MASK 0x00000007 +#define PCIX_STATUS 0x04 +#define PCIX_STATUS_FN_MASK 0x00000007 #define PCIX_STATUS_DEV_MASK 0x000000f8 +#define PCIX_STATUS_DEV_SHIFT 3 #define PCIX_STATUS_BUS_MASK 0x0000ff00 -#define PCIX_STATUS_64BIT 0x00010000 -#define PCIX_STATUS_133 0x00020000 -#define PCIX_STATUS_SPLDISC 0x00040000 -#define PCIX_STATUS_SPLUNEX 0x00080000 -#define PCIX_STATUS_DEVCPLX 0x00100000 -#define PCIX_STATUS_MAXB_MASK 0x00600000 +#define PCIX_STATUS_BUS_SHIFT 8 +#define PCIX_STATUS_FN(val) ((val) & PCIX_STATUS_FN_MASK) +#define PCIX_STATUS_DEV(val) \ + (((val) & PCIX_STATUS_DEV_MASK) >> PCIX_STATUS_DEV_SHIFT) +#define PCIX_STATUS_BUS(val) \ + (((val) & PCIX_STATUS_BUS_MASK) >> PCIX_STATUS_BUS_SHIFT) +#define PCIX_STATUS_64BIT 0x00010000 /* 64bit device */ +#define PCIX_STATUS_133 0x00020000 /* 133MHz capable */ +#define PCIX_STATUS_SPLDISC 0x00040000 /* Split completion discarded*/ +#define PCIX_STATUS_SPLUNEX 0x00080000 /* Unexpected split complet. */ +#define PCIX_STATUS_DEVCPLX 0x00100000 /* Device Complexity */ +#define PCIX_STATUS_MAXB_MASK 0x00600000 /* MAX memory read Byte count*/ #define PCIX_STATUS_MAXB_SHIFT 21 #define PCIX_STATUS_MAXB_512 0x00000000 #define PCIX_STATUS_MAXB_1024 0x00200000 #define PCIX_STATUS_MAXB_2048 0x00400000 #define PCIX_STATUS_MAXB_4096 0x00600000 -#define PCIX_STATUS_MAXST_MASK 0x03800000 -#define PCIX_STATUS_MAXST_1 0x00000000 -#define PCIX_STATUS_MAXST_2 0x00800000 -#define PCIX_STATUS_MAXST_3 0x01000000 -#define PCIX_STATUS_MAXST_4 0x01800000 -#define PCIX_STATUS_MAXST_8 0x02000000 +#define PCIX_STATUS_MAXST_MASK 0x03800000 /* MAX outstand. Split Trans.*/ +#define PCIX_STATUS_MAXST_SHIFT 23 +#define PCIX_STATUS_MAXST_1 0x00000000 +#define PCIX_STATUS_MAXST_2 0x00800000 +#define PCIX_STATUS_MAXST_3 0x01000000 +#define PCIX_STATUS_MAXST_4 0x01800000 +#define PCIX_STATUS_MAXST_8 0x02000000 #define PCIX_STATUS_MAXST_12 0x02800000 #define PCIX_STATUS_MAXST_16 0x03000000 #define PCIX_STATUS_MAXST_32 0x03800000 -#define PCIX_STATUS_MAXRS_MASK 0x1c000000 +#define PCIX_STATUS_MAXRS_MASK 0x1c000000 /* MAX cumulative Read Size */ +#define PCIX_STATUS_MAXRS_SHIFT 26 #define PCIX_STATUS_MAXRS_1K 0x00000000 #define PCIX_STATUS_MAXRS_2K 0x04000000 #define PCIX_STATUS_MAXRS_4K 0x08000000 @@ -706,7 +724,37 @@ typedef u_int8_t pci_revision_t; #define PCIX_STATUS_MAXRS_32K 0x14000000 #define PCIX_STATUS_MAXRS_64K 0x18000000 #define PCIX_STATUS_MAXRS_128K 0x1c000000 -#define PCIX_STATUS_SCERR 0x20000000 +#define PCIX_STATUS_SCERR 0x20000000 /* rcv. Split Completion ERR.*/ +#define PCIX_STATUS_266 0x40000000 /* 266MHz capable */ +#define PCIX_STATUS_533 0x80000000 /* 533MHz capable */ + +/* For bridge function */ + +#define PCIX_BRIDGE_2ND_STATUS 0x00 +#define PCIX_BRIDGE_ST_64BIT 0x00010000 /* Same as PCIX_STATUS (nonb)*/ +#define PCIX_BRIDGE_ST_133 0x00020000 /* Same as PCIX_STATUS (nonb)*/ +#define PCIX_BRIDGE_ST_SPLDISC 0x00040000 /* Same as PCIX_STATUS (nonb)*/ +#define PCIX_BRIDGE_ST_SPLUNEX 0x00080000 /* Same as PCIX_STATUS (nonb)*/ +#define PCIX_BRIDGE_ST_SPLOVRN 0x00100000 /* Split completion overrun */ +#define PCIX_BRIDGE_ST_SPLRQDL 0x00200000 /* Split request delayed */ +#define PCIX_BRIDGE_2NDST_CLKF 0x03c00000 /* Secondary clock frequency */ +#define PCIX_BRIDGE_2NDST_CLKF_SHIFT 22 +#define PCIX_BRIDGE_2NDST_VER_MASK 0x30000000 /* Version */ +#define PCIX_BRIDGE_2NDST_VER_SHIFT 28 +#define PCIX_BRIDGE_ST_266 0x40000000 /* Same as PCIX_STATUS (nonb)*/ +#define PCIX_BRIDGE_ST_533 0x80000000 /* Same as PCIX_STATUS (nonb)*/ + +#define PCIX_BRIDGE_PRI_STATUS 0x04 +/* Bit 0 to 15 are the same as PCIX_STATUS */ +/* Bit 16 to 21 are the same as PCIX_BRIDGE_2ND_STATUS */ +/* Bit 30 and 31 are the same as PCIX_BRIDGE_2ND_STATUS */ + +#define PCIX_BRIDGE_UP_STCR 0x08 /* Upstream Split Transaction Control */ +#define PCIX_BRIDGE_DOWN_STCR 0x0c /* Downstream Split Transaction Control */ +/* The layouts of above two registers are the same */ +#define PCIX_BRIDGE_STCAP 0x0000ffff /* Sp. Tr. Capacity */ +#define PCIX_BRIDGE_STCLIM 0xffff0000 /* Sp. Tr. Commitment Limit */ +#define PCIX_BRIDGE_STCLIM_SHIFT 16 /* * Capability ID: 0x08