Fri Jan 17 02:08:26 2020 UTC ()
 Fix a bug that the virtual channel extended configuraton's arbitration phase
register can't be decoded correcty. Found by jmcneill.


(msaitoh)
diff -r1.218 -r1.219 src/sys/dev/pci/pci_subr.c

cvs diff -r1.218 -r1.219 src/sys/dev/pci/pci_subr.c (expand / switch to unified diff)

--- src/sys/dev/pci/pci_subr.c 2019/12/11 07:33:55 1.218
+++ src/sys/dev/pci/pci_subr.c 2020/01/17 02:08:25 1.219
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pci_subr.c,v 1.218 2019/12/11 07:33:55 msaitoh Exp $ */ 1/* $NetBSD: pci_subr.c,v 1.219 2020/01/17 02:08:25 msaitoh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1997 Zubin D. Dittia. All rights reserved. 4 * Copyright (c) 1997 Zubin D. Dittia. All rights reserved.
5 * Copyright (c) 1995, 1996, 1998, 2000 5 * Copyright (c) 1995, 1996, 1998, 2000
6 * Christopher G. Demetriou. All rights reserved. 6 * Christopher G. Demetriou. All rights reserved.
7 * Copyright (c) 1994 Charles M. Hannum. All rights reserved. 7 * Copyright (c) 1994 Charles M. Hannum. All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -30,27 +30,27 @@ @@ -30,27 +30,27 @@
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35/* 35/*
36 * PCI autoconfiguration support functions. 36 * PCI autoconfiguration support functions.
37 * 37 *
38 * Note: This file is also built into a userland library (libpci). 38 * Note: This file is also built into a userland library (libpci).
39 * Pay attention to this when you make modifications. 39 * Pay attention to this when you make modifications.
40 */ 40 */
41 41
42#include <sys/cdefs.h> 42#include <sys/cdefs.h>
43__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.218 2019/12/11 07:33:55 msaitoh Exp $"); 43__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.219 2020/01/17 02:08:25 msaitoh Exp $");
44 44
45#ifdef _KERNEL_OPT 45#ifdef _KERNEL_OPT
46#include "opt_pci.h" 46#include "opt_pci.h"
47#endif 47#endif
48 48
49#include <sys/param.h> 49#include <sys/param.h>
50 50
51#ifdef _KERNEL 51#ifdef _KERNEL
52#include <sys/systm.h> 52#include <sys/systm.h>
53#include <sys/intr.h> 53#include <sys/intr.h>
54#include <sys/module.h> 54#include <sys/module.h>
55#else 55#else
56#include <pci.h> 56#include <pci.h>
@@ -2854,151 +2854,158 @@ pci_conf_print_aer_cap(const pcireg_t *r @@ -2854,151 +2854,158 @@ pci_conf_print_aer_cap(const pcireg_t *r
2854 reg = regs[o2i(extcapoff + PCI_AER_ERRSRC_ID)]; 2854 reg = regs[o2i(extcapoff + PCI_AER_ERRSRC_ID)];
2855 printf(" Error Source Identification register: 0x%08x\n", 2855 printf(" Error Source Identification register: 0x%08x\n",
2856 reg); 2856 reg);
2857 pci_conf_print_aer_cap_errsrc_id(reg); 2857 pci_conf_print_aer_cap_errsrc_id(reg);
2858 break; 2858 break;
2859 } 2859 }
2860 2860
2861 if (tlp_prefix_log) { 2861 if (tlp_prefix_log) {
2862 reg = regs[o2i(extcapoff + PCI_AER_TLP_PREFIX_LOG)]; 2862 reg = regs[o2i(extcapoff + PCI_AER_TLP_PREFIX_LOG)];
2863 printf(" TLP Prefix Log register: 0x%08x\n", reg); 2863 printf(" TLP Prefix Log register: 0x%08x\n", reg);
2864 } 2864 }
2865} 2865}
2866 2866
 2867/*
 2868 * Helper function to print the arbitration phase register.
 2869 *
 2870 * phases: Number of phases in the arbitration tables.
 2871 * arbsize: Number of bits in each phase.
 2872 * indent: Add more two spaces if it's true.
 2873 */
