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 2008 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 37 #ifdef _KERNEL 38 39 typedef enum { 40 INVALID_VENDOR = 0, 41 AMD_IOMMU, 42 INTEL_IOMMU 43 } iommulib_vendor_t; 44 45 typedef enum { 46 IOMMU_OPS_VERSION_INVALID = 0, 47 IOMMU_OPS_VERSION_1 = 1 48 } iommulib_opsversion_t; 49 50 #define IOMMU_OPS_VERSION IOMMU_OPS_VERSION_1 51 52 typedef struct iommulib_ops { 53 iommulib_opsversion_t ilops_vers; 54 iommulib_vendor_t ilops_vendor; 55 char *ilops_id; 56 void *ilops_data; 57 58 int (*ilops_probe)(iommulib_handle_t handle, dev_info_t *rdip); 59 60 int (*ilops_dma_allochdl)(iommulib_handle_t handle, 61 dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *attr, 62 int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *dma_handlep); 63 64 int (*ilops_dma_freehdl)(iommulib_handle_t handle, 65 dev_info_t *dip, dev_info_t *rdip, ddi_dma_handle_t dma_handle); 66 67 int (*ilops_dma_bindhdl)(iommulib_handle_t handle, dev_info_t *dip, 68 dev_info_t *rdip, ddi_dma_handle_t dma_handle, 69 struct ddi_dma_req *dmareq, ddi_dma_cookie_t *cookiep, 70 uint_t *ccountp); 71 72 int (*ilops_dma_unbindhdl)(iommulib_handle_t handle, 73 dev_info_t *dip, dev_info_t *rdip, ddi_dma_handle_t dma_handle); 74 75 int (*ilops_dma_sync)(iommulib_handle_t handle, dev_info_t *dip, 76 dev_info_t *rdip, ddi_dma_handle_t dma_handle, off_t off, 77 size_t len, uint_t cache_flags); 78 79 int (*ilops_dma_win)(iommulib_handle_t handle, dev_info_t *dip, 80 dev_info_t *rdip, ddi_dma_handle_t dma_handle, uint_t win, 81 off_t *offp, size_t *lenp, ddi_dma_cookie_t *cookiep, 82 uint_t *ccountp); 83 84 85 /* Obsolete DMA routines */ 86 87 int (*ilops_dma_map)(iommulib_handle_t handle, dev_info_t *dip, 88 dev_info_t *rdip, struct ddi_dma_req *dmareq, 89 ddi_dma_handle_t *dma_handle); 90 91 int (*ilops_dma_mctl)(iommulib_handle_t handle, dev_info_t *dip, 92 dev_info_t *rdip, ddi_dma_handle_t dma_handle, 93 enum ddi_dma_ctlops request, off_t *offp, size_t *lenp, 94 caddr_t *objpp, uint_t cache_flags); 95 96 } iommulib_ops_t; 97 98 #define IOMMU_USED(dip) (DEVI(dip)->devi_iommulib_handle != NULL) 99 100 typedef enum { 101 IOMMU_NEXOPS_VERSION_INVALID = 0, 102 IOMMU_NEXOPS_VERSION_1 = 1 103 } iommulib_nexops_version_t; 104 105 #define IOMMU_NEXOPS_VERSION IOMMU_NEXOPS_VERSION_1 106 107 typedef struct iommulib_nexops { 108 iommulib_nexops_version_t nops_vers; 109 char *nops_id; 110 void *nops_data; 111 112 int (*nops_dma_allochdl)(dev_info_t *dip, dev_info_t *rdip, 113 ddi_dma_attr_t *attr, int (*waitfp)(caddr_t), caddr_t arg, 114 ddi_dma_handle_t *handlep); 115 116 int (*nops_dma_freehdl)(dev_info_t *dip, dev_info_t *rdip, 117 ddi_dma_handle_t handle); 118 119 int (*nops_dma_bindhdl)(dev_info_t *dip, dev_info_t *rdip, 120 ddi_dma_handle_t handle, struct ddi_dma_req *dmareq, 121 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 122 123 int (*nops_dma_unbindhdl)(dev_info_t *dip, dev_info_t *rdip, 124 ddi_dma_handle_t handle); 125 126 void (*nops_dma_reset_cookies)(dev_info_t *dip, 127 ddi_dma_handle_t handle); 128 129 int (*nops_dma_get_cookies)(dev_info_t *dip, ddi_dma_handle_t handle, 130 ddi_dma_cookie_t **cookiepp, uint_t *ccountp); 131 132 int (*nops_dma_set_cookies)(dev_info_t *dip, ddi_dma_handle_t handle, 133 ddi_dma_cookie_t *cookiep, uint_t ccount); 134 135 int (*nops_dma_clear_cookies)(dev_info_t *dip, ddi_dma_handle_t handle); 136 137 int (*nops_dma_get_sleep_flags)(ddi_dma_handle_t handle); 138 139 int (*nops_dma_sync)(dev_info_t *dip, dev_info_t *rdip, 140 ddi_dma_handle_t handle, off_t off, size_t len, uint_t cache_flags); 141 142 int (*nops_dma_win)(dev_info_t *dip, dev_info_t *rdip, 143 ddi_dma_handle_t handle, uint_t win, off_t *offp, size_t *lenp, 144 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 145 146 int (*nops_dma_map)(dev_info_t *dip, dev_info_t *rdip, 147 struct ddi_dma_req *dmareq, ddi_dma_handle_t *handlep); 148 149 int (*nops_dma_mctl)(dev_info_t *dip, dev_info_t *rdip, 150 ddi_dma_handle_t handle, enum ddi_dma_ctlops request, off_t *offp, 151 size_t *lenp, caddr_t *objpp, uint_t cache_flags); 152 } iommulib_nexops_t; 153 154 struct iommulib_nex; 155 typedef struct iommulib_nex *iommulib_nexhandle_t; 156 157 /* 158 * struct iommu_dip_private 159 * private iommu structure hook on dev_info 160 */ 161 typedef struct iommu_private { 162 /* pci seg, bus, dev, func */ 163 int idp_seg; 164 int idp_bus; 165 int idp_devfn; 166 167 /* ppb information */ 168 boolean_t idp_is_bridge; 169 int idp_bbp_type; 170 int idp_sec; 171 int idp_sub; 172 173 /* identifier for special devices */ 174 boolean_t idp_is_display; 175 boolean_t idp_is_lpc; 176 177 /* domain ptr */ 178 void *idp_intel_domain; 179 } iommu_private_t; 180 181 #define INTEL_IOMMU_PRIVATE(i) (dmar_domain_state_t *)(i) 182 183 typedef struct gfx_entry { 184 dev_info_t *g_dip; 185 struct gfx_entry *g_prev; 186 struct gfx_entry *g_next; 187 } gfx_entry_t; 188 189 /* 190 * Interfaces for nexus drivers - typically rootnex 191 */ 192 193 int iommulib_nexus_register(dev_info_t *dip, iommulib_nexops_t *nexops, 194 iommulib_nexhandle_t *handle); 195 196 int iommulib_nexus_unregister(iommulib_nexhandle_t handle); 197 198 int iommulib_nex_open(dev_info_t *rdip, uint_t *errorp); 199 void iommulib_nex_close(dev_info_t *rdip); 200 201 int iommulib_nexdma_allochdl(dev_info_t *dip, dev_info_t *rdip, 202 ddi_dma_attr_t *attr, int (*waitfp)(caddr_t), 203 caddr_t arg, ddi_dma_handle_t *dma_handlep); 204 205 int iommulib_nexdma_freehdl(dev_info_t *dip, dev_info_t *rdip, 206 ddi_dma_handle_t dma_handle); 207 208 int iommulib_nexdma_bindhdl(dev_info_t *dip, dev_info_t *rdip, 209 ddi_dma_handle_t dma_handle, struct ddi_dma_req *dmareq, 210 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 211 212 int iommulib_nexdma_unbindhdl(dev_info_t *dip, dev_info_t *rdip, 213 ddi_dma_handle_t dma_handle); 214 215 int iommulib_nexdma_sync(dev_info_t *dip, dev_info_t *rdip, 216 ddi_dma_handle_t dma_handle, off_t off, size_t len, 217 uint_t cache_flags); 218 219 int iommulib_nexdma_win(dev_info_t *dip, dev_info_t *rdip, 220 ddi_dma_handle_t dma_handle, uint_t win, off_t *offp, size_t *lenp, 221 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 222 223 int iommulib_nexdma_map(dev_info_t *dip, dev_info_t *rdip, 224 struct ddi_dma_req *dmareq, ddi_dma_handle_t *dma_handle); 225 226 int iommulib_nexdma_mctl(dev_info_t *dip, dev_info_t *rdip, 227 ddi_dma_handle_t dma_handle, enum ddi_dma_ctlops request, 228 off_t *offp, size_t *lenp, caddr_t *objpp, uint_t cache_flags); 229 230 /* 231 * Interfaces for IOMMU drivers provided by IOMMULIB 232 */ 233 234 int iommulib_iommu_register(dev_info_t *dip, iommulib_ops_t *ops, 235 iommulib_handle_t *handle); 236 237 int iommulib_iommu_unregister(iommulib_handle_t handle); 238 239 int iommulib_iommu_getunitid(iommulib_handle_t handle, uint64_t *unitidp); 240 241 dev_info_t *iommulib_iommu_getdip(iommulib_handle_t handle); 242 243 iommulib_ops_t *iommulib_iommu_getops(iommulib_handle_t handle); 244 245 void *iommulib_iommu_getdata(iommulib_handle_t handle); 246 247 248 /* Interfaces for IOMMU drivers provided by NEXUS drivers (typically rootnex) */ 249 250 int iommulib_iommu_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, 251 ddi_dma_attr_t *attr, int (*waitfp)(caddr_t), caddr_t arg, 252 ddi_dma_handle_t *handlep); 253 254 int iommulib_iommu_dma_freehdl(dev_info_t *dip, dev_info_t *rdip, 255 ddi_dma_handle_t handle); 256 257 int iommulib_iommu_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip, 258 ddi_dma_handle_t handle, struct ddi_dma_req *dmareq, 259 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 260 261 int iommulib_iommu_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip, 262 ddi_dma_handle_t handle); 263 264 void iommulib_iommu_dma_reset_cookies(dev_info_t *dip, ddi_dma_handle_t handle); 265 266 int iommulib_iommu_dma_get_cookies(dev_info_t *dip, ddi_dma_handle_t handle, 267 ddi_dma_cookie_t **cookiepp, uint_t *ccountp); 268 269 int iommulib_iommu_dma_set_cookies(dev_info_t *dip, ddi_dma_handle_t handle, 270 ddi_dma_cookie_t *cookiep, uint_t ccount); 271 272 int iommulib_iommu_dma_clear_cookies(dev_info_t *dip, ddi_dma_handle_t handle); 273 274 int iommulib_iommu_dma_get_sleep_flags(dev_info_t *dip, 275 ddi_dma_handle_t handle); 276 277 int iommulib_iommu_dma_sync(dev_info_t *dip, dev_info_t *rdip, 278 ddi_dma_handle_t handle, off_t off, size_t len, uint_t cache_flags); 279 280 int iommulib_iommu_dma_win(dev_info_t *dip, dev_info_t *rdip, 281 ddi_dma_handle_t handle, uint_t win, off_t *offp, size_t *lenp, 282 ddi_dma_cookie_t *cookiep, uint_t *ccountp); 283 284 int iommulib_iommu_dma_map(dev_info_t *dip, dev_info_t *rdip, 285 struct ddi_dma_req *dmareq, ddi_dma_handle_t *handlep); 286 287 int iommulib_iommu_dma_mctl(dev_info_t *dip, dev_info_t *rdip, 288 ddi_dma_handle_t handle, enum ddi_dma_ctlops request, off_t *offp, 289 size_t *lenp, caddr_t *objpp, uint_t cache_flags); 290 291 #endif /* _KERNEL */ 292 293 #ifdef __cplusplus 294 } 295 #endif 296 297 #endif /* _SYS_IOMMULIB_H */ 298