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.
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.
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]
22 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
26 #ifndef _SYS_IOMMULIB_H
27 #define _SYS_IOMMULIB_H
33 #include <sys/ddi_impldefs.h>
34 #include <sys/smbios.h>
45 IOMMU_OPS_VERSION_INVALID
= 0,
46 IOMMU_OPS_VERSION_1
= 1,
47 IOMMU_OPS_VERSION_2
= 2,
48 IOMMU_OPS_VERSION_3
= 3
49 } iommulib_opsversion_t
;
51 #define IOMMU_OPS_VERSION IOMMU_OPS_VERSION_3
53 typedef struct iommulib_ops
{
54 iommulib_opsversion_t ilops_vers
;
55 iommulib_vendor_t ilops_vendor
;
59 int (*ilops_probe
)(iommulib_handle_t handle
, dev_info_t
*rdip
);
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
);
65 int (*ilops_dma_freehdl
)(iommulib_handle_t handle
,
66 dev_info_t
*dip
, dev_info_t
*rdip
, ddi_dma_handle_t dma_handle
);
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
,
73 int (*ilops_dma_unbindhdl
)(iommulib_handle_t handle
,
74 dev_info_t
*dip
, dev_info_t
*rdip
, ddi_dma_handle_t dma_handle
);
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
);
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
,
85 int (*ilops_dma_mapobject
)(iommulib_handle_t handle
,
86 dev_info_t
*dip
, dev_info_t
*rdip
, ddi_dma_handle_t dma_handle
,
87 struct ddi_dma_req
*dmareq
, ddi_dma_obj_t
*dmao
);
89 int (*ilops_dma_unmapobject
)(iommulib_handle_t handle
,
90 dev_info_t
*dip
, dev_info_t
*rdip
, ddi_dma_handle_t dma_handle
,
96 * Fake pointer value to indicate that a device will not use an IOMMU
97 * for DMA (it's either set up for passthrough or uses a unity mapping).
99 #define IOMMU_HANDLE_UNUSED (void *)-1
102 * IOMMU_UNITIALIZED() is true if it has not been determined whether
103 * a device uses an IOMMU for DMA or not. After it has been determined,
104 * the USED and UNUSED macros may be used to see if an IOMMU is being
107 * IOMMU_USED() is true if a device uses an IOMMU for DMA
109 * IOMMU_UNUSED() is true if a device does not use an IOMMU for DMA
111 #define IOMMU_USED(dip) \
112 (DEVI(dip)->devi_iommulib_handle != NULL && \
113 DEVI(dip)->devi_iommulib_handle != IOMMU_HANDLE_UNUSED)
114 #define IOMMU_UNUSED(dip) \
115 (DEVI(dip)->devi_iommulib_handle == IOMMU_HANDLE_UNUSED)
116 #define IOMMU_UNITIALIZED(dip) \
117 (DEVI(dip)->devi_iommulib_handle == NULL)
120 IOMMU_NEXOPS_VERSION_INVALID
= 0,
121 IOMMU_NEXOPS_VERSION_1
= 1,
122 IOMMU_NEXOPS_VERSION_2
= 2,
123 IOMMU_NEXOPS_VERSION_3
= 3
124 } iommulib_nexops_version_t
;
126 #define IOMMU_NEXOPS_VERSION IOMMU_NEXOPS_VERSION_3
128 typedef struct iommulib_nexops
{
129 iommulib_nexops_version_t nops_vers
;
133 int (*nops_dma_allochdl
)(dev_info_t
*dip
, dev_info_t
*rdip
,
134 ddi_dma_attr_t
*attr
, int (*waitfp
)(caddr_t
), caddr_t arg
,
135 ddi_dma_handle_t
*handlep
);
137 int (*nops_dma_freehdl
)(dev_info_t
*dip
, dev_info_t
*rdip
,
138 ddi_dma_handle_t handle
);
140 int (*nops_dma_bindhdl
)(dev_info_t
*dip
, dev_info_t
*rdip
,
141 ddi_dma_handle_t handle
, struct ddi_dma_req
*dmareq
,
142 ddi_dma_cookie_t
*cookiep
, uint_t
*ccountp
);
144 int (*nops_dma_unbindhdl
)(dev_info_t
*dip
, dev_info_t
*rdip
,
145 ddi_dma_handle_t handle
);
147 void (*nops_dma_reset_cookies
)(dev_info_t
*dip
,
148 ddi_dma_handle_t handle
);
150 int (*nops_dma_get_cookies
)(dev_info_t
*dip
, ddi_dma_handle_t handle
,
151 ddi_dma_cookie_t
**cookiepp
, uint_t
*ccountp
);
153 int (*nops_dma_set_cookies
)(dev_info_t
*dip
, ddi_dma_handle_t handle
,
154 ddi_dma_cookie_t
*cookiep
, uint_t ccount
);
156 int (*nops_dma_clear_cookies
)(dev_info_t
*dip
, ddi_dma_handle_t handle
);
158 int (*nops_dma_get_sleep_flags
)(ddi_dma_handle_t handle
);
160 int (*nops_dma_sync
)(dev_info_t
*dip
, dev_info_t
*rdip
,
161 ddi_dma_handle_t handle
, off_t off
, size_t len
, uint_t cache_flags
);
163 int (*nops_dma_win
)(dev_info_t
*dip
, dev_info_t
*rdip
,
164 ddi_dma_handle_t handle
, uint_t win
, off_t
*offp
, size_t *lenp
,
165 ddi_dma_cookie_t
*cookiep
, uint_t
*ccountp
);
167 int (*nops_dmahdl_setprivate
)(dev_info_t
*dip
, dev_info_t
*rdip
,
168 ddi_dma_handle_t handle
, void *priv
);
170 void * (*nops_dmahdl_getprivate
)(dev_info_t
*dip
, dev_info_t
*rdip
,
171 ddi_dma_handle_t handle
);
175 * struct iommu_dip_private
176 * private iommu structure hook on dev_info
178 typedef struct iommu_private
{
179 /* pci seg, bus, dev, func */
184 /* ppb information */
185 boolean_t idp_is_bridge
;
190 /* identifier for special devices */
191 boolean_t idp_is_display
;
192 boolean_t idp_is_lpc
;
195 void *idp_intel_domain
;
198 #define INTEL_IOMMU_PRIVATE(i) (dmar_domain_state_t *)(i)
200 typedef struct gfx_entry
{
203 struct gfx_entry
*g_prev
;
204 struct gfx_entry
*g_next
;
208 * Interfaces for nexus drivers - typically rootnex
211 int iommulib_nexus_register(dev_info_t
*dip
, iommulib_nexops_t
*nexops
,
212 iommulib_nexhandle_t
*handle
);
214 int iommulib_nexus_unregister(iommulib_nexhandle_t handle
);
216 int iommulib_nex_open(dev_info_t
*dip
, dev_info_t
*rdip
);
217 void iommulib_nex_close(dev_info_t
*rdip
);
219 int iommulib_nexdma_allochdl(dev_info_t
*dip
, dev_info_t
*rdip
,
220 ddi_dma_attr_t
*attr
, int (*waitfp
)(caddr_t
),
221 caddr_t arg
, ddi_dma_handle_t
*dma_handlep
);
223 int iommulib_nexdma_freehdl(dev_info_t
*dip
, dev_info_t
*rdip
,
224 ddi_dma_handle_t dma_handle
);
226 int iommulib_nexdma_bindhdl(dev_info_t
*dip
, dev_info_t
*rdip
,
227 ddi_dma_handle_t dma_handle
, struct ddi_dma_req
*dmareq
,
228 ddi_dma_cookie_t
*cookiep
, uint_t
*ccountp
);
230 int iommulib_nexdma_unbindhdl(dev_info_t
*dip
, dev_info_t
*rdip
,
231 ddi_dma_handle_t dma_handle
);
233 int iommulib_nexdma_sync(dev_info_t
*dip
, dev_info_t
*rdip
,
234 ddi_dma_handle_t dma_handle
, off_t off
, size_t len
,
237 int iommulib_nexdma_win(dev_info_t
*dip
, dev_info_t
*rdip
,
238 ddi_dma_handle_t dma_handle
, uint_t win
, off_t
*offp
, size_t *lenp
,
239 ddi_dma_cookie_t
*cookiep
, uint_t
*ccountp
);
241 int iommulib_nexdma_mapobject(dev_info_t
*dip
, dev_info_t
*rdip
,
242 ddi_dma_handle_t dma_handle
, struct ddi_dma_req
*dmareq
,
243 ddi_dma_obj_t
*dmao
);
244 int iommulib_nexdma_unmapobject(dev_info_t
*dip
, dev_info_t
*rdip
,
245 ddi_dma_handle_t dma_handle
, ddi_dma_obj_t
*dmao
);
248 * Interfaces for IOMMU drivers provided by IOMMULIB
251 int iommulib_iommu_register(dev_info_t
*dip
, iommulib_ops_t
*ops
,
252 iommulib_handle_t
*handle
);
254 int iommulib_iommu_unregister(iommulib_handle_t handle
);
256 int iommulib_iommu_getunitid(iommulib_handle_t handle
, uint64_t *unitidp
);
258 dev_info_t
*iommulib_iommu_getdip(iommulib_handle_t handle
);
260 iommulib_ops_t
*iommulib_iommu_getops(iommulib_handle_t handle
);
262 void *iommulib_iommu_getdata(iommulib_handle_t handle
);
265 /* Interfaces for IOMMU drivers provided by NEXUS drivers (typically rootnex) */
267 int iommulib_iommu_dma_allochdl(dev_info_t
*dip
, dev_info_t
*rdip
,
268 ddi_dma_attr_t
*attr
, int (*waitfp
)(caddr_t
), caddr_t arg
,
269 ddi_dma_handle_t
*handlep
);
271 int iommulib_iommu_dma_freehdl(dev_info_t
*dip
, dev_info_t
*rdip
,
272 ddi_dma_handle_t handle
);
274 int iommulib_iommu_dma_bindhdl(dev_info_t
*dip
, dev_info_t
*rdip
,
275 ddi_dma_handle_t handle
, struct ddi_dma_req
*dmareq
,
276 ddi_dma_cookie_t
*cookiep
, uint_t
*ccountp
);
278 int iommulib_iommu_dma_unbindhdl(dev_info_t
*dip
, dev_info_t
*rdip
,
279 ddi_dma_handle_t handle
);
281 void iommulib_iommu_dma_reset_cookies(dev_info_t
*dip
, ddi_dma_handle_t handle
);
283 int iommulib_iommu_dma_get_cookies(dev_info_t
*dip
, ddi_dma_handle_t handle
,
284 ddi_dma_cookie_t
**cookiepp
, uint_t
*ccountp
);
286 int iommulib_iommu_dma_set_cookies(dev_info_t
*dip
, ddi_dma_handle_t handle
,
287 ddi_dma_cookie_t
*cookiep
, uint_t ccount
);
289 int iommulib_iommu_dma_clear_cookies(dev_info_t
*dip
, ddi_dma_handle_t handle
);
291 int iommulib_iommu_dma_get_sleep_flags(dev_info_t
*dip
,
292 ddi_dma_handle_t handle
);
294 int iommulib_iommu_dma_sync(dev_info_t
*dip
, dev_info_t
*rdip
,
295 ddi_dma_handle_t handle
, off_t off
, size_t len
, uint_t cache_flags
);
297 int iommulib_iommu_dma_win(dev_info_t
*dip
, dev_info_t
*rdip
,
298 ddi_dma_handle_t handle
, uint_t win
, off_t
*offp
, size_t *lenp
,
299 ddi_dma_cookie_t
*cookiep
, uint_t
*ccountp
);
301 int iommulib_iommu_dmahdl_setprivate(dev_info_t
*dip
, dev_info_t
*rdip
,
302 ddi_dma_handle_t handle
, void *priv
);
304 void *iommulib_iommu_dmahdl_getprivate(dev_info_t
*dip
, dev_info_t
*rdip
,
305 ddi_dma_handle_t handle
);
309 * For SMBIOS access from IOMMU drivers
311 extern smbios_hdl_t
*iommulib_smbios
;
319 #endif /* _SYS_IOMMULIB_H */