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 * IOMMULIB_HDL() checks if there is an IOMMU controlling the dip's DMA 102 * IOMMU_USED() checks if the dip associated with the DMA handle has DMA 103 * controlled by an IOMMU. 104 * This ensures that we use the right dip associated with the 105 * DMA handle irrespective of which dip's context we call 106 * ddi_dma_* routines in. 107 */ 108 #define IOMMULIB_HDL(dip) (DEVI(dip)->devi_iommulib_handle) 109 #define IOMMU_USED(dmahdl) \ 110 (DEVI(((struct ddi_dma_impl *)(dmahdl))->dmai_rdip)->devi_iommulib_handle) 111 112 typedef enum { 113 IOMMU_NEXOPS_VERSION_INVALID = 0, 114 IOMMU_NEXOPS_VERSION_1 = 1 115 } iommulib_nexops_version_t; 116 117 #define IOMMU_NEXOPS_VERSION IOMMU_NEXOPS_VERSION_1 118 119 typedef struct iommulib_nexops { 120 iommulib_nexops_version_t nops_vers; 121 char *nops_id; 122 void *nops_data; 123 124 int (*nops_dma_allochdl)(dev_info_t *dip, dev_info_t *rdip, 125 ddi_dma_attr_t *attr, int (*waitfp)(caddr_t), caddr_t arg, 126 ddi_dma_handle_t *handlep); 127 128 int (*nops_dma_freehdl)(dev_info_t *dip, dev_info_t *rdip, 129 ddi_dma_handle_t handle); 130 131 int (*nops_dma_bindhdl)(dev_info_t *dip, dev_info_t *rdip, 132 ddi_dma_handle_t handle, struct ddi_dma_req *dmareq, 133 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 134 135 int (*nops_dma_unbindhdl)(dev_info_t *dip, dev_info_t *rdip, 136 ddi_dma_handle_t handle); 137 138 void (*nops_dma_reset_cookies)(dev_info_t *dip, 139 ddi_dma_handle_t handle); 140 141 int (*nops_dma_get_cookies)(dev_info_t *dip, ddi_dma_handle_t handle, 142 ddi_dma_cookie_t **cookiepp, uint_t *ccountp); 143 144 int (*nops_dma_set_cookies)(dev_info_t *dip, ddi_dma_handle_t handle, 145 ddi_dma_cookie_t *cookiep, uint_t ccount); 146 147 int (*nops_dma_clear_cookies)(dev_info_t *dip, ddi_dma_handle_t handle); 148 149 int (*nops_dma_get_sleep_flags)(ddi_dma_handle_t handle); 150 151 int (*nops_dma_sync)(dev_info_t *dip, dev_info_t *rdip, 152 ddi_dma_handle_t handle, off_t off, size_t len, uint_t cache_flags); 153 154 int (*nops_dma_win)(dev_info_t *dip, dev_info_t *rdip, 155 ddi_dma_handle_t handle, uint_t win, off_t *offp, size_t *lenp, 156 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 157 158 int (*nops_dma_map)(dev_info_t *dip, dev_info_t *rdip, 159 struct ddi_dma_req *dmareq, ddi_dma_handle_t *handlep); 160 161 int (*nops_dma_mctl)(dev_info_t *dip, dev_info_t *rdip, 162 ddi_dma_handle_t handle, enum ddi_dma_ctlops request, off_t *offp, 163 size_t *lenp, caddr_t *objpp, uint_t cache_flags); 164 } iommulib_nexops_t; 165 166 struct iommulib_nex; 167 typedef struct iommulib_nex *iommulib_nexhandle_t; 168 169 /* 170 * struct iommu_dip_private 171 * private iommu structure hook on dev_info 172 */ 173 typedef struct iommu_private { 174 /* pci seg, bus, dev, func */ 175 int idp_seg; 176 int idp_bus; 177 int idp_devfn; 178 179 /* ppb information */ 180 boolean_t idp_is_bridge; 181 int idp_bbp_type; 182 int idp_sec; 183 int idp_sub; 184 185 /* identifier for special devices */ 186 boolean_t idp_is_display; 187 boolean_t idp_is_lpc; 188 189 /* domain ptr */ 190 void *idp_intel_domain; 191 } iommu_private_t; 192 193 #define INTEL_IOMMU_PRIVATE(i) (dmar_domain_state_t *)(i) 194 195 typedef struct gfx_entry { 196 dev_info_t *g_dip; 197 struct gfx_entry *g_prev; 198 struct gfx_entry *g_next; 199 } gfx_entry_t; 200 201 /* 202 * Interfaces for nexus drivers - typically rootnex 203 */ 204 205 int iommulib_nexus_register(dev_info_t *dip, iommulib_nexops_t *nexops, 206 iommulib_nexhandle_t *handle); 207 208 int iommulib_nexus_unregister(iommulib_nexhandle_t handle); 209 210 int iommulib_nex_open(dev_info_t *rdip, uint_t *errorp); 211 void iommulib_nex_close(dev_info_t *rdip); 212 213 int iommulib_nexdma_allochdl(dev_info_t *dip, dev_info_t *rdip, 214 ddi_dma_attr_t *attr, int (*waitfp)(caddr_t), 215 caddr_t arg, ddi_dma_handle_t *dma_handlep); 216 217 int iommulib_nexdma_freehdl(dev_info_t *dip, dev_info_t *rdip, 218 ddi_dma_handle_t dma_handle); 219 220 int iommulib_nexdma_bindhdl(dev_info_t *dip, dev_info_t *rdip, 221 ddi_dma_handle_t dma_handle, struct ddi_dma_req *dmareq, 222 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 223 224 int iommulib_nexdma_unbindhdl(dev_info_t *dip, dev_info_t *rdip, 225 ddi_dma_handle_t dma_handle); 226 227 int iommulib_nexdma_sync(dev_info_t *dip, dev_info_t *rdip, 228 ddi_dma_handle_t dma_handle, off_t off, size_t len, 229 uint_t cache_flags); 230 231 int iommulib_nexdma_win(dev_info_t *dip, dev_info_t *rdip, 232 ddi_dma_handle_t dma_handle, uint_t win, off_t *offp, size_t *lenp, 233 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 234 235 int iommulib_nexdma_map(dev_info_t *dip, dev_info_t *rdip, 236 struct ddi_dma_req *dmareq, ddi_dma_handle_t *dma_handle); 237 238 int iommulib_nexdma_mctl(dev_info_t *dip, dev_info_t *rdip, 239 ddi_dma_handle_t dma_handle, enum ddi_dma_ctlops request, 240 off_t *offp, size_t *lenp, caddr_t *objpp, uint_t cache_flags); 241 242 /* 243 * Interfaces for IOMMU drivers provided by IOMMULIB 244 */ 245 246 int iommulib_iommu_register(dev_info_t *dip, iommulib_ops_t *ops, 247 iommulib_handle_t *handle); 248 249 int iommulib_iommu_unregister(iommulib_handle_t handle); 250 251 int iommulib_iommu_getunitid(iommulib_handle_t handle, uint64_t *unitidp); 252 253 dev_info_t *iommulib_iommu_getdip(iommulib_handle_t handle); 254 255 iommulib_ops_t *iommulib_iommu_getops(iommulib_handle_t handle); 256 257 void *iommulib_iommu_getdata(iommulib_handle_t handle); 258 259 260 /* Interfaces for IOMMU drivers provided by NEXUS drivers (typically rootnex) */ 261 262 int iommulib_iommu_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, 263 ddi_dma_attr_t *attr, int (*waitfp)(caddr_t), caddr_t arg, 264 ddi_dma_handle_t *handlep); 265 266 int iommulib_iommu_dma_freehdl(dev_info_t *dip, dev_info_t *rdip, 267 ddi_dma_handle_t handle); 268 269 int iommulib_iommu_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip, 270 ddi_dma_handle_t handle, struct ddi_dma_req *dmareq, 271 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 272 273 int iommulib_iommu_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip, 274 ddi_dma_handle_t handle); 275 276 void iommulib_iommu_dma_reset_cookies(dev_info_t *dip, ddi_dma_handle_t handle); 277 278 int iommulib_iommu_dma_get_cookies(dev_info_t *dip, ddi_dma_handle_t handle, 279 ddi_dma_cookie_t **cookiepp, uint_t *ccountp); 280 281 int iommulib_iommu_dma_set_cookies(dev_info_t *dip, ddi_dma_handle_t handle, 282 ddi_dma_cookie_t *cookiep, uint_t ccount); 283 284 int iommulib_iommu_dma_clear_cookies(dev_info_t *dip, ddi_dma_handle_t handle); 285 286 int iommulib_iommu_dma_get_sleep_flags(dev_info_t *dip, 287 ddi_dma_handle_t handle); 288 289 int iommulib_iommu_dma_sync(dev_info_t *dip, dev_info_t *rdip, 290 ddi_dma_handle_t handle, off_t off, size_t len, uint_t cache_flags); 291 292 int iommulib_iommu_dma_win(dev_info_t *dip, dev_info_t *rdip, 293 ddi_dma_handle_t handle, uint_t win, off_t *offp, size_t *lenp, 294 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 295 296 int iommulib_iommu_dma_map(dev_info_t *dip, dev_info_t *rdip, 297 struct ddi_dma_req *dmareq, ddi_dma_handle_t *handlep); 298 299 int iommulib_iommu_dma_mctl(dev_info_t *dip, dev_info_t *rdip, 300 ddi_dma_handle_t handle, enum ddi_dma_ctlops request, off_t *offp, 301 size_t *lenp, caddr_t *objpp, uint_t cache_flags); 302 303 /* 304 * For SMBIOS access from IOMMU drivers 305 */ 306 extern smbios_hdl_t *iommulib_smbios; 307 308 #endif /* _KERNEL */ 309 310 #ifdef __cplusplus 311 } 312 #endif 313 314 #endif /* _SYS_IOMMULIB_H */ 315