16732dbb3SVikram Hegde /* 26732dbb3SVikram Hegde * CDDL HEADER START 36732dbb3SVikram Hegde * 46732dbb3SVikram Hegde * The contents of this file are subject to the terms of the 56732dbb3SVikram Hegde * Common Development and Distribution License (the "License"). 66732dbb3SVikram Hegde * You may not use this file except in compliance with the License. 76732dbb3SVikram Hegde * 86732dbb3SVikram Hegde * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 96732dbb3SVikram Hegde * or http://www.opensolaris.org/os/licensing. 106732dbb3SVikram Hegde * See the License for the specific language governing permissions 116732dbb3SVikram Hegde * and limitations under the License. 126732dbb3SVikram Hegde * 136732dbb3SVikram Hegde * When distributing Covered Code, include this CDDL HEADER in each 146732dbb3SVikram Hegde * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 156732dbb3SVikram Hegde * If applicable, add the following below this CDDL HEADER, with the 166732dbb3SVikram Hegde * fields enclosed by brackets "[]" replaced with your own identifying 176732dbb3SVikram Hegde * information: Portions Copyright [yyyy] [name of copyright owner] 186732dbb3SVikram Hegde * 196732dbb3SVikram Hegde * CDDL HEADER END 206732dbb3SVikram Hegde */ 216732dbb3SVikram Hegde /* 22*ba758cf1SJerry Gilliam * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 236732dbb3SVikram Hegde */ 246732dbb3SVikram Hegde 256732dbb3SVikram Hegde #ifndef _AMD_IOMMU_IMPL_H 266732dbb3SVikram Hegde #define _AMD_IOMMU_IMPL_H 276732dbb3SVikram Hegde 286732dbb3SVikram Hegde #ifdef __cplusplus 296732dbb3SVikram Hegde extern "C" { 306732dbb3SVikram Hegde #endif 316732dbb3SVikram Hegde 326732dbb3SVikram Hegde #include <sys/pci.h> 336732dbb3SVikram Hegde 346732dbb3SVikram Hegde #ifdef _KERNEL 356732dbb3SVikram Hegde 366732dbb3SVikram Hegde #define AMD_IOMMU_PCI_PROG_IF (0x0) 376732dbb3SVikram Hegde 386732dbb3SVikram Hegde #define AMD_IOMMU_CAP (0x3) 396732dbb3SVikram Hegde 406732dbb3SVikram Hegde #define AMD_IOMMU_REG_SIZE (0x2028) 416732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_SZ (16) 426732dbb3SVikram Hegde #define AMD_IOMMU_CMDBUF_SZ (15) 436732dbb3SVikram Hegde #define AMD_IOMMU_EVENTLOG_SZ (15) 446732dbb3SVikram Hegde #define AMD_IOMMU_DEVENT_SZ (32) 456732dbb3SVikram Hegde #define AMD_IOMMU_CMD_SZ (16) 466732dbb3SVikram Hegde #define AMD_IOMMU_EVENT_SZ (16) 476732dbb3SVikram Hegde 486732dbb3SVikram Hegde /* Capability Register offsets */ 496732dbb3SVikram Hegde #define AMD_IOMMU_CAP_HDR_OFF (0x00) 506732dbb3SVikram Hegde #define AMD_IOMMU_CAP_ADDR_LOW_OFF (0x04) 516732dbb3SVikram Hegde #define AMD_IOMMU_CAP_ADDR_HI_OFF (0x08) 526732dbb3SVikram Hegde #define AMD_IOMMU_CAP_RANGE_OFF (0x0C) 536732dbb3SVikram Hegde #define AMD_IOMMU_CAP_MISC_OFF (0x10) 546732dbb3SVikram Hegde 556732dbb3SVikram Hegde /* ControL Registers offsets */ 566732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_REG_OFF (0x00) 576732dbb3SVikram Hegde #define AMD_IOMMU_CMDBUF_REG_OFF (0x08) 586732dbb3SVikram Hegde #define AMD_IOMMU_EVENTLOG_REG_OFF (0x10) 596732dbb3SVikram Hegde #define AMD_IOMMU_CTRL_REG_OFF (0x18) 606732dbb3SVikram Hegde #define AMD_IOMMU_EXCL_BASE_REG_OFF (0x20) 616732dbb3SVikram Hegde #define AMD_IOMMU_EXCL_LIM_REG_OFF (0x28) 626732dbb3SVikram Hegde #define AMD_IOMMU_CMDBUF_HEAD_REG_OFF (0x2000) 636732dbb3SVikram Hegde #define AMD_IOMMU_CMDBUF_TAIL_REG_OFF (0x2008) 646732dbb3SVikram Hegde #define AMD_IOMMU_EVENTLOG_HEAD_REG_OFF (0x2010) 656732dbb3SVikram Hegde #define AMD_IOMMU_EVENTLOG_TAIL_REG_OFF (0x2018) 666732dbb3SVikram Hegde #define AMD_IOMMU_STATUS_REG_OFF (0x2020) 676732dbb3SVikram Hegde 686732dbb3SVikram Hegde /* Capability Header Register Bits */ 696732dbb3SVikram Hegde #define AMD_IOMMU_CAP_NPCACHE (26 << 16 | 26) 706732dbb3SVikram Hegde #define AMD_IOMMU_CAP_HTTUN (25 << 16 | 25) 716732dbb3SVikram Hegde #define AMD_IOMMU_CAP_IOTLB (24 << 16 | 24) 726732dbb3SVikram Hegde #define AMD_IOMMU_CAP_TYPE (18 << 16 | 16) 736732dbb3SVikram Hegde #define AMD_IOMMU_CAP_ID (7 << 16 | 0) 746732dbb3SVikram Hegde 756732dbb3SVikram Hegde /* Capability Range Register bits */ 766732dbb3SVikram Hegde #define AMD_IOMMU_LAST_DEVFN (31 << 16 | 24) 776732dbb3SVikram Hegde #define AMD_IOMMU_FIRST_DEVFN (23 << 16 | 16) 786732dbb3SVikram Hegde #define AMD_IOMMU_RNG_BUS (15 << 16 | 8) 796732dbb3SVikram Hegde #define AMD_IOMMU_RNG_VALID (7 << 16 | 7) 806732dbb3SVikram Hegde #define AMD_IOMMU_HT_UNITID (4 << 16 | 0) 816732dbb3SVikram Hegde 826732dbb3SVikram Hegde 836732dbb3SVikram Hegde /* Capability Misc Register bits */ 846732dbb3SVikram Hegde #define AMD_IOMMU_HT_ATSRSV (22 << 16 | 22) 856732dbb3SVikram Hegde #define AMD_IOMMU_VA_SIZE (21 << 16 | 15) 866732dbb3SVikram Hegde #define AMD_IOMMU_PA_SIZE (14 << 16 | 8) 876732dbb3SVikram Hegde #define AMD_IOMMU_MSINUM (4 << 16 | 0) 886732dbb3SVikram Hegde 896732dbb3SVikram Hegde /* Device Table Base Address register bits */ 906732dbb3SVikram Hegde #define AMD_IOMMU_DEVTABBASE (51 << 16 | 12) 916732dbb3SVikram Hegde #define AMD_IOMMU_DEVTABSIZE (8 << 16 | 0) 926732dbb3SVikram Hegde 936732dbb3SVikram Hegde /* Command Buffer Base Address register bits */ 946732dbb3SVikram Hegde #define AMD_IOMMU_COMLEN (59 << 16 | 56) 956732dbb3SVikram Hegde #define AMD_IOMMU_COMBASE (51 << 16 | 12) 966732dbb3SVikram Hegde 976732dbb3SVikram Hegde #define AMD_IOMMU_CMDBUF_MINSZ (8) 986732dbb3SVikram Hegde #define AMD_IOMMU_CMDBUF_MAXSZ (15) 996732dbb3SVikram Hegde 1006732dbb3SVikram Hegde /* Event Log Base Address register bits */ 1016732dbb3SVikram Hegde #define AMD_IOMMU_EVENTLEN (59 << 16 | 56) 1026732dbb3SVikram Hegde #define AMD_IOMMU_EVENTBASE (51 << 16 | 12) 1036732dbb3SVikram Hegde 1046732dbb3SVikram Hegde #define AMD_IOMMU_EVENTLOG_MINSZ (8) 1056732dbb3SVikram Hegde #define AMD_IOMMU_EVENTLOG_MAXSZ (15) 1066732dbb3SVikram Hegde 1076732dbb3SVikram Hegde /* Control register bits */ 1086732dbb3SVikram Hegde #define AMD_IOMMU_CMDBUF_ENABLE (12 << 16 | 12) 1096732dbb3SVikram Hegde #define AMD_IOMMU_ISOC (11 << 16 | 11) 1106732dbb3SVikram Hegde #define AMD_IOMMU_COHERENT (10 << 16 | 10) 1116732dbb3SVikram Hegde #define AMD_IOMMU_RESPASSPW (9 << 16 | 9) 1126732dbb3SVikram Hegde #define AMD_IOMMU_PASSPW (8 << 16 | 8) 1136732dbb3SVikram Hegde #define AMD_IOMMU_INVTO (7 << 16 | 5) 1146732dbb3SVikram Hegde #define AMD_IOMMU_COMWAITINT_ENABLE (4 << 16 | 4) 1156732dbb3SVikram Hegde #define AMD_IOMMU_EVENTINT_ENABLE (3 << 16 | 3) 1166732dbb3SVikram Hegde #define AMD_IOMMU_EVENTLOG_ENABLE (2 << 16 | 2) 1176732dbb3SVikram Hegde #define AMD_IOMMU_HT_TUN_ENABLE (1 << 16 | 1) 1186732dbb3SVikram Hegde #define AMD_IOMMU_ENABLE (0 << 16 | 0) 1196732dbb3SVikram Hegde 1206732dbb3SVikram Hegde /* Exclusion Base Register bits */ 1216732dbb3SVikram Hegde #define AMD_IOMMU_EXCL_BASE_ADDR (51 << 16 | 12) 1226732dbb3SVikram Hegde #define AMD_IOMMU_EXCL_BASE_ALLOW (1 << 16 | 1) 1236732dbb3SVikram Hegde #define AMD_IOMMU_EXCL_BASE_EXEN (0 << 16 | 0) 1246732dbb3SVikram Hegde 1256732dbb3SVikram Hegde /* Exclusion Limit Register bits */ 1266732dbb3SVikram Hegde #define AMD_IOMMU_EXCL_LIM (51 << 16 | 12) 1276732dbb3SVikram Hegde 1286732dbb3SVikram Hegde /* Command Buffer Head Pointer Register bits */ 1296732dbb3SVikram Hegde #define AMD_IOMMU_CMDHEADPTR (18 << 16 | 4) 1306732dbb3SVikram Hegde 1316732dbb3SVikram Hegde /* Command Buffer Tail Pointer Register bits */ 1326732dbb3SVikram Hegde #define AMD_IOMMU_CMDTAILPTR (18 << 16 | 4) 1336732dbb3SVikram Hegde 1346732dbb3SVikram Hegde /* Event Log Head Pointer Register bits */ 1356732dbb3SVikram Hegde #define AMD_IOMMU_EVENTHEADPTR (18 << 16 | 4) 1366732dbb3SVikram Hegde 1376732dbb3SVikram Hegde /* Event Log Tail Pointer Register bits */ 1386732dbb3SVikram Hegde #define AMD_IOMMU_EVENTTAILPTR (18 << 16 | 4) 1396732dbb3SVikram Hegde 1406732dbb3SVikram Hegde /* Status Register bits */ 1416732dbb3SVikram Hegde #define AMD_IOMMU_CMDBUF_RUN (4 << 16 | 4) 1426732dbb3SVikram Hegde #define AMD_IOMMU_EVENT_LOG_RUN (3 << 16 | 3) 1436732dbb3SVikram Hegde #define AMD_IOMMU_COMWAIT_INT (2 << 16 | 2) 1446732dbb3SVikram Hegde #define AMD_IOMMU_EVENT_LOG_INT (1 << 16 | 1) 1456732dbb3SVikram Hegde #define AMD_IOMMU_EVENT_OVERFLOW_INT (0 << 16 | 0) 1466732dbb3SVikram Hegde 1476732dbb3SVikram Hegde /* Device Table Bits */ 1486732dbb3SVikram Hegde 1496732dbb3SVikram Hegde /* size in bytes of each device table entry */ 1506732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_ENTRY_SZ (32) 1516732dbb3SVikram Hegde 1526732dbb3SVikram Hegde /* Interrupt Remapping related Device Table bits */ 1536732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_LINT1PASS ((191-128) << 16 | (191-128)) 1546732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_LINT0PASS ((190-128) << 16 | (190-128)) 1556732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_INTCTL ((189-128) << 16 | (188-128)) 1566732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_NMIPASS ((186-128) << 16 | (186-128)) 1576732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_EXTINTPAS ((185-128) << 16 | (185-128)) 1586732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_INITPASS ((184-128) << 16 | (184-128)) 1596732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_INTR_ROOT ((179-128) << 16 | (134-128)) 1606732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_IG ((133-128) << 16 | (133-128)) 1616732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_INTTABLEN ((132-128) << 16 | (129-128)) 1626732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_IV ((128-128) << 16 | (128-128)) 1636732dbb3SVikram Hegde 1646732dbb3SVikram Hegde /* DMA Remapping related Device Table Bits */ 1656732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_SYSMGT ((105-64) << 16 | (104-64)) 1666732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_EX ((103-64) << 16 | (103-64)) 1676732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_SD ((102-64) << 16 | (102-64)) 1686732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_CACHE ((101-64) << 16 | (101-64)) 1696732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_IOCTL ((100-64) << 16 | (99-64)) 1706732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_SA ((98-64) << 16 | (98-64)) 1716732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_SE ((97-64) << 16 | (97-64)) 1726732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_IOTLB ((96-64) << 16 | (96-64)) 1736732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_DOMAINID ((79-64) << 16 | (64-64)) 1746732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_IW (62 << 16 | 62) 1756732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_IR (61 << 16 | 61) 1766732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_ROOT_PGTBL (51 << 16 | 12) 1776732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_PG_MODE (11 << 16 | 9) 1786732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_TV (1 << 16 | 1) 1796732dbb3SVikram Hegde #define AMD_IOMMU_DEVTBL_V (0 << 16 | 0) 1806732dbb3SVikram Hegde 1816732dbb3SVikram Hegde #define BUS_DEVFN_TO_BDF(b, devfn) (devfn) 1826732dbb3SVikram Hegde #define AMD_IOMMU_ALIAS_HASH_SZ (256) 1836732dbb3SVikram Hegde 1846732dbb3SVikram Hegde #define AMD_IOMMU_REG_ADDR_LOCKED (0x1) 1856732dbb3SVikram Hegde 1866732dbb3SVikram Hegde /* 1876732dbb3SVikram Hegde * IOMMU Command bits 1886732dbb3SVikram Hegde */ 1896732dbb3SVikram Hegde 1906732dbb3SVikram Hegde typedef enum { 1916732dbb3SVikram Hegde AMD_IOMMU_CMD_INVAL = 0, 1926732dbb3SVikram Hegde AMD_IOMMU_CMD_COMPL_WAIT, 1936732dbb3SVikram Hegde AMD_IOMMU_CMD_INVAL_DEVTAB_ENTRY, 1946732dbb3SVikram Hegde AMD_IOMMU_CMD_INVAL_IOMMU_PAGES, 1956732dbb3SVikram Hegde AMD_IOMMU_CMD_INVAL_IOTLB_PAGES, 1966732dbb3SVikram Hegde AMD_IOMMU_CMD_INVAL_INTR_TABLE, 1976732dbb3SVikram Hegde } amd_iommu_cmd_t; 1986732dbb3SVikram Hegde 1996732dbb3SVikram Hegde typedef enum { 2006732dbb3SVikram Hegde AMD_IOMMU_CMD_FLAGS_NONE = 0, 2016732dbb3SVikram Hegde AMD_IOMMU_CMD_FLAGS_COMPL_WAIT = 1, 2026732dbb3SVikram Hegde AMD_IOMMU_CMD_FLAGS_COMPL_WAIT_F = 2, 2036732dbb3SVikram Hegde AMD_IOMMU_CMD_FLAGS_COMPL_WAIT_S = 4, 2046732dbb3SVikram Hegde AMD_IOMMU_CMD_FLAGS_PAGE_PDE_INVAL = 8, 2056732dbb3SVikram Hegde AMD_IOMMU_CMD_FLAGS_PAGE_INVAL_S = 16, 2066732dbb3SVikram Hegde AMD_IOMMU_CMD_FLAGS_IOTLB_INVAL_S = 32 2076732dbb3SVikram Hegde } amd_iommu_cmd_flags_t; 2086732dbb3SVikram Hegde 2096732dbb3SVikram Hegde /* Common command bits */ 2106732dbb3SVikram Hegde #define AMD_IOMMU_CMD_OPCODE (31 << 16 | 28) 2116732dbb3SVikram Hegde 2126732dbb3SVikram Hegde /* Completion Wait command bits */ 2136732dbb3SVikram Hegde #define AMD_IOMMU_CMD_COMPL_WAIT_S (0 << 16 | 0) 2146732dbb3SVikram Hegde #define AMD_IOMMU_CMD_COMPL_WAIT_I (1 << 16 | 1) 2156732dbb3SVikram Hegde #define AMD_IOMMU_CMD_COMPL_WAIT_F (2 << 16 | 2) 2166732dbb3SVikram Hegde #define AMD_IOMMU_CMD_COMPL_WAIT_STORE_ADDR_LO (31 << 16 | 3) 2176732dbb3SVikram Hegde #define AMD_IOMMU_CMD_COMPL_WAIT_STORE_ADDR_HI (19 << 16 | 0) 2186732dbb3SVikram Hegde 2196732dbb3SVikram Hegde /* Invalidate Device Table entry command bits */ 2206732dbb3SVikram Hegde #define AMD_IOMMU_CMD_INVAL_DEVTAB_DEVICEID (15 << 16 | 0) 2216732dbb3SVikram Hegde 2226732dbb3SVikram Hegde /* Invalidate IOMMU Pages command bits */ 2236732dbb3SVikram Hegde #define AMD_IOMMU_CMD_INVAL_PAGES_DOMAINID (15 << 16 | 0) 2246732dbb3SVikram Hegde #define AMD_IOMMU_CMD_INVAL_PAGES_S (0 << 16 | 0) 2256732dbb3SVikram Hegde #define AMD_IOMMU_CMD_INVAL_PAGES_PDE (1 << 16 | 1) 2266732dbb3SVikram Hegde #define AMD_IOMMU_CMD_INVAL_PAGES_ADDR_LO (31 << 16 | 12) 2276732dbb3SVikram Hegde #define AMD_IOMMU_CMD_INVAL_PAGES_ADDR_HI (63 << 16 | 32) 2286732dbb3SVikram Hegde 2296732dbb3SVikram Hegde 2306732dbb3SVikram Hegde /* Invalidate IOTLB command bits */ 2316732dbb3SVikram Hegde #define AMD_IOMMU_CMD_INVAL_IOTLB_DEVICEID (15 << 16 | 0) 2326732dbb3SVikram Hegde #define AMD_IOMMU_CMD_INVAL_IOTLB_MAXPEND (31 << 16 | 24) 2336732dbb3SVikram Hegde #define AMD_IOMMU_CMD_INVAL_IOTLB_QUEUEID (15 << 16 | 0) 2346732dbb3SVikram Hegde #define AMD_IOMMU_CMD_INVAL_IOTLB_S (0 << 16 | 0) 2356732dbb3SVikram Hegde #define AMD_IOMMU_CMD_INVAL_IOTLB_ADDR_LO (31 << 16 | 12) 2366732dbb3SVikram Hegde #define AMD_IOMMU_CMD_INVAL_IOTLB_ADDR_HI (31 << 16 | 0) 2376732dbb3SVikram Hegde 2386732dbb3SVikram Hegde #define AMD_IOMMU_DEFAULT_MAXPEND (10) 2396732dbb3SVikram Hegde 2406732dbb3SVikram Hegde /* Invalidate Interrupt Table bits */ 2416732dbb3SVikram Hegde #define AMD_IOMMU_CMD_INVAL_INTR_DEVICEID (15 << 16 | 0) 2426732dbb3SVikram Hegde 2436732dbb3SVikram Hegde #if defined(__amd64) 2446732dbb3SVikram Hegde #define dmac_cookie_addr dmac_laddress 2456732dbb3SVikram Hegde #else 2466732dbb3SVikram Hegde #define dmac_cookie_addr dmac_address 2476732dbb3SVikram Hegde #endif 2486732dbb3SVikram Hegde 2496732dbb3SVikram Hegde #define AMD_IOMMU_TABLE_ALIGN ((1ULL << 12) - 1) 2506732dbb3SVikram Hegde 2516732dbb3SVikram Hegde #define AMD_IOMMU_MAX_DEVICEID (0xFFFF) 2526732dbb3SVikram Hegde 2536732dbb3SVikram Hegde /* 2546732dbb3SVikram Hegde * DMA sync macros 2556732dbb3SVikram Hegde * TODO: optimize sync only small ranges 2566732dbb3SVikram Hegde */ 2576732dbb3SVikram Hegde #define SYNC_FORDEV(h) (void) ddi_dma_sync(h, 0, 0, DDI_DMA_SYNC_FORDEV) 2586732dbb3SVikram Hegde #define SYNC_FORKERN(h) (void) ddi_dma_sync(h, 0, 0, DDI_DMA_SYNC_FORKERNEL) 2596732dbb3SVikram Hegde 2606732dbb3SVikram Hegde #define WAIT_SEC(s) drv_usecwait(1000000*(s)) 2616732dbb3SVikram Hegde 2626732dbb3SVikram Hegde #define CMD2OFF(c) ((c) << 4) 2636732dbb3SVikram Hegde #define OFF2CMD(o) ((o) >> 4) 2646732dbb3SVikram Hegde 2656732dbb3SVikram Hegde typedef union split { 2666732dbb3SVikram Hegde uint64_t u64; 2676732dbb3SVikram Hegde uint32_t u32[2]; 2686732dbb3SVikram Hegde } split_t; 2696732dbb3SVikram Hegde 2706732dbb3SVikram Hegde #define BITPOS_START(b) ((b) >> 16) 2716732dbb3SVikram Hegde #define BITPOS_END(b) ((b) & 0xFFFF) 2726732dbb3SVikram Hegde 2736732dbb3SVikram Hegde #define START_MASK64(s) (((s) == 63) ? ~((uint64_t)0) : \ 2746732dbb3SVikram Hegde (uint64_t)((1ULL << ((s)+1)) - 1)) 2756732dbb3SVikram Hegde #define START_MASK32(s) (((s) == 31) ? ~((uint32_t)0) : \ 2766732dbb3SVikram Hegde (uint32_t)((1ULL << ((s)+1)) - 1)) 2776732dbb3SVikram Hegde #define START_MASK16(s) (((s) == 15) ? ~((uint16_t)0) : \ 2786732dbb3SVikram Hegde (uint16_t)((1ULL << ((s)+1)) - 1)) 2796732dbb3SVikram Hegde #define START_MASK8(s) (((s) == 7) ? ~((uint8_t)0) : \ 2806732dbb3SVikram Hegde (uint8_t)((1ULL << ((s)+1)) - 1)) 2816732dbb3SVikram Hegde 2826732dbb3SVikram Hegde #define END_MASK(e) ((1ULL << (e)) - 1) 2836732dbb3SVikram Hegde 2846732dbb3SVikram Hegde #define BIT_MASK64(s, e) (uint64_t)(START_MASK64(s) & ~END_MASK(e)) 2856732dbb3SVikram Hegde #define BIT_MASK32(s, e) (uint32_t)(START_MASK32(s) & ~END_MASK(e)) 2866732dbb3SVikram Hegde #define BIT_MASK16(s, e) (uint16_t)(START_MASK16(s) & ~END_MASK(e)) 2876732dbb3SVikram Hegde #define BIT_MASK8(s, e) (uint8_t)(START_MASK8(s) & ~END_MASK(e)) 2886732dbb3SVikram Hegde 2896732dbb3SVikram Hegde #define AMD_IOMMU_REG_GET64_IMPL(rp, b) \ 2906732dbb3SVikram Hegde (((*(rp)) & (START_MASK64(BITPOS_START(b)))) >> BITPOS_END(b)) 2916732dbb3SVikram Hegde #define AMD_IOMMU_REG_GET64(rp, b) \ 2926732dbb3SVikram Hegde ((amd_iommu_64bit_bug) ? amd_iommu_reg_get64_workaround(rp, b) : \ 2936732dbb3SVikram Hegde AMD_IOMMU_REG_GET64_IMPL(rp, b)) 2946732dbb3SVikram Hegde #define AMD_IOMMU_REG_GET32(rp, b) \ 2956732dbb3SVikram Hegde (((*(rp)) & (START_MASK32(BITPOS_START(b)))) >> BITPOS_END(b)) 2966732dbb3SVikram Hegde #define AMD_IOMMU_REG_GET16(rp, b) \ 2976732dbb3SVikram Hegde (((*(rp)) & (START_MASK16(BITPOS_START(b)))) >> BITPOS_END(b)) 2986732dbb3SVikram Hegde #define AMD_IOMMU_REG_GET8(rp, b) \ 2996732dbb3SVikram Hegde (((*(rp)) & (START_MASK8(BITPOS_START(b)))) >> BITPOS_END(b)) 3006732dbb3SVikram Hegde 3016732dbb3SVikram Hegde #define AMD_IOMMU_REG_SET64_IMPL(rp, b, v) \ 3026732dbb3SVikram Hegde ((*(rp)) = \ 3036732dbb3SVikram Hegde (((uint64_t)(*(rp)) & ~(BIT_MASK64(BITPOS_START(b), BITPOS_END(b)))) \ 3046732dbb3SVikram Hegde | ((uint64_t)(v) << BITPOS_END(b)))) 3056732dbb3SVikram Hegde 3066732dbb3SVikram Hegde #define AMD_IOMMU_REG_SET64(rp, b, v) \ 3076732dbb3SVikram Hegde (void) ((amd_iommu_64bit_bug) ? \ 3086732dbb3SVikram Hegde amd_iommu_reg_set64_workaround(rp, b, v) : \ 3096732dbb3SVikram Hegde AMD_IOMMU_REG_SET64_IMPL(rp, b, v)) 3106732dbb3SVikram Hegde 3116732dbb3SVikram Hegde #define AMD_IOMMU_REG_SET32(rp, b, v) \ 3126732dbb3SVikram Hegde ((*(rp)) = \ 3136732dbb3SVikram Hegde (((uint32_t)(*(rp)) & ~(BIT_MASK32(BITPOS_START(b), BITPOS_END(b)))) \ 3146732dbb3SVikram Hegde | ((uint32_t)(v) << BITPOS_END(b)))) 3156732dbb3SVikram Hegde 3166732dbb3SVikram Hegde #define AMD_IOMMU_REG_SET16(rp, b, v) \ 3176732dbb3SVikram Hegde ((*(rp)) = \ 3186732dbb3SVikram Hegde (((uint16_t)(*(rp)) & ~(BIT_MASK16(BITPOS_START(b), BITPOS_END(b)))) \ 3196732dbb3SVikram Hegde | ((uint16_t)(v) << BITPOS_END(b)))) 3206732dbb3SVikram Hegde 3216732dbb3SVikram Hegde #define AMD_IOMMU_REG_SET8(rp, b, v) \ 3226732dbb3SVikram Hegde ((*(rp)) = \ 3236732dbb3SVikram Hegde (((uint8_t)(*(rp)) & ~(BIT_MASK8(BITPOS_START(b), BITPOS_END(b)))) \ 3246732dbb3SVikram Hegde | ((uint8_t)(v) << BITPOS_END(b)))) 3256732dbb3SVikram Hegde 3266732dbb3SVikram Hegde /* 3276732dbb3SVikram Hegde * Cast a 64 bit pointer to a uint64_t * 3286732dbb3SVikram Hegde */ 3296732dbb3SVikram Hegde #define REGADDR64(a) ((uint64_t *)(uintptr_t)(a)) 3306732dbb3SVikram Hegde 3316732dbb3SVikram Hegde typedef enum { 3326732dbb3SVikram Hegde AMD_IOMMU_INTR_INVALID = 0, 3336732dbb3SVikram Hegde AMD_IOMMU_INTR_TABLE, 3346732dbb3SVikram Hegde AMD_IOMMU_INTR_ALLOCED, 3356732dbb3SVikram Hegde AMD_IOMMU_INTR_HANDLER, 3366732dbb3SVikram Hegde AMD_IOMMU_INTR_ENABLED 3376732dbb3SVikram Hegde } amd_iommu_intr_state_t; 3386732dbb3SVikram Hegde 3396732dbb3SVikram Hegde 3406732dbb3SVikram Hegde typedef struct amd_iommu { 3416732dbb3SVikram Hegde kmutex_t aiomt_mutex; 3426732dbb3SVikram Hegde kmutex_t aiomt_eventlock; 3436732dbb3SVikram Hegde kmutex_t aiomt_cmdlock; 3446732dbb3SVikram Hegde dev_info_t *aiomt_dip; 345*ba758cf1SJerry Gilliam uint16_t aiomt_bdf; 3466732dbb3SVikram Hegde int aiomt_idx; 3476732dbb3SVikram Hegde iommulib_handle_t aiomt_iommulib_handle; 3486732dbb3SVikram Hegde iommulib_ops_t *aiomt_iommulib_ops; 3496732dbb3SVikram Hegde uint32_t aiomt_cap_hdr; 3506732dbb3SVikram Hegde uint8_t aiomt_npcache; 3516732dbb3SVikram Hegde uint8_t aiomt_httun; 3526732dbb3SVikram Hegde uint8_t aiomt_iotlb; 3536732dbb3SVikram Hegde uint8_t aiomt_captype; 3546732dbb3SVikram Hegde uint8_t aiomt_capid; 3556732dbb3SVikram Hegde uint32_t aiomt_low_addr32; 3566732dbb3SVikram Hegde uint32_t aiomt_hi_addr32; 3576732dbb3SVikram Hegde uint64_t aiomt_reg_pa; 3586732dbb3SVikram Hegde uint64_t aiomt_va; 3596732dbb3SVikram Hegde uint64_t aiomt_reg_va; 3606732dbb3SVikram Hegde uint32_t aiomt_range; 3616732dbb3SVikram Hegde uint8_t aiomt_rng_bus; 3626732dbb3SVikram Hegde uint8_t aiomt_first_devfn; 3636732dbb3SVikram Hegde uint8_t aiomt_last_devfn; 3646732dbb3SVikram Hegde uint8_t aiomt_rng_valid; 3656732dbb3SVikram Hegde uint8_t aiomt_ht_unitid; 3666732dbb3SVikram Hegde uint32_t aiomt_misc; 3676732dbb3SVikram Hegde uint8_t aiomt_htatsresv; 3686732dbb3SVikram Hegde uint8_t aiomt_vasize; 3696732dbb3SVikram Hegde uint8_t aiomt_pasize; 3706732dbb3SVikram Hegde uint8_t aiomt_msinum; 3716732dbb3SVikram Hegde uint8_t aiomt_reg_pages; 3726732dbb3SVikram Hegde uint32_t aiomt_reg_size; 3736732dbb3SVikram Hegde uint32_t aiomt_devtbl_sz; 3746732dbb3SVikram Hegde uint32_t aiomt_cmdbuf_sz; 3756732dbb3SVikram Hegde uint32_t aiomt_eventlog_sz; 3766732dbb3SVikram Hegde caddr_t aiomt_devtbl; 3776732dbb3SVikram Hegde caddr_t aiomt_cmdbuf; 3786732dbb3SVikram Hegde caddr_t aiomt_eventlog; 3796732dbb3SVikram Hegde uint32_t *aiomt_cmd_tail; 3806732dbb3SVikram Hegde uint32_t *aiomt_event_head; 3816732dbb3SVikram Hegde ddi_dma_handle_t aiomt_dmahdl; 3826732dbb3SVikram Hegde void *aiomt_dma_bufva; 3836732dbb3SVikram Hegde uint64_t aiomt_dma_mem_realsz; 3846732dbb3SVikram Hegde ddi_acc_handle_t aiomt_dma_mem_hdl; 3856732dbb3SVikram Hegde ddi_dma_cookie_t aiomt_buf_dma_cookie; 3866732dbb3SVikram Hegde uint_t aiomt_buf_dma_ncookie; 3876732dbb3SVikram Hegde amd_iommu_intr_state_t aiomt_intr_state; 3886732dbb3SVikram Hegde ddi_intr_handle_t *aiomt_intr_htable; 3896732dbb3SVikram Hegde uint32_t aiomt_intr_htable_sz; 3906732dbb3SVikram Hegde uint32_t aiomt_actual_intrs; 3916732dbb3SVikram Hegde uint32_t aiomt_intr_cap; 3926732dbb3SVikram Hegde uint64_t aiomt_reg_devtbl_va; 3936732dbb3SVikram Hegde uint64_t aiomt_reg_cmdbuf_va; 3946732dbb3SVikram Hegde uint64_t aiomt_reg_eventlog_va; 3956732dbb3SVikram Hegde uint64_t aiomt_reg_ctrl_va; 3966732dbb3SVikram Hegde uint64_t aiomt_reg_excl_base_va; 3976732dbb3SVikram Hegde uint64_t aiomt_reg_excl_lim_va; 3986732dbb3SVikram Hegde uint64_t aiomt_reg_cmdbuf_head_va; 3996732dbb3SVikram Hegde uint64_t aiomt_reg_cmdbuf_tail_va; 4006732dbb3SVikram Hegde uint64_t aiomt_reg_eventlog_head_va; 4016732dbb3SVikram Hegde uint64_t aiomt_reg_eventlog_tail_va; 4026732dbb3SVikram Hegde uint64_t aiomt_reg_status_va; 4036732dbb3SVikram Hegde struct amd_iommu *aiomt_next; 4046732dbb3SVikram Hegde } amd_iommu_t; 4056732dbb3SVikram Hegde 4066732dbb3SVikram Hegde typedef struct amd_iommu_dma_devtbl_ent { 4076732dbb3SVikram Hegde uint16_t de_domainid; 4086732dbb3SVikram Hegde uint8_t de_R; 4096732dbb3SVikram Hegde uint8_t de_W; 4106732dbb3SVikram Hegde caddr_t de_root_pgtbl; 4116732dbb3SVikram Hegde uint8_t de_pgmode; 4126732dbb3SVikram Hegde } amd_iommu_dma_devtbl_entry_t; 4136732dbb3SVikram Hegde 4146732dbb3SVikram Hegde typedef struct amd_iommu_alias { 4156732dbb3SVikram Hegde uint16_t al_bdf; 4166732dbb3SVikram Hegde uint16_t al_src_bdf; 4176732dbb3SVikram Hegde struct amd_iommu_alias *al_next; 4186732dbb3SVikram Hegde } amd_iommu_alias_t; 4196732dbb3SVikram Hegde 4206732dbb3SVikram Hegde typedef struct amd_iommu_cmdargs { 4216732dbb3SVikram Hegde uint64_t ca_addr; 4226732dbb3SVikram Hegde uint16_t ca_domainid; 4236732dbb3SVikram Hegde uint16_t ca_deviceid; 4246732dbb3SVikram Hegde } amd_iommu_cmdargs_t; 4256732dbb3SVikram Hegde 4266732dbb3SVikram Hegde struct amd_iommu_page_table; 4276732dbb3SVikram Hegde 4286732dbb3SVikram Hegde typedef struct amd_iommu_page_table_hash { 4296732dbb3SVikram Hegde kmutex_t ampt_lock; 4306732dbb3SVikram Hegde struct amd_iommu_page_table **ampt_hash; 4316732dbb3SVikram Hegde } amd_iommu_page_table_hash_t; 4326732dbb3SVikram Hegde 4336732dbb3SVikram Hegde typedef enum { 4346732dbb3SVikram Hegde AMD_IOMMU_LOG_INVALID_OP = 0, 4356732dbb3SVikram Hegde AMD_IOMMU_LOG_DISPLAY, 4366732dbb3SVikram Hegde AMD_IOMMU_LOG_DISCARD 4376732dbb3SVikram Hegde } amd_iommu_log_op_t; 4386732dbb3SVikram Hegde 4396732dbb3SVikram Hegde typedef enum { 4406732dbb3SVikram Hegde AMD_IOMMU_DEBUG_NONE = 0, 4416732dbb3SVikram Hegde AMD_IOMMU_DEBUG_ALLOCHDL = 0x1, 4426732dbb3SVikram Hegde AMD_IOMMU_DEBUG_FREEHDL = 0x2, 4436732dbb3SVikram Hegde AMD_IOMMU_DEBUG_BIND = 0x4, 4446732dbb3SVikram Hegde AMD_IOMMU_DEBUG_UNBIND = 0x8, 4456732dbb3SVikram Hegde AMD_IOMMU_DEBUG_WIN = 0x10, 4466732dbb3SVikram Hegde AMD_IOMMU_DEBUG_PAGE_TABLES = 0x20, 4476732dbb3SVikram Hegde AMD_IOMMU_DEBUG_DEVTBL = 0x40, 4486732dbb3SVikram Hegde AMD_IOMMU_DEBUG_CMDBUF = 0x80, 4496732dbb3SVikram Hegde AMD_IOMMU_DEBUG_EVENTLOG = 0x100, 4506732dbb3SVikram Hegde AMD_IOMMU_DEBUG_ACPI = 0x200, 4516732dbb3SVikram Hegde AMD_IOMMU_DEBUG_PA2VA = 0x400, 4526732dbb3SVikram Hegde AMD_IOMMU_DEBUG_TABLES = 0x800, 4536732dbb3SVikram Hegde AMD_IOMMU_DEBUG_EXCL = 0x1000, 4546732dbb3SVikram Hegde AMD_IOMMU_DEBUG_INTR = 0x2000 4556732dbb3SVikram Hegde } amd_iommu_debug_t; 4566732dbb3SVikram Hegde 4576732dbb3SVikram Hegde extern const char *amd_iommu_modname; 4586732dbb3SVikram Hegde extern kmutex_t amd_iommu_global_lock; 4596732dbb3SVikram Hegde extern amd_iommu_alias_t **amd_iommu_alias; 4606732dbb3SVikram Hegde extern amd_iommu_page_table_hash_t amd_iommu_page_table_hash; 4616732dbb3SVikram Hegde extern ddi_device_acc_attr_t amd_iommu_devacc; 4626732dbb3SVikram Hegde extern amd_iommu_debug_t amd_iommu_debug; 4636732dbb3SVikram Hegde 4646732dbb3SVikram Hegde extern uint8_t amd_iommu_htatsresv; 4656732dbb3SVikram Hegde extern uint8_t amd_iommu_vasize; 4666732dbb3SVikram Hegde extern uint8_t amd_iommu_pasize; 4676732dbb3SVikram Hegde extern int amd_iommu_64bit_bug; 4686732dbb3SVikram Hegde extern int amd_iommu_unity_map; 4696732dbb3SVikram Hegde extern int amd_iommu_no_RW_perms; 4706732dbb3SVikram Hegde extern int amd_iommu_no_unmap; 4716732dbb3SVikram Hegde extern int amd_iommu_pageva_inval_all; 4726732dbb3SVikram Hegde extern int amd_iommu_disable; 4736732dbb3SVikram Hegde extern char *amd_iommu_disable_list; 4746732dbb3SVikram Hegde 4756732dbb3SVikram Hegde extern uint64_t amd_iommu_reg_get64_workaround(uint64_t *regp, uint32_t bits); 4766732dbb3SVikram Hegde extern uint64_t amd_iommu_reg_set64_workaround(uint64_t *regp, uint32_t bits, 4776732dbb3SVikram Hegde uint64_t value); 478*ba758cf1SJerry Gilliam extern dev_info_t *amd_iommu_pci_dip(dev_info_t *rdip, const char *path); 4796732dbb3SVikram Hegde 4806732dbb3SVikram Hegde int amd_iommu_cmd(amd_iommu_t *iommu, amd_iommu_cmd_t cmd, 4816732dbb3SVikram Hegde amd_iommu_cmdargs_t *cmdargs, amd_iommu_cmd_flags_t flags, int lock_held); 4826732dbb3SVikram Hegde int amd_iommu_page_table_hash_init(amd_iommu_page_table_hash_t *ampt); 4836732dbb3SVikram Hegde void amd_iommu_page_table_hash_fini(amd_iommu_page_table_hash_t *ampt); 4846732dbb3SVikram Hegde 4856732dbb3SVikram Hegde int amd_iommu_read_log(amd_iommu_t *iommu, amd_iommu_log_op_t op); 4866732dbb3SVikram Hegde void amd_iommu_read_boot_props(void); 4876732dbb3SVikram Hegde void amd_iommu_lookup_conf_props(dev_info_t *dip); 4886732dbb3SVikram Hegde 4896732dbb3SVikram Hegde #endif /* _KERNEL */ 4906732dbb3SVikram Hegde 4916732dbb3SVikram Hegde #ifdef __cplusplus 4926732dbb3SVikram Hegde } 4936732dbb3SVikram Hegde #endif 4946732dbb3SVikram Hegde 4956732dbb3SVikram Hegde #endif /* _AMD_IOMMU_IMPL_H */ 496