17c8c0b82SPatrick Mooney /*- 2*32640292SAndy Fiddaman * SPDX-License-Identifier: BSD-2-Clause 37c8c0b82SPatrick Mooney * 47c8c0b82SPatrick Mooney * Copyright (c) 2016 Anish Gupta (anish@freebsd.org) 57c8c0b82SPatrick Mooney * Copyright (c) 2021 The FreeBSD Foundation 67c8c0b82SPatrick Mooney * 77c8c0b82SPatrick Mooney * Portions of this software were developed by Ka Ho Ng 87c8c0b82SPatrick Mooney * under sponsorship from the FreeBSD Foundation. 97c8c0b82SPatrick Mooney * 107c8c0b82SPatrick Mooney * Redistribution and use in source and binary forms, with or without 117c8c0b82SPatrick Mooney * modification, are permitted provided that the following conditions 127c8c0b82SPatrick Mooney * are met: 137c8c0b82SPatrick Mooney * 1. Redistributions of source code must retain the above copyright 147c8c0b82SPatrick Mooney * notice unmodified, this list of conditions, and the following 157c8c0b82SPatrick Mooney * disclaimer. 167c8c0b82SPatrick Mooney * 2. Redistributions in binary form must reproduce the above copyright 177c8c0b82SPatrick Mooney * notice, this list of conditions and the following disclaimer in the 187c8c0b82SPatrick Mooney * documentation and/or other materials provided with the distribution. 197c8c0b82SPatrick Mooney * 207c8c0b82SPatrick Mooney * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 217c8c0b82SPatrick Mooney * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 227c8c0b82SPatrick Mooney * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 237c8c0b82SPatrick Mooney * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 247c8c0b82SPatrick Mooney * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 257c8c0b82SPatrick Mooney * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 267c8c0b82SPatrick Mooney * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 277c8c0b82SPatrick Mooney * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 287c8c0b82SPatrick Mooney * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 297c8c0b82SPatrick Mooney * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 307c8c0b82SPatrick Mooney */ 317c8c0b82SPatrick Mooney 327c8c0b82SPatrick Mooney #ifndef _AMDVI_PRIV_H_ 337c8c0b82SPatrick Mooney #define _AMDVI_PRIV_H_ 347c8c0b82SPatrick Mooney 357c8c0b82SPatrick Mooney #include <contrib/dev/acpica/include/acpi.h> 367c8c0b82SPatrick Mooney 377c8c0b82SPatrick Mooney #define BIT(n) (1ULL << (n)) 387c8c0b82SPatrick Mooney /* Return value of bits[n:m] where n and (n >= ) m are bit positions. */ 397c8c0b82SPatrick Mooney #define REG_BITS(x, n, m) (((x) >> (m)) & \ 407c8c0b82SPatrick Mooney ((1 << (((n) - (m)) + 1)) - 1)) 417c8c0b82SPatrick Mooney 427c8c0b82SPatrick Mooney /* 437c8c0b82SPatrick Mooney * IOMMU PCI capability. 447c8c0b82SPatrick Mooney */ 457c8c0b82SPatrick Mooney #define AMDVI_PCI_CAP_IOTLB BIT(0) /* IOTLB is supported. */ 467c8c0b82SPatrick Mooney #define AMDVI_PCI_CAP_HT BIT(1) /* HyperTransport tunnel support. */ 477c8c0b82SPatrick Mooney #define AMDVI_PCI_CAP_NPCACHE BIT(2) /* Not present page cached. */ 487c8c0b82SPatrick Mooney #define AMDVI_PCI_CAP_EFR BIT(3) /* Extended features. */ 497c8c0b82SPatrick Mooney #define AMDVI_PCI_CAP_EXT BIT(4) /* Miscellaneous information reg. */ 507c8c0b82SPatrick Mooney 517c8c0b82SPatrick Mooney /* 527c8c0b82SPatrick Mooney * IOMMU extended features. 537c8c0b82SPatrick Mooney */ 547c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_PREFSUP BIT(0) /* Prefetch command support. */ 557c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_PPRSUP BIT(1) /* PPR support */ 567c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_XTSUP BIT(2) /* Reserved */ 577c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_NXSUP BIT(3) /* No-execute. */ 587c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_GTSUP BIT(4) /* Guest translation support. */ 597c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_EFRW BIT(5) /* Reserved */ 607c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_IASUP BIT(6) /* Invalidate all command supp. */ 617c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_GASUP BIT(7) /* Guest APIC or AVIC support. */ 627c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_HESUP BIT(8) /* Hardware Error. */ 637c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_PCSUP BIT(9) /* Performance counters support. */ 647c8c0b82SPatrick Mooney /* XXX: add more EFER bits. */ 657c8c0b82SPatrick Mooney 667c8c0b82SPatrick Mooney /* 677c8c0b82SPatrick Mooney * Device table entry or DTE 687c8c0b82SPatrick Mooney * NOTE: Must be 256-bits/32 bytes aligned. 697c8c0b82SPatrick Mooney */ 707c8c0b82SPatrick Mooney struct amdvi_dte { 717c8c0b82SPatrick Mooney uint32_t dt_valid:1; /* Device Table valid. */ 727c8c0b82SPatrick Mooney uint32_t pt_valid:1; /* Page translation valid. */ 737c8c0b82SPatrick Mooney uint16_t :7; /* Reserved[8:2] */ 747c8c0b82SPatrick Mooney uint8_t pt_level:3; /* Paging level, 0 to disable. */ 757c8c0b82SPatrick Mooney uint64_t pt_base:40; /* Page table root pointer. */ 767c8c0b82SPatrick Mooney uint8_t :3; /* Reserved[54:52] */ 777c8c0b82SPatrick Mooney uint8_t gv_valid:1; /* Revision 2, GVA to SPA. */ 787c8c0b82SPatrick Mooney uint8_t gv_level:2; /* Revision 2, GLX level. */ 797c8c0b82SPatrick Mooney uint8_t gv_cr3_lsb:3; /* Revision 2, GCR3[14:12] */ 807c8c0b82SPatrick Mooney uint8_t read_allow:1; /* I/O read enabled. */ 817c8c0b82SPatrick Mooney uint8_t write_allow:1; /* I/O write enabled. */ 827c8c0b82SPatrick Mooney uint8_t :1; /* Reserved[63] */ 837c8c0b82SPatrick Mooney uint16_t domain_id:16; /* Domain ID */ 847c8c0b82SPatrick Mooney uint16_t gv_cr3_lsb2:16; /* Revision 2, GCR3[30:15] */ 857c8c0b82SPatrick Mooney uint8_t iotlb_enable:1; /* Device support IOTLB */ 867c8c0b82SPatrick Mooney uint8_t sup_second_io_fault:1; /* Suppress subsequent I/O faults. */ 877c8c0b82SPatrick Mooney uint8_t sup_all_io_fault:1; /* Suppress all I/O page faults. */ 887c8c0b82SPatrick Mooney uint8_t IOctl:2; /* Port I/O control. */ 897c8c0b82SPatrick Mooney uint8_t iotlb_cache_disable:1; /* IOTLB cache hints. */ 907c8c0b82SPatrick Mooney uint8_t snoop_disable:1; /* Snoop disable. */ 917c8c0b82SPatrick Mooney uint8_t allow_ex:1; /* Allow exclusion. */ 927c8c0b82SPatrick Mooney uint8_t sysmgmt:2; /* System management message.*/ 937c8c0b82SPatrick Mooney uint8_t :1; /* Reserved[106] */ 947c8c0b82SPatrick Mooney uint32_t gv_cr3_msb:21; /* Revision 2, GCR3[51:31] */ 957c8c0b82SPatrick Mooney uint8_t intmap_valid:1; /* Interrupt map valid. */ 967c8c0b82SPatrick Mooney uint8_t intmap_len:4; /* Interrupt map table length. */ 977c8c0b82SPatrick Mooney uint8_t intmap_ign:1; /* Ignore unmapped interrupts. */ 987c8c0b82SPatrick Mooney uint64_t intmap_base:46; /* IntMap base. */ 997c8c0b82SPatrick Mooney uint8_t :4; /* Reserved[183:180] */ 1007c8c0b82SPatrick Mooney uint8_t init_pass:1; /* INIT pass through or PT */ 1017c8c0b82SPatrick Mooney uint8_t extintr_pass:1; /* External Interrupt PT */ 1027c8c0b82SPatrick Mooney uint8_t nmi_pass:1; /* NMI PT */ 1037c8c0b82SPatrick Mooney uint8_t :1; /* Reserved[187] */ 1047c8c0b82SPatrick Mooney uint8_t intr_ctrl:2; /* Interrupt control */ 1057c8c0b82SPatrick Mooney uint8_t lint0_pass:1; /* LINT0 PT */ 1067c8c0b82SPatrick Mooney uint8_t lint1_pass:1; /* LINT1 PT */ 1077c8c0b82SPatrick Mooney uint64_t :64; /* Reserved[255:192] */ 1087c8c0b82SPatrick Mooney } __attribute__((__packed__)); 1097c8c0b82SPatrick Mooney CTASSERT(sizeof(struct amdvi_dte) == 32); 1107c8c0b82SPatrick Mooney 1117c8c0b82SPatrick Mooney /* 1127c8c0b82SPatrick Mooney * IOMMU command entry. 1137c8c0b82SPatrick Mooney */ 1147c8c0b82SPatrick Mooney struct amdvi_cmd { 1157c8c0b82SPatrick Mooney uint32_t word0; 1167c8c0b82SPatrick Mooney uint32_t word1:28; 1177c8c0b82SPatrick Mooney uint8_t opcode:4; 1187c8c0b82SPatrick Mooney uint64_t addr; 1197c8c0b82SPatrick Mooney } __attribute__((__packed__)); 1207c8c0b82SPatrick Mooney 1217c8c0b82SPatrick Mooney /* Command opcodes. */ 1227c8c0b82SPatrick Mooney #define AMDVI_CMP_WAIT_OPCODE 0x1 /* Completion wait. */ 1237c8c0b82SPatrick Mooney #define AMDVI_INVD_DTE_OPCODE 0x2 /* Invalidate device table entry. */ 1247c8c0b82SPatrick Mooney #define AMDVI_INVD_PAGE_OPCODE 0x3 /* Invalidate pages. */ 1257c8c0b82SPatrick Mooney #define AMDVI_INVD_IOTLB_OPCODE 0x4 /* Invalidate IOTLB pages. */ 1267c8c0b82SPatrick Mooney #define AMDVI_INVD_INTR_OPCODE 0x5 /* Invalidate Interrupt table. */ 1277c8c0b82SPatrick Mooney #define AMDVI_PREFETCH_PAGES_OPCODE 0x6 /* Prefetch IOMMU pages. */ 1287c8c0b82SPatrick Mooney #define AMDVI_COMP_PPR_OPCODE 0x7 /* Complete PPR request. */ 1297c8c0b82SPatrick Mooney #define AMDVI_INV_ALL_OPCODE 0x8 /* Invalidate all. */ 1307c8c0b82SPatrick Mooney 1317c8c0b82SPatrick Mooney /* Completion wait attributes. */ 1327c8c0b82SPatrick Mooney #define AMDVI_CMP_WAIT_STORE BIT(0) /* Write back data. */ 1337c8c0b82SPatrick Mooney #define AMDVI_CMP_WAIT_INTR BIT(1) /* Completion wait interrupt. */ 1347c8c0b82SPatrick Mooney #define AMDVI_CMP_WAIT_FLUSH BIT(2) /* Flush queue. */ 1357c8c0b82SPatrick Mooney 1367c8c0b82SPatrick Mooney /* Invalidate page. */ 1377c8c0b82SPatrick Mooney #define AMDVI_INVD_PAGE_S BIT(0) /* Invalidation size. */ 1387c8c0b82SPatrick Mooney #define AMDVI_INVD_PAGE_PDE BIT(1) /* Invalidate PDE. */ 1397c8c0b82SPatrick Mooney #define AMDVI_INVD_PAGE_GN_GVA BIT(2) /* GPA or GVA. */ 1407c8c0b82SPatrick Mooney 1417c8c0b82SPatrick Mooney #define AMDVI_INVD_PAGE_ALL_ADDR (0x7FFFFFFFFFFFFULL << 12) 1427c8c0b82SPatrick Mooney 1437c8c0b82SPatrick Mooney /* Invalidate IOTLB. */ 1447c8c0b82SPatrick Mooney #define AMDVI_INVD_IOTLB_S BIT(0) /* Invalidation size 4k or addr */ 1457c8c0b82SPatrick Mooney #define AMDVI_INVD_IOTLB_GN_GVA BIT(2) /* GPA or GVA. */ 1467c8c0b82SPatrick Mooney 1477c8c0b82SPatrick Mooney #define AMDVI_INVD_IOTLB_ALL_ADDR (0x7FFFFFFFFFFFFULL << 12) 1487c8c0b82SPatrick Mooney /* XXX: add more command entries. */ 1497c8c0b82SPatrick Mooney 1507c8c0b82SPatrick Mooney /* 1517c8c0b82SPatrick Mooney * IOMMU event entry. 1527c8c0b82SPatrick Mooney */ 1537c8c0b82SPatrick Mooney struct amdvi_event { 1547c8c0b82SPatrick Mooney uint16_t devid; 1557c8c0b82SPatrick Mooney uint16_t pasid_hi; 1567c8c0b82SPatrick Mooney uint16_t pasid_domid; /* PASID low or DomainID */ 1577c8c0b82SPatrick Mooney uint16_t flag:12; 1587c8c0b82SPatrick Mooney uint8_t opcode:4; 1597c8c0b82SPatrick Mooney uint64_t addr; 1607c8c0b82SPatrick Mooney } __attribute__((__packed__)); 1617c8c0b82SPatrick Mooney CTASSERT(sizeof(struct amdvi_event) == 16); 1627c8c0b82SPatrick Mooney 1637c8c0b82SPatrick Mooney /* Various event types. */ 1647c8c0b82SPatrick Mooney #define AMDVI_EVENT_INVALID_DTE 0x1 1657c8c0b82SPatrick Mooney #define AMDVI_EVENT_PFAULT 0x2 1667c8c0b82SPatrick Mooney #define AMDVI_EVENT_DTE_HW_ERROR 0x3 1677c8c0b82SPatrick Mooney #define AMDVI_EVENT_PAGE_HW_ERROR 0x4 1687c8c0b82SPatrick Mooney #define AMDVI_EVENT_ILLEGAL_CMD 0x5 1697c8c0b82SPatrick Mooney #define AMDVI_EVENT_CMD_HW_ERROR 0x6 1707c8c0b82SPatrick Mooney #define AMDVI_EVENT_IOTLB_TIMEOUT 0x7 1717c8c0b82SPatrick Mooney #define AMDVI_EVENT_INVALID_DTE_REQ 0x8 1727c8c0b82SPatrick Mooney #define AMDVI_EVENT_INVALID_PPR_REQ 0x9 1737c8c0b82SPatrick Mooney #define AMDVI_EVENT_COUNTER_ZERO 0xA 1747c8c0b82SPatrick Mooney 1757c8c0b82SPatrick Mooney #define AMDVI_EVENT_FLAG_MASK 0x1FF /* Mask for event flags. */ 1767c8c0b82SPatrick Mooney #define AMDVI_EVENT_FLAG_TYPE(x) (((x) >> 9) & 0x3) 1777c8c0b82SPatrick Mooney 1787c8c0b82SPatrick Mooney /* 1797c8c0b82SPatrick Mooney * IOMMU control block. 1807c8c0b82SPatrick Mooney */ 1817c8c0b82SPatrick Mooney struct amdvi_ctrl { 1827c8c0b82SPatrick Mooney struct { 1837c8c0b82SPatrick Mooney uint16_t size:9; 1847c8c0b82SPatrick Mooney uint16_t :3; 1857c8c0b82SPatrick Mooney uint64_t base:40; /* Devtable register base. */ 1867c8c0b82SPatrick Mooney uint16_t :12; 1877c8c0b82SPatrick Mooney } dte; 1887c8c0b82SPatrick Mooney struct { 1897c8c0b82SPatrick Mooney uint16_t :12; 1907c8c0b82SPatrick Mooney uint64_t base:40; 1917c8c0b82SPatrick Mooney uint8_t :4; 1927c8c0b82SPatrick Mooney uint8_t len:4; 1937c8c0b82SPatrick Mooney uint8_t :4; 1947c8c0b82SPatrick Mooney } cmd; 1957c8c0b82SPatrick Mooney struct { 1967c8c0b82SPatrick Mooney uint16_t :12; 1977c8c0b82SPatrick Mooney uint64_t base:40; 1987c8c0b82SPatrick Mooney uint8_t :4; 1997c8c0b82SPatrick Mooney uint8_t len:4; 2007c8c0b82SPatrick Mooney uint8_t :4; 2017c8c0b82SPatrick Mooney } event; 2027c8c0b82SPatrick Mooney uint16_t control :13; 2037c8c0b82SPatrick Mooney uint64_t :51; 2047c8c0b82SPatrick Mooney struct { 2057c8c0b82SPatrick Mooney uint8_t enable:1; 2067c8c0b82SPatrick Mooney uint8_t allow:1; 2077c8c0b82SPatrick Mooney uint16_t :10; 2087c8c0b82SPatrick Mooney uint64_t base:40; 2097c8c0b82SPatrick Mooney uint16_t :12; 2107c8c0b82SPatrick Mooney uint16_t :12; 2117c8c0b82SPatrick Mooney uint64_t limit:40; 2127c8c0b82SPatrick Mooney uint16_t :12; 2137c8c0b82SPatrick Mooney } excl; 2147c8c0b82SPatrick Mooney /* 2157c8c0b82SPatrick Mooney * Revision 2 only. 2167c8c0b82SPatrick Mooney */ 2177c8c0b82SPatrick Mooney uint64_t ex_feature; 2187c8c0b82SPatrick Mooney struct { 2197c8c0b82SPatrick Mooney uint16_t :12; 2207c8c0b82SPatrick Mooney uint64_t base:40; 2217c8c0b82SPatrick Mooney uint8_t :4; 2227c8c0b82SPatrick Mooney uint8_t len:4; 2237c8c0b82SPatrick Mooney uint8_t :4; 2247c8c0b82SPatrick Mooney } ppr; 2257c8c0b82SPatrick Mooney uint64_t first_event; 2267c8c0b82SPatrick Mooney uint64_t second_event; 2277c8c0b82SPatrick Mooney uint64_t event_status; 2287c8c0b82SPatrick Mooney /* Revision 2 only, end. */ 2297c8c0b82SPatrick Mooney uint8_t pad1[0x1FA8]; /* Padding. */ 2307c8c0b82SPatrick Mooney uint32_t cmd_head:19; 2317c8c0b82SPatrick Mooney uint64_t :45; 2327c8c0b82SPatrick Mooney uint32_t cmd_tail:19; 2337c8c0b82SPatrick Mooney uint64_t :45; 2347c8c0b82SPatrick Mooney uint32_t evt_head:19; 2357c8c0b82SPatrick Mooney uint64_t :45; 2367c8c0b82SPatrick Mooney uint32_t evt_tail:19; 2377c8c0b82SPatrick Mooney uint64_t :45; 2387c8c0b82SPatrick Mooney uint32_t status:19; 2397c8c0b82SPatrick Mooney uint64_t :45; 2407c8c0b82SPatrick Mooney uint64_t pad2; 2417c8c0b82SPatrick Mooney uint8_t :4; 2427c8c0b82SPatrick Mooney uint16_t ppr_head:15; 2437c8c0b82SPatrick Mooney uint64_t :45; 2447c8c0b82SPatrick Mooney uint8_t :4; 2457c8c0b82SPatrick Mooney uint16_t ppr_tail:15; 2467c8c0b82SPatrick Mooney uint64_t :45; 2477c8c0b82SPatrick Mooney uint8_t pad3[0x1FC0]; /* Padding. */ 2487c8c0b82SPatrick Mooney 2497c8c0b82SPatrick Mooney /* XXX: More for rev2. */ 2507c8c0b82SPatrick Mooney } __attribute__((__packed__)); 2517c8c0b82SPatrick Mooney CTASSERT(offsetof(struct amdvi_ctrl, pad1)== 0x58); 2527c8c0b82SPatrick Mooney CTASSERT(offsetof(struct amdvi_ctrl, pad2)== 0x2028); 2537c8c0b82SPatrick Mooney CTASSERT(offsetof(struct amdvi_ctrl, pad3)== 0x2040); 2547c8c0b82SPatrick Mooney 2557c8c0b82SPatrick Mooney #define AMDVI_MMIO_V1_SIZE (4 * PAGE_SIZE) /* v1 size */ 2567c8c0b82SPatrick Mooney /* 2577c8c0b82SPatrick Mooney * AMF IOMMU v2 size including event counters 2587c8c0b82SPatrick Mooney */ 2597c8c0b82SPatrick Mooney #define AMDVI_MMIO_V2_SIZE (8 * PAGE_SIZE) 2607c8c0b82SPatrick Mooney 2617c8c0b82SPatrick Mooney CTASSERT(sizeof(struct amdvi_ctrl) == 0x4000); 2627c8c0b82SPatrick Mooney CTASSERT(sizeof(struct amdvi_ctrl) == AMDVI_MMIO_V1_SIZE); 2637c8c0b82SPatrick Mooney 2647c8c0b82SPatrick Mooney /* IVHD flag */ 2657c8c0b82SPatrick Mooney #define IVHD_FLAG_HTT BIT(0) /* Hypertransport Tunnel. */ 2667c8c0b82SPatrick Mooney #define IVHD_FLAG_PPW BIT(1) /* Pass posted write. */ 2677c8c0b82SPatrick Mooney #define IVHD_FLAG_RPPW BIT(2) /* Response pass posted write. */ 2687c8c0b82SPatrick Mooney #define IVHD_FLAG_ISOC BIT(3) /* Isoc support. */ 2697c8c0b82SPatrick Mooney #define IVHD_FLAG_IOTLB BIT(4) /* IOTLB support. */ 2707c8c0b82SPatrick Mooney #define IVHD_FLAG_COH BIT(5) /* Coherent control, default 1 */ 2717c8c0b82SPatrick Mooney #define IVHD_FLAG_PFS BIT(6) /* Prefetch IOMMU pages. */ 2727c8c0b82SPatrick Mooney #define IVHD_FLAG_PPRS BIT(7) /* Peripheral page support. */ 2737c8c0b82SPatrick Mooney 2747c8c0b82SPatrick Mooney /* IVHD device entry data setting. */ 2757c8c0b82SPatrick Mooney #define IVHD_DEV_LINT0_PASS BIT(6) /* LINT0 interrupts. */ 2767c8c0b82SPatrick Mooney #define IVHD_DEV_LINT1_PASS BIT(7) /* LINT1 interrupts. */ 2777c8c0b82SPatrick Mooney 2787c8c0b82SPatrick Mooney /* Bit[5:4] for System Mgmt. Bit3 is reserved. */ 2797c8c0b82SPatrick Mooney #define IVHD_DEV_INIT_PASS BIT(0) /* INIT */ 2807c8c0b82SPatrick Mooney #define IVHD_DEV_EXTINTR_PASS BIT(1) /* ExtInt */ 2817c8c0b82SPatrick Mooney #define IVHD_DEV_NMI_PASS BIT(2) /* NMI */ 2827c8c0b82SPatrick Mooney 2837c8c0b82SPatrick Mooney /* IVHD 8-byte extended data settings. */ 2847c8c0b82SPatrick Mooney #define IVHD_DEV_EXT_ATS_DISABLE BIT(31) /* Disable ATS */ 2857c8c0b82SPatrick Mooney 2867c8c0b82SPatrick Mooney /* IOMMU control register. */ 2877c8c0b82SPatrick Mooney #define AMDVI_CTRL_EN BIT(0) /* IOMMU enable. */ 2887c8c0b82SPatrick Mooney #define AMDVI_CTRL_HTT BIT(1) /* Hypertransport tunnel enable. */ 2897c8c0b82SPatrick Mooney #define AMDVI_CTRL_ELOG BIT(2) /* Event log enable. */ 2907c8c0b82SPatrick Mooney #define AMDVI_CTRL_ELOGINT BIT(3) /* Event log interrupt. */ 2917c8c0b82SPatrick Mooney #define AMDVI_CTRL_COMINT BIT(4) /* Completion wait interrupt. */ 2927c8c0b82SPatrick Mooney #define AMDVI_CTRL_PPW BIT(8) 2937c8c0b82SPatrick Mooney #define AMDVI_CTRL_RPPW BIT(9) 2947c8c0b82SPatrick Mooney #define AMDVI_CTRL_COH BIT(10) 2957c8c0b82SPatrick Mooney #define AMDVI_CTRL_ISOC BIT(11) 2967c8c0b82SPatrick Mooney #define AMDVI_CTRL_CMD BIT(12) /* Command buffer enable. */ 2977c8c0b82SPatrick Mooney #define AMDVI_CTRL_PPRLOG BIT(13) 2987c8c0b82SPatrick Mooney #define AMDVI_CTRL_PPRINT BIT(14) 2997c8c0b82SPatrick Mooney #define AMDVI_CTRL_PPREN BIT(15) 3007c8c0b82SPatrick Mooney #define AMDVI_CTRL_GTE BIT(16) /* Guest translation enable. */ 3017c8c0b82SPatrick Mooney #define AMDVI_CTRL_GAE BIT(17) /* Guest APIC enable. */ 3027c8c0b82SPatrick Mooney 3037c8c0b82SPatrick Mooney /* Invalidation timeout. */ 3047c8c0b82SPatrick Mooney #define AMDVI_CTRL_INV_NO_TO 0 /* No timeout. */ 3057c8c0b82SPatrick Mooney #define AMDVI_CTRL_INV_TO_1ms 1 /* 1 ms */ 3067c8c0b82SPatrick Mooney #define AMDVI_CTRL_INV_TO_10ms 2 /* 10 ms */ 3077c8c0b82SPatrick Mooney #define AMDVI_CTRL_INV_TO_100ms 3 /* 100 ms */ 3087c8c0b82SPatrick Mooney #define AMDVI_CTRL_INV_TO_1S 4 /* 1 second */ 3097c8c0b82SPatrick Mooney #define AMDVI_CTRL_INV_TO_10S 5 /* 10 second */ 3107c8c0b82SPatrick Mooney #define AMDVI_CTRL_INV_TO_100S 6 /* 100 second */ 3117c8c0b82SPatrick Mooney 3127c8c0b82SPatrick Mooney /* 3137c8c0b82SPatrick Mooney * Max number of PCI devices. 3147c8c0b82SPatrick Mooney * 256 bus x 32 slot/devices x 8 functions. 3157c8c0b82SPatrick Mooney */ 3167c8c0b82SPatrick Mooney #define PCI_NUM_DEV_MAX 0x10000 3177c8c0b82SPatrick Mooney 3187c8c0b82SPatrick Mooney /* Maximum number of domains supported by IOMMU. */ 3197c8c0b82SPatrick Mooney #define AMDVI_MAX_DOMAIN (BIT(16) - 1) 3207c8c0b82SPatrick Mooney 3217c8c0b82SPatrick Mooney /* 3227c8c0b82SPatrick Mooney * IOMMU Page Table attributes. 3237c8c0b82SPatrick Mooney */ 3247c8c0b82SPatrick Mooney #define AMDVI_PT_PRESENT BIT(0) 3257c8c0b82SPatrick Mooney #define AMDVI_PT_COHERENT BIT(60) 3267c8c0b82SPatrick Mooney #define AMDVI_PT_READ BIT(61) 3277c8c0b82SPatrick Mooney #define AMDVI_PT_WRITE BIT(62) 3287c8c0b82SPatrick Mooney 3297c8c0b82SPatrick Mooney #define AMDVI_PT_RW (AMDVI_PT_READ | AMDVI_PT_WRITE) 3307c8c0b82SPatrick Mooney #define AMDVI_PT_MASK 0xFFFFFFFFFF000UL /* Only [51:12] for PA */ 3317c8c0b82SPatrick Mooney 3327c8c0b82SPatrick Mooney #define AMDVI_PD_LEVEL_SHIFT 9 3337c8c0b82SPatrick Mooney #define AMDVI_PD_SUPER(x) (((x) >> AMDVI_PD_LEVEL_SHIFT) == 7) 3347c8c0b82SPatrick Mooney /* 3357c8c0b82SPatrick Mooney * IOMMU Status, offset 0x2020 3367c8c0b82SPatrick Mooney */ 3377c8c0b82SPatrick Mooney #define AMDVI_STATUS_EV_OF BIT(0) /* Event overflow. */ 3387c8c0b82SPatrick Mooney #define AMDVI_STATUS_EV_INTR BIT(1) /* Event interrupt. */ 3397c8c0b82SPatrick Mooney /* Completion wait command completed. */ 3407c8c0b82SPatrick Mooney #define AMDVI_STATUS_CMP BIT(2) 3417c8c0b82SPatrick Mooney 3427c8c0b82SPatrick Mooney #define IVRS_CTRL_RID 1 /* MMIO RID */ 3437c8c0b82SPatrick Mooney 3447c8c0b82SPatrick Mooney /* ACPI IVHD */ 3457c8c0b82SPatrick Mooney struct ivhd_dev_cfg { 3467c8c0b82SPatrick Mooney uint32_t start_id; 3477c8c0b82SPatrick Mooney uint32_t end_id; 3487c8c0b82SPatrick Mooney uint8_t data; /* Device configuration. */ 3497c8c0b82SPatrick Mooney bool enable_ats; /* ATS enabled for the device. */ 3507c8c0b82SPatrick Mooney int ats_qlen; /* ATS invalidation queue depth. */ 3517c8c0b82SPatrick Mooney }; 3527c8c0b82SPatrick Mooney 3537c8c0b82SPatrick Mooney struct amdvi_domain { 3547c8c0b82SPatrick Mooney uint64_t *ptp; /* Highest level page table */ 3557c8c0b82SPatrick Mooney int ptp_level; /* Level of page tables */ 3567c8c0b82SPatrick Mooney u_int id; /* Domain id */ 3577c8c0b82SPatrick Mooney SLIST_ENTRY (amdvi_domain) next; 3587c8c0b82SPatrick Mooney }; 3597c8c0b82SPatrick Mooney 3607c8c0b82SPatrick Mooney /* 3617c8c0b82SPatrick Mooney * Different type of IVHD. 3627c8c0b82SPatrick Mooney * XXX: Use AcpiIvrsType once new IVHD types are available. 3637c8c0b82SPatrick Mooney */ 3647c8c0b82SPatrick Mooney enum IvrsType 3657c8c0b82SPatrick Mooney { 3667c8c0b82SPatrick Mooney IVRS_TYPE_HARDWARE_LEGACY = ACPI_IVRS_TYPE_HARDWARE1, 3677c8c0b82SPatrick Mooney /* Legacy without EFRi support. */ 3687c8c0b82SPatrick Mooney IVRS_TYPE_HARDWARE_EFR = ACPI_IVRS_TYPE_HARDWARE2, 3697c8c0b82SPatrick Mooney /* With EFR support. */ 3707c8c0b82SPatrick Mooney IVRS_TYPE_HARDWARE_MIXED = 0x40, /* Mixed with EFR support. */ 3717c8c0b82SPatrick Mooney }; 3727c8c0b82SPatrick Mooney 3737c8c0b82SPatrick Mooney /* 3747c8c0b82SPatrick Mooney * AMD IOMMU softc. 3757c8c0b82SPatrick Mooney */ 3767c8c0b82SPatrick Mooney struct amdvi_softc { 3777c8c0b82SPatrick Mooney struct amdvi_ctrl *ctrl; /* Control area. */ 3787c8c0b82SPatrick Mooney device_t dev; /* IOMMU device. */ 3797c8c0b82SPatrick Mooney device_t pci_dev; /* IOMMU PCI function device. */ 3807c8c0b82SPatrick Mooney enum IvrsType ivhd_type; /* IOMMU IVHD type. */ 3817c8c0b82SPatrick Mooney bool iotlb; /* IOTLB supported by IOMMU */ 3827c8c0b82SPatrick Mooney struct amdvi_cmd *cmd; /* Command descriptor area. */ 3837c8c0b82SPatrick Mooney int cmd_max; /* Max number of commands. */ 3847c8c0b82SPatrick Mooney uint64_t cmp_data; /* Command completion write back. */ 3857c8c0b82SPatrick Mooney struct amdvi_event *event; /* Event descriptor area. */ 3867c8c0b82SPatrick Mooney int event_max; /* Max number of events. */ 3877c8c0b82SPatrick Mooney /* ACPI various flags. */ 3887c8c0b82SPatrick Mooney uint32_t ivhd_flag; /* ACPI IVHD flag. */ 3897c8c0b82SPatrick Mooney uint32_t ivhd_feature; /* ACPI v1 Reserved or v2 attribute. */ 3907c8c0b82SPatrick Mooney uint64_t ext_feature; /* IVHD EFR */ 3917c8c0b82SPatrick Mooney /* PCI related. */ 3927c8c0b82SPatrick Mooney uint16_t cap_off; /* PCI Capability offset. */ 3937c8c0b82SPatrick Mooney uint8_t pci_cap; /* PCI capability. */ 3947c8c0b82SPatrick Mooney uint16_t pci_seg; /* IOMMU PCI domain/segment. */ 3957c8c0b82SPatrick Mooney uint16_t pci_rid; /* PCI BDF of IOMMU */ 3967c8c0b82SPatrick Mooney /* ACPI device configuration for end points. */ 3977c8c0b82SPatrick Mooney struct ivhd_dev_cfg *dev_cfg; 3987c8c0b82SPatrick Mooney int dev_cfg_cnt; 3997c8c0b82SPatrick Mooney int dev_cfg_cap; 4007c8c0b82SPatrick Mooney 4017c8c0b82SPatrick Mooney /* Software statistics. */ 4027c8c0b82SPatrick Mooney uint64_t event_intr_cnt; /* Total event INTR count. */ 4037c8c0b82SPatrick Mooney uint64_t total_cmd; /* Total number of commands. */ 4047c8c0b82SPatrick Mooney }; 4057c8c0b82SPatrick Mooney 4067c8c0b82SPatrick Mooney int amdvi_setup_hw(struct amdvi_softc *softc); 4077c8c0b82SPatrick Mooney int amdvi_teardown_hw(struct amdvi_softc *softc); 4087c8c0b82SPatrick Mooney #endif /* _AMDVI_PRIV_H_ */ 409