1 /* 2 * Based on acpi.c from coreboot 3 * 4 * Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com> 5 * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com> 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <cpu.h> 12 #include <dm.h> 13 #include <dm/uclass-internal.h> 14 #include <asm/acpi_table.h> 15 #include <asm/lapic.h> 16 #include <asm/tables.h> 17 18 /* 19 * IASL compiles the dsdt entries and writes the hex values 20 * to a C array AmlCode[] (see dsdt.c). 21 */ 22 extern const unsigned char AmlCode[]; 23 24 static void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, 25 struct acpi_xsdt *xsdt) 26 { 27 memset(rsdp, 0, sizeof(struct acpi_rsdp)); 28 29 memcpy(rsdp->signature, RSDP_SIG, 8); 30 memcpy(rsdp->oem_id, OEM_ID, 6); 31 32 rsdp->length = sizeof(struct acpi_rsdp); 33 rsdp->rsdt_address = (u32)rsdt; 34 35 /* 36 * Revision: ACPI 1.0: 0, ACPI 2.0/3.0/4.0: 2 37 * 38 * Some OSes expect an XSDT to be present for RSD PTR revisions >= 2. 39 * If we don't have an ACPI XSDT, force ACPI 1.0 (and thus RSD PTR 40 * revision 0) 41 */ 42 if (xsdt == NULL) { 43 rsdp->revision = ACPI_RSDP_REV_ACPI_1_0; 44 } else { 45 rsdp->xsdt_address = (u64)(u32)xsdt; 46 rsdp->revision = ACPI_RSDP_REV_ACPI_2_0; 47 } 48 49 /* Calculate checksums */ 50 rsdp->checksum = table_compute_checksum((void *)rsdp, 20); 51 rsdp->ext_checksum = table_compute_checksum((void *)rsdp, 52 sizeof(struct acpi_rsdp)); 53 } 54 55 void acpi_fill_header(struct acpi_table_header *header, char *signature) 56 { 57 memcpy(header->signature, signature, 4); 58 memcpy(header->oem_id, OEM_ID, 6); 59 memcpy(header->oem_table_id, OEM_TABLE_ID, 8); 60 memcpy(header->aslc_id, ASLC_ID, 4); 61 } 62 63 static void acpi_write_rsdt(struct acpi_rsdt *rsdt) 64 { 65 struct acpi_table_header *header = &(rsdt->header); 66 67 /* Fill out header fields */ 68 acpi_fill_header(header, "RSDT"); 69 header->length = sizeof(struct acpi_rsdt); 70 header->revision = 1; 71 72 /* Entries are filled in later, we come with an empty set */ 73 74 /* Fix checksum */ 75 header->checksum = table_compute_checksum((void *)rsdt, 76 sizeof(struct acpi_rsdt)); 77 } 78 79 static void acpi_write_xsdt(struct acpi_xsdt *xsdt) 80 { 81 struct acpi_table_header *header = &(xsdt->header); 82 83 /* Fill out header fields */ 84 acpi_fill_header(header, "XSDT"); 85 header->length = sizeof(struct acpi_xsdt); 86 header->revision = 1; 87 88 /* Entries are filled in later, we come with an empty set */ 89 90 /* Fix checksum */ 91 header->checksum = table_compute_checksum((void *)xsdt, 92 sizeof(struct acpi_xsdt)); 93 } 94 95 /** 96 * Add an ACPI table to the RSDT (and XSDT) structure, recalculate length 97 * and checksum. 98 */ 99 static void acpi_add_table(struct acpi_rsdp *rsdp, void *table) 100 { 101 int i, entries_num; 102 struct acpi_rsdt *rsdt; 103 struct acpi_xsdt *xsdt = NULL; 104 105 /* The RSDT is mandatory while the XSDT is not */ 106 rsdt = (struct acpi_rsdt *)rsdp->rsdt_address; 107 108 if (rsdp->xsdt_address) 109 xsdt = (struct acpi_xsdt *)((u32)rsdp->xsdt_address); 110 111 /* This should always be MAX_ACPI_TABLES */ 112 entries_num = ARRAY_SIZE(rsdt->entry); 113 114 for (i = 0; i < entries_num; i++) { 115 if (rsdt->entry[i] == 0) 116 break; 117 } 118 119 if (i >= entries_num) { 120 debug("ACPI: Error: too many tables\n"); 121 return; 122 } 123 124 /* Add table to the RSDT */ 125 rsdt->entry[i] = (u32)table; 126 127 /* Fix RSDT length or the kernel will assume invalid entries */ 128 rsdt->header.length = sizeof(struct acpi_table_header) + 129 (sizeof(u32) * (i + 1)); 130 131 /* Re-calculate checksum */ 132 rsdt->header.checksum = 0; 133 rsdt->header.checksum = table_compute_checksum((u8 *)rsdt, 134 rsdt->header.length); 135 136 /* 137 * And now the same thing for the XSDT. We use the same index as for 138 * now we want the XSDT and RSDT to always be in sync in U-Boot 139 */ 140 if (xsdt) { 141 /* Add table to the XSDT */ 142 xsdt->entry[i] = (u64)(u32)table; 143 144 /* Fix XSDT length */ 145 xsdt->header.length = sizeof(struct acpi_table_header) + 146 (sizeof(u64) * (i + 1)); 147 148 /* Re-calculate checksum */ 149 xsdt->header.checksum = 0; 150 xsdt->header.checksum = table_compute_checksum((u8 *)xsdt, 151 xsdt->header.length); 152 } 153 } 154 155 static void acpi_create_facs(struct acpi_facs *facs) 156 { 157 memset((void *)facs, 0, sizeof(struct acpi_facs)); 158 159 memcpy(facs->signature, "FACS", 4); 160 facs->length = sizeof(struct acpi_facs); 161 facs->hardware_signature = 0; 162 facs->firmware_waking_vector = 0; 163 facs->global_lock = 0; 164 facs->flags = 0; 165 facs->x_firmware_waking_vector_l = 0; 166 facs->x_firmware_waking_vector_h = 0; 167 facs->version = 1; 168 } 169 170 static int acpi_create_madt_lapic(struct acpi_madt_lapic *lapic, 171 u8 cpu, u8 apic) 172 { 173 lapic->type = ACPI_APIC_LAPIC; 174 lapic->length = sizeof(struct acpi_madt_lapic); 175 lapic->flags = LOCAL_APIC_FLAG_ENABLED; 176 lapic->processor_id = cpu; 177 lapic->apic_id = apic; 178 179 return lapic->length; 180 } 181 182 int acpi_create_madt_lapics(u32 current) 183 { 184 struct udevice *dev; 185 int length = 0; 186 187 for (uclass_find_first_device(UCLASS_CPU, &dev); 188 dev; 189 uclass_find_next_device(&dev)) { 190 struct cpu_platdata *plat = dev_get_parent_platdata(dev); 191 192 length += acpi_create_madt_lapic( 193 (struct acpi_madt_lapic *)current, 194 plat->cpu_id, plat->cpu_id); 195 current += length; 196 } 197 198 return length; 199 } 200 201 int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id, 202 u32 addr, u32 gsi_base) 203 { 204 ioapic->type = ACPI_APIC_IOAPIC; 205 ioapic->length = sizeof(struct acpi_madt_ioapic); 206 ioapic->reserved = 0x00; 207 ioapic->gsi_base = gsi_base; 208 ioapic->ioapic_id = id; 209 ioapic->ioapic_addr = addr; 210 211 return ioapic->length; 212 } 213 214 int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride, 215 u8 bus, u8 source, u32 gsirq, u16 flags) 216 { 217 irqoverride->type = ACPI_APIC_IRQ_SRC_OVERRIDE; 218 irqoverride->length = sizeof(struct acpi_madt_irqoverride); 219 irqoverride->bus = bus; 220 irqoverride->source = source; 221 irqoverride->gsirq = gsirq; 222 irqoverride->flags = flags; 223 224 return irqoverride->length; 225 } 226 227 int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi, 228 u8 cpu, u16 flags, u8 lint) 229 { 230 lapic_nmi->type = ACPI_APIC_LAPIC_NMI; 231 lapic_nmi->length = sizeof(struct acpi_madt_lapic_nmi); 232 lapic_nmi->flags = flags; 233 lapic_nmi->processor_id = cpu; 234 lapic_nmi->lint = lint; 235 236 return lapic_nmi->length; 237 } 238 239 static void acpi_create_madt(struct acpi_madt *madt) 240 { 241 struct acpi_table_header *header = &(madt->header); 242 u32 current = (u32)madt + sizeof(struct acpi_madt); 243 244 memset((void *)madt, 0, sizeof(struct acpi_madt)); 245 246 /* Fill out header fields */ 247 acpi_fill_header(header, "APIC"); 248 header->length = sizeof(struct acpi_madt); 249 header->revision = 4; 250 251 madt->lapic_addr = LAPIC_DEFAULT_BASE; 252 madt->flags = ACPI_MADT_PCAT_COMPAT; 253 254 current = acpi_fill_madt(current); 255 256 /* (Re)calculate length and checksum */ 257 header->length = current - (u32)madt; 258 259 header->checksum = table_compute_checksum((void *)madt, header->length); 260 } 261 262 static int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, 263 u32 base, u16 seg_nr, u8 start, u8 end) 264 { 265 memset(mmconfig, 0, sizeof(*mmconfig)); 266 mmconfig->base_address_l = base; 267 mmconfig->base_address_h = 0; 268 mmconfig->pci_segment_group_number = seg_nr; 269 mmconfig->start_bus_number = start; 270 mmconfig->end_bus_number = end; 271 272 return sizeof(struct acpi_mcfg_mmconfig); 273 } 274 275 static u32 acpi_fill_mcfg(u32 current) 276 { 277 current += acpi_create_mcfg_mmconfig 278 ((struct acpi_mcfg_mmconfig *)current, 279 CONFIG_PCIE_ECAM_BASE, 0x0, 0x0, 255); 280 281 return current; 282 } 283 284 /* MCFG is defined in the PCI Firmware Specification 3.0 */ 285 static void acpi_create_mcfg(struct acpi_mcfg *mcfg) 286 { 287 struct acpi_table_header *header = &(mcfg->header); 288 u32 current = (u32)mcfg + sizeof(struct acpi_mcfg); 289 290 memset((void *)mcfg, 0, sizeof(struct acpi_mcfg)); 291 292 /* Fill out header fields */ 293 acpi_fill_header(header, "MCFG"); 294 header->length = sizeof(struct acpi_mcfg); 295 header->revision = 1; 296 297 current = acpi_fill_mcfg(current); 298 299 /* (Re)calculate length and checksum */ 300 header->length = current - (u32)mcfg; 301 header->checksum = table_compute_checksum((void *)mcfg, header->length); 302 } 303 304 /* 305 * QEMU's version of write_acpi_tables is defined in 306 * arch/x86/cpu/qemu/fw_cfg.c 307 */ 308 u32 write_acpi_tables(u32 start) 309 { 310 u32 current; 311 struct acpi_rsdp *rsdp; 312 struct acpi_rsdt *rsdt; 313 struct acpi_xsdt *xsdt; 314 struct acpi_facs *facs; 315 struct acpi_table_header *dsdt; 316 struct acpi_fadt *fadt; 317 struct acpi_mcfg *mcfg; 318 struct acpi_madt *madt; 319 320 current = start; 321 322 /* Align ACPI tables to 16 byte */ 323 current = ALIGN(current, 16); 324 325 debug("ACPI: Writing ACPI tables at %x\n", start); 326 327 /* We need at least an RSDP and an RSDT Table */ 328 rsdp = (struct acpi_rsdp *)current; 329 current += sizeof(struct acpi_rsdp); 330 current = ALIGN(current, 16); 331 rsdt = (struct acpi_rsdt *)current; 332 current += sizeof(struct acpi_rsdt); 333 current = ALIGN(current, 16); 334 xsdt = (struct acpi_xsdt *)current; 335 current += sizeof(struct acpi_xsdt); 336 /* 337 * Per ACPI spec, the FACS table address must be aligned to a 64 byte 338 * boundary (Windows checks this, but Linux does not). 339 */ 340 current = ALIGN(current, 64); 341 342 /* clear all table memory */ 343 memset((void *)start, 0, current - start); 344 345 acpi_write_rsdp(rsdp, rsdt, xsdt); 346 acpi_write_rsdt(rsdt); 347 acpi_write_xsdt(xsdt); 348 349 debug("ACPI: * FACS\n"); 350 facs = (struct acpi_facs *)current; 351 current += sizeof(struct acpi_facs); 352 current = ALIGN(current, 16); 353 354 acpi_create_facs(facs); 355 356 debug("ACPI: * DSDT\n"); 357 dsdt = (struct acpi_table_header *)current; 358 memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header)); 359 if (dsdt->length >= sizeof(struct acpi_table_header)) { 360 current += sizeof(struct acpi_table_header); 361 memcpy((char *)current, 362 (char *)&AmlCode + sizeof(struct acpi_table_header), 363 dsdt->length - sizeof(struct acpi_table_header)); 364 current += dsdt->length - sizeof(struct acpi_table_header); 365 366 /* (Re)calculate length and checksum */ 367 dsdt->length = current - (u32)dsdt; 368 dsdt->checksum = 0; 369 dsdt->checksum = table_compute_checksum((void *)dsdt, 370 dsdt->length); 371 } 372 current = ALIGN(current, 16); 373 374 debug("ACPI: * FADT\n"); 375 fadt = (struct acpi_fadt *)current; 376 current += sizeof(struct acpi_fadt); 377 current = ALIGN(current, 16); 378 acpi_create_fadt(fadt, facs, dsdt); 379 acpi_add_table(rsdp, fadt); 380 381 debug("ACPI: * MADT\n"); 382 madt = (struct acpi_madt *)current; 383 acpi_create_madt(madt); 384 if (madt->header.length > sizeof(struct acpi_madt)) { 385 current += madt->header.length; 386 acpi_add_table(rsdp, madt); 387 } 388 current = ALIGN(current, 16); 389 390 debug("ACPI: * MCFG\n"); 391 mcfg = (struct acpi_mcfg *)current; 392 acpi_create_mcfg(mcfg); 393 if (mcfg->header.length > sizeof(struct acpi_mcfg)) { 394 current += mcfg->header.length; 395 current = ALIGN(current, 16); 396 acpi_add_table(rsdp, mcfg); 397 } 398 399 debug("current = %x\n", current); 400 401 debug("ACPI: done\n"); 402 403 return current; 404 } 405