17125fcbdSVikram Hegde /* 27125fcbdSVikram Hegde * CDDL HEADER START 37125fcbdSVikram Hegde * 47125fcbdSVikram Hegde * The contents of this file are subject to the terms of the 57125fcbdSVikram Hegde * Common Development and Distribution License (the "License"). 67125fcbdSVikram Hegde * You may not use this file except in compliance with the License. 77125fcbdSVikram Hegde * 87125fcbdSVikram Hegde * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97125fcbdSVikram Hegde * or http://www.opensolaris.org/os/licensing. 107125fcbdSVikram Hegde * See the License for the specific language governing permissions 117125fcbdSVikram Hegde * and limitations under the License. 127125fcbdSVikram Hegde * 137125fcbdSVikram Hegde * When distributing Covered Code, include this CDDL HEADER in each 147125fcbdSVikram Hegde * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157125fcbdSVikram Hegde * If applicable, add the following below this CDDL HEADER, with the 167125fcbdSVikram Hegde * fields enclosed by brackets "[]" replaced with your own identifying 177125fcbdSVikram Hegde * information: Portions Copyright [yyyy] [name of copyright owner] 187125fcbdSVikram Hegde * 197125fcbdSVikram Hegde * CDDL HEADER END 207125fcbdSVikram Hegde */ 217125fcbdSVikram Hegde /* 22*ba758cf1SJerry Gilliam * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 237125fcbdSVikram Hegde */ 247125fcbdSVikram Hegde 257125fcbdSVikram Hegde #ifndef _AMD_IOMMU_IMPL_H 267125fcbdSVikram Hegde #define _AMD_IOMMU_IMPL_H 277125fcbdSVikram Hegde 287125fcbdSVikram Hegde #ifdef __cplusplus 297125fcbdSVikram Hegde extern "C" { 307125fcbdSVikram Hegde #endif 317125fcbdSVikram Hegde 327125fcbdSVikram Hegde #include <sys/pci.h> 337125fcbdSVikram Hegde 347125fcbdSVikram Hegde #ifdef _KERNEL 357125fcbdSVikram Hegde 367125fcbdSVikram Hegde #define AMD_IOMMU_PCI_PROG_IF (0x0) 377125fcbdSVikram Hegde 387125fcbdSVikram Hegde #define AMD_IOMMU_CAP (0x3) 397125fcbdSVikram Hegde 407125fcbdSVikram Hegde #define AMD_IOMMU_REG_SIZE (0x2028) 417125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_SZ (16) 427125fcbdSVikram Hegde #define AMD_IOMMU_CMDBUF_SZ (15) 437125fcbdSVikram Hegde #define AMD_IOMMU_EVENTLOG_SZ (15) 447125fcbdSVikram Hegde #define AMD_IOMMU_DEVENT_SZ (32) 457125fcbdSVikram Hegde #define AMD_IOMMU_CMD_SZ (16) 467125fcbdSVikram Hegde #define AMD_IOMMU_EVENT_SZ (16) 477125fcbdSVikram Hegde 487125fcbdSVikram Hegde /* Capability Register offsets */ 497125fcbdSVikram Hegde #define AMD_IOMMU_CAP_HDR_OFF (0x00) 507125fcbdSVikram Hegde #define AMD_IOMMU_CAP_ADDR_LOW_OFF (0x04) 517125fcbdSVikram Hegde #define AMD_IOMMU_CAP_ADDR_HI_OFF (0x08) 527125fcbdSVikram Hegde #define AMD_IOMMU_CAP_RANGE_OFF (0x0C) 537125fcbdSVikram Hegde #define AMD_IOMMU_CAP_MISC_OFF (0x10) 547125fcbdSVikram Hegde 557125fcbdSVikram Hegde /* ControL Registers offsets */ 567125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_REG_OFF (0x00) 577125fcbdSVikram Hegde #define AMD_IOMMU_CMDBUF_REG_OFF (0x08) 587125fcbdSVikram Hegde #define AMD_IOMMU_EVENTLOG_REG_OFF (0x10) 597125fcbdSVikram Hegde #define AMD_IOMMU_CTRL_REG_OFF (0x18) 607125fcbdSVikram Hegde #define AMD_IOMMU_EXCL_BASE_REG_OFF (0x20) 617125fcbdSVikram Hegde #define AMD_IOMMU_EXCL_LIM_REG_OFF (0x28) 627125fcbdSVikram Hegde #define AMD_IOMMU_CMDBUF_HEAD_REG_OFF (0x2000) 637125fcbdSVikram Hegde #define AMD_IOMMU_CMDBUF_TAIL_REG_OFF (0x2008) 647125fcbdSVikram Hegde #define AMD_IOMMU_EVENTLOG_HEAD_REG_OFF (0x2010) 657125fcbdSVikram Hegde #define AMD_IOMMU_EVENTLOG_TAIL_REG_OFF (0x2018) 667125fcbdSVikram Hegde #define AMD_IOMMU_STATUS_REG_OFF (0x2020) 677125fcbdSVikram Hegde 687125fcbdSVikram Hegde /* Capability Header Register Bits */ 697125fcbdSVikram Hegde #define AMD_IOMMU_CAP_NPCACHE (26 << 16 | 26) 707125fcbdSVikram Hegde #define AMD_IOMMU_CAP_HTTUN (25 << 16 | 25) 717125fcbdSVikram Hegde #define AMD_IOMMU_CAP_IOTLB (24 << 16 | 24) 727125fcbdSVikram Hegde #define AMD_IOMMU_CAP_TYPE (18 << 16 | 16) 737125fcbdSVikram Hegde #define AMD_IOMMU_CAP_ID (7 << 16 | 0) 747125fcbdSVikram Hegde 757125fcbdSVikram Hegde /* Capability Range Register bits */ 767125fcbdSVikram Hegde #define AMD_IOMMU_LAST_DEVFN (31 << 16 | 24) 777125fcbdSVikram Hegde #define AMD_IOMMU_FIRST_DEVFN (23 << 16 | 16) 787125fcbdSVikram Hegde #define AMD_IOMMU_RNG_BUS (15 << 16 | 8) 797125fcbdSVikram Hegde #define AMD_IOMMU_RNG_VALID (7 << 16 | 7) 807125fcbdSVikram Hegde #define AMD_IOMMU_HT_UNITID (4 << 16 | 0) 817125fcbdSVikram Hegde 827125fcbdSVikram Hegde 837125fcbdSVikram Hegde /* Capability Misc Register bits */ 847125fcbdSVikram Hegde #define AMD_IOMMU_HT_ATSRSV (22 << 16 | 22) 857125fcbdSVikram Hegde #define AMD_IOMMU_VA_SIZE (21 << 16 | 15) 867125fcbdSVikram Hegde #define AMD_IOMMU_PA_SIZE (14 << 16 | 8) 877125fcbdSVikram Hegde #define AMD_IOMMU_MSINUM (4 << 16 | 0) 887125fcbdSVikram Hegde 897125fcbdSVikram Hegde /* Device Table Base Address register bits */ 907125fcbdSVikram Hegde #define AMD_IOMMU_DEVTABBASE (51 << 16 | 12) 917125fcbdSVikram Hegde #define AMD_IOMMU_DEVTABSIZE (8 << 16 | 0) 927125fcbdSVikram Hegde 937125fcbdSVikram Hegde /* Command Buffer Base Address register bits */ 947125fcbdSVikram Hegde #define AMD_IOMMU_COMLEN (59 << 16 | 56) 957125fcbdSVikram Hegde #define AMD_IOMMU_COMBASE (51 << 16 | 12) 967125fcbdSVikram Hegde 977125fcbdSVikram Hegde #define AMD_IOMMU_CMDBUF_MINSZ (8) 987125fcbdSVikram Hegde #define AMD_IOMMU_CMDBUF_MAXSZ (15) 997125fcbdSVikram Hegde 1007125fcbdSVikram Hegde /* Event Log Base Address register bits */ 1017125fcbdSVikram Hegde #define AMD_IOMMU_EVENTLEN (59 << 16 | 56) 1027125fcbdSVikram Hegde #define AMD_IOMMU_EVENTBASE (51 << 16 | 12) 1037125fcbdSVikram Hegde 1047125fcbdSVikram Hegde #define AMD_IOMMU_EVENTLOG_MINSZ (8) 1057125fcbdSVikram Hegde #define AMD_IOMMU_EVENTLOG_MAXSZ (15) 1067125fcbdSVikram Hegde 1077125fcbdSVikram Hegde /* Control register bits */ 1087125fcbdSVikram Hegde #define AMD_IOMMU_CMDBUF_ENABLE (12 << 16 | 12) 10994f1124eSVikram Hegde #define AMD_IOMMU_ISOC (11 << 16 | 11) 11094f1124eSVikram Hegde #define AMD_IOMMU_COHERENT (10 << 16 | 10) 11194f1124eSVikram Hegde #define AMD_IOMMU_RESPASSPW (9 << 16 | 9) 11294f1124eSVikram Hegde #define AMD_IOMMU_PASSPW (8 << 16 | 8) 11394f1124eSVikram Hegde #define AMD_IOMMU_INVTO (7 << 16 | 5) 1147125fcbdSVikram Hegde #define AMD_IOMMU_COMWAITINT_ENABLE (4 << 16 | 4) 1157125fcbdSVikram Hegde #define AMD_IOMMU_EVENTINT_ENABLE (3 << 16 | 3) 1167125fcbdSVikram Hegde #define AMD_IOMMU_EVENTLOG_ENABLE (2 << 16 | 2) 1177125fcbdSVikram Hegde #define AMD_IOMMU_HT_TUN_ENABLE (1 << 16 | 1) 1187125fcbdSVikram Hegde #define AMD_IOMMU_ENABLE (0 << 16 | 0) 1197125fcbdSVikram Hegde 1207125fcbdSVikram Hegde /* Exclusion Base Register bits */ 1217125fcbdSVikram Hegde #define AMD_IOMMU_EXCL_BASE_ADDR (51 << 16 | 12) 1227125fcbdSVikram Hegde #define AMD_IOMMU_EXCL_BASE_ALLOW (1 << 16 | 1) 1237125fcbdSVikram Hegde #define AMD_IOMMU_EXCL_BASE_EXEN (0 << 16 | 0) 1247125fcbdSVikram Hegde 1257125fcbdSVikram Hegde /* Exclusion Limit Register bits */ 1267125fcbdSVikram Hegde #define AMD_IOMMU_EXCL_LIM (51 << 16 | 12) 1277125fcbdSVikram Hegde 1287125fcbdSVikram Hegde /* Command Buffer Head Pointer Register bits */ 1297125fcbdSVikram Hegde #define AMD_IOMMU_CMDHEADPTR (18 << 16 | 4) 1307125fcbdSVikram Hegde 1317125fcbdSVikram Hegde /* Command Buffer Tail Pointer Register bits */ 1327125fcbdSVikram Hegde #define AMD_IOMMU_CMDTAILPTR (18 << 16 | 4) 1337125fcbdSVikram Hegde 1347125fcbdSVikram Hegde /* Event Log Head Pointer Register bits */ 1357125fcbdSVikram Hegde #define AMD_IOMMU_EVENTHEADPTR (18 << 16 | 4) 1367125fcbdSVikram Hegde 1377125fcbdSVikram Hegde /* Event Log Tail Pointer Register bits */ 1387125fcbdSVikram Hegde #define AMD_IOMMU_EVENTTAILPTR (18 << 16 | 4) 1397125fcbdSVikram Hegde 1407125fcbdSVikram Hegde /* Status Register bits */ 14194f1124eSVikram Hegde #define AMD_IOMMU_CMDBUF_RUN (4 << 16 | 4) 14294f1124eSVikram Hegde #define AMD_IOMMU_EVENT_LOG_RUN (3 << 16 | 3) 1437125fcbdSVikram Hegde #define AMD_IOMMU_COMWAIT_INT (2 << 16 | 2) 1447125fcbdSVikram Hegde #define AMD_IOMMU_EVENT_LOG_INT (1 << 16 | 1) 1457125fcbdSVikram Hegde #define AMD_IOMMU_EVENT_OVERFLOW_INT (0 << 16 | 0) 1467125fcbdSVikram Hegde 1477125fcbdSVikram Hegde /* Device Table Bits */ 1487125fcbdSVikram Hegde 1497125fcbdSVikram Hegde /* size in bytes of each device table entry */ 1507125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_ENTRY_SZ (32) 1517125fcbdSVikram Hegde 1527125fcbdSVikram Hegde /* Interrupt Remapping related Device Table bits */ 1537125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_LINT1PASS ((191-128) << 16 | (191-128)) 1547125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_LINT0PASS ((190-128) << 16 | (190-128)) 1557125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_INTCTL ((189-128) << 16 | (188-128)) 1567125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_NMIPASS ((186-128) << 16 | (186-128)) 1577125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_EXTINTPAS ((185-128) << 16 | (185-128)) 1587125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_INITPASS ((184-128) << 16 | (184-128)) 1597125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_INTR_ROOT ((179-128) << 16 | (134-128)) 1607125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_IG ((133-128) << 16 | (133-128)) 1617125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_INTTABLEN ((132-128) << 16 | (129-128)) 1627125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_IV ((128-128) << 16 | (128-128)) 1637125fcbdSVikram Hegde 1647125fcbdSVikram Hegde /* DMA Remapping related Device Table Bits */ 1657125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_SYSMGT ((105-64) << 16 | (104-64)) 1667125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_EX ((103-64) << 16 | (103-64)) 1677125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_SD ((102-64) << 16 | (102-64)) 1687125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_CACHE ((101-64) << 16 | (101-64)) 1697125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_IOCTL ((100-64) << 16 | (99-64)) 1707125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_SA ((98-64) << 16 | (98-64)) 1717125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_SE ((97-64) << 16 | (97-64)) 1727125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_IOTLB ((96-64) << 16 | (96-64)) 1737125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_DOMAINID ((79-64) << 16 | (64-64)) 1747125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_IW (62 << 16 | 62) 1757125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_IR (61 << 16 | 61) 1767125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_ROOT_PGTBL (51 << 16 | 12) 1777125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_PG_MODE (11 << 16 | 9) 1787125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_TV (1 << 16 | 1) 1797125fcbdSVikram Hegde #define AMD_IOMMU_DEVTBL_V (0 << 16 | 0) 1807125fcbdSVikram Hegde 1817125fcbdSVikram Hegde #define BUS_DEVFN_TO_BDF(b, devfn) (devfn) 1827125fcbdSVikram Hegde #define AMD_IOMMU_ALIAS_HASH_SZ (256) 1837125fcbdSVikram Hegde 1847125fcbdSVikram Hegde #define AMD_IOMMU_REG_ADDR_LOCKED (0x1) 1857125fcbdSVikram Hegde 1867125fcbdSVikram Hegde /* 1877125fcbdSVikram Hegde * IOMMU Command bits 1887125fcbdSVikram Hegde */ 1897125fcbdSVikram Hegde 1907125fcbdSVikram Hegde typedef enum { 1917125fcbdSVikram Hegde AMD_IOMMU_CMD_INVAL = 0, 1927125fcbdSVikram Hegde AMD_IOMMU_CMD_COMPL_WAIT, 1937125fcbdSVikram Hegde AMD_IOMMU_CMD_INVAL_DEVTAB_ENTRY, 1947125fcbdSVikram Hegde AMD_IOMMU_CMD_INVAL_IOMMU_PAGES, 1957125fcbdSVikram Hegde AMD_IOMMU_CMD_INVAL_IOTLB_PAGES, 1967125fcbdSVikram Hegde AMD_IOMMU_CMD_INVAL_INTR_TABLE, 1977125fcbdSVikram Hegde } amd_iommu_cmd_t; 1987125fcbdSVikram Hegde 1997125fcbdSVikram Hegde typedef enum { 2007125fcbdSVikram Hegde AMD_IOMMU_CMD_FLAGS_NONE = 0, 2017125fcbdSVikram Hegde AMD_IOMMU_CMD_FLAGS_COMPL_WAIT = 1, 2027125fcbdSVikram Hegde AMD_IOMMU_CMD_FLAGS_COMPL_WAIT_F = 2, 2037125fcbdSVikram Hegde AMD_IOMMU_CMD_FLAGS_COMPL_WAIT_S = 4, 2047125fcbdSVikram Hegde AMD_IOMMU_CMD_FLAGS_PAGE_PDE_INVAL = 8, 2057125fcbdSVikram Hegde AMD_IOMMU_CMD_FLAGS_PAGE_INVAL_S = 16, 2067125fcbdSVikram Hegde AMD_IOMMU_CMD_FLAGS_IOTLB_INVAL_S = 32 2077125fcbdSVikram Hegde } amd_iommu_cmd_flags_t; 2087125fcbdSVikram Hegde 2097125fcbdSVikram Hegde /* Common command bits */ 2107125fcbdSVikram Hegde #define AMD_IOMMU_CMD_OPCODE (31 << 16 | 28) 2117125fcbdSVikram Hegde 2127125fcbdSVikram Hegde /* Completion Wait command bits */ 21394f1124eSVikram Hegde #define AMD_IOMMU_CMD_COMPL_WAIT_S (0 << 16 | 0) 2147125fcbdSVikram Hegde #define AMD_IOMMU_CMD_COMPL_WAIT_I (1 << 16 | 1) 2157125fcbdSVikram Hegde #define AMD_IOMMU_CMD_COMPL_WAIT_F (2 << 16 | 2) 2167125fcbdSVikram Hegde #define AMD_IOMMU_CMD_COMPL_WAIT_STORE_ADDR_LO (31 << 16 | 3) 2177125fcbdSVikram Hegde #define AMD_IOMMU_CMD_COMPL_WAIT_STORE_ADDR_HI (19 << 16 | 0) 2187125fcbdSVikram Hegde 2197125fcbdSVikram Hegde /* Invalidate Device Table entry command bits */ 2207125fcbdSVikram Hegde #define AMD_IOMMU_CMD_INVAL_DEVTAB_DEVICEID (15 << 16 | 0) 2217125fcbdSVikram Hegde 2227125fcbdSVikram Hegde /* Invalidate IOMMU Pages command bits */ 2237125fcbdSVikram Hegde #define AMD_IOMMU_CMD_INVAL_PAGES_DOMAINID (15 << 16 | 0) 2247125fcbdSVikram Hegde #define AMD_IOMMU_CMD_INVAL_PAGES_S (0 << 16 | 0) 22594f1124eSVikram Hegde #define AMD_IOMMU_CMD_INVAL_PAGES_PDE (1 << 16 | 1) 2267125fcbdSVikram Hegde #define AMD_IOMMU_CMD_INVAL_PAGES_ADDR_LO (31 << 16 | 12) 2277125fcbdSVikram Hegde #define AMD_IOMMU_CMD_INVAL_PAGES_ADDR_HI (63 << 16 | 32) 2287125fcbdSVikram Hegde 2297125fcbdSVikram Hegde 2307125fcbdSVikram Hegde /* Invalidate IOTLB command bits */ 2317125fcbdSVikram Hegde #define AMD_IOMMU_CMD_INVAL_IOTLB_DEVICEID (15 << 16 | 0) 2327125fcbdSVikram Hegde #define AMD_IOMMU_CMD_INVAL_IOTLB_MAXPEND (31 << 16 | 24) 2337125fcbdSVikram Hegde #define AMD_IOMMU_CMD_INVAL_IOTLB_QUEUEID (15 << 16 | 0) 2347125fcbdSVikram Hegde #define AMD_IOMMU_CMD_INVAL_IOTLB_S (0 << 16 | 0) 2357125fcbdSVikram Hegde #define AMD_IOMMU_CMD_INVAL_IOTLB_ADDR_LO (31 << 16 | 12) 23694f1124eSVikram Hegde #define AMD_IOMMU_CMD_INVAL_IOTLB_ADDR_HI (31 << 16 | 0) 2377125fcbdSVikram Hegde 2387125fcbdSVikram Hegde #define AMD_IOMMU_DEFAULT_MAXPEND (10) 2397125fcbdSVikram Hegde 2407125fcbdSVikram Hegde /* Invalidate Interrupt Table bits */ 2417125fcbdSVikram Hegde #define AMD_IOMMU_CMD_INVAL_INTR_DEVICEID (15 << 16 | 0) 2427125fcbdSVikram Hegde 2430412ba67SVikram Hegde #if defined(__amd64) 2447125fcbdSVikram Hegde #define dmac_cookie_addr dmac_laddress 2457125fcbdSVikram Hegde #else 2467125fcbdSVikram Hegde #define dmac_cookie_addr dmac_address 2477125fcbdSVikram Hegde #endif 2487125fcbdSVikram Hegde 2497125fcbdSVikram Hegde #define AMD_IOMMU_TABLE_ALIGN ((1ULL << 12) - 1) 2507125fcbdSVikram Hegde 25194f1124eSVikram Hegde #define AMD_IOMMU_MAX_DEVICEID (0xFFFF) 25294f1124eSVikram Hegde 2537125fcbdSVikram Hegde /* 2547125fcbdSVikram Hegde * DMA sync macros 25594f1124eSVikram Hegde * TODO: optimize sync only small ranges 2567125fcbdSVikram Hegde */ 2577125fcbdSVikram Hegde #define SYNC_FORDEV(h) (void) ddi_dma_sync(h, 0, 0, DDI_DMA_SYNC_FORDEV) 2587125fcbdSVikram Hegde #define SYNC_FORKERN(h) (void) ddi_dma_sync(h, 0, 0, DDI_DMA_SYNC_FORKERNEL) 2597125fcbdSVikram Hegde 2607125fcbdSVikram Hegde #define WAIT_SEC(s) drv_usecwait(1000000*(s)) 2617125fcbdSVikram Hegde 2627125fcbdSVikram Hegde #define CMD2OFF(c) ((c) << 4) 2637125fcbdSVikram Hegde #define OFF2CMD(o) ((o) >> 4) 2647125fcbdSVikram Hegde 26594f1124eSVikram Hegde typedef union split { 26694f1124eSVikram Hegde uint64_t u64; 26794f1124eSVikram Hegde uint32_t u32[2]; 26894f1124eSVikram Hegde } split_t; 26994f1124eSVikram Hegde 27094f1124eSVikram Hegde #define BITPOS_START(b) ((b) >> 16) 27194f1124eSVikram Hegde #define BITPOS_END(b) ((b) & 0xFFFF) 27294f1124eSVikram Hegde 27394f1124eSVikram Hegde #define START_MASK64(s) (((s) == 63) ? ~((uint64_t)0) : \ 27494f1124eSVikram Hegde (uint64_t)((1ULL << ((s)+1)) - 1)) 27594f1124eSVikram Hegde #define START_MASK32(s) (((s) == 31) ? ~((uint32_t)0) : \ 27694f1124eSVikram Hegde (uint32_t)((1ULL << ((s)+1)) - 1)) 27794f1124eSVikram Hegde #define START_MASK16(s) (((s) == 15) ? ~((uint16_t)0) : \ 27894f1124eSVikram Hegde (uint16_t)((1ULL << ((s)+1)) - 1)) 27994f1124eSVikram Hegde #define START_MASK8(s) (((s) == 7) ? ~((uint8_t)0) : \ 28094f1124eSVikram Hegde (uint8_t)((1ULL << ((s)+1)) - 1)) 28194f1124eSVikram Hegde 28294f1124eSVikram Hegde #define END_MASK(e) ((1ULL << (e)) - 1) 28394f1124eSVikram Hegde 28494f1124eSVikram Hegde #define BIT_MASK64(s, e) (uint64_t)(START_MASK64(s) & ~END_MASK(e)) 28594f1124eSVikram Hegde #define BIT_MASK32(s, e) (uint32_t)(START_MASK32(s) & ~END_MASK(e)) 28694f1124eSVikram Hegde #define BIT_MASK16(s, e) (uint16_t)(START_MASK16(s) & ~END_MASK(e)) 28794f1124eSVikram Hegde #define BIT_MASK8(s, e) (uint8_t)(START_MASK8(s) & ~END_MASK(e)) 28894f1124eSVikram Hegde 28994f1124eSVikram Hegde #define AMD_IOMMU_REG_GET64_IMPL(rp, b) \ 29094f1124eSVikram Hegde (((*(rp)) & (START_MASK64(BITPOS_START(b)))) >> BITPOS_END(b)) 29194f1124eSVikram Hegde #define AMD_IOMMU_REG_GET64(rp, b) \ 29294f1124eSVikram Hegde ((amd_iommu_64bit_bug) ? amd_iommu_reg_get64_workaround(rp, b) : \ 29394f1124eSVikram Hegde AMD_IOMMU_REG_GET64_IMPL(rp, b)) 29494f1124eSVikram Hegde #define AMD_IOMMU_REG_GET32(rp, b) \ 29594f1124eSVikram Hegde (((*(rp)) & (START_MASK32(BITPOS_START(b)))) >> BITPOS_END(b)) 29694f1124eSVikram Hegde #define AMD_IOMMU_REG_GET16(rp, b) \ 29794f1124eSVikram Hegde (((*(rp)) & (START_MASK16(BITPOS_START(b)))) >> BITPOS_END(b)) 29894f1124eSVikram Hegde #define AMD_IOMMU_REG_GET8(rp, b) \ 29994f1124eSVikram Hegde (((*(rp)) & (START_MASK8(BITPOS_START(b)))) >> BITPOS_END(b)) 30094f1124eSVikram Hegde 30194f1124eSVikram Hegde #define AMD_IOMMU_REG_SET64_IMPL(rp, b, v) \ 30294f1124eSVikram Hegde ((*(rp)) = \ 30394f1124eSVikram Hegde (((uint64_t)(*(rp)) & ~(BIT_MASK64(BITPOS_START(b), BITPOS_END(b)))) \ 30494f1124eSVikram Hegde | ((uint64_t)(v) << BITPOS_END(b)))) 30594f1124eSVikram Hegde 30694f1124eSVikram Hegde #define AMD_IOMMU_REG_SET64(rp, b, v) \ 30794f1124eSVikram Hegde (void) ((amd_iommu_64bit_bug) ? \ 30894f1124eSVikram Hegde amd_iommu_reg_set64_workaround(rp, b, v) : \ 30994f1124eSVikram Hegde AMD_IOMMU_REG_SET64_IMPL(rp, b, v)) 31094f1124eSVikram Hegde 31194f1124eSVikram Hegde #define AMD_IOMMU_REG_SET32(rp, b, v) \ 31294f1124eSVikram Hegde ((*(rp)) = \ 31394f1124eSVikram Hegde (((uint32_t)(*(rp)) & ~(BIT_MASK32(BITPOS_START(b), BITPOS_END(b)))) \ 31494f1124eSVikram Hegde | ((uint32_t)(v) << BITPOS_END(b)))) 31594f1124eSVikram Hegde 31694f1124eSVikram Hegde #define AMD_IOMMU_REG_SET16(rp, b, v) \ 31794f1124eSVikram Hegde ((*(rp)) = \ 31894f1124eSVikram Hegde (((uint16_t)(*(rp)) & ~(BIT_MASK16(BITPOS_START(b), BITPOS_END(b)))) \ 31994f1124eSVikram Hegde | ((uint16_t)(v) << BITPOS_END(b)))) 32094f1124eSVikram Hegde 32194f1124eSVikram Hegde #define AMD_IOMMU_REG_SET8(rp, b, v) \ 32294f1124eSVikram Hegde ((*(rp)) = \ 32394f1124eSVikram Hegde (((uint8_t)(*(rp)) & ~(BIT_MASK8(BITPOS_START(b), BITPOS_END(b)))) \ 32494f1124eSVikram Hegde | ((uint8_t)(v) << BITPOS_END(b)))) 32594f1124eSVikram Hegde 3267125fcbdSVikram Hegde /* 32794f1124eSVikram Hegde * Cast a 64 bit pointer to a uint64_t * 3287125fcbdSVikram Hegde */ 32994f1124eSVikram Hegde #define REGADDR64(a) ((uint64_t *)(uintptr_t)(a)) 33094f1124eSVikram Hegde 33194f1124eSVikram Hegde typedef enum { 33294f1124eSVikram Hegde AMD_IOMMU_INTR_INVALID = 0, 33394f1124eSVikram Hegde AMD_IOMMU_INTR_TABLE, 33494f1124eSVikram Hegde AMD_IOMMU_INTR_ALLOCED, 33594f1124eSVikram Hegde AMD_IOMMU_INTR_HANDLER, 33694f1124eSVikram Hegde AMD_IOMMU_INTR_ENABLED 33794f1124eSVikram Hegde } amd_iommu_intr_state_t; 33894f1124eSVikram Hegde 3397125fcbdSVikram Hegde 3407125fcbdSVikram Hegde typedef struct amd_iommu { 3417125fcbdSVikram Hegde kmutex_t aiomt_mutex; 3427125fcbdSVikram Hegde kmutex_t aiomt_eventlock; 34394f1124eSVikram Hegde kmutex_t aiomt_cmdlock; 3447125fcbdSVikram Hegde dev_info_t *aiomt_dip; 345*ba758cf1SJerry Gilliam uint16_t aiomt_bdf; 3467125fcbdSVikram Hegde int aiomt_idx; 3477125fcbdSVikram Hegde iommulib_handle_t aiomt_iommulib_handle; 3487125fcbdSVikram Hegde iommulib_ops_t *aiomt_iommulib_ops; 3497125fcbdSVikram Hegde uint32_t aiomt_cap_hdr; 3507125fcbdSVikram Hegde uint8_t aiomt_npcache; 3517125fcbdSVikram Hegde uint8_t aiomt_httun; 3527125fcbdSVikram Hegde uint8_t aiomt_iotlb; 3537125fcbdSVikram Hegde uint8_t aiomt_captype; 3547125fcbdSVikram Hegde uint8_t aiomt_capid; 3557125fcbdSVikram Hegde uint32_t aiomt_low_addr32; 3567125fcbdSVikram Hegde uint32_t aiomt_hi_addr32; 3577125fcbdSVikram Hegde uint64_t aiomt_reg_pa; 35894f1124eSVikram Hegde uint64_t aiomt_va; 3597125fcbdSVikram Hegde uint64_t aiomt_reg_va; 3607125fcbdSVikram Hegde uint32_t aiomt_range; 3617125fcbdSVikram Hegde uint8_t aiomt_rng_bus; 3627125fcbdSVikram Hegde uint8_t aiomt_first_devfn; 3637125fcbdSVikram Hegde uint8_t aiomt_last_devfn; 3647125fcbdSVikram Hegde uint8_t aiomt_rng_valid; 3657125fcbdSVikram Hegde uint8_t aiomt_ht_unitid; 3667125fcbdSVikram Hegde uint32_t aiomt_misc; 3677125fcbdSVikram Hegde uint8_t aiomt_htatsresv; 3687125fcbdSVikram Hegde uint8_t aiomt_vasize; 3697125fcbdSVikram Hegde uint8_t aiomt_pasize; 3707125fcbdSVikram Hegde uint8_t aiomt_msinum; 3717125fcbdSVikram Hegde uint8_t aiomt_reg_pages; 3727125fcbdSVikram Hegde uint32_t aiomt_reg_size; 3737125fcbdSVikram Hegde uint32_t aiomt_devtbl_sz; 3747125fcbdSVikram Hegde uint32_t aiomt_cmdbuf_sz; 3757125fcbdSVikram Hegde uint32_t aiomt_eventlog_sz; 3767125fcbdSVikram Hegde caddr_t aiomt_devtbl; 3777125fcbdSVikram Hegde caddr_t aiomt_cmdbuf; 3787125fcbdSVikram Hegde caddr_t aiomt_eventlog; 3797125fcbdSVikram Hegde uint32_t *aiomt_cmd_tail; 3807125fcbdSVikram Hegde uint32_t *aiomt_event_head; 3817125fcbdSVikram Hegde ddi_dma_handle_t aiomt_dmahdl; 3827125fcbdSVikram Hegde void *aiomt_dma_bufva; 3837125fcbdSVikram Hegde uint64_t aiomt_dma_mem_realsz; 3847125fcbdSVikram Hegde ddi_acc_handle_t aiomt_dma_mem_hdl; 3857125fcbdSVikram Hegde ddi_dma_cookie_t aiomt_buf_dma_cookie; 3867125fcbdSVikram Hegde uint_t aiomt_buf_dma_ncookie; 3877125fcbdSVikram Hegde amd_iommu_intr_state_t aiomt_intr_state; 3887125fcbdSVikram Hegde ddi_intr_handle_t *aiomt_intr_htable; 3897125fcbdSVikram Hegde uint32_t aiomt_intr_htable_sz; 3907125fcbdSVikram Hegde uint32_t aiomt_actual_intrs; 3917125fcbdSVikram Hegde uint32_t aiomt_intr_cap; 3927125fcbdSVikram Hegde uint64_t aiomt_reg_devtbl_va; 3937125fcbdSVikram Hegde uint64_t aiomt_reg_cmdbuf_va; 3947125fcbdSVikram Hegde uint64_t aiomt_reg_eventlog_va; 3957125fcbdSVikram Hegde uint64_t aiomt_reg_ctrl_va; 3967125fcbdSVikram Hegde uint64_t aiomt_reg_excl_base_va; 3977125fcbdSVikram Hegde uint64_t aiomt_reg_excl_lim_va; 3987125fcbdSVikram Hegde uint64_t aiomt_reg_cmdbuf_head_va; 3997125fcbdSVikram Hegde uint64_t aiomt_reg_cmdbuf_tail_va; 4007125fcbdSVikram Hegde uint64_t aiomt_reg_eventlog_head_va; 4017125fcbdSVikram Hegde uint64_t aiomt_reg_eventlog_tail_va; 4027125fcbdSVikram Hegde uint64_t aiomt_reg_status_va; 4037125fcbdSVikram Hegde struct amd_iommu *aiomt_next; 4047125fcbdSVikram Hegde } amd_iommu_t; 4057125fcbdSVikram Hegde 4067125fcbdSVikram Hegde typedef struct amd_iommu_dma_devtbl_ent { 4077125fcbdSVikram Hegde uint16_t de_domainid; 4087125fcbdSVikram Hegde uint8_t de_R; 4097125fcbdSVikram Hegde uint8_t de_W; 4107125fcbdSVikram Hegde caddr_t de_root_pgtbl; 4117125fcbdSVikram Hegde uint8_t de_pgmode; 4127125fcbdSVikram Hegde } amd_iommu_dma_devtbl_entry_t; 4137125fcbdSVikram Hegde 4147125fcbdSVikram Hegde typedef struct amd_iommu_alias { 4157125fcbdSVikram Hegde uint16_t al_bdf; 4167125fcbdSVikram Hegde uint16_t al_src_bdf; 4177125fcbdSVikram Hegde struct amd_iommu_alias *al_next; 4187125fcbdSVikram Hegde } amd_iommu_alias_t; 4197125fcbdSVikram Hegde 4207125fcbdSVikram Hegde typedef struct amd_iommu_cmdargs { 42194f1124eSVikram Hegde uint64_t ca_addr; 4227125fcbdSVikram Hegde uint16_t ca_domainid; 4237125fcbdSVikram Hegde uint16_t ca_deviceid; 4247125fcbdSVikram Hegde } amd_iommu_cmdargs_t; 4257125fcbdSVikram Hegde 4267125fcbdSVikram Hegde struct amd_iommu_page_table; 4277125fcbdSVikram Hegde 4287125fcbdSVikram Hegde typedef struct amd_iommu_page_table_hash { 4297125fcbdSVikram Hegde kmutex_t ampt_lock; 4307125fcbdSVikram Hegde struct amd_iommu_page_table **ampt_hash; 4317125fcbdSVikram Hegde } amd_iommu_page_table_hash_t; 4327125fcbdSVikram Hegde 43394f1124eSVikram Hegde typedef enum { 43494f1124eSVikram Hegde AMD_IOMMU_LOG_INVALID_OP = 0, 43594f1124eSVikram Hegde AMD_IOMMU_LOG_DISPLAY, 43694f1124eSVikram Hegde AMD_IOMMU_LOG_DISCARD 43794f1124eSVikram Hegde } amd_iommu_log_op_t; 43894f1124eSVikram Hegde 4397125fcbdSVikram Hegde typedef enum { 4407125fcbdSVikram Hegde AMD_IOMMU_DEBUG_NONE = 0, 4417125fcbdSVikram Hegde AMD_IOMMU_DEBUG_ALLOCHDL = 0x1, 4427125fcbdSVikram Hegde AMD_IOMMU_DEBUG_FREEHDL = 0x2, 4437125fcbdSVikram Hegde AMD_IOMMU_DEBUG_BIND = 0x4, 4447125fcbdSVikram Hegde AMD_IOMMU_DEBUG_UNBIND = 0x8, 4457125fcbdSVikram Hegde AMD_IOMMU_DEBUG_WIN = 0x10, 4467125fcbdSVikram Hegde AMD_IOMMU_DEBUG_PAGE_TABLES = 0x20, 4477125fcbdSVikram Hegde AMD_IOMMU_DEBUG_DEVTBL = 0x40, 4487125fcbdSVikram Hegde AMD_IOMMU_DEBUG_CMDBUF = 0x80, 4497125fcbdSVikram Hegde AMD_IOMMU_DEBUG_EVENTLOG = 0x100, 45094f1124eSVikram Hegde AMD_IOMMU_DEBUG_ACPI = 0x200, 45194f1124eSVikram Hegde AMD_IOMMU_DEBUG_PA2VA = 0x400, 45294f1124eSVikram Hegde AMD_IOMMU_DEBUG_TABLES = 0x800, 45394f1124eSVikram Hegde AMD_IOMMU_DEBUG_EXCL = 0x1000, 45494f1124eSVikram Hegde AMD_IOMMU_DEBUG_INTR = 0x2000 4557125fcbdSVikram Hegde } amd_iommu_debug_t; 4567125fcbdSVikram Hegde 4577125fcbdSVikram Hegde extern const char *amd_iommu_modname; 4587125fcbdSVikram Hegde extern kmutex_t amd_iommu_global_lock; 4597125fcbdSVikram Hegde extern amd_iommu_alias_t **amd_iommu_alias; 4607125fcbdSVikram Hegde extern amd_iommu_page_table_hash_t amd_iommu_page_table_hash; 4617125fcbdSVikram Hegde extern ddi_device_acc_attr_t amd_iommu_devacc; 4627125fcbdSVikram Hegde extern amd_iommu_debug_t amd_iommu_debug; 4637125fcbdSVikram Hegde 4647125fcbdSVikram Hegde extern uint8_t amd_iommu_htatsresv; 4657125fcbdSVikram Hegde extern uint8_t amd_iommu_vasize; 4667125fcbdSVikram Hegde extern uint8_t amd_iommu_pasize; 46794f1124eSVikram Hegde extern int amd_iommu_64bit_bug; 46894f1124eSVikram Hegde extern int amd_iommu_unity_map; 46994f1124eSVikram Hegde extern int amd_iommu_no_RW_perms; 47094f1124eSVikram Hegde extern int amd_iommu_no_unmap; 47194f1124eSVikram Hegde extern int amd_iommu_pageva_inval_all; 47294f1124eSVikram Hegde extern int amd_iommu_disable; 47394f1124eSVikram Hegde extern char *amd_iommu_disable_list; 47494f1124eSVikram Hegde 47594f1124eSVikram Hegde extern uint64_t amd_iommu_reg_get64_workaround(uint64_t *regp, uint32_t bits); 47694f1124eSVikram Hegde extern uint64_t amd_iommu_reg_set64_workaround(uint64_t *regp, uint32_t bits, 47794f1124eSVikram Hegde uint64_t value); 478*ba758cf1SJerry Gilliam extern dev_info_t *amd_iommu_pci_dip(dev_info_t *rdip, const char *path); 4797125fcbdSVikram Hegde 4807125fcbdSVikram Hegde int amd_iommu_cmd(amd_iommu_t *iommu, amd_iommu_cmd_t cmd, 4817125fcbdSVikram Hegde amd_iommu_cmdargs_t *cmdargs, amd_iommu_cmd_flags_t flags, int lock_held); 4827125fcbdSVikram Hegde int amd_iommu_page_table_hash_init(amd_iommu_page_table_hash_t *ampt); 4837125fcbdSVikram Hegde void amd_iommu_page_table_hash_fini(amd_iommu_page_table_hash_t *ampt); 4847125fcbdSVikram Hegde 48594f1124eSVikram Hegde int amd_iommu_read_log(amd_iommu_t *iommu, amd_iommu_log_op_t op); 48694f1124eSVikram Hegde void amd_iommu_read_boot_props(void); 48794f1124eSVikram Hegde void amd_iommu_lookup_conf_props(dev_info_t *dip); 4887125fcbdSVikram Hegde 4897125fcbdSVikram Hegde #endif /* _KERNEL */ 4907125fcbdSVikram Hegde 4917125fcbdSVikram Hegde #ifdef __cplusplus 4927125fcbdSVikram Hegde } 4937125fcbdSVikram Hegde #endif 4947125fcbdSVikram Hegde 4957125fcbdSVikram Hegde #endif /* _AMD_IOMMU_IMPL_H */ 496