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