Message ID | 20170324161015.8664-3-colin.king@canonical.com |
---|---|
State | Accepted |
Headers | show |
On 2017-03-25 12:10 AM, Colin King wrote: > From: Colin Ian King <colin.king@canonical.com> > > In the case where the FACS and DSDT are loaded from file and don't have > an address then fwts makes up a fake address for these tables to keep > ACPICA happy. However, the FACP (FADT) points to these tables so we > can actually fix up the FACS and DSDT table addresses to these known > addresses fiven by the FACP. We prefer 64 bit addresses from the FACP > but if they don't exist, use the 32 bit addresses. > > Signed-off-by: Colin Ian King <colin.king@canonical.com> > --- > src/lib/src/fwts_acpi_tables.c | 56 +++++++++++++++++++++++++++++++++++++----- > 1 file changed, 50 insertions(+), 6 deletions(-) > > diff --git a/src/lib/src/fwts_acpi_tables.c b/src/lib/src/fwts_acpi_tables.c > index 3d342299..1d4fc705 100644 > --- a/src/lib/src/fwts_acpi_tables.c > +++ b/src/lib/src/fwts_acpi_tables.c > @@ -925,6 +925,38 @@ static bool fwts_acpi_table_fixable(fwts_acpi_table_info *table) > } > > /* > + * fwts_acpi_fixup_addr_from_fadt() > + * fixup the ACPI table address of a given table if we have it defined > + * in the FADT. This is only for fixed up tables loaded from file > + * where these table addresses are unknown and hence are faked physical > + * addresses to keep ACPICA happy. > + */ > +void fwts_acpi_fixup_addr_from_fadt( > + fwts_framework *fw, > + const char *name, > + uint32_t addr32, > + uint64_t addr64) > +{ > + fwts_acpi_table_info *table; > + > + /* Fetch the table */ > + if (fwts_acpi_find_table(fw, name, 0, &table) != FWTS_OK) > + return; > + if (!table) > + return; > + > + /* > + * OK, we have something to patch up, 64 bit addresses > + * are used in preference to 32 bit. And only patch > + * the addresses if they are non-zero. > + */ > + if (addr64) > + table->addr = addr64; > + else if (addr32) > + table->addr = addr32; > +} > + > +/* > * fwts_acpi_load_tables_fixup() > * tables loaded from file sometimes do not contain the original > * physical address of the tables, so these need faking. Also, some > @@ -938,6 +970,7 @@ static int fwts_acpi_load_tables_fixup(fwts_framework *fw) > fwts_acpi_table_info *table; > fwts_acpi_table_rsdp *rsdp = NULL; > fwts_acpi_table_fadt *fadt = NULL; > + fwts_acpi_table_facs *facs = NULL; > uint64_t rsdt_fake_addr = 0, xsdt_fake_addr = 0; > bool redo_rsdp_checksum = false; > > @@ -946,21 +979,22 @@ static int fwts_acpi_load_tables_fixup(fwts_framework *fw) > fwts_log_error(fw, "ACPI table find failure."); > return FWTS_ERROR; > } > - if (table) { > - fadt = (fwts_acpi_table_fadt *)table->data; > - oem_tbl_id = fadt->header.oem_tbl_id; > - } else { > + if (!table) { > fwts_log_error(fw, "Cannot find FACP."); > return FWTS_ERROR; > } > > + fadt = (fwts_acpi_table_fadt *)table->data; > + oem_tbl_id = fadt->header.oem_tbl_id; > + > /* Get FACS */ > if (fwts_acpi_find_table(fw, "FACS", 0, &table) != FWTS_OK) { > fwts_log_error(fw, "ACPI table find failure."); > return FWTS_ERROR; > } > - if (!table) { > - fwts_acpi_table_facs *facs; > + if (table) { > + facs = (fwts_acpi_table_facs *)table->data; > + } else { > size_t size = 64; > uint64_t facs_addr; > > @@ -995,6 +1029,16 @@ static int fwts_acpi_load_tables_fixup(fwts_framework *fw) > size, FWTS_ACPI_TABLE_FROM_FIXUP); > } > > + /* > + * In the case where the tables have be loaded from file > + * and the address is not known we may have a valid FACP (FADT) > + * that points to the FACS and DSDT, so we need to ensure > + * fake addresses created by fwts for these are in-sync > + * before we create RSDT and XSDTs > + */ > + fwts_acpi_fixup_addr_from_fadt(fw, "FACS", fadt->firmware_control, fadt->x_firmware_ctrl); > + fwts_acpi_fixup_addr_from_fadt(fw, "DSDT", fadt->dsdt, fadt->x_dsdt); > + > /* Figure out how many tables we need to put into RSDT and XSDT */ > for (count = 0, i = 0; ; i++) { > if (fwts_acpi_get_table(fw, i, &table) != FWTS_OK) > Acked-by: Alex Hung <alex.hung@canonical.com>
On 03/25/2017 12:10 AM, Colin King wrote: > From: Colin Ian King <colin.king@canonical.com> > > In the case where the FACS and DSDT are loaded from file and don't have > an address then fwts makes up a fake address for these tables to keep > ACPICA happy. However, the FACP (FADT) points to these tables so we > can actually fix up the FACS and DSDT table addresses to these known > addresses fiven by the FACP. We prefer 64 bit addresses from the FACP > but if they don't exist, use the 32 bit addresses. > > Signed-off-by: Colin Ian King <colin.king@canonical.com> > --- > src/lib/src/fwts_acpi_tables.c | 56 +++++++++++++++++++++++++++++++++++++----- > 1 file changed, 50 insertions(+), 6 deletions(-) > > diff --git a/src/lib/src/fwts_acpi_tables.c b/src/lib/src/fwts_acpi_tables.c > index 3d342299..1d4fc705 100644 > --- a/src/lib/src/fwts_acpi_tables.c > +++ b/src/lib/src/fwts_acpi_tables.c > @@ -925,6 +925,38 @@ static bool fwts_acpi_table_fixable(fwts_acpi_table_info *table) > } > > /* > + * fwts_acpi_fixup_addr_from_fadt() > + * fixup the ACPI table address of a given table if we have it defined > + * in the FADT. This is only for fixed up tables loaded from file > + * where these table addresses are unknown and hence are faked physical > + * addresses to keep ACPICA happy. > + */ > +void fwts_acpi_fixup_addr_from_fadt( > + fwts_framework *fw, > + const char *name, > + uint32_t addr32, > + uint64_t addr64) > +{ > + fwts_acpi_table_info *table; > + > + /* Fetch the table */ > + if (fwts_acpi_find_table(fw, name, 0, &table) != FWTS_OK) > + return; > + if (!table) > + return; > + > + /* > + * OK, we have something to patch up, 64 bit addresses > + * are used in preference to 32 bit. And only patch > + * the addresses if they are non-zero. > + */ > + if (addr64) > + table->addr = addr64; > + else if (addr32) > + table->addr = addr32; > +} > + > +/* > * fwts_acpi_load_tables_fixup() > * tables loaded from file sometimes do not contain the original > * physical address of the tables, so these need faking. Also, some > @@ -938,6 +970,7 @@ static int fwts_acpi_load_tables_fixup(fwts_framework *fw) > fwts_acpi_table_info *table; > fwts_acpi_table_rsdp *rsdp = NULL; > fwts_acpi_table_fadt *fadt = NULL; > + fwts_acpi_table_facs *facs = NULL; > uint64_t rsdt_fake_addr = 0, xsdt_fake_addr = 0; > bool redo_rsdp_checksum = false; > > @@ -946,21 +979,22 @@ static int fwts_acpi_load_tables_fixup(fwts_framework *fw) > fwts_log_error(fw, "ACPI table find failure."); > return FWTS_ERROR; > } > - if (table) { > - fadt = (fwts_acpi_table_fadt *)table->data; > - oem_tbl_id = fadt->header.oem_tbl_id; > - } else { > + if (!table) { > fwts_log_error(fw, "Cannot find FACP."); > return FWTS_ERROR; > } > > + fadt = (fwts_acpi_table_fadt *)table->data; > + oem_tbl_id = fadt->header.oem_tbl_id; > + > /* Get FACS */ > if (fwts_acpi_find_table(fw, "FACS", 0, &table) != FWTS_OK) { > fwts_log_error(fw, "ACPI table find failure."); > return FWTS_ERROR; > } > - if (!table) { > - fwts_acpi_table_facs *facs; > + if (table) { > + facs = (fwts_acpi_table_facs *)table->data; > + } else { > size_t size = 64; > uint64_t facs_addr; > > @@ -995,6 +1029,16 @@ static int fwts_acpi_load_tables_fixup(fwts_framework *fw) > size, FWTS_ACPI_TABLE_FROM_FIXUP); > } > > + /* > + * In the case where the tables have be loaded from file > + * and the address is not known we may have a valid FACP (FADT) > + * that points to the FACS and DSDT, so we need to ensure > + * fake addresses created by fwts for these are in-sync > + * before we create RSDT and XSDTs > + */ > + fwts_acpi_fixup_addr_from_fadt(fw, "FACS", fadt->firmware_control, fadt->x_firmware_ctrl); > + fwts_acpi_fixup_addr_from_fadt(fw, "DSDT", fadt->dsdt, fadt->x_dsdt); > + > /* Figure out how many tables we need to put into RSDT and XSDT */ > for (count = 0, i = 0; ; i++) { > if (fwts_acpi_get_table(fw, i, &table) != FWTS_OK) Acked-by: Ivan Hu <ivan.hu@canonical.com>
diff --git a/src/lib/src/fwts_acpi_tables.c b/src/lib/src/fwts_acpi_tables.c index 3d342299..1d4fc705 100644 --- a/src/lib/src/fwts_acpi_tables.c +++ b/src/lib/src/fwts_acpi_tables.c @@ -925,6 +925,38 @@ static bool fwts_acpi_table_fixable(fwts_acpi_table_info *table) } /* + * fwts_acpi_fixup_addr_from_fadt() + * fixup the ACPI table address of a given table if we have it defined + * in the FADT. This is only for fixed up tables loaded from file + * where these table addresses are unknown and hence are faked physical + * addresses to keep ACPICA happy. + */ +void fwts_acpi_fixup_addr_from_fadt( + fwts_framework *fw, + const char *name, + uint32_t addr32, + uint64_t addr64) +{ + fwts_acpi_table_info *table; + + /* Fetch the table */ + if (fwts_acpi_find_table(fw, name, 0, &table) != FWTS_OK) + return; + if (!table) + return; + + /* + * OK, we have something to patch up, 64 bit addresses + * are used in preference to 32 bit. And only patch + * the addresses if they are non-zero. + */ + if (addr64) + table->addr = addr64; + else if (addr32) + table->addr = addr32; +} + +/* * fwts_acpi_load_tables_fixup() * tables loaded from file sometimes do not contain the original * physical address of the tables, so these need faking. Also, some @@ -938,6 +970,7 @@ static int fwts_acpi_load_tables_fixup(fwts_framework *fw) fwts_acpi_table_info *table; fwts_acpi_table_rsdp *rsdp = NULL; fwts_acpi_table_fadt *fadt = NULL; + fwts_acpi_table_facs *facs = NULL; uint64_t rsdt_fake_addr = 0, xsdt_fake_addr = 0; bool redo_rsdp_checksum = false; @@ -946,21 +979,22 @@ static int fwts_acpi_load_tables_fixup(fwts_framework *fw) fwts_log_error(fw, "ACPI table find failure."); return FWTS_ERROR; } - if (table) { - fadt = (fwts_acpi_table_fadt *)table->data; - oem_tbl_id = fadt->header.oem_tbl_id; - } else { + if (!table) { fwts_log_error(fw, "Cannot find FACP."); return FWTS_ERROR; } + fadt = (fwts_acpi_table_fadt *)table->data; + oem_tbl_id = fadt->header.oem_tbl_id; + /* Get FACS */ if (fwts_acpi_find_table(fw, "FACS", 0, &table) != FWTS_OK) { fwts_log_error(fw, "ACPI table find failure."); return FWTS_ERROR; } - if (!table) { - fwts_acpi_table_facs *facs; + if (table) { + facs = (fwts_acpi_table_facs *)table->data; + } else { size_t size = 64; uint64_t facs_addr; @@ -995,6 +1029,16 @@ static int fwts_acpi_load_tables_fixup(fwts_framework *fw) size, FWTS_ACPI_TABLE_FROM_FIXUP); } + /* + * In the case where the tables have be loaded from file + * and the address is not known we may have a valid FACP (FADT) + * that points to the FACS and DSDT, so we need to ensure + * fake addresses created by fwts for these are in-sync + * before we create RSDT and XSDTs + */ + fwts_acpi_fixup_addr_from_fadt(fw, "FACS", fadt->firmware_control, fadt->x_firmware_ctrl); + fwts_acpi_fixup_addr_from_fadt(fw, "DSDT", fadt->dsdt, fadt->x_dsdt); + /* Figure out how many tables we need to put into RSDT and XSDT */ for (count = 0, i = 0; ; i++) { if (fwts_acpi_get_table(fw, i, &table) != FWTS_OK)