xref: /titanic_52/usr/src/uts/i86pc/io/amd_iommu/amd_iommu_acpi.h (revision ba758cf1b2fe06a606303351c36a766f2f9f6665)
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_ACPI_H
26 #define	_AMD_IOMMU_ACPI_H
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 #include <sys/sunddi.h>
33 #include <sys/acpi/acpi.h>
34 #include <sys/acpica.h>
35 #include <sys/amd_iommu.h>
36 #include "amd_iommu_impl.h"
37 
38 #ifdef _KERNEL
39 
40 #define	IVRS_SIG	"IVRS"
41 
42 /*
43  * IVINFO settings
44  */
45 #define	AMD_IOMMU_ACPI_IVINFO_RSV1	(31 << 16 | 23)
46 #define	AMD_IOMMU_ACPI_HT_ATSRSV	(22 << 16 | 22)
47 #define	AMD_IOMMU_ACPI_VA_SIZE		(21 << 16 | 15)
48 #define	AMD_IOMMU_ACPI_PA_SIZE		(14 << 16 | 8)
49 #define	AMD_IOMMU_ACPI_IVINFO_RSV2	(7 << 16 | 0)
50 
51 /*
52  * IVHD Device entry len field
53  */
54 #define	AMD_IOMMU_ACPI_DEVENTRY_LEN	(7 << 16 | 6)
55 
56 /*
57  * IVHD flag fields definition
58  */
59 #define	AMD_IOMMU_ACPI_IVHD_FLAGS_RSV		(7 << 16 | 5)
60 #define	AMD_IOMMU_ACPI_IVHD_FLAGS_IOTLBSUP	(4 << 16 | 4)
61 #define	AMD_IOMMU_ACPI_IVHD_FLAGS_ISOC		(3 << 16 | 3)
62 #define	AMD_IOMMU_ACPI_IVHD_FLAGS_RESPASSPW	(2 << 16 | 2)
63 #define	AMD_IOMMU_ACPI_IVHD_FLAGS_PASSPW	(1 << 16 | 1)
64 #define	AMD_IOMMU_ACPI_IVHD_FLAGS_HTTUNEN	(0 << 16 | 0)
65 
66 /*
67  * IVHD IOMMU info fields
68  */
69 #define	AMD_IOMMU_ACPI_IOMMU_INFO_RSV1		(15 << 16 | 13)
70 #define	AMD_IOMMU_ACPI_IOMMU_INFO_UNITID	(12 << 16 | 8)
71 #define	AMD_IOMMU_ACPI_IOMMU_INFO_RSV2		(7 << 16 | 5)
72 #define	AMD_IOMMU_ACPI_IOMMU_INFO_MSINUM	(4 << 16 | 0)
73 
74 /*
75  * IVHD deventry data settings
76  */
77 #define	AMD_IOMMU_ACPI_LINT1PASS	(7 << 16 | 7)
78 #define	AMD_IOMMU_ACPI_LINT0PASS	(6 << 16 | 6)
79 #define	AMD_IOMMU_ACPI_SYSMGT		(5 << 16 | 4)
80 #define	AMD_IOMMU_ACPI_DATRSV		(3 << 16 | 3)
81 #define	AMD_IOMMU_ACPI_NMIPASS		(2 << 16 | 2)
82 #define	AMD_IOMMU_ACPI_EXTINTPASS	(1 << 16 | 1)
83 #define	AMD_IOMMU_ACPI_INITPASS		(0 << 16 | 0)
84 
85 /*
86  * IVHD deventry extended data settings
87  */
88 #define	AMD_IOMMU_ACPI_ATSDISABLED	(31 << 16 | 31)
89 #define	AMD_IOMMU_ACPI_EXTDATRSV	(30 << 16 | 0)
90 
91 /*
92  * IVMD flags fields settings
93  */
94 #define	AMD_IOMMU_ACPI_IVMD_RSV		(7 << 16 | 4)
95 #define	AMD_IOMMU_ACPI_IVMD_EXCL_RANGE	(3 << 16 | 3)
96 #define	AMD_IOMMU_ACPI_IVMD_IW		(2 << 16 | 2)
97 #define	AMD_IOMMU_ACPI_IVMD_IR		(1 << 16 | 1)
98 #define	AMD_IOMMU_ACPI_IVMD_UNITY	(0 << 16 | 0)
99 
100 #define	AMD_IOMMU_ACPI_INFO_HASH_SZ	(256)
101 
102 /*
103  * Deventry special device "variety"
104  */
105 #define	AMD_IOMMU_ACPI_SPECIAL_APIC	0x1
106 #define	AMD_IOMMU_ACPI_SPECIAL_HPET	0x2
107 
108 typedef enum {
109 	DEVENTRY_INVALID = 0,
110 	DEVENTRY_ALL = 1,
111 	DEVENTRY_SELECT,
112 	DEVENTRY_RANGE,
113 	DEVENTRY_RANGE_END,
114 	DEVENTRY_ALIAS_SELECT,
115 	DEVENTRY_ALIAS_RANGE,
116 	DEVENTRY_EXTENDED_SELECT,
117 	DEVENTRY_EXTENDED_RANGE,
118 	DEVENTRY_SPECIAL_DEVICE
119 } ivhd_deventry_type_t;
120 
121 typedef enum {
122 	IVMD_DEVICE_INVALID = 0,
123 	IVMD_DEVICEID_ALL,
124 	IVMD_DEVICEID_SELECT,
125 	IVMD_DEVICEID_RANGE
126 } ivmd_deviceid_type_t;
127 
128 typedef struct ivhd_deventry {
129 	uint8_t idev_len;
130 	ivhd_deventry_type_t  idev_type;
131 	int32_t idev_deviceid;
132 	int32_t idev_src_deviceid;
133 	uint8_t idev_handle;
134 	uint8_t idev_variety;
135 	uint8_t idev_Lint1Pass;
136 	uint8_t idev_Lint0Pass;
137 	uint8_t idev_SysMgt;
138 	uint8_t idev_NMIPass;
139 	uint8_t idev_ExtIntPass;
140 	uint8_t idev_INITPass;
141 	uint8_t idev_AtsDisabled;
142 	struct ivhd_deventry *idev_next;
143 } ivhd_deventry_t;
144 
145 typedef struct ivhd {
146 	uint8_t ivhd_type;
147 	uint8_t ivhd_flags;
148 	uint16_t ivhd_len;
149 	uint16_t ivhd_deviceid;
150 	uint16_t ivhd_cap_off;
151 	uint64_t ivhd_reg_base;
152 	uint16_t ivhd_pci_seg;
153 	uint16_t ivhd_iommu_info;
154 	uint32_t ivhd_resv;
155 } ivhd_t;
156 
157 typedef struct ivhd_container {
158 	ivhd_t *ivhdc_ivhd;
159 	ivhd_deventry_t *ivhdc_first_deventry;
160 	ivhd_deventry_t *ivhdc_last_deventry;
161 	struct ivhd_container *ivhdc_next;
162 } ivhd_container_t;
163 
164 typedef struct ivmd {
165 	uint8_t ivmd_type;
166 	uint8_t ivmd_flags;
167 	uint16_t ivmd_len;
168 	uint16_t ivmd_deviceid;
169 	uint16_t ivmd_auxdata;
170 	uint64_t ivmd_resv;
171 	uint64_t ivmd_phys_start;
172 	uint64_t ivmd_phys_len;
173 } ivmd_t;
174 
175 typedef struct ivmd_container {
176 	ivmd_t *ivmdc_ivmd;
177 	struct ivmd_container *ivmdc_next;
178 } ivmd_container_t;
179 
180 typedef struct ivrs {
181 	struct acpi_table_header ivrs_hdr;
182 	uint32_t ivrs_ivinfo;
183 	uint64_t ivrs_resv;
184 } ivrs_t;
185 
186 typedef struct amd_iommu_acpi {
187 	struct ivrs *acp_ivrs;
188 	ivhd_container_t *acp_first_ivhdc;
189 	ivhd_container_t *acp_last_ivhdc;
190 	ivmd_container_t *acp_first_ivmdc;
191 	ivmd_container_t *acp_last_ivmdc;
192 } amd_iommu_acpi_t;
193 
194 
195 /* Global IVINFo fields */
196 typedef struct amd_iommu_acpi_global {
197 	uint8_t acg_HtAtsResv;
198 	uint8_t acg_VAsize;
199 	uint8_t acg_PAsize;
200 } amd_iommu_acpi_global_t;
201 
202 typedef struct amd_iommu_acpi_ivhd {
203 	int32_t ach_deviceid_start;
204 	int32_t ach_deviceid_end;
205 
206 	/* IVHD deventry type */
207 	ivhd_deventry_type_t ach_dev_type;
208 
209 	/* IVHD flag fields */
210 	uint8_t ach_IotlbSup;
211 	uint8_t ach_Isoc;
212 	uint8_t ach_ResPassPW;
213 	uint8_t ach_PassPW;
214 	uint8_t ach_HtTunEn;
215 
216 	/* IVHD fields */
217 	uint16_t ach_IOMMU_deviceid;
218 	uint16_t ach_IOMMU_cap_off;
219 	uint64_t ach_IOMMU_reg_base;
220 	uint16_t ach_IOMMU_pci_seg;
221 
222 	/* IVHD IOMMU info fields */
223 	uint8_t ach_IOMMU_UnitID;
224 	uint8_t ach_IOMMU_MSInum;
225 
226 	/* IVHD deventry data settings */
227 	uint8_t ach_Lint1Pass;
228 	uint8_t ach_Lint0Pass;
229 	uint8_t ach_SysMgt;
230 	uint8_t ach_NMIPass;
231 	uint8_t ach_ExtIntPass;
232 	uint8_t ach_INITPass;
233 
234 	/* alias */
235 	int32_t ach_src_deviceid;
236 
237 	/* IVHD deventry extended data settings */
238 	uint8_t ach_AtsDisabled;
239 
240 	/* IVHD deventry special device */
241 	uint8_t ach_special_handle;
242 	uint8_t ach_special_variety;
243 
244 	struct amd_iommu_acpi_ivhd *ach_next;
245 } amd_iommu_acpi_ivhd_t;
246 
247 typedef struct amd_iommu_acpi_ivmd {
248 	int32_t acm_deviceid_start;
249 	int32_t acm_deviceid_end;
250 
251 	/* IVMD type */
252 	ivmd_deviceid_type_t acm_dev_type;
253 
254 	/* IVMD flags */
255 	uint8_t acm_ExclRange;
256 	uint8_t acm_IW;
257 	uint8_t acm_IR;
258 	uint8_t acm_Unity;
259 
260 	/* IVMD mem block */
261 	uint64_t acm_ivmd_phys_start;
262 	uint64_t acm_ivmd_phys_len;
263 
264 	struct amd_iommu_acpi_ivmd *acm_next;
265 } amd_iommu_acpi_ivmd_t;
266 
267 typedef union {
268 	uint16_t   ent16;
269 	uint8_t	   ent8[2];
270 } align_16_t;
271 
272 typedef union {
273 	uint32_t   ent32;
274 	uint8_t	   ent8[4];
275 } align_32_t;
276 
277 typedef union {
278 	ivhd_t *ivhdp;
279 	char   *cp;
280 } align_ivhd_t;
281 
282 typedef union {
283 	ivmd_t *ivmdp;
284 	char   *cp;
285 } align_ivmd_t;
286 
287 #pragma pack()
288 
289 int amd_iommu_acpi_init(void);
290 void amd_iommu_acpi_fini(void);
291 amd_iommu_acpi_ivhd_t *amd_iommu_lookup_all_ivhd(void);
292 amd_iommu_acpi_ivmd_t *amd_iommu_lookup_all_ivmd(void);
293 amd_iommu_acpi_ivhd_t *amd_iommu_lookup_any_ivhd(amd_iommu_t *);
294 amd_iommu_acpi_ivmd_t *amd_iommu_lookup_any_ivmd(void);
295 amd_iommu_acpi_global_t *amd_iommu_lookup_acpi_global(void);
296 amd_iommu_acpi_ivhd_t *amd_iommu_lookup_ivhd(int32_t deviceid);
297 amd_iommu_acpi_ivmd_t *amd_iommu_lookup_ivmd(int32_t deviceid);
298 int amd_iommu_acpi_init_devtbl(amd_iommu_t *iommu);
299 
300 #endif /* _KERNEL */
301 
302 #ifdef __cplusplus
303 }
304 #endif
305 
306 #endif	/* _AMD_IOMMU_ACPI_H */
307