Attention is currently required from: Lance Zhao, Tim Wawrzynczak.
Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/75904?usp=email )
Change subject: UNTESTED acpi: Load DSDT directly into target location ......................................................................
UNTESTED acpi: Load DSDT directly into target location
Instead of first mapping DSDT and then copying it into the target location, load it straight away.
This changes DSDT injections to be appended to DSDT file instead of prepended. TOTEST: is this ok? Test on chromeos platform.
This makes compressing DSDT possible on platforms where cbfs_map only does return a pointer to a memory mapped medium.
TESTED work on Foxconn G41M.
Signed-off-by: Arthur Heymans arthur@aheymans.xyz Change-Id: I8f5e01da6ab33869c61801de1e7364bb680f44eb --- M src/acpi/acpi.c 1 file changed, 43 insertions(+), 48 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/04/75904/1
diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c index d8988ea..04f100f 100644 --- a/src/acpi/acpi.c +++ b/src/acpi/acpi.c @@ -1864,7 +1864,7 @@ acpi_facs_t *facs = NULL; acpi_header_t *slic_file, *slic = NULL; acpi_header_t *ssdt = NULL; - acpi_header_t *dsdt_file, *dsdt = NULL; + acpi_header_t *dsdt = NULL; acpi_mcfg_t *mcfg = NULL; acpi_tcpa_t *tcpa = NULL; acpi_tpm2_t *tpm2 = NULL; @@ -1873,7 +1873,7 @@ acpi_bert_t *bert = NULL; struct device *dev; unsigned long fw; - size_t slic_size, dsdt_size; + size_t slic_size; char oem_id[6], oem_table_id[8];
current = start; @@ -1928,20 +1928,6 @@ return fw; }
- dsdt_file = cbfs_map(CONFIG_CBFS_PREFIX "/dsdt.aml", &dsdt_size); - if (!dsdt_file) { - printk(BIOS_ERR, "No DSDT file, skipping ACPI tables\n"); - return start; - } - - if (dsdt_file->length > dsdt_size - || dsdt_file->length < sizeof(acpi_header_t) - || memcmp(dsdt_file->signature, "DSDT", 4) != 0) { - printk(BIOS_ERR, "Invalid DSDT file, skipping ACPI tables\n"); - cbfs_unmap(dsdt_file); - return start; - } - slic_file = cbfs_map(CONFIG_CBFS_PREFIX "/slic", &slic_size); if (slic_file && (slic_file->length > slic_size @@ -1990,33 +1976,50 @@
printk(BIOS_DEBUG, "ACPI: * DSDT\n"); dsdt = (acpi_header_t *)current; - memcpy(dsdt, dsdt_file, sizeof(acpi_header_t)); - if (dsdt->length >= sizeof(acpi_header_t)) { - current += sizeof(acpi_header_t);
- acpigen_set_current((char *)current); - - if (CONFIG(ACPI_SOC_NVS)) - acpi_fill_gnvs(); - if (CONFIG(CHROMEOS_NVS)) - acpi_fill_cnvs(); - - for (dev = all_devices; dev; dev = dev->next) - if (dev->ops && dev->ops->acpi_inject_dsdt) - dev->ops->acpi_inject_dsdt(dev); - current = (unsigned long)acpigen_get_current(); - memcpy((char *)current, - (char *)dsdt_file + sizeof(acpi_header_t), - dsdt->length - sizeof(acpi_header_t)); - current += dsdt->length - sizeof(acpi_header_t); - - /* (Re)calculate length and checksum. */ - dsdt->length = current - (unsigned long)dsdt; - dsdt->checksum = 0; - dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length); +#define DSDT_SIZE_LIM (256 * KiB) + if (cbfs_get_size(CONFIG_CBFS_PREFIX "/dsdt.aml") > DSDT_SIZE_LIM) { + printk(BIOS_ERR, "DSDT file too large, increase DSDT_SIZE_LIM, skipping ACPI tables\n"); + /* clear all table memory */ + memset((void *)start, 0, current - start); + return start; }
- current = acpi_align_current(current); + + const size_t dsdt_size = cbfs_load(CONFIG_CBFS_PREFIX "/dsdt.aml", dsdt, DSDT_SIZE_LIM); + if (dsdt_size == 0) { + printk(BIOS_ERR, "No DSDT file or unable to load, skipping ACPI tables\n"); + /* clear all table memory */ + memset((void *)start, 0, current - start); + return start; + } + + if (dsdt->length < sizeof(acpi_header_t) + || memcmp(dsdt->signature, "DSDT", 4) != 0) { + printk(BIOS_ERR, "Invalid DSDT file, skipping ACPI tables\n"); + /* clear all table memory */ + memset((void *)start, 0, current - start); + return start; + } + + current += dsdt->length; + + acpigen_set_current((char *)current); + + if (CONFIG(ACPI_SOC_NVS)) + acpi_fill_gnvs(); + if (CONFIG(CHROMEOS_NVS)) + acpi_fill_cnvs(); + + for (dev = all_devices; dev; dev = dev->next) + if (dev->ops && dev->ops->acpi_inject_dsdt) + dev->ops->acpi_inject_dsdt(dev); + + /* (Re)calculate length and checksum. */ + current = (unsigned long)acpigen_get_current(); + dsdt->length = current - (unsigned long)dsdt; + dsdt->checksum = 0; + dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length);
printk(BIOS_DEBUG, "ACPI: * FADT\n"); fadt = (acpi_fadt_t *)current; @@ -2036,14 +2039,6 @@ cbfs_unmap(slic_file); }
- /* - * cbfs_unmap() uses mem_pool_free() which works correctly only - * if freeing is done in reverse order than memory allocation. - * This is why unmapping of dsdt_file must be done after - * unmapping slic file. - */ - cbfs_unmap(dsdt_file); - printk(BIOS_DEBUG, "ACPI: * SSDT\n"); ssdt = (acpi_header_t *)current; acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR);