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 static void enter_acpi_mode(int pm1_cnt) 308 { 309 /* 310 * PM1_CNT register bit0 selects the power management event to be 311 * either an SCI or SMI interrupt. When this bit is set, then power 312 * management events will generate an SCI interrupt. When this bit 313 * is reset power management events will generate an SMI interrupt. 314 * 315 * Per ACPI spec, it is the responsibility of the hardware to set 316 * or reset this bit. OSPM always preserves this bit position. 317 * 318 * U-Boot does not support SMI. And we don't have plan to support 319 * anything running in SMM within U-Boot. To create a legacy-free 320 * system, and expose ourselves to OSPM as working under ACPI mode 321 * already, turn this bit on. 322 */ 323 outw(PM1_CNT_SCI_EN, pm1_cnt); 324 } 325 326 /* 327 * QEMU's version of write_acpi_tables is defined in 328 * arch/x86/cpu/qemu/acpi_table.c 329 */ 330 ulong write_acpi_tables(ulong start) 331 { 332 u32 current; 333 struct acpi_rsdp *rsdp; 334 struct acpi_rsdt *rsdt; 335 struct acpi_xsdt *xsdt; 336 struct acpi_facs *facs; 337 struct acpi_table_header *dsdt; 338 struct acpi_fadt *fadt; 339 struct acpi_mcfg *mcfg; 340 struct acpi_madt *madt; 341 int i; 342 343 current = start; 344 345 /* Align ACPI tables to 16 byte */ 346 current = ALIGN(current, 16); 347 348 debug("ACPI: Writing ACPI tables at %lx\n", start); 349 350 /* We need at least an RSDP and an RSDT Table */ 351 rsdp = (struct acpi_rsdp *)current; 352 current += sizeof(struct acpi_rsdp); 353 current = ALIGN(current, 16); 354 rsdt = (struct acpi_rsdt *)current; 355 current += sizeof(struct acpi_rsdt); 356 current = ALIGN(current, 16); 357 xsdt = (struct acpi_xsdt *)current; 358 current += sizeof(struct acpi_xsdt); 359 /* 360 * Per ACPI spec, the FACS table address must be aligned to a 64 byte 361 * boundary (Windows checks this, but Linux does not). 362 */ 363 current = ALIGN(current, 64); 364 365 /* clear all table memory */ 366 memset((void *)start, 0, current - start); 367 368 acpi_write_rsdp(rsdp, rsdt, xsdt); 369 acpi_write_rsdt(rsdt); 370 acpi_write_xsdt(xsdt); 371 372 debug("ACPI: * FACS\n"); 373 facs = (struct acpi_facs *)current; 374 current += sizeof(struct acpi_facs); 375 current = ALIGN(current, 16); 376 377 acpi_create_facs(facs); 378 379 debug("ACPI: * DSDT\n"); 380 dsdt = (struct acpi_table_header *)current; 381 memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header)); 382 current += sizeof(struct acpi_table_header); 383 memcpy((char *)current, 384 (char *)&AmlCode + sizeof(struct acpi_table_header), 385 dsdt->length - sizeof(struct acpi_table_header)); 386 current += dsdt->length - sizeof(struct acpi_table_header); 387 current = ALIGN(current, 16); 388 389 /* Pack GNVS into the ACPI table area */ 390 for (i = 0; i < dsdt->length; i++) { 391 u32 *gnvs = (u32 *)((u32)dsdt + i); 392 if (*gnvs == ACPI_GNVS_ADDR) { 393 debug("Fix up global NVS in DSDT to 0x%08x\n", current); 394 *gnvs = current; 395 break; 396 } 397 } 398 399 /* Update DSDT checksum since we patched the GNVS address */ 400 dsdt->checksum = 0; 401 dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length); 402 403 /* Fill in platform-specific global NVS variables */ 404 acpi_create_gnvs((struct acpi_global_nvs *)current); 405 current += sizeof(struct acpi_global_nvs); 406 current = ALIGN(current, 16); 407 408 debug("ACPI: * FADT\n"); 409 fadt = (struct acpi_fadt *)current; 410 current += sizeof(struct acpi_fadt); 411 current = ALIGN(current, 16); 412 acpi_create_fadt(fadt, facs, dsdt); 413 acpi_add_table(rsdp, fadt); 414 415 debug("ACPI: * MADT\n"); 416 madt = (struct acpi_madt *)current; 417 acpi_create_madt(madt); 418 current += madt->header.length; 419 acpi_add_table(rsdp, madt); 420 current = ALIGN(current, 16); 421 422 debug("ACPI: * MCFG\n"); 423 mcfg = (struct acpi_mcfg *)current; 424 acpi_create_mcfg(mcfg); 425 current += mcfg->header.length; 426 acpi_add_table(rsdp, mcfg); 427 current = ALIGN(current, 16); 428 429 debug("current = %x\n", current); 430 431 debug("ACPI: done\n"); 432 433 /* 434 * Other than waiting for OSPM to request us to switch to ACPI mode, 435 * do it by ourselves, since SMI will not be triggered. 436 */ 437 enter_acpi_mode(fadt->pm1a_cnt_blk); 438 439 return current; 440 } 441