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