Page MenuHomeFreeBSD

D47255.diff
No OneTemporary

D47255.diff

diff --git a/sys/x86/iommu/amd_reg.h b/sys/x86/iommu/amd_reg.h
new file mode 100644
--- /dev/null
+++ b/sys/x86/iommu/amd_reg.h
@@ -0,0 +1,746 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024 The FreeBSD Foundation
+ *
+ * This software was developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __X86_IOMMU_AMD_REG_H
+#define __X86_IOMMU_AMD_REG_H
+
+/*
+ * MMIO Registers. Offsets and bits definitions.
+ */
+
+#define AMDIOMMU_DEVTAB_BASE 0x0000
+#define AMDIOMMU_CMDBUF_BASE 0x0008
+#define AMDIOMMU_EVNTLOG_BASE 0x0010
+#define AMDIOMMU_CTRL 0x0018
+#define AMDIOMMU_EXCL_BASE 0x0020
+#define AMDIOMMU_EXCL_RANGE 0x0028
+#define AMDIOMMU_EFR 0x0030
+#define AMDIOMMU_PPRLOG_BASE 0x0038
+#define AMDIOMMU_HWEV_UPPER 0x0040
+#define AMDIOMMU_HWEV_LOWER 0x0048
+#define AMDIOMMU_HWEV_STATUS 0x0050
+
+#define AMDIOMMU_SMIF_0 0x0060
+#define AMDIOMMU_SMIF_1 0x0068
+#define AMDIOMMU_SMIF_2 0x0070
+#define AMDIOMMU_SMIF_3 0x0078
+#define AMDIOMMU_SMIF_4 0x0080
+#define AMDIOMMU_SMIF_5 0x0088
+#define AMDIOMMU_SMIF_6 0x0090
+#define AMDIOMMU_SMIF_7 0x0098
+#define AMDIOMMU_SMIF_8 0x00a0
+#define AMDIOMMU_SMIF_9 0x00a8
+#define AMDIOMMU_SMIF_10 0x00b0
+#define AMDIOMMU_SMIF_11 0x00b8
+#define AMDIOMMU_SMIF_12 0x00c0
+#define AMDIOMMU_SMIF_13 0x00c8
+#define AMDIOMMU_SMIF_14 0x00d0
+#define AMDIOMMU_SMIF_15 0x00d8
+
+#define AMDIOMMU_VAPIC_LOG_BASE 0x00e0
+#define AMDIOMMU_VAPIC_LOG_TAIL 0x00e8
+#define AMDIOMMU_PPRLOGB_BASE 0x00f0
+#define AMDIOMMU_EVNTLOGB_BASE 0x00f0
+
+#define AMDIOMMU_DEVTAB_S1_BASE 0x0100
+#define AMDIOMMU_DEVTAB_S2_BASE 0x0108
+#define AMDIOMMU_DEVTAB_S3_BASE 0x0110
+#define AMDIOMMU_DEVTAB_S4_BASE 0x0118
+#define AMDIOMMU_DEVTAB_S5_BASE 0x0120
+#define AMDIOMMU_DEVTAB_S6_BASE 0x0128
+#define AMDIOMMU_DEVTAB_S7_BASE 0x0130
+
+#define AMDIOMMU_DSFX 0x0138
+#define AMDIOMMU_DSCX 0x0140
+#define AMDIOMMU_DSSX 0x0148
+
+#define AMDIOMMU_MSI_VEC0 0x0150
+#define AMDIOMMU_MSI_VEC1 0x0154
+#define AMDIOMMU_MSI_CAP_H 0x0158
+#define AMDIOMMU_MSI_ADDR_LOW 0x015c
+#define AMDIOMMU_MSI_ADDR_HIGH 0x0160
+#define AMDIOMMU_MSI_DATA 0x0164
+#define AMDIOMMU_MSI_MAPCAP 0x0168
+
+#define AMDIOMMU_PERFOPT 0x016c
+
+#define AMDIOMMU_x2APIC_CTRL 0x0170
+#define AMDIOMMU_PPRI_CTRL 0x0178
+#define AMDIOMMU_GALOGI_CTRL 0x0180
+
+#define AMDIOMMU_vIOMMU_STATUS 0x0190
+
+#define AMDIOMMU_MARC0_BASE 0x0200
+#define AMDIOMMU_MARC0_RELOC 0x0208
+#define AMDIOMMU_MARC0_LEN 0x0210
+#define AMDIOMMU_MARC1_BASE 0x0218
+#define AMDIOMMU_MARC1_RELOC 0x0220
+#define AMDIOMMU_MARC1_LEN 0x0228
+#define AMDIOMMU_MARC2_BASE 0x0230
+#define AMDIOMMU_MARC2_RELOC 0x0238
+#define AMDIOMMU_MARC2_LEN 0x0240
+#define AMDIOMMU_MARC3_BASE 0x0248
+#define AMDIOMMU_MARC3_RELOC 0x0250
+#define AMDIOMMU_MARC3_LEN 0x0258
+
+#define AMDIOMMU_EFR2 0x01a0
+
+#define AMDIOMMU_CMDBUF_HEAD 0x2000
+#define AMDIOMMU_CMDBUF_TAIL 0x2008
+#define AMDIOMMU_EVNTLOG_HEAD 0x2010
+#define AMDIOMMU_EVNTLOG_TAIL 0x2018
+#define AMDIOMMU_CMDEV_STATUS 0x2020
+#define AMDIOMMU_PPRLOG_HEAD 0x2030
+#define AMDIOMMU_PPRLOG_TAIL 0x2038
+#define AMDIOMMU_vAPICLOG_HEAD 0x2040
+#define AMDIOMMU_vAPICLOG_TAIL 0x2048
+#define AMDIOMMU_PPRLOGB_HEAD 0x2050
+#define AMDIOMMU_PPRLOGB_TAIL 0x2058
+#define AMDIOMMU_EVNTLOGB_HEAD 0x2070
+#define AMDIOMMU_EVNTLOGB_TAIL 0x2078
+#define AMDIOMMU_PPRLOG_AUR 0x2080
+#define AMDIOMMU_PPRLOG_EAI 0x2088
+#define AMDIOMMU_PPRLOGB_AUR 0x2090
+
+/*
+ * IOMMU Control Register AMDIOMMU_CTRL fields
+ */
+#define AMDIOMMU_CTRL_EN 0x0000000000000001ull /* IOMMU En */
+#define AMDIOMMU_CTRL_HTTUN_EN 0x0000000000000002ull /* HT Tun Trans En */
+#define AMDIOMMU_CTRL_EVNTLOG_EN 0x0000000000000004ull /* Event Log En */
+#define AMDIOMMU_CTRL_EVENTINT_EN 0x0000000000000008ull /* Event Log Intr En */
+#define AMDIOMMU_CTRL_COMWINT_EN 0x0000000000000010ull /* Compl Wait Intr En */
+#define AMDIOMMU_CTRL_INVTOUT_MASK 0x00000000000000e0ull /* IOTLB Inv Timeout*/
+#define AMDIOMMU_CTRL_INVTOUT_NO 0x0000000000000000ull
+#define AMDIOMMU_CTRL_INVTOUT_1MS 0x0000000000000020ull
+#define AMDIOMMU_CTRL_INVTOUT_10MS 0x0000000000000040ull
+#define AMDIOMMU_CTRL_INVTOUT_100MS 0x0000000000000060ull
+#define AMDIOMMU_CTRL_INVTOUT_1S 0x0000000000000080ull
+#define AMDIOMMU_CTRL_INVTOUT_10S 0x00000000000000a0ull
+#define AMDIOMMU_CTRL_INVTOUT_100S 0x00000000000000b0ull
+#define AMDIOMMU_CTRL_INVTOUT_RSRV 0x00000000000000e0ull
+#define AMDIOMMU_CTRL_PASSPW 0x0000000000000100ull /* HT Pass Posted Wr */
+#define AMDIOMMU_CTRL_REPASSPW 0x0000000000000200ull /* HT Resp Pass Posted Wr */
+#define AMDIOMMU_CTRL_COHERENT 0x0000000000000400ull /* HT Coherent Reads */
+#define AMDIOMMU_CTRL_ISOC 0x0000000000000800ull /* HT Isoc Reads */
+#define AMDIOMMU_CTRL_CMDBUF_EN 0x0000000000001000ull /* Start CMD proc En */
+#define AMDIOMMU_CTRL_PPRLOG_EN 0x0000000000002000ull /* Periph Page Req Log En */
+#define AMDIOMMU_CTRL_PPRINT_EN 0x0000000000004000ull /* Periph Page Req Intr En */
+#define AMDIOMMU_CTRL_PPR_EN 0x0000000000008000ull /* Periph Page Req En */
+#define AMDIOMMU_CTRL_GT_EN 0x0000000000010000ull /* Guest En */
+#define AMDIOMMU_CTRL_GA_EN 0x0000000000020000ull /* Guest vAPIC En */
+#define AMDIOMMU_CTRL_SMIF_EN 0x0000000000400000ull /* SMI Filter En */
+#define AMDIOMMU_CTRL_SLFWB_DIS 0x0000000000800000ull /* Self WriteBack Dis */
+#define AMDIOMMU_CTRL_SMIFLOG_EN 0x0000000001000000ull /* SMI Filter Log En */
+#define AMDIOMMU_CTRL_GAM_EN_MASK 0x000000000e000000ull /* Guest vAPIC Mode En */
+#define AMDIOMMU_CTRL_GAM_EN_vAPIC_GM0 0x0000000000000000ull /* IRTE.GM = 0 */
+#define AMDIOMMU_CTRL_GAM_EN_vAPIC_GM1 0x0000000002000000ull /* IRTE.GM = 1 */
+#define AMDIOMMU_CTRL_GALOG_EN 0x0000000010000000ull /* Guest vAPIC GA Log En */
+#define AMDIOMMU_CTRL_GAINT_EN 0x0000000020000000ull /* Guest vAPIC GA Intr En */
+#define AMDIOMMU_CTRL_DUALPPRLOG_MASK 0x00000000c0000000ull /* Dual Periph Page Req Log En */
+#define AMDIOMMU_CTRL_DUALPPRLOG_A 0x0000000000000000ull /* Use Log A */
+#define AMDIOMMU_CTRL_DUALPPRLOG_B 0x0000000040000000ull /* Use Log B */
+#define AMDIOMMU_CTRL_DUALPPRLOG_SWAP 0x0000000080000000ull /* Auto-swap on full */
+#define AMDIOMMU_CTRL_DUALPPRLOG_RSRV 0x00000000c0000000ull
+#define AMDIOMMU_CTRL_DUALEVNTLOG_MASK 0x0000000300000000ull /* Dual Event Log En */
+#define AMDIOMMU_CTRL_DUALEVNTLOG_A 0x0000000000000000ull /* Use Log A Buf */
+#define AMDIOMMU_CTRL_DUALEVNTLOG_B 0x0000000100000000ull /* Use Log B Buf */
+#define AMDIOMMU_CTRL_DUALEVNTLOG_SWAP 0x0000000200000000ull /* Auto-swap on full */
+#define AMDIOMMU_CTRL_DUALEVNTLOG_RSRV 0x0000000300000000ull
+#define AMDIOMMU_CTRL_DEVTABSEG_MASK 0x0000001c00000000ull /* Dev Table Segm */
+#define AMDIOMMU_CTRL_DEVTABSEG_1 0x0000000000000000ull /* 1 Segment */
+#define AMDIOMMU_CTRL_DEVTABSEG_2 0x0000000400000000ull /* 2 Segments */
+#define AMDIOMMU_CTRL_DEVTABSEG_4 0x0000000800000000ull /* 4 Segments */
+#define AMDIOMMU_CTRL_DEVTABSEG_8 0x0000000c00000000ull /* 8 Segments */
+#define AMDIOMMU_CTRL_PRIVABRT_MASK 0x0000006000000000ull /* Privilege Abort En */
+#define AMDIOMMU_CTRL_PRIVABRT_USR 0x0000000000000000ull /* Privilege Abort User */
+#define AMDIOMMU_CTRL_PRIVABRT_ALL 0x0000002000000000ull /* Privilege Abort Always */
+#define AMDIOMMU_CTRL_PPRAUTORSP_EN 0x0000008000000000ull /* PPR Auto Resp En */
+#define AMDIOMMU_CTRL_MARC_EN 0x0000010000000000ull /* Memory Addr Routing En */
+#define AMDIOMMU_CTRL_BLKSTOPMRK_EN 0x0000020000000000ull /* Block StopMark En */
+#define AMDIOMMU_CTRL_PPRAUTORESPA_EN 0x0000040000000000ull /* PPR Auto Resp Always En */
+#define AMDIOMMU_CTRL_EPH_EN 0x0000200000000000ull /* Enh PPR Handling En */
+#define AMDIOMMU_CTRL_HADUP_MASK 0x0000c00000000000ull /* Access and Dirty in host PT */
+#define AMDIOMMU_CTRL_GDUP_DIS 0x0001000000000000ull /* Dis Dirty in guest PT */
+#define AMDIOMMU_CTRL_XT_EN 0x0004000000000000ull /* x2APIC mode */
+#define AMDIOMMU_CTRL_INTCAPXT_EN 0x0008000000000000ull /* x2APIC mode for IOMMU intrs */
+#define AMDIOMMU_CTRL_vCMD_EN 0x0010000000000000ull /* vCMD buffer proc En */
+#define AMDIOMMU_CTRL_vIOMMU_EN 0x0020000000000000ull /* vIOMMU En */
+#define AMDIOMMU_CTRL_GAUP_DIS 0x0040000000000000ull /* Dis Access in guest PT */
+#define AMDIOMMU_CTRL_GAPPI_EN 0x0080000000000000ull /* Guest APIC phys proc intr En */
+#define AMDIOMMU_CTRL_TMPM_EN 0x0100000000000000ull /* Tiered Mem Page Migration En */
+#define AMDIOMMU_CTRL_GGCR3TRP_PHYS 0x0400000000000000ull /* GCR3 is GPA (otherwise SPA) */
+#define AMDIOMMU_CTRL_IRTCACHE_DIS 0x0800000000000000ull /* IRT Caching Dis */
+#define AMDIOMMU_CTRL_GSTBUFTRP_MODE 0x1000000000000000ull /* See spec */
+#define AMDIOMMU_CTRL_SNPAVIC_MASK 0xe000000000000000ull /* MBZ */
+
+/*
+ * IOMMU Extended Feature Register AMDIOMMU_EFR fields
+ */
+#define AMDIOMMU_EFR_XT_SUP 0x0000000000000004ull /* x2APIC */
+#define AMDIOMMU_EFR_HWEV_SUP 0x0000000000000100ull /* HW Event regs */
+#define AMDIOMMU_EFR_PC_SUP 0x0000000000000200ull /* Perf counters */
+#define AMDIOMMU_EFR_HATS_MASK 0x0000000000000c00ull /* Host Addr Trans Size */
+#define AMDIOMMU_EFR_HATS_4LVL 0x0000000000000000ull
+#define AMDIOMMU_EFR_HATS_5LVL 0x0000000000000400ull
+#define AMDIOMMU_EFR_HATS_6LVL 0x0000000000000800ull
+#define AMDIOMMU_EFR_DEVTBLSEG_MASK 0x000000c000000000ull /* DevTbl segmentation */
+#define AMDIOMMU_EFR_DEVTBLSEG_SHIFT 38
+
+/* IOMMU Command Pointers (Head/Tail) registers fields */
+#define AMDIOMMU_CMDPTR_MASK 0x000000000007fff0ull
+
+/* IOMMU Command Buffer Base fields */
+#define AMDIOMMU_CMDBUF_BASE_SZSHIFT 56 /* Shift for size */
+#define AMDIOMMU_CMDBUF_MAX (512 * 1024)
+
+/* IOMMU Event Log Base register fields */
+#define AMDIOMMU_EVNTLOG_BASE_SZSHIFT 56 /* Shift for size */
+#define AMDIOMMU_EVNTLOG_MIN 256
+#define AMDIOMMU_EVNTLOG_MAX 32768
+
+/* IOMMU Hardware Event Status register fields */
+#define AMDIOMMU_HWEVS_HEV 0x00000001 /* HW Ev Valid */
+#define AMDIOMMU_HWEVS_HEO 0x00000002 /* HW Ev Overfl */
+
+/*
+ * IOMMU Command and Event Status register fields.
+ * From the spec, all defined bits are either RO or RW1C. As a consequence,
+ * single bit can be safely written to the register to clean a specific
+ * condition.
+ */
+#define AMDIOMMU_CMDEVS_EVOVRFLW 0x00000001
+#define AMDIOMMU_CMDEVS_EVLOGINT 0x00000002
+#define AMDIOMMU_CMDEVS_COMWAITINT 0x00000004
+#define AMDIOMMU_CMDEVS_EVLOGRUN 0x00000008
+#define AMDIOMMU_CMDEVS_CMDBUFRUN 0x00000010
+#define AMDIOMMU_CMDEVS_PPROVRFLW 0x00000020
+#define AMDIOMMU_CMDEVS_PPRINT 0x00000040
+#define AMDIOMMU_CMDEVS_PPRLOGRUN 0x00000080
+#define AMDIOMMU_CMDEVS_GALOGRUN 0x00000100
+#define AMDIOMMU_CMDEVS_GALOVRFLW 0x00000200
+#define AMDIOMMU_CMDEVS_GAINT 0x00000400
+#define AMDIOMMU_CMDEVS_PPROVRFLWB 0x00000800
+#define AMDIOMMU_CMDEVS_PPRLOGACTIVE 0x00001000
+#define AMDIOMMU_CMDEVS_RESV1 0x00002000
+#define AMDIOMMU_CMDEVS_RESV2 0x00004000
+#define AMDIOMMU_CMDEVS_EVOVRFLWB 0x00008000
+#define AMDIOMMU_CMDEVS_EVLOGACTIVE 0x00010000
+#define AMDIOMMU_CMDEVS_PPROVRFLWEB 0x00020000
+#define AMDIOMMU_CMDEVS_PPROVRFLWE 0x00040000
+
+/*
+ * Device Table Entry (DTE)
+ */
+struct amdiommu_dte {
+ u_int v:1; /* Valid */
+ u_int tv:1; /* Translation Valid */
+ u_int rsrv0:5;
+ u_int had:2; /* Host Access Dirty */
+ u_int pgmode:3; /* Paging Mode */
+ uint64_t ptroot:40; /* Page Table Root */
+ u_int ppr:1; /* PPR En */
+ u_int gprp:1; /* Guest PPR Resp with PASID */
+ u_int giov:1; /* Guest IO Prot Valid */
+ u_int gv:1; /* Guest Translation Valid */
+ u_int glx:2; /* Guest Levels Translated */
+ u_int gcr3root0:3; /* GCR3 root pointer part */
+ u_int ir:1; /* Read Perm */
+ u_int iw:1; /* Write Perm */
+ u_int rsrv1:1;
+ u_int domainid:16; /* domain tag */
+ u_int gcr3root1:16; /* GCR3 root pointer part */
+ u_int i:1; /* IOTLB En */
+ u_int se:1; /* Suppress IO Fault Events */
+ u_int sa:1; /* Suppress All IO Fault Events */
+ u_int pioctl:2; /* Port IO Control */
+ u_int cache:1; /* IOTLB Cache Hint */
+ u_int sd:1; /* Snoop Disable */
+ u_int ex:1; /* Allow Exclusion */
+ u_int sysmgt:2; /* System Management Msg Handling */
+ u_int sats:1; /* Secure/Non-secure ATS */
+ u_int gcr3root2:21; /* GCR3 root pointer part */
+ u_int iv:1; /* Intr Map Valid */
+ u_int inttablen:4; /* log2 Intr Table Len */
+ u_int ig:1; /* Ignore Unmapped Interrupts */
+ uint64_t intrroot:46; /* Interrupt Table Root (-low 6bits) */
+ u_int rsrv2:2;
+ u_int gpm:2; /* Guest Paging Mode */
+ u_int initpass:1; /* INIT pass-through */
+ u_int eintpass:1; /* ExtInt pass-through */
+ u_int nmipass:1; /* NMI pass-through */
+ u_int hptmode:1; /* Host Page Table Mode Hint */
+ u_int intctl:2; /* Interrupt Control */
+ u_int lint0pass:1; /* LINT0 pass-through */
+ u_int lint1pass:1; /* LINT1 pass-through */
+ u_int rsrv3:15;
+ u_int vimu:1; /* Virtualize IOMMU En */
+ u_int gdevid:16; /* Guest Dev Id */
+ u_int gid:16; /* Guest Id */
+ u_int rsrv4:5;
+ u_int rsrv5:1; /* Not Checked, sw avail */
+ u_int attrv:1; /* Attr Override Valid */
+ u_int mode0fc:1; /* Replace for PTE.FC */
+ u_int snoopattr:8; /* GuestPTE.PAT -> ATS.N xlat */
+} __packed;
+_Static_assert(sizeof(struct amdiommu_dte) == 8 * sizeof(uint32_t), "DTE");
+
+#define AMDIOMMU_DTE_HAD_NAND 0x0 /* No Access, No Dirty */
+#define AMDIOMMU_DTE_HAD_AND 0x1 /* Access, No Dirty */
+#define AMDIOMMU_DTE_HAD_RSRV 0x2
+#define AMDIOMMU_DTE_HAD_AD 0x3 /* Access, Dirty */
+
+#define AMDIOMMU_DTE_PGMODE_1T1 0x0 /* SPA = GPA */
+#define AMDIOMMU_DTE_PGMODE_1LV 0x1 /* 1 Level PT */
+#define AMDIOMMU_DTE_PGMODE_2LV 0x2 /* 2 Level PT */
+#define AMDIOMMU_DTE_PGMODE_3LV 0x3 /* 3 Level PT */
+#define AMDIOMMU_DTE_PGMODE_4LV 0x4 /* 4 Level PT */
+#define AMDIOMMU_DTE_PGMODE_5LV 0x5 /* 5 Level PT */
+#define AMDIOMMU_DTE_PGMODE_6LV 0x6 /* 6 Level PT */
+#define AMDIOMMU_DTE_PGMODE_RSRV 0x7
+
+#define AMDIOMMU_DTE_GLX_1LV 0x0 /* 1 Level GCR3 */
+#define AMDIOMMU_DTE_GLX_2LV 0x1 /* 2 Level GCR3 */
+#define AMDIOMMU_DTE_GLX_3LV 0x2 /* 3 Level GCR3 */
+#define AMDIOMMU_DTE_GLX_RSRV 0x3
+
+#define AMDIOMMU_DTE_PIOCTL_DIS 0x0
+#define AMDIOMMU_DTE_PIOCTL_EN 0x1
+#define AMDIOMMU_DTE_PIOCTL_MAP 0x2
+#define AMDIOMMU_DTE_PIOCTL_RSRV 0x3
+
+#define AMDIOMMU_DTE_SYSMGT_DIS 0x0 /* Target Abort */
+#define AMDIOMMU_DTE_SYSMGT_FW 0x0 /* Forwarded All */
+#define AMDIOMMU_DTE_SYSMGT_FWI 0x0 /* Forwarded INT */
+#define AMDIOMMU_DTE_SYSMGT_T 0x0 /* Translated */
+
+#define AMDIOMMU_DTE_GPM_4LV 0x0 /* 4 Level */
+#define AMDIOMMU_DTE_GPM_5LV 0x1 /* 4 Level */
+#define AMDIOMMU_DTE_GPM_RSRV1 0x2
+#define AMDIOMMU_DTE_GPM_RSRV2 0x3
+
+#define AMDIOMMU_DTE_INTCTL_DIS 0x0 /* Target Abort */
+#define AMDIOMMU_DTE_INTCTL_FW 0x1 /* Forward Unmapped */
+#define AMDIOMMU_DTE_INTCTL_MAP 0x2 /* Forward Remapped */
+#define AMDIOMMU_DTE_INTCTL_RSRV 0x3
+
+#define AMDIOMMU_PGTBL_MAXLVL 6
+
+/*
+ * Page Table Entry (PTE/PDE)
+ */
+#define AMDIOMMU_PTE_PR 0x0001 /* Present, AKA V */
+#define AMDIOMMU_IGN1 0x0002
+#define AMDIOMMU_IGN2 0x0004
+#define AMDIOMMU_IGN3 0x0008
+#define AMDIOMMU_IGN4 0x0010
+#define AMDIOMMU_PTE_A 0x0020 /* Accessed */
+#define AMDIOMMU_PTE_D 0x0040 /* Dirty */
+#define AMDIOMMU_IGN5 0x0080
+#define AMDIOMMU_IGN6 0x0100
+#define AMDIOMMU_PTE_NLVL_MASK 0x0e00 /* Next Level */
+#define AMDIOMMU_PTE_NLVL_SHIFT 9
+#define AMDIOMMU_PTE_NLVL_7h 0x0e00 /* Magic Next Level */
+#define AMDIOMMU_PTE_PA_MASK 0x000ffffffffff000ull
+#define AMDIOMMU_PTE_PA_SHIFT 12
+#define AMDIOMMU_PTE_PMC_MASK 0x0600000000000000ull /* Page Migr */
+#define AMDIOMMU_PTE_U 0x0800000000000000ull /* ATS.U */
+#define AMDIOMMU_PTE_FC 0x1000000000000000ull /* Force Coh */
+#define AMDIOMMU_PTE_IR 0x2000000000000000ull /* Read Perm */
+#define AMDIOMMU_PTE_IW 0x4000000000000000ull /* Write Perm */
+#define AMDIOMMU_PTE_IGN7 0x8000000000000000ull
+
+/*
+ * IRTEs
+ */
+
+/* vAPIC is not enabled, guestmode = 0 */
+struct amdiommu_irte_basic_novapic {
+ u_int remapen:1; /* 0 - Target Abort */
+ u_int supiopf:1; /* Supress IO_PAGE_FAULT events */
+ u_int inttype:3;
+ u_int rqeoi:1; /* Request EOI */
+ u_int dm:1; /* Dest Mode */
+ u_int guestmode:1; /* MBZ */
+ u_int dest:8; /* Destination APIC */
+ u_int vector:8;
+ u_int rsrv:8;
+} __packed;
+_Static_assert(sizeof(struct amdiommu_irte_basic_novapic) ==
+ 1 * sizeof(uint32_t), "IRTE 1");
+
+/* vAPIC is enabled, guestmode = 0 */
+struct amdiommu_irte_basic_vapic {
+ u_int remapen:1; /* 0 - Target Abort */
+ u_int supiopf:1; /* Supress IO_PAGE_FAULT events */
+ u_int inttype:3;
+ u_int rqeoi:1; /* Request EOI */
+ u_int dm:1; /* Dest Mode */
+ u_int guestmode:1; /* MBZ */
+ u_int dest:8; /* Destination APIC */
+ u_int rsrv0:16;
+ u_int rsrv1:32;
+ u_int vector:8;
+ u_int rsrv2:24;
+ u_int rsrv3:32;
+} __packed;
+_Static_assert(sizeof(struct amdiommu_irte_basic_vapic) ==
+ 4 * sizeof(uint32_t), "IRTE 2");
+
+/* vAPIC is enabled, guestmode = 1 */
+struct amdiommu_irte_guest_vapic {
+ u_int remapen:1; /* 0 - Target Abort */
+ u_int supiopf:1; /* Supress IO_PAGE_FAULT events */
+ u_int galogintr:1;
+ u_int rsrv0:2;
+ u_int gappidis:1; /* supress GAPPI */
+ u_int isrun:1; /* Guest Running hint */
+ u_int guestmode:1; /* MB1 */
+ u_int dest:8; /* Destination APIC for dorbell */
+ u_int rsrv1:16;
+ u_int gatag:32;
+ u_int vector:8;
+ u_int rsrv2:4;
+ uint64_t vapicrp:40; /* 51:12 bits of SPA for APIC backing page */
+ u_int rsrv3:12;
+} __packed;
+_Static_assert(sizeof(struct amdiommu_irte_guest_vapic) ==
+ 4 * sizeof(uint32_t), "IRTE 3");
+
+/* vAPIC is enabled, guestmode = 0, x2APIC */
+struct amdiommu_irte_basic_vapic_x2 {
+ u_int remapen:1; /* 0 - Target Abort */
+ u_int supiopf:1; /* Supress IO_PAGE_FAULT events */
+ u_int inttype:3;
+ u_int rqeoi:1; /* Request EOI */
+ u_int dm:1; /* Dest Mode */
+ u_int guestmode:1; /* MBZ */
+ u_int dest0:24; /* Destination APIC 23:0 */
+ u_int rsrv0:32;
+ u_int vector:8;
+ u_int rsrv1:24;
+ u_int rsrv2:24;
+ u_int dest1:8; /* Destination APIC 31:24 */
+} __packed;
+_Static_assert(sizeof(struct amdiommu_irte_basic_vapic_x2) ==
+ 4 * sizeof(uint32_t), "IRTE 4");
+
+/* vAPIC is enabled, guestmode = 1, x2APIC */
+struct amdiommu_irte_guest_vapic_x2 {
+ u_int remapen:1; /* 0 - Target Abort */
+ u_int supiopf:1; /* Supress IO_PAGE_FAULT events */
+ u_int galogintr:1;
+ u_int rsrv0:2;
+ u_int gappidis:1; /* supress GAPPI */
+ u_int isrun:1; /* Guest Running hint */
+ u_int guestmode:1; /* MB1 */
+ u_int dest0:24; /* Destination APIC for dorbell 23:0 */
+ u_int gatag:32;
+ u_int vector:8;
+ u_int rsrv2:4;
+ uint64_t vapicrp:40; /* 51:12 bits of SPA for APIC backing page */
+ u_int rsrv3:4;
+ u_int dest1:8; /* Destination APIC 31:24 */
+} __packed;
+_Static_assert(sizeof(struct amdiommu_irte_guest_vapic_x2) ==
+ 4 * sizeof(uint32_t), "IRTE 5");
+
+#define AMDIOMMU_IRTE_INTTYPE_FIXED 0
+#define AMDIOMMU_IRTE_INTTYPE_ARBITR 1
+
+#define AMDIOMMU_IRTE_DM_LOGICAL 1
+#define AMDIOMMU_IRTE_DM_PHYSICAL 1
+
+/*
+ * Commands
+ */
+
+struct amdiommu_cmd_generic {
+ u_int w0:32;
+ union {
+ u_int ww1:32;
+ struct {
+ u_int w1:28;
+ u_int op:4;
+ };
+ };
+ u_int w2:32;
+ u_int w3:32;
+} __packed;
+_Static_assert(sizeof(struct amdiommu_cmd_generic) ==
+ 4 * sizeof(uint32_t), "CMD_GENERIC");
+
+#define AMDIOMMU_CMD_SZ_SHIFT 4 /* Shift for cmd count
+ to ring offset */
+#define AMDIOMMU_CMD_SZ sizeof(struct amdiommu_cmd_generic)
+ /* Command size */
+_Static_assert((1 << AMDIOMMU_CMD_SZ_SHIFT) == AMDIOMMU_CMD_SZ,
+ "CMD size shift");
+
+struct amdiommu_cmd_completion_wait {
+ u_int s:1;
+ u_int i:1;
+ u_int f:1;
+ u_int address0:29; /* Store Address 31:3 */
+ u_int address1:20; /* Store Address 51:32 */
+ u_int rsrv:8;
+ u_int op:4;
+ u_int data0:32;
+ u_int data1:32;
+} __packed;
+_Static_assert(sizeof(struct amdiommu_cmd_completion_wait) ==
+ 4 * sizeof(uint32_t), "CMD_COMPLETION_WAIT");
+
+struct amdiommu_cmd_invalidate_devtab_entry {
+ u_int devid:16;
+ u_int rsrv0:16;
+ u_int rsrv1:28;
+ u_int op:4;
+ u_int rsrv2:32;
+ u_int rsrv3:32;
+} __packed;
+_Static_assert(sizeof(struct amdiommu_cmd_invalidate_devtab_entry) ==
+ 4 * sizeof(uint32_t), "CMD_INVALIDATE_DEVTAB_ENTRY");
+
+struct amdiommu_cmd_invalidate_iommu_pages {
+ u_int pasid:20;
+ u_int rsrv0:12;
+ u_int domainid:16;
+ u_int rsrv1:12;
+ u_int op:4;
+ u_int s:1;
+ u_int pde:1;
+ u_int gn:1;
+ u_int rsrv2:9;
+ uint64_t address:52; /* Address 63:12 */
+} __packed;
+_Static_assert(sizeof(struct amdiommu_cmd_invalidate_iommu_pages) ==
+ 4 * sizeof(uint32_t), "CMD_INVALIDATE_IOMMU_PAGES");
+
+struct amdiommu_cmd_invalidate_iotlb_pages {
+ u_int devid:16;
+ u_int pasid1:8;
+ u_int maxpend0:8;
+ u_int queueid:16;
+ u_int pasid0:8;
+ u_int pasid2:4;
+ u_int op:4;
+ u_int s:1;
+ u_int rsrv0:1;
+ u_int gn:1;
+ u_int rsrv1:1;
+ u_int type:2;
+ u_int rsrv2:6;
+ uint64_t address:52; /* Address 63:12 */
+} __packed;
+_Static_assert(sizeof(struct amdiommu_cmd_invalidate_iotlb_pages) ==
+ 4 * sizeof(uint32_t), "CMD_INVALIDATE_IOTLB_PAGES");
+
+struct amdiommu_cmd_invalidate_interrupt_table {
+ u_int devid:16;
+ u_int rsrv0:16;
+ u_int rsrv1:28;
+ u_int op:4;
+ u_int rsrv2:32;
+ u_int rsrv3:32;
+} __packed;
+_Static_assert(sizeof(struct amdiommu_cmd_invalidate_interrupt_table) ==
+ 4 * sizeof(uint32_t), "CMD_INVALIDATE_INTERRUPT_TABLE");
+
+struct amdiommu_cmd_prefetch_iommu_pages {
+ u_int devid:16;
+ u_int rsrv0:8;
+ u_int pfcount:8;
+ u_int pasid:20;
+ u_int rsrv1:8;
+ u_int op:4;
+ u_int s:1;
+ u_int rsrv2:1;
+ u_int gn:1;
+ u_int rsrv3:1;
+ u_int inval:1; /* Invalidate First */
+ u_int rsrv4:7;
+ uint64_t address:52; /* Address 63:12 */
+} __packed;
+_Static_assert(sizeof(struct amdiommu_cmd_prefetch_iommu_pages) ==
+ 4 * sizeof(uint32_t), "CMD_PREFETCH_IOMMU_PAGES");
+
+struct amdiommu_cmd_complete_ppr_request {
+ u_int devid:16;
+ u_int rsrv0:16;
+ u_int pasid:20;
+ u_int rsrv1:8;
+ u_int op:4;
+ u_int rsrv2:2;
+ u_int gn:1;
+ u_int rsrv3:29;
+ u_int compltag:16;
+ u_int rsrv4:16;
+} __packed;
+_Static_assert(sizeof(struct amdiommu_cmd_complete_ppr_request) ==
+ 4 * sizeof(uint32_t), "CMD_COMPLETE_PPR_REQUEST");
+
+struct amdiommu_cmd_invalidate_iommu_all {
+ u_int rsrv0:32;
+ u_int op:4;
+ u_int rsrv1:28;
+ u_int rsrv2:32;
+ u_int rsrv3:32;
+} __packed;
+_Static_assert(sizeof(struct amdiommu_cmd_invalidate_iommu_all) ==
+ 4 * sizeof(uint32_t), "CMD_INVALIDATE_IOMMU_ALL");
+
+struct amdiommu_cmd_insert_guest_event {
+ u_int rsrv0:32;
+ u_int guestid:16;
+ u_int rsrv1:12;
+ u_int op:4;
+ u_int rsrv2:32;
+ u_int rsrv3:32;
+} __packed;
+_Static_assert(sizeof(struct amdiommu_cmd_insert_guest_event) ==
+ 4 * sizeof(uint32_t), "CMD_INSERT_GUEST_EVENT");
+
+struct amdiommu_cmd_reset_vmmio {
+ u_int guestid:16;
+ u_int rsrv0:11;
+ u_int all:1;
+ u_int rsrv1:3;
+ u_int vcmd:1;
+ u_int rsrv2:27;
+ u_int op:4;
+ u_int rsrv3:32;
+ u_int rsrv4:32;
+} __packed;
+_Static_assert(sizeof(struct amdiommu_cmd_reset_vmmio) ==
+ 4 * sizeof(uint32_t), "CMD_RESET_VMMIO");
+
+#define AMDIOMMU_CMD_COMPLETION_WAIT 0x1
+#define AMDIOMMU_CMD_INVALIDATE_DEVTAB_ENTRY 0x2
+#define AMDIOMMU_CMD_INVALIDATE_IOMMU_PAGES 0x3
+#define AMDIOMMU_CMD_INVALIDATE_IOTLB_PAGES 0x4
+#define AMDIOMMU_CMD_INVALIDATE_INTERRUPT_TABLE 0x5
+#define AMDIOMMU_CMD_PREFETCH_IOMMU_PAGES 0x6
+#define AMDIOMMU_CMD_COMPLETE_PPR_REQUEST 0x7
+#define AMDIOMMU_CMD_INVALIDATE_IOMMU_ALL 0x8
+#define AMDIOMMU_CMD_INSERT_GUEST_EVENT 0x9
+#define AMDIOMMU_CMD_RESET_VMMIO 0xa
+
+/*
+ * Logging
+ */
+struct amdiommu_event_generic {
+ u_int w0:32;
+ union {
+ u_int ww1:32;
+ struct {
+ u_int w1:28;
+ u_int code:4;
+ };
+ };
+ u_int w2:32;
+ u_int w3:32;
+} __packed;
+_Static_assert(sizeof(struct amdiommu_event_generic) ==
+ 4 * sizeof(uint32_t), "EVENT_GENERIC");
+
+#define AMDIOMMU_EV_SZ_SHIFT 4 /* Shift for event count
+ to ring offset */
+#define AMDIOMMU_EV_SZ sizeof(struct amdiommu_event_generic)
+ /* Event size */
+_Static_assert((1 << AMDIOMMU_EV_SZ_SHIFT) == AMDIOMMU_EV_SZ,
+ "Event size shift");
+
+struct amdiommu_event_ill_dev_table_entry {
+ u_int devid:16;
+ u_int pasid1:4;
+ u_int rsrv0:7;
+ u_int vnr:1;
+ u_int rsrv1:1;
+ u_int vevent:1;
+ u_int vptr:1;
+ u_int vcmd:1;
+ u_int pasid:16;
+ u_int gn:1;
+ u_int rsrv2:2;
+ u_int i:1;
+ u_int rsrv3:1;
+ u_int rw:1;
+ u_int rsrv4:1;
+ u_int rz:1;
+ u_int tr:1;
+ u_int rsrv5:3;
+ u_int code:4;
+ u_int rsrv6:2;
+ u_int addr1:30;
+ u_int addr2:32;
+} __packed;
+_Static_assert(sizeof(struct amdiommu_event_ill_dev_table_entry) ==
+ 4 * sizeof(uint32_t), "EVENT_ILLEGAL_DEV_TABLE_ENTRY");
+
+struct amdiommu_event_io_page_fault_entry {
+ u_int devid:16;
+ u_int pasid1:4;
+ u_int rsrv0:7;
+ u_int vnr:1;
+ u_int rsrv1:1;
+ u_int vevent:1;
+ u_int vptr:1;
+ u_int vcmd:1;
+ u_int pasid:16; /* also domain id */
+ u_int gn:1;
+ u_int nx:1;
+ u_int us:1;
+ u_int i:1;
+ u_int pr:1;
+ u_int rw:1;
+ u_int pe:1;
+ u_int rz:1;
+ u_int tr:1;
+ u_int rsrv2:3;
+ u_int code:4;
+ u_int addr1:32;
+ u_int addr2:32;
+} __packed;
+_Static_assert(sizeof(struct amdiommu_event_io_page_fault_entry) ==
+ 4 * sizeof(uint32_t), "EVENT_IO_PAGE_FAULT_ENTRY");
+
+#define AMDIOMMU_EV_ILL_DEV_TABLE_ENTRY 0x1
+#define AMDIOMMU_EV_IO_PAGE_FAULT 0x2
+#define AMDIOMMU_EV_DEV_TAB_HW_ERROR 0x3
+#define AMDIOMMU_EV_PAGE_TAB_HW_ERROR 0x4
+#define AMDIOMMU_EV_ILL_CMD_ERROR 0x5
+#define AMDIOMMU_EV_CMD_HW_ERROR 0x6
+#define AMDIOMMU_EV_IOTLB_INV_TIMEOUT 0x7
+#define AMDIOMMU_EV_INVALID_DEV_REQ 0x8
+#define AMDIOMMU_EV_INVALID_PPR_REQ 0x9
+#define AMDIOMMU_EV_COUNTER_ZERO 0xa /* Typo in table 42? */
+
+#endif /* __X86_IOMMU_AMD_REG_H */

File Metadata

Mime Type
text/plain
Expires
Mon, Dec 2, 4:50 AM (21 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14440514
Default Alt Text
D47255.diff (26 KB)

Event Timeline