Tue Jan 20 13:54:43 2009 UTC ()
Decode and display PCI Power Management registers when available.


(jmcneill)
diff -r1.76 -r1.77 src/sys/dev/pci/pci_subr.c

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

--- src/sys/dev/pci/pci_subr.c 2008/11/17 23:33:41 1.76
+++ src/sys/dev/pci/pci_subr.c 2009/01/20 13:54:43 1.77
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pci_subr.c,v 1.76 2008/11/17 23:33:41 matt Exp $ */ 1/* $NetBSD: pci_subr.c,v 1.77 2009/01/20 13:54:43 jmcneill 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.76 2008/11/17 23:33:41 matt Exp $"); 43__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.77 2009/01/20 13:54:43 jmcneill 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#else 54#else
55#include <pci.h> 55#include <pci.h>
56#include <stdbool.h> 56#include <stdbool.h>
@@ -887,55 +887,114 @@ pci_conf_print_pcie_cap(const pcireg_t * @@ -887,55 +887,114 @@ pci_conf_print_pcie_cap(const pcireg_t *
887 break; 887 break;
888 case 0x3: 888 case 0x3:
889 printf("off\n"); 889 printf("off\n");
890 break; 890 break;
891 } 891 }
892 printf(" Power Controller Control: "); 892 printf(" Power Controller Control: ");
893 if ((regs[o2i(capoff + 0x18)] & 0x0400) != 0) 893 if ((regs[o2i(capoff + 0x18)] & 0x0400) != 0)
894 printf("off\n"); 894 printf("off\n");
895 else 895 else
896 printf("on\n"); 896 printf("on\n");
897 } 897 }
898} 898}
899 899
 900static const char *
 901pci_conf_print_pcipm_cap_aux(uint16_t caps)
 902{
 903 switch ((caps >> 6) & 7) {
 904 case 0: return "self-powered";
 905 case 1: return "55 mA";
 906 case 2: return "100 mA";
 907 case 3: return "160 mA";
 908 case 4: return "220 mA";
 909 case 5: return "270 mA";
 910 case 6: return "320 mA";
 911 case 7:
 912 default: return "375 mA";
 913 }
 914}
 915
 916static const char *
 917pci_conf_print_pcipm_cap_pmrev(uint8_t val)
 918{
 919 static const char unk[] = "unknown";
 920 static const char *pmrev[8] = {
 921 unk, "1.0", "1.1", "1.2", unk, unk, unk, unk
 922 };
 923 if (val > 7)
 924 return unk;
 925 return pmrev[val];
 926}
 927
 928static void
 929pci_conf_print_pcipm_cap(const pcireg_t *regs, int capoff)
 930{
 931 uint16_t caps, pmcsr;
 932
 933 caps = regs[o2i(capoff)] >> 16;
 934 pmcsr = regs[o2i(capoff + 0x04)] & 0xffff;
 935
 936 printf("\n PCI Power Management Capabilities Register\n");
 937
 938 printf(" Capabilities register: 0x%04x\n", caps);
 939 printf(" Version: %s\n",
 940 pci_conf_print_pcipm_cap_pmrev(caps & 0x3));
 941 printf(" PME# clock: %s\n", caps & 0x4 ? "on" : "off");
 942 printf(" Device specific initialization: %s\n",
 943 caps & 0x20 ? "on" : "off");
 944 printf(" 3.3V auxiliary current: %s\n",
 945 pci_conf_print_pcipm_cap_aux(caps));
 946 printf(" D1 power management state support: %s\n",
 947 (caps >> 9) & 1 ? "on" : "off");
 948 printf(" D2 power management state support: %s\n",
 949 (caps >> 10) & 1 ? "on" : "off");
 950 printf(" PME# support: 0x%02x\n", caps >> 11);
 951
 952 printf(" Control/status register: 0x%04x\n", pmcsr);
 953 printf(" Power state: D%d\n", pmcsr & 3);
 954 printf(" PCI Express reserved: %s\n",
 955 (pmcsr >> 2) & 1 ? "on" : "off");
 956 printf(" No soft reset: %s\n", (pmcsr >> 3) & 1 ? "on" : "off");
 957 printf(" PME# assertion %sabled\n",
 958 (pmcsr >> 8) & 1 ? "en" : "dis");
 959 printf(" PME# status: %s\n", (pmcsr >> 15) ? "on" : "off");
 960}
 961
900static void 962static void
901pci_conf_print_caplist( 963pci_conf_print_caplist(
902#ifdef _KERNEL 964#ifdef _KERNEL
903 pci_chipset_tag_t pc, pcitag_t tag, 965 pci_chipset_tag_t pc, pcitag_t tag,
904#endif 966#endif
905 const pcireg_t *regs, int capoff) 967 const pcireg_t *regs, int capoff)
906{ 968{
907 static const char unk[] = "unknown"; 
908 static const char *pmrev[8] = { 
909 unk, "1.0", "1.1", "1.2", unk, unk, unk, unk 
910 }; 
911 int off; 969 int off;
912 pcireg_t rval; 970 pcireg_t rval;
913 int pcie_off = -1; 971 int pcie_off = -1, pcipm_off = -1;
914 972
915 for (off = PCI_CAPLIST_PTR(regs[o2i(capoff)]); 973 for (off = PCI_CAPLIST_PTR(regs[o2i(capoff)]);
916 off != 0; 974 off != 0;
917 off = PCI_CAPLIST_NEXT(regs[o2i(off)])) { 975 off = PCI_CAPLIST_NEXT(regs[o2i(off)])) {
918 rval = regs[o2i(off)]; 976 rval = regs[o2i(off)];
919 printf(" Capability register at 0x%02x\n", off); 977 printf(" Capability register at 0x%02x\n", off);
920 978
921 printf(" type: 0x%02x (", PCI_CAPLIST_CAP(rval)); 979 printf(" type: 0x%02x (", PCI_CAPLIST_CAP(rval));
922 switch (PCI_CAPLIST_CAP(rval)) { 980 switch (PCI_CAPLIST_CAP(rval)) {
923 case PCI_CAP_RESERVED0: 981 case PCI_CAP_RESERVED0:
924 printf("reserved"); 982 printf("reserved");
925 break; 983 break;
926 case PCI_CAP_PWRMGMT: 984 case PCI_CAP_PWRMGMT:
927 printf("Power Management, rev. %s", 985 printf("Power Management, rev. %s",
928 pmrev[(rval >> 0) & 0x07]); 986 pci_conf_print_pcipm_cap_pmrev((rval >> 0) & 0x07));
 987 pcipm_off = off;
929 break; 988 break;
930 case PCI_CAP_AGP: 989 case PCI_CAP_AGP:
931 printf("AGP, rev. %d.%d", 990 printf("AGP, rev. %d.%d",
932 PCI_CAP_AGP_MAJOR(rval), 991 PCI_CAP_AGP_MAJOR(rval),
933 PCI_CAP_AGP_MINOR(rval)); 992 PCI_CAP_AGP_MINOR(rval));
934 break; 993 break;
935 case PCI_CAP_VPD: 994 case PCI_CAP_VPD:
936 printf("VPD"); 995 printf("VPD");
937 break; 996 break;
938 case PCI_CAP_SLOTID: 997 case PCI_CAP_SLOTID:
939 printf("SlotID"); 998 printf("SlotID");
940 break; 999 break;
941 case PCI_CAP_MSI: 1000 case PCI_CAP_MSI:
@@ -970,26 +1029,28 @@ pci_conf_print_caplist( @@ -970,26 +1029,28 @@ pci_conf_print_caplist(
970 break; 1029 break;
971 case PCI_CAP_PCIEXPRESS: 1030 case PCI_CAP_PCIEXPRESS:
972 printf("PCI Express"); 1031 printf("PCI Express");
973 pcie_off = off; 1032 pcie_off = off;
974 break; 1033 break;
975 case PCI_CAP_MSIX: 1034 case PCI_CAP_MSIX:
976 printf("MSI-X"); 1035 printf("MSI-X");
977 break; 1036 break;
978 default: 1037 default:
979 printf("unknown"); 1038 printf("unknown");
980 } 1039 }
981 printf(")\n"); 1040 printf(")\n");
982 } 1041 }
 1042 if (pcipm_off != -1)
 1043 pci_conf_print_pcipm_cap(regs, pcipm_off);
983 if (pcie_off != -1) 1044 if (pcie_off != -1)
984 pci_conf_print_pcie_cap(regs, pcie_off); 1045 pci_conf_print_pcie_cap(regs, pcie_off);
985} 1046}
986 1047
987static void 1048static void
988pci_conf_print_type1( 1049pci_conf_print_type1(
989#ifdef _KERNEL 1050#ifdef _KERNEL
990 pci_chipset_tag_t pc, pcitag_t tag, 1051 pci_chipset_tag_t pc, pcitag_t tag,
991#endif 1052#endif
992 const pcireg_t *regs 1053 const pcireg_t *regs
993#ifdef _KERNEL 1054#ifdef _KERNEL
994 , int sizebars 1055 , int sizebars
995#endif 1056#endif