13a634bfcSVikram Hegde /* 23a634bfcSVikram Hegde * CDDL HEADER START 33a634bfcSVikram Hegde * 43a634bfcSVikram Hegde * The contents of this file are subject to the terms of the 53a634bfcSVikram Hegde * Common Development and Distribution License (the "License"). 63a634bfcSVikram Hegde * You may not use this file except in compliance with the License. 73a634bfcSVikram Hegde * 83a634bfcSVikram Hegde * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93a634bfcSVikram Hegde * or http://www.opensolaris.org/os/licensing. 103a634bfcSVikram Hegde * See the License for the specific language governing permissions 113a634bfcSVikram Hegde * and limitations under the License. 123a634bfcSVikram Hegde * 133a634bfcSVikram Hegde * When distributing Covered Code, include this CDDL HEADER in each 143a634bfcSVikram Hegde * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153a634bfcSVikram Hegde * If applicable, add the following below this CDDL HEADER, with the 163a634bfcSVikram Hegde * fields enclosed by brackets "[]" replaced with your own identifying 173a634bfcSVikram Hegde * information: Portions Copyright [yyyy] [name of copyright owner] 183a634bfcSVikram Hegde * 193a634bfcSVikram Hegde * CDDL HEADER END 203a634bfcSVikram Hegde */ 213a634bfcSVikram Hegde /* 229e986f0eSFrank Van Der Linden * Portions Copyright (c) 2010, Oracle and/or its affiliates. 239e986f0eSFrank Van Der Linden * All rights reserved. 243a634bfcSVikram Hegde */ 253a634bfcSVikram Hegde 263a634bfcSVikram Hegde /* 273a634bfcSVikram Hegde * Copyright (c) 2008, Intel Corporation. 283a634bfcSVikram Hegde * All rights reserved. 293a634bfcSVikram Hegde */ 303a634bfcSVikram Hegde 313a634bfcSVikram Hegde #ifndef _SYS_INTEL_IOMMU_H 323a634bfcSVikram Hegde #define _SYS_INTEL_IOMMU_H 333a634bfcSVikram Hegde 343a634bfcSVikram Hegde /* 353a634bfcSVikram Hegde * Intel IOMMU implementation specific state 363a634bfcSVikram Hegde */ 373a634bfcSVikram Hegde 383a634bfcSVikram Hegde #ifdef __cplusplus 393a634bfcSVikram Hegde extern "C" { 403a634bfcSVikram Hegde #endif 413a634bfcSVikram Hegde 423a634bfcSVikram Hegde #include <sys/types.h> 433a634bfcSVikram Hegde #include <sys/bitset.h> 443a634bfcSVikram Hegde #include <sys/kstat.h> 45*50200e77SFrank Van Der Linden #include <sys/kmem.h> 463a634bfcSVikram Hegde #include <sys/vmem.h> 473a634bfcSVikram Hegde #include <sys/rootnex.h> 48*50200e77SFrank Van Der Linden #include <sys/iommulib.h> 49*50200e77SFrank Van Der Linden #include <sys/sdt.h> 503a634bfcSVikram Hegde 513a634bfcSVikram Hegde /* 523a634bfcSVikram Hegde * Some ON drivers have bugs. Keep this define until all such drivers 533a634bfcSVikram Hegde * have been fixed 543a634bfcSVikram Hegde */ 553a634bfcSVikram Hegde #define BUGGY_DRIVERS 1 563a634bfcSVikram Hegde 573a634bfcSVikram Hegde /* PD(T)E entries */ 583a634bfcSVikram Hegde typedef uint64_t hw_pdte_t; 593a634bfcSVikram Hegde 603a634bfcSVikram Hegde #define IMMU_MAXNAMELEN (64) 613a634bfcSVikram Hegde #define IMMU_MAXSEG (1) 623a634bfcSVikram Hegde #define IMMU_REGSZ (1UL << 12) 633a634bfcSVikram Hegde #define IMMU_PAGESIZE (4096) 643a634bfcSVikram Hegde #define IMMU_PAGESHIFT (12) 653a634bfcSVikram Hegde #define IMMU_PAGEOFFSET (IMMU_PAGESIZE - 1) 663a634bfcSVikram Hegde #define IMMU_PAGEMASK (~IMMU_PAGEOFFSET) 673a634bfcSVikram Hegde #define IMMU_BTOP(b) (((uint64_t)b) >> IMMU_PAGESHIFT) 683a634bfcSVikram Hegde #define IMMU_PTOB(p) (((uint64_t)p) << IMMU_PAGESHIFT) 69*50200e77SFrank Van Der Linden #define IMMU_BTOPR(x) ((((x) + IMMU_PAGEOFFSET) >> IMMU_PAGESHIFT)) 703a634bfcSVikram Hegde #define IMMU_PGTABLE_MAX_LEVELS (6) 713a634bfcSVikram Hegde #define IMMU_ROUNDUP(size) (((size) + IMMU_PAGEOFFSET) & ~IMMU_PAGEOFFSET) 723a634bfcSVikram Hegde #define IMMU_ROUNDOWN(addr) ((addr) & ~IMMU_PAGEOFFSET) 733a634bfcSVikram Hegde #define IMMU_PGTABLE_LEVEL_STRIDE (9) 743a634bfcSVikram Hegde #define IMMU_PGTABLE_LEVEL_MASK ((1<<IMMU_PGTABLE_LEVEL_STRIDE) - 1) 753a634bfcSVikram Hegde #define IMMU_PGTABLE_OFFSHIFT (IMMU_PAGESHIFT - IMMU_PGTABLE_LEVEL_STRIDE) 763a634bfcSVikram Hegde #define IMMU_PGTABLE_MAXIDX ((IMMU_PAGESIZE / sizeof (hw_pdte_t)) - 1) 773a634bfcSVikram Hegde 783a634bfcSVikram Hegde /* 793a634bfcSVikram Hegde * DMAR global defines 803a634bfcSVikram Hegde */ 813a634bfcSVikram Hegde #define DMAR_TABLE "dmar-table" 823a634bfcSVikram Hegde #define DMAR_INTRMAP_SUPPORT (0x01) 833a634bfcSVikram Hegde 843a634bfcSVikram Hegde /* DMAR unit types */ 853a634bfcSVikram Hegde #define DMAR_DRHD 0 863a634bfcSVikram Hegde #define DMAR_RMRR 1 873a634bfcSVikram Hegde #define DMAR_ATSR 2 883a634bfcSVikram Hegde #define DMAR_RHSA 3 893a634bfcSVikram Hegde 903a634bfcSVikram Hegde /* DRHD flag values */ 913a634bfcSVikram Hegde #define DMAR_INCLUDE_ALL (0x01) 923a634bfcSVikram Hegde 933a634bfcSVikram Hegde /* Device scope types */ 943a634bfcSVikram Hegde #define DMAR_ENDPOINT 1 953a634bfcSVikram Hegde #define DMAR_SUBTREE 2 963a634bfcSVikram Hegde #define DMAR_IOAPIC 3 973a634bfcSVikram Hegde #define DMAR_HPET 4 983a634bfcSVikram Hegde 993a634bfcSVikram Hegde 1003a634bfcSVikram Hegde /* Forward declarations for IOMMU state structure and DVMA domain struct */ 1013a634bfcSVikram Hegde struct immu; 1023a634bfcSVikram Hegde struct domain; 1033a634bfcSVikram Hegde 1043a634bfcSVikram Hegde /* 1053a634bfcSVikram Hegde * The following structure describes the formate of DMAR ACPI table format. 1063a634bfcSVikram Hegde * They are used to parse DMAR ACPI table. Read the spec for the meaning 1073a634bfcSVikram Hegde * of each member. 1083a634bfcSVikram Hegde */ 1093a634bfcSVikram Hegde 1103a634bfcSVikram Hegde /* lengths of various strings */ 1113a634bfcSVikram Hegde #define DMAR_SIG_LEN (4) /* table signature */ 1123a634bfcSVikram Hegde #define DMAR_OEMID_LEN (6) /* OEM ID */ 1133a634bfcSVikram Hegde #define DMAR_TBLID_LEN (8) /* OEM table ID */ 1143a634bfcSVikram Hegde #define DMAR_ASL_LEN (4) /* ASL len */ 1153a634bfcSVikram Hegde 1163a634bfcSVikram Hegde typedef struct dmar_table { 1173a634bfcSVikram Hegde kmutex_t tbl_lock; 1183a634bfcSVikram Hegde uint8_t tbl_haw; 1193a634bfcSVikram Hegde boolean_t tbl_intrmap; 1203a634bfcSVikram Hegde list_t tbl_drhd_list[IMMU_MAXSEG]; 1213a634bfcSVikram Hegde list_t tbl_rmrr_list[IMMU_MAXSEG]; 1223a634bfcSVikram Hegde char *tbl_oem_id; 1233a634bfcSVikram Hegde char *tbl_oem_tblid; 1243a634bfcSVikram Hegde uint32_t tbl_oem_rev; 1253a634bfcSVikram Hegde caddr_t tbl_raw; 1263a634bfcSVikram Hegde int tbl_rawlen; 1273a634bfcSVikram Hegde } dmar_table_t; 1283a634bfcSVikram Hegde 1293a634bfcSVikram Hegde typedef struct drhd { 1303a634bfcSVikram Hegde kmutex_t dr_lock; /* protects the dmar field */ 1313a634bfcSVikram Hegde struct immu *dr_immu; 1323a634bfcSVikram Hegde dev_info_t *dr_dip; 1333a634bfcSVikram Hegde uint16_t dr_seg; 1343a634bfcSVikram Hegde uint64_t dr_regs; 1353a634bfcSVikram Hegde boolean_t dr_include_all; 1363a634bfcSVikram Hegde list_t dr_scope_list; 1373a634bfcSVikram Hegde list_node_t dr_node; 1383a634bfcSVikram Hegde } drhd_t; 1393a634bfcSVikram Hegde 1403a634bfcSVikram Hegde typedef struct rmrr { 1413a634bfcSVikram Hegde kmutex_t rm_lock; 1423a634bfcSVikram Hegde uint16_t rm_seg; 1433a634bfcSVikram Hegde uint64_t rm_base; 1443a634bfcSVikram Hegde uint64_t rm_limit; 1453a634bfcSVikram Hegde list_t rm_scope_list; 1463a634bfcSVikram Hegde list_node_t rm_node; 1473a634bfcSVikram Hegde } rmrr_t; 1483a634bfcSVikram Hegde 149*50200e77SFrank Van Der Linden #define IMMU_UNIT_NAME "iommu" 150*50200e77SFrank Van Der Linden 1513a634bfcSVikram Hegde /* 1523a634bfcSVikram Hegde * Macros based on PCI spec 1533a634bfcSVikram Hegde */ 1543a634bfcSVikram Hegde #define IMMU_PCI_DEV(devfunc) ((uint64_t)devfunc >> 3) /* from devfunc */ 1553a634bfcSVikram Hegde #define IMMU_PCI_FUNC(devfunc) (devfunc & 7) /* get func from devfunc */ 1563a634bfcSVikram Hegde #define IMMU_PCI_DEVFUNC(d, f) (((d) << 3) | (f)) /* create devfunc */ 1573a634bfcSVikram Hegde 1583a634bfcSVikram Hegde typedef struct scope { 1593a634bfcSVikram Hegde uint8_t scp_type; 1603a634bfcSVikram Hegde uint8_t scp_enumid; 1613a634bfcSVikram Hegde uint8_t scp_bus; 1623a634bfcSVikram Hegde uint8_t scp_dev; 1633a634bfcSVikram Hegde uint8_t scp_func; 1643a634bfcSVikram Hegde list_node_t scp_node; 1653a634bfcSVikram Hegde } scope_t; 1663a634bfcSVikram Hegde 1673a634bfcSVikram Hegde /* 1683a634bfcSVikram Hegde * interrupt source id and drhd info for ioapic 1693a634bfcSVikram Hegde */ 1703a634bfcSVikram Hegde typedef struct ioapic_drhd { 1713a634bfcSVikram Hegde uchar_t ioapic_ioapicid; 1723a634bfcSVikram Hegde uint16_t ioapic_sid; /* ioapic source id */ 1733a634bfcSVikram Hegde drhd_t *ioapic_drhd; 1743a634bfcSVikram Hegde list_node_t ioapic_node; 1753a634bfcSVikram Hegde } ioapic_drhd_t; 1763a634bfcSVikram Hegde 1773a634bfcSVikram Hegde typedef struct memrng { 1783a634bfcSVikram Hegde uint64_t mrng_start; 1793a634bfcSVikram Hegde uint64_t mrng_npages; 1803a634bfcSVikram Hegde } memrng_t; 1813a634bfcSVikram Hegde 1823a634bfcSVikram Hegde typedef enum immu_flags { 1833a634bfcSVikram Hegde IMMU_FLAGS_NONE = 0x1, 1843a634bfcSVikram Hegde IMMU_FLAGS_SLEEP = 0x1, 1853a634bfcSVikram Hegde IMMU_FLAGS_NOSLEEP = 0x2, 1863a634bfcSVikram Hegde IMMU_FLAGS_READ = 0x4, 1873a634bfcSVikram Hegde IMMU_FLAGS_WRITE = 0x8, 1883a634bfcSVikram Hegde IMMU_FLAGS_DONTPASS = 0x10, 1893a634bfcSVikram Hegde IMMU_FLAGS_ALLOC = 0x20, 1903a634bfcSVikram Hegde IMMU_FLAGS_MUST_MATCH = 0x40, 1913a634bfcSVikram Hegde IMMU_FLAGS_PAGE1 = 0x80, 1923a634bfcSVikram Hegde IMMU_FLAGS_UNITY = 0x100, 1933a634bfcSVikram Hegde IMMU_FLAGS_DMAHDL = 0x200, 1943a634bfcSVikram Hegde IMMU_FLAGS_MEMRNG = 0x400 1953a634bfcSVikram Hegde } immu_flags_t; 1963a634bfcSVikram Hegde 1973a634bfcSVikram Hegde typedef enum cont_avail { 1983a634bfcSVikram Hegde IMMU_CONT_BAD = 0x0, 1993a634bfcSVikram Hegde IMMU_CONT_UNINITED = 0x1, 2003a634bfcSVikram Hegde IMMU_CONT_INITED = 0x2 2013a634bfcSVikram Hegde } cont_avail_t; 2023a634bfcSVikram Hegde 2033a634bfcSVikram Hegde /* Size of root and context tables and their entries */ 2043a634bfcSVikram Hegde #define IMMU_ROOT_TBLSZ (4096) 2053a634bfcSVikram Hegde #define IMMU_CONT_TBLSZ (4096) 2063a634bfcSVikram Hegde #define IMMU_ROOT_NUM (256) 2073a634bfcSVikram Hegde #define IMMU_CONT_NUM (256) 2083a634bfcSVikram Hegde 2093a634bfcSVikram Hegde /* register offset */ 2103a634bfcSVikram Hegde #define IMMU_REG_VERSION (0x00) /* Version Rigister, 32 bit */ 2113a634bfcSVikram Hegde #define IMMU_REG_CAP (0x08) /* Capability Register, 64 bit */ 2123a634bfcSVikram Hegde #define IMMU_REG_EXCAP (0x10) /* Extended Capability Reg, 64 bit */ 2133a634bfcSVikram Hegde #define IMMU_REG_GLOBAL_CMD (0x18) /* Global Command Register, 32 bit */ 2143a634bfcSVikram Hegde #define IMMU_REG_GLOBAL_STS (0x1C) /* Global Status Register, 32 bit */ 2153a634bfcSVikram Hegde #define IMMU_REG_ROOTENTRY (0x20) /* Root-Entry Table Addr Reg, 64 bit */ 2163a634bfcSVikram Hegde #define IMMU_REG_CONTEXT_CMD (0x28) /* Context Comand Register, 64 bit */ 2173a634bfcSVikram Hegde #define IMMU_REG_FAULT_STS (0x34) /* Fault Status Register, 32 bit */ 2183a634bfcSVikram Hegde #define IMMU_REG_FEVNT_CON (0x38) /* Fault Event Control Reg, 32 bit */ 2193a634bfcSVikram Hegde #define IMMU_REG_FEVNT_DATA (0x3C) /* Fault Event Data Register, 32 bit */ 2203a634bfcSVikram Hegde #define IMMU_REG_FEVNT_ADDR (0x40) /* Fault Event Address Reg, 32 bit */ 2213a634bfcSVikram Hegde #define IMMU_REG_FEVNT_UADDR (0x44) /* Fault Event Upper Addr Reg, 32 bit */ 2223a634bfcSVikram Hegde #define IMMU_REG_AFAULT_LOG (0x58) /* Advanced Fault Log Reg, 64 bit */ 2233a634bfcSVikram Hegde #define IMMU_REG_PMER (0x64) /* Protected Memory Enble Reg, 32 bit */ 2243a634bfcSVikram Hegde #define IMMU_REG_PLMBR (0x68) /* Protected Low Mem Base Reg, 32 bit */ 2253a634bfcSVikram Hegde #define IMMU_REG_PLMLR (0x6C) /* Protected Low Mem Lim Reg, 32 bit */ 2263a634bfcSVikram Hegde #define IMMU_REG_PHMBR (0X70) /* Protectd High Mem Base Reg, 64 bit */ 2273a634bfcSVikram Hegde #define IMMU_REG_PHMLR (0x78) /* Protected High Mem Lim Reg, 64 bit */ 2283a634bfcSVikram Hegde #define IMMU_REG_INVAL_QH (0x80) /* Invalidation Queue Head, 64 bit */ 2293a634bfcSVikram Hegde #define IMMU_REG_INVAL_QT (0x88) /* Invalidation Queue Tail, 64 bit */ 2303a634bfcSVikram Hegde #define IMMU_REG_INVAL_QAR (0x90) /* Invalidtion Queue Addr Reg, 64 bit */ 2313a634bfcSVikram Hegde #define IMMU_REG_INVAL_CSR (0x9C) /* Inval Compl Status Reg, 32 bit */ 2323a634bfcSVikram Hegde #define IMMU_REG_INVAL_CECR (0xA0) /* Inval Compl Evnt Ctrl Reg, 32 bit */ 2333a634bfcSVikram Hegde #define IMMU_REG_INVAL_CEDR (0xA4) /* Inval Compl Evnt Data Reg, 32 bit */ 2343a634bfcSVikram Hegde #define IMMU_REG_INVAL_CEAR (0xA8) /* Inval Compl Event Addr Reg, 32 bit */ 2353a634bfcSVikram Hegde #define IMMU_REG_INVAL_CEUAR (0xAC) /* Inval Comp Evnt Up Addr reg, 32bit */ 2363a634bfcSVikram Hegde #define IMMU_REG_IRTAR (0xB8) /* INTR Remap Tbl Addr Reg, 64 bit */ 2373a634bfcSVikram Hegde 2383a634bfcSVikram Hegde /* ioapic memory region */ 2393a634bfcSVikram Hegde #define IOAPIC_REGION_START (0xfee00000) 2403a634bfcSVikram Hegde #define IOAPIC_REGION_END (0xfeefffff) 2413a634bfcSVikram Hegde 2423a634bfcSVikram Hegde /* fault register */ 2433a634bfcSVikram Hegde #define IMMU_FAULT_STS_PPF (2) 2443a634bfcSVikram Hegde #define IMMU_FAULT_STS_PFO (1) 2453a634bfcSVikram Hegde #define IMMU_FAULT_STS_ITE (1 << 6) 2463a634bfcSVikram Hegde #define IMMU_FAULT_STS_ICE (1 << 5) 2473a634bfcSVikram Hegde #define IMMU_FAULT_STS_IQE (1 << 4) 2483a634bfcSVikram Hegde #define IMMU_FAULT_GET_INDEX(x) ((((uint64_t)x) >> 8) & 0xff) 2493a634bfcSVikram Hegde #define IMMU_FRR_GET_F(x) (((uint64_t)x) >> 63) 2503a634bfcSVikram Hegde #define IMMU_FRR_GET_FR(x) ((((uint64_t)x) >> 32) & 0xff) 2513a634bfcSVikram Hegde #define IMMU_FRR_GET_FT(x) ((((uint64_t)x) >> 62) & 0x1) 2523a634bfcSVikram Hegde #define IMMU_FRR_GET_SID(x) ((x) & 0xffff) 2533a634bfcSVikram Hegde 2543a634bfcSVikram Hegde /* (ex)capability register */ 2553a634bfcSVikram Hegde #define IMMU_CAP_GET_NFR(x) (((((uint64_t)x) >> 40) & 0xff) + 1) 2563a634bfcSVikram Hegde #define IMMU_CAP_GET_DWD(x) ((((uint64_t)x) >> 54) & 1) 2573a634bfcSVikram Hegde #define IMMU_CAP_GET_DRD(x) ((((uint64_t)x) >> 55) & 1) 2583a634bfcSVikram Hegde #define IMMU_CAP_GET_PSI(x) ((((uint64_t)x) >> 39) & 1) 2593a634bfcSVikram Hegde #define IMMU_CAP_GET_SPS(x) ((((uint64_t)x) >> 34) & 0xf) 2603a634bfcSVikram Hegde #define IMMU_CAP_GET_ISOCH(x) ((((uint64_t)x) >> 23) & 1) 2613a634bfcSVikram Hegde #define IMMU_CAP_GET_ZLR(x) ((((uint64_t)x) >> 22) & 1) 2623a634bfcSVikram Hegde #define IMMU_CAP_GET_MAMV(x) ((((uint64_t)x) >> 48) & 0x3f) 2633a634bfcSVikram Hegde #define IMMU_CAP_GET_CM(x) ((((uint64_t)x) >> 7) & 1) 2643a634bfcSVikram Hegde #define IMMU_CAP_GET_PHMR(x) ((((uint64_t)x) >> 6) & 1) 2653a634bfcSVikram Hegde #define IMMU_CAP_GET_PLMR(x) ((((uint64_t)x) >> 5) & 1) 2663a634bfcSVikram Hegde #define IMMU_CAP_GET_RWBF(x) ((((uint64_t)x) >> 4) & 1) 2673a634bfcSVikram Hegde #define IMMU_CAP_GET_AFL(x) ((((uint64_t)x) >> 3) & 1) 2683a634bfcSVikram Hegde #define IMMU_CAP_GET_FRO(x) (((((uint64_t)x) >> 24) & 0x3ff) * 16) 2693a634bfcSVikram Hegde #define IMMU_CAP_MGAW(x) (((((uint64_t)x) >> 16) & 0x3f) + 1) 2703a634bfcSVikram Hegde #define IMMU_CAP_SAGAW(x) ((((uint64_t)x) >> 8) & 0x1f) 2713a634bfcSVikram Hegde #define IMMU_CAP_ND(x) (1 << (((x) & 0x7) *2 + 4)) -1 2723a634bfcSVikram Hegde #define IMMU_ECAP_GET_IRO(x) (((((uint64_t)x) >> 8) & 0x3ff) << 4) 2733a634bfcSVikram Hegde #define IMMU_ECAP_GET_MHMV(x) (((uint64_t)x >> 20) & 0xf) 2743a634bfcSVikram Hegde #define IMMU_ECAP_GET_SC(x) ((x) & 0x80) 2753a634bfcSVikram Hegde #define IMMU_ECAP_GET_PT(x) ((x) & 0x40) 2763a634bfcSVikram Hegde #define IMMU_ECAP_GET_CH(x) ((x) & 0x20) 2773a634bfcSVikram Hegde #define IMMU_ECAP_GET_EIM(x) ((x) & 0x10) 2783a634bfcSVikram Hegde #define IMMU_ECAP_GET_IR(x) ((x) & 0x8) 2793a634bfcSVikram Hegde #define IMMU_ECAP_GET_DI(x) ((x) & 0x4) 2803a634bfcSVikram Hegde #define IMMU_ECAP_GET_QI(x) ((x) & 0x2) 2813a634bfcSVikram Hegde #define IMMU_ECAP_GET_C(x) ((x) & 0x1) 2823a634bfcSVikram Hegde 2833a634bfcSVikram Hegde #define IMMU_CAP_SET_RWBF(x) ((x) |= (1 << 4)) 2843a634bfcSVikram Hegde 2853a634bfcSVikram Hegde 2863a634bfcSVikram Hegde /* iotlb invalidation */ 2873a634bfcSVikram Hegde #define TLB_INV_GLOBAL (((uint64_t)1) << 60) 2883a634bfcSVikram Hegde #define TLB_INV_DOMAIN (((uint64_t)2) << 60) 2893a634bfcSVikram Hegde #define TLB_INV_PAGE (((uint64_t)3) << 60) 2903a634bfcSVikram Hegde #define TLB_INV_GET_IAIG(x) ((((uint64_t)x) >> 57) & 7) 2913a634bfcSVikram Hegde #define TLB_INV_DRAIN_READ (((uint64_t)1) << 49) 2923a634bfcSVikram Hegde #define TLB_INV_DRAIN_WRITE (((uint64_t)1) << 48) 2933a634bfcSVikram Hegde #define TLB_INV_DID(x) (((uint64_t)((x) & 0xffff)) << 32) 2943a634bfcSVikram Hegde #define TLB_INV_IVT (((uint64_t)1) << 63) 2953a634bfcSVikram Hegde #define TLB_IVA_HINT(x) (((x) & 0x1) << 6) 2963a634bfcSVikram Hegde #define TLB_IVA_LEAF 1 2973a634bfcSVikram Hegde #define TLB_IVA_WHOLE 0 2983a634bfcSVikram Hegde 2993a634bfcSVikram Hegde /* dont use value 0 for enums - to catch unit 8 */ 3003a634bfcSVikram Hegde typedef enum iotlb_inv { 3013a634bfcSVikram Hegde IOTLB_PSI = 1, 3023a634bfcSVikram Hegde IOTLB_DSI, 3033a634bfcSVikram Hegde IOTLB_GLOBAL 3043a634bfcSVikram Hegde } immu_iotlb_inv_t; 3053a634bfcSVikram Hegde 3063a634bfcSVikram Hegde typedef enum context_inv { 3073a634bfcSVikram Hegde CONTEXT_FSI = 1, 3083a634bfcSVikram Hegde CONTEXT_DSI, 3093a634bfcSVikram Hegde CONTEXT_GLOBAL 3103a634bfcSVikram Hegde } immu_context_inv_t; 3113a634bfcSVikram Hegde 3123a634bfcSVikram Hegde /* context invalidation */ 3133a634bfcSVikram Hegde #define CCMD_INV_ICC (((uint64_t)1) << 63) 3143a634bfcSVikram Hegde #define CCMD_INV_GLOBAL (((uint64_t)1) << 61) 3153a634bfcSVikram Hegde #define CCMD_INV_DOMAIN (((uint64_t)2) << 61) 3163a634bfcSVikram Hegde #define CCMD_INV_DEVICE (((uint64_t)3) << 61) 3173a634bfcSVikram Hegde #define CCMD_INV_DID(x) ((uint64_t)((x) & 0xffff)) 3183a634bfcSVikram Hegde #define CCMD_INV_SID(x) (((uint64_t)((x) & 0xffff)) << 16) 3193a634bfcSVikram Hegde #define CCMD_INV_FM(x) (((uint64_t)((x) & 0x3)) << 32) 3203a634bfcSVikram Hegde 3213a634bfcSVikram Hegde /* global command register */ 3223a634bfcSVikram Hegde #define IMMU_GCMD_TE (((uint32_t)1) << 31) 3233a634bfcSVikram Hegde #define IMMU_GCMD_SRTP (((uint32_t)1) << 30) 3243a634bfcSVikram Hegde #define IMMU_GCMD_SFL (((uint32_t)1) << 29) 3253a634bfcSVikram Hegde #define IMMU_GCMD_EAFL (((uint32_t)1) << 28) 3263a634bfcSVikram Hegde #define IMMU_GCMD_WBF (((uint32_t)1) << 27) 3273a634bfcSVikram Hegde #define IMMU_GCMD_QIE (((uint32_t)1) << 26) 3283a634bfcSVikram Hegde #define IMMU_GCMD_IRE (((uint32_t)1) << 25) 3293a634bfcSVikram Hegde #define IMMU_GCMD_SIRTP (((uint32_t)1) << 24) 3303a634bfcSVikram Hegde #define IMMU_GCMD_CFI (((uint32_t)1) << 23) 3313a634bfcSVikram Hegde 3323a634bfcSVikram Hegde /* global status register */ 3333a634bfcSVikram Hegde #define IMMU_GSTS_TES (((uint32_t)1) << 31) 3343a634bfcSVikram Hegde #define IMMU_GSTS_RTPS (((uint32_t)1) << 30) 3353a634bfcSVikram Hegde #define IMMU_GSTS_FLS (((uint32_t)1) << 29) 3363a634bfcSVikram Hegde #define IMMU_GSTS_AFLS (((uint32_t)1) << 28) 3373a634bfcSVikram Hegde #define IMMU_GSTS_WBFS (((uint32_t)1) << 27) 3383a634bfcSVikram Hegde #define IMMU_GSTS_QIES (((uint32_t)1) << 26) 3393a634bfcSVikram Hegde #define IMMU_GSTS_IRES (((uint32_t)1) << 25) 3403a634bfcSVikram Hegde #define IMMU_GSTS_IRTPS (((uint32_t)1) << 24) 3413a634bfcSVikram Hegde #define IMMU_GSTS_CFIS (((uint32_t)1) << 23) 3423a634bfcSVikram Hegde 3433a634bfcSVikram Hegde /* psi address mask */ 3443a634bfcSVikram Hegde #define ADDR_AM_MAX(m) (((uint_t)1) << (m)) 3453a634bfcSVikram Hegde #define ADDR_AM_OFFSET(n, m) ((n) & (ADDR_AM_MAX(m) - 1)) 3463a634bfcSVikram Hegde 3473a634bfcSVikram Hegde /* dmar fault event */ 348e03dceedSVikram Hegde #define IMMU_INTR_IPL (4) 3493a634bfcSVikram Hegde #define IMMU_REG_FEVNT_CON_IM_SHIFT (31) 3503a634bfcSVikram Hegde 3513a634bfcSVikram Hegde #define IMMU_ALLOC_RESOURCE_DELAY (drv_usectohz(5000)) 3523a634bfcSVikram Hegde 3533a634bfcSVikram Hegde /* max value of Size field of Interrupt Remapping Table Address Register */ 3543a634bfcSVikram Hegde #define INTRMAP_MAX_IRTA_SIZE 0xf 3553a634bfcSVikram Hegde 3563a634bfcSVikram Hegde /* interrupt remapping table entry size */ 3573a634bfcSVikram Hegde #define INTRMAP_RTE_SIZE 0x10 3583a634bfcSVikram Hegde 3593a634bfcSVikram Hegde /* ioapic redirection table entry related shift of remappable interrupt */ 3603a634bfcSVikram Hegde #define INTRMAP_IOAPIC_IDX_SHIFT 17 3613a634bfcSVikram Hegde #define INTRMAP_IOAPIC_FORMAT_SHIFT 16 3623a634bfcSVikram Hegde #define INTRMAP_IOAPIC_TM_SHIFT 15 3633a634bfcSVikram Hegde #define INTRMAP_IOAPIC_POL_SHIFT 13 3643a634bfcSVikram Hegde #define INTRMAP_IOAPIC_IDX15_SHIFT 11 3653a634bfcSVikram Hegde 3663a634bfcSVikram Hegde /* msi intr entry related shift of remappable interrupt */ 3673a634bfcSVikram Hegde #define INTRMAP_MSI_IDX_SHIFT 5 3683a634bfcSVikram Hegde #define INTRMAP_MSI_FORMAT_SHIFT 4 3693a634bfcSVikram Hegde #define INTRMAP_MSI_SHV_SHIFT 3 3703a634bfcSVikram Hegde #define INTRMAP_MSI_IDX15_SHIFT 2 3713a634bfcSVikram Hegde 3723a634bfcSVikram Hegde #define INTRMAP_IDX_FULL (uint_t)-1 3733a634bfcSVikram Hegde 3743a634bfcSVikram Hegde #define RDT_DLM(rdt) BITX((rdt), 10, 8) 3753a634bfcSVikram Hegde #define RDT_DM(rdt) BT_TEST(&(rdt), 11) 3763a634bfcSVikram Hegde #define RDT_POL(rdt) BT_TEST(&(rdt), 13) 3773a634bfcSVikram Hegde #define RDT_TM(rdt) BT_TEST(&(rdt), 15) 3783a634bfcSVikram Hegde 3793a634bfcSVikram Hegde #define INTRMAP_DISABLE (void *)-1 3803a634bfcSVikram Hegde 3813a634bfcSVikram Hegde /* 3823a634bfcSVikram Hegde * invalidation granularity 3833a634bfcSVikram Hegde */ 3843a634bfcSVikram Hegde typedef enum { 3853a634bfcSVikram Hegde TLB_INV_G_GLOBAL = 1, 3863a634bfcSVikram Hegde TLB_INV_G_DOMAIN, 3873a634bfcSVikram Hegde TLB_INV_G_PAGE 3883a634bfcSVikram Hegde } tlb_inv_g_t; 3893a634bfcSVikram Hegde 3903a634bfcSVikram Hegde typedef enum { 3913a634bfcSVikram Hegde CTT_INV_G_GLOBAL = 1, 3923a634bfcSVikram Hegde CTT_INV_G_DOMAIN, 3933a634bfcSVikram Hegde CTT_INV_G_DEVICE 3943a634bfcSVikram Hegde } ctt_inv_g_t; 3953a634bfcSVikram Hegde 3963a634bfcSVikram Hegde typedef enum { 3973a634bfcSVikram Hegde IEC_INV_GLOBAL = 0, 3983a634bfcSVikram Hegde IEC_INV_INDEX 3993a634bfcSVikram Hegde } iec_inv_g_t; 4003a634bfcSVikram Hegde 4013a634bfcSVikram Hegde 4023a634bfcSVikram Hegde struct inv_queue_state; 4033a634bfcSVikram Hegde struct intrmap_tbl_state; 4043a634bfcSVikram Hegde 4053a634bfcSVikram Hegde /* A software page table structure */ 4063a634bfcSVikram Hegde typedef struct pgtable { 4073a634bfcSVikram Hegde krwlock_t swpg_rwlock; 4083a634bfcSVikram Hegde caddr_t hwpg_vaddr; /* HW pgtable VA */ 4093a634bfcSVikram Hegde paddr_t hwpg_paddr; /* HW pgtable PA */ 4103a634bfcSVikram Hegde ddi_dma_handle_t hwpg_dmahdl; 4113a634bfcSVikram Hegde ddi_acc_handle_t hwpg_memhdl; 4123a634bfcSVikram Hegde struct pgtable **swpg_next_array; 4133a634bfcSVikram Hegde list_node_t swpg_domain_node; /* domain list of pgtables */ 4143a634bfcSVikram Hegde } pgtable_t; 4153a634bfcSVikram Hegde 4163a634bfcSVikram Hegde /* interrupt remapping table state info */ 4173a634bfcSVikram Hegde typedef struct intrmap { 4183a634bfcSVikram Hegde kmutex_t intrmap_lock; 4193a634bfcSVikram Hegde ddi_dma_handle_t intrmap_dma_hdl; 4203a634bfcSVikram Hegde ddi_acc_handle_t intrmap_acc_hdl; 4213a634bfcSVikram Hegde caddr_t intrmap_vaddr; 4223a634bfcSVikram Hegde paddr_t intrmap_paddr; 4233a634bfcSVikram Hegde uint_t intrmap_size; 4243a634bfcSVikram Hegde bitset_t intrmap_map; 4253a634bfcSVikram Hegde uint_t intrmap_free; 4263a634bfcSVikram Hegde } intrmap_t; 4273a634bfcSVikram Hegde 4283a634bfcSVikram Hegde typedef struct hw_rce { 4293a634bfcSVikram Hegde uint64_t lo; 4303a634bfcSVikram Hegde uint64_t hi; 4313a634bfcSVikram Hegde } hw_rce_t; 4323a634bfcSVikram Hegde 4333a634bfcSVikram Hegde 4343a634bfcSVikram Hegde #define ROOT_GET_P(hrent) ((hrent)->lo & 0x1) 4353a634bfcSVikram Hegde #define ROOT_SET_P(hrent) ((hrent)->lo |= 0x1) 4363a634bfcSVikram Hegde 4373a634bfcSVikram Hegde #define ROOT_GET_CONT(hrent) ((hrent)->lo & ~(0xFFF)) 4383a634bfcSVikram Hegde #define ROOT_SET_CONT(hrent, paddr) ((hrent)->lo |= (paddr & (~0xFFF))) 4393a634bfcSVikram Hegde 4403a634bfcSVikram Hegde #define TTYPE_XLATE_ONLY (0x0) 4413a634bfcSVikram Hegde #define TTYPE_XLATE_IOTLB (0x1) 4423a634bfcSVikram Hegde #define TTYPE_PASSTHRU (0x2) 4433a634bfcSVikram Hegde #define TTYPE_RESERVED (0x3) 4443a634bfcSVikram Hegde 4453a634bfcSVikram Hegde #define CONT_GET_DID(hcent) ((((uint64_t)(hcent)->hi) >> 8) & 0xFFFF) 4463a634bfcSVikram Hegde #define CONT_SET_DID(hcent, did) ((hcent)->hi |= ((0xFFFF & (did)) << 8)) 4473a634bfcSVikram Hegde 4483a634bfcSVikram Hegde #define CONT_GET_AVAIL(hcent) ((((uint64_t)((hcent)->hi)) >> 0x3) & 0xF) 4493a634bfcSVikram Hegde #define CONT_SET_AVAIL(hcent, av) ((hcent)->hi |= ((0xF & (av)) << 0x3)) 4503a634bfcSVikram Hegde 4513a634bfcSVikram Hegde #define CONT_GET_LO_AW(hcent) (30 + 9 *((hcent)->hi & 0x7)) 4523a634bfcSVikram Hegde #define CONT_GET_AW(hcent) \ 4533a634bfcSVikram Hegde ((CONT_GET_LO_AW(hcent) == 66) ? 64 : CONT_GET_LO_AW(hcent)) 4543a634bfcSVikram Hegde #define CONT_SET_AW(hcent, aw) \ 4553a634bfcSVikram Hegde ((hcent)->hi |= (((((aw) + 2) - 30) / 9) & 0x7)) 4563a634bfcSVikram Hegde 4573a634bfcSVikram Hegde #define CONT_GET_ASR(hcent) ((hcent)->lo & ~(0xFFF)) 4583a634bfcSVikram Hegde #define CONT_SET_ASR(hcent, paddr) ((hcent)->lo |= (paddr & (~0xFFF))) 4593a634bfcSVikram Hegde 4603a634bfcSVikram Hegde #define CONT_GET_TTYPE(hcent) ((((uint64_t)(hcent)->lo) >> 0x2) & 0x3) 4613a634bfcSVikram Hegde #define CONT_SET_TTYPE(hcent, ttype) ((hcent)->lo |= (((ttype) & 0x3) << 0x2)) 4623a634bfcSVikram Hegde 4633a634bfcSVikram Hegde #define CONT_GET_P(hcent) ((hcent)->lo & 0x1) 4643a634bfcSVikram Hegde #define CONT_SET_P(hcent) ((hcent)->lo |= 0x1) 4653a634bfcSVikram Hegde 466*50200e77SFrank Van Der Linden #define CONT_GET_ALH(hcent) ((hcent)->lo & 0x20) 467*50200e77SFrank Van Der Linden #define CONT_SET_ALH(hcent) ((hcent)->lo |= 0x20) 468*50200e77SFrank Van Der Linden 469*50200e77SFrank Van Der Linden #define CONT_GET_EH(hcent) ((hcent)->lo & 0x10) 470*50200e77SFrank Van Der Linden #define CONT_SET_EH(hcent) ((hcent)->lo |= 0x10) 471*50200e77SFrank Van Der Linden 4723a634bfcSVikram Hegde 4733a634bfcSVikram Hegde /* we use the bit 63 (available for system SW) as a present bit */ 4743a634bfcSVikram Hegde #define PDTE_SW4(hw_pdte) ((hw_pdte) & ((uint64_t)1<<63)) 4753a634bfcSVikram Hegde #define PDTE_CLEAR_SW4(hw_pdte) ((hw_pdte) &= ~((uint64_t)1<<63)) 4763a634bfcSVikram Hegde 4773a634bfcSVikram Hegde #define PDTE_P(hw_pdte) ((hw_pdte) & ((uint64_t)1<<63)) 4783a634bfcSVikram Hegde #define PDTE_CLEAR_P(hw_pdte) ((hw_pdte) &= ~((uint64_t)1<<63)) 4793a634bfcSVikram Hegde #define PDTE_SET_P(hw_pdte) ((hw_pdte) |= ((uint64_t)1<<63)) 4803a634bfcSVikram Hegde 4813a634bfcSVikram Hegde #define PDTE_TM(hw_pdte) ((hw_pdte) & ((uint64_t)1<<62)) 4823a634bfcSVikram Hegde #define PDTE_CLEAR_TM(hw_pdte) ((hw_pdte) &= ~((uint64_t)1<<62)) 4833a634bfcSVikram Hegde 4843a634bfcSVikram Hegde #define PDTE_SW3(hw_pdte) \ 4853a634bfcSVikram Hegde (((hw_pdte) & ~(((uint64_t)0x3<<62)|(((uint64_t)1<<52)-1))) >> 52) 4863a634bfcSVikram Hegde #define PDTE_SW3_OVERFLOW(hw_pdte) \ 4873a634bfcSVikram Hegde (PDTE_SW3(hw_pdte) == 0x3FF) 4883a634bfcSVikram Hegde #define PDTE_CLEAR_SW3(hw_pdte) \ 4893a634bfcSVikram Hegde ((hw_pdte) &= (((uint64_t)0x3<<62)|(((uint64_t)1<<52)-1))) 4903a634bfcSVikram Hegde #define PDTE_SET_SW3(hw_pdte, ref) \ 4913a634bfcSVikram Hegde ((hw_pdte) |= ((((uint64_t)(ref)) & 0x3FF) << 52)) 4923a634bfcSVikram Hegde 4933a634bfcSVikram Hegde #define PDTE_PADDR(hw_pdte) ((hw_pdte) & ~(((uint64_t)0xFFF<<52)|((1<<12)-1))) 4943a634bfcSVikram Hegde #define PDTE_CLEAR_PADDR(hw_pdte) \ 4953a634bfcSVikram Hegde ((hw_pdte) &= (((uint64_t)0xFFF<<52)|((1<<12)-1))) 4963a634bfcSVikram Hegde #define PDTE_SET_PADDR(hw_pdte, paddr) ((hw_pdte) |= PDTE_PADDR(paddr)) 4973a634bfcSVikram Hegde 4983a634bfcSVikram Hegde #define PDTE_SNP(hw_pdte) ((hw_pdte) & (1<<11)) 4993a634bfcSVikram Hegde #define PDTE_CLEAR_SNP(hw_pdte) ((hw_pdte) &= ~(1<<11)) 5003a634bfcSVikram Hegde #define PDTE_SET_SNP(hw_pdte) ((hw_pdte) |= (1<<11)) 5013a634bfcSVikram Hegde 5023a634bfcSVikram Hegde #define PDTE_SW2(hw_pdte) ((hw_pdte) & (0x700)) 5033a634bfcSVikram Hegde #define PDTE_CLEAR_SW2(hw_pdte) ((hw_pdte) &= ~(0x700)) 5043a634bfcSVikram Hegde 5053a634bfcSVikram Hegde #define PDTE_SP(hw_pdte) ((hw_pdte) & (0x80)) 5063a634bfcSVikram Hegde #define PDTE_CLEAR_SP(hw_pdte) ((hw_pdte) &= ~(0x80)) 5073a634bfcSVikram Hegde 5083a634bfcSVikram Hegde #define PDTE_SW1(hw_pdte) ((hw_pdte) & (0x7C)) 5093a634bfcSVikram Hegde #define PDTE_CLEAR_SW1(hw_pdte) ((hw_pdte) &= ~(0x7C)) 5103a634bfcSVikram Hegde 5113a634bfcSVikram Hegde #define PDTE_WRITE(hw_pdte) ((hw_pdte) & (0x2)) 5123a634bfcSVikram Hegde #define PDTE_CLEAR_WRITE(hw_pdte) ((hw_pdte) &= ~(0x2)) 5133a634bfcSVikram Hegde #define PDTE_SET_WRITE(hw_pdte) ((hw_pdte) |= (0x2)) 5143a634bfcSVikram Hegde 5153a634bfcSVikram Hegde #define PDTE_READ(hw_pdte) ((hw_pdte) & (0x1)) 5163a634bfcSVikram Hegde #define PDTE_CLEAR_READ(hw_pdte) ((hw_pdte) &= ~(0x1)) 5173a634bfcSVikram Hegde #define PDTE_SET_READ(hw_pdte) ((hw_pdte) |= (0x1)) 5183a634bfcSVikram Hegde 519*50200e77SFrank Van Der Linden #define PDTE_MASK_R ((uint64_t)1 << 0) 520*50200e77SFrank Van Der Linden #define PDTE_MASK_W ((uint64_t)1 << 1) 521*50200e77SFrank Van Der Linden #define PDTE_MASK_SNP ((uint64_t)1 << 11) 522*50200e77SFrank Van Der Linden #define PDTE_MASK_TM ((uint64_t)1 << 62) 523*50200e77SFrank Van Der Linden #define PDTE_MASK_P ((uint64_t)1 << 63) 524*50200e77SFrank Van Der Linden 525c94adbf9SFrank Van Der Linden struct immu_flushops; 526c94adbf9SFrank Van Der Linden 527*50200e77SFrank Van Der Linden /* 528*50200e77SFrank Van Der Linden * Used to wait for invalidation completion. 529*50200e77SFrank Van Der Linden * vstatus is the virtual address of the status word that will be written 530*50200e77SFrank Van Der Linden * pstatus is the physical addres 531*50200e77SFrank Van Der Linden * If sync is true, then the the operation will be waited on for 532*50200e77SFrank Van Der Linden * completion immediately. Else, the wait interface can be called 533*50200e77SFrank Van Der Linden * to wait for completion later. 534*50200e77SFrank Van Der Linden */ 535*50200e77SFrank Van Der Linden 536*50200e77SFrank Van Der Linden #define IMMU_INV_DATA_PENDING 1 537*50200e77SFrank Van Der Linden #define IMMU_INV_DATA_DONE 2 538*50200e77SFrank Van Der Linden 539*50200e77SFrank Van Der Linden typedef struct immu_inv_wait { 540*50200e77SFrank Van Der Linden volatile uint32_t iwp_vstatus; 541*50200e77SFrank Van Der Linden uint64_t iwp_pstatus; 542*50200e77SFrank Van Der Linden boolean_t iwp_sync; 543*50200e77SFrank Van Der Linden const char *iwp_name; /* ID for debugging/statistics */ 544*50200e77SFrank Van Der Linden } immu_inv_wait_t; 545*50200e77SFrank Van Der Linden 546*50200e77SFrank Van Der Linden /* 547*50200e77SFrank Van Der Linden * Used to batch IOMMU pagetable writes. 548*50200e77SFrank Van Der Linden */ 549*50200e77SFrank Van Der Linden typedef struct immu_dcookie { 550*50200e77SFrank Van Der Linden paddr_t dck_paddr; 551*50200e77SFrank Van Der Linden uint64_t dck_npages; 552*50200e77SFrank Van Der Linden } immu_dcookie_t; 553*50200e77SFrank Van Der Linden 5543a634bfcSVikram Hegde typedef struct immu { 5553a634bfcSVikram Hegde kmutex_t immu_lock; 5563a634bfcSVikram Hegde char *immu_name; 5573a634bfcSVikram Hegde 5583a634bfcSVikram Hegde /* lock grabbed by interrupt handler */ 5593a634bfcSVikram Hegde kmutex_t immu_intr_lock; 5603a634bfcSVikram Hegde 5613a634bfcSVikram Hegde /* ACPI/DMAR table related */ 5623a634bfcSVikram Hegde void *immu_dmar_unit; 5633a634bfcSVikram Hegde dev_info_t *immu_dip; 5643a634bfcSVikram Hegde struct domain *immu_unity_domain; 5653a634bfcSVikram Hegde 5663a634bfcSVikram Hegde /* IOMMU register related */ 5673a634bfcSVikram Hegde kmutex_t immu_regs_lock; 568e03dceedSVikram Hegde kcondvar_t immu_regs_cv; 569e03dceedSVikram Hegde boolean_t immu_regs_busy; 5703a634bfcSVikram Hegde boolean_t immu_regs_setup; 5713a634bfcSVikram Hegde boolean_t immu_regs_running; 5723a634bfcSVikram Hegde boolean_t immu_regs_quiesced; 5733a634bfcSVikram Hegde ddi_acc_handle_t immu_regs_handle; 5743a634bfcSVikram Hegde caddr_t immu_regs_addr; 5753a634bfcSVikram Hegde uint64_t immu_regs_cap; 5763a634bfcSVikram Hegde uint64_t immu_regs_excap; 5773a634bfcSVikram Hegde uint32_t immu_regs_cmdval; 5783a634bfcSVikram Hegde uint32_t immu_regs_intr_msi_addr; 5793a634bfcSVikram Hegde uint32_t immu_regs_intr_msi_data; 5803a634bfcSVikram Hegde uint32_t immu_regs_intr_uaddr; 5813a634bfcSVikram Hegde 5823a634bfcSVikram Hegde /* DVMA related */ 5833a634bfcSVikram Hegde kmutex_t immu_dvma_lock; 5843a634bfcSVikram Hegde boolean_t immu_dvma_setup; 5853a634bfcSVikram Hegde boolean_t immu_dvma_running; 5863a634bfcSVikram Hegde int immu_dvma_gaw; 5873a634bfcSVikram Hegde int immu_dvma_agaw; 5883a634bfcSVikram Hegde int immu_dvma_nlevels; 5893a634bfcSVikram Hegde boolean_t immu_dvma_coherent; 590e03dceedSVikram Hegde boolean_t immu_TM_reserved; 591e03dceedSVikram Hegde boolean_t immu_SNP_reserved; 592*50200e77SFrank Van Der Linden uint64_t immu_ptemask; 5933a634bfcSVikram Hegde 5943a634bfcSVikram Hegde /* DVMA context related */ 5953a634bfcSVikram Hegde krwlock_t immu_ctx_rwlock; 5963a634bfcSVikram Hegde pgtable_t *immu_ctx_root; 597*50200e77SFrank Van Der Linden immu_inv_wait_t immu_ctx_inv_wait; 5983a634bfcSVikram Hegde 5993a634bfcSVikram Hegde /* DVMA domain related */ 6003a634bfcSVikram Hegde int immu_max_domains; 6013a634bfcSVikram Hegde vmem_t *immu_did_arena; 6023a634bfcSVikram Hegde char immu_did_arena_name[IMMU_MAXNAMELEN]; 6033a634bfcSVikram Hegde list_t immu_domain_list; 6043a634bfcSVikram Hegde 6053a634bfcSVikram Hegde /* DVMA special devices */ 6063a634bfcSVikram Hegde boolean_t immu_dvma_gfx_only; 6073a634bfcSVikram Hegde list_t immu_dvma_lpc_list; 6083a634bfcSVikram Hegde list_t immu_dvma_gfx_list; 6093a634bfcSVikram Hegde 6103a634bfcSVikram Hegde /* interrupt remapping related */ 6113a634bfcSVikram Hegde kmutex_t immu_intrmap_lock; 6123a634bfcSVikram Hegde boolean_t immu_intrmap_setup; 6133a634bfcSVikram Hegde boolean_t immu_intrmap_running; 6143a634bfcSVikram Hegde intrmap_t *immu_intrmap; 6153a634bfcSVikram Hegde uint64_t immu_intrmap_irta_reg; 616*50200e77SFrank Van Der Linden immu_inv_wait_t immu_intrmap_inv_wait; 6173a634bfcSVikram Hegde 6183a634bfcSVikram Hegde /* queued invalidation related */ 6193a634bfcSVikram Hegde kmutex_t immu_qinv_lock; 6203a634bfcSVikram Hegde boolean_t immu_qinv_setup; 6213a634bfcSVikram Hegde boolean_t immu_qinv_running; 6223a634bfcSVikram Hegde boolean_t immu_qinv_enabled; 6233a634bfcSVikram Hegde void *immu_qinv; 6243a634bfcSVikram Hegde uint64_t immu_qinv_reg_value; 6253a634bfcSVikram Hegde 6263a634bfcSVikram Hegde /* list_node for system-wide list of DMAR units */ 6273a634bfcSVikram Hegde list_node_t immu_node; 628c94adbf9SFrank Van Der Linden 629c94adbf9SFrank Van Der Linden struct immu_flushops *immu_flushops; 630*50200e77SFrank Van Der Linden 631*50200e77SFrank Van Der Linden kmem_cache_t *immu_hdl_cache; 632*50200e77SFrank Van Der Linden kmem_cache_t *immu_pgtable_cache; 633*50200e77SFrank Van Der Linden 634*50200e77SFrank Van Der Linden iommulib_handle_t immu_iommulib_handle; 6353a634bfcSVikram Hegde } immu_t; 6363a634bfcSVikram Hegde 637*50200e77SFrank Van Der Linden /* 638*50200e77SFrank Van Der Linden * Enough space to hold the decimal number of any device instance. 639*50200e77SFrank Van Der Linden * Used for device/cache names. 640*50200e77SFrank Van Der Linden */ 641*50200e77SFrank Van Der Linden #define IMMU_ISTRLEN 11 /* log10(2^31) + 1 */ 642*50200e77SFrank Van Der Linden 6433a634bfcSVikram Hegde /* properties that control DVMA */ 6449e986f0eSFrank Van Der Linden #define DDI_DVMA_MAPTYPE_ROOTNEX_PROP "immu-dvma-mapping" 6453a634bfcSVikram Hegde 6463a634bfcSVikram Hegde #define DDI_DVMA_MAPTYPE_UNITY "unity" 6479e986f0eSFrank Van Der Linden #define DDI_DVMA_MAPTYPE_XLATE "xlate" 6483a634bfcSVikram Hegde 6493a634bfcSVikram Hegde typedef enum immu_maptype { 6503a634bfcSVikram Hegde IMMU_MAPTYPE_BAD = 0, /* 0 is always bad */ 6513a634bfcSVikram Hegde IMMU_MAPTYPE_UNITY = 1, 6523a634bfcSVikram Hegde IMMU_MAPTYPE_XLATE 6533a634bfcSVikram Hegde } immu_maptype_t; 6543a634bfcSVikram Hegde 655e03dceedSVikram Hegde #define IMMU_COOKIE_HASHSZ (512) 656e03dceedSVikram Hegde 6573a634bfcSVikram Hegde /* 6583a634bfcSVikram Hegde * domain_t 6593a634bfcSVikram Hegde * 6603a634bfcSVikram Hegde */ 6613a634bfcSVikram Hegde typedef struct domain { 6623a634bfcSVikram Hegde /* the basics */ 6633a634bfcSVikram Hegde uint_t dom_did; 6643a634bfcSVikram Hegde immu_t *dom_immu; 6653a634bfcSVikram Hegde 6663a634bfcSVikram Hegde /* mapping related */ 6673a634bfcSVikram Hegde immu_maptype_t dom_maptype; 6683a634bfcSVikram Hegde vmem_t *dom_dvma_arena; 6693a634bfcSVikram Hegde char dom_dvma_arena_name[IMMU_MAXNAMELEN]; 6703a634bfcSVikram Hegde 6713a634bfcSVikram Hegde /* pgtables */ 6723a634bfcSVikram Hegde pgtable_t *dom_pgtable_root; 6733a634bfcSVikram Hegde krwlock_t dom_pgtable_rwlock; 6743a634bfcSVikram Hegde 6753a634bfcSVikram Hegde /* list node for list of domains (unity or xlate) */ 6763a634bfcSVikram Hegde list_node_t dom_maptype_node; 6773a634bfcSVikram Hegde /* list node for list of domains off immu */ 6783a634bfcSVikram Hegde list_node_t dom_immu_node; 679e03dceedSVikram Hegde 680e03dceedSVikram Hegde mod_hash_t *dom_cookie_hash; 681*50200e77SFrank Van Der Linden 682*50200e77SFrank Van Der Linden /* topmost device in domain; usually the device itself (non-shared) */ 683*50200e77SFrank Van Der Linden dev_info_t *dom_dip; 6843a634bfcSVikram Hegde } domain_t; 6853a634bfcSVikram Hegde 6863a634bfcSVikram Hegde typedef enum immu_pcib { 6873a634bfcSVikram Hegde IMMU_PCIB_BAD = 0, 6883a634bfcSVikram Hegde IMMU_PCIB_NOBDF, 6893a634bfcSVikram Hegde IMMU_PCIB_PCIE_PCIE, 6903a634bfcSVikram Hegde IMMU_PCIB_PCIE_PCI, 6913a634bfcSVikram Hegde IMMU_PCIB_PCI_PCI, 6923a634bfcSVikram Hegde IMMU_PCIB_ENDPOINT 6933a634bfcSVikram Hegde } immu_pcib_t; 6943a634bfcSVikram Hegde 6953a634bfcSVikram Hegde /* 6963a634bfcSVikram Hegde * immu_devi_t 6973a634bfcSVikram Hegde * Intel IOMMU in devinfo node 6983a634bfcSVikram Hegde */ 6993a634bfcSVikram Hegde typedef struct immu_devi { 7003a634bfcSVikram Hegde /* pci seg, bus, dev, func */ 7013a634bfcSVikram Hegde int imd_seg; 7023a634bfcSVikram Hegde int imd_bus; 7033a634bfcSVikram Hegde int imd_devfunc; 7043a634bfcSVikram Hegde 7053a634bfcSVikram Hegde /* ppb information */ 7063a634bfcSVikram Hegde immu_pcib_t imd_pcib_type; 7073a634bfcSVikram Hegde int imd_sec; 7083a634bfcSVikram Hegde int imd_sub; 7093a634bfcSVikram Hegde 7103a634bfcSVikram Hegde /* identifier for special devices */ 7113a634bfcSVikram Hegde boolean_t imd_display; 7123a634bfcSVikram Hegde boolean_t imd_lpc; 7133a634bfcSVikram Hegde 714*50200e77SFrank Van Der Linden /* set if premapped DVMA space is used */ 715*50200e77SFrank Van Der Linden boolean_t imd_use_premap; 716*50200e77SFrank Van Der Linden 7173a634bfcSVikram Hegde /* dmar unit to which this dip belongs */ 7183a634bfcSVikram Hegde immu_t *imd_immu; 7193a634bfcSVikram Hegde 7209e986f0eSFrank Van Der Linden immu_flags_t imd_dvma_flags; 7219e986f0eSFrank Van Der Linden 7223a634bfcSVikram Hegde /* domain ptr */ 7233a634bfcSVikram Hegde domain_t *imd_domain; 7243a634bfcSVikram Hegde dev_info_t *imd_ddip; 7253a634bfcSVikram Hegde 7263a634bfcSVikram Hegde /* my devinfo */ 7273a634bfcSVikram Hegde dev_info_t *imd_dip; 7283a634bfcSVikram Hegde 7293a634bfcSVikram Hegde /* 7303a634bfcSVikram Hegde * if we are a "special" devinfo 7313a634bfcSVikram Hegde * the node for the special linked list 7323a634bfcSVikram Hegde * off the DMAR unit structure 7333a634bfcSVikram Hegde */ 7343a634bfcSVikram Hegde list_node_t imd_spc_node; 7353a634bfcSVikram Hegde } immu_devi_t; 7363a634bfcSVikram Hegde 7373a634bfcSVikram Hegde #define IMMU_DEVI(dip) ((immu_devi_t *)(DEVI(dip)->devi_iommu)) 7383a634bfcSVikram Hegde #define IMMU_DEVI_SET(dip, imd) (DEVI(dip)->devi_iommu = (void *)imd) 7393a634bfcSVikram Hegde 7403a634bfcSVikram Hegde /* 7413a634bfcSVikram Hegde * struct dmar_arg 7423a634bfcSVikram Hegde */ 7433a634bfcSVikram Hegde typedef struct immu_arg { 7443a634bfcSVikram Hegde int ima_seg; 7453a634bfcSVikram Hegde int ima_bus; 7463a634bfcSVikram Hegde int ima_devfunc; 7473a634bfcSVikram Hegde dev_info_t *ima_rdip; 7483a634bfcSVikram Hegde dev_info_t *ima_ddip; 7493a634bfcSVikram Hegde } immu_arg_t; 7503a634bfcSVikram Hegde 751*50200e77SFrank Van Der Linden #define IMMU_NDVSEG 8 752*50200e77SFrank Van Der Linden #define IMMU_NDCK 64 753*50200e77SFrank Van Der Linden #define IMMU_NPREPTES 8 754*50200e77SFrank Van Der Linden 755*50200e77SFrank Van Der Linden typedef struct immu_hdl_private { 756*50200e77SFrank Van Der Linden immu_inv_wait_t ihp_inv_wait; 757*50200e77SFrank Van Der Linden size_t ihp_ndvseg; 758*50200e77SFrank Van Der Linden struct dvmaseg ihp_dvseg[IMMU_NDVSEG]; 759*50200e77SFrank Van Der Linden immu_dcookie_t ihp_dcookies[IMMU_NDCK]; 760*50200e77SFrank Van Der Linden 761*50200e77SFrank Van Der Linden hw_pdte_t *ihp_preptes[IMMU_NPREPTES]; 762*50200e77SFrank Van Der Linden uint64_t ihp_predvma; 763*50200e77SFrank Van Der Linden int ihp_npremapped; 764*50200e77SFrank Van Der Linden } immu_hdl_priv_t; 765*50200e77SFrank Van Der Linden 7663a634bfcSVikram Hegde /* 767c94adbf9SFrank Van Der Linden * Invalidation operation function pointers for context and IOTLB. 768c94adbf9SFrank Van Der Linden * These will be set to either the register or the queue invalidation 769c94adbf9SFrank Van Der Linden * interface functions, since the hardware does not allow using them 770c94adbf9SFrank Van Der Linden * both at the same time. 771c94adbf9SFrank Van Der Linden */ 772c94adbf9SFrank Van Der Linden struct immu_flushops { 773*50200e77SFrank Van Der Linden void (*imf_context_fsi)(immu_t *, uint8_t, uint16_t, uint_t, 774*50200e77SFrank Van Der Linden immu_inv_wait_t *); 775*50200e77SFrank Van Der Linden void (*imf_context_dsi)(immu_t *, uint_t, immu_inv_wait_t *); 776*50200e77SFrank Van Der Linden void (*imf_context_gbl)(immu_t *, immu_inv_wait_t *); 777c94adbf9SFrank Van Der Linden 778*50200e77SFrank Van Der Linden void (*imf_iotlb_psi)(immu_t *, uint_t, uint64_t, uint_t, uint_t, 779*50200e77SFrank Van Der Linden immu_inv_wait_t *); 780*50200e77SFrank Van Der Linden void (*imf_iotlb_dsi)(immu_t *, uint_t, immu_inv_wait_t *); 781*50200e77SFrank Van Der Linden void (*imf_iotlb_gbl)(immu_t *, immu_inv_wait_t *); 782*50200e77SFrank Van Der Linden 783*50200e77SFrank Van Der Linden void (*imf_wait)(immu_inv_wait_t *); 784c94adbf9SFrank Van Der Linden }; 785c94adbf9SFrank Van Der Linden 786*50200e77SFrank Van Der Linden #define immu_flush_context_fsi(i, f, s, d, w) \ 787*50200e77SFrank Van Der Linden (i)->immu_flushops->imf_context_fsi(i, f, s, d, w) 788*50200e77SFrank Van Der Linden #define immu_flush_context_dsi(i, d, w) \ 789*50200e77SFrank Van Der Linden (i)->immu_flushops->imf_context_dsi(i, d, w) 790*50200e77SFrank Van Der Linden #define immu_flush_context_gbl(i, w) \ 791*50200e77SFrank Van Der Linden (i)->immu_flushops->imf_context_gbl(i, w) 792c94adbf9SFrank Van Der Linden 793*50200e77SFrank Van Der Linden #define immu_flush_iotlb_psi(i, d, v, c, h, w) \ 794*50200e77SFrank Van Der Linden (i)->immu_flushops->imf_iotlb_psi(i, d, v, c, h, w) 795*50200e77SFrank Van Der Linden #define immu_flush_iotlb_dsi(i, d, w) \ 796*50200e77SFrank Van Der Linden (i)->immu_flushops->imf_iotlb_dsi(i, d, w) 797*50200e77SFrank Van Der Linden #define immu_flush_iotlb_gbl(i, w) \ 798*50200e77SFrank Van Der Linden (i)->immu_flushops->imf_iotlb_gbl(i, w) 799*50200e77SFrank Van Der Linden 800*50200e77SFrank Van Der Linden #define immu_flush_wait(i, w) \ 801*50200e77SFrank Van Der Linden (i)->immu_flushops->imf_wait(w) 802c94adbf9SFrank Van Der Linden 803c94adbf9SFrank Van Der Linden /* 8043a634bfcSVikram Hegde * Globals used by IOMMU code 8053a634bfcSVikram Hegde */ 8063a634bfcSVikram Hegde /* shared between IOMMU files */ 8073a634bfcSVikram Hegde extern dev_info_t *root_devinfo; 8083a634bfcSVikram Hegde extern kmutex_t immu_lock; 8093a634bfcSVikram Hegde extern list_t immu_list; 8103a634bfcSVikram Hegde extern boolean_t immu_setup; 8113a634bfcSVikram Hegde extern boolean_t immu_running; 8123a634bfcSVikram Hegde extern kmutex_t ioapic_drhd_lock; 8133a634bfcSVikram Hegde extern list_t ioapic_drhd_list; 814*50200e77SFrank Van Der Linden extern struct iommulib_ops immulib_ops; 8153a634bfcSVikram Hegde 8163a634bfcSVikram Hegde /* switches */ 8173a634bfcSVikram Hegde 8183a634bfcSVikram Hegde /* Various features */ 8193a634bfcSVikram Hegde extern boolean_t immu_enable; 8203a634bfcSVikram Hegde extern boolean_t immu_gfxdvma_enable; 8213a634bfcSVikram Hegde extern boolean_t immu_intrmap_enable; 8223a634bfcSVikram Hegde extern boolean_t immu_qinv_enable; 8233a634bfcSVikram Hegde 8243a634bfcSVikram Hegde /* various quirks that need working around */ 8253a634bfcSVikram Hegde extern boolean_t immu_quirk_usbpage0; 8263a634bfcSVikram Hegde extern boolean_t immu_quirk_usbfullpa; 8273a634bfcSVikram Hegde extern boolean_t immu_quirk_usbrmrr; 8283a634bfcSVikram Hegde extern boolean_t immu_quirk_mobile4; 8293a634bfcSVikram Hegde 8303a634bfcSVikram Hegde /* debug messages */ 8313a634bfcSVikram Hegde extern boolean_t immu_dmar_print; 8323a634bfcSVikram Hegde 833e03dceedSVikram Hegde /* tunables */ 834e03dceedSVikram Hegde extern int64_t immu_flush_gran; 835e03dceedSVikram Hegde 8369e986f0eSFrank Van Der Linden extern immu_flags_t immu_global_dvma_flags; 8379e986f0eSFrank Van Der Linden 838*50200e77SFrank Van Der Linden extern int immu_use_tm; 839*50200e77SFrank Van Der Linden extern int immu_use_alh; 840*50200e77SFrank Van Der Linden 8413a634bfcSVikram Hegde /* ################### Interfaces exported outside IOMMU code ############## */ 8423a634bfcSVikram Hegde void immu_init(void); 8433a634bfcSVikram Hegde void immu_startup(void); 8443a634bfcSVikram Hegde void immu_shutdown(void); 8453a634bfcSVikram Hegde void immu_destroy(void); 8463a634bfcSVikram Hegde int immu_map_sgl(ddi_dma_impl_t *hp, struct ddi_dma_req *dmareq, 8473a634bfcSVikram Hegde int prealloc_count, dev_info_t *rdip); 8483a634bfcSVikram Hegde int immu_unmap_sgl(ddi_dma_impl_t *hp, dev_info_t *rdip); 8493a634bfcSVikram Hegde void immu_device_tree_changed(void); 8503a634bfcSVikram Hegde void immu_physmem_update(uint64_t addr, uint64_t size); 8513a634bfcSVikram Hegde int immu_quiesce(void); 8523a634bfcSVikram Hegde int immu_unquiesce(void); 8533a634bfcSVikram Hegde /* ######################################################################### */ 8543a634bfcSVikram Hegde 8553a634bfcSVikram Hegde /* ################# Interfaces used within IOMMU code #################### */ 8563a634bfcSVikram Hegde /* immu_dmar.c interfaces */ 8573a634bfcSVikram Hegde int immu_dmar_setup(void); 8583a634bfcSVikram Hegde int immu_dmar_parse(void); 8593a634bfcSVikram Hegde void immu_dmar_startup(void); 8603a634bfcSVikram Hegde void immu_dmar_shutdown(void); 8613a634bfcSVikram Hegde void immu_dmar_destroy(void); 8623a634bfcSVikram Hegde boolean_t immu_dmar_blacklisted(char **strings_array, uint_t nstrings); 8633a634bfcSVikram Hegde immu_t *immu_dmar_get_immu(dev_info_t *rdip); 8643a634bfcSVikram Hegde dev_info_t *immu_dmar_unit_dip(void *dmar_unit); 8653a634bfcSVikram Hegde void immu_dmar_set_immu(void *dmar_unit, immu_t *immu); 8663a634bfcSVikram Hegde void *immu_dmar_walk_units(int seg, void *dmar_unit); 8673a634bfcSVikram Hegde boolean_t immu_dmar_intrmap_supported(void); 8683a634bfcSVikram Hegde uint16_t immu_dmar_ioapic_sid(int ioapicid); 8693a634bfcSVikram Hegde immu_t *immu_dmar_ioapic_immu(int ioapicid); 8703a634bfcSVikram Hegde void immu_dmar_rmrr_map(void); 8713a634bfcSVikram Hegde 8723a634bfcSVikram Hegde /* immu.c interfaces */ 8733a634bfcSVikram Hegde int immu_walk_ancestor(dev_info_t *rdip, dev_info_t *ddip, 8743a634bfcSVikram Hegde int (*func)(dev_info_t *, void *arg), void *arg, 8753a634bfcSVikram Hegde int *level, immu_flags_t immu_flags); 876*50200e77SFrank Van Der Linden void immu_init_inv_wait(immu_inv_wait_t *iwp, const char *s, boolean_t sync); 8773a634bfcSVikram Hegde 8783a634bfcSVikram Hegde /* immu_regs.c interfaces */ 8793a634bfcSVikram Hegde void immu_regs_setup(list_t *immu_list); 8803a634bfcSVikram Hegde void immu_regs_startup(immu_t *immu); 8813a634bfcSVikram Hegde int immu_regs_resume(immu_t *immu); 8823a634bfcSVikram Hegde void immu_regs_suspend(immu_t *immu); 8833a634bfcSVikram Hegde void immu_regs_shutdown(immu_t *immu); 8843a634bfcSVikram Hegde void immu_regs_destroy(list_t *immu_list); 8853a634bfcSVikram Hegde 8863a634bfcSVikram Hegde void immu_regs_intr(immu_t *immu, uint32_t msi_addr, uint32_t msi_data, 8873a634bfcSVikram Hegde uint32_t uaddr); 8883a634bfcSVikram Hegde 8893a634bfcSVikram Hegde boolean_t immu_regs_passthru_supported(immu_t *immu); 8903a634bfcSVikram Hegde boolean_t immu_regs_is_TM_reserved(immu_t *immu); 8913a634bfcSVikram Hegde boolean_t immu_regs_is_SNP_reserved(immu_t *immu); 8923a634bfcSVikram Hegde 8933a634bfcSVikram Hegde void immu_regs_wbf_flush(immu_t *immu); 8943a634bfcSVikram Hegde void immu_regs_cpu_flush(immu_t *immu, caddr_t addr, uint_t size); 895c94adbf9SFrank Van Der Linden 896c94adbf9SFrank Van Der Linden void immu_regs_context_fsi(immu_t *immu, uint8_t function_mask, 897*50200e77SFrank Van Der Linden uint16_t source_id, uint_t domain_id, immu_inv_wait_t *iwp); 898*50200e77SFrank Van Der Linden void immu_regs_context_dsi(immu_t *immu, uint_t domain_id, 899*50200e77SFrank Van Der Linden immu_inv_wait_t *iwp); 900*50200e77SFrank Van Der Linden void immu_regs_context_gbl(immu_t *immu, immu_inv_wait_t *iwp); 901c94adbf9SFrank Van Der Linden void immu_regs_iotlb_psi(immu_t *immu, uint_t domain_id, 902*50200e77SFrank Van Der Linden uint64_t dvma, uint_t count, uint_t hint, immu_inv_wait_t *iwp); 903*50200e77SFrank Van Der Linden void immu_regs_iotlb_dsi(immu_t *immu, uint_t domain_id, immu_inv_wait_t *iwp); 904*50200e77SFrank Van Der Linden void immu_regs_iotlb_gbl(immu_t *immu, immu_inv_wait_t *iwp); 905c94adbf9SFrank Van Der Linden 9063a634bfcSVikram Hegde void immu_regs_set_root_table(immu_t *immu); 9073a634bfcSVikram Hegde void immu_regs_qinv_enable(immu_t *immu, uint64_t qinv_reg_value); 9083a634bfcSVikram Hegde void immu_regs_intr_enable(immu_t *immu, uint32_t msi_addr, uint32_t msi_data, 9093a634bfcSVikram Hegde uint32_t uaddr); 9103a634bfcSVikram Hegde void immu_regs_intrmap_enable(immu_t *immu, uint64_t irta_reg); 9113a634bfcSVikram Hegde uint64_t immu_regs_get64(immu_t *immu, uint_t reg); 9123a634bfcSVikram Hegde void immu_regs_put64(immu_t *immu, uint_t reg, uint64_t val); 9133a634bfcSVikram Hegde uint32_t immu_regs_get32(immu_t *immu, uint_t reg); 9143a634bfcSVikram Hegde void immu_regs_put32(immu_t *immu, uint_t reg, uint32_t val); 9153a634bfcSVikram Hegde 9163a634bfcSVikram Hegde /* immu_dvma.c interfaces */ 9173a634bfcSVikram Hegde void immu_dvma_setup(list_t *immu_list); 9183a634bfcSVikram Hegde void immu_dvma_startup(immu_t *immu); 9193a634bfcSVikram Hegde void immu_dvma_shutdown(immu_t *immu); 9203a634bfcSVikram Hegde void immu_dvma_destroy(list_t *immu_list); 9213a634bfcSVikram Hegde 9223a634bfcSVikram Hegde void immu_dvma_physmem_update(uint64_t addr, uint64_t size); 923*50200e77SFrank Van Der Linden int immu_map_memrange(dev_info_t *, memrng_t *); 924*50200e77SFrank Van Der Linden int immu_dvma_map(ddi_dma_impl_t *hp, struct ddi_dma_req *dmareq, 925*50200e77SFrank Van Der Linden uint_t prealloc_count, dev_info_t *rdip); 9263a634bfcSVikram Hegde int immu_dvma_unmap(ddi_dma_impl_t *hp, dev_info_t *rdip); 9273a634bfcSVikram Hegde int immu_devi_set(dev_info_t *dip, immu_flags_t immu_flags); 9283a634bfcSVikram Hegde immu_devi_t *immu_devi_get(dev_info_t *dip); 9293a634bfcSVikram Hegde immu_t *immu_dvma_get_immu(dev_info_t *dip, immu_flags_t immu_flags); 930e03dceedSVikram Hegde int pgtable_ctor(void *buf, void *arg, int kmflag); 931e03dceedSVikram Hegde void pgtable_dtor(void *buf, void *arg); 9323a634bfcSVikram Hegde 933*50200e77SFrank Van Der Linden int immu_hdl_priv_ctor(void *buf, void *arg, int kmf); 934*50200e77SFrank Van Der Linden 935*50200e77SFrank Van Der Linden int immu_dvma_device_setup(dev_info_t *rdip, immu_flags_t immu_flags); 936*50200e77SFrank Van Der Linden 937*50200e77SFrank Van Der Linden void immu_print_fault_info(uint_t sid, uint64_t dvma); 938*50200e77SFrank Van Der Linden 9393a634bfcSVikram Hegde /* immu_intrmap.c interfaces */ 9403a634bfcSVikram Hegde void immu_intrmap_setup(list_t *immu_list); 9413a634bfcSVikram Hegde void immu_intrmap_startup(immu_t *immu); 9423a634bfcSVikram Hegde void immu_intrmap_shutdown(immu_t *immu); 9433a634bfcSVikram Hegde void immu_intrmap_destroy(list_t *immu_list); 9443a634bfcSVikram Hegde 9453a634bfcSVikram Hegde /* registers interrupt handler for IOMMU unit */ 9463a634bfcSVikram Hegde void immu_intr_register(immu_t *immu); 9473a634bfcSVikram Hegde int immu_intr_handler(immu_t *immu); 9483a634bfcSVikram Hegde 9493a634bfcSVikram Hegde 9503a634bfcSVikram Hegde /* immu_qinv.c interfaces */ 951d2256d26SFrank Van Der Linden int immu_qinv_setup(list_t *immu_list); 9523a634bfcSVikram Hegde void immu_qinv_startup(immu_t *immu); 9533a634bfcSVikram Hegde void immu_qinv_shutdown(immu_t *immu); 9543a634bfcSVikram Hegde void immu_qinv_destroy(list_t *immu_list); 9553a634bfcSVikram Hegde 9563a634bfcSVikram Hegde void immu_qinv_context_fsi(immu_t *immu, uint8_t function_mask, 957*50200e77SFrank Van Der Linden uint16_t source_id, uint_t domain_id, immu_inv_wait_t *iwp); 958*50200e77SFrank Van Der Linden void immu_qinv_context_dsi(immu_t *immu, uint_t domain_id, 959*50200e77SFrank Van Der Linden immu_inv_wait_t *iwp); 960*50200e77SFrank Van Der Linden void immu_qinv_context_gbl(immu_t *immu, immu_inv_wait_t *iwp); 9613a634bfcSVikram Hegde void immu_qinv_iotlb_psi(immu_t *immu, uint_t domain_id, 962*50200e77SFrank Van Der Linden uint64_t dvma, uint_t count, uint_t hint, immu_inv_wait_t *iwp); 963*50200e77SFrank Van Der Linden void immu_qinv_iotlb_dsi(immu_t *immu, uint_t domain_id, immu_inv_wait_t *iwp); 964*50200e77SFrank Van Der Linden void immu_qinv_iotlb_gbl(immu_t *immu, immu_inv_wait_t *iwp); 965c94adbf9SFrank Van Der Linden 966*50200e77SFrank Van Der Linden void immu_qinv_intr_global(immu_t *immu, immu_inv_wait_t *iwp); 967*50200e77SFrank Van Der Linden void immu_qinv_intr_one_cache(immu_t *immu, uint_t idx, immu_inv_wait_t *iwp); 968*50200e77SFrank Van Der Linden void immu_qinv_intr_caches(immu_t *immu, uint_t idx, uint_t cnt, 969*50200e77SFrank Van Der Linden immu_inv_wait_t *); 9703a634bfcSVikram Hegde void immu_qinv_report_fault(immu_t *immu); 9713a634bfcSVikram Hegde 972*50200e77SFrank Van Der Linden #ifdef DEBUG 973*50200e77SFrank Van Der Linden #define IMMU_DPROBE1(name, type1, arg1) \ 974*50200e77SFrank Van Der Linden DTRACE_PROBE1(name, type1, arg1) 975*50200e77SFrank Van Der Linden #define IMMU_DPROBE2(name, type1, arg1, type2, arg2) \ 976*50200e77SFrank Van Der Linden DTRACE_PROBE2(name, type1, arg1, type2, arg2) 977*50200e77SFrank Van Der Linden #define IMMU_DPROBE3(name, type1, arg1, type2, arg2, type3, arg3) \ 978*50200e77SFrank Van Der Linden DTRACE_PROBE3(name, type1, arg1, type2, arg2, type3, arg3) 979*50200e77SFrank Van Der Linden #define IMMU_DPROBE4(name, type1, arg1, type2, arg2, type3, arg3, type4, arg4) \ 980*50200e77SFrank Van Der Linden DTRACE_PROBE4(name, type1, arg1, type2, arg2, type3, arg3, type4, arg4) 981*50200e77SFrank Van Der Linden #else 982*50200e77SFrank Van Der Linden #define IMMU_DPROBE1(name, type1, arg1) 983*50200e77SFrank Van Der Linden #define IMMU_DPROBE2(name, type1, arg1, type2, arg2) 984*50200e77SFrank Van Der Linden #define IMMU_DPROBE3(name, type1, arg1, type2, arg2, type3, arg3) 985*50200e77SFrank Van Der Linden #define IMMU_DPROBE4(name, type1, arg1, type2, arg2, type3, arg3, type4, arg4) 986*50200e77SFrank Van Der Linden #endif 987*50200e77SFrank Van Der Linden 9883a634bfcSVikram Hegde 9893a634bfcSVikram Hegde #ifdef __cplusplus 9903a634bfcSVikram Hegde } 9913a634bfcSVikram Hegde #endif 9923a634bfcSVikram Hegde 9933a634bfcSVikram Hegde #endif /* _SYS_INTEL_IOMMU_H */ 994