2867static void 2874static void
2868pci_conf_print_vc_cap_arbtab(const pcireg_t *regs, int off, const char *name, 2875pci_conf_print_vc_cap_arbtab(const pcireg_t *regs, int off, const char *name,
2869 pcireg_t parbsel, int parbsize) 2876 const int phases, int arbsize, bool indent)
2870{ 2877{
2871 pcireg_t reg; 2878 pcireg_t reg;
2872 int num = 16 << parbsel; 2879 int num_per_reg = 32 / arbsize;
2873 int num_per_reg = sizeof(pcireg_t) / parbsize; 
2874 int i, j; 2880 int i, j;
2875 2881
2876 /* First, dump the table */ 2882 printf("%s %s Arbitration Table:\n", indent ? " " : "", name);
2877 for (i = 0; i < num; i += num_per_reg) { 2883 for (i = 0; i < phases; i += num_per_reg) {
2878 reg = regs[o2i(off + i / num_per_reg)]; 2884 reg = regs[o2i(off + (sizeof(uint32_t) * (i / num_per_reg)))];
2879 printf(" %s Arbitration Table: 0x%08x\n", name, reg); 2885 for (j = 0; j < num_per_reg; j++) {
2880 } 2886 printf("%s Phase[%d]: 0x%x\n", indent ? " " : "",
2881 /* And then, decode each entry */ 2887 i + j,
2882 for (i = 0; i < num; i += num_per_reg) { 2888 (uint32_t)(reg & __BITS(arbsize - 1, 0)));
2883 reg = regs[o2i(off + i / num_per_reg)]; 2889 reg >>= arbsize;
2884 for (j = 0; j < num_per_reg; j++) 2890 }
2885 printf(" Phase[%d]: %d\n", j, reg); 
2886 } 2891 }
2887} 2892}
2888 2893
 2894/* For VC, bit 4-7 are reserved. For Port, bit 6-7 are reserved */
 2895static const int arb_phases[8] = {0, 32, 64, 128, 128, 256, 0, 0 };
 2896
