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 int g_ref; 190 dev_info_t *g_dip; 191 struct gfx_entry *g_prev; 192 struct gfx_entry *g_next; 193 } gfx_entry_t; 194 195 /* 196 * Interfaces for nexus drivers - typically rootnex 197 */ 198 199 int iommulib_nexus_register(dev_info_t *dip, iommulib_nexops_t *nexops, 200 iommulib_nexhandle_t *handle); 201 202 int iommulib_nexus_unregister(iommulib_nexhandle_t handle); 203 204 int iommulib_nex_open(dev_info_t *rdip, uint_t *errorp); 205 void iommulib_nex_close(dev_info_t *rdip); 206 207 int iommulib_nexdma_allochdl(dev_info_t *dip, dev_info_t *rdip, 208 ddi_dma_attr_t *attr, int (*waitfp)(caddr_t), 209 caddr_t arg, ddi_dma_handle_t *dma_handlep); 210 211 int iommulib_nexdma_freehdl(dev_info_t *dip, dev_info_t *rdip, 212 ddi_dma_handle_t dma_handle); 213 214 int iommulib_nexdma_bindhdl(dev_info_t *dip, dev_info_t *rdip, 215 ddi_dma_handle_t dma_handle, struct ddi_dma_req *dmareq, 216 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 217 218 int iommulib_nexdma_unbindhdl(dev_info_t *dip, dev_info_t *rdip, 219 ddi_dma_handle_t dma_handle); 220 221 int iommulib_nexdma_sync(dev_info_t *dip, dev_info_t *rdip, 222 ddi_dma_handle_t dma_handle, off_t off, size_t len, 223 uint_t cache_flags); 224 225 int iommulib_nexdma_win(dev_info_t *dip, dev_info_t *rdip, 226 ddi_dma_handle_t dma_handle, uint_t win, off_t *offp, size_t *lenp, 227 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 228 229 int iommulib_nexdma_map(dev_info_t *dip, dev_info_t *rdip, 230 struct ddi_dma_req *dmareq, ddi_dma_handle_t *dma_handle); 231 232 int iommulib_nexdma_mctl(dev_info_t *dip, dev_info_t *rdip, 233 ddi_dma_handle_t dma_handle, enum ddi_dma_ctlops request, 234 off_t *offp, size_t *lenp, caddr_t *objpp, uint_t cache_flags); 235 236 /* 237 * Interfaces for IOMMU drivers provided by IOMMULIB 238 */ 239 240 int iommulib_iommu_register(dev_info_t *dip, iommulib_ops_t *ops, 241 iommulib_handle_t *handle); 242 243 int iommulib_iommu_unregister(iommulib_handle_t handle); 244 245 int iommulib_iommu_getunitid(iommulib_handle_t handle, uint64_t *unitidp); 246 247 dev_info_t *iommulib_iommu_getdip(iommulib_handle_t handle); 248 249 iommulib_ops_t *iommulib_iommu_getops(iommulib_handle_t handle); 250 251 void *iommulib_iommu_getdata(iommulib_handle_t handle); 252 253 254 /* Interfaces for IOMMU drivers provided by NEXUS drivers (typically rootnex) */ 255 256 int iommulib_iommu_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, 257 ddi_dma_attr_t *attr, int (*waitfp)(caddr_t), caddr_t arg, 258 ddi_dma_handle_t *handlep); 259 260 int iommulib_iommu_dma_freehdl(dev_info_t *dip, dev_info_t *rdip, 261 ddi_dma_handle_t handle); 262 263 int iommulib_iommu_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip, 264 ddi_dma_handle_t handle, struct ddi_dma_req *dmareq, 265 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 266 267 int iommulib_iommu_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip, 268 ddi_dma_handle_t handle); 269 270 void iommulib_iommu_dma_reset_cookies(dev_info_t *dip, ddi_dma_handle_t handle); 271 272 int iommulib_iommu_dma_get_cookies(dev_info_t *dip, ddi_dma_handle_t handle, 273 ddi_dma_cookie_t **cookiepp, uint_t *ccountp); 274 275 int iommulib_iommu_dma_set_cookies(dev_info_t *dip, ddi_dma_handle_t handle, 276 ddi_dma_cookie_t *cookiep, uint_t ccount); 277 278 int iommulib_iommu_dma_clear_cookies(dev_info_t *dip, ddi_dma_handle_t handle); 279 280 int iommulib_iommu_dma_get_sleep_flags(dev_info_t *dip, 281 ddi_dma_handle_t handle); 282 283 int iommulib_iommu_dma_sync(dev_info_t *dip, dev_info_t *rdip, 284 ddi_dma_handle_t handle, off_t off, size_t len, uint_t cache_flags); 285 286 int iommulib_iommu_dma_win(dev_info_t *dip, dev_info_t *rdip, 287 ddi_dma_handle_t handle, uint_t win, off_t *offp, size_t *lenp, 288 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 289 290 int iommulib_iommu_dma_map(dev_info_t *dip, dev_info_t *rdip, 291 struct ddi_dma_req *dmareq, ddi_dma_handle_t *handlep); 292 293 int iommulib_iommu_dma_mctl(dev_info_t *dip, dev_info_t *rdip, 294 ddi_dma_handle_t handle, enum ddi_dma_ctlops request, off_t *offp, 295 size_t *lenp, caddr_t *objpp, uint_t cache_flags); 296 297 /* 298 * For SMBIOS access from IOMMU drivers 299 */ 300 extern smbios_hdl_t *iommulib_smbios; 301 302 #endif /* _KERNEL */ 303 304 #ifdef __cplusplus 305 } 306 #endif 307 308 #endif /* _SYS_IOMMULIB_H */ 309