diff options
author | Arthur Heymans <arthur@aheymans.xyz> | 2023-06-27 11:58:04 +0200 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2023-07-03 22:03:06 +0000 |
commit | 01af0f8ac80384d23abc99860f2c5d605a1aa540 (patch) | |
tree | a65a2751b0953586af21999962f0e643536ff7f0 /src | |
parent | 5b9957be0a7014dbcf14b6fe42f1273c763c3768 (diff) |
acpi/acpi.c: Reduce boilerplate
Adding tables to R/XSDT, aligning current pointer, computing checksum is
a lot of boilerplate that needs to be done for each table.
TESTED on foxconn/g41.
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Change-Id: If4915b8cdfcfdbb34284ea75fa8a0fd23554152d
Reviewed-on: https://review.coreboot.org/c/coreboot/+/76127
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/acpi/acpi.c | 319 |
1 files changed, 118 insertions, 201 deletions
diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c index 267a989573..36556afe5c 100644 --- a/src/acpi/acpi.c +++ b/src/acpi/acpi.c @@ -338,13 +338,11 @@ static unsigned long acpi_create_madt_lapics_with_nmis(unsigned long current) return current; } -static void acpi_create_madt(acpi_madt_t *madt) +static void acpi_create_madt(acpi_header_t *header, void *unused) { - acpi_header_t *header = &(madt->header); + acpi_madt_t *madt = (acpi_madt_t *)header; unsigned long current = (unsigned long)madt + sizeof(acpi_madt_t); - memset((void *)madt, 0, sizeof(acpi_madt_t)); - if (!header) return; @@ -371,10 +369,8 @@ static void acpi_create_madt(acpi_madt_t *madt) if (CONFIG(ACPI_CUSTOM_MADT)) current = acpi_fill_madt(current); - /* (Re)calculate length and checksum. */ + /* (Re)calculate length . */ header->length = current - (unsigned long)madt; - - header->checksum = acpi_checksum((void *)madt, header->length); } static unsigned long acpi_fill_mcfg(unsigned long current) @@ -386,13 +382,11 @@ static unsigned long acpi_fill_mcfg(unsigned long current) } /* MCFG is defined in the PCI Firmware Specification 3.0. */ -static void acpi_create_mcfg(acpi_mcfg_t *mcfg) +static void acpi_create_mcfg(acpi_header_t *header, void *unused) { - acpi_header_t *header = &(mcfg->header); + acpi_mcfg_t *mcfg = (acpi_mcfg_t *)header; unsigned long current = (unsigned long)mcfg + sizeof(acpi_mcfg_t); - memset((void *)mcfg, 0, sizeof(acpi_mcfg_t)); - if (!header) return; @@ -409,9 +403,8 @@ static void acpi_create_mcfg(acpi_mcfg_t *mcfg) if (CONFIG(ECAM_MMCONF_SUPPORT)) current = acpi_fill_mcfg(current); - /* (Re)calculate length and checksum. */ + /* (Re)calculate length */ header->length = current - (unsigned long)mcfg; - header->checksum = acpi_checksum((void *)mcfg, header->length); } static void *get_tcpa_log(u32 *size) @@ -439,14 +432,15 @@ static void *get_tcpa_log(u32 *size) return lasa; } -static void acpi_create_tcpa(acpi_tcpa_t *tcpa) +static void acpi_create_tcpa(acpi_header_t *header, void *unused) { - acpi_header_t *header = &(tcpa->header); + if (!CONFIG(TPM1)) + return; + + acpi_tcpa_t *tcpa = (acpi_tcpa_t *)header; u32 tcpa_log_len; void *lasa; - memset((void *)tcpa, 0, sizeof(acpi_tcpa_t)); - lasa = get_tcpa_log(&tcpa_log_len); if (!lasa) return; @@ -467,9 +461,6 @@ static void acpi_create_tcpa(acpi_tcpa_t *tcpa) tcpa->platform_class = 0; tcpa->laml = tcpa_log_len; tcpa->lasa = (uintptr_t)lasa; - - /* Calculate checksum. */ - header->checksum = acpi_checksum((void *)tcpa, header->length); } static void *get_tpm2_log(u32 *size) @@ -497,14 +488,15 @@ static void *get_tpm2_log(u32 *size) return lasa; } -static void acpi_create_tpm2(acpi_tpm2_t *tpm2) +static void acpi_create_tpm2(acpi_header_t *header, void *unused) { - acpi_header_t *header = &(tpm2->header); + if (!CONFIG(TPM2)) + return; + + acpi_tpm2_t *tpm2 = (acpi_tpm2_t *)header; u32 tpm2_log_len; void *lasa; - memset((void *)tpm2, 0, sizeof(acpi_tpm2_t)); - /* * Some payloads like SeaBIOS depend on log area to use TPM2. * Get the memory size and address of TPM2 log area or initialize it. @@ -542,9 +534,6 @@ static void acpi_create_tpm2(acpi_tpm2_t *tpm2) /* Fill the log area size and start address fields. */ tpm2->laml = tpm2_log_len; tpm2->lasa = (uintptr_t)lasa; - - /* Calculate checksum. */ - header->checksum = acpi_checksum((void *)tpm2, header->length); } static void acpi_ssdt_write_cbtable(void) @@ -570,7 +559,7 @@ static void acpi_ssdt_write_cbtable(void) acpigen_pop_len(); } -static void acpi_create_ssdt_generator(acpi_header_t *ssdt, const char *oem_table_id) +static void acpi_create_ssdt_generator(acpi_header_t *ssdt, void *unused) { unsigned long current = (unsigned long)ssdt + sizeof(acpi_header_t); @@ -579,7 +568,7 @@ static void acpi_create_ssdt_generator(acpi_header_t *ssdt, const char *oem_tabl memcpy(&ssdt->signature, "SSDT", 4); ssdt->revision = get_acpi_table_revision(SSDT); memcpy(&ssdt->oem_id, OEM_ID, 6); - memcpy(&ssdt->oem_table_id, oem_table_id, 8); + memcpy(&ssdt->oem_table_id, ACPI_TABLE_CREATOR, 8); ssdt->oem_revision = 42; memcpy(&ssdt->asl_compiler_id, ASLC, 4); ssdt->asl_compiler_revision = asl_revision; @@ -600,7 +589,6 @@ static void acpi_create_ssdt_generator(acpi_header_t *ssdt, const char *oem_tabl /* (Re)calculate length and checksum. */ ssdt->length = current - (unsigned long)ssdt; - ssdt->checksum = acpi_checksum((void *)ssdt, ssdt->length); } int acpi_create_srat_lapic(acpi_srat_lapic_t *lapic, u8 node, u8 apic) @@ -1504,9 +1492,9 @@ unsigned long acpi_write_dbg2_pci_uart(acpi_rsdp_t *rsdp, unsigned long current, return current; } -static void acpi_create_facs(acpi_facs_t *facs) +static void acpi_create_facs(void *header) { - memset((void *)facs, 0, sizeof(acpi_facs_t)); + acpi_facs_t *facs = header; memcpy(facs->signature, "FACS", 4); facs->length = sizeof(acpi_facs_t); @@ -1681,15 +1669,21 @@ void acpi_write_hest(acpi_hest_t *hest, } /* ACPI 3.0b */ -static void acpi_write_bert(acpi_bert_t *bert, uintptr_t region, size_t length) +static void acpi_create_bert(acpi_header_t *header, void *unused) { - acpi_header_t *header = &(bert->header); + if (!CONFIG(ACPI_BERT)) + return; - memset(bert, 0, sizeof(acpi_bert_t)); + acpi_bert_t *bert = (acpi_bert_t *)header; if (!header) return; + void *region; + size_t size; + if (acpi_soc_get_bert_region(®ion, &size) != CB_SUCCESS) + return; + memcpy(header->signature, "BERT", 4); memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); @@ -1698,22 +1692,19 @@ static void acpi_write_bert(acpi_bert_t *bert, uintptr_t region, size_t length) header->length += sizeof(acpi_bert_t); header->revision = get_acpi_table_revision(BERT); - bert->error_region = region; - bert->region_length = length; - - /* Calculate checksums. */ - header->checksum = acpi_checksum((void *)bert, header->length); + bert->error_region = (uintptr_t)region; + bert->region_length = (size_t)size; } __weak void arch_fill_fadt(acpi_fadt_t *fadt) { } __weak void soc_fill_fadt(acpi_fadt_t *fadt) { } __weak void mainboard_fill_fadt(acpi_fadt_t *fadt) { } -static void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt) +static acpi_header_t *dsdt; +static void acpi_create_fadt(acpi_header_t *header, void *arg1) { - acpi_header_t *header = &(fadt->header); - - memset((void *)fadt, 0, sizeof(acpi_fadt_t)); + acpi_fadt_t *fadt = (acpi_fadt_t *)header; + acpi_facs_t *facs = (acpi_facs_t *)(*(acpi_facs_t **)arg1); if (!header) return; @@ -1756,17 +1747,15 @@ static void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt) soc_fill_fadt(fadt); mainboard_fill_fadt(fadt); - - header->checksum = - acpi_checksum((void *)fadt, header->length); } -static void acpi_create_lpit(acpi_lpit_t *lpit) +static void acpi_create_lpit(acpi_header_t *header, void *unused) { - acpi_header_t *header = &(lpit->header); - unsigned long current = (unsigned long)lpit + sizeof(acpi_lpit_t); + if (!CONFIG(ACPI_LPIT)) + return; - memset((void *)lpit, 0, sizeof(acpi_lpit_t)); + acpi_lpit_t *lpit = (acpi_lpit_t *)header; + unsigned long current = (unsigned long)lpit + sizeof(acpi_lpit_t); if (!header) return; @@ -1784,9 +1773,8 @@ static void acpi_create_lpit(acpi_lpit_t *lpit) current = acpi_fill_lpit(current); - /* (Re)calculate length and checksum. */ + /* (Re)calculate length. */ header->length = current - (unsigned long)lpit; - header->checksum = acpi_checksum((void *)lpit, header->length); } unsigned long acpi_create_lpi_desc_ncst(acpi_lpi_desc_ncst_t *lpi_desc, uint16_t uid) @@ -1811,14 +1799,11 @@ static uint8_t acpi_spcr_type(void) return 0xff; } -static void acpi_create_spcr(acpi_spcr_t *spcr) +static void acpi_create_spcr(acpi_header_t *header, void *unused) { - acpi_header_t *header = &(spcr->header); + acpi_spcr_t *spcr = (acpi_spcr_t *)header; struct lb_serial serial; - /* The caller checks the header size, so call this first */ - memset((void *)spcr, 0, sizeof(acpi_spcr_t)); - if (!CONFIG(CONSOLE_SERIAL)) return; @@ -1886,6 +1871,46 @@ void preload_acpi_dsdt(void) cbfs_preload(file); } +static void acpi_create_dsdt(acpi_header_t *header, void *dsdt_file_arg) +{ + dsdt = header; + acpi_header_t *dsdt_file = *(acpi_header_t **)dsdt_file_arg; + unsigned long current = (unsigned long)header; + + 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 (const struct device *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. */ + dsdt->length = current - (unsigned long)dsdt; + } +} + +static void acpi_create_slic(acpi_header_t *header, void *slic_file_arg) +{ + acpi_header_t *slic_file = *(acpi_header_t **)slic_file_arg; + acpi_header_t *slic = header; + if (slic_file) + memcpy(slic, slic_file, slic_file->length); +} + static uintptr_t coreboot_rsdp; uintptr_t get_coreboot_rsdp(void) @@ -1931,22 +1956,33 @@ unsigned long write_acpi_tables(const unsigned long start) acpi_rsdp_t *rsdp; acpi_rsdt_t *rsdt = NULL; acpi_xsdt_t *xsdt = NULL; - acpi_fadt_t *fadt = NULL; acpi_facs_t *facs = NULL; - acpi_header_t *slic_file, *slic = NULL; + acpi_header_t *slic_file; acpi_header_t *ssdt = NULL; - acpi_header_t *dsdt_file, *dsdt = NULL; - acpi_mcfg_t *mcfg = NULL; - acpi_tcpa_t *tcpa = NULL; - acpi_tpm2_t *tpm2 = NULL; - acpi_madt_t *madt = NULL; - acpi_lpit_t *lpit = NULL; - acpi_bert_t *bert = NULL; + acpi_header_t *dsdt_file; struct device *dev; unsigned long fw; size_t slic_size, dsdt_size; char oem_id[6], oem_table_id[8]; + const struct acpi_table_generator { + void (*create_table)(acpi_header_t *table, void *arg); + void *args; + size_t min_size; + } tables[] = { + { acpi_create_dsdt, &dsdt_file, sizeof(acpi_header_t) }, + { acpi_create_fadt, &facs, sizeof(acpi_fadt_t) }, + { acpi_create_slic, &slic_file, sizeof(acpi_header_t) }, + { acpi_create_ssdt_generator, NULL, sizeof(acpi_header_t) }, + { acpi_create_mcfg, NULL, sizeof(acpi_mcfg_t) }, + { acpi_create_tcpa, NULL, sizeof(acpi_tcpa_t) }, + { acpi_create_tpm2, NULL, sizeof(acpi_tpm2_t) }, + { acpi_create_lpit, NULL, sizeof(acpi_lpit_t) }, + { acpi_create_madt, NULL, sizeof(acpi_header_t) }, + { acpi_create_bert, NULL, sizeof(acpi_bert_t) }, + { acpi_create_spcr, NULL, sizeof(acpi_spcr_t) }, + }; + current = start; /* Align ACPI tables to 16byte */ @@ -1992,7 +2028,7 @@ unsigned long write_acpi_tables(const unsigned long start) ssdt->length = current - (unsigned long)ssdt; ssdt->checksum = acpi_checksum((void *)ssdt, ssdt->length); - acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR); + acpi_create_ssdt_generator(ssdt, NULL); acpi_add_table(rsdp, ssdt); @@ -2052,59 +2088,26 @@ unsigned long write_acpi_tables(const unsigned long start) acpi_write_rsdt(rsdt, oem_id, oem_table_id); acpi_write_xsdt(xsdt, oem_id, oem_table_id); - printk(BIOS_DEBUG, "ACPI: * FACS\n"); current = ALIGN_UP(current, 64); + + printk(BIOS_DEBUG, "ACPI: * FACS\n"); facs = (acpi_facs_t *)current; current += sizeof(acpi_facs_t); current = acpi_align_current(current); acpi_create_facs(facs); - 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); - } - - current = acpi_align_current(current); - - printk(BIOS_DEBUG, "ACPI: * FADT\n"); - fadt = (acpi_fadt_t *)current; - current += sizeof(acpi_fadt_t); - current = acpi_align_current(current); - - acpi_create_fadt(fadt, facs, dsdt); - acpi_add_table(rsdp, fadt); - - if (slic_file) { - printk(BIOS_DEBUG, "ACPI: * SLIC\n"); - slic = (acpi_header_t *)current; - memcpy(slic, slic_file, slic_file->length); - current += slic_file->length; + for (size_t i = 0; i < ARRAY_SIZE(tables); i++) { + acpi_header_t *header = (acpi_header_t *)current; + memset(header, 0, tables[i].min_size); + tables[i].create_table(header, tables[i].args); + if (header->length < tables[i].min_size) + continue; + header->checksum = 0; + header->checksum = acpi_checksum((void *)header, header->length); + current += header->length; current = acpi_align_current(current); - acpi_add_table(rsdp, slic); - cbfs_unmap(slic_file); + printk(BIOS_DEBUG, "ACPI: * %.4s\n", header->signature); + acpi_add_table(rsdp, header); } /* @@ -2113,95 +2116,9 @@ unsigned long write_acpi_tables(const unsigned long start) * This is why unmapping of dsdt_file must be done after * unmapping slic file. */ + cbfs_unmap(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); - if (ssdt->length > sizeof(acpi_header_t)) { - current += ssdt->length; - acpi_add_table(rsdp, ssdt); - current = acpi_align_current(current); - } - - printk(BIOS_DEBUG, "ACPI: * MCFG\n"); - mcfg = (acpi_mcfg_t *)current; - acpi_create_mcfg(mcfg); - if (mcfg->header.length > sizeof(acpi_mcfg_t)) { - current += mcfg->header.length; - current = acpi_align_current(current); - acpi_add_table(rsdp, mcfg); - } - - if (CONFIG(TPM1)) { - printk(BIOS_DEBUG, "ACPI: * TCPA\n"); - tcpa = (acpi_tcpa_t *)current; - acpi_create_tcpa(tcpa); - if (tcpa->header.length >= sizeof(acpi_tcpa_t)) { - current += tcpa->header.length; - current = acpi_align_current(current); - acpi_add_table(rsdp, tcpa); - } - } - - if (CONFIG(TPM2)) { - printk(BIOS_DEBUG, "ACPI: * TPM2\n"); - tpm2 = (acpi_tpm2_t *)current; - acpi_create_tpm2(tpm2); - if (tpm2->header.length >= sizeof(acpi_tpm2_t)) { - current += tpm2->header.length; - current = acpi_align_current(current); - acpi_add_table(rsdp, tpm2); - } - } - - if (CONFIG(ACPI_LPIT)) { - printk(BIOS_DEBUG, "ACPI: * LPIT\n"); - - lpit = (acpi_lpit_t *)current; - acpi_create_lpit(lpit); - if (lpit->header.length >= sizeof(acpi_lpit_t)) { - current += lpit->header.length; - current = acpi_align_current(current); - acpi_add_table(rsdp, lpit); - } - } - - printk(BIOS_DEBUG, "ACPI: * MADT\n"); - - madt = (acpi_madt_t *)current; - acpi_create_madt(madt); - if (madt->header.length > sizeof(acpi_madt_t)) { - current += madt->header.length; - acpi_add_table(rsdp, madt); - } - - current = acpi_align_current(current); - - if (CONFIG(ACPI_BERT)) { - void *region; - size_t size; - bert = (acpi_bert_t *)current; - if (acpi_soc_get_bert_region(®ion, &size) == CB_SUCCESS) { - printk(BIOS_DEBUG, "ACPI: * BERT\n"); - acpi_write_bert(bert, (uintptr_t)region, size); - if (bert->header.length >= sizeof(acpi_bert_t)) { - current += bert->header.length; - acpi_add_table(rsdp, bert); - } - current = acpi_align_current(current); - } - } - - printk(BIOS_DEBUG, "ACPI: * SPCR\n"); - acpi_spcr_t * const spcr = (acpi_spcr_t *)current; - acpi_create_spcr(spcr); - if (spcr->header.length >= sizeof(acpi_spcr_t)) { - current += spcr->header.length; - acpi_add_table(rsdp, spcr); - } - current = acpi_align_current(current); - printk(BIOS_DEBUG, "current = %lx\n", current); for (dev = all_devices; dev; dev = dev->next) { |