10a9bec17SKonstantin Belousov /*- 20a9bec17SKonstantin Belousov * SPDX-License-Identifier: BSD-2-Clause 30a9bec17SKonstantin Belousov * 40a9bec17SKonstantin Belousov * Copyright (c) 2024 The FreeBSD Foundation 50a9bec17SKonstantin Belousov * 60a9bec17SKonstantin Belousov * This software was developed by Konstantin Belousov <kib@FreeBSD.org> 70a9bec17SKonstantin Belousov * under sponsorship from the FreeBSD Foundation. 80a9bec17SKonstantin Belousov * 90a9bec17SKonstantin Belousov * Redistribution and use in source and binary forms, with or without 100a9bec17SKonstantin Belousov * modification, are permitted provided that the following conditions 110a9bec17SKonstantin Belousov * are met: 120a9bec17SKonstantin Belousov * 1. Redistributions of source code must retain the above copyright 130a9bec17SKonstantin Belousov * notice, this list of conditions and the following disclaimer. 140a9bec17SKonstantin Belousov * 2. Redistributions in binary form must reproduce the above copyright 150a9bec17SKonstantin Belousov * notice, this list of conditions and the following disclaimer in the 160a9bec17SKonstantin Belousov * documentation and/or other materials provided with the distribution. 170a9bec17SKonstantin Belousov * 180a9bec17SKonstantin Belousov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 190a9bec17SKonstantin Belousov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 200a9bec17SKonstantin Belousov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 210a9bec17SKonstantin Belousov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 220a9bec17SKonstantin Belousov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 230a9bec17SKonstantin Belousov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 240a9bec17SKonstantin Belousov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 250a9bec17SKonstantin Belousov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 260a9bec17SKonstantin Belousov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 270a9bec17SKonstantin Belousov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 280a9bec17SKonstantin Belousov * SUCH DAMAGE. 290a9bec17SKonstantin Belousov */ 300a9bec17SKonstantin Belousov 310a9bec17SKonstantin Belousov #ifndef __X86_IOMMU_AMD_REG_H 320a9bec17SKonstantin Belousov #define __X86_IOMMU_AMD_REG_H 330a9bec17SKonstantin Belousov 340a9bec17SKonstantin Belousov /* 350a9bec17SKonstantin Belousov * MMIO Registers. Offsets and bits definitions. 360a9bec17SKonstantin Belousov */ 370a9bec17SKonstantin Belousov 380a9bec17SKonstantin Belousov #define AMDIOMMU_DEVTAB_BASE 0x0000 390a9bec17SKonstantin Belousov #define AMDIOMMU_CMDBUF_BASE 0x0008 400a9bec17SKonstantin Belousov #define AMDIOMMU_EVNTLOG_BASE 0x0010 410a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL 0x0018 420a9bec17SKonstantin Belousov #define AMDIOMMU_EXCL_BASE 0x0020 430a9bec17SKonstantin Belousov #define AMDIOMMU_EXCL_RANGE 0x0028 440a9bec17SKonstantin Belousov #define AMDIOMMU_EFR 0x0030 450a9bec17SKonstantin Belousov #define AMDIOMMU_PPRLOG_BASE 0x0038 460a9bec17SKonstantin Belousov #define AMDIOMMU_HWEV_UPPER 0x0040 470a9bec17SKonstantin Belousov #define AMDIOMMU_HWEV_LOWER 0x0048 480a9bec17SKonstantin Belousov #define AMDIOMMU_HWEV_STATUS 0x0050 490a9bec17SKonstantin Belousov 500a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_0 0x0060 510a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_1 0x0068 520a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_2 0x0070 530a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_3 0x0078 540a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_4 0x0080 550a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_5 0x0088 560a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_6 0x0090 570a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_7 0x0098 580a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_8 0x00a0 590a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_9 0x00a8 600a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_10 0x00b0 610a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_11 0x00b8 620a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_12 0x00c0 630a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_13 0x00c8 640a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_14 0x00d0 650a9bec17SKonstantin Belousov #define AMDIOMMU_SMIF_15 0x00d8 660a9bec17SKonstantin Belousov 670a9bec17SKonstantin Belousov #define AMDIOMMU_VAPIC_LOG_BASE 0x00e0 680a9bec17SKonstantin Belousov #define AMDIOMMU_VAPIC_LOG_TAIL 0x00e8 690a9bec17SKonstantin Belousov #define AMDIOMMU_PPRLOGB_BASE 0x00f0 700a9bec17SKonstantin Belousov #define AMDIOMMU_EVNTLOGB_BASE 0x00f0 710a9bec17SKonstantin Belousov 720a9bec17SKonstantin Belousov #define AMDIOMMU_DEVTAB_S1_BASE 0x0100 730a9bec17SKonstantin Belousov #define AMDIOMMU_DEVTAB_S2_BASE 0x0108 740a9bec17SKonstantin Belousov #define AMDIOMMU_DEVTAB_S3_BASE 0x0110 750a9bec17SKonstantin Belousov #define AMDIOMMU_DEVTAB_S4_BASE 0x0118 760a9bec17SKonstantin Belousov #define AMDIOMMU_DEVTAB_S5_BASE 0x0120 770a9bec17SKonstantin Belousov #define AMDIOMMU_DEVTAB_S6_BASE 0x0128 780a9bec17SKonstantin Belousov #define AMDIOMMU_DEVTAB_S7_BASE 0x0130 790a9bec17SKonstantin Belousov 800a9bec17SKonstantin Belousov #define AMDIOMMU_DSFX 0x0138 810a9bec17SKonstantin Belousov #define AMDIOMMU_DSCX 0x0140 820a9bec17SKonstantin Belousov #define AMDIOMMU_DSSX 0x0148 830a9bec17SKonstantin Belousov 840a9bec17SKonstantin Belousov #define AMDIOMMU_MSI_VEC0 0x0150 850a9bec17SKonstantin Belousov #define AMDIOMMU_MSI_VEC1 0x0154 860a9bec17SKonstantin Belousov #define AMDIOMMU_MSI_CAP_H 0x0158 870a9bec17SKonstantin Belousov #define AMDIOMMU_MSI_ADDR_LOW 0x015c 880a9bec17SKonstantin Belousov #define AMDIOMMU_MSI_ADDR_HIGH 0x0160 890a9bec17SKonstantin Belousov #define AMDIOMMU_MSI_DATA 0x0164 900a9bec17SKonstantin Belousov #define AMDIOMMU_MSI_MAPCAP 0x0168 910a9bec17SKonstantin Belousov 920a9bec17SKonstantin Belousov #define AMDIOMMU_PERFOPT 0x016c 930a9bec17SKonstantin Belousov 940a9bec17SKonstantin Belousov #define AMDIOMMU_x2APIC_CTRL 0x0170 950a9bec17SKonstantin Belousov #define AMDIOMMU_PPRI_CTRL 0x0178 960a9bec17SKonstantin Belousov #define AMDIOMMU_GALOGI_CTRL 0x0180 970a9bec17SKonstantin Belousov 980a9bec17SKonstantin Belousov #define AMDIOMMU_vIOMMU_STATUS 0x0190 990a9bec17SKonstantin Belousov 1000a9bec17SKonstantin Belousov #define AMDIOMMU_MARC0_BASE 0x0200 1010a9bec17SKonstantin Belousov #define AMDIOMMU_MARC0_RELOC 0x0208 1020a9bec17SKonstantin Belousov #define AMDIOMMU_MARC0_LEN 0x0210 1030a9bec17SKonstantin Belousov #define AMDIOMMU_MARC1_BASE 0x0218 1040a9bec17SKonstantin Belousov #define AMDIOMMU_MARC1_RELOC 0x0220 1050a9bec17SKonstantin Belousov #define AMDIOMMU_MARC1_LEN 0x0228 1060a9bec17SKonstantin Belousov #define AMDIOMMU_MARC2_BASE 0x0230 1070a9bec17SKonstantin Belousov #define AMDIOMMU_MARC2_RELOC 0x0238 1080a9bec17SKonstantin Belousov #define AMDIOMMU_MARC2_LEN 0x0240 1090a9bec17SKonstantin Belousov #define AMDIOMMU_MARC3_BASE 0x0248 1100a9bec17SKonstantin Belousov #define AMDIOMMU_MARC3_RELOC 0x0250 1110a9bec17SKonstantin Belousov #define AMDIOMMU_MARC3_LEN 0x0258 1120a9bec17SKonstantin Belousov 1130a9bec17SKonstantin Belousov #define AMDIOMMU_EFR2 0x01a0 1140a9bec17SKonstantin Belousov 1150a9bec17SKonstantin Belousov #define AMDIOMMU_CMDBUF_HEAD 0x2000 1160a9bec17SKonstantin Belousov #define AMDIOMMU_CMDBUF_TAIL 0x2008 1170a9bec17SKonstantin Belousov #define AMDIOMMU_EVNTLOG_HEAD 0x2010 1180a9bec17SKonstantin Belousov #define AMDIOMMU_EVNTLOG_TAIL 0x2018 1190a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEV_STATUS 0x2020 1200a9bec17SKonstantin Belousov #define AMDIOMMU_PPRLOG_HEAD 0x2030 1210a9bec17SKonstantin Belousov #define AMDIOMMU_PPRLOG_TAIL 0x2038 1220a9bec17SKonstantin Belousov #define AMDIOMMU_vAPICLOG_HEAD 0x2040 1230a9bec17SKonstantin Belousov #define AMDIOMMU_vAPICLOG_TAIL 0x2048 1240a9bec17SKonstantin Belousov #define AMDIOMMU_PPRLOGB_HEAD 0x2050 1250a9bec17SKonstantin Belousov #define AMDIOMMU_PPRLOGB_TAIL 0x2058 1260a9bec17SKonstantin Belousov #define AMDIOMMU_EVNTLOGB_HEAD 0x2070 1270a9bec17SKonstantin Belousov #define AMDIOMMU_EVNTLOGB_TAIL 0x2078 1280a9bec17SKonstantin Belousov #define AMDIOMMU_PPRLOG_AUR 0x2080 1290a9bec17SKonstantin Belousov #define AMDIOMMU_PPRLOG_EAI 0x2088 1300a9bec17SKonstantin Belousov #define AMDIOMMU_PPRLOGB_AUR 0x2090 1310a9bec17SKonstantin Belousov 1320a9bec17SKonstantin Belousov /* 1330a9bec17SKonstantin Belousov * IOMMU Control Register AMDIOMMU_CTRL fields 1340a9bec17SKonstantin Belousov */ 1350a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_EN 0x0000000000000001ull /* IOMMU En */ 1360a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_HTTUN_EN 0x0000000000000002ull /* HT Tun Trans En */ 1370a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_EVNTLOG_EN 0x0000000000000004ull /* Event Log En */ 1380a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_EVENTINT_EN 0x0000000000000008ull /* Event Log Intr En */ 1390a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_COMWINT_EN 0x0000000000000010ull /* Compl Wait Intr En */ 1400a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_INVTOUT_MASK 0x00000000000000e0ull /* IOTLB Inv Timeout*/ 1410a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_INVTOUT_NO 0x0000000000000000ull 1420a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_INVTOUT_1MS 0x0000000000000020ull 1430a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_INVTOUT_10MS 0x0000000000000040ull 1440a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_INVTOUT_100MS 0x0000000000000060ull 1450a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_INVTOUT_1S 0x0000000000000080ull 1460a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_INVTOUT_10S 0x00000000000000a0ull 1470a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_INVTOUT_100S 0x00000000000000b0ull 1480a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_INVTOUT_RSRV 0x00000000000000e0ull 1490a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_PASSPW 0x0000000000000100ull /* HT Pass Posted Wr */ 1500a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_REPASSPW 0x0000000000000200ull /* HT Resp Pass Posted Wr */ 1510a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_COHERENT 0x0000000000000400ull /* HT Coherent Reads */ 1520a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_ISOC 0x0000000000000800ull /* HT Isoc Reads */ 1530a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_CMDBUF_EN 0x0000000000001000ull /* Start CMD proc En */ 1540a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_PPRLOG_EN 0x0000000000002000ull /* Periph Page Req Log En */ 1550a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_PPRINT_EN 0x0000000000004000ull /* Periph Page Req Intr En */ 1560a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_PPR_EN 0x0000000000008000ull /* Periph Page Req En */ 1570a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_GT_EN 0x0000000000010000ull /* Guest En */ 1580a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_GA_EN 0x0000000000020000ull /* Guest vAPIC En */ 1590a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_SMIF_EN 0x0000000000400000ull /* SMI Filter En */ 1600a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_SLFWB_DIS 0x0000000000800000ull /* Self WriteBack Dis */ 1610a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_SMIFLOG_EN 0x0000000001000000ull /* SMI Filter Log En */ 1620a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_GAM_EN_MASK 0x000000000e000000ull /* Guest vAPIC Mode En */ 1630a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_GAM_EN_vAPIC_GM0 0x0000000000000000ull /* IRTE.GM = 0 */ 1640a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_GAM_EN_vAPIC_GM1 0x0000000002000000ull /* IRTE.GM = 1 */ 1650a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_GALOG_EN 0x0000000010000000ull /* Guest vAPIC GA Log En */ 1660a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_GAINT_EN 0x0000000020000000ull /* Guest vAPIC GA Intr En */ 1670a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_DUALPPRLOG_MASK 0x00000000c0000000ull /* Dual Periph Page Req Log En */ 1680a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_DUALPPRLOG_A 0x0000000000000000ull /* Use Log A */ 1690a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_DUALPPRLOG_B 0x0000000040000000ull /* Use Log B */ 1700a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_DUALPPRLOG_SWAP 0x0000000080000000ull /* Auto-swap on full */ 1710a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_DUALPPRLOG_RSRV 0x00000000c0000000ull 1720a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_DUALEVNTLOG_MASK 0x0000000300000000ull /* Dual Event Log En */ 1730a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_DUALEVNTLOG_A 0x0000000000000000ull /* Use Log A Buf */ 1740a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_DUALEVNTLOG_B 0x0000000100000000ull /* Use Log B Buf */ 1750a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_DUALEVNTLOG_SWAP 0x0000000200000000ull /* Auto-swap on full */ 1760a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_DUALEVNTLOG_RSRV 0x0000000300000000ull 1770a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_DEVTABSEG_MASK 0x0000001c00000000ull /* Dev Table Segm */ 1780a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_DEVTABSEG_1 0x0000000000000000ull /* 1 Segment */ 1790a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_DEVTABSEG_2 0x0000000400000000ull /* 2 Segments */ 1800a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_DEVTABSEG_4 0x0000000800000000ull /* 4 Segments */ 1810a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_DEVTABSEG_8 0x0000000c00000000ull /* 8 Segments */ 1820a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_PRIVABRT_MASK 0x0000006000000000ull /* Privilege Abort En */ 1830a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_PRIVABRT_USR 0x0000000000000000ull /* Privilege Abort User */ 1840a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_PRIVABRT_ALL 0x0000002000000000ull /* Privilege Abort Always */ 1850a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_PPRAUTORSP_EN 0x0000008000000000ull /* PPR Auto Resp En */ 1860a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_MARC_EN 0x0000010000000000ull /* Memory Addr Routing En */ 1870a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_BLKSTOPMRK_EN 0x0000020000000000ull /* Block StopMark En */ 1880a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_PPRAUTORESPA_EN 0x0000040000000000ull /* PPR Auto Resp Always En */ 18943fa7b90SKonstantin Belousov #define AMDIOMMU_CTRL_NUMINTRREMAP_MASK 0x0000180000000000ull /* Remapping MSI mode */ 19043fa7b90SKonstantin Belousov #define AMDIOMMU_CTRL_NUMINTRREMAP_512 0x0000000000000000ull /* 512 max */ 19143fa7b90SKonstantin Belousov #define AMDIOMMU_CTRL_NUMINTRREMAP_2048 0x0000080000000000ull /* 2048 max */ 1920a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_EPH_EN 0x0000200000000000ull /* Enh PPR Handling En */ 1930a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_HADUP_MASK 0x0000c00000000000ull /* Access and Dirty in host PT */ 1940a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_GDUP_DIS 0x0001000000000000ull /* Dis Dirty in guest PT */ 1950a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_XT_EN 0x0004000000000000ull /* x2APIC mode */ 1960a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_INTCAPXT_EN 0x0008000000000000ull /* x2APIC mode for IOMMU intrs */ 1970a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_vCMD_EN 0x0010000000000000ull /* vCMD buffer proc En */ 1980a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_vIOMMU_EN 0x0020000000000000ull /* vIOMMU En */ 1990a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_GAUP_DIS 0x0040000000000000ull /* Dis Access in guest PT */ 2000a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_GAPPI_EN 0x0080000000000000ull /* Guest APIC phys proc intr En */ 2010a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_TMPM_EN 0x0100000000000000ull /* Tiered Mem Page Migration En */ 2020a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_GGCR3TRP_PHYS 0x0400000000000000ull /* GCR3 is GPA (otherwise SPA) */ 2030a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_IRTCACHE_DIS 0x0800000000000000ull /* IRT Caching Dis */ 2040a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_GSTBUFTRP_MODE 0x1000000000000000ull /* See spec */ 2050a9bec17SKonstantin Belousov #define AMDIOMMU_CTRL_SNPAVIC_MASK 0xe000000000000000ull /* MBZ */ 2060a9bec17SKonstantin Belousov 2070a9bec17SKonstantin Belousov /* 2080a9bec17SKonstantin Belousov * IOMMU Extended Feature Register AMDIOMMU_EFR fields 2090a9bec17SKonstantin Belousov */ 2100a9bec17SKonstantin Belousov #define AMDIOMMU_EFR_XT_SUP 0x0000000000000004ull /* x2APIC */ 2110a9bec17SKonstantin Belousov #define AMDIOMMU_EFR_HWEV_SUP 0x0000000000000100ull /* HW Event regs */ 2120a9bec17SKonstantin Belousov #define AMDIOMMU_EFR_PC_SUP 0x0000000000000200ull /* Perf counters */ 2130a9bec17SKonstantin Belousov #define AMDIOMMU_EFR_HATS_MASK 0x0000000000000c00ull /* Host Addr Trans Size */ 2140a9bec17SKonstantin Belousov #define AMDIOMMU_EFR_HATS_4LVL 0x0000000000000000ull 2150a9bec17SKonstantin Belousov #define AMDIOMMU_EFR_HATS_5LVL 0x0000000000000400ull 2160a9bec17SKonstantin Belousov #define AMDIOMMU_EFR_HATS_6LVL 0x0000000000000800ull 2170a9bec17SKonstantin Belousov #define AMDIOMMU_EFR_DEVTBLSEG_MASK 0x000000c000000000ull /* DevTbl segmentation */ 2180a9bec17SKonstantin Belousov #define AMDIOMMU_EFR_DEVTBLSEG_SHIFT 38 2190a9bec17SKonstantin Belousov 2200a9bec17SKonstantin Belousov /* IOMMU Command Pointers (Head/Tail) registers fields */ 2210a9bec17SKonstantin Belousov #define AMDIOMMU_CMDPTR_MASK 0x000000000007fff0ull 2220a9bec17SKonstantin Belousov 2230a9bec17SKonstantin Belousov /* IOMMU Command Buffer Base fields */ 2240a9bec17SKonstantin Belousov #define AMDIOMMU_CMDBUF_BASE_SZSHIFT 56 /* Shift for size */ 2250a9bec17SKonstantin Belousov #define AMDIOMMU_CMDBUF_MAX (512 * 1024) 2260a9bec17SKonstantin Belousov 2270a9bec17SKonstantin Belousov /* IOMMU Event Log Base register fields */ 2280a9bec17SKonstantin Belousov #define AMDIOMMU_EVNTLOG_BASE_SZSHIFT 56 /* Shift for size */ 2290a9bec17SKonstantin Belousov #define AMDIOMMU_EVNTLOG_MIN 256 2300a9bec17SKonstantin Belousov #define AMDIOMMU_EVNTLOG_MAX 32768 2310a9bec17SKonstantin Belousov 2320a9bec17SKonstantin Belousov /* IOMMU Hardware Event Status register fields */ 2330a9bec17SKonstantin Belousov #define AMDIOMMU_HWEVS_HEV 0x00000001 /* HW Ev Valid */ 2340a9bec17SKonstantin Belousov #define AMDIOMMU_HWEVS_HEO 0x00000002 /* HW Ev Overfl */ 2350a9bec17SKonstantin Belousov 2360a9bec17SKonstantin Belousov /* 2370a9bec17SKonstantin Belousov * IOMMU Command and Event Status register fields. 2380a9bec17SKonstantin Belousov * From the spec, all defined bits are either RO or RW1C. As a consequence, 2390a9bec17SKonstantin Belousov * single bit can be safely written to the register to clean a specific 2400a9bec17SKonstantin Belousov * condition. 2410a9bec17SKonstantin Belousov */ 2420a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_EVOVRFLW 0x00000001 2430a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_EVLOGINT 0x00000002 2440a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_COMWAITINT 0x00000004 2450a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_EVLOGRUN 0x00000008 2460a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_CMDBUFRUN 0x00000010 2470a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_PPROVRFLW 0x00000020 2480a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_PPRINT 0x00000040 2490a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_PPRLOGRUN 0x00000080 2500a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_GALOGRUN 0x00000100 2510a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_GALOVRFLW 0x00000200 2520a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_GAINT 0x00000400 2530a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_PPROVRFLWB 0x00000800 2540a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_PPRLOGACTIVE 0x00001000 2550a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_RESV1 0x00002000 2560a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_RESV2 0x00004000 2570a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_EVOVRFLWB 0x00008000 2580a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_EVLOGACTIVE 0x00010000 2590a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_PPROVRFLWEB 0x00020000 2600a9bec17SKonstantin Belousov #define AMDIOMMU_CMDEVS_PPROVRFLWE 0x00040000 2610a9bec17SKonstantin Belousov 2620a9bec17SKonstantin Belousov /* 26343fa7b90SKonstantin Belousov * IOMMU Extended Feature2 register fields. 26443fa7b90SKonstantin Belousov * All currently defined bits are RO. 26543fa7b90SKonstantin Belousov */ 266*bb9c3f51SKonstantin Belousov #define AMDIOMMU_EFR2_TMPMSUP 0x0000000000000004ull /* Tiered Mem Migration */ 26743fa7b90SKonstantin Belousov #define AMDIOMMU_EFR2_GCR3TRPM 0x0000000000000008ull /* GPA based GCR3 pointer in DTE */ 26843fa7b90SKonstantin Belousov #define AMDIOMMU_EFR2_GAPPID 0x0000000000000010ull /* masking of GAPIC PPI */ 26943fa7b90SKonstantin Belousov #define AMDIOMMU_EFR2_SNPAVIC_MASK 0x00000000000000e0ull /* SNP-enabled Adv intr features */ 27043fa7b90SKonstantin Belousov #define AMDIOMMU_EFR2_SNPAVIC_NO 0x0000000000000000ull /* No features supported */ 27143fa7b90SKonstantin Belousov #define AMDIOMMU_EFR2_SNPAVIC_REMAPV 0x0000000000000020ull /* Intr remapping with GVAPIC */ 27243fa7b90SKonstantin Belousov #define AMDIOMMU_EFR2_NUMINTRREMAP_MASK 0x0000000000000300ull /* Number of remapped intr per dev */ 27343fa7b90SKonstantin Belousov #define AMDIOMMU_EFR2_NUMINTRREMAP_512 0x0000000000000000ull /* 512 */ 27443fa7b90SKonstantin Belousov #define AMDIOMMU_EFR2_NUMINTRREMAP_2048 0x0000000000000100ull /* 2048 */ 27543fa7b90SKonstantin Belousov #define AMDIOMMU_EFR2_HTRANGEIGN 0x0000000000000800ull /* HT range is regular GPA */ 27643fa7b90SKonstantin Belousov 27743fa7b90SKonstantin Belousov /* 2780a9bec17SKonstantin Belousov * Device Table Entry (DTE) 2790a9bec17SKonstantin Belousov */ 2800a9bec17SKonstantin Belousov struct amdiommu_dte { 2810a9bec17SKonstantin Belousov u_int v:1; /* Valid */ 2820a9bec17SKonstantin Belousov u_int tv:1; /* Translation Valid */ 2830a9bec17SKonstantin Belousov u_int rsrv0:5; 2840a9bec17SKonstantin Belousov u_int had:2; /* Host Access Dirty */ 2850a9bec17SKonstantin Belousov u_int pgmode:3; /* Paging Mode */ 2860a9bec17SKonstantin Belousov uint64_t ptroot:40; /* Page Table Root */ 2870a9bec17SKonstantin Belousov u_int ppr:1; /* PPR En */ 2880a9bec17SKonstantin Belousov u_int gprp:1; /* Guest PPR Resp with PASID */ 2890a9bec17SKonstantin Belousov u_int giov:1; /* Guest IO Prot Valid */ 2900a9bec17SKonstantin Belousov u_int gv:1; /* Guest Translation Valid */ 2910a9bec17SKonstantin Belousov u_int glx:2; /* Guest Levels Translated */ 2920a9bec17SKonstantin Belousov u_int gcr3root0:3; /* GCR3 root pointer part */ 2930a9bec17SKonstantin Belousov u_int ir:1; /* Read Perm */ 2940a9bec17SKonstantin Belousov u_int iw:1; /* Write Perm */ 2950a9bec17SKonstantin Belousov u_int rsrv1:1; 2960a9bec17SKonstantin Belousov u_int domainid:16; /* domain tag */ 2970a9bec17SKonstantin Belousov u_int gcr3root1:16; /* GCR3 root pointer part */ 2980a9bec17SKonstantin Belousov u_int i:1; /* IOTLB En */ 2990a9bec17SKonstantin Belousov u_int se:1; /* Suppress IO Fault Events */ 3000a9bec17SKonstantin Belousov u_int sa:1; /* Suppress All IO Fault Events */ 3010a9bec17SKonstantin Belousov u_int pioctl:2; /* Port IO Control */ 3020a9bec17SKonstantin Belousov u_int cache:1; /* IOTLB Cache Hint */ 3030a9bec17SKonstantin Belousov u_int sd:1; /* Snoop Disable */ 3040a9bec17SKonstantin Belousov u_int ex:1; /* Allow Exclusion */ 3050a9bec17SKonstantin Belousov u_int sysmgt:2; /* System Management Msg Handling */ 3060a9bec17SKonstantin Belousov u_int sats:1; /* Secure/Non-secure ATS */ 3070a9bec17SKonstantin Belousov u_int gcr3root2:21; /* GCR3 root pointer part */ 3080a9bec17SKonstantin Belousov u_int iv:1; /* Intr Map Valid */ 3090a9bec17SKonstantin Belousov u_int inttablen:4; /* log2 Intr Table Len */ 3100a9bec17SKonstantin Belousov u_int ig:1; /* Ignore Unmapped Interrupts */ 3110a9bec17SKonstantin Belousov uint64_t intrroot:46; /* Interrupt Table Root (-low 6bits) */ 3120a9bec17SKonstantin Belousov u_int rsrv2:2; 3130a9bec17SKonstantin Belousov u_int gpm:2; /* Guest Paging Mode */ 3140a9bec17SKonstantin Belousov u_int initpass:1; /* INIT pass-through */ 3150a9bec17SKonstantin Belousov u_int eintpass:1; /* ExtInt pass-through */ 3160a9bec17SKonstantin Belousov u_int nmipass:1; /* NMI pass-through */ 3170a9bec17SKonstantin Belousov u_int hptmode:1; /* Host Page Table Mode Hint */ 3180a9bec17SKonstantin Belousov u_int intctl:2; /* Interrupt Control */ 3190a9bec17SKonstantin Belousov u_int lint0pass:1; /* LINT0 pass-through */ 3200a9bec17SKonstantin Belousov u_int lint1pass:1; /* LINT1 pass-through */ 3210a9bec17SKonstantin Belousov u_int rsrv3:15; 3220a9bec17SKonstantin Belousov u_int vimu:1; /* Virtualize IOMMU En */ 3230a9bec17SKonstantin Belousov u_int gdevid:16; /* Guest Dev Id */ 3240a9bec17SKonstantin Belousov u_int gid:16; /* Guest Id */ 3250a9bec17SKonstantin Belousov u_int rsrv4:5; 3260a9bec17SKonstantin Belousov u_int rsrv5:1; /* Not Checked, sw avail */ 3270a9bec17SKonstantin Belousov u_int attrv:1; /* Attr Override Valid */ 3280a9bec17SKonstantin Belousov u_int mode0fc:1; /* Replace for PTE.FC */ 3290a9bec17SKonstantin Belousov u_int snoopattr:8; /* GuestPTE.PAT -> ATS.N xlat */ 3300a9bec17SKonstantin Belousov } __packed; 3310a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_dte) == 8 * sizeof(uint32_t), "DTE"); 3320a9bec17SKonstantin Belousov 3330a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_HAD_NAND 0x0 /* No Access, No Dirty */ 3340a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_HAD_AND 0x1 /* Access, No Dirty */ 3350a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_HAD_RSRV 0x2 3360a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_HAD_AD 0x3 /* Access, Dirty */ 3370a9bec17SKonstantin Belousov 3380a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_PGMODE_1T1 0x0 /* SPA = GPA */ 3390a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_PGMODE_1LV 0x1 /* 1 Level PT */ 3400a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_PGMODE_2LV 0x2 /* 2 Level PT */ 3410a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_PGMODE_3LV 0x3 /* 3 Level PT */ 3420a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_PGMODE_4LV 0x4 /* 4 Level PT */ 3430a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_PGMODE_5LV 0x5 /* 5 Level PT */ 3440a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_PGMODE_6LV 0x6 /* 6 Level PT */ 3450a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_PGMODE_RSRV 0x7 3460a9bec17SKonstantin Belousov 3470a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_GLX_1LV 0x0 /* 1 Level GCR3 */ 3480a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_GLX_2LV 0x1 /* 2 Level GCR3 */ 3490a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_GLX_3LV 0x2 /* 3 Level GCR3 */ 3500a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_GLX_RSRV 0x3 3510a9bec17SKonstantin Belousov 3520a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_PIOCTL_DIS 0x0 3530a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_PIOCTL_EN 0x1 3540a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_PIOCTL_MAP 0x2 3550a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_PIOCTL_RSRV 0x3 3560a9bec17SKonstantin Belousov 3570a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_SYSMGT_DIS 0x0 /* Target Abort */ 3580a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_SYSMGT_FW 0x0 /* Forwarded All */ 3590a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_SYSMGT_FWI 0x0 /* Forwarded INT */ 3600a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_SYSMGT_T 0x0 /* Translated */ 3610a9bec17SKonstantin Belousov 3620a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_GPM_4LV 0x0 /* 4 Level */ 36357aebec4SKonstantin Belousov #define AMDIOMMU_DTE_GPM_5LV 0x1 /* 5 Level */ 3640a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_GPM_RSRV1 0x2 3650a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_GPM_RSRV2 0x3 3660a9bec17SKonstantin Belousov 3670a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_INTCTL_DIS 0x0 /* Target Abort */ 3680a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_INTCTL_FW 0x1 /* Forward Unmapped */ 3690a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_INTCTL_MAP 0x2 /* Forward Remapped */ 3700a9bec17SKonstantin Belousov #define AMDIOMMU_DTE_INTCTL_RSRV 0x3 3710a9bec17SKonstantin Belousov 3720a9bec17SKonstantin Belousov #define AMDIOMMU_PGTBL_MAXLVL 6 3730a9bec17SKonstantin Belousov 3740a9bec17SKonstantin Belousov /* 3750a9bec17SKonstantin Belousov * Page Table Entry (PTE/PDE) 3760a9bec17SKonstantin Belousov */ 3770a9bec17SKonstantin Belousov #define AMDIOMMU_PTE_PR 0x0001 /* Present, AKA V */ 3780a9bec17SKonstantin Belousov #define AMDIOMMU_IGN1 0x0002 3790a9bec17SKonstantin Belousov #define AMDIOMMU_IGN2 0x0004 3800a9bec17SKonstantin Belousov #define AMDIOMMU_IGN3 0x0008 3810a9bec17SKonstantin Belousov #define AMDIOMMU_IGN4 0x0010 3820a9bec17SKonstantin Belousov #define AMDIOMMU_PTE_A 0x0020 /* Accessed */ 3830a9bec17SKonstantin Belousov #define AMDIOMMU_PTE_D 0x0040 /* Dirty */ 3840a9bec17SKonstantin Belousov #define AMDIOMMU_IGN5 0x0080 3850a9bec17SKonstantin Belousov #define AMDIOMMU_IGN6 0x0100 3860a9bec17SKonstantin Belousov #define AMDIOMMU_PTE_NLVL_MASK 0x0e00 /* Next Level */ 3870a9bec17SKonstantin Belousov #define AMDIOMMU_PTE_NLVL_SHIFT 9 3880a9bec17SKonstantin Belousov #define AMDIOMMU_PTE_NLVL_7h 0x0e00 /* Magic Next Level */ 3890a9bec17SKonstantin Belousov #define AMDIOMMU_PTE_PA_MASK 0x000ffffffffff000ull 3900a9bec17SKonstantin Belousov #define AMDIOMMU_PTE_PA_SHIFT 12 3910a9bec17SKonstantin Belousov #define AMDIOMMU_PTE_PMC_MASK 0x0600000000000000ull /* Page Migr */ 3920a9bec17SKonstantin Belousov #define AMDIOMMU_PTE_U 0x0800000000000000ull /* ATS.U */ 3930a9bec17SKonstantin Belousov #define AMDIOMMU_PTE_FC 0x1000000000000000ull /* Force Coh */ 3940a9bec17SKonstantin Belousov #define AMDIOMMU_PTE_IR 0x2000000000000000ull /* Read Perm */ 3950a9bec17SKonstantin Belousov #define AMDIOMMU_PTE_IW 0x4000000000000000ull /* Write Perm */ 3960a9bec17SKonstantin Belousov #define AMDIOMMU_PTE_IGN7 0x8000000000000000ull 3970a9bec17SKonstantin Belousov 3980a9bec17SKonstantin Belousov /* 3990a9bec17SKonstantin Belousov * IRTEs 4000a9bec17SKonstantin Belousov */ 4010a9bec17SKonstantin Belousov 4020a9bec17SKonstantin Belousov /* vAPIC is not enabled, guestmode = 0 */ 4030a9bec17SKonstantin Belousov struct amdiommu_irte_basic_novapic { 4040a9bec17SKonstantin Belousov u_int remapen:1; /* 0 - Target Abort */ 4050a9bec17SKonstantin Belousov u_int supiopf:1; /* Supress IO_PAGE_FAULT events */ 4060a9bec17SKonstantin Belousov u_int inttype:3; 4070a9bec17SKonstantin Belousov u_int rqeoi:1; /* Request EOI */ 4080a9bec17SKonstantin Belousov u_int dm:1; /* Dest Mode */ 4090a9bec17SKonstantin Belousov u_int guestmode:1; /* MBZ */ 4100a9bec17SKonstantin Belousov u_int dest:8; /* Destination APIC */ 4110a9bec17SKonstantin Belousov u_int vector:8; 4120a9bec17SKonstantin Belousov u_int rsrv:8; 4130a9bec17SKonstantin Belousov } __packed; 4140a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_irte_basic_novapic) == 4150a9bec17SKonstantin Belousov 1 * sizeof(uint32_t), "IRTE 1"); 4160a9bec17SKonstantin Belousov 4170a9bec17SKonstantin Belousov /* vAPIC is enabled, guestmode = 0 */ 4180a9bec17SKonstantin Belousov struct amdiommu_irte_basic_vapic { 4190a9bec17SKonstantin Belousov u_int remapen:1; /* 0 - Target Abort */ 4200a9bec17SKonstantin Belousov u_int supiopf:1; /* Supress IO_PAGE_FAULT events */ 4210a9bec17SKonstantin Belousov u_int inttype:3; 4220a9bec17SKonstantin Belousov u_int rqeoi:1; /* Request EOI */ 4230a9bec17SKonstantin Belousov u_int dm:1; /* Dest Mode */ 4240a9bec17SKonstantin Belousov u_int guestmode:1; /* MBZ */ 4250a9bec17SKonstantin Belousov u_int dest:8; /* Destination APIC */ 4260a9bec17SKonstantin Belousov u_int rsrv0:16; 4270a9bec17SKonstantin Belousov u_int rsrv1:32; 4280a9bec17SKonstantin Belousov u_int vector:8; 4290a9bec17SKonstantin Belousov u_int rsrv2:24; 4300a9bec17SKonstantin Belousov u_int rsrv3:32; 4310a9bec17SKonstantin Belousov } __packed; 4320a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_irte_basic_vapic) == 4330a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "IRTE 2"); 4340a9bec17SKonstantin Belousov 4350a9bec17SKonstantin Belousov /* vAPIC is enabled, guestmode = 1 */ 4360a9bec17SKonstantin Belousov struct amdiommu_irte_guest_vapic { 4370a9bec17SKonstantin Belousov u_int remapen:1; /* 0 - Target Abort */ 4380a9bec17SKonstantin Belousov u_int supiopf:1; /* Supress IO_PAGE_FAULT events */ 4390a9bec17SKonstantin Belousov u_int galogintr:1; 4400a9bec17SKonstantin Belousov u_int rsrv0:2; 4410a9bec17SKonstantin Belousov u_int gappidis:1; /* supress GAPPI */ 4420a9bec17SKonstantin Belousov u_int isrun:1; /* Guest Running hint */ 4430a9bec17SKonstantin Belousov u_int guestmode:1; /* MB1 */ 4440a9bec17SKonstantin Belousov u_int dest:8; /* Destination APIC for dorbell */ 4450a9bec17SKonstantin Belousov u_int rsrv1:16; 4460a9bec17SKonstantin Belousov u_int gatag:32; 4470a9bec17SKonstantin Belousov u_int vector:8; 4480a9bec17SKonstantin Belousov u_int rsrv2:4; 4490a9bec17SKonstantin Belousov uint64_t vapicrp:40; /* 51:12 bits of SPA for APIC backing page */ 4500a9bec17SKonstantin Belousov u_int rsrv3:12; 4510a9bec17SKonstantin Belousov } __packed; 4520a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_irte_guest_vapic) == 4530a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "IRTE 3"); 4540a9bec17SKonstantin Belousov 4550a9bec17SKonstantin Belousov /* vAPIC is enabled, guestmode = 0, x2APIC */ 4560a9bec17SKonstantin Belousov struct amdiommu_irte_basic_vapic_x2 { 4570a9bec17SKonstantin Belousov u_int remapen:1; /* 0 - Target Abort */ 4580a9bec17SKonstantin Belousov u_int supiopf:1; /* Supress IO_PAGE_FAULT events */ 4590a9bec17SKonstantin Belousov u_int inttype:3; 4600a9bec17SKonstantin Belousov u_int rqeoi:1; /* Request EOI */ 4610a9bec17SKonstantin Belousov u_int dm:1; /* Dest Mode */ 4620a9bec17SKonstantin Belousov u_int guestmode:1; /* MBZ */ 4630a9bec17SKonstantin Belousov u_int dest0:24; /* Destination APIC 23:0 */ 4640a9bec17SKonstantin Belousov u_int rsrv0:32; 4650a9bec17SKonstantin Belousov u_int vector:8; 4660a9bec17SKonstantin Belousov u_int rsrv1:24; 4670a9bec17SKonstantin Belousov u_int rsrv2:24; 4680a9bec17SKonstantin Belousov u_int dest1:8; /* Destination APIC 31:24 */ 4690a9bec17SKonstantin Belousov } __packed; 4700a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_irte_basic_vapic_x2) == 4710a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "IRTE 4"); 4720a9bec17SKonstantin Belousov 4730a9bec17SKonstantin Belousov /* vAPIC is enabled, guestmode = 1, x2APIC */ 4740a9bec17SKonstantin Belousov struct amdiommu_irte_guest_vapic_x2 { 4750a9bec17SKonstantin Belousov u_int remapen:1; /* 0 - Target Abort */ 4760a9bec17SKonstantin Belousov u_int supiopf:1; /* Supress IO_PAGE_FAULT events */ 4770a9bec17SKonstantin Belousov u_int galogintr:1; 4780a9bec17SKonstantin Belousov u_int rsrv0:2; 4790a9bec17SKonstantin Belousov u_int gappidis:1; /* supress GAPPI */ 4800a9bec17SKonstantin Belousov u_int isrun:1; /* Guest Running hint */ 4810a9bec17SKonstantin Belousov u_int guestmode:1; /* MB1 */ 4820a9bec17SKonstantin Belousov u_int dest0:24; /* Destination APIC for dorbell 23:0 */ 4830a9bec17SKonstantin Belousov u_int gatag:32; 4840a9bec17SKonstantin Belousov u_int vector:8; 4850a9bec17SKonstantin Belousov u_int rsrv2:4; 4860a9bec17SKonstantin Belousov uint64_t vapicrp:40; /* 51:12 bits of SPA for APIC backing page */ 4870a9bec17SKonstantin Belousov u_int rsrv3:4; 4880a9bec17SKonstantin Belousov u_int dest1:8; /* Destination APIC 31:24 */ 4890a9bec17SKonstantin Belousov } __packed; 4900a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_irte_guest_vapic_x2) == 4910a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "IRTE 5"); 4920a9bec17SKonstantin Belousov 4930a9bec17SKonstantin Belousov #define AMDIOMMU_IRTE_INTTYPE_FIXED 0 4940a9bec17SKonstantin Belousov #define AMDIOMMU_IRTE_INTTYPE_ARBITR 1 4950a9bec17SKonstantin Belousov 4960a9bec17SKonstantin Belousov #define AMDIOMMU_IRTE_DM_LOGICAL 1 4970a9bec17SKonstantin Belousov #define AMDIOMMU_IRTE_DM_PHYSICAL 1 4980a9bec17SKonstantin Belousov 4990a9bec17SKonstantin Belousov /* 5000a9bec17SKonstantin Belousov * Commands 5010a9bec17SKonstantin Belousov */ 5020a9bec17SKonstantin Belousov 5030a9bec17SKonstantin Belousov struct amdiommu_cmd_generic { 5040a9bec17SKonstantin Belousov u_int w0:32; 5050a9bec17SKonstantin Belousov union { 5060a9bec17SKonstantin Belousov u_int ww1:32; 5070a9bec17SKonstantin Belousov struct { 5080a9bec17SKonstantin Belousov u_int w1:28; 5090a9bec17SKonstantin Belousov u_int op:4; 5100a9bec17SKonstantin Belousov }; 5110a9bec17SKonstantin Belousov }; 5120a9bec17SKonstantin Belousov u_int w2:32; 5130a9bec17SKonstantin Belousov u_int w3:32; 5140a9bec17SKonstantin Belousov } __packed; 5150a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_cmd_generic) == 5160a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "CMD_GENERIC"); 5170a9bec17SKonstantin Belousov 5180a9bec17SKonstantin Belousov #define AMDIOMMU_CMD_SZ_SHIFT 4 /* Shift for cmd count 5190a9bec17SKonstantin Belousov to ring offset */ 5200a9bec17SKonstantin Belousov #define AMDIOMMU_CMD_SZ sizeof(struct amdiommu_cmd_generic) 5210a9bec17SKonstantin Belousov /* Command size */ 5220a9bec17SKonstantin Belousov _Static_assert((1 << AMDIOMMU_CMD_SZ_SHIFT) == AMDIOMMU_CMD_SZ, 5230a9bec17SKonstantin Belousov "CMD size shift"); 5240a9bec17SKonstantin Belousov 5250a9bec17SKonstantin Belousov struct amdiommu_cmd_completion_wait { 5260a9bec17SKonstantin Belousov u_int s:1; 5270a9bec17SKonstantin Belousov u_int i:1; 5280a9bec17SKonstantin Belousov u_int f:1; 5290a9bec17SKonstantin Belousov u_int address0:29; /* Store Address 31:3 */ 5300a9bec17SKonstantin Belousov u_int address1:20; /* Store Address 51:32 */ 5310a9bec17SKonstantin Belousov u_int rsrv:8; 5320a9bec17SKonstantin Belousov u_int op:4; 5330a9bec17SKonstantin Belousov u_int data0:32; 5340a9bec17SKonstantin Belousov u_int data1:32; 5350a9bec17SKonstantin Belousov } __packed; 5360a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_cmd_completion_wait) == 5370a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "CMD_COMPLETION_WAIT"); 5380a9bec17SKonstantin Belousov 5390a9bec17SKonstantin Belousov struct amdiommu_cmd_invalidate_devtab_entry { 5400a9bec17SKonstantin Belousov u_int devid:16; 5410a9bec17SKonstantin Belousov u_int rsrv0:16; 5420a9bec17SKonstantin Belousov u_int rsrv1:28; 5430a9bec17SKonstantin Belousov u_int op:4; 5440a9bec17SKonstantin Belousov u_int rsrv2:32; 5450a9bec17SKonstantin Belousov u_int rsrv3:32; 5460a9bec17SKonstantin Belousov } __packed; 5470a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_cmd_invalidate_devtab_entry) == 5480a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "CMD_INVALIDATE_DEVTAB_ENTRY"); 5490a9bec17SKonstantin Belousov 5500a9bec17SKonstantin Belousov struct amdiommu_cmd_invalidate_iommu_pages { 5510a9bec17SKonstantin Belousov u_int pasid:20; 5520a9bec17SKonstantin Belousov u_int rsrv0:12; 5530a9bec17SKonstantin Belousov u_int domainid:16; 5540a9bec17SKonstantin Belousov u_int rsrv1:12; 5550a9bec17SKonstantin Belousov u_int op:4; 5560a9bec17SKonstantin Belousov u_int s:1; 5570a9bec17SKonstantin Belousov u_int pde:1; 5580a9bec17SKonstantin Belousov u_int gn:1; 5590a9bec17SKonstantin Belousov u_int rsrv2:9; 5600a9bec17SKonstantin Belousov uint64_t address:52; /* Address 63:12 */ 5610a9bec17SKonstantin Belousov } __packed; 5620a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_cmd_invalidate_iommu_pages) == 5630a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "CMD_INVALIDATE_IOMMU_PAGES"); 5640a9bec17SKonstantin Belousov 5650a9bec17SKonstantin Belousov struct amdiommu_cmd_invalidate_iotlb_pages { 5660a9bec17SKonstantin Belousov u_int devid:16; 5670a9bec17SKonstantin Belousov u_int pasid1:8; 5680a9bec17SKonstantin Belousov u_int maxpend0:8; 5690a9bec17SKonstantin Belousov u_int queueid:16; 5700a9bec17SKonstantin Belousov u_int pasid0:8; 5710a9bec17SKonstantin Belousov u_int pasid2:4; 5720a9bec17SKonstantin Belousov u_int op:4; 5730a9bec17SKonstantin Belousov u_int s:1; 5740a9bec17SKonstantin Belousov u_int rsrv0:1; 5750a9bec17SKonstantin Belousov u_int gn:1; 5760a9bec17SKonstantin Belousov u_int rsrv1:1; 5770a9bec17SKonstantin Belousov u_int type:2; 5780a9bec17SKonstantin Belousov u_int rsrv2:6; 5790a9bec17SKonstantin Belousov uint64_t address:52; /* Address 63:12 */ 5800a9bec17SKonstantin Belousov } __packed; 5810a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_cmd_invalidate_iotlb_pages) == 5820a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "CMD_INVALIDATE_IOTLB_PAGES"); 5830a9bec17SKonstantin Belousov 5840a9bec17SKonstantin Belousov struct amdiommu_cmd_invalidate_interrupt_table { 5850a9bec17SKonstantin Belousov u_int devid:16; 5860a9bec17SKonstantin Belousov u_int rsrv0:16; 5870a9bec17SKonstantin Belousov u_int rsrv1:28; 5880a9bec17SKonstantin Belousov u_int op:4; 5890a9bec17SKonstantin Belousov u_int rsrv2:32; 5900a9bec17SKonstantin Belousov u_int rsrv3:32; 5910a9bec17SKonstantin Belousov } __packed; 5920a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_cmd_invalidate_interrupt_table) == 5930a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "CMD_INVALIDATE_INTERRUPT_TABLE"); 5940a9bec17SKonstantin Belousov 5950a9bec17SKonstantin Belousov struct amdiommu_cmd_prefetch_iommu_pages { 5960a9bec17SKonstantin Belousov u_int devid:16; 5970a9bec17SKonstantin Belousov u_int rsrv0:8; 5980a9bec17SKonstantin Belousov u_int pfcount:8; 5990a9bec17SKonstantin Belousov u_int pasid:20; 6000a9bec17SKonstantin Belousov u_int rsrv1:8; 6010a9bec17SKonstantin Belousov u_int op:4; 6020a9bec17SKonstantin Belousov u_int s:1; 6030a9bec17SKonstantin Belousov u_int rsrv2:1; 6040a9bec17SKonstantin Belousov u_int gn:1; 6050a9bec17SKonstantin Belousov u_int rsrv3:1; 6060a9bec17SKonstantin Belousov u_int inval:1; /* Invalidate First */ 6070a9bec17SKonstantin Belousov u_int rsrv4:7; 6080a9bec17SKonstantin Belousov uint64_t address:52; /* Address 63:12 */ 6090a9bec17SKonstantin Belousov } __packed; 6100a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_cmd_prefetch_iommu_pages) == 6110a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "CMD_PREFETCH_IOMMU_PAGES"); 6120a9bec17SKonstantin Belousov 6130a9bec17SKonstantin Belousov struct amdiommu_cmd_complete_ppr_request { 6140a9bec17SKonstantin Belousov u_int devid:16; 6150a9bec17SKonstantin Belousov u_int rsrv0:16; 6160a9bec17SKonstantin Belousov u_int pasid:20; 6170a9bec17SKonstantin Belousov u_int rsrv1:8; 6180a9bec17SKonstantin Belousov u_int op:4; 6190a9bec17SKonstantin Belousov u_int rsrv2:2; 6200a9bec17SKonstantin Belousov u_int gn:1; 6210a9bec17SKonstantin Belousov u_int rsrv3:29; 6220a9bec17SKonstantin Belousov u_int compltag:16; 6230a9bec17SKonstantin Belousov u_int rsrv4:16; 6240a9bec17SKonstantin Belousov } __packed; 6250a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_cmd_complete_ppr_request) == 6260a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "CMD_COMPLETE_PPR_REQUEST"); 6270a9bec17SKonstantin Belousov 6280a9bec17SKonstantin Belousov struct amdiommu_cmd_invalidate_iommu_all { 6290a9bec17SKonstantin Belousov u_int rsrv0:32; 6300a9bec17SKonstantin Belousov u_int op:4; 6310a9bec17SKonstantin Belousov u_int rsrv1:28; 6320a9bec17SKonstantin Belousov u_int rsrv2:32; 6330a9bec17SKonstantin Belousov u_int rsrv3:32; 6340a9bec17SKonstantin Belousov } __packed; 6350a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_cmd_invalidate_iommu_all) == 6360a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "CMD_INVALIDATE_IOMMU_ALL"); 6370a9bec17SKonstantin Belousov 6380a9bec17SKonstantin Belousov struct amdiommu_cmd_insert_guest_event { 6390a9bec17SKonstantin Belousov u_int rsrv0:32; 6400a9bec17SKonstantin Belousov u_int guestid:16; 6410a9bec17SKonstantin Belousov u_int rsrv1:12; 6420a9bec17SKonstantin Belousov u_int op:4; 6430a9bec17SKonstantin Belousov u_int rsrv2:32; 6440a9bec17SKonstantin Belousov u_int rsrv3:32; 6450a9bec17SKonstantin Belousov } __packed; 6460a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_cmd_insert_guest_event) == 6470a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "CMD_INSERT_GUEST_EVENT"); 6480a9bec17SKonstantin Belousov 6490a9bec17SKonstantin Belousov struct amdiommu_cmd_reset_vmmio { 6500a9bec17SKonstantin Belousov u_int guestid:16; 6510a9bec17SKonstantin Belousov u_int rsrv0:11; 6520a9bec17SKonstantin Belousov u_int all:1; 6530a9bec17SKonstantin Belousov u_int rsrv1:3; 6540a9bec17SKonstantin Belousov u_int vcmd:1; 6550a9bec17SKonstantin Belousov u_int rsrv2:27; 6560a9bec17SKonstantin Belousov u_int op:4; 6570a9bec17SKonstantin Belousov u_int rsrv3:32; 6580a9bec17SKonstantin Belousov u_int rsrv4:32; 6590a9bec17SKonstantin Belousov } __packed; 6600a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_cmd_reset_vmmio) == 6610a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "CMD_RESET_VMMIO"); 6620a9bec17SKonstantin Belousov 6630a9bec17SKonstantin Belousov #define AMDIOMMU_CMD_COMPLETION_WAIT 0x1 6640a9bec17SKonstantin Belousov #define AMDIOMMU_CMD_INVALIDATE_DEVTAB_ENTRY 0x2 6650a9bec17SKonstantin Belousov #define AMDIOMMU_CMD_INVALIDATE_IOMMU_PAGES 0x3 6660a9bec17SKonstantin Belousov #define AMDIOMMU_CMD_INVALIDATE_IOTLB_PAGES 0x4 6670a9bec17SKonstantin Belousov #define AMDIOMMU_CMD_INVALIDATE_INTERRUPT_TABLE 0x5 6680a9bec17SKonstantin Belousov #define AMDIOMMU_CMD_PREFETCH_IOMMU_PAGES 0x6 6690a9bec17SKonstantin Belousov #define AMDIOMMU_CMD_COMPLETE_PPR_REQUEST 0x7 6700a9bec17SKonstantin Belousov #define AMDIOMMU_CMD_INVALIDATE_IOMMU_ALL 0x8 6710a9bec17SKonstantin Belousov #define AMDIOMMU_CMD_INSERT_GUEST_EVENT 0x9 6720a9bec17SKonstantin Belousov #define AMDIOMMU_CMD_RESET_VMMIO 0xa 6730a9bec17SKonstantin Belousov 6740a9bec17SKonstantin Belousov /* 6750a9bec17SKonstantin Belousov * Logging 6760a9bec17SKonstantin Belousov */ 6770a9bec17SKonstantin Belousov struct amdiommu_event_generic { 6780a9bec17SKonstantin Belousov u_int w0:32; 6790a9bec17SKonstantin Belousov union { 6800a9bec17SKonstantin Belousov u_int ww1:32; 6810a9bec17SKonstantin Belousov struct { 6820a9bec17SKonstantin Belousov u_int w1:28; 6830a9bec17SKonstantin Belousov u_int code:4; 6840a9bec17SKonstantin Belousov }; 6850a9bec17SKonstantin Belousov }; 6860a9bec17SKonstantin Belousov u_int w2:32; 6870a9bec17SKonstantin Belousov u_int w3:32; 6880a9bec17SKonstantin Belousov } __packed; 6890a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_event_generic) == 6900a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "EVENT_GENERIC"); 6910a9bec17SKonstantin Belousov 6920a9bec17SKonstantin Belousov #define AMDIOMMU_EV_SZ_SHIFT 4 /* Shift for event count 6930a9bec17SKonstantin Belousov to ring offset */ 6940a9bec17SKonstantin Belousov #define AMDIOMMU_EV_SZ sizeof(struct amdiommu_event_generic) 6950a9bec17SKonstantin Belousov /* Event size */ 6960a9bec17SKonstantin Belousov _Static_assert((1 << AMDIOMMU_EV_SZ_SHIFT) == AMDIOMMU_EV_SZ, 6970a9bec17SKonstantin Belousov "Event size shift"); 6980a9bec17SKonstantin Belousov 6990a9bec17SKonstantin Belousov struct amdiommu_event_ill_dev_table_entry { 7000a9bec17SKonstantin Belousov u_int devid:16; 7010a9bec17SKonstantin Belousov u_int pasid1:4; 7020a9bec17SKonstantin Belousov u_int rsrv0:7; 7030a9bec17SKonstantin Belousov u_int vnr:1; 7040a9bec17SKonstantin Belousov u_int rsrv1:1; 7050a9bec17SKonstantin Belousov u_int vevent:1; 7060a9bec17SKonstantin Belousov u_int vptr:1; 7070a9bec17SKonstantin Belousov u_int vcmd:1; 7080a9bec17SKonstantin Belousov u_int pasid:16; 7090a9bec17SKonstantin Belousov u_int gn:1; 7100a9bec17SKonstantin Belousov u_int rsrv2:2; 7110a9bec17SKonstantin Belousov u_int i:1; 7120a9bec17SKonstantin Belousov u_int rsrv3:1; 7130a9bec17SKonstantin Belousov u_int rw:1; 7140a9bec17SKonstantin Belousov u_int rsrv4:1; 7150a9bec17SKonstantin Belousov u_int rz:1; 7160a9bec17SKonstantin Belousov u_int tr:1; 7170a9bec17SKonstantin Belousov u_int rsrv5:3; 7180a9bec17SKonstantin Belousov u_int code:4; 7190a9bec17SKonstantin Belousov u_int rsrv6:2; 7200a9bec17SKonstantin Belousov u_int addr1:30; 7210a9bec17SKonstantin Belousov u_int addr2:32; 7220a9bec17SKonstantin Belousov } __packed; 7230a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_event_ill_dev_table_entry) == 7240a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "EVENT_ILLEGAL_DEV_TABLE_ENTRY"); 7250a9bec17SKonstantin Belousov 7260a9bec17SKonstantin Belousov struct amdiommu_event_io_page_fault_entry { 7270a9bec17SKonstantin Belousov u_int devid:16; 7280a9bec17SKonstantin Belousov u_int pasid1:4; 7290a9bec17SKonstantin Belousov u_int rsrv0:7; 7300a9bec17SKonstantin Belousov u_int vnr:1; 7310a9bec17SKonstantin Belousov u_int rsrv1:1; 7320a9bec17SKonstantin Belousov u_int vevent:1; 7330a9bec17SKonstantin Belousov u_int vptr:1; 7340a9bec17SKonstantin Belousov u_int vcmd:1; 7350a9bec17SKonstantin Belousov u_int pasid:16; /* also domain id */ 7360a9bec17SKonstantin Belousov u_int gn:1; 7370a9bec17SKonstantin Belousov u_int nx:1; 7380a9bec17SKonstantin Belousov u_int us:1; 7390a9bec17SKonstantin Belousov u_int i:1; 7400a9bec17SKonstantin Belousov u_int pr:1; 7410a9bec17SKonstantin Belousov u_int rw:1; 7420a9bec17SKonstantin Belousov u_int pe:1; 7430a9bec17SKonstantin Belousov u_int rz:1; 7440a9bec17SKonstantin Belousov u_int tr:1; 7450a9bec17SKonstantin Belousov u_int rsrv2:3; 7460a9bec17SKonstantin Belousov u_int code:4; 7470a9bec17SKonstantin Belousov u_int addr1:32; 7480a9bec17SKonstantin Belousov u_int addr2:32; 7490a9bec17SKonstantin Belousov } __packed; 7500a9bec17SKonstantin Belousov _Static_assert(sizeof(struct amdiommu_event_io_page_fault_entry) == 7510a9bec17SKonstantin Belousov 4 * sizeof(uint32_t), "EVENT_IO_PAGE_FAULT_ENTRY"); 7520a9bec17SKonstantin Belousov 7530a9bec17SKonstantin Belousov #define AMDIOMMU_EV_ILL_DEV_TABLE_ENTRY 0x1 7540a9bec17SKonstantin Belousov #define AMDIOMMU_EV_IO_PAGE_FAULT 0x2 7550a9bec17SKonstantin Belousov #define AMDIOMMU_EV_DEV_TAB_HW_ERROR 0x3 7560a9bec17SKonstantin Belousov #define AMDIOMMU_EV_PAGE_TAB_HW_ERROR 0x4 7570a9bec17SKonstantin Belousov #define AMDIOMMU_EV_ILL_CMD_ERROR 0x5 7580a9bec17SKonstantin Belousov #define AMDIOMMU_EV_CMD_HW_ERROR 0x6 7590a9bec17SKonstantin Belousov #define AMDIOMMU_EV_IOTLB_INV_TIMEOUT 0x7 7600a9bec17SKonstantin Belousov #define AMDIOMMU_EV_INVALID_DEV_REQ 0x8 7610a9bec17SKonstantin Belousov #define AMDIOMMU_EV_INVALID_PPR_REQ 0x9 7620a9bec17SKonstantin Belousov #define AMDIOMMU_EV_COUNTER_ZERO 0xa /* Typo in table 42? */ 7630a9bec17SKonstantin Belousov 7640a9bec17SKonstantin Belousov #endif /* __X86_IOMMU_AMD_REG_H */ 765