]> mj.ucw.cz Git - pciutils.git/commitdiff
lspci: Parse Intel Vendor specific capabilities
authorPali Rohár <pali@kernel.org>
Fri, 5 Jul 2024 09:40:06 +0000 (11:40 +0200)
committerMartin Mares <mj@ucw.cz>
Fri, 5 Jul 2024 17:28:38 +0000 (19:28 +0200)
Intel Vendor specific capabilities are present on following devices:
* Intel Host Bridge / DRAM Controller
* Intel Integrated Graphics Controller
* Intel LPC Controller

Intel Host Bridge / DRAM Controller is on BDF address 00:00.0, so following
command should should parse and show Intel Vendor specific capabilities:

  lspci -s 00:00.0 -vv

Currently only Intel Capabilities Version 1 is supported for now. This is
used since second generation of the Intel Core processors (Sandy Bridge).

ls-caps-vendor.c

index 62ee586dcd6de978162cb8e5c7b813fe7fe4df96..83ff761c37490224b45e00065bd02c387d5e146d 100644 (file)
@@ -61,6 +61,157 @@ show_vendor_caps_virtio(struct device *d, int where, int cap)
   return 1;
 }
 
+static int
+show_vendor_caps_intel(struct device *d, int where, int cap)
+{
+  int length = BITS(cap, 0, 8);
+  int version = BITS(cap, 8, 4);
+  int type = BITS(cap, 12, 4);
+  u32 l;
+
+  if (type == 0)
+    {
+      printf("Intel Capabilities v%d\n", version);
+      /*
+       * Intel Capabilities is used at least on Intel Host Bridge / DRAM Controller
+       * and Intel Integrated Graphics Controller. Format of the CAPID0_<X>
+       * registers parsed below matches Cap Version 1 which is used since second
+       * generation of the Intel Core processors (Sandy Bridge). Parsing of other
+       * versions is not currently supported.
+       */
+      if (version != 1)
+        return 1;
+    }
+  else if (type == 1)
+    {
+      printf("Intel Feature Detection\n");
+      /*
+       * Intel Feature Detection Capabilities is used on Intel LPC Controller.
+       * Capabilities are accessed indirectly by writing indirect capability
+       * register to PCI config space. Because lspci cannot write to PCI config
+       * space, it is not possible to read or parse Intel Feature Vector Space.
+       */
+      return 1;
+    }
+  else
+    {
+      printf("Intel <unknown>\n");
+      return 1;
+    }
+
+  if (!config_fetch(d, where, length))
+    return 0;
+
+  /* CAPID0_A */
+  if (length >= 8)
+    {
+      l = get_conf_long(d, where + 4);
+      printf("\t\tCapA:");
+      printf(" Peg60Dis%c", FLAG(l, BIT(31)));
+      printf(" Peg12Dis%c", FLAG(l, BIT(30)));
+      printf(" Peg11Dis%c", FLAG(l, BIT(29)));
+      printf(" Peg10Dis%c", FLAG(l, BIT(28)));
+      printf(" PeLWUDis%c", FLAG(l, BIT(27)));
+      printf(" DmiWidth=x%u", (l & BIT(26)) ? 2 : 4);
+      printf("\n\t\t     ");
+      printf(" EccDis%c", FLAG(l, BIT(25)));
+      printf(" ForceEccEn%c", FLAG(l, BIT(24)));
+      printf(" VTdDis%c", FLAG(l, BIT(23)));
+      printf(" DmiG2Dis%c", FLAG(l, BIT(22)));
+      printf(" PegG2Dis%c", FLAG(l, BIT(21)));
+      printf(" DDRMaxSize=");
+      if (BITS(l, 19, 2) == 0)
+        printf("Unlimited");
+      else
+        printf("%gGB/chan", 512 * (1 << ((3-BITS(l, 19, 2))*2)) / 1024.0);
+      printf("\n\t\t     ");
+      printf(" 1NDis%c", FLAG(l, BIT(17)));
+      printf(" CDDis%c", FLAG(l, BIT(15)));
+      printf(" DDPCDis%c", FLAG(l, BIT(14)));
+      printf(" X2APICEn%c", FLAG(l, BIT(13)));
+      printf(" PDCDis%c", FLAG(l, BIT(12)));
+      printf(" IGDis%c", FLAG(l, BIT(11)));
+      printf(" CDID=%u", BITS(l, 8, 2));
+      printf(" CRID=%u", BITS(l, 4, 4));
+      printf("\n\t\t     ");
+      printf(" DDROCCAP%c", FLAG(l, BIT(3)));
+      printf(" OCEn%c", FLAG(l, BIT(2)));
+      printf(" DDRWrtVrefEn%c", FLAG(l, BIT(1)));
+      printf(" DDR3LEn%c", FLAG(l, BIT(0)));
+      printf("\n");
+    }
+
+  /* CAPID0_B */
+  if (length >= 12)
+    {
+      l = get_conf_long(d, where + 8);
+      printf("\t\tCapB:");
+      printf(" ImguDis%c", FLAG(l, BIT(31)));
+      printf(" OCbySSKUCap%c", FLAG(l, BIT(30)));
+      printf(" OCbySSKUEn%c", FLAG(l, BIT(29)));
+      printf(" SMTCap%c", FLAG(l, BIT(28)));
+      printf(" CacheSzCap 0x%x", BITS(l, 25, 3));
+      printf("\n\t\t     ");
+      printf(" SoftBinCap%c", FLAG(l, BIT(24)));
+      printf(" DDR3MaxFreqWithRef100=");
+      if (BITS(l, 21, 3) == 0)
+        printf("Disabled");
+      else if (BITS(l, 21, 3) == 7)
+        printf("Unlimited");
+      else
+        printf("%uMHz", (6+BITS(l, 21, 3)) * 200);
+      printf(" PegG3Dis%c", FLAG(l, BIT(20)));
+      printf("\n\t\t     ");
+      printf(" PkgTyp%c", FLAG(l, BIT(19)));
+      printf(" AddGfxEn%c", FLAG(l, BIT(18)));
+      printf(" AddGfxCap%c", FLAG(l, BIT(17)));
+      printf(" PegX16Dis%c", FLAG(l, BIT(16)));
+      printf(" DmiG3Dis%c", FLAG(l, BIT(15)));
+      printf(" GmmDis%c", FLAG(l, BIT(8)));
+      printf("\n\t\t     ");
+      printf(" DDR3MaxFreq=%uMHz", (11-BITS(l, 4, 2)) * 2666 / 10);
+      printf(" LPDDR3En%c", FLAG(l, BIT(2)));
+      printf("\n");
+    }
+
+  /* CAPID0_C */
+  if (length >= 16)
+    {
+      l = get_conf_long(d, where + 12);
+      printf("\t\tCapC:");
+      printf(" PegG4Dis%c", FLAG(l, BIT(28)));
+      printf(" DDR4MaxFreq=");
+      if (BITS(l, 23, 4) == 0)
+        printf("Unlimited");
+      else
+        printf("%uMHz", BITS(l, 0, 4) * 2666 / 10);
+      printf(" LPDDREn%c", FLAG(l, BIT(22)));
+      printf(" LPDDR4MaxFreq=");
+      if (BITS(l, 17, 4) == 0)
+        printf("Unlimited");
+      else
+        printf("%uMHz", BITS(l, 0, 4) * 2666 / 10);
+      printf(" LPDDR4En%c", FLAG(l, BIT(16)));
+      printf("\n\t\t     ");
+      printf(" QClkGvDis%c", FLAG(l, BIT(14)));
+      printf(" SgxDis%c", FLAG(l, BIT(9)));
+      printf(" BClkOC=%s", BITS(l, 7, 2) == 0 ? "Disabled" :
+                           BITS(l, 7, 2) == 1 ? "115MHz" :
+                           BITS(l, 7, 2) == 2 ? "130MHz" :
+                                                "Unlimited");
+      printf(" IddDis%c", FLAG(l, BIT(6)));
+      printf(" Pipe3Dis%c", FLAG(l, BIT(5)));
+      printf(" Gear1MaxFreq=");
+      if (BITS(l, 0, 4) == 0)
+        printf("Unlimited");
+      else
+        printf("%uMHz", BITS(l, 0, 4) * 2666 / 10);
+      printf("\n");
+    }
+
+  return 1;
+}
+
 static int
 do_show_vendor_caps(struct device *d, int where, int cap)
 {
@@ -71,6 +222,8 @@ do_show_vendor_caps(struct device *d, int where, int cap)
          d->dev->device_id <= 0x107f)
        return show_vendor_caps_virtio(d, where, cap);
       break;
+    case 0x8086: /* Intel */
+      return show_vendor_caps_intel(d, where, cap);
     }
   return 0;
 }