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> 4550200e77SFrank Van Der Linden #include <sys/kmem.h> 463a634bfcSVikram Hegde #include <sys/vmem.h> 473a634bfcSVikram Hegde #include <sys/rootnex.h> 4850200e77SFrank Van Der Linden #include <sys/iommulib.h> 4950200e77SFrank 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) 6950200e77SFrank 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; 133*7fd1b424SToomas Soome uint16_t dr_seg; 134*7fd1b424SToomas Soome uint64_t dr_regs; 1353a634bfcSVikram Hegde boolean_t dr_include_all; 136*7fd1b424SToomas Soome list_t dr_scope_list; 137*7fd1b424SToomas Soome 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 14950200e77SFrank Van Der Linden #define IMMU_UNIT_NAME "iommu" 15050200e77SFrank 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 46650200e77SFrank Van Der Linden #define CONT_GET_ALH(hcent) ((hcent)->lo & 0x20) 46750200e77SFrank Van Der Linden #define CONT_SET_ALH(hcent) ((hcent)->lo |= 0x20) 46850200e77SFrank Van Der Linden 46950200e77SFrank Van Der Linden #define CONT_GET_EH(hcent) ((hcent)->lo & 0x10) 47050200e77SFrank Van Der Linden #define CONT_SET_EH(hcent) ((hcent)->lo |= 0x10) 47150200e77SFrank 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)) 479