1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13#pragma pack(push,1) 14 15#define ACPI_APIC_LOCAL 0x00 16#define ACPI_APIC_IOAPIC 0x01 17#define ACPI_APIC_ISO 0x02 18#define ACPI_APIC_NMI 0x03 19#define ACPI_APIC_LOCAL_NMI 0x04 20#define ACPI_APIC_LOCAL_AO 0x05 21#define ACPI_APIC_IOSAPIC 0x06 22#define ACPI_APIC_SAPIC 0x07 23#define ACPI_APIC_PINT_SRC 0x08 24#define ACPI_APIC_LOCAL_X2APIC 0x09 25#define ACPI_APIC_LOCAL_X2APIC_NMI 0x0A 26#define ACPI_APIC_GIC 0x0B 27#define ACPI_APIC_GICD 0x0C 28 29/* interrupt control structure header */ 30typedef struct acpi_madt_ics_hdr { 31 uint8_t type; 32 uint8_t length; 33} acpi_madt_ics_hdr_t; 34 35/* Processor local APIC (0)*/ 36typedef struct acpi_madt_local_apic { 37 acpi_madt_ics_hdr_t header; 38 uint8_t processor_id; 39 uint8_t apic_id; 40 uint32_t flags; 41} acpi_madt_local_apic_t; 42 43/* IO APIC structre (1)*/ 44typedef struct acpi_madt_ioapic { 45 acpi_madt_ics_hdr_t header; 46 uint8_t ioapic_id; 47 uint8_t res; /* 0 */ 48 uint32_t address; 49 uint32_t gs_interrupt_base; 50} acpi_madt_ioapic_t; 51 52/* Interrupt Source Override structure (2)*/ 53typedef struct acpi_madt_override { 54 acpi_madt_ics_hdr_t header; 55 uint8_t bus; 56 uint8_t src; 57 uint32_t gs_interrupt; 58 uint16_t mps_inti_flags; 59} acpi_madt_override_t; 60 61/* NMI source structure (3)*/ 62typedef struct acpi_madt_nmi { 63 acpi_madt_ics_hdr_t header; 64 uint16_t flags; 65 uint32_t gs_interrupt; 66} acpi_madt_nmi_t; 67 68/* Local APIC NMI structure (4)*/ 69typedef struct acpi_madt_locnmi { 70 acpi_madt_ics_hdr_t header; 71 uint8_t processor_id; 72 uint16_t flags; 73 uint8_t local_apic_lint; 74} acpi_madt_locnmi_t; 75 76/* Local APIC address override structure (5) */ 77typedef struct acpi_madt_locoverride { 78 acpi_madt_ics_hdr_t header; 79 uint8_t res[2]; 80 uint64_t local_apic_address; 81} acpi_madt_locoverride_t; 82 83/* IO SAPIC structure (6)*/ 84typedef struct acpi_madt_sapic { 85 acpi_madt_ics_hdr_t header; 86 uint8_t ioapic_id; 87 uint8_t res; 88 uint32_t gs_interrupt_base; 89 uint64_t iosapic_address; 90} acpi_madt_sapic_t; 91 92/* Processor Local SAPIC structure (7)*/ 93typedef struct acpi_madt_locsapic { 94 acpi_madt_ics_hdr_t header; 95 uint8_t processor_id; 96 uint8_t locsapic_id; 97 uint8_t locsapic_eid; 98 uint8_t res[3]; 99 uint32_t flags; 100 uint32_t processor_uid; 101 /* \0 terminated string */ 102 char processor_uid_str[]; 103} acpi_madt_locsapic_t; 104 105/* Platform interrupt source (8)*/ 106typedef struct acpi_madt_platformis { 107 acpi_madt_ics_hdr_t header; 108 uint16_t flags; 109 uint8_t int_type; 110 uint8_t processor_id; 111 uint8_t processor_eid; 112 uint8_t iosapic_vector; 113 uint32_t gs_interrupt; 114 uint32_t platform_int_src_flags; 115} acpi_madt_platformis_t; 116 117/* Processor local x2APIC structure (9)*/ 118typedef struct acpi_madt_locx2apic { 119 acpi_madt_ics_hdr_t header; 120 uint8_t res[2]; /* 0 */ 121 uint32_t local_x2apic_id; 122 uint32_t flags; 123 uint32_t processor_uid; 124} acpi_madt_locx2apic; 125 126/* Local x2 APIC NMI structure (A) */ 127typedef struct acpi_madt_locx2apicnmi { 128 acpi_madt_ics_hdr_t header; 129 uint16_t flags; 130 uint32_t processor_uid; 131 uint8_t local_x2apic_lint; 132 uint8_t res[3]; /* 0 */ 133} acpi_madt_locx2apicnmi_t; 134 135/* Processor Local GIC structure (B) */ 136typedef struct acpi_madt_gic { 137 acpi_madt_ics_hdr_t header; 138 uint8_t res[2]; /* 0 */ 139 uint32_t gic_id; 140 uint32_t processor_uid; 141 uint32_t flags; 142 uint32_t parking_prot_version; 143 uint64_t parked_address; 144 uint64_t gic_address; 145} acpi_madt_gic_t; 146 147/* GIC Distributor structure (C) */ 148typedef struct acpi_madt_gicdist { 149 acpi_madt_ics_hdr_t header; 150 uint8_t res1[2]; 151 uint32_t gic_id; 152 uint64_t gicdist_address; 153 uint32_t system_vector_base; 154 uint8_t res2[4]; 155} acpi_madt_gicdist_t; 156 157/* MADT structure */ 158typedef struct acpi_madt { 159 acpi_header_t header; 160 uint32_t local_int_crt_address; 161 uint32_t flags; 162 /* list of APICS */ 163// acpi_madt_ics_hdr_t ics; 164} acpi_madt_t; 165 166#pragma pack(pop) 167 168/******************************** 169 **** MADT sub table helpers **** 170 ********************************/ 171 172/* Retrieve the header of the first entry */ 173static inline acpi_madt_ics_hdr_t* 174acpi_madt_first_ics(acpi_madt_t* tbl) 175{ 176 return (acpi_madt_ics_hdr_t*)(tbl + 1); 177} 178 179/* Retrieve the next DMAR sub header */ 180static inline acpi_madt_ics_hdr_t* 181acpi_madt_next_ics(acpi_madt_t* tbl, 182 acpi_madt_ics_hdr_t* hdr) 183{ 184 void* next = (uint8_t*)hdr + hdr->length; 185 void* end = (uint8_t*)tbl + tbl->header.length; 186 if (next < end) { 187 return (acpi_madt_ics_hdr_t*)next; 188 } else { 189 return NULL; 190 } 191} 192 193/* Retrieve the DMAR sub header located at the specified index */ 194static inline acpi_madt_ics_hdr_t* 195acpi_madt_ics_at(acpi_madt_t* tbl, int index) 196{ 197 acpi_madt_ics_hdr_t* next = acpi_madt_first_ics(tbl); 198 while (next != NULL && index-- > 0) { 199 next = acpi_madt_next_ics(tbl, next); 200 } 201 return next; 202} 203 204/* Retrieve the next DMAR sub header of the specified type */ 205static inline acpi_madt_ics_hdr_t* 206acpi_madt_next_ics_type(acpi_madt_t* tbl, 207 acpi_madt_ics_hdr_t* hdr, int type) 208{ 209 do { 210 hdr = acpi_madt_next_ics(tbl, hdr); 211 if (hdr == NULL) { 212 return NULL; 213 } 214 if (hdr->type == type) { 215 return hdr; 216 } 217 } while (1); 218} 219 220/* Retrieve the first DMAR sub header of the specified type */ 221static inline acpi_madt_ics_hdr_t* 222acpi_madt_first_ics_type(acpi_madt_t* tbl, int type) 223{ 224 acpi_madt_ics_hdr_t* hdr = acpi_madt_first_ics(tbl); 225 if (hdr == NULL) { 226 return NULL; 227 } 228 229 if (hdr->type != type) { 230 return acpi_madt_next_ics_type(tbl, hdr, type); 231 } else { 232 return hdr; 233 } 234} 235