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