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 <acpica/include/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 */