/* 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
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)
{
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;