1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_IOMMULIB_H 27 #define _SYS_IOMMULIB_H 28 29 #pragma ident "@(#)iommulib.h 1.3 08/08/31 SMI" 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #include <sys/ddi_impldefs.h> 36 #include <sys/smbios.h> 37 38 #ifdef _KERNEL 39 40 typedef enum { 41 INVALID_VENDOR = 0, 42 AMD_IOMMU, 43 INTEL_IOMMU 44 } iommulib_vendor_t; 45 46 typedef enum { 47 IOMMU_OPS_VERSION_INVALID = 0, 48 IOMMU_OPS_VERSION_1 = 1 49 } iommulib_opsversion_t; 50 51 #define IOMMU_OPS_VERSION IOMMU_OPS_VERSION_1 52 53 typedef struct iommulib_ops { 54 iommulib_opsversion_t ilops_vers; 55 iommulib_vendor_t ilops_vendor; 56 char *ilops_id; 57 void *ilops_data; 58 59 int (*ilops_probe)(iommulib_handle_t handle, dev_info_t *rdip); 60 61 int (*ilops_dma_allochdl)(iommulib_handle_t handle, 62 dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *attr, 63 int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *dma_handlep); 64 65 int (*ilops_dma_freehdl)(iommulib_handle_t handle, 66 dev_info_t *dip, dev_info_t *rdip, ddi_dma_handle_t dma_handle); 67 68 int (*ilops_dma_bindhdl)(iommulib_handle_t handle, dev_info_t *dip, 69 dev_info_t *rdip, ddi_dma_handle_t dma_handle, 70 struct ddi_dma_req *dmareq, ddi_dma_cookie_t *cookiep, 71 uint_t *ccountp); 72 73 int (*ilops_dma_unbindhdl)(iommulib_handle_t handle, 74 dev_info_t *dip, dev_info_t *rdip, ddi_dma_handle_t dma_handle); 75 76 int (*ilops_dma_sync)(iommulib_handle_t handle, dev_info_t *dip, 77 dev_info_t *rdip, ddi_dma_handle_t dma_handle, off_t off, 78 size_t len, uint_t cache_flags); 79 80 int (*ilops_dma_win)(iommulib_handle_t handle, dev_info_t *dip, 81 dev_info_t *rdip, ddi_dma_handle_t dma_handle, uint_t win, 82 off_t *offp, size_t *lenp, ddi_dma_cookie_t *cookiep, 83 uint_t *ccountp); 84 85 86 /* Obsolete DMA routines */ 87 88 int (*ilops_dma_map)(iommulib_handle_t handle, dev_info_t *dip, 89 dev_info_t *rdip, struct ddi_dma_req *dmareq, 90 ddi_dma_handle_t *dma_handle); 91 92 int (*ilops_dma_mctl)(iommulib_handle_t handle, dev_info_t *dip, 93 dev_info_t *rdip, ddi_dma_handle_t dma_handle, 94 enum ddi_dma_ctlops request, off_t *offp, size_t *lenp, 95 caddr_t *objpp, uint_t cache_flags); 96 97 } iommulib_ops_t; 98 99 100 /* 101 * IOMMU_USED() checks if there is an IOMMU controlling the dip's DMA 102 */ 103 #define IOMMU_USED(dip) (DEVI(dip)->devi_iommulib_handle) 104 105 typedef enum { 106 IOMMU_NEXOPS_VERSION_INVALID = 0, 107 IOMMU_NEXOPS_VERSION_1 = 1 108 } iommulib_nexops_version_t; 109 110 #define IOMMU_NEXOPS_VERSION IOMMU_NEXOPS_VERSION_1 111 112 typedef struct iommulib_nexops { 113 iommulib_nexops_version_t nops_vers; 114 char *nops_id; 115 void *nops_data; 116 117 int (*nops_dma_allochdl)(dev_info_t *dip, dev_info_t *rdip, 118 ddi_dma_attr_t *attr, int (*waitfp)(caddr_t), caddr_t arg, 119 ddi_dma_handle_t *handlep); 120 121 int (*nops_dma_freehdl)(dev_info_t *dip, dev_info_t *rdip, 122 ddi_dma_handle_t handle); 123 124 int (*nops_dma_bindhdl)(dev_info_t *dip, dev_info_t *rdip, 125 ddi_dma_handle_t handle, struct ddi_dma_req *dmareq, 126 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 127 128 int (*nops_dma_unbindhdl)(dev_info_t *dip, dev_info_t *rdip, 129 ddi_dma_handle_t handle); 130 131 void (*nops_dma_reset_cookies)(dev_info_t *dip, 132 ddi_dma_handle_t handle); 133 134 int (*nops_dma_get_cookies)(dev_info_t *dip, ddi_dma_handle_t handle, 135 ddi_dma_cookie_t **cookiepp, uint_t *ccountp); 136 137 int (*nops_dma_set_cookies)(dev_info_t *dip, ddi_dma_handle_t handle, 138 ddi_dma_cookie_t *cookiep, uint_t ccount); 139 140 int (*nops_dma_clear_cookies)(dev_info_t *dip, ddi_dma_handle_t handle); 141 142 int (*nops_dma_get_sleep_flags)(ddi_dma_handle_t handle); 143 144 int (*nops_dma_sync)(dev_info_t *dip, dev_info_t *rdip, 145 ddi_dma_handle_t handle, off_t off, size_t len, uint_t cache_flags); 146 147 int (*nops_dma_win)(dev_info_t *dip, dev_info_t *rdip, 148 ddi_dma_handle_t handle, uint_t win, off_t *offp, size_t *lenp, 149 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 150 151 int (*nops_dma_map)(dev_info_t *dip, dev_info_t *rdip, 152 struct ddi_dma_req *dmareq, ddi_dma_handle_t *handlep); 153 154 int (*nops_dma_mctl)(dev_info_t *dip, dev_info_t *rdip, 155 ddi_dma_handle_t handle, enum ddi_dma_ctlops request, off_t *offp, 156 size_t *lenp, caddr_t *objpp, uint_t cache_flags); 157 } iommulib_nexops_t; 158 159 struct iommulib_nex; 160 typedef struct iommulib_nex *iommulib_nexhandle_t; 161 162 /* 163 * struct iommu_dip_private 164 * private iommu structure hook on dev_info 165 */ 166 typedef struct iommu_private { 167 /* pci seg, bus, dev, func */ 168 int idp_seg; 169 int idp_bus; 170 int idp_devfn; 171 172 /* ppb information */ 173 boolean_t idp_is_bridge; 174 int idp_bbp_type; 175 int idp_sec; 176 int idp_sub; 177 178 /* identifier for special devices */ 179 boolean_t idp_is_display; 180 boolean_t idp_is_lpc; 181 182 /* domain ptr */ 183 void *idp_intel_domain; 184 } iommu_private_t; 185 186 #define INTEL_IOMMU_PRIVATE(i) (dmar_domain_state_t *)(i) 187 188 typedef struct gfx_entry { 189 dev_info_t *g_dip; 190 struct gfx_entry *g_prev; 191 struct gfx_entry *g_next; 192 } gfx_entry_t; 193 194 /* 195 * Interfaces for nexus drivers - typically rootnex 196 */ 197 198 int iommulib_nexus_register(dev_info_t *dip, iommulib_nexops_t *nexops, 199 iommulib_nexhandle_t *handle); 200 201 int iommulib_nexus_unregister(iommulib_nexhandle_t handle); 202 203 int iommulib_nex_open(dev_info_t *rdip, uint_t *errorp); 204 void iommulib_nex_close(dev_info_t *rdip); 205 206 int iommulib_nexdma_allochdl(dev_info_t *dip, dev_info_t *rdip, 207 ddi_dma_attr_t *attr, int (*waitfp)(caddr_t), 208 caddr_t arg, ddi_dma_handle_t *dma_handlep); 209 210 int iommulib_nexdma_freehdl(dev_info_t *dip, dev_info_t *rdip, 211 ddi_dma_handle_t dma_handle); 212 213 int iommulib_nexdma_bindhdl(dev_info_t *dip, dev_info_t *rdip, 214 ddi_dma_handle_t dma_handle, struct ddi_dma_req *dmareq, 215 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 216 217 int iommulib_nexdma_unbindhdl(dev_info_t *dip, dev_info_t *rdip, 218 ddi_dma_handle_t dma_handle); 219 220 int iommulib_nexdma_sync(dev_info_t *dip, dev_info_t *rdip, 221 ddi_dma_handle_t dma_handle, off_t off, size_t len, 222 uint_t cache_flags); 223 224 int iommulib_nexdma_win(dev_info_t *dip, dev_info_t *rdip, 225 ddi_dma_handle_t dma_handle, uint_t win, off_t *offp, size_t *lenp, 226 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 227 228 int iommulib_nexdma_map(dev_info_t *dip, dev_info_t *rdip, 229 struct ddi_dma_req *dmareq, ddi_dma_handle_t *dma_handle); 230 231 int iommulib_nexdma_mctl(dev_info_t *dip, dev_info_t *rdip, 232 ddi_dma_handle_t dma_handle, enum ddi_dma_ctlops request, 233 off_t *offp, size_t *lenp, caddr_t *objpp, uint_t cache_flags); 234 235 /* 236 * Interfaces for IOMMU drivers provided by IOMMULIB 237 */ 238 239 int iommulib_iommu_register(dev_info_t *dip, iommulib_ops_t *ops, 240 iommulib_handle_t *handle); 241 242 int iommulib_iommu_unregister(iommulib_handle_t handle); 243 244 int iommulib_iommu_getunitid(iommulib_handle_t handle, uint64_t *unitidp); 245 246 dev_info_t *iommulib_iommu_getdip(iommulib_handle_t handle); 247 248 iommulib_ops_t *iommulib_iommu_getops(iommulib_handle_t handle); 249 250 void *iommulib_iommu_getdata(iommulib_handle_t handle); 251 252 253 /* Interfaces for IOMMU drivers provided by NEXUS drivers (typically rootnex) */ 254 255 int iommulib_iommu_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, 256 ddi_dma_attr_t *attr, int (*waitfp)(caddr_t), caddr_t arg, 257 ddi_dma_handle_t *handlep); 258 259 int iommulib_iommu_dma_freehdl(dev_info_t *dip, dev_info_t *rdip, 260 ddi_dma_handle_t handle); 261 262 int iommulib_iommu_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip, 263 ddi_dma_handle_t handle, struct ddi_dma_req *dmareq, 264 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 265 266 int iommulib_iommu_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip, 267 ddi_dma_handle_t handle); 268 269 void iommulib_iommu_dma_reset_cookies(dev_info_t *dip, ddi_dma_handle_t handle); 270 271 int iommulib_iommu_dma_get_cookies(dev_info_t *dip, ddi_dma_handle_t handle, 272 ddi_dma_cookie_t **cookiepp, uint_t *ccountp); 273 274 int iommulib_iommu_dma_set_cookies(dev_info_t *dip, ddi_dma_handle_t handle, 275 ddi_dma_cookie_t *cookiep, uint_t ccount); 276 277 int iommulib_iommu_dma_clear_cookies(dev_info_t *dip, ddi_dma_handle_t handle); 278 279 int iommulib_iommu_dma_get_sleep_flags(dev_info_t *dip, 280 ddi_dma_handle_t handle); 281 282 int iommulib_iommu_dma_sync(dev_info_t *dip, dev_info_t *rdip, 283 ddi_dma_handle_t handle, off_t off, size_t len, uint_t cache_flags); 284 285 int iommulib_iommu_dma_win(dev_info_t *dip, dev_info_t *rdip, 286 ddi_dma_handle_t handle, uint_t win, off_t *offp, size_t *lenp, 287 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 288 289 int iommulib_iommu_dma_map(dev_info_t *dip, dev_info_t *rdip, 290 struct ddi_dma_req *dmareq, ddi_dma_handle_t *handlep); 291 292 int iommulib_iommu_dma_mctl(dev_info_t *dip, dev_info_t *rdip, 293 ddi_dma_handle_t handle, enum ddi_dma_ctlops request, off_t *offp, 294 size_t *lenp, caddr_t *objpp, uint_t cache_flags); 295 296 /* 297 * For SMBIOS access from IOMMU drivers 298 */ 299 extern smbios_hdl_t *iommulib_smbios; 300 301 #endif /* _KERNEL */ 302 303 #ifdef __cplusplus 304 } 305 #endif 306 307 #endif /* _SYS_IOMMULIB_H */ 308