From: Alex Martens Date: Fri, 4 Jul 2025 16:48:56 +0000 (-0700) Subject: lspci: decode MMIO Register Block Locator X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=56c44d8d79dc93657dfd3612df299af254d54f3e;p=thirdparty%2Fpciutils.git lspci: decode MMIO Register Block Locator MRBL is defined in the PCIe base specification 6.2. Signed-off-by: Alex Martens --- diff --git a/lib/header.h b/lib/header.h index b68f2a0..26cdf87 100644 --- a/lib/header.h +++ b/lib/header.h @@ -1593,6 +1593,15 @@ /* 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 diff --git a/ls-ecaps.c b/ls-ecaps.c index 0bb7412..1765f35 100644 --- a/ls-ecaps.c +++ b/ls-ecaps.c @@ -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\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\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\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;