2889static void 2897static void
2890pci_conf_print_vc_cap(const pcireg_t *regs, int extcapoff) 2898pci_conf_print_vc_cap(const pcireg_t *regs, int extcapoff)
2891{ 2899{
2892 pcireg_t reg, n; 2900 pcireg_t reg, n;
2893 int parbtab, parbsize; 2901 int arbtab, parbsize;
2894 pcireg_t parbsel; 2902 pcireg_t arbsel;
2895 int varbtab, varbsize; 
2896 pcireg_t varbsel; 
2897 int i, count; 2903 int i, count;
2898 2904
2899 printf("\n Virtual Channel Register\n"); 2905 printf("\n Virtual Channel Register\n");
2900 reg = regs[o2i(extcapoff + PCI_VC_CAP1)]; 2906 reg = regs[o2i(extcapoff + PCI_VC_CAP1)];
2901 printf(" Port VC Capability register 1: 0x%08x\n", reg); 2907 printf(" Port VC Capability register 1: 0x%08x\n", reg);
2902 count = __SHIFTOUT(reg, PCI_VC_CAP1_EXT_COUNT); 2908 count = __SHIFTOUT(reg, PCI_VC_CAP1_EXT_COUNT);
2903 printf(" Extended VC Count: %d\n", count); 2909 printf(" Extended VC Count: %d\n", count);
2904 n = __SHIFTOUT(reg, PCI_VC_CAP1_LOWPRI_EXT_COUNT); 2910 n = __SHIFTOUT(reg, PCI_VC_CAP1_LOWPRI_EXT_COUNT);
2905 printf(" Low Priority Extended VC Count: %u\n", n); 2911 printf(" Low Priority Extended VC Count: %u\n", n);
2906 n = __SHIFTOUT(reg, PCI_VC_CAP1_REFCLK); 2912 n = __SHIFTOUT(reg, PCI_VC_CAP1_REFCLK);
2907 printf(" Reference Clock: %s\n", 2913 printf(" Reference Clock: %s\n",
2908 (n == PCI_VC_CAP1_REFCLK_100NS) ? "100ns" : "unknown"); 2914 (n == PCI_VC_CAP1_REFCLK_100NS) ? "100ns" : "unknown");
2909 parbsize = 1 << __SHIFTOUT(reg, PCI_VC_CAP1_PORT_ARB_TABLE_SIZE); 2915 parbsize = 1 << __SHIFTOUT(reg, PCI_VC_CAP1_PORT_ARB_TABLE_SIZE);
2910 printf(" Port Arbitration Table Entry Size: %dbit\n", parbsize); 2916 printf(" Port Arbitration Table Entry Size: %dbit\n", parbsize);
2911 2917
2912 reg = regs[o2i(extcapoff + PCI_VC_CAP2)]; 2918 reg = regs[o2i(extcapoff + PCI_VC_CAP2)];
2913 printf(" Port VC Capability register 2: 0x%08x\n", reg); 2919 printf(" Port VC Capability register 2: 0x%08x\n", reg);
2914 onoff("Hardware fixed arbitration scheme", 2920 onoff("Hardware fixed arbitration scheme",
2915 reg, PCI_VC_CAP2_ARB_CAP_HW_FIXED_SCHEME); 2921 reg, PCI_VC_CAP2_ARB_CAP_HW_FIXED_SCHEME);
2916 onoff("WRR arbitration with 32 phases", 2922 onoff("WRR arbitration with 32 phases",
2917 reg, PCI_VC_CAP2_ARB_CAP_WRR_32); 2923 reg, PCI_VC_CAP2_ARB_CAP_WRR_32);
2918 onoff("WRR arbitration with 64 phases", 2924 onoff("WRR arbitration with 64 phases",
2919 reg, PCI_VC_CAP2_ARB_CAP_WRR_64); 2925 reg, PCI_VC_CAP2_ARB_CAP_WRR_64);
2920 onoff("WRR arbitration with 128 phases", 2926 onoff("WRR arbitration with 128 phases",
2921 reg, PCI_VC_CAP2_ARB_CAP_WRR_128); 2927 reg, PCI_VC_CAP2_ARB_CAP_WRR_128);
2922 varbtab = __SHIFTOUT(reg, PCI_VC_CAP2_ARB_TABLE_OFFSET); 2928 arbtab = __SHIFTOUT(reg, PCI_VC_CAP2_ARB_TABLE_OFFSET);
2923 printf(" VC Arbitration Table Offset: 0x%x\n", varbtab); 2929 printf(" VC Arbitration Table Offset: 0x%x\n", arbtab);
2924 2930
2925 reg = regs[o2i(extcapoff + PCI_VC_CONTROL)] & 0xffff; 2931 reg = regs[o2i(extcapoff + PCI_VC_CONTROL)] & 0xffff;
2926 printf(" Port VC Control register: 0x%04x\n", reg); 2932 printf(" Port VC Control register: 0x%04x\n", reg);
2927 varbsel = __SHIFTOUT(reg, PCI_VC_CONTROL_VC_ARB_SELECT); 2933 arbsel = __SHIFTOUT(reg, PCI_VC_CONTROL_VC_ARB_SELECT);
2928 printf(" VC Arbitration Select: 0x%x\n", varbsel); 2934 printf(" VC Arbitration Select: 0x%x\n", arbsel);
2929 2935
2930 reg = regs[o2i(extcapoff + PCI_VC_STATUS)] >> 16; 2936 reg = regs[o2i(extcapoff + PCI_VC_STATUS)] >> 16;
2931 printf(" Port VC Status register: 0x%04x\n", reg); 2937 printf(" Port VC Status register: 0x%04x\n", reg);
2932 onoff("VC Arbitration Table Status", 2938 onoff("VC Arbitration Table Status",
2933 reg, PCI_VC_STATUS_LOAD_VC_ARB_TABLE); 2939 reg, PCI_VC_STATUS_LOAD_VC_ARB_TABLE);
2934 2940
 2941 if ((arbtab != 0) && (arbsel != 0))
 2942 pci_conf_print_vc_cap_arbtab(regs, extcapoff + (arbtab * 16),
 2943 "VC", arb_phases[arbsel], 4, false);
 2944
2935 for (i = 0; i < count + 1; i++) { 2945 for (i = 0; i < count + 1; i++) {
2936 reg = regs[o2i(extcapoff + PCI_VC_RESOURCE_CAP(i))]; 2946 reg = regs[o2i(extcapoff + PCI_VC_RESOURCE_CAP(i))];
2937 printf(" VC number %d\n", i); 2947 printf(" VC number %d\n", i);
2938 printf(" VC Resource Capability Register: 0x%08x\n", reg); 2948 printf(" VC Resource Capability Register: 0x%08x\n", reg);
2939 onoff(" Non-configurable Hardware fixed arbitration scheme", 2949 onoff(" Non-configurable Hardware fixed arbitration scheme",
2940 reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_HW_FIXED_SCHEME); 2950 reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_HW_FIXED_SCHEME);
2941 onoff(" WRR arbitration with 32 phases", 2951 onoff(" WRR arbitration with 32 phases",
2942 reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_32); 2952 reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_32);
2943 onoff(" WRR arbitration with 64 phases", 2953 onoff(" WRR arbitration with 64 phases",
2944 reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_64); 2954 reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_64);
2945 onoff(" WRR arbitration with 128 phases", 2955 onoff(" WRR arbitration with 128 phases",
2946 reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_128); 2956 reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_128);
2947 onoff(" Time-based WRR arbitration with 128 phases", 2957 onoff(" Time-based WRR arbitration with 128 phases",
2948 reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_TWRR_128); 2958 reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_TWRR_128);
2949 onoff(" WRR arbitration with 256 phases", 2959 onoff(" WRR arbitration with 256 phases",
2950 reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_256); 2960 reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_256);
2951 onoff(" Advanced Packet Switching", 2961 onoff(" Advanced Packet Switching",
2952 reg, PCI_VC_RESOURCE_CAP_ADV_PKT_SWITCH); 2962 reg, PCI_VC_RESOURCE_CAP_ADV_PKT_SWITCH);
2953 onoff(" Reject Snoop Transaction", 2963 onoff(" Reject Snoop Transaction",
2954 reg, PCI_VC_RESOURCE_CAP_REJCT_SNOOP_TRANS); 2964 reg, PCI_VC_RESOURCE_CAP_REJCT_SNOOP_TRANS);
2955 n = __SHIFTOUT(reg, PCI_VC_RESOURCE_CAP_MAX_TIME_SLOTS) + 1; 2965 n = __SHIFTOUT(reg, PCI_VC_RESOURCE_CAP_MAX_TIME_SLOTS) + 1;
2956 printf(" Maximum Time Slots: %d\n", n); 2966 printf(" Maximum Time Slots: %d\n", n);
2957 parbtab = reg >> PCI_VC_RESOURCE_CAP_PORT_ARB_TABLE_OFFSET_S; 2967 arbtab = __SHIFTOUT(reg,
 2968 PCI_VC_RESOURCE_CAP_PORT_ARB_TABLE_OFFSET);
2958 printf(" Port Arbitration Table offset: 0x%02x\n", 2969 printf(" Port Arbitration Table offset: 0x%02x\n",
2959 parbtab); 2970 arbtab);
2960 2971
2961 reg = regs[o2i(extcapoff + PCI_VC_RESOURCE_CTL(i))]; 2972 reg = regs[o2i(extcapoff + PCI_VC_RESOURCE_CTL(i))];
2962 printf(" VC Resource Control Register: 0x%08x\n", reg); 2973 printf(" VC Resource Control Register: 0x%08x\n", reg);
2963 printf(" TC/VC Map: 0x%02x\n", 2974 printf(" TC/VC Map: 0x%02x\n",
2964 (pcireg_t)__SHIFTOUT(reg, PCI_VC_RESOURCE_CTL_TCVC_MAP)); 2975 (pcireg_t)__SHIFTOUT(reg, PCI_VC_RESOURCE_CTL_TCVC_MAP));
2965 /* 2976 /*
2966 * The load Port Arbitration Table bit is used to update 2977 * The load Port Arbitration Table bit is used to update
2967 * the Port Arbitration logic and it's always 0 on read, so 2978 * the Port Arbitration logic and it's always 0 on read, so
2968 * we don't print it. 2979 * we don't print it.
2969 */ 2980 */
2970 parbsel = __SHIFTOUT(reg, PCI_VC_RESOURCE_CTL_PORT_ARB_SELECT); 2981 arbsel = __SHIFTOUT(reg, PCI_VC_RESOURCE_CTL_PORT_ARB_SELECT);
2971 printf(" Port Arbitration Select: 0x%x\n", parbsel); 2982 printf(" Port Arbitration Select: 0x%x\n", arbsel);
2972 n = __SHIFTOUT(reg, PCI_VC_RESOURCE_CTL_VC_ID); 2983 n = __SHIFTOUT(reg, PCI_VC_RESOURCE_CTL_VC_ID);
2973 printf(" VC ID: %d\n", n); 2984 printf(" VC ID: %d\n", n);
2974 onoff(" VC Enable", reg, PCI_VC_RESOURCE_CTL_VC_ENABLE); 2985 onoff(" VC Enable", reg, PCI_VC_RESOURCE_CTL_VC_ENABLE);
2975 2986
2976 reg = regs[o2i(extcapoff + PCI_VC_RESOURCE_STA(i))] >> 16; 2987 reg = regs[o2i(extcapoff + PCI_VC_RESOURCE_STA(i))] >> 16;
2977 printf(" VC Resource Status Register: 0x%08x\n", reg); 2988 printf(" VC Resource Status Register: 0x%08x\n", reg);
2978 onoff(" Port Arbitration Table Status", 2989 onoff(" Port Arbitration Table Status",
2979 reg, PCI_VC_RESOURCE_STA_PORT_ARB_TABLE); 2990 reg, PCI_VC_RESOURCE_STA_PORT_ARB_TABLE);
2980 onoff(" VC Negotiation Pending", 2991 onoff(" VC Negotiation Pending",
2981 reg, PCI_VC_RESOURCE_STA_VC_NEG_PENDING); 2992 reg, PCI_VC_RESOURCE_STA_VC_NEG_PENDING);
2982 2993
2983 if ((parbtab != 0) && (parbsel != 0)) 2994 if ((arbtab != 0) && (arbsel != 0))
2984 pci_conf_print_vc_cap_arbtab(regs, extcapoff + parbtab, 2995 pci_conf_print_vc_cap_arbtab(regs,
2985 "Port", parbsel, parbsize); 2996 extcapoff + (arbtab * 16),
 2997 "Port", arb_phases[arbsel], parbsize, true);
2986 } 2998 }
2987 
2988 varbsize = 8; 
2989 if ((varbtab != 0) && (varbsel != 0)) 
2990 pci_conf_print_vc_cap_arbtab(regs, extcapoff + varbtab, 
2991 " VC", varbsel, varbsize); 
2992} 2999}
2993 3000
2994/* 3001/*
2995 * Print Power limit. This encoding is the same among the following registers: 3002 * Print Power limit. This encoding is the same among the following registers:
2996 * - The Captured Slot Power Limit in the PCIe Device Capability Register. 3003 * - The Captured Slot Power Limit in the PCIe Device Capability Register.
2997 * - The Slot Power Limit in the PCIe Slot Capability Register. 3004 * - The Slot Power Limit in the PCIe Slot Capability Register.
2998 * - The Base Power in the Data register of Power Budgeting capability. 3005 * - The Base Power in the Data register of Power Budgeting capability.
2999 */ 3006 */
3000static void 3007static void
3001pci_conf_print_pcie_power(uint8_t base, unsigned int scale) 3008pci_conf_print_pcie_power(uint8_t base, unsigned int scale)
3002{ 3009{
3003 unsigned int sdiv = 1; 3010 unsigned int sdiv = 1;
3004 3011