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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 
25 #ifndef	_AMD_IOMMU_IMPL_H
26 #define	_AMD_IOMMU_IMPL_H
27 
28 #ifdef	__cplusplus
29 extern "C" {
30 #endif
31 
32 #include <sys/pci.h>
33 
34 #ifdef	_KERNEL
35 
36 #define	AMD_IOMMU_PCI_PROG_IF	(0x0)
37 
38 #define	AMD_IOMMU_CAP		(0x3)
39 
40 #define	AMD_IOMMU_REG_SIZE	(0x2028)
41 #define	AMD_IOMMU_DEVTBL_SZ	(16)
42 #define	AMD_IOMMU_CMDBUF_SZ	(15)
43 #define	AMD_IOMMU_EVENTLOG_SZ	(15)
44 #define	AMD_IOMMU_DEVENT_SZ	(32)
45 #define	AMD_IOMMU_CMD_SZ	(16)
46 #define	AMD_IOMMU_EVENT_SZ	(16)
47 
48 /* Capability Register offsets */
49 #define	AMD_IOMMU_CAP_HDR_OFF		(0x00)
50 #define	AMD_IOMMU_CAP_ADDR_LOW_OFF	(0x04)
51 #define	AMD_IOMMU_CAP_ADDR_HI_OFF	(0x08)
52 #define	AMD_IOMMU_CAP_RANGE_OFF		(0x0C)
53 #define	AMD_IOMMU_CAP_MISC_OFF		(0x10)
54 
55 /* ControL Registers offsets */
56 #define	AMD_IOMMU_DEVTBL_REG_OFF	(0x00)
57 #define	AMD_IOMMU_CMDBUF_REG_OFF	(0x08)
58 #define	AMD_IOMMU_EVENTLOG_REG_OFF	(0x10)
59 #define	AMD_IOMMU_CTRL_REG_OFF		(0x18)
60 #define	AMD_IOMMU_EXCL_BASE_REG_OFF	(0x20)
61 #define	AMD_IOMMU_EXCL_LIM_REG_OFF	(0x28)
62 #define	AMD_IOMMU_CMDBUF_HEAD_REG_OFF	(0x2000)
63 #define	AMD_IOMMU_CMDBUF_TAIL_REG_OFF	(0x2008)
64 #define	AMD_IOMMU_EVENTLOG_HEAD_REG_OFF	(0x2010)
65 #define	AMD_IOMMU_EVENTLOG_TAIL_REG_OFF	(0x2018)
66 #define	AMD_IOMMU_STATUS_REG_OFF	(0x2020)
67 
68 /* Capability Header Register Bits */
69 #define	AMD_IOMMU_CAP_NPCACHE	(26 << 16 | 26)
70 #define	AMD_IOMMU_CAP_HTTUN	(25 << 16 | 25)
71 #define	AMD_IOMMU_CAP_IOTLB	(24 << 16 | 24)
72 #define	AMD_IOMMU_CAP_TYPE	(18 << 16 | 16)
73 #define	AMD_IOMMU_CAP_ID	(7 << 16 | 0)
74 
75 /* Capability Range Register bits */
76 #define	AMD_IOMMU_LAST_DEVFN	(31 << 16 | 24)
77 #define	AMD_IOMMU_FIRST_DEVFN	(23 << 16 | 16)
78 #define	AMD_IOMMU_RNG_BUS	(15 << 16 | 8)
79 #define	AMD_IOMMU_RNG_VALID	(7 << 16 | 7)
80 #define	AMD_IOMMU_HT_UNITID	(4 << 16 | 0)
81 
82 
83 /* Capability Misc Register bits */
84 #define	AMD_IOMMU_HT_ATSRSV	(22 << 16 | 22)
85 #define	AMD_IOMMU_VA_SIZE	(21 << 16 | 15)
86 #define	AMD_IOMMU_PA_SIZE	(14 << 16 | 8)
87 #define	AMD_IOMMU_MSINUM	(4 << 16 | 0)
88 
89 /* Device Table Base Address register bits */
90 #define	AMD_IOMMU_DEVTABBASE	(51 << 16 | 12)
91 #define	AMD_IOMMU_DEVTABSIZE	(8 << 16 | 0)
92 
93 /* Command Buffer Base Address register bits */
94 #define	AMD_IOMMU_COMLEN	(59 << 16 | 56)
95 #define	AMD_IOMMU_COMBASE	(51 << 16 | 12)
96 
97 #define	AMD_IOMMU_CMDBUF_MINSZ	(8)
98 #define	AMD_IOMMU_CMDBUF_MAXSZ	(15)
99 
100 /* Event Log Base Address register bits */
101 #define	AMD_IOMMU_EVENTLEN	(59 << 16 | 56)
102 #define	AMD_IOMMU_EVENTBASE	(51 << 16 | 12)
103 
104 #define	AMD_IOMMU_EVENTLOG_MINSZ	(8)
105 #define	AMD_IOMMU_EVENTLOG_MAXSZ	(15)
106 
107 /* Control register bits */
108 #define	AMD_IOMMU_CMDBUF_ENABLE		(12 << 16 | 12)
109 #define	AMD_IOMMU_ISOC			(11 << 16 | 11)
110 #define	AMD_IOMMU_COHERENT		(10 << 16 | 10)
111 #define	AMD_IOMMU_RESPASSPW		(9 << 16 | 9)
112 #define	AMD_IOMMU_PASSPW		(8 << 16 | 8)
113 #define	AMD_IOMMU_INVTO			(7 << 16 | 5)
114 #define	AMD_IOMMU_COMWAITINT_ENABLE	(4 << 16 | 4)
115 #define	AMD_IOMMU_EVENTINT_ENABLE	(3 << 16 | 3)
116 #define	AMD_IOMMU_EVENTLOG_ENABLE	(2 << 16 | 2)
117 #define	AMD_IOMMU_HT_TUN_ENABLE		(1 << 16 | 1)
118 #define	AMD_IOMMU_ENABLE		(0 << 16 | 0)
119 
120 /* Exclusion Base Register bits */
121 #define	AMD_IOMMU_EXCL_BASE_ADDR	(51 << 16 | 12)
122 #define	AMD_IOMMU_EXCL_BASE_ALLOW	(1 << 16 | 1)
123 #define	AMD_IOMMU_EXCL_BASE_EXEN	(0 << 16 | 0)
124 
125 /* Exclusion Limit Register bits */
126 #define	AMD_IOMMU_EXCL_LIM		(51 << 16 | 12)
127 
128 /* Command Buffer Head Pointer Register bits */
129 #define	AMD_IOMMU_CMDHEADPTR		(18 << 16 | 4)
130 
131 /* Command Buffer Tail Pointer Register bits */
132 #define	AMD_IOMMU_CMDTAILPTR		(18 << 16 | 4)
133 
134 /* Event Log Head Pointer Register bits */
135 #define	AMD_IOMMU_EVENTHEADPTR		(18 << 16 | 4)
136 
137 /* Event Log Tail Pointer Register bits */
138 #define	AMD_IOMMU_EVENTTAILPTR		(18 << 16 | 4)
139 
140 /* Status Register bits */
141 #define	AMD_IOMMU_CMDBUF_RUN		(4 << 16 | 4)
142 #define	AMD_IOMMU_EVENT_LOG_RUN		(3 << 16 | 3)
143 #define	AMD_IOMMU_COMWAIT_INT		(2 << 16 | 2)
144 #define	AMD_IOMMU_EVENT_LOG_INT		(1 << 16 | 1)
145 #define	AMD_IOMMU_EVENT_OVERFLOW_INT	(0 << 16 | 0)
146 
147 /* Device Table Bits */
148 
149 /* size in bytes of each device table entry */
150 #define	AMD_IOMMU_DEVTBL_ENTRY_SZ	(32)
151 
152 /* Interrupt Remapping related Device Table bits */
153 #define	AMD_IOMMU_DEVTBL_LINT1PASS	((191-128) << 16 | (191-128))
154 #define	AMD_IOMMU_DEVTBL_LINT0PASS	((190-128) << 16 | (190-128))
155 #define	AMD_IOMMU_DEVTBL_INTCTL		((189-128) << 16 | (188-128))
156 #define	AMD_IOMMU_DEVTBL_NMIPASS	((186-128) << 16 | (186-128))
157 #define	AMD_IOMMU_DEVTBL_EXTINTPAS	((185-128) << 16 | (185-128))
158 #define	AMD_IOMMU_DEVTBL_INITPASS	((184-128) << 16 | (184-128))
159 #define	AMD_IOMMU_DEVTBL_INTR_ROOT	((179-128) << 16 | (134-128))
160 #define	AMD_IOMMU_DEVTBL_IG		((133-128) << 16 | (133-128))
161 #define	AMD_IOMMU_DEVTBL_INTTABLEN	((132-128) << 16 | (129-128))
162 #define	AMD_IOMMU_DEVTBL_IV		((128-128) << 16 | (128-128))
163 
164 /* DMA Remapping related Device Table Bits */
165 #define	AMD_IOMMU_DEVTBL_SYSMGT		((105-64) << 16 | (104-64))
166 #define	AMD_IOMMU_DEVTBL_EX		((103-64) << 16 | (103-64))
167 #define	AMD_IOMMU_DEVTBL_SD		((102-64) << 16 | (102-64))
168 #define	AMD_IOMMU_DEVTBL_CACHE		((101-64) << 16 | (101-64))
169 #define	AMD_IOMMU_DEVTBL_IOCTL		((100-64) << 16 | (99-64))
170 #define	AMD_IOMMU_DEVTBL_SA		((98-64) << 16 | (98-64))
171 #define	AMD_IOMMU_DEVTBL_SE		((97-64) << 16 | (97-64))
172 #define	AMD_IOMMU_DEVTBL_IOTLB		((96-64) << 16 | (96-64))
173 #define	AMD_IOMMU_DEVTBL_DOMAINID	((79-64) << 16 | (64-64))
174 #define	AMD_IOMMU_DEVTBL_IW		(62 << 16 | 62)
175 #define	AMD_IOMMU_DEVTBL_IR		(61 << 16 | 61)
176 #define	AMD_IOMMU_DEVTBL_ROOT_PGTBL	(51 << 16 | 12)
177 #define	AMD_IOMMU_DEVTBL_PG_MODE	(11 << 16 | 9)
178 #define	AMD_IOMMU_DEVTBL_TV		(1 << 16 | 1)
179 #define	AMD_IOMMU_DEVTBL_V		(0 << 16 | 0)
180 
181 #define	BUS_DEVFN_TO_BDF(b, devfn)	(devfn)
182 #define	AMD_IOMMU_ALIAS_HASH_SZ		(256)
183 
184 #define	AMD_IOMMU_REG_ADDR_LOCKED	(0x1)
185 
186 /*
187  * IOMMU Command bits
188  */
189 
190 typedef enum {
191 	AMD_IOMMU_CMD_INVAL = 0,
192 	AMD_IOMMU_CMD_COMPL_WAIT,
193 	AMD_IOMMU_CMD_INVAL_DEVTAB_ENTRY,
194 	AMD_IOMMU_CMD_INVAL_IOMMU_PAGES,
195 	AMD_IOMMU_CMD_INVAL_IOTLB_PAGES,
196 	AMD_IOMMU_CMD_INVAL_INTR_TABLE,
197 } amd_iommu_cmd_t;
198 
199 typedef enum {
200 	AMD_IOMMU_CMD_FLAGS_NONE = 0,
201 	AMD_IOMMU_CMD_FLAGS_COMPL_WAIT = 1,
202 	AMD_IOMMU_CMD_FLAGS_COMPL_WAIT_F = 2,
203 	AMD_IOMMU_CMD_FLAGS_COMPL_WAIT_S = 4,
204 	AMD_IOMMU_CMD_FLAGS_PAGE_PDE_INVAL = 8,
205 	AMD_IOMMU_CMD_FLAGS_PAGE_INVAL_S = 16,
206 	AMD_IOMMU_CMD_FLAGS_IOTLB_INVAL_S = 32
207 } amd_iommu_cmd_flags_t;
208 
209 /* Common command bits */
210 #define	AMD_IOMMU_CMD_OPCODE		(31 << 16 | 28)
211 
212 /* Completion Wait command bits */
213 #define	AMD_IOMMU_CMD_COMPL_WAIT_S		(0 << 16 | 0)
214 #define	AMD_IOMMU_CMD_COMPL_WAIT_I		(1 << 16 | 1)
215 #define	AMD_IOMMU_CMD_COMPL_WAIT_F		(2 << 16 | 2)
216 #define	AMD_IOMMU_CMD_COMPL_WAIT_STORE_ADDR_LO	(31 << 16 | 3)
217 #define	AMD_IOMMU_CMD_COMPL_WAIT_STORE_ADDR_HI	(19 << 16 | 0)
218 
219 /* Invalidate Device Table entry command bits */
220 #define	AMD_IOMMU_CMD_INVAL_DEVTAB_DEVICEID		(15 << 16 | 0)
221 
222 /* Invalidate IOMMU Pages command bits */
223 #define	AMD_IOMMU_CMD_INVAL_PAGES_DOMAINID		(15 << 16 | 0)
224 #define	AMD_IOMMU_CMD_INVAL_PAGES_S			(0 << 16 | 0)
225 #define	AMD_IOMMU_CMD_INVAL_PAGES_PDE			(1 << 16 | 1)
226 #define	AMD_IOMMU_CMD_INVAL_PAGES_ADDR_LO		(31 << 16 | 12)
227 #define	AMD_IOMMU_CMD_INVAL_PAGES_ADDR_HI		(63 << 16 | 32)
228 
229 
230 /* Invalidate IOTLB command bits */
231 #define	AMD_IOMMU_CMD_INVAL_IOTLB_DEVICEID		(15 << 16 | 0)
232 #define	AMD_IOMMU_CMD_INVAL_IOTLB_MAXPEND		(31 << 16 | 24)
233 #define	AMD_IOMMU_CMD_INVAL_IOTLB_QUEUEID		(15 << 16 | 0)
234 #define	AMD_IOMMU_CMD_INVAL_IOTLB_S			(0 << 16 | 0)
235 #define	AMD_IOMMU_CMD_INVAL_IOTLB_ADDR_LO		(31 << 16 | 12)
236 #define	AMD_IOMMU_CMD_INVAL_IOTLB_ADDR_HI		(31 << 16 | 0)
237 
238 #define	AMD_IOMMU_DEFAULT_MAXPEND			(10)
239 
240 /* Invalidate Interrupt Table bits */
241 #define	AMD_IOMMU_CMD_INVAL_INTR_DEVICEID		(15 << 16 | 0)
242 
243 #if defined(__amd64)
244 #define	dmac_cookie_addr	dmac_laddress
245 #else
246 #define	dmac_cookie_addr	dmac_address
247 #endif
248 
249 #define	AMD_IOMMU_TABLE_ALIGN	((1ULL << 12) - 1)
250 
251 #define	AMD_IOMMU_MAX_DEVICEID	(0xFFFF)
252 
253 /*
254  * DMA sync macros
255  * TODO: optimize sync only small ranges
256  */
257 #define	SYNC_FORDEV(h)	(void) ddi_dma_sync(h, 0, 0, DDI_DMA_SYNC_FORDEV)
258 #define	SYNC_FORKERN(h)	(void) ddi_dma_sync(h, 0, 0, DDI_DMA_SYNC_FORKERNEL)
259 
260 #define	WAIT_SEC(s)	drv_usecwait(1000000*(s))
261 
262 #define	CMD2OFF(c)	((c) << 4)
263 #define	OFF2CMD(o)	((o) >> 4)
264 
265 typedef union split {
266 	uint64_t u64;
267 	uint32_t u32[2];
268 } split_t;
269 
270 #define	BITPOS_START(b)	((b) >> 16)
271 #define	BITPOS_END(b)	((b) & 0xFFFF)
272 
273 #define	START_MASK64(s)	(((s) == 63) ? ~((uint64_t)0) : \
274 	(uint64_t)((1ULL << ((s)+1)) - 1))
275 #define	START_MASK32(s)	(((s) == 31) ? ~((uint32_t)0) : \
276 	(uint32_t)((1ULL << ((s)+1)) - 1))
277 #define	START_MASK16(s)	(((s) == 15) ? ~((uint16_t)0) : \
278 	(uint16_t)((1ULL << ((s)+1)) - 1))
279 #define	START_MASK8(s)	(((s) == 7) ? ~((uint8_t)0) : \
280 	(uint8_t)((1ULL << ((s)+1)) - 1))
281 
282 #define	END_MASK(e)	((1ULL << (e)) - 1)
283 
284 #define	BIT_MASK64(s, e)	(uint64_t)(START_MASK64(s) & ~END_MASK(e))
285 #define	BIT_MASK32(s, e)	(uint32_t)(START_MASK32(s) & ~END_MASK(e))
286 #define	BIT_MASK16(s, e)	(uint16_t)(START_MASK16(s) & ~END_MASK(e))
287 #define	BIT_MASK8(s, e)		(uint8_t)(START_MASK8(s) & ~END_MASK(e))
288 
289 #define	AMD_IOMMU_REG_GET64_IMPL(rp, b) \
290 	(((*(rp)) & (START_MASK64(BITPOS_START(b)))) >> BITPOS_END(b))
291 #define	AMD_IOMMU_REG_GET64(rp, b) 					 \
292 	((amd_iommu_64bit_bug) ? amd_iommu_reg_get64_workaround(rp, b) : \
293 	AMD_IOMMU_REG_GET64_IMPL(rp, b))
294 #define	AMD_IOMMU_REG_GET32(rp, b) \
295 	(((*(rp)) & (START_MASK32(BITPOS_START(b)))) >> BITPOS_END(b))
296 #define	AMD_IOMMU_REG_GET16(rp, b) \
297 	(((*(rp)) & (START_MASK16(BITPOS_START(b)))) >> BITPOS_END(b))
298 #define	AMD_IOMMU_REG_GET8(rp, b) \
299 	(((*(rp)) & (START_MASK8(BITPOS_START(b)))) >> BITPOS_END(b))
300 
301 #define	AMD_IOMMU_REG_SET64_IMPL(rp, b, v) \
302 	((*(rp)) = \
303 	(((uint64_t)(*(rp)) & ~(BIT_MASK64(BITPOS_START(b), BITPOS_END(b)))) \
304 	| ((uint64_t)(v) << BITPOS_END(b))))
305 
306 #define	AMD_IOMMU_REG_SET64(rp, b, v) 			\
307 	(void) ((amd_iommu_64bit_bug) ?			\
308 	amd_iommu_reg_set64_workaround(rp, b, v) : 	\
309 	AMD_IOMMU_REG_SET64_IMPL(rp, b, v))
310 
311 #define	AMD_IOMMU_REG_SET32(rp, b, v) \
312 	((*(rp)) = \
313 	(((uint32_t)(*(rp)) & ~(BIT_MASK32(BITPOS_START(b), BITPOS_END(b)))) \
314 	| ((uint32_t)(v) << BITPOS_END(b))))
315 
316 #define	AMD_IOMMU_REG_SET16(rp, b, v) \
317 	((*(rp)) = \
318 	(((uint16_t)(*(rp)) & ~(BIT_MASK16(BITPOS_START(b), BITPOS_END(b)))) \
319 	| ((uint16_t)(v) << BITPOS_END(b))))
320 
321 #define	AMD_IOMMU_REG_SET8(rp, b, v) \
322 	((*(rp)) = \
323 	(((uint8_t)(*(rp)) & ~(BIT_MASK8(BITPOS_START(b), BITPOS_END(b)))) \
324 	| ((uint8_t)(v) << BITPOS_END(b))))
325 
326 /*
327  * Cast a 64 bit pointer to a uint64_t *
328  */
329 #define	REGADDR64(a)	((uint64_t *)(uintptr_t)(a))
330 
331 typedef enum {
332 	AMD_IOMMU_INTR_INVALID = 0,
333 	AMD_IOMMU_INTR_TABLE,
334 	AMD_IOMMU_INTR_ALLOCED,
335 	AMD_IOMMU_INTR_HANDLER,
336 	AMD_IOMMU_INTR_ENABLED
337 } amd_iommu_intr_state_t;
338 
339 
340 typedef struct amd_iommu {
341 	kmutex_t aiomt_mutex;
342 	kmutex_t aiomt_eventlock;
343 	kmutex_t aiomt_cmdlock;
344 	dev_info_t *aiomt_dip;
345 	uint16_t aiomt_bdf;
346 	int aiomt_idx;
347 	iommulib_handle_t aiomt_iommulib_handle;
348 	iommulib_ops_t *aiomt_iommulib_ops;
349 	uint32_t aiomt_cap_hdr;
350 	uint8_t aiomt_npcache;
351 	uint8_t aiomt_httun;
352 	uint8_t aiomt_iotlb;
353 	uint8_t aiomt_captype;
354 	uint8_t aiomt_capid;
355 	uint32_t aiomt_low_addr32;
356 	uint32_t aiomt_hi_addr32;
357 	uint64_t aiomt_reg_pa;
358 	uint64_t aiomt_va;
359 	uint64_t aiomt_reg_va;
360 	uint32_t aiomt_range;
361 	uint8_t aiomt_rng_bus;
362 	uint8_t aiomt_first_devfn;
363 	uint8_t aiomt_last_devfn;
364 	uint8_t aiomt_rng_valid;
365 	uint8_t aiomt_ht_unitid;
366 	uint32_t aiomt_misc;
367 	uint8_t aiomt_htatsresv;
368 	uint8_t aiomt_vasize;
369 	uint8_t aiomt_pasize;
370 	uint8_t aiomt_msinum;
371 	uint8_t aiomt_reg_pages;
372 	uint32_t aiomt_reg_size;
373 	uint32_t aiomt_devtbl_sz;
374 	uint32_t aiomt_cmdbuf_sz;
375 	uint32_t aiomt_eventlog_sz;
376 	caddr_t aiomt_devtbl;
377 	caddr_t aiomt_cmdbuf;
378 	caddr_t aiomt_eventlog;
379 	uint32_t *aiomt_cmd_tail;
380 	uint32_t *aiomt_event_head;
381 	ddi_dma_handle_t aiomt_dmahdl;
382 	void *aiomt_dma_bufva;
383 	uint64_t aiomt_dma_mem_realsz;
384 	ddi_acc_handle_t aiomt_dma_mem_hdl;
385 	ddi_dma_cookie_t aiomt_buf_dma_cookie;
386 	uint_t aiomt_buf_dma_ncookie;
387 	amd_iommu_intr_state_t aiomt_intr_state;
388 	ddi_intr_handle_t *aiomt_intr_htable;
389 	uint32_t aiomt_intr_htable_sz;
390 	uint32_t aiomt_actual_intrs;
391 	uint32_t aiomt_intr_cap;
392 	uint64_t aiomt_reg_devtbl_va;
393 	uint64_t aiomt_reg_cmdbuf_va;
394 	uint64_t aiomt_reg_eventlog_va;
395 	uint64_t aiomt_reg_ctrl_va;
396 	uint64_t aiomt_reg_excl_base_va;
397 	uint64_t aiomt_reg_excl_lim_va;
398 	uint64_t aiomt_reg_cmdbuf_head_va;
399 	uint64_t aiomt_reg_cmdbuf_tail_va;
400 	uint64_t aiomt_reg_eventlog_head_va;
401 	uint64_t aiomt_reg_eventlog_tail_va;
402 	uint64_t aiomt_reg_status_va;
403 	struct amd_iommu *aiomt_next;
404 } amd_iommu_t;
405 
406 typedef struct amd_iommu_dma_devtbl_ent {
407 	uint16_t de_domainid;
408 	uint8_t de_R;
409 	uint8_t de_W;
410 	caddr_t de_root_pgtbl;
411 	uint8_t de_pgmode;
412 } amd_iommu_dma_devtbl_entry_t;
413 
414 typedef struct amd_iommu_alias {
415 	uint16_t al_bdf;
416 	uint16_t al_src_bdf;
417 	struct amd_iommu_alias *al_next;
418 } amd_iommu_alias_t;
419 
420 typedef struct amd_iommu_cmdargs {
421 	uint64_t ca_addr;
422 	uint16_t ca_domainid;
423 	uint16_t ca_deviceid;
424 } amd_iommu_cmdargs_t;
425 
426 struct amd_iommu_page_table;
427 
428 typedef struct amd_iommu_page_table_hash {
429 	kmutex_t ampt_lock;
430 	struct amd_iommu_page_table **ampt_hash;
431 } amd_iommu_page_table_hash_t;
432 
433 typedef enum {
434 	AMD_IOMMU_LOG_INVALID_OP = 0,
435 	AMD_IOMMU_LOG_DISPLAY,
436 	AMD_IOMMU_LOG_DISCARD
437 } amd_iommu_log_op_t;
438 
439 typedef enum {
440 	AMD_IOMMU_DEBUG_NONE = 0,
441 	AMD_IOMMU_DEBUG_ALLOCHDL = 0x1,
442 	AMD_IOMMU_DEBUG_FREEHDL = 0x2,
443 	AMD_IOMMU_DEBUG_BIND = 0x4,
444 	AMD_IOMMU_DEBUG_UNBIND = 0x8,
445 	AMD_IOMMU_DEBUG_WIN = 0x10,
446 	AMD_IOMMU_DEBUG_PAGE_TABLES = 0x20,
447 	AMD_IOMMU_DEBUG_DEVTBL = 0x40,
448 	AMD_IOMMU_DEBUG_CMDBUF = 0x80,
449 	AMD_IOMMU_DEBUG_EVENTLOG = 0x100,
450 	AMD_IOMMU_DEBUG_ACPI = 0x200,
451 	AMD_IOMMU_DEBUG_PA2VA = 0x400,
452 	AMD_IOMMU_DEBUG_TABLES = 0x800,
453 	AMD_IOMMU_DEBUG_EXCL = 0x1000,
454 	AMD_IOMMU_DEBUG_INTR = 0x2000
455 } amd_iommu_debug_t;
456 
457 extern const char *amd_iommu_modname;
458 extern kmutex_t amd_iommu_global_lock;
459 extern amd_iommu_alias_t **amd_iommu_alias;
460 extern amd_iommu_page_table_hash_t amd_iommu_page_table_hash;
461 extern ddi_device_acc_attr_t amd_iommu_devacc;
462 extern amd_iommu_debug_t amd_iommu_debug;
463 
464 extern uint8_t amd_iommu_htatsresv;
465 extern uint8_t amd_iommu_vasize;
466 extern uint8_t amd_iommu_pasize;
467 extern int amd_iommu_64bit_bug;
468 extern int amd_iommu_unity_map;
469 extern int amd_iommu_no_RW_perms;
470 extern int amd_iommu_no_unmap;
471 extern int amd_iommu_pageva_inval_all;
472 extern int amd_iommu_disable;
473 extern char *amd_iommu_disable_list;
474 
475 extern uint64_t amd_iommu_reg_get64_workaround(uint64_t *regp, uint32_t bits);
476 extern uint64_t amd_iommu_reg_set64_workaround(uint64_t *regp, uint32_t bits,
477     uint64_t value);
478 extern dev_info_t *amd_iommu_pci_dip(dev_info_t *rdip, const char *path);
479 
480 int amd_iommu_cmd(amd_iommu_t *iommu, amd_iommu_cmd_t cmd,
481     amd_iommu_cmdargs_t *cmdargs, amd_iommu_cmd_flags_t flags, int lock_held);
482 int amd_iommu_page_table_hash_init(amd_iommu_page_table_hash_t *ampt);
483 void amd_iommu_page_table_hash_fini(amd_iommu_page_table_hash_t *ampt);
484 
485 int amd_iommu_read_log(amd_iommu_t *iommu, amd_iommu_log_op_t op);
486 void amd_iommu_read_boot_props(void);
487 void amd_iommu_lookup_conf_props(dev_info_t *dip);
488 
489 #endif	/* _KERNEL */
490 
491 #ifdef	__cplusplus
492 }
493 #endif
494 
495 #endif	/* _AMD_IOMMU_IMPL_H */
496