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