[PATCH 1/2] lib: fwts_acpi_tables: add ACPI table provenance

Keng-Yu Lin kengyu at canonical.com
Mon Jun 25 05:50:21 UTC 2012


On Fri, Jun 22, 2012 at 7:01 PM, Colin King <colin.king at canonical.com> wrote:
> From: Colin Ian King <colin.king at canonical.com>
>
> It is useful (for example in the acpidump test) to be able
> to determine where an ACPI table came from.  In normal mode, fwts
> loads ACPI tables directly from firmware in memory, but it can also
> load them from file (e.g. from acpidump) or even generate them if
> they are missing in a fix-up processing stage.
>
> So, lets add an extra field in the acpi table structure that keeps
> track of each tables provenance.
>
> Signed-off-by: Colin Ian King <colin.king at canonical.com>
> ---
>  src/lib/include/fwts_acpi_tables.h |    7 +++++
>  src/lib/src/fwts_acpi_tables.c     |   57 ++++++++++++++++++++++++------------
>  2 files changed, 46 insertions(+), 18 deletions(-)
>
> diff --git a/src/lib/include/fwts_acpi_tables.h b/src/lib/include/fwts_acpi_tables.h
> index 80fe75e..33f4e4d 100644
> --- a/src/lib/include/fwts_acpi_tables.h
> +++ b/src/lib/include/fwts_acpi_tables.h
> @@ -22,12 +22,19 @@
>
>  #include "fwts.h"
>
> +typedef enum {
> +       FWTS_ACPI_TABLE_FROM_FIRMWARE,  /* directly from firmware */
> +       FWTS_ACPI_TABLE_FROM_FILE,      /* loaded from file, e.g. from acpidump */
> +       FWTS_ACPI_TABLE_FROM_FIXUP,     /* auto-generated fixup by fwts */
> +} fwts_acpi_table_provenance;
> +
>  typedef struct {
>        char    name[5];
>        const void *data;
>        size_t  length;
>        int     which;
>        uint64_t addr;
> +       fwts_acpi_table_provenance provenance;
>  } fwts_acpi_table_info;
>
>  int fwts_acpi_load_tables(fwts_framework *fw);
> diff --git a/src/lib/src/fwts_acpi_tables.c b/src/lib/src/fwts_acpi_tables.c
> index 513dfff..042c3ec 100644
> --- a/src/lib/src/fwts_acpi_tables.c
> +++ b/src/lib/src/fwts_acpi_tables.c
> @@ -152,7 +152,12 @@ static void *fwts_acpi_load_table(const off_t addr)
>  *     Add a table to internal ACPI table cache. Ignore duplicates based on
>  *     their address.
>  */
> -static void fwts_acpi_add_table(const char *name, const void *table, const uint64_t addr, const size_t length)
> +static void fwts_acpi_add_table(
> +       const char *name,                       /* Table Name */
> +       const void *table,                      /* Table binary blob */
> +       const uint64_t addr,                    /* Address of table */
> +       const size_t length,                    /* Length of table */
> +       fwts_acpi_table_provenance provenance)  /* Where we got the table from */
>  {
>        int i;
>        int which = 0;
> @@ -172,6 +177,7 @@ static void fwts_acpi_add_table(const char *name, const void *table, const uint6
>                        tables[i].addr = addr;
>                        tables[i].length = length;
>                        tables[i].which = which;
> +                       tables[i].provenance = provenance;
>                        return;
>                }
>        }
> @@ -199,7 +205,11 @@ int fwts_acpi_free_tables(void)
>  *     depending on whether 32 or 64 bit address is usable, get the FADT table
>  *     address and load the FADT.
>  */
> -static void fwts_acpi_handle_fadt_tables(fwts_acpi_table_fadt *fadt, const uint32_t *addr32, const uint64_t *addr64)
> +static void fwts_acpi_handle_fadt_tables(
> +       fwts_acpi_table_fadt *fadt,
> +       const uint32_t *addr32,
> +       const uint64_t *addr64,
> +       fwts_acpi_table_provenance provenance)
>  {
>        off_t addr;
>        fwts_acpi_table_header *header;
> @@ -212,14 +222,15 @@ static void fwts_acpi_handle_fadt_tables(fwts_acpi_table_fadt *fadt, const uint3
>
>        if (addr) {
>                if ((header = fwts_acpi_load_table(addr)) != NULL)
> -                       fwts_acpi_add_table(header->signature, header, (uint64_t)addr, header->length);
> +                       fwts_acpi_add_table(header->signature, header,
> +                               (uint64_t)addr, header->length, provenance);
>        }
>  }
>
> -static void fwts_acpi_handle_fadt(fwts_acpi_table_fadt *fadt)
> +static void fwts_acpi_handle_fadt(fwts_acpi_table_fadt *fadt, fwts_acpi_table_provenance provenance)
>  {
> -       fwts_acpi_handle_fadt_tables(fadt, &fadt->dsdt, &fadt->x_dsdt);
> -       fwts_acpi_handle_fadt_tables(fadt, &fadt->firmware_control, &fadt->x_firmware_ctrl);
> +       fwts_acpi_handle_fadt_tables(fadt, &fadt->dsdt, &fadt->x_dsdt, provenance);
> +       fwts_acpi_handle_fadt_tables(fadt, &fadt->firmware_control, &fadt->x_firmware_ctrl, provenance);
>  }
>
>  /*
> @@ -246,19 +257,22 @@ static int fwts_acpi_load_tables_from_firmware(void)
>        /* Load and save cached RSDP */
>        if ((rsdp = fwts_acpi_get_rsdp(rsdp_addr, &rsdp_len)) == NULL)
>                return FWTS_ERROR;
> -       fwts_acpi_add_table("RSDP", rsdp, (uint64_t)(off_t)rsdp_addr, rsdp_len);
> +       fwts_acpi_add_table("RSDP", rsdp, (uint64_t)(off_t)rsdp_addr, rsdp_len, FWTS_ACPI_TABLE_FROM_FIRMWARE);
>
>        /* Load any tables from RSDT if it's valid */
>        if (rsdp->rsdt_address) {
>                if ((rsdt = fwts_acpi_load_table((off_t)rsdp->rsdt_address)) != NULL) {
> -                       fwts_acpi_add_table("RSDT", rsdt, (uint64_t)rsdp->rsdt_address, rsdt->header.length);
> +                       fwts_acpi_add_table("RSDT", rsdt, (uint64_t)rsdp->rsdt_address,
> +                               rsdt->header.length, FWTS_ACPI_TABLE_FROM_FIRMWARE);
>                        num_entries = (rsdt->header.length - sizeof(fwts_acpi_table_header)) / 4;
>                        for (i=0; i<num_entries; i++) {
>                                if (rsdt->entries[i]) {
>                                        if ((header = fwts_acpi_load_table((off_t)rsdt->entries[i])) != NULL) {
>                                                if (strncmp("FACP", header->signature, 4) == 0)
> -                                                       fwts_acpi_handle_fadt((fwts_acpi_table_fadt*)header);
> -                                               fwts_acpi_add_table(header->signature, header, (uint64_t)rsdt->entries[i], header->length);
> +                                                       fwts_acpi_handle_fadt((fwts_acpi_table_fadt*)header,
> +                                                               FWTS_ACPI_TABLE_FROM_FIRMWARE);
> +                                               fwts_acpi_add_table(header->signature, header, (uint64_t)rsdt->entries[i],
> +                                                       header->length, FWTS_ACPI_TABLE_FROM_FIRMWARE);
>                                        }
>                                }
>                        }
> @@ -268,14 +282,17 @@ static int fwts_acpi_load_tables_from_firmware(void)
>        /* Load any tables from XSDT if it's valid */
>        if (rsdp->xsdt_address) {
>                if ((xsdt = fwts_acpi_load_table((off_t)rsdp->xsdt_address)) != NULL) {
> -                       fwts_acpi_add_table("XSDT", xsdt, (uint64_t)rsdp->xsdt_address, xsdt->header.length);
> +                       fwts_acpi_add_table("XSDT", xsdt, (uint64_t)rsdp->xsdt_address,
> +                               xsdt->header.length, FWTS_ACPI_TABLE_FROM_FIRMWARE);
>                        num_entries = (xsdt->header.length - sizeof(fwts_acpi_table_header)) / 8;
>                        for (i=0; i<num_entries; i++) {
>                                if (xsdt->entries[i]) {
>                                        if ((header = fwts_acpi_load_table((off_t)xsdt->entries[i])) != NULL) {
>                                                if (strncmp("FACP", header->signature, 4) == 0)
> -                                                       fwts_acpi_handle_fadt((fwts_acpi_table_fadt*)header);
> -                                               fwts_acpi_add_table(header->signature, header, xsdt->entries[i], header->length);
> +                                                       fwts_acpi_handle_fadt((fwts_acpi_table_fadt*)header,
> +                                                               FWTS_ACPI_TABLE_FROM_FIRMWARE);
> +                                               fwts_acpi_add_table(header->signature, header, xsdt->entries[i],
> +                                                       header->length, FWTS_ACPI_TABLE_FROM_FIRMWARE);
>                                        }
>                                }
>                        }
> @@ -402,7 +419,7 @@ static int fwts_acpi_load_tables_from_acpidump(fwts_framework *fw)
>                char name[16];
>
>                if ((table = fwts_acpi_load_table_from_acpidump(fp, name, &addr, &length)) != NULL)
> -                       fwts_acpi_add_table(name, table, addr, length);
> +                       fwts_acpi_add_table(name, table, addr, length, FWTS_ACPI_TABLE_FROM_FILE);
>        }
>
>        fclose(fp);
> @@ -475,7 +492,8 @@ static int fwts_acpi_load_tables_from_file(fwts_framework *fw)
>                                name[strlen(name)-4] = '\0';
>                                if ((table = fwts_acpi_load_table_from_file(fd, &length)) != NULL)
>                                        fwts_acpi_add_table(name, table,
> -                                               (uint64_t)fwts_fake_physical_addr(length), length);
> +                                               (uint64_t)fwts_fake_physical_addr(length), length,
> +                                               FWTS_ACPI_TABLE_FROM_FILE);
>                                close(fd);
>                        } else
>                                fwts_log_error(fw, "Cannot load ACPI table from file '%s'\n", path);
> @@ -590,7 +608,8 @@ static int fwts_acpi_load_tables_fixup(fwts_framework *fw)
>                rsdt->header.creator_revision = 1;
>                rsdt->header.checksum = 256 - fwts_checksum((uint8_t*)rsdt, size);
>
> -               fwts_acpi_add_table("RSDT", rsdt, (uint64_t)fwts_fake_physical_addr(size), size);
> +               fwts_acpi_add_table("RSDT", rsdt, (uint64_t)fwts_fake_physical_addr(size),
> +                       size, FWTS_ACPI_TABLE_FROM_FIXUP);
>        }
>
>        /* No XSDT? go and fake one */
> @@ -614,7 +633,8 @@ static int fwts_acpi_load_tables_fixup(fwts_framework *fw)
>                xsdt->header.creator_revision = 1;
>                xsdt->header.checksum = 256 - fwts_checksum((uint8_t*)xsdt, size);
>
> -               fwts_acpi_add_table("XSDT", xsdt, (uint64_t)fwts_fake_physical_addr(size), size);
> +               fwts_acpi_add_table("XSDT", xsdt, (uint64_t)fwts_fake_physical_addr(size),
> +                       size, FWTS_ACPI_TABLE_FROM_FIXUP);
>        }
>
>        /* No RSDP? go and fake one */
> @@ -636,7 +656,8 @@ static int fwts_acpi_load_tables_fixup(fwts_framework *fw)
>                rsdp->checksum = 256 - fwts_checksum((uint8_t*)rsdp, 20);
>                rsdp->extended_checksum = 256 - fwts_checksum((uint8_t*)rsdp, sizeof(fwts_acpi_table_rsdp));
>
> -               fwts_acpi_add_table("RSDP", rsdp, (uint64_t)fwts_fake_physical_addr(size), sizeof(fwts_acpi_table_rsdp));
> +               fwts_acpi_add_table("RSDP", rsdp, (uint64_t)fwts_fake_physical_addr(size),
> +                       sizeof(fwts_acpi_table_rsdp), FWTS_ACPI_TABLE_FROM_FIXUP);
>        }
>        return FWTS_OK;
>  }
> --
> 1.7.10.4
>
Acked-by: Keng-Yu Lin <kengyu at canonical.com>


More information about the fwts-devel mailing list