git: 1e6db7be6921 - main - pciconf(8): dump AMD IOMMU Base Capability
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 10 Apr 2024 05:28:59 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=1e6db7be692198acfa7f02dea83aa9aa1dfce273
commit 1e6db7be692198acfa7f02dea83aa9aa1dfce273
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-04-09 22:13:59 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-04-10 05:28:24 +0000
pciconf(8): dump AMD IOMMU Base Capability
Reviewed by: emaste
Sponsored by: Advanced Micro Devices (AMD)
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D44732
---
usr.sbin/pciconf/cap.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 115 insertions(+)
diff --git a/usr.sbin/pciconf/cap.c b/usr.sbin/pciconf/cap.c
index 8595bff3d3d7..e252926ab9be 100644
--- a/usr.sbin/pciconf/cap.c
+++ b/usr.sbin/pciconf/cap.c
@@ -376,6 +376,118 @@ cap_subvendor(int fd, struct pci_conf *p, uint8_t ptr)
printf("PCI Bridge subvendor=0x%04x subdevice=0x%04x", ssvid, ssid);
}
+static const char *
+cap_secdev_amdiommu_decode_vasize(uint32_t misc0)
+{
+ switch (misc0 & PCIM_AMDIOMMU_MISC0_VASIZE_MASK) {
+ case PCIM_AMDIOMMU_MISC0_VASIZE_32:
+ return ("32bit");
+ case PCIM_AMDIOMMU_MISC0_VASIZE_40:
+ return ("40bit");
+ case PCIM_AMDIOMMU_MISC0_VASIZE_48:
+ return ("48bit");
+ case PCIM_AMDIOMMU_MISC0_VASIZE_64:
+ return ("64bit");
+ default:
+ return ("unknown");
+ }
+}
+
+static const char *
+cap_secdev_amdiommu_decode_pasize(uint32_t misc0)
+{
+ switch (misc0 & PCIM_AMDIOMMU_MISC0_PASIZE_MASK) {
+ case PCIM_AMDIOMMU_MISC0_PASIZE_40:
+ return ("40bit");
+ case PCIM_AMDIOMMU_MISC0_PASIZE_48:
+ return ("48bit");
+ case PCIM_AMDIOMMU_MISC0_PASIZE_52:
+ return ("52bit");
+ default:
+ return ("unknown");
+ }
+}
+
+static const char *
+cap_secdev_amdiommu_decode_gvasize(uint32_t misc0)
+{
+ switch (misc0 & PCIM_AMDIOMMU_MISC0_GVASIZE_MASK) {
+ case PCIM_AMDIOMMU_MISC0_GVASIZE_48:
+ return ("48bit");
+ case PCIM_AMDIOMMU_MISC0_GVASIZE_57:
+ return ("57bit");
+ default:
+ return ("unknown");
+ }
+}
+
+static void
+cap_secdev(int fd, struct pci_conf *p, uint8_t ptr)
+{
+ uint32_t cap_h;
+ uint32_t cap_type, cap_rev;
+ uint32_t base_low, base_high;
+ uint32_t range;
+ uint32_t misc0, misc1;
+ const char *delim;
+
+ cap_h = read_config(fd, &p->pc_sel, ptr + PCIR_AMDIOMMU_CAP_HEADER, 4);
+ cap_type = cap_h & PCIM_AMDIOMMU_CAP_TYPE_MASK;
+ cap_rev = cap_h & PCIM_AMDIOMMU_CAP_REV_MASK;
+ if (cap_type != PCIM_AMDIOMMU_CAP_TYPE_VAL ||
+ cap_rev != PCIM_AMDIOMMU_CAP_REV_VAL) {
+ printf("Secure Device Type=0x%1x Rev=0x%02x\n",
+ cap_type >> 16, cap_rev >> 19);
+ return;
+ }
+ base_low = read_config(fd, &p->pc_sel, ptr + PCIR_AMDIOMMU_BASE_LOW,
+ 4);
+ base_high = read_config(fd, &p->pc_sel, ptr + PCIR_AMDIOMMU_BASE_HIGH,
+ 4);
+ printf("AMD IOMMU Base Capability Base=%#018jx/%sabled",
+ (uintmax_t)(base_low & PCIM_AMDIOMMU_BASE_LOW_ADDRM) +
+ ((uintmax_t)base_high << 32),
+ (base_low & PCIM_AMDIOMMU_BASE_LOW_EN) != 0 ? "En" : "Dis");
+
+ delim = "\n\t\t";
+#define PRINTCAP(bit, name) \
+ if ((cap_h & PCIM_AMDIOMMU_CAP_ ##bit) != 0) { \
+ printf("%s%s", delim, #name); \
+ delim = ","; \
+ }
+ PRINTCAP(CAPEXT, CapExt);
+ PRINTCAP(EFR, EFRSup);
+ PRINTCAP(NPCACHE, NpCache);
+ PRINTCAP(HTTUN, HtTunnel);
+ PRINTCAP(IOTLB, IotlbSup);
+#undef PRINTCAP
+
+ range = read_config(fd, &p->pc_sel, ptr + PCIR_AMDIOMMU_RANGE, 4);
+ printf("\n\t\tUnitId=%d", range & PCIM_AMDIOMMU_RANGE_UNITID_MASK);
+ if ((range & PCIM_AMDIOMMU_RANGE_RNGVALID) != 0) {
+ printf(" BusNum=%#06x FirstDev=%#06x LastDev=%#06x",
+ (range & PCIM_AMDIOMMU_RANGE_BUSNUM_MASK) >> 8,
+ (range & PCIM_AMDIOMMU_RANGE_FIRSTDEV_MASK) >> 16,
+ (range & PCIM_AMDIOMMU_RANGE_LASTDEV_MASK) >> 24);
+ }
+
+ misc0 = read_config(fd, &p->pc_sel, ptr + PCIR_AMDIOMMU_MISC0, 4);
+ printf("\n\t\tMsiNum=%d MsiNumPPR=%d HtAtsResv=%d",
+ misc0 & PCIM_AMDIOMMU_MISC0_MSINUM_MASK,
+ (misc0 & PCIM_AMDIOMMU_MISC0_MSINUMPPR_MASK) >> 27,
+ (misc0 & PCIM_AMDIOMMU_MISC0_HTATSRESV) != 0);
+ if ((cap_h & PCIM_AMDIOMMU_CAP_CAPEXT) != 0) {
+ misc1 = read_config(fd, &p->pc_sel,
+ ptr + PCIR_AMDIOMMU_MISC1, 4);
+ printf(" MsiNumGA=%d",
+ misc1 & PCIM_AMDIOMMU_MISC1_MSINUMGA_MASK);
+ }
+ printf("\n\t\tVAsize=%s PAsize=%s GVAsize=%s",
+ cap_secdev_amdiommu_decode_vasize(misc0),
+ cap_secdev_amdiommu_decode_pasize(misc0),
+ cap_secdev_amdiommu_decode_gvasize(misc0));
+}
+
#define MAX_PAYLOAD(field) (128 << (field))
static const char *
@@ -813,6 +925,9 @@ list_caps(int fd, struct pci_conf *p, int level)
case PCIY_SUBVENDOR:
cap_subvendor(fd, p, ptr);
break;
+ case PCIY_SECDEV:
+ cap_secdev(fd, p, ptr);
+ break;
case PCIY_EXPRESS:
express = 1;
cap_express(fd, p, ptr);