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