110535SVikram.Hegde@Sun.COM /* 210535SVikram.Hegde@Sun.COM * CDDL HEADER START 310535SVikram.Hegde@Sun.COM * 410535SVikram.Hegde@Sun.COM * The contents of this file are subject to the terms of the 510535SVikram.Hegde@Sun.COM * Common Development and Distribution License (the "License"). 610535SVikram.Hegde@Sun.COM * You may not use this file except in compliance with the License. 710535SVikram.Hegde@Sun.COM * 810535SVikram.Hegde@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 910535SVikram.Hegde@Sun.COM * or http://www.opensolaris.org/os/licensing. 1010535SVikram.Hegde@Sun.COM * See the License for the specific language governing permissions 1110535SVikram.Hegde@Sun.COM * and limitations under the License. 1210535SVikram.Hegde@Sun.COM * 1310535SVikram.Hegde@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 1410535SVikram.Hegde@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1510535SVikram.Hegde@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 1610535SVikram.Hegde@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 1710535SVikram.Hegde@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 1810535SVikram.Hegde@Sun.COM * 1910535SVikram.Hegde@Sun.COM * CDDL HEADER END 2010535SVikram.Hegde@Sun.COM */ 2110535SVikram.Hegde@Sun.COM /* 22*12203SJerry.Gilliam@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 2310535SVikram.Hegde@Sun.COM */ 2410535SVikram.Hegde@Sun.COM 2510535SVikram.Hegde@Sun.COM #ifndef _AMD_IOMMU_IMPL_H 2610535SVikram.Hegde@Sun.COM #define _AMD_IOMMU_IMPL_H 2710535SVikram.Hegde@Sun.COM 2810535SVikram.Hegde@Sun.COM #ifdef __cplusplus 2910535SVikram.Hegde@Sun.COM extern "C" { 3010535SVikram.Hegde@Sun.COM #endif 3110535SVikram.Hegde@Sun.COM 3210535SVikram.Hegde@Sun.COM #include <sys/pci.h> 3310535SVikram.Hegde@Sun.COM 3410535SVikram.Hegde@Sun.COM #ifdef _KERNEL 3510535SVikram.Hegde@Sun.COM 3610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_PCI_PROG_IF (0x0) 3710535SVikram.Hegde@Sun.COM 3810535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CAP (0x3) 3910535SVikram.Hegde@Sun.COM 4010535SVikram.Hegde@Sun.COM #define AMD_IOMMU_REG_SIZE (0x2028) 4110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_SZ (16) 4210535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMDBUF_SZ (15) 4310535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENTLOG_SZ (15) 4410535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVENT_SZ (32) 4510535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_SZ (16) 4610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENT_SZ (16) 4710535SVikram.Hegde@Sun.COM 4810535SVikram.Hegde@Sun.COM /* Capability Register offsets */ 4910535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CAP_HDR_OFF (0x00) 5010535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CAP_ADDR_LOW_OFF (0x04) 5110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CAP_ADDR_HI_OFF (0x08) 5210535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CAP_RANGE_OFF (0x0C) 5310535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CAP_MISC_OFF (0x10) 5410535SVikram.Hegde@Sun.COM 5510535SVikram.Hegde@Sun.COM /* ControL Registers offsets */ 5610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_REG_OFF (0x00) 5710535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMDBUF_REG_OFF (0x08) 5810535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENTLOG_REG_OFF (0x10) 5910535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CTRL_REG_OFF (0x18) 6010535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EXCL_BASE_REG_OFF (0x20) 6110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EXCL_LIM_REG_OFF (0x28) 6210535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMDBUF_HEAD_REG_OFF (0x2000) 6310535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMDBUF_TAIL_REG_OFF (0x2008) 6410535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENTLOG_HEAD_REG_OFF (0x2010) 6510535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENTLOG_TAIL_REG_OFF (0x2018) 6610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_STATUS_REG_OFF (0x2020) 6710535SVikram.Hegde@Sun.COM 6810535SVikram.Hegde@Sun.COM /* Capability Header Register Bits */ 6910535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CAP_NPCACHE (26 << 16 | 26) 7010535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CAP_HTTUN (25 << 16 | 25) 7110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CAP_IOTLB (24 << 16 | 24) 7210535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CAP_TYPE (18 << 16 | 16) 7310535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CAP_ID (7 << 16 | 0) 7410535SVikram.Hegde@Sun.COM 7510535SVikram.Hegde@Sun.COM /* Capability Range Register bits */ 7610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_LAST_DEVFN (31 << 16 | 24) 7710535SVikram.Hegde@Sun.COM #define AMD_IOMMU_FIRST_DEVFN (23 << 16 | 16) 7810535SVikram.Hegde@Sun.COM #define AMD_IOMMU_RNG_BUS (15 << 16 | 8) 7910535SVikram.Hegde@Sun.COM #define AMD_IOMMU_RNG_VALID (7 << 16 | 7) 8010535SVikram.Hegde@Sun.COM #define AMD_IOMMU_HT_UNITID (4 << 16 | 0) 8110535SVikram.Hegde@Sun.COM 8210535SVikram.Hegde@Sun.COM 8310535SVikram.Hegde@Sun.COM /* Capability Misc Register bits */ 8410535SVikram.Hegde@Sun.COM #define AMD_IOMMU_HT_ATSRSV (22 << 16 | 22) 8510535SVikram.Hegde@Sun.COM #define AMD_IOMMU_VA_SIZE (21 << 16 | 15) 8610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_PA_SIZE (14 << 16 | 8) 8710535SVikram.Hegde@Sun.COM #define AMD_IOMMU_MSINUM (4 << 16 | 0) 8810535SVikram.Hegde@Sun.COM 8910535SVikram.Hegde@Sun.COM /* Device Table Base Address register bits */ 9010535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTABBASE (51 << 16 | 12) 9110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTABSIZE (8 << 16 | 0) 9210535SVikram.Hegde@Sun.COM 9310535SVikram.Hegde@Sun.COM /* Command Buffer Base Address register bits */ 9410535SVikram.Hegde@Sun.COM #define AMD_IOMMU_COMLEN (59 << 16 | 56) 9510535SVikram.Hegde@Sun.COM #define AMD_IOMMU_COMBASE (51 << 16 | 12) 9610535SVikram.Hegde@Sun.COM 9710535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMDBUF_MINSZ (8) 9810535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMDBUF_MAXSZ (15) 9910535SVikram.Hegde@Sun.COM 10010535SVikram.Hegde@Sun.COM /* Event Log Base Address register bits */ 10110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENTLEN (59 << 16 | 56) 10210535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENTBASE (51 << 16 | 12) 10310535SVikram.Hegde@Sun.COM 10410535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENTLOG_MINSZ (8) 10510535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENTLOG_MAXSZ (15) 10610535SVikram.Hegde@Sun.COM 10710535SVikram.Hegde@Sun.COM /* Control register bits */ 10810535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMDBUF_ENABLE (12 << 16 | 12) 10910535SVikram.Hegde@Sun.COM #define AMD_IOMMU_ISOC (11 << 16 | 11) 11010535SVikram.Hegde@Sun.COM #define AMD_IOMMU_COHERENT (10 << 16 | 10) 11110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_RESPASSPW (9 << 16 | 9) 11210535SVikram.Hegde@Sun.COM #define AMD_IOMMU_PASSPW (8 << 16 | 8) 11310535SVikram.Hegde@Sun.COM #define AMD_IOMMU_INVTO (7 << 16 | 5) 11410535SVikram.Hegde@Sun.COM #define AMD_IOMMU_COMWAITINT_ENABLE (4 << 16 | 4) 11510535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENTINT_ENABLE (3 << 16 | 3) 11610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENTLOG_ENABLE (2 << 16 | 2) 11710535SVikram.Hegde@Sun.COM #define AMD_IOMMU_HT_TUN_ENABLE (1 << 16 | 1) 11810535SVikram.Hegde@Sun.COM #define AMD_IOMMU_ENABLE (0 << 16 | 0) 11910535SVikram.Hegde@Sun.COM 12010535SVikram.Hegde@Sun.COM /* Exclusion Base Register bits */ 12110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EXCL_BASE_ADDR (51 << 16 | 12) 12210535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EXCL_BASE_ALLOW (1 << 16 | 1) 12310535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EXCL_BASE_EXEN (0 << 16 | 0) 12410535SVikram.Hegde@Sun.COM 12510535SVikram.Hegde@Sun.COM /* Exclusion Limit Register bits */ 12610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EXCL_LIM (51 << 16 | 12) 12710535SVikram.Hegde@Sun.COM 12810535SVikram.Hegde@Sun.COM /* Command Buffer Head Pointer Register bits */ 12910535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMDHEADPTR (18 << 16 | 4) 13010535SVikram.Hegde@Sun.COM 13110535SVikram.Hegde@Sun.COM /* Command Buffer Tail Pointer Register bits */ 13210535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMDTAILPTR (18 << 16 | 4) 13310535SVikram.Hegde@Sun.COM 13410535SVikram.Hegde@Sun.COM /* Event Log Head Pointer Register bits */ 13510535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENTHEADPTR (18 << 16 | 4) 13610535SVikram.Hegde@Sun.COM 13710535SVikram.Hegde@Sun.COM /* Event Log Tail Pointer Register bits */ 13810535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENTTAILPTR (18 << 16 | 4) 13910535SVikram.Hegde@Sun.COM 14010535SVikram.Hegde@Sun.COM /* Status Register bits */ 14110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMDBUF_RUN (4 << 16 | 4) 14210535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENT_LOG_RUN (3 << 16 | 3) 14310535SVikram.Hegde@Sun.COM #define AMD_IOMMU_COMWAIT_INT (2 << 16 | 2) 14410535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENT_LOG_INT (1 << 16 | 1) 14510535SVikram.Hegde@Sun.COM #define AMD_IOMMU_EVENT_OVERFLOW_INT (0 << 16 | 0) 14610535SVikram.Hegde@Sun.COM 14710535SVikram.Hegde@Sun.COM /* Device Table Bits */ 14810535SVikram.Hegde@Sun.COM 14910535SVikram.Hegde@Sun.COM /* size in bytes of each device table entry */ 15010535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_ENTRY_SZ (32) 15110535SVikram.Hegde@Sun.COM 15210535SVikram.Hegde@Sun.COM /* Interrupt Remapping related Device Table bits */ 15310535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_LINT1PASS ((191-128) << 16 | (191-128)) 15410535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_LINT0PASS ((190-128) << 16 | (190-128)) 15510535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_INTCTL ((189-128) << 16 | (188-128)) 15610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_NMIPASS ((186-128) << 16 | (186-128)) 15710535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_EXTINTPAS ((185-128) << 16 | (185-128)) 15810535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_INITPASS ((184-128) << 16 | (184-128)) 15910535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_INTR_ROOT ((179-128) << 16 | (134-128)) 16010535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_IG ((133-128) << 16 | (133-128)) 16110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_INTTABLEN ((132-128) << 16 | (129-128)) 16210535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_IV ((128-128) << 16 | (128-128)) 16310535SVikram.Hegde@Sun.COM 16410535SVikram.Hegde@Sun.COM /* DMA Remapping related Device Table Bits */ 16510535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_SYSMGT ((105-64) << 16 | (104-64)) 16610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_EX ((103-64) << 16 | (103-64)) 16710535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_SD ((102-64) << 16 | (102-64)) 16810535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_CACHE ((101-64) << 16 | (101-64)) 16910535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_IOCTL ((100-64) << 16 | (99-64)) 17010535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_SA ((98-64) << 16 | (98-64)) 17110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_SE ((97-64) << 16 | (97-64)) 17210535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_IOTLB ((96-64) << 16 | (96-64)) 17310535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_DOMAINID ((79-64) << 16 | (64-64)) 17410535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_IW (62 << 16 | 62) 17510535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_IR (61 << 16 | 61) 17610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_ROOT_PGTBL (51 << 16 | 12) 17710535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_PG_MODE (11 << 16 | 9) 17810535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_TV (1 << 16 | 1) 17910535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEVTBL_V (0 << 16 | 0) 18010535SVikram.Hegde@Sun.COM 18110535SVikram.Hegde@Sun.COM #define BUS_DEVFN_TO_BDF(b, devfn) (devfn) 18210535SVikram.Hegde@Sun.COM #define AMD_IOMMU_ALIAS_HASH_SZ (256) 18310535SVikram.Hegde@Sun.COM 18410535SVikram.Hegde@Sun.COM #define AMD_IOMMU_REG_ADDR_LOCKED (0x1) 18510535SVikram.Hegde@Sun.COM 18610535SVikram.Hegde@Sun.COM /* 18710535SVikram.Hegde@Sun.COM * IOMMU Command bits 18810535SVikram.Hegde@Sun.COM */ 18910535SVikram.Hegde@Sun.COM 19010535SVikram.Hegde@Sun.COM typedef enum { 19110535SVikram.Hegde@Sun.COM AMD_IOMMU_CMD_INVAL = 0, 19210535SVikram.Hegde@Sun.COM AMD_IOMMU_CMD_COMPL_WAIT, 19310535SVikram.Hegde@Sun.COM AMD_IOMMU_CMD_INVAL_DEVTAB_ENTRY, 19410535SVikram.Hegde@Sun.COM AMD_IOMMU_CMD_INVAL_IOMMU_PAGES, 19510535SVikram.Hegde@Sun.COM AMD_IOMMU_CMD_INVAL_IOTLB_PAGES, 19610535SVikram.Hegde@Sun.COM AMD_IOMMU_CMD_INVAL_INTR_TABLE, 19710535SVikram.Hegde@Sun.COM } amd_iommu_cmd_t; 19810535SVikram.Hegde@Sun.COM 19910535SVikram.Hegde@Sun.COM typedef enum { 20010535SVikram.Hegde@Sun.COM AMD_IOMMU_CMD_FLAGS_NONE = 0, 20110535SVikram.Hegde@Sun.COM AMD_IOMMU_CMD_FLAGS_COMPL_WAIT = 1, 20210535SVikram.Hegde@Sun.COM AMD_IOMMU_CMD_FLAGS_COMPL_WAIT_F = 2, 20310535SVikram.Hegde@Sun.COM AMD_IOMMU_CMD_FLAGS_COMPL_WAIT_S = 4, 20410535SVikram.Hegde@Sun.COM AMD_IOMMU_CMD_FLAGS_PAGE_PDE_INVAL = 8, 20510535SVikram.Hegde@Sun.COM AMD_IOMMU_CMD_FLAGS_PAGE_INVAL_S = 16, 20610535SVikram.Hegde@Sun.COM AMD_IOMMU_CMD_FLAGS_IOTLB_INVAL_S = 32 20710535SVikram.Hegde@Sun.COM } amd_iommu_cmd_flags_t; 20810535SVikram.Hegde@Sun.COM 20910535SVikram.Hegde@Sun.COM /* Common command bits */ 21010535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_OPCODE (31 << 16 | 28) 21110535SVikram.Hegde@Sun.COM 21210535SVikram.Hegde@Sun.COM /* Completion Wait command bits */ 21310535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_COMPL_WAIT_S (0 << 16 | 0) 21410535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_COMPL_WAIT_I (1 << 16 | 1) 21510535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_COMPL_WAIT_F (2 << 16 | 2) 21610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_COMPL_WAIT_STORE_ADDR_LO (31 << 16 | 3) 21710535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_COMPL_WAIT_STORE_ADDR_HI (19 << 16 | 0) 21810535SVikram.Hegde@Sun.COM 21910535SVikram.Hegde@Sun.COM /* Invalidate Device Table entry command bits */ 22010535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_INVAL_DEVTAB_DEVICEID (15 << 16 | 0) 22110535SVikram.Hegde@Sun.COM 22210535SVikram.Hegde@Sun.COM /* Invalidate IOMMU Pages command bits */ 22310535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_INVAL_PAGES_DOMAINID (15 << 16 | 0) 22410535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_INVAL_PAGES_S (0 << 16 | 0) 22510535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_INVAL_PAGES_PDE (1 << 16 | 1) 22610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_INVAL_PAGES_ADDR_LO (31 << 16 | 12) 22710535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_INVAL_PAGES_ADDR_HI (63 << 16 | 32) 22810535SVikram.Hegde@Sun.COM 22910535SVikram.Hegde@Sun.COM 23010535SVikram.Hegde@Sun.COM /* Invalidate IOTLB command bits */ 23110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_INVAL_IOTLB_DEVICEID (15 << 16 | 0) 23210535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_INVAL_IOTLB_MAXPEND (31 << 16 | 24) 23310535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_INVAL_IOTLB_QUEUEID (15 << 16 | 0) 23410535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_INVAL_IOTLB_S (0 << 16 | 0) 23510535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_INVAL_IOTLB_ADDR_LO (31 << 16 | 12) 23610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_INVAL_IOTLB_ADDR_HI (31 << 16 | 0) 23710535SVikram.Hegde@Sun.COM 23810535SVikram.Hegde@Sun.COM #define AMD_IOMMU_DEFAULT_MAXPEND (10) 23910535SVikram.Hegde@Sun.COM 24010535SVikram.Hegde@Sun.COM /* Invalidate Interrupt Table bits */ 24110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_CMD_INVAL_INTR_DEVICEID (15 << 16 | 0) 24210535SVikram.Hegde@Sun.COM 24310535SVikram.Hegde@Sun.COM #if defined(__amd64) 24410535SVikram.Hegde@Sun.COM #define dmac_cookie_addr dmac_laddress 24510535SVikram.Hegde@Sun.COM #else 24610535SVikram.Hegde@Sun.COM #define dmac_cookie_addr dmac_address 24710535SVikram.Hegde@Sun.COM #endif 24810535SVikram.Hegde@Sun.COM 24910535SVikram.Hegde@Sun.COM #define AMD_IOMMU_TABLE_ALIGN ((1ULL << 12) - 1) 25010535SVikram.Hegde@Sun.COM 25110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_MAX_DEVICEID (0xFFFF) 25210535SVikram.Hegde@Sun.COM 25310535SVikram.Hegde@Sun.COM /* 25410535SVikram.Hegde@Sun.COM * DMA sync macros 25510535SVikram.Hegde@Sun.COM * TODO: optimize sync only small ranges 25610535SVikram.Hegde@Sun.COM */ 25710535SVikram.Hegde@Sun.COM #define SYNC_FORDEV(h) (void) ddi_dma_sync(h, 0, 0, DDI_DMA_SYNC_FORDEV) 25810535SVikram.Hegde@Sun.COM #define SYNC_FORKERN(h) (void) ddi_dma_sync(h, 0, 0, DDI_DMA_SYNC_FORKERNEL) 25910535SVikram.Hegde@Sun.COM 26010535SVikram.Hegde@Sun.COM #define WAIT_SEC(s) drv_usecwait(1000000*(s)) 26110535SVikram.Hegde@Sun.COM 26210535SVikram.Hegde@Sun.COM #define CMD2OFF(c) ((c) << 4) 26310535SVikram.Hegde@Sun.COM #define OFF2CMD(o) ((o) >> 4) 26410535SVikram.Hegde@Sun.COM 26510535SVikram.Hegde@Sun.COM typedef union split { 26610535SVikram.Hegde@Sun.COM uint64_t u64; 26710535SVikram.Hegde@Sun.COM uint32_t u32[2]; 26810535SVikram.Hegde@Sun.COM } split_t; 26910535SVikram.Hegde@Sun.COM 27010535SVikram.Hegde@Sun.COM #define BITPOS_START(b) ((b) >> 16) 27110535SVikram.Hegde@Sun.COM #define BITPOS_END(b) ((b) & 0xFFFF) 27210535SVikram.Hegde@Sun.COM 27310535SVikram.Hegde@Sun.COM #define START_MASK64(s) (((s) == 63) ? ~((uint64_t)0) : \ 27410535SVikram.Hegde@Sun.COM (uint64_t)((1ULL << ((s)+1)) - 1)) 27510535SVikram.Hegde@Sun.COM #define START_MASK32(s) (((s) == 31) ? ~((uint32_t)0) : \ 27610535SVikram.Hegde@Sun.COM (uint32_t)((1ULL << ((s)+1)) - 1)) 27710535SVikram.Hegde@Sun.COM #define START_MASK16(s) (((s) == 15) ? ~((uint16_t)0) : \ 27810535SVikram.Hegde@Sun.COM (uint16_t)((1ULL << ((s)+1)) - 1)) 27910535SVikram.Hegde@Sun.COM #define START_MASK8(s) (((s) == 7) ? ~((uint8_t)0) : \ 28010535SVikram.Hegde@Sun.COM (uint8_t)((1ULL << ((s)+1)) - 1)) 28110535SVikram.Hegde@Sun.COM 28210535SVikram.Hegde@Sun.COM #define END_MASK(e) ((1ULL << (e)) - 1) 28310535SVikram.Hegde@Sun.COM 28410535SVikram.Hegde@Sun.COM #define BIT_MASK64(s, e) (uint64_t)(START_MASK64(s) & ~END_MASK(e)) 28510535SVikram.Hegde@Sun.COM #define BIT_MASK32(s, e) (uint32_t)(START_MASK32(s) & ~END_MASK(e)) 28610535SVikram.Hegde@Sun.COM #define BIT_MASK16(s, e) (uint16_t)(START_MASK16(s) & ~END_MASK(e)) 28710535SVikram.Hegde@Sun.COM #define BIT_MASK8(s, e) (uint8_t)(START_MASK8(s) & ~END_MASK(e)) 28810535SVikram.Hegde@Sun.COM 28910535SVikram.Hegde@Sun.COM #define AMD_IOMMU_REG_GET64_IMPL(rp, b) \ 29010535SVikram.Hegde@Sun.COM (((*(rp)) & (START_MASK64(BITPOS_START(b)))) >> BITPOS_END(b)) 29110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_REG_GET64(rp, b) \ 29210535SVikram.Hegde@Sun.COM ((amd_iommu_64bit_bug) ? amd_iommu_reg_get64_workaround(rp, b) : \ 29310535SVikram.Hegde@Sun.COM AMD_IOMMU_REG_GET64_IMPL(rp, b)) 29410535SVikram.Hegde@Sun.COM #define AMD_IOMMU_REG_GET32(rp, b) \ 29510535SVikram.Hegde@Sun.COM (((*(rp)) & (START_MASK32(BITPOS_START(b)))) >> BITPOS_END(b)) 29610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_REG_GET16(rp, b) \ 29710535SVikram.Hegde@Sun.COM (((*(rp)) & (START_MASK16(BITPOS_START(b)))) >> BITPOS_END(b)) 29810535SVikram.Hegde@Sun.COM #define AMD_IOMMU_REG_GET8(rp, b) \ 29910535SVikram.Hegde@Sun.COM (((*(rp)) & (START_MASK8(BITPOS_START(b)))) >> BITPOS_END(b)) 30010535SVikram.Hegde@Sun.COM 30110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_REG_SET64_IMPL(rp, b, v) \ 30210535SVikram.Hegde@Sun.COM ((*(rp)) = \ 30310535SVikram.Hegde@Sun.COM (((uint64_t)(*(rp)) & ~(BIT_MASK64(BITPOS_START(b), BITPOS_END(b)))) \ 30410535SVikram.Hegde@Sun.COM | ((uint64_t)(v) << BITPOS_END(b)))) 30510535SVikram.Hegde@Sun.COM 30610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_REG_SET64(rp, b, v) \ 30710535SVikram.Hegde@Sun.COM (void) ((amd_iommu_64bit_bug) ? \ 30810535SVikram.Hegde@Sun.COM amd_iommu_reg_set64_workaround(rp, b, v) : \ 30910535SVikram.Hegde@Sun.COM AMD_IOMMU_REG_SET64_IMPL(rp, b, v)) 31010535SVikram.Hegde@Sun.COM 31110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_REG_SET32(rp, b, v) \ 31210535SVikram.Hegde@Sun.COM ((*(rp)) = \ 31310535SVikram.Hegde@Sun.COM (((uint32_t)(*(rp)) & ~(BIT_MASK32(BITPOS_START(b), BITPOS_END(b)))) \ 31410535SVikram.Hegde@Sun.COM | ((uint32_t)(v) << BITPOS_END(b)))) 31510535SVikram.Hegde@Sun.COM 31610535SVikram.Hegde@Sun.COM #define AMD_IOMMU_REG_SET16(rp, b, v) \ 31710535SVikram.Hegde@Sun.COM ((*(rp)) = \ 31810535SVikram.Hegde@Sun.COM (((uint16_t)(*(rp)) & ~(BIT_MASK16(BITPOS_START(b), BITPOS_END(b)))) \ 31910535SVikram.Hegde@Sun.COM | ((uint16_t)(v) << BITPOS_END(b)))) 32010535SVikram.Hegde@Sun.COM 32110535SVikram.Hegde@Sun.COM #define AMD_IOMMU_REG_SET8(rp, b, v) \ 32210535SVikram.Hegde@Sun.COM ((*(rp)) = \ 32310535SVikram.Hegde@Sun.COM (((uint8_t)(*(rp)) & ~(BIT_MASK8(BITPOS_START(b), BITPOS_END(b)))) \ 32410535SVikram.Hegde@Sun.COM | ((uint8_t)(v) << BITPOS_END(b)))) 32510535SVikram.Hegde@Sun.COM 32610535SVikram.Hegde@Sun.COM /* 32710535SVikram.Hegde@Sun.COM * Cast a 64 bit pointer to a uint64_t * 32810535SVikram.Hegde@Sun.COM */ 32910535SVikram.Hegde@Sun.COM #define REGADDR64(a) ((uint64_t *)(uintptr_t)(a)) 33010535SVikram.Hegde@Sun.COM 33110535SVikram.Hegde@Sun.COM typedef enum { 33210535SVikram.Hegde@Sun.COM AMD_IOMMU_INTR_INVALID = 0, 33310535SVikram.Hegde@Sun.COM AMD_IOMMU_INTR_TABLE, 33410535SVikram.Hegde@Sun.COM AMD_IOMMU_INTR_ALLOCED, 33510535SVikram.Hegde@Sun.COM AMD_IOMMU_INTR_HANDLER, 33610535SVikram.Hegde@Sun.COM AMD_IOMMU_INTR_ENABLED 33710535SVikram.Hegde@Sun.COM } amd_iommu_intr_state_t; 33810535SVikram.Hegde@Sun.COM 33910535SVikram.Hegde@Sun.COM 34010535SVikram.Hegde@Sun.COM typedef struct amd_iommu { 34110535SVikram.Hegde@Sun.COM kmutex_t aiomt_mutex; 34210535SVikram.Hegde@Sun.COM kmutex_t aiomt_eventlock; 34310535SVikram.Hegde@Sun.COM kmutex_t aiomt_cmdlock; 34410535SVikram.Hegde@Sun.COM dev_info_t *aiomt_dip; 345*12203SJerry.Gilliam@Sun.COM uint16_t aiomt_bdf; 34610535SVikram.Hegde@Sun.COM int aiomt_idx; 34710535SVikram.Hegde@Sun.COM iommulib_handle_t aiomt_iommulib_handle; 34810535SVikram.Hegde@Sun.COM iommulib_ops_t *aiomt_iommulib_ops; 34910535SVikram.Hegde@Sun.COM uint32_t aiomt_cap_hdr; 35010535SVikram.Hegde@Sun.COM uint8_t aiomt_npcache; 35110535SVikram.Hegde@Sun.COM uint8_t aiomt_httun; 35210535SVikram.Hegde@Sun.COM uint8_t aiomt_iotlb; 35310535SVikram.Hegde@Sun.COM uint8_t aiomt_captype; 35410535SVikram.Hegde@Sun.COM uint8_t aiomt_capid; 35510535SVikram.Hegde@Sun.COM uint32_t aiomt_low_addr32; 35610535SVikram.Hegde@Sun.COM uint32_t aiomt_hi_addr32; 35710535SVikram.Hegde@Sun.COM uint64_t aiomt_reg_pa; 35810535SVikram.Hegde@Sun.COM uint64_t aiomt_va; 35910535SVikram.Hegde@Sun.COM uint64_t aiomt_reg_va; 36010535SVikram.Hegde@Sun.COM uint32_t aiomt_range; 36110535SVikram.Hegde@Sun.COM uint8_t aiomt_rng_bus; 36210535SVikram.Hegde@Sun.COM uint8_t aiomt_first_devfn; 36310535SVikram.Hegde@Sun.COM uint8_t aiomt_last_devfn; 36410535SVikram.Hegde@Sun.COM uint8_t aiomt_rng_valid; 36510535SVikram.Hegde@Sun.COM uint8_t aiomt_ht_unitid; 36610535SVikram.Hegde@Sun.COM uint32_t aiomt_misc; 36710535SVikram.Hegde@Sun.COM uint8_t aiomt_htatsresv; 36810535SVikram.Hegde@Sun.COM uint8_t aiomt_vasize; 36910535SVikram.Hegde@Sun.COM uint8_t aiomt_pasize; 37010535SVikram.Hegde@Sun.COM uint8_t aiomt_msinum; 37110535SVikram.Hegde@Sun.COM uint8_t aiomt_reg_pages; 37210535SVikram.Hegde@Sun.COM uint32_t aiomt_reg_size; 37310535SVikram.Hegde@Sun.COM uint32_t aiomt_devtbl_sz; 37410535SVikram.Hegde@Sun.COM uint32_t aiomt_cmdbuf_sz; 37510535SVikram.Hegde@Sun.COM uint32_t aiomt_eventlog_sz; 37610535SVikram.Hegde@Sun.COM caddr_t aiomt_devtbl; 37710535SVikram.Hegde@Sun.COM caddr_t aiomt_cmdbuf; 37810535SVikram.Hegde@Sun.COM caddr_t aiomt_eventlog; 37910535SVikram.Hegde@Sun.COM uint32_t *aiomt_cmd_tail; 38010535SVikram.Hegde@Sun.COM uint32_t *aiomt_event_head; 38110535SVikram.Hegde@Sun.COM ddi_dma_handle_t aiomt_dmahdl; 38210535SVikram.Hegde@Sun.COM void *aiomt_dma_bufva; 38310535SVikram.Hegde@Sun.COM uint64_t aiomt_dma_mem_realsz; 38410535SVikram.Hegde@Sun.COM ddi_acc_handle_t aiomt_dma_mem_hdl; 38510535SVikram.Hegde@Sun.COM ddi_dma_cookie_t aiomt_buf_dma_cookie; 38610535SVikram.Hegde@Sun.COM uint_t aiomt_buf_dma_ncookie; 38710535SVikram.Hegde@Sun.COM amd_iommu_intr_state_t aiomt_intr_state; 38810535SVikram.Hegde@Sun.COM ddi_intr_handle_t *aiomt_intr_htable; 38910535SVikram.Hegde@Sun.COM uint32_t aiomt_intr_htable_sz; 39010535SVikram.Hegde@Sun.COM uint32_t aiomt_actual_intrs; 39110535SVikram.Hegde@Sun.COM uint32_t aiomt_intr_cap; 39210535SVikram.Hegde@Sun.COM uint64_t aiomt_reg_devtbl_va; 39310535SVikram.Hegde@Sun.COM uint64_t aiomt_reg_cmdbuf_va; 39410535SVikram.Hegde@Sun.COM uint64_t aiomt_reg_eventlog_va; 39510535SVikram.Hegde@Sun.COM uint64_t aiomt_reg_ctrl_va; 39610535SVikram.Hegde@Sun.COM uint64_t aiomt_reg_excl_base_va; 39710535SVikram.Hegde@Sun.COM uint64_t aiomt_reg_excl_lim_va; 39810535SVikram.Hegde@Sun.COM uint64_t aiomt_reg_cmdbuf_head_va; 39910535SVikram.Hegde@Sun.COM uint64_t aiomt_reg_cmdbuf_tail_va; 40010535SVikram.Hegde@Sun.COM uint64_t aiomt_reg_eventlog_head_va; 40110535SVikram.Hegde@Sun.COM uint64_t aiomt_reg_eventlog_tail_va; 40210535SVikram.Hegde@Sun.COM uint64_t aiomt_reg_status_va; 40310535SVikram.Hegde@Sun.COM struct amd_iommu *aiomt_next; 40410535SVikram.Hegde@Sun.COM } amd_iommu_t; 40510535SVikram.Hegde@Sun.COM 40610535SVikram.Hegde@Sun.COM typedef struct amd_iommu_dma_devtbl_ent { 40710535SVikram.Hegde@Sun.COM uint16_t de_domainid; 40810535SVikram.Hegde@Sun.COM uint8_t de_R; 40910535SVikram.Hegde@Sun.COM uint8_t de_W; 41010535SVikram.Hegde@Sun.COM caddr_t de_root_pgtbl; 41110535SVikram.Hegde@Sun.COM uint8_t de_pgmode; 41210535SVikram.Hegde@Sun.COM } amd_iommu_dma_devtbl_entry_t; 41310535SVikram.Hegde@Sun.COM 41410535SVikram.Hegde@Sun.COM typedef struct amd_iommu_alias { 41510535SVikram.Hegde@Sun.COM uint16_t al_bdf; 41610535SVikram.Hegde@Sun.COM uint16_t al_src_bdf; 41710535SVikram.Hegde@Sun.COM struct amd_iommu_alias *al_next; 41810535SVikram.Hegde@Sun.COM } amd_iommu_alias_t; 41910535SVikram.Hegde@Sun.COM 42010535SVikram.Hegde@Sun.COM typedef struct amd_iommu_cmdargs { 42110535SVikram.Hegde@Sun.COM uint64_t ca_addr; 42210535SVikram.Hegde@Sun.COM uint16_t ca_domainid; 42310535SVikram.Hegde@Sun.COM uint16_t ca_deviceid; 42410535SVikram.Hegde@Sun.COM } amd_iommu_cmdargs_t; 42510535SVikram.Hegde@Sun.COM 42610535SVikram.Hegde@Sun.COM struct amd_iommu_page_table; 42710535SVikram.Hegde@Sun.COM 42810535SVikram.Hegde@Sun.COM typedef struct amd_iommu_page_table_hash { 42910535SVikram.Hegde@Sun.COM kmutex_t ampt_lock; 43010535SVikram.Hegde@Sun.COM struct amd_iommu_page_table **ampt_hash; 43110535SVikram.Hegde@Sun.COM } amd_iommu_page_table_hash_t; 43210535SVikram.Hegde@Sun.COM 43310535SVikram.Hegde@Sun.COM typedef enum { 43410535SVikram.Hegde@Sun.COM AMD_IOMMU_LOG_INVALID_OP = 0, 43510535SVikram.Hegde@Sun.COM AMD_IOMMU_LOG_DISPLAY, 43610535SVikram.Hegde@Sun.COM AMD_IOMMU_LOG_DISCARD 43710535SVikram.Hegde@Sun.COM } amd_iommu_log_op_t; 43810535SVikram.Hegde@Sun.COM 43910535SVikram.Hegde@Sun.COM typedef enum { 44010535SVikram.Hegde@Sun.COM AMD_IOMMU_DEBUG_NONE = 0, 44110535SVikram.Hegde@Sun.COM AMD_IOMMU_DEBUG_ALLOCHDL = 0x1, 44210535SVikram.Hegde@Sun.COM AMD_IOMMU_DEBUG_FREEHDL = 0x2, 44310535SVikram.Hegde@Sun.COM AMD_IOMMU_DEBUG_BIND = 0x4, 44410535SVikram.Hegde@Sun.COM AMD_IOMMU_DEBUG_UNBIND = 0x8, 44510535SVikram.Hegde@Sun.COM AMD_IOMMU_DEBUG_WIN = 0x10, 44610535SVikram.Hegde@Sun.COM AMD_IOMMU_DEBUG_PAGE_TABLES = 0x20, 44710535SVikram.Hegde@Sun.COM AMD_IOMMU_DEBUG_DEVTBL = 0x40, 44810535SVikram.Hegde@Sun.COM AMD_IOMMU_DEBUG_CMDBUF = 0x80, 44910535SVikram.Hegde@Sun.COM AMD_IOMMU_DEBUG_EVENTLOG = 0x100, 45010535SVikram.Hegde@Sun.COM AMD_IOMMU_DEBUG_ACPI = 0x200, 45110535SVikram.Hegde@Sun.COM AMD_IOMMU_DEBUG_PA2VA = 0x400, 45210535SVikram.Hegde@Sun.COM AMD_IOMMU_DEBUG_TABLES = 0x800, 45310535SVikram.Hegde@Sun.COM AMD_IOMMU_DEBUG_EXCL = 0x1000, 45410535SVikram.Hegde@Sun.COM AMD_IOMMU_DEBUG_INTR = 0x2000 45510535SVikram.Hegde@Sun.COM } amd_iommu_debug_t; 45610535SVikram.Hegde@Sun.COM 45710535SVikram.Hegde@Sun.COM extern const char *amd_iommu_modname; 45810535SVikram.Hegde@Sun.COM extern kmutex_t amd_iommu_global_lock; 45910535SVikram.Hegde@Sun.COM extern amd_iommu_alias_t **amd_iommu_alias; 46010535SVikram.Hegde@Sun.COM extern amd_iommu_page_table_hash_t amd_iommu_page_table_hash; 46110535SVikram.Hegde@Sun.COM extern ddi_device_acc_attr_t amd_iommu_devacc; 46210535SVikram.Hegde@Sun.COM extern amd_iommu_debug_t amd_iommu_debug; 46310535SVikram.Hegde@Sun.COM 46410535SVikram.Hegde@Sun.COM extern uint8_t amd_iommu_htatsresv; 46510535SVikram.Hegde@Sun.COM extern uint8_t amd_iommu_vasize; 46610535SVikram.Hegde@Sun.COM extern uint8_t amd_iommu_pasize; 46710535SVikram.Hegde@Sun.COM extern int amd_iommu_64bit_bug; 46810535SVikram.Hegde@Sun.COM extern int amd_iommu_unity_map; 46910535SVikram.Hegde@Sun.COM extern int amd_iommu_no_RW_perms; 47010535SVikram.Hegde@Sun.COM extern int amd_iommu_no_unmap; 47110535SVikram.Hegde@Sun.COM extern int amd_iommu_pageva_inval_all; 47210535SVikram.Hegde@Sun.COM extern int amd_iommu_disable; 47310535SVikram.Hegde@Sun.COM extern char *amd_iommu_disable_list; 47410535SVikram.Hegde@Sun.COM 47510535SVikram.Hegde@Sun.COM extern uint64_t amd_iommu_reg_get64_workaround(uint64_t *regp, uint32_t bits); 47610535SVikram.Hegde@Sun.COM extern uint64_t amd_iommu_reg_set64_workaround(uint64_t *regp, uint32_t bits, 47710535SVikram.Hegde@Sun.COM uint64_t value); 478*12203SJerry.Gilliam@Sun.COM extern dev_info_t *amd_iommu_pci_dip(dev_info_t *rdip, const char *path); 47910535SVikram.Hegde@Sun.COM 48010535SVikram.Hegde@Sun.COM int amd_iommu_cmd(amd_iommu_t *iommu, amd_iommu_cmd_t cmd, 48110535SVikram.Hegde@Sun.COM amd_iommu_cmdargs_t *cmdargs, amd_iommu_cmd_flags_t flags, int lock_held); 48210535SVikram.Hegde@Sun.COM int amd_iommu_page_table_hash_init(amd_iommu_page_table_hash_t *ampt); 48310535SVikram.Hegde@Sun.COM void amd_iommu_page_table_hash_fini(amd_iommu_page_table_hash_t *ampt); 48410535SVikram.Hegde@Sun.COM 48510535SVikram.Hegde@Sun.COM int amd_iommu_read_log(amd_iommu_t *iommu, amd_iommu_log_op_t op); 48610535SVikram.Hegde@Sun.COM void amd_iommu_read_boot_props(void); 48710535SVikram.Hegde@Sun.COM void amd_iommu_lookup_conf_props(dev_info_t *dip); 48810535SVikram.Hegde@Sun.COM 48910535SVikram.Hegde@Sun.COM #endif /* _KERNEL */ 49010535SVikram.Hegde@Sun.COM 49110535SVikram.Hegde@Sun.COM #ifdef __cplusplus 49210535SVikram.Hegde@Sun.COM } 49310535SVikram.Hegde@Sun.COM #endif 49410535SVikram.Hegde@Sun.COM 49510535SVikram.Hegde@Sun.COM #endif /* _AMD_IOMMU_IMPL_H */ 496