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/global_nvs.h> 15 #include <asm/acpi_table.h> 16 #include <asm/io.h> 17 #include <asm/lapic.h> 18 #include <asm/tables.h> 19 #include <asm/arch/global_nvs.h> 20 21 /* 22 * IASL compiles the dsdt entries and writes the hex values 23 * to a C array AmlCode[] (see dsdt.c). 24 */ 25 extern const unsigned char AmlCode[]; 26 27 static void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, 28 struct acpi_xsdt *xsdt) 29 { 30 memset(rsdp, 0, sizeof(struct acpi_rsdp)); 31 32 memcpy(rsdp->signature, RSDP_SIG, 8); 33 memcpy(rsdp->oem_id, OEM_ID, 6); 34 35 rsdp->length = sizeof(struct acpi_rsdp); 36 rsdp->rsdt_address = (u32)rsdt; 37 38 /* 39 * Revision: ACPI 1.0: 0, ACPI 2.0/3.0/4.0: 2 40 * 41 * Some OSes expect an XSDT to be present for RSD PTR revisions >= 2. 42 * If we don't have an ACPI XSDT, force ACPI 1.0 (and thus RSD PTR 43 * revision 0) 44 */ 45 if (xsdt == NULL) { 46 rsdp->revision = ACPI_RSDP_REV_ACPI_1_0; 47 } else { 48 rsdp->xsdt_address = (u64)(u32)xsdt; 49 rsdp->revision = ACPI_RSDP_REV_ACPI_2_0; 50 } 51 52 /* Calculate checksums */ 53 rsdp->checksum = table_compute_checksum((void *)rsdp, 20); 54 rsdp->ext_checksum = table_compute_checksum((void *)rsdp, 55 sizeof(struct acpi_rsdp)); 56 } 57 58 void acpi_fill_header(struct acpi_table_header *header, char *signature) 59 { 60 memcpy(header->signature, signature, 4); 61 memcpy(header->oem_id, OEM_ID, 6); 62 memcpy(header->oem_table_id, OEM_TABLE_ID, 8); 63 memcpy(header->aslc_id, ASLC_ID, 4); 64 } 65 66 static void acpi_write_rsdt(struct acpi_rsdt *rsdt) 67 { 68 struct acpi_table_header *header = &(rsdt->header); 69 70 /* Fill out header fields */ 71 acpi_fill_header(header, "RSDT"); 72 header->length = sizeof(struct acpi_rsdt); 73 header->revision = 1; 74 75 /* Entries are filled in later, we come with an empty set */ 76 77 /* Fix checksum */ 78 header->checksum = table_compute_checksum((void *)rsdt, 79 sizeof(struct acpi_rsdt)); 80 } 81 82 static void acpi_write_xsdt(struct acpi_xsdt *xsdt) 83 { 84 struct acpi_table_header *header = &(xsdt->header); 85 86 /* Fill out header fields */ 87 acpi_fill_header(header, "XSDT"); 88 header->length = sizeof(struct acpi_xsdt); 89 header->revision = 1; 90 91 /* Entries are filled in later, we come with an empty set */ 92 93 /* Fix checksum */ 94 header->checksum = table_compute_checksum((void *)xsdt, 95 sizeof(struct acpi_xsdt)); 96 } 97 98 /** 99 * Add an ACPI table to the RSDT (and XSDT) structure, recalculate length 100 * and checksum. 101 */ 102 static void acpi_add_table(struct acpi_rsdp *rsdp, void *table) 103 { 104 int i, entries_num; 105 struct acpi_rsdt *rsdt; 106 struct acpi_xsdt *xsdt = NULL; 107 108 /* The RSDT is mandatory while the XSDT is not */ 109 rsdt = (struct acpi_rsdt *)rsdp->rsdt_address; 110 111 if (rsdp->xsdt_address) 112 xsdt = (struct acpi_xsdt *)((u32)rsdp->xsdt_address); 113 114 /* This should always be MAX_ACPI_TABLES */ 115 entries_num = ARRAY_SIZE(rsdt->entry); 116 117 for (i = 0; i < entries_num; i++) { 118 if (rsdt->entry[i] == 0) 119 break; 120 } 121 122 if (i >= entries_num) { 123 debug("ACPI: Error: too many tables\n"); 124 return; 125 } 126 127 /* Add table to the RSDT */ 128 rsdt->entry[i] = (u32)table; 129 130 /* Fix RSDT length or the kernel will assume invalid entries */ 131 rsdt->header.length = sizeof(struct acpi_table_header) + 132 (sizeof(u32) * (i + 1)); 133 134 /* Re-calculate checksum */ 135 rsdt->header.checksum = 0; 136 rsdt->header.checksum = table_compute_checksum((u8 *)rsdt, 137 rsdt->header.length); 138 139 /* 140 * And now the same thing for the XSDT. We use the same index as for 141 * now we want the XSDT and RSDT to always be in sync in U-Boot 142 */ 143 if (xsdt) { 144 /* Add table to the XSDT */ 145 xsdt->entry[i] = (u64)(u32)table; 146 147 /* Fix XSDT length */ 148 xsdt->header.length = sizeof(struct acpi_table_header) + 149 (sizeof(u64) * (i + 1)); 150 151 /* Re-calculate checksum */ 152 xsdt->header.checksum = 0; 153 xsdt->header.checksum = table_compute_checksum((u8 *)xsdt, 154 xsdt->header.length); 155 } 156 } 157 158 static void acpi_create_facs(struct acpi_facs *facs) 159 { 160 memset((void *)facs, 0, sizeof(struct acpi_facs)); 161 162 memcpy(facs->signature, "FACS", 4); 163 facs->length = sizeof(struct acpi_facs); 164 facs->hardware_signature = 0; 165 facs->firmware_waking_vector = 0; 166 facs->global_lock = 0; 167 facs->flags = 0; 168 facs->x_firmware_waking_vector_l = 0; 169 facs->x_firmware_waking_vector_h = 0; 170 facs->version = 1; 171 } 172 173 static int acpi_create_madt_lapic(struct acpi_madt_lapic *lapic, 174 u8 cpu, u8 apic) 175 { 176 lapic->type = ACPI_APIC_LAPIC; 177 lapic->length = sizeof(struct acpi_madt_lapic); 178 lapic->flags = LOCAL_APIC_FLAG_ENABLED; 179 lapic->processor_id = cpu; 180 lapic->apic_id = apic; 181 182 return lapic->length; 183 } 184 185 int acpi_create_madt_lapics(u32 current) 186 { 187 struct udevice *dev; 188 int total_length = 0; 189 190 for (uclass_find_first_device(UCLASS_CPU, &dev); 191 dev; 192 uclass_find_next_device(&dev)) { 193 struct cpu_platdata *plat = dev_get_parent_platdata(dev); 194 int length = acpi_create_madt_lapic( 195 (struct acpi_madt_lapic *)current, 196 plat->cpu_id, plat->cpu_id); 197 current += length; 198 total_length += length; 199 } 200 201 return total_length; 202 } 203 204 int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id, 205 u32 addr, u32 gsi_base) 206 { 207 ioapic->type = ACPI_APIC_IOAPIC; 208 ioapic->length = sizeof(struct acpi_madt_ioapic); 209 ioapic->reserved = 0x00; 210 ioapic->gsi_base = gsi_base; 211 ioapic->ioapic_id = id; 212 ioapic->ioapic_addr = addr; 213 214 return ioapic->length; 215 } 216 217 int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride, 218 u8 bus, u8 source, u32 gsirq, u16 flags) 219 { 220 irqoverride->type = ACPI_APIC_IRQ_SRC_OVERRIDE; 221 irqoverride->length = sizeof(struct acpi_madt_irqoverride); 222 irqoverride->bus = bus; 223 irqoverride->source = source; 224 irqoverride->gsirq = gsirq; 225 irqoverride->flags = flags; 226 227 return irqoverride->length; 228 } 229 230 int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi, 231 u8 cpu, u16 flags, u8 lint) 232 { 233 lapic_nmi->type = ACPI_APIC_LAPIC_NMI; 234 lapic_nmi->length = sizeof(struct acpi_madt_lapic_nmi); 235 lapic_nmi->flags = flags; 236 lapic_nmi->processor_id = cpu; 237 lapic_nmi->lint = lint; 238 239 return lapic_nmi->length; 240 } 241 242 static void acpi_create_madt(struct acpi_madt *madt) 243 { 244 struct acpi_table_header *header = &(madt->header); 245 u32 current = (u32)madt + sizeof(struct acpi_madt); 246 247 memset((void *)madt, 0, sizeof(struct acpi_madt)); 248 249 /* Fill out header fields */ 250 acpi_fill_header(header, "APIC"); 251 header->length = sizeof(struct acpi_madt); 252 header->revision = 4; 253 254 madt->lapic_addr = LAPIC_DEFAULT_BASE; 255 madt->flags = ACPI_MADT_PCAT_COMPAT; 256 257 current = acpi_fill_madt(current); 258 259 /* (Re)calculate length and checksum */ 260 header->length = current - (u32)madt; 261 262 header->checksum = table_compute_checksum((void *)madt, header->length); 263 } 264 265 static int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, 266 u32 base, u16 seg_nr, u8 start, u8 end) 267 { 268 memset(mmconfig, 0, sizeof(*mmconfig)); 269 mmconfig->base_address_l = base; 270 mmconfig->base_address_h = 0; 271 mmconfig->pci_segment_group_number = seg_nr; 272 mmconfig->start_bus_number = start; 273 mmconfig->end_bus_number = end; 274 275 return sizeof(struct acpi_mcfg_mmconfig); 276 } 277 278 static u32 acpi_fill_mcfg(u32 current) 279 { 280 current += acpi_create_mcfg_mmconfig 281 ((struct acpi_mcfg_mmconfig *)current, 282 CONFIG_PCIE_ECAM_BASE, 0x0, 0x0, 255); 283 284 return current; 285 } 286 287 /* MCFG is defined in the PCI Firmware Specification 3.0 */ 288 static void acpi_create_mcfg(struct acpi_mcfg *mcfg) 289 { 290 struct acpi_table_header *header = &(mcfg->header); 291 u32 current = (u32)mcfg + sizeof(struct acpi_mcfg); 292 293 memset((void *)mcfg, 0, sizeof(struct acpi_mcfg)); 294 295 /* Fill out header fields */ 296 acpi_fill_header(header, "MCFG"); 297 header->length = sizeof(struct acpi_mcfg); 298 header->revision = 1; 299 300 current = acpi_fill_mcfg(current); 301 302 /* (Re)calculate length and checksum */ 303 header->length = current - (u32)mcfg; 304 header->checksum = table_compute_checksum((void *)mcfg, header->length); 305 } 306 307 void enter_acpi_mode(int pm1_cnt) 308 { 309 u16 val = inw(pm1_cnt); 310 311 /* 312 * PM1_CNT register bit0 selects the power management event to be 313 * either an SCI or SMI interrupt. When this bit is set, then power 314 * management events will generate an SCI interrupt. When this bit 315 * is reset power management events will generate an SMI interrupt. 316 * 317 * Per ACPI spec, it is the responsibility of the hardware to set 318 * or reset this bit. OSPM always preserves this bit position. 319 * 320 * U-Boot does not support SMI. And we don't have plan to support 321 * anything running in SMM within U-Boot. To create a legacy-free 322 * system, and expose ourselves to OSPM as working under ACPI mode 323 * already, turn this bit on. 324 */ 325 outw(val | PM1_CNT_SCI_EN, pm1_cnt); 326 } 327 328 /* 329 * QEMU's version of write_acpi_tables is defined in 330 * arch/x86/cpu/qemu/acpi_table.c 331 */ 332 ulong write_acpi_tables(ulong start) 333 { 334 u32 current; 335 struct acpi_rsdp *rsdp; 336 struct acpi_rsdt *rsdt; 337 struct acpi_xsdt *xsdt; 338 struct acpi_facs *facs; 339 struct acpi_table_header *dsdt; 340 struct acpi_fadt *fadt; 341 struct acpi_mcfg *mcfg; 342 struct acpi_madt *madt; 343 int i; 344 345 current = start; 346 347 /* Align ACPI tables to 16 byte */ 348 current = ALIGN(current, 16); 349 350 debug("ACPI: Writing ACPI tables at %lx\n", start); 351 352 /* We need at least an RSDP and an RSDT Table */ 353 rsdp = (struct acpi_rsdp *)current; 354 current += sizeof(struct acpi_rsdp); 355 current = ALIGN(current, 16); 356 rsdt = (struct acpi_rsdt *)current; 357 current += sizeof(struct acpi_rsdt); 358 current = ALIGN(current, 16); 359 xsdt = (struct acpi_xsdt *)current; 360 current += sizeof(struct acpi_xsdt); 361 /* 362 * Per ACPI spec, the FACS table address must be aligned to a 64 byte 363 * boundary (Windows checks this, but Linux does not). 364 */ 365 current = ALIGN(current, 64); 366 367 /* clear all table memory */ 368 memset((void *)start, 0, current - start); 369 370 acpi_write_rsdp(rsdp, rsdt, xsdt); 371 acpi_write_rsdt(rsdt); 372 acpi_write_xsdt(xsdt); 373 374 debug("ACPI: * FACS\n"); 375 facs = (struct acpi_facs *)current; 376 current += sizeof(struct acpi_facs); 377 current = ALIGN(current, 16); 378 379 acpi_create_facs(facs); 380 381 debug("ACPI: * DSDT\n"); 382 dsdt = (struct acpi_table_header *)current; 383 memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header)); 384 current += sizeof(struct acpi_table_header); 385 memcpy((char *)current, 386 (char *)&AmlCode + sizeof(struct acpi_table_header), 387 dsdt->length - sizeof(struct acpi_table_header)); 388 current += dsdt->length - sizeof(struct acpi_table_header); 389 current = ALIGN(current, 16); 390 391 /* Pack GNVS into the ACPI table area */ 392 for (i = 0; i < dsdt->length; i++) { 393 u32 *gnvs = (u32 *)((u32)dsdt + i); 394 if (*gnvs == ACPI_GNVS_ADDR) { 395 debug("Fix up global NVS in DSDT to 0x%08x\n", current); 396 *gnvs = current; 397 break; 398 } 399 } 400 401 /* Update DSDT checksum since we patched the GNVS address */ 402 dsdt->checksum = 0; 403 dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length); 404 405 /* Fill in platform-specific global NVS variables */ 406 acpi_create_gnvs((struct acpi_global_nvs *)current); 407 current += sizeof(struct acpi_global_nvs); 408 current = ALIGN(current, 16); 409 410 debug("ACPI: * FADT\n"); 411 fadt = (struct acpi_fadt *)current; 412 current += sizeof(struct acpi_fadt); 413 current = ALIGN(current, 16); 414 acpi_create_fadt(fadt, facs, dsdt); 415 acpi_add_table(rsdp, fadt); 416 417 debug("ACPI: * MADT\n"); 418 madt = (struct acpi_madt *)current; 419 acpi_create_madt(madt); 420 current += madt->header.length; 421 acpi_add_table(rsdp, madt); 422 current = ALIGN(current, 16); 423 424 debug("ACPI: * MCFG\n"); 425 mcfg = (struct acpi_mcfg *)current; 426 acpi_create_mcfg(mcfg); 427 current += mcfg->header.length; 428 acpi_add_table(rsdp, mcfg); 429 current = ALIGN(current, 16); 430 431 debug("current = %x\n", current); 432 433 debug("ACPI: done\n"); 434 435 /* 436 * Other than waiting for OSPM to request us to switch to ACPI mode, 437 * do it by ourselves, since SMI will not be triggered. 438 */ 439 enter_acpi_mode(fadt->pm1a_cnt_blk); 440 441 return current; 442 } 443 444 static struct acpi_rsdp *acpi_valid_rsdp(struct acpi_rsdp *rsdp) 445 { 446 if (strncmp((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) 447 return NULL; 448 449 debug("Looking on %p for valid checksum\n", rsdp); 450 451 if (table_compute_checksum((void *)rsdp, 20) != 0) 452 return NULL; 453 debug("acpi rsdp checksum 1 passed\n"); 454 455 if ((rsdp->revision > 1) && 456 (table_compute_checksum((void *)rsdp, rsdp->length) != 0)) 457 return NULL; 458 debug("acpi rsdp checksum 2 passed\n"); 459 460 return rsdp; 461 } 462 463 struct acpi_fadt *acpi_find_fadt(void) 464 { 465 char *p, *end; 466 struct acpi_rsdp *rsdp = NULL; 467 struct acpi_rsdt *rsdt; 468 struct acpi_fadt *fadt = NULL; 469 int i; 470 471 /* Find RSDP */ 472 for (p = (char *)ROM_TABLE_ADDR; p < (char *)ROM_TABLE_END; p += 16) { 473 rsdp = acpi_valid_rsdp((struct acpi_rsdp *)p); 474 if (rsdp) 475 break; 476 } 477 478 if (rsdp == NULL) 479 return NULL; 480 481 debug("RSDP found at %p\n", rsdp); 482 rsdt = (struct acpi_rsdt *)rsdp->rsdt_address; 483 484 end = (char *)rsdt + rsdt->header.length; 485 debug("RSDT found at %p ends at %p\n", rsdt, end); 486 487 for (i = 0; ((char *)&rsdt->entry[i]) < end; i++) { 488 fadt = (struct acpi_fadt *)rsdt->entry[i]; 489 if (strncmp((char *)fadt, "FACP", 4) == 0) 490 break; 491 fadt = NULL; 492 } 493 494 if (fadt == NULL) 495 return NULL; 496 497 debug("FADT found at %p\n", fadt); 498 return fadt; 499 } 500 501 void *acpi_find_wakeup_vector(struct acpi_fadt *fadt) 502 { 503 struct acpi_facs *facs; 504 void *wake_vec; 505 506 debug("Trying to find the wakeup vector...\n"); 507 508 facs = (struct acpi_facs *)fadt->firmware_ctrl; 509 510 if (facs == NULL) { 511 debug("No FACS found, wake up from S3 not possible.\n"); 512 return NULL; 513 } 514 515 debug("FACS found at %p\n", facs); 516 wake_vec = (void *)facs->firmware_waking_vector; 517 debug("OS waking vector is %p\n", wake_vec); 518 519 return wake_vec; 520 } 521