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