]> git.ipfire.org Git - thirdparty/pciutils.git/commitdiff
lspci: decode MMIO Register Block Locator
authorAlex Martens <alex.martens@asteralabs.com>
Fri, 4 Jul 2025 16:48:56 +0000 (09:48 -0700)
committerMartin Mareš <mj@ucw.cz>
Sun, 28 Dec 2025 19:54:16 +0000 (20:54 +0100)
MRBL is defined in the PCIe base specification 6.2.

Signed-off-by: Alex Martens <alex.martens@asteralabs.com>
lib/header.h
ls-ecaps.c

index b68f2a0559e5ae2f31e00e65a8b19de36a28e07d..26cdf874d76a169c14080ad525581dd46997b4b0 100644 (file)
 /* IDE Address Association Register 2 is "Memory Limit Upper" */
 /* IDE Address Association Register 3 is "Memory Base Upper" */
 
+/* MMIO Register Block Locator Capability */
+#define PCI_MRBL_CAP           0x04    /* MRBL Capabilities Register */
+#define PCI_MRBL_REG           0x08    /* MRBL Locator Register base */
+#define PCI_MRBL_REG_SIZE      0x08    /* MRBL Locator Register size */
+#define  PCI_MRBL_CAP_STRUCT_LEN(x)    ((x) & 0xFFF) /* MRBL Structure Length in bytes */
+#define  PCI_MRBL_LOC_BIR(x)           ((x) & 0x7) /* MRBL Locator BIR */
+#define  PCI_MRBL_LOC_BID(x)           (((x) >> 8) & 0xff) /* MRBL Locator Block ID */
+#define  PCI_MRBL_LOC_OFF_LOW(x)       ((x) & 0xffff0000) /* MRBL Locator Offset Low */
+
 /*
  * The PCI interface treats multi-function devices as independent
  * devices.  The slot/function address of each device is encoded
index 0bb7412467e020dfe414c59a63fbd130568a6361..1765f351b00825025a8534ee0acb66ccc9d10574 100644 (file)
@@ -1910,6 +1910,68 @@ cap_dev3(struct device *d, int where)
          FLAG(devsta3, PCI_DEV3_DEVSTA3_REMOTE_L0P_SUPP));
 }
 
+static const char *mmio_rbl_bid(char *buf, size_t buflen, u8 bid)
+{
+  switch (bid)
+    {
+      case 0x00:
+        return "Empty";
+      case 0x01:
+        return "MCAP";
+      case 0xFF:
+        return "MDVS";
+      default:
+        snprintf(buf, buflen, "Reserved (%u)", bid);
+        return buf;
+    }
+}
+
+static void
+cap_mmio_rbl(struct device *d, int where)
+{
+  char buf[16];
+
+  printf("MMIO Register Block Locator\n");
+
+  if (verbose < 2)
+    return;
+
+  if (!config_fetch(d, where + PCI_MRBL_CAP, 0x0C)) {
+    printf("\t\t<unreadable>\n");
+    return;
+  }
+
+  u32 cap = get_conf_long(d, where + PCI_MRBL_CAP);
+
+  u32 mrbllen = PCI_MRBL_CAP_STRUCT_LEN(cap);
+
+  if (!config_fetch(d, where + PCI_MRBL_REG, mrbllen)) {
+    printf("\t\t<unreadable>\n");
+    return;
+  }
+
+  u32 num_mrbl = (mrbllen / 8) - 1;
+
+  for (u32 i = 0; i < num_mrbl; i++) {
+    unsigned int pos = where + PCI_MRBL_REG + i * PCI_MRBL_REG_SIZE;
+    if (!config_fetch(d, pos, PCI_MRBL_REG_SIZE)) {
+      printf("\t\t<unreadable>\n");
+      return;
+    }
+
+    u32 lo = get_conf_long(d, pos);
+    u32 hi = get_conf_long(d, pos + 0x04);
+
+    u64 offs = ((u64) hi << 32) | PCI_MRBL_LOC_OFF_LOW(lo);
+
+    printf("\t\tLocator%u: BIR: BAR%u, ID: %s, offset: %016" PCI_U64_FMT_X "\n",
+          i,
+          PCI_MRBL_LOC_BIR(lo),
+          mmio_rbl_bid(buf, sizeof(buf), PCI_MRBL_LOC_BID(lo)),
+          offs);
+  }
+}
+
 void
 show_ext_caps(struct device *d, int type)
 {
@@ -2072,6 +2134,9 @@ show_ext_caps(struct device *d, int type)
          case PCI_EXT_CAP_ID_DEV3:
            cap_dev3(d, where);
            break;
+         case PCI_EXT_CAP_ID_MMIO_RBL:
+           cap_mmio_rbl(d, where);
+           break;
          default:
            printf("Extended Capability ID %#02x\n", id);
            break;