On 09/05/2013 09:47 AM, Tomasz Nowicki wrote:
o move common code to separate direction so others application can reuse it o appropriate changes around Makefile files o minor changes regarding compilator worrnings
Makefile | 16 +- platforms/Makefile | 6 +- tools/cab/Makefile | 12 +- tools/cab/cab.c | 527 +------------------------------------- tools/cab/cab.h | 149 ----------- tools/common/Makefile | 4 + tools/common/build_aml.c | 455 ++++++++++++++++++++++++++++++++ tools/common/check_aml.c | 512 ++++++++++++++++++++++++++++++++++++ tools/common/include/build_aml.h | 74 ++++++ tools/common/include/check_aml.h | 99 +++++++ tools/mab/Makefile | 13 +- tools/mab/mab.c | 430 +------------------------------ tools/mab/mab.h | 77 ------ 13 files changed, 1183 insertions(+), 1191 deletions(-) create mode 100644 tools/common/Makefile create mode 100644 tools/common/build_aml.c create mode 100644 tools/common/check_aml.c create mode 100644 tools/common/include/build_aml.h create mode 100644 tools/common/include/check_aml.h
diff --git a/Makefile b/Makefile index ef63965..e897c69 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,21 @@ MABDIR := tools/mab/ CABDIR := tools/cab/ +COMMON_DIR := tools/common/ PLATDIR := platforms/
-%.acpi : $(MABDIR)/mab $(CABDIR)/cab +%.acpi : mab cab make MAB=$(CURDIR)/$(MABDIR)/mab PADDR=$(PADDR) -C $(PLATDIR) $@
-$(MABDIR)/mab : FORCE
- make -C $(MABDIR)
+mab : FORCE
- make -C $(MABDIR) PROG=mab
-$(CABDIR)/cab : FORCE
- make -C $(CABDIR)
+cab : FORCE
make -C $(CABDIR) PROG=cab
clean :
- make -C $(MABDIR) clean
- make -C $(CABDIR) clean
make -C $(MABDIR) clean PROG=mab
make -C $(CABDIR) clean PROG=cab
make -C $(COMMON_DIR) clean make -C $(PLATDIR) clean
FORCE :
diff --git a/platforms/Makefile b/platforms/Makefile index 95e8453..caff1c8 100644 --- a/platforms/Makefile +++ b/platforms/Makefile @@ -6,9 +6,9 @@ endif $(MAB) -d $@ $(PADDR_ARG) -i $(basename $@).manifest -o $@
clean :
- -rm *.acpi/*.aml
- -rm *.acpi/*.lst
- -rm *.acpi/*.acpi
-rm -f *.acpi/*.aml
-rm -f *.acpi/*.lst
-rm -f *.acpi/*.acpi
FORCE :
diff --git a/tools/cab/Makefile b/tools/cab/Makefile index b363232..2dcec39 100644 --- a/tools/cab/Makefile +++ b/tools/cab/Makefile @@ -1,7 +1,11 @@ -CFLAGS := -g +CFLAGS := -g -Wall -I../common/include
-cab : cab.h cab.c
- $(CC) $(CFLAGS) -o cab cab.c
+HEADERS = $(wildcard *.h) $(wildcard ../common/include/*.h)
+SOURCES = $(wildcard *.c) $(wildcard ../common/*.c)
+$(PROG) : $(patsubst %.c,%.o, $(SOURCES)) $(HEADERS)
$(CC) $(CFLAGS) $(patsubst %.c,%.o, $(SOURCES)) -o $@
clean :
- -rm -f cab cab.o
- -rm -f $(patsubst %.c,%.o, $(wildcard *.c)) $(PROG)
diff --git a/tools/cab/cab.c b/tools/cab/cab.c index 155e055..481c021 100644 --- a/tools/cab/cab.c +++ b/tools/cab/cab.c @@ -11,28 +11,12 @@
*/
-#include "cab.h"
-#include <sys/queue.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mman.h>
-#include <ctype.h> -#include <endian.h> -#include <errno.h> -#include <fcntl.h> -#include <libgen.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> +#include <build_aml.h> +#include <check_aml.h>
-int passed; -int failed; +#include "cab.h"
-void usage(void) +static void usage(void) { printf("%s %s\n", PROGNAME, VERSION); printf("usage: %s -b <blob> -p <paddr> [-q]\n", PROGNAME); @@ -42,517 +26,24 @@ void usage(void) printf(" -q => if given, supress output\n"); }
-int get_file_size(char *fname) -{
- struct stat buf;
- int err;
- err = stat(fname, &buf);
- if (err)
printf("? cannot stat %s (%d)\n", fname, err);
- return (err == 0 ? buf.st_size : 0);
-}
-int valid_sig(char *sig) -{
- char **p;
- p = known_sigs;
- while (*p != NULL) {
if (strncmp(*p, sig, strlen(*p)) == 0)
return 1;
p++;
- }
- return 0;
-}
-struct table *build_table_entry(unsigned char *buf) -{
- struct table *tmp;
- const int RSDP_NUDGE = 3;
- int len;
- tmp = (struct table *)malloc(sizeof(struct table));
- if (tmp != NULL) {
memset(tmp, 0, sizeof(struct table));
/* fill in the struct */
len = SIG_LENGTH + 1;
if (strncmp(buf, SIG_RSDP, SIG_LENGTH + RSDP_NUDGE) == 0)
len += RSDP_NUDGE;
tmp->signature = (char *)malloc(len);
memset(tmp->signature, 0, len);
memcpy(tmp->signature, buf, len - 1);
LIST_INSERT_HEAD(&thead, tmp, tables);
- }
- return tmp;
-}
-struct table *find_table(char *sig) -{
- struct table *np;
- LIST_FOREACH(np, &thead, tables) {
if (strncmp(np->signature, sig, strlen(np->signature)) == 0)
return np;
- }
- return NULL;
-}
-struct known_table_info *find_known_table_info(char *sig) -{
- struct known_table_info *np;
- for (np = known_info; np->signature != NULL; np++) {
if (strncmp(np->signature, sig, strlen(np->signature)) == 0)
return np;
- }
- return NULL;
-}
-int verify_checksum(unsigned char *start, int offset, int len) -{
- uint8_t newsum, oldsum;
- uint8_t *p;
- uint8_t old_cksum, cksum;
- old_cksum = start[offset];
- cksum = old_cksum;
- newsum = 0;
- for (p = (uint8_t *)start; p < (uint8_t *)(start + len); p++)
newsum += *p;
- oldsum = cksum;
- newsum = (uint8_t)(newsum - oldsum);
- cksum = (uint8_t)(0 - newsum);
- return (old_cksum == cksum ? PASS : FAIL);
-}
-int verify_revision(unsigned char *r, int min) -{
- return (*(uint8_t *)r >= min ? PASS : FAIL);
-}
-void presult(int res, char *topic) -{
- if (res != 0)
passed++;
- else
failed++;
- if (res >= 0)
printf("[%4s] %s\n", (res != 0) ? "PASS" : "FAIL", topic);
- else
printf("[%4s] %s\n", "INFO", topic);
-}
-void check_blob_header(unsigned char *blob) -{
- int res;
- printf("\nchecking blob header...\n");
- res = strncmp(blob, BLOB_MAGIC, BLOB_MAGIC_SIZE);
- res = (res == 0 ? PASS : FAIL);
- presult(res, "blob magic number is correct");
-}
-void check_table_header(char *name, unsigned char *loc) -{
- const int CHECKSUM_OFFSET = 9;
- const int CREATOR_ID_OFFSET = 28;
- const int CREATOR_ID_LEN = 4;
- const int CREATOR_REV_OFFSET = 32;
- const int CREATOR_REV_LEN = 4;
- const int OEMID_OFFSET = 10;
- const int OEMID_LEN = 6;
- const int REVISION_OFFSET = 8;
- struct known_table_info *kp;
- char buf[MAX_LINE];
- int res;
- int offset;
- uint32_t len;
- int min;
- /* valid signature? */
- kp = find_known_table_info(name);
- res = (kp ? PASS : FAIL);
- memset(buf, 0, MAX_LINE);
- sprintf(buf, "%s: signature is correct", name);
- presult(res, buf);
- if (!kp) {
printf("? %s is an unknown table\n", name);
return;
- }
- /* possibly usable length? */
- len = *(uint32_t *)(loc + TABLE_LEN_OFFSET);
- res = PASS;
- if ((len <= 0) || (len < MIN_TABLE_LENGTH))
res = FAIL;
- memset(buf, 0, MAX_LINE);
- sprintf(buf, "%s: table length is reasonable (%d)", name, len);
- presult(res, buf);
- /* valid checksum? */
- res = verify_checksum(loc, CHECKSUM_OFFSET, len);
- memset(buf, 0, MAX_LINE);
- sprintf(buf, "%s: checksum is correct", name);
- presult(res, buf);
- /* valid revision number? */
- res = verify_revision(loc + REVISION_OFFSET, kp->min_revision);
- memset(buf, 0, MAX_LINE);
- sprintf(buf, "%s: minimum revision is correct", name);
- presult(res, buf);
- /* non-empty OEMID field? */
- res = (loc[OEMID_OFFSET] != 0 ? PASS : FAIL);
- memset(buf, 0, MAX_LINE);
- sprintf(buf, "%s: there is an OEMID (", name);
- strncat(buf, (unsigned char *)(loc + OEMID_OFFSET), OEMID_LEN);
- strncat(buf, ")", 1);
- presult(res, buf);
- /* non-empty CreatorID field? */
- res = (loc[CREATOR_ID_OFFSET] != 0 ? PASS : FAIL);
- memset(buf, 0, MAX_LINE);
- sprintf(buf, "%s: there is a CreatorID", name);
- presult(res, buf);
- /* non-empty CreatorRevision field? */
- res = (loc[CREATOR_REV_OFFSET] != 0 ? PASS : FAIL);
- memset(buf, 0, MAX_LINE);
- sprintf(buf, "%s: there is a CreatorRevision", name);
- presult(res, buf);
-}
-void check_first_table_is_rsdp(unsigned char *blob) -{
- int res;
- res = strncmp(blob + BLOB_HEADER_SIZE, SIG_RSDP, strlen(SIG_RSDP));
- res = (res == 0 ? PASS : FAIL);
- presult(res, "first table has RSDP signature");
-}
-void check_rsdp(unsigned char *blob) -{
- const int RSDP_FIRST_CKSUM_OFFSET = 8;
- const int RSDP_FIRST_CKSUM_LEN = 20;
- const int RSDP_SECOND_CKSUM_OFFSET = 32;
- const int RSDP_SECOND_CKSUM_LEN = 36;
- const int RSDP_RSDT_ADDR_OFFSET = 16;
- unsigned char *ptr;
- int res;
- uint32_t rsdt_addr;
- ptr = blob + BLOB_HEADER_SIZE;
- printf("\nchecking RSDP...\n");
- check_first_table_is_rsdp(blob);
- res = verify_checksum(ptr, RSDP_FIRST_CKSUM_OFFSET,
RSDP_FIRST_CKSUM_LEN);
- presult(res, "first RSDP checksum verified");
- res = verify_checksum(ptr, RSDP_SECOND_CKSUM_OFFSET,
RSDP_SECOND_CKSUM_LEN);
- presult(res, "second RSDP checksum verified");
- rsdt_addr = *(uint32_t *)(ptr + RSDP_RSDT_ADDR_OFFSET);
- res = (rsdt_addr == 0) ? PASS : FAIL;
- presult(res, "RSDT address is null");
-}
-void find_all_tables(unsigned char *blob, int size, int base_addr) -{
- struct table *tp;
- unsigned char *p;
- int offset;
- int delta;
- /* this assumes that all signatures and lengths are correct */
- printf("\nscanning for tables...\n");
- p = blob + BLOB_HEADER_SIZE;
- offset = (int)(p - blob);
- while (offset + SIG_LENGTH < size) {
if (valid_sig(p)) {
tp = build_table_entry(p);
if (tp) {
delta = TABLE_LEN_OFFSET;
if (strcmp(tp->signature, SIG_RSDP) == 0)
delta = RSDP_LEN_OFFSET;
tp->len = *(uint32_t *)(p + delta);
tp->offset = offset;
tp->paddr = base_addr + offset;
offset += *(uint32_t *)(p + delta);
p += tp->len;
} else {
printf("? no room for building a table\n");
exit(1);
}
} else {
/* skip forward until we find something; a table
* could have been moved to the next page boundary */
while (offset + SIG_LENGTH < size) {
p++;
offset++;
if (isalpha(*p) && valid_sig(p))
break;
}
}
- }
-}
-void check_rsdp_relocs(unsigned char *blob, int size, uint64_t paddr) -{
- const int RSDT_ADDR_OFFSET = 16;
- const int XSDT_ADDR_OFFSET = 24;
- struct table *np, *xp;
- int res;
- uint32_t rsdt_addr;
- uint64_t xsdt_addr;
- printf("\nchecking RSDP relocations...\n");
- res = FAIL;
- np = find_table(SIG_RSDP);
- if (np) {
np->ref_cnt++;
rsdt_addr = *(uint32_t *)(blob + np->offset + RSDT_ADDR_OFFSET);
res = (rsdt_addr == 0) ? PASS : FAIL;
presult(res, "RSDP has null RSDT pointer");
xsdt_addr = *(uint32_t *)(blob + np->offset + XSDT_ADDR_OFFSET);
xp = find_table(SIG_XSDT);
if (xp) {
xp->ref_cnt++;
if ((xsdt_addr == xp->paddr) &&
(strncmp(blob + xp->offset, SIG_XSDT,
strlen(xp->signature)) == 0))
res = PASS;
}
presult(res, "RSDP has correct XSDT pointer");
- } else {
res = FAIL;
presult(res, "RSDP has null RSDT pointer");
presult(res, "RSDP has correct XSDT pointer");
- }
-}
-void check_xsdt_relocs(unsigned char *blob, int size, uint64_t paddr) -{
- const int XSDT_ENTRY_START = 36;
- const int XSDT_ENTRY_SIZE = 8;
- struct table *np, *xp;
- int res;
- int cnt;
- int ii;
- int offset;
- uint32_t len;
- uint64_t *tpaddr;
- char buf[MAX_LINE];
- printf("\nchecking XSDT relocations...\n");
- res = FAIL;
- np = find_table(SIG_XSDT);
- if (np) {
len = *(uint32_t *)(blob + np->offset + TABLE_LEN_OFFSET);
cnt = (len - XSDT_ENTRY_START) / XSDT_ENTRY_SIZE;
tpaddr = (uint64_t *)(blob + np->offset + XSDT_ENTRY_START);
if (len < 1) {
printf("? XSDT can not have an empty list\n");
exit(1);
}
/* first entry needs to be the FACP (aka FADT) */
offset = (*tpaddr - paddr);
if (strncmp(blob + offset, SIG_FACP, strlen(SIG_FACP)) == 0)
res = PASS;
presult(res, "first XSDT entry points to the FADT (aka FACP)");
/* verify all the relocations, best we can */
for (ii = 0; ii < cnt; ii++, tpaddr++) {
offset = (*tpaddr - paddr);
res = FAIL;
if (valid_sig(blob + offset)) {
xp = find_table(blob + offset);
if (xp) {
xp->ref_cnt++;
if ((*tpaddr == xp->paddr) &&
(strncmp(blob + xp->offset,
blob + offset,
strlen(xp->signature)) == 0))
res = PASS;
memset(buf, 0, MAX_LINE);
sprintf(buf,
"XSDT has correct %s pointer",
xp->signature);
presult(res, buf);
} else {
memset(buf, 0, MAX_LINE);
sprintf(buf,
"XSDT entry %d does not point to a valid table",
ii);
presult(res, buf);
}
}
}
- } else {
printf("? XSDT can not be found in table list\n");
exit(1);
- }
-}
-void check_fadt_relocs(unsigned char *blob, int size, uint64_t paddr) -{
- const int FWCTL_OFFSET = 36;
- const int DSDT_OFFSET = 40;
- const int XFWCTL_OFFSET = 132;
- const int XDSDT_OFFSET = 140;
- struct table *np, *xp;
- uint32_t fwctl, dsdt;
- uint64_t xfwctl, xdsdt;
- uint64_t tpaddr;
- int res;
- int offset;
- printf("\nchecking FADT relocations...\n");
- np = find_table(SIG_FACP);
- if (np) {
fwctl = *(uint32_t *)(blob + np->offset + FWCTL_OFFSET);
xfwctl = *(uint64_t *)(blob + np->offset + XFWCTL_OFFSET);
res = FAIL;
if ((fwctl == 0 && xfwctl == 0) || /* no FACS is okay */
(fwctl == 0 && xfwctl != 0) ||
(fwctl != 0 && xfwctl == 0))
res = PASS;
presult(res, "FADT has a proper 32-bit FACS pointer");
presult(res, "FADT has a proper 64-bit FACS pointer");
if (fwctl != 0 && xfwctl != 0)
presult(INFO,
"both fields have been set, not just one");
if (fwctl != 0 || xfwctl != 0) {
tpaddr = (fwctl == 0) ? xfwctl : fwctl;
offset = tpaddr - paddr;
xp = find_table(SIG_FACS);
if (xp) {
xp->ref_cnt++;
res = FAIL;
if ((tpaddr == xp->paddr) &&
(strncmp(blob + xp->offset,
blob + offset,
strlen(xp->signature)) == 0))
res = PASS;
presult(res, "FADT has correct FACS pointer");
} else {
printf("? FADT refers to an FACS but ");
printf("there is no such table\n");
exit(1);
}
}
dsdt = *(uint32_t *)(blob + np->offset + DSDT_OFFSET);
xdsdt = *(uint64_t *)(blob + np->offset + XDSDT_OFFSET);
res = FAIL;
if ((dsdt == 0 && xdsdt != 0) || /* must have a DSDT */
(dsdt != 0 && xdsdt == 0))
res = PASS;
presult(res, "FADT has a proper 32-bit DSDT pointer");
presult(res, "FADT has a proper 64-bit DSDT pointer");
if (dsdt != 0 && xdsdt != 0)
presult(INFO,
"both fields have been set, not just one");
if (dsdt != 0 || xdsdt != 0) {
tpaddr = (dsdt == 0) ? xdsdt : dsdt;
offset = tpaddr - paddr;
xp = find_table(SIG_DSDT);
if (xp) {
xp->ref_cnt++;
res = FAIL;
if ((tpaddr == xp->paddr) &&
(strncmp(blob + xp->offset,
blob + offset,
strlen(xp->signature)) == 0))
res = PASS;
presult(res, "FADT has correct DSDT pointer");
} else {
printf("? FADT refers to a DSDT but ");
printf("there is no such table\n");
exit(1);
}
}
- } else {
printf("? FADT (aka FACP) can not be found in table list\n");
exit(1);
- }
-}
-void check_ref_cnts(void) -{
- struct table *np;
- int res;
- char buf[MAX_LINE];
- printf("\nchecking references to tables...\n");
- LIST_FOREACH(np, &thead, tables) {
memset(buf, 0, MAX_LINE);
sprintf(buf, "%s referenced only once", np->signature);
res = (np->ref_cnt == 1) ? PASS : FAIL;
presult(res, buf);
- }
-}
-void check_relocations(unsigned char *blob, int size, uint64_t paddr) -{
- check_rsdp_relocs(blob, size, paddr);
- check_xsdt_relocs(blob, size, paddr);
- check_fadt_relocs(blob, size, paddr);
- check_ref_cnts();
-}
- int main(int argc, char *argv[]) {
- int ii, jj;
- int offset;
- int delta;
- int ii; int size; int fd; unsigned char *blob; char *acpi_blob_name; char *paddr_cmd; uint64_t paddr = 0;
- char sig[SIG_LENGTH]; struct table *np; int opt; int quiet;
int failed;
/* parameter handling */ acpi_blob_name = NULL; paddr_cmd = NULL; quiet = 0;
passed = 0; failed = 0;
while ((opt = getopt(argc, argv, "b:p:q")) != EOF) {
@@ -640,11 +131,7 @@ int main(int argc, char *argv[])
check_relocations(blob, size, paddr);
- printf("\nTotal tests: %d\n", passed + failed);
- printf("Passed: %d\n", passed);
- printf("Failed: %d\n", failed);
- printf("Success rate: %0.1f%\n",
(100.0 * (float)passed) / (float)(passed + failed));
failed = check_print_summary();
munmap(blob, size);
diff --git a/tools/cab/cab.h b/tools/cab/cab.h index 4512757..464ac45 100644 --- a/tools/cab/cab.h +++ b/tools/cab/cab.h @@ -13,157 +13,8 @@
*/
-#include <stdint.h> -#include <string.h>
-#include <sys/queue.h>
- /* VERSION a.b.c = <ACPI standard>.<functionality changes>.<bug fixes> */ const char VERSION[] = { "5.0~3.1" }; const char PROGNAME[] = { "cab" };
-#define PASS 1 -#define FAIL 0 -#define INFO (-1)
-#define BLOB_HEADER_SIZE 8 -#define BLOB_MAGIC "ACPI" -#define BLOB_MAGIC_SIZE 4 -#define MAX_LINE 1024 -#define MIN_TABLE_LENGTH 36 -#define NOT_REQUIRED 0 -#define REQUIRED 1 -#define RSDP_LEN_OFFSET 20 -#define SIG_LENGTH 4 -#define TABLE_LEN_OFFSET 4
-#define SIG_APIC "APIC" -#define SIG_BERT "BERT" -#define SIG_CPEP "CPEP" -#define SIG_DSDT "DSDT" -#define SIG_ECDT "ECDT" -#define SIG_EINJ "EINJ" -#define SIG_ERST "ERST" -#define SIG_FACP "FACP" -#define SIG_FACS "FACS" -#define SIG_FPDT "FPDT" -#define SIG_GTDT "GTDT" -#define SIG_HEST "HEST" -#define SIG_MCFG "MCFG" -#define SIG_MCHI "MCHI" -#define SIG_MPST "MPST" -#define SIG_MSCT "MSCT" -#define SIG_OEM "OEM" -#define SIG_PCCT "PCCT" -#define SIG_PMTT "PMTT" -#define SIG_RASF "RASF" -#define SIG_RSDP "RSD PTR" -#define SIG_RSDT "RSDT" -#define SIG_SLIT "SLIT" -#define SIG_SPMI "SPMI" -#define SIG_SRAT "SRAT" -#define SIG_SSDT "SSDT" -#define SIG_UEFI "UEFI" -#define SIG_XSDT "XSDT"
-struct known_table_info {
- char *signature; /* table signature */
- int min_revision; /* minimum allowed revision */
-};
-struct known_table_info known_info[] = {
- { SIG_APIC, 3 },
- { SIG_BERT, 1 },
- { SIG_CPEP, 1 },
- { SIG_DSDT, 2 },
- { SIG_ECDT, 1 },
- { SIG_EINJ, 1 },
- { SIG_ERST, 1 },
- { SIG_FACP, 5 },
- { SIG_FACS, 5 },
- { SIG_FPDT, 1 },
- { SIG_GTDT, 1 },
- { SIG_HEST, 1 },
- { SIG_MCFG, 1 },
- { SIG_MCHI, 1 },
- { SIG_MPST, 1 },
- { SIG_MSCT, 1 },
- { SIG_OEM, 1 },
- { SIG_PMTT, 1 },
- { SIG_RASF, 1 },
- { SIG_RSDP, 2 },
- { SIG_RSDT, 1 },
- { SIG_SLIT, 1 },
- { SIG_SPMI, 1 },
- { SIG_SRAT, 3 },
- { SIG_SSDT, 2 },
- { SIG_UEFI, 1 },
- { SIG_XSDT, 1 },
- { NULL, 0 }
-};
-char *known_sigs[] = {
- "APIC",
- "BERT",
- "CPEP",
- "DSDT",
- "ECDT",
- "EINJ",
- "ERST",
- "FACP",
- "FACS",
- "FPDT",
- "GTDT",
- "HEST",
- "MCFG",
- "MCHI",
- "MPST",
- "MSCT",
- "OEM",
- "PCCT",
- "PMTT",
- "RASF",
- "RSD PTR",
- "SLIT",
- "SPMI",
- "SRAT",
- "SSDT",
- "UEFI",
- "XSDT",
- NULL
-};
-LIST_HEAD(table_head, table) thead; -struct table_head *theadp;
-struct table {
- char *signature; /* an ACPI table name/signature */
- int len; /* reported table length */
- int offset; /* location in the blob */
- uint64_t paddr; /* where it should live in RAM */
- int ref_cnt; /* reference count */
- LIST_ENTRY(table) tables;
-};
-struct table *build_table_entry(unsigned char *buf); -void check_blob_header(unsigned char *blob); -void check_fadt_relocs(unsigned char *blob, int size, uint64_t paddr); -void check_first_table_is_rsdp(unsigned char *blob); -void check_rsdp(unsigned char *blob); -void check_ref_cnts(void); -void check_relocations(unsigned char *blob, int size, uint64_t paddr); -void check_rsdp_relocs(unsigned char *blob, int size, uint64_t paddr); -void check_table_header(char *name, unsigned char *loc); -void check_xsdt_relocs(unsigned char *blob, int size, uint64_t paddr); -void find_all_tables(unsigned char *blob, int size, int base_addr); -struct known_table_info *find_known_table_info(char *sig); -struct table *find_table(char *sig); -int get_file_size(char *fname); -void usage(void); -int valid_sig(char *sig); -int verify_checksum(unsigned char *start, int offset, int len); -int verify_revision(unsigned char *r, int min); -void presult(int res, char *topic);
- #endif
diff --git a/tools/common/Makefile b/tools/common/Makefile new file mode 100644 index 0000000..03d9388 --- /dev/null +++ b/tools/common/Makefile @@ -0,0 +1,4 @@ +SOURCES = $(wildcard *.c)
+clean :
- -rm -f $(patsubst %.c,%.o, $(SOURCES))
diff --git a/tools/common/build_aml.c b/tools/common/build_aml.c new file mode 100644 index 0000000..ebfcdc4 --- /dev/null +++ b/tools/common/build_aml.c @@ -0,0 +1,455 @@ +/*
- build_aml.c: helper functions for the tool to Make A Blob of ACPI tables
- This file is subject to the terms and conditions of the GNU General
- Public License. See the file "COPYING" in the main directory of this
- archive for more details.
- Copyright (c) 2013, Al Stone al.stone@linaro.org
- NB: all values are assumed to be little-endian in the blob.
- */
+#include <build_aml.h>
+char *known_sigs[] = {
- "apic",
- "bert",
- "cpep",
- "dsdt",
- "ecdt",
- "einj",
- "erst",
- "facp",
- "facs",
- "fpdt",
- "gtdt",
- "hest",
- "mcfg",
- "mchi",
- "mpst",
- "msct",
- "oem",
- "pcct",
- "pmtt",
- "rasf",
- "rsdp",
- "slit",
- "spmi",
- "srat",
- "ssdt",
- "uefi",
- "xsdt",
- NULL
+};
+int get_file_size(char *fname) +{
- struct stat buf;
- int err;
- err = stat(fname, &buf);
- if (err)
printf("? cannot stat %s (%d)\n", fname, err);
- return (err == 0 ? buf.st_size : 0);
+}
+int valid_sig(char *sig) +{
- char **p;
- p = known_sigs;
- while (*p != NULL) {
if (strcmp(*p, sig) == 0)
return 1;
p++;
- }
- return 0;
+}
+struct table *build_table_entry(char *dir, char *buf) +{
- struct table *tmp;
- char sig[MAX_LINE];
- char fname[MAX_LINE];
- int ii, n;
- char *p;
- tmp = (struct table *)malloc(sizeof(struct table));
- if (tmp != NULL) {
memset(tmp, 0, sizeof(struct table));
memset(sig, 0, MAX_LINE);
memset(fname, 0, MAX_LINE);
/* parse the line */
n = 0;
for (ii = 0; ii < strlen(buf); ii++) {
if (buf[ii] == ':' || isspace(buf[ii]))
break;
sig[n++] = buf[ii];
}
if (!valid_sig((unsigned char*)sig)) {
free(tmp);
return NULL;
}
while (buf[ii] == ':' || isspace(buf[ii]))
ii++;
n = 0;
for (; ii < strlen(buf); ii++) {
if (buf[ii] == '\n' || !isascii(buf[ii]))
break;
fname[n++] = buf[ii];
}
/* fill in the struct */
tmp->signature = (char *)malloc(strlen(sig) + 1);
memset(tmp->signature, 0, strlen(sig) + 1);
memcpy(tmp->signature, sig, strlen(sig));
n = strlen(fname) + strlen(dir) + 2;
tmp->asl_name = (char *)malloc(n);
memset(tmp->asl_name, 0, n);
strcpy(tmp->asl_name, dir);
strcat(tmp->asl_name, "/");
strcat(tmp->asl_name, fname);
tmp->aml_name = (char *)malloc(n);
memset(tmp->aml_name, 0, n);
strcpy(tmp->aml_name, tmp->asl_name);
p = strrchr(tmp->aml_name, '.');
if (p)
strcpy(p, ".aml");
tmp->file_size = -1; /* need to build .aml file first */
tmp->offset = -1;
- }
- return tmp;
+}
+int read_manifest(char *dir, char *fname) +{
- FILE *fp;
- struct table *p;
- char line[MAX_LINE];
- char *tmp;
- char buf[MAX_LINE];
- memset(buf, 0, MAX_LINE);
- strcpy(buf, dir);
- strcat(buf, "/");
- strcat(buf, fname);
- fp = fopen(buf, "r");
- if (!fp)
return -ENOENT;
- LIST_INIT(&thead);
- memset(line, 0, MAX_LINE);
- tmp = fgets(line, MAX_LINE, fp);
- while (tmp != NULL) {
if (strlen(line) > 0 && line[0] != '#' && line[0] != '\n') {
p = build_table_entry(dir, line);
if (p)
LIST_INSERT_HEAD(&thead, p, tables);
}
memset(line, 0, MAX_LINE);
tmp = fgets(line, MAX_LINE, fp);
- }
- fclose(fp);
- return 0;
+}
+void set_blob_header(unsigned char *blob, int blob_size) +{
- uint32_t *psize;
- /* the resulting blob contents are always little-endian */
- memcpy(blob, BLOB_MAGIC, BLOB_MAGIC_SIZE);
- psize = (uint32_t *)(blob + BLOB_MAGIC_SIZE);
- *psize = (uint32_t)(htobe32(blob_size));
+}
+struct table *find_table(char *sig) +{
- struct table *np;
- LIST_FOREACH(np, &thead, tables) {
if (strcmp(np->signature, sig) == 0)
return np;
- }
- return NULL;
+}
+void write_table(unsigned char *blob, struct table *tp, int offset) +{
- unsigned char *start;
- FILE *fp;
- tp->offset = offset;
- start = blob + offset;
- fp = fopen(tp->aml_name, "r");
- if (fp) {
fread(start, 1, tp->file_size, fp);
fclose(fp);
- }
+}
+void write_blob(char *dir, char *fname, unsigned char *blob, int size) +{
- FILE *fp;
- char newname[MAX_LINE];
- memset(newname, 0, MAX_LINE);
- strcpy(newname, dir);
- strcat(newname, "/");
- strcat(newname, fname);
- fp = fopen(newname, "w+");
- if (fp) {
fwrite(blob, 1, size, fp);
fclose(fp);
- } else {
printf("? could not open the blob file: %s\n", newname);
- }
+}
+void set_checksum(unsigned char *start, int len, uint8_t *cksum) +{
- uint8_t newsum, oldsum;
- uint8_t *p;
- newsum = 0;
- for (p = (uint8_t *)start; p < (uint8_t *)(start + len); p++)
newsum += *p;
- oldsum = *cksum;
- newsum = (uint8_t)(newsum - oldsum);
- *cksum = (uint8_t)(0 - newsum);
+}
+int add_table(unsigned char **blob, char *table_name, int offset, int reqd) +{
- struct table *p;
- int new_offset;
- int adjustment = 0;
- p = find_table(table_name);
- new_offset = offset + p->file_size;
- /*
* Handle crossing of page boundaries to prevent problems
* on armv7 with small page sizes
*/
- if ((new_offset / PAGE_SIZE) != (offset / PAGE_SIZE)) {
adjustment = PAGE_SIZE - (offset % PAGE_SIZE);
/*
* If this is the first page crossing remove the
* blob header from calculations
*/
if (!(offset / PAGE_SIZE))
adjustment -= BLOB_HEADER_SIZE;
- }
- if (p) {
*blob = realloc(*blob, offset + adjustment + p->file_size);
write_table(*blob, p, offset + adjustment);
p->offset = offset + adjustment;
- } else {
if (reqd) {
printf("? %s table is required\n", table_name);
return 0;
}
- }
- /* NB: ACPI table size cannot be zero -- there must be a header */
- return p->file_size + adjustment;
+}
+void fixup_rsdp(unsigned char *blob, uint64_t paddr) +{
- /* We could use the 32-bit RSDT address but that has
* essentially been deprecated. Instead, use the 64-bit
* XSDT address though be sure to use little-endian values.
*/
- const int RSDP_FIRST_CHECKSUM_BYTES = 20;
- const int RSDP_FIRST_CHECKSUM_OFFSET = 8;
- const int RSDP_SECOND_CHECKSUM_BYTES = 36;
- const int RSDP_SECOND_CHECKSUM_OFFSET = 32;
- const int RSDT_ADDR_OFFSET = 16;
- const int XSDT_ADDR_OFFSET = 24;
- uint8_t *pcksum;
- uint32_t *stmp;
- uint64_t *ltmp;
- struct table *rsdpp;
- struct table *p;
- /* NB: there are no safety checks on the find_table()
* return value because if we've gotten this far and
* the RSDP doesn't exist, something else has gone
* seriously wrong far earlier.
*/
- rsdpp = find_table("rsdp");
- stmp = (uint32_t *)(blob + rsdpp->offset + RSDT_ADDR_OFFSET);
- ltmp = (uint64_t *)(blob + rsdpp->offset + XSDT_ADDR_OFFSET);
- p = find_table("xsdt");
- if (p)
*ltmp = p->offset + paddr;
- else
*ltmp = (uint64_t)0;
- p = find_table("rsdt");
- if (p)
*stmp = p->offset + paddr;
- else
*stmp = (uint64_t)0;
- /* always reset the checksum, even if it is seldom used */
- pcksum = (uint8_t *)(blob + rsdpp->offset + RSDP_FIRST_CHECKSUM_OFFSET);
- set_checksum((unsigned char *)(blob + rsdpp->offset),
RSDP_FIRST_CHECKSUM_BYTES, pcksum);
- pcksum = (uint8_t *)
(blob + rsdpp->offset + RSDP_SECOND_CHECKSUM_OFFSET);
- set_checksum((unsigned char *)(blob + rsdpp->offset),
RSDP_SECOND_CHECKSUM_BYTES, pcksum);
+}
+void fixup_facp(unsigned char *blob, int *offset, uint64_t paddr, int facs64) +{
- const int DSDT_ADDR_OFFSET = 40;
- const int FACP_CHECKSUM_OFFSET = 9;
- const int FIRMWARE_CTRL_OFFSET = 36;
- const int X_DSDT_ADDR_OFFSET = 140;
- const int X_FIRMWARE_CTRL_OFFSET = 132;
- struct table *facpp;
- struct table *p;
- uint32_t *stmp;
- uint64_t *ltmp;
- uint8_t *pcksum;
- facpp = find_table("facp");
- /* add in the DSDT and X_DSDT addresses */
- stmp = (uint32_t *)(blob + facpp->offset + DSDT_ADDR_OFFSET);
- ltmp = (uint64_t *)(blob + facpp->offset + X_DSDT_ADDR_OFFSET);
- p = find_table("dsdt");
- if (p) {
if (facs64) {
*stmp = (uint32_t)0;
*ltmp = (uint64_t)p->offset + paddr;
} else {
*stmp = (uint32_t)p->offset + paddr;
*ltmp = (uint64_t)0;
}
- } else {
*stmp = (uint32_t)0;
*ltmp = (uint64_t)0;
return;
- }
- /* add in the FIRMWARE_CTRL and X_FIRMWARE_CTRL addresses */
- stmp = (uint32_t *)(blob + facpp->offset + FIRMWARE_CTRL_OFFSET);
- ltmp = (uint64_t *)(blob + facpp->offset + X_FIRMWARE_CTRL_OFFSET);
- p = find_table("facs");
- if (p) {
if (facs64) {
*stmp = (uint32_t)0;
*ltmp = (uint64_t)p->offset + paddr;
} else {
*stmp = (uint32_t)p->offset + paddr;
*ltmp = (uint64_t)0;
}
- } else {
*stmp = (uint32_t)0;
*ltmp = (uint64_t)0;
return;
- }
- /* always reset the checksum, even if it is seldom used */
- pcksum = (uint8_t *)(blob + facpp->offset + FACP_CHECKSUM_OFFSET);
- set_checksum((unsigned char *)(blob + facpp->offset),
facpp->file_size, pcksum);
+}
+void fixup_xsdt(unsigned char **blob, int *offset, uint64_t paddr) +{
- const int FACP_ADDR_OFFSET = 36;
- const int XSDT_CHECKSUM_OFFSET = 9;
- const int XSDT_HEADER_SIZE = 36;
- struct table *xsdtp;
- struct table *p;
- uint64_t *tmp;
- uint8_t *pcksum;
- int delta;
- int allowed;
- xsdtp = find_table("xsdt");
- tmp = (uint64_t *)(*blob + xsdtp->offset + FACP_ADDR_OFFSET);
- allowed = (xsdtp->file_size - XSDT_HEADER_SIZE) / sizeof(uint64_t);
- /* first table must be FACP (aka FADT) */
- p = find_table("facp");
- if (p)
*tmp = p->offset + paddr;
- else {
*tmp = (uint64_t)0;
return;
- }
- /* any tables not already in use go here */
- allowed--;
- tmp++;
- LIST_FOREACH(p, &thead, tables) {
if (p->offset < 0) {
if ((unsigned long long)tmp <
(unsigned long long)
(xsdtp + xsdtp->file_size)) {
delta = add_table(blob, p->signature,
*offset, NOT_REQUIRED);
*offset += delta;
*tmp++ = p->offset + paddr;
allowed--;
if (allowed < 1)
break;
}
}
- }
- /* always reset the checksum, even if it is seldom used */
- pcksum = (uint8_t *)(*blob + xsdtp->offset + XSDT_CHECKSUM_OFFSET);
- set_checksum((unsigned char *)(*blob + xsdtp->offset),
xsdtp->file_size, pcksum);
+}
+void build_aml(int q, char *dir, char *iasl_cmd, struct table *tp) +{
- char cmd[MAX_LINE];
- struct stat mbuf;
- struct stat sbuf;
- if (!tp)
return;
- if ((stat(tp->aml_name, &mbuf) == 0) &&
(stat(tp->asl_name, &sbuf) == 0)) {
if (mbuf.st_mtime > sbuf.st_mtime)
return; /* AML file is newer than ASL file */
- }
- strcpy(cmd, iasl_cmd);
- strcat(cmd, " ");
- strcat(cmd, tp->asl_name);
- if (q)
strcat(cmd, " >/dev/null 2&1");
- system(cmd);
+} diff --git a/tools/common/check_aml.c b/tools/common/check_aml.c new file mode 100644 index 0000000..ac47aa6 --- /dev/null +++ b/tools/common/check_aml.c @@ -0,0 +1,512 @@ +/*
- cab.c: helper functions for the tool to Check A Blob of ACPI tables
Wrong file name in the comment.
- This file is subject to the terms and conditions of the GNU General
- Public License. See the file "COPYING" in the main directory of this
- archive for more details.
- Copyright (c) 2013, Al Stone al.stone@linaro.org
- NB: all values are assumed to be little-endian in the blob.
- */
+#include <build_aml.h> +#include <check_aml.h>
+int passed; +int failed;
+struct known_table_info known_info[] = {
- { SIG_APIC, 3 },
- { SIG_BERT, 1 },
- { SIG_CPEP, 1 },
- { SIG_DSDT, 2 },
- { SIG_ECDT, 1 },
- { SIG_EINJ, 1 },
- { SIG_ERST, 1 },
- { SIG_FACP, 5 },
- { SIG_FACS, 5 },
- { SIG_FPDT, 1 },
- { SIG_GTDT, 1 },
- { SIG_HEST, 1 },
- { SIG_MCFG, 1 },
- { SIG_MCHI, 1 },
- { SIG_MPST, 1 },
- { SIG_MSCT, 1 },
- { SIG_OEM, 1 },
- { SIG_PMTT, 1 },
- { SIG_RASF, 1 },
- { SIG_RSDP, 2 },
- { SIG_RSDT, 1 },
- { SIG_SLIT, 1 },
- { SIG_SPMI, 1 },
- { SIG_SRAT, 3 },
- { SIG_SSDT, 2 },
- { SIG_UEFI, 1 },
- { SIG_XSDT, 1 },
- { NULL, 0 }
+};
+struct table *check_table_entry(unsigned char *buf) +{
- struct table *tmp;
- const int RSDP_NUDGE = 3;
- int len;
- tmp = (struct table *)malloc(sizeof(struct table));
- if (tmp != NULL) {
memset(tmp, 0, sizeof(struct table));
/* fill in the struct */
len = SIG_LENGTH + 1;
if (strncmp((char *)buf, SIG_RSDP, SIG_LENGTH + RSDP_NUDGE) == 0)
len += RSDP_NUDGE;
tmp->signature = (char *)malloc(len);
memset(tmp->signature, 0, len);
memcpy(tmp->signature, buf, len - 1);
LIST_INSERT_HEAD(&thead, tmp, tables);
- }
- return tmp;
+}
+struct known_table_info *find_known_table_info(char *sig) +{
- struct known_table_info *np;
- for (np = known_info; np->signature != NULL; np++) {
if (strncmp(np->signature, sig, strlen(np->signature)) == 0)
return np;
- }
- return NULL;
+}
+int verify_checksum(unsigned char *start, int offset, int len) +{
- uint8_t newsum, oldsum;
- uint8_t *p;
- uint8_t old_cksum, cksum;
- old_cksum = start[offset];
- cksum = old_cksum;
- newsum = 0;
- for (p = (uint8_t *)start; p < (uint8_t *)(start + len); p++)
newsum += *p;
- oldsum = cksum;
- newsum = (uint8_t)(newsum - oldsum);
- cksum = (uint8_t)(0 - newsum);
- return (old_cksum == cksum ? PASS : FAIL);
+}
+int verify_revision(unsigned char *r, int min) +{
- return (*(uint8_t *)r >= min ? PASS : FAIL);
+}
+void check_blob_header(unsigned char *blob) +{
- int res;
- printf("\nchecking blob header...\n");
- res = strncmp((char *)blob, BLOB_MAGIC, BLOB_MAGIC_SIZE);
- res = (res == 0 ? PASS : FAIL);
- presult(res, "blob magic number is correct");
+}
+void check_table_header(char *name, unsigned char *loc) +{
- const int CHECKSUM_OFFSET = 9;
- const int CREATOR_ID_OFFSET = 28;
- const int CREATOR_REV_OFFSET = 32;
- const int OEMID_OFFSET = 10;
- const int OEMID_LEN = 6;
- const int REVISION_OFFSET = 8;
- struct known_table_info *kp;
- char buf[MAX_LINE];
- int res;
- uint32_t len;
- /* valid signature? */
- kp = find_known_table_info(name);
- res = (kp ? PASS : FAIL);
- memset(buf, 0, MAX_LINE);
- sprintf(buf, "%s: signature is correct", name);
- presult(res, buf);
- if (!kp) {
printf("? %s is an unknown table\n", name);
return;
- }
- /* possibly usable length? */
- len = *(uint32_t *)(loc + TABLE_LEN_OFFSET);
- res = PASS;
- if ((len <= 0) || (len < MIN_TABLE_LENGTH))
res = FAIL;
- memset(buf, 0, MAX_LINE);
- sprintf(buf, "%s: table length is reasonable (%d)", name, len);
- presult(res, buf);
- /* valid checksum? */
- res = verify_checksum(loc, CHECKSUM_OFFSET, len);
- memset(buf, 0, MAX_LINE);
- sprintf(buf, "%s: checksum is correct", name);
- presult(res, buf);
- /* valid revision number? */
- res = verify_revision(loc + REVISION_OFFSET, kp->min_revision);
- memset(buf, 0, MAX_LINE);
- sprintf(buf, "%s: minimum revision is correct", name);
- presult(res, buf);
- /* non-empty OEMID field? */
- res = (loc[OEMID_OFFSET] != 0 ? PASS : FAIL);
- memset(buf, 0, MAX_LINE);
- sprintf(buf, "%s: there is an OEMID (", name);
- strncat(buf, (char *)(loc + OEMID_OFFSET), OEMID_LEN);
- strncat(buf, ")", 1);
- presult(res, buf);
- /* non-empty CreatorID field? */
- res = (loc[CREATOR_ID_OFFSET] != 0 ? PASS : FAIL);
- memset(buf, 0, MAX_LINE);
- sprintf(buf, "%s: there is a CreatorID", name);
- presult(res, buf);
- /* non-empty CreatorRevision field? */
- res = (loc[CREATOR_REV_OFFSET] != 0 ? PASS : FAIL);
- memset(buf, 0, MAX_LINE);
- sprintf(buf, "%s: there is a CreatorRevision", name);
- presult(res, buf);
+}
+void check_first_table_is_rsdp(unsigned char *blob) +{
- int res;
- res = strncmp((char *)blob + BLOB_HEADER_SIZE, SIG_RSDP, strlen(SIG_RSDP));
- res = (res == 0 ? PASS : FAIL);
- presult(res, "first table has RSDP signature");
+}
+void check_rsdp(unsigned char *blob) +{
- const int RSDP_FIRST_CKSUM_OFFSET = 8;
- const int RSDP_FIRST_CKSUM_LEN = 20;
- const int RSDP_SECOND_CKSUM_OFFSET = 32;
- const int RSDP_SECOND_CKSUM_LEN = 36;
- const int RSDP_RSDT_ADDR_OFFSET = 16;
- unsigned char *ptr;
- int res;
- uint32_t rsdt_addr;
- ptr = blob + BLOB_HEADER_SIZE;
- printf("\nchecking RSDP...\n");
- check_first_table_is_rsdp(blob);
- res = verify_checksum(ptr, RSDP_FIRST_CKSUM_OFFSET,
RSDP_FIRST_CKSUM_LEN);
- presult(res, "first RSDP checksum verified");
- res = verify_checksum(ptr, RSDP_SECOND_CKSUM_OFFSET,
RSDP_SECOND_CKSUM_LEN);
- presult(res, "second RSDP checksum verified");
- rsdt_addr = *(uint32_t *)(ptr + RSDP_RSDT_ADDR_OFFSET);
- res = (rsdt_addr == 0) ? PASS : FAIL;
- presult(res, "RSDT address is null");
+}
+void find_all_tables(unsigned char *blob, int size, int base_addr) +{
- struct table *tp;
- unsigned char *p;
- int offset;
- int delta;
- /* this assumes that all signatures and lengths are correct */
- printf("\nscanning for tables...\n");
- p = blob + BLOB_HEADER_SIZE;
- offset = (int)(p - blob);
- while (offset + SIG_LENGTH < size) {
if (valid_sig(p)) {
tp = check_table_entry(p);
if (tp) {
delta = TABLE_LEN_OFFSET;
if (strcmp(tp->signature, SIG_RSDP) == 0)
delta = RSDP_LEN_OFFSET;
tp->len = *(uint32_t *)(p + delta);
tp->offset = offset;
tp->paddr = base_addr + offset;
offset += *(uint32_t *)(p + delta);
p += tp->len;
} else {
printf("? no room for building a table\n");
exit(1);
}
} else {
/* skip forward until we find something; a table
* could have been moved to the next page boundary */
while (offset + SIG_LENGTH < size) {
p++;
offset++;
if (isalpha(*p) && valid_sig(p))
break;
}
}
- }
+}
+void check_rsdp_relocs(unsigned char *blob, int size, uint64_t paddr) +{
- const int RSDT_ADDR_OFFSET = 16;
- const int XSDT_ADDR_OFFSET = 24;
- struct table *np, *xp;
- int res;
- uint32_t rsdt_addr;
- uint64_t xsdt_addr;
- printf("\nchecking RSDP relocations...\n");
- res = FAIL;
- np = find_table(SIG_RSDP);
- if (np) {
np->ref_cnt++;
rsdt_addr = *(uint32_t *)(blob + np->offset + RSDT_ADDR_OFFSET);
res = (rsdt_addr == 0) ? PASS : FAIL;
presult(res, "RSDP has null RSDT pointer");
xsdt_addr = *(uint32_t *)(blob + np->offset + XSDT_ADDR_OFFSET);
xp = find_table(SIG_XSDT);
if (xp) {
xp->ref_cnt++;
if ((xsdt_addr == xp->paddr) &&
(strncmp((char *)blob + xp->offset, SIG_XSDT,
strlen(xp->signature)) == 0))
res = PASS;
}
presult(res, "RSDP has correct XSDT pointer");
- } else {
res = FAIL;
presult(res, "RSDP has null RSDT pointer");
presult(res, "RSDP has correct XSDT pointer");
- }
+}
+void check_xsdt_relocs(unsigned char *blob, int size, uint64_t paddr) +{
- const int XSDT_ENTRY_START = 36;
- const int XSDT_ENTRY_SIZE = 8;
- struct table *np, *xp;
- int res;
- int cnt;
- int ii;
- int offset;
- uint32_t len;
- uint64_t *tpaddr;
- char buf[MAX_LINE];
- printf("\nchecking XSDT relocations...\n");
- res = FAIL;
- np = find_table(SIG_XSDT);
- if (np) {
len = *(uint32_t *)(blob + np->offset + TABLE_LEN_OFFSET);
cnt = (len - XSDT_ENTRY_START) / XSDT_ENTRY_SIZE;
tpaddr = (uint64_t *)(blob + np->offset + XSDT_ENTRY_START);
if (len < 1) {
printf("? XSDT can not have an empty list\n");
exit(1);
}
/* first entry needs to be the FACP (aka FADT) */
offset = (*tpaddr - paddr);
if (strncmp((char *)blob + offset, SIG_FACP, strlen(SIG_FACP)) == 0)
res = PASS;
presult(res, "first XSDT entry points to the FADT (aka FACP)");
/* verify all the relocations, best we can */
for (ii = 0; ii < cnt; ii++, tpaddr++) {
offset = (*tpaddr - paddr);
res = FAIL;
if (valid_sig((unsigned char *)blob + offset)) {
xp = find_table((char *)blob + offset);
if (xp) {
xp->ref_cnt++;
if ((*tpaddr == xp->paddr) &&
(strncmp((char *)blob + xp->offset,
(char *)blob + offset,
strlen(xp->signature)) == 0))
res = PASS;
memset(buf, 0, MAX_LINE);
sprintf(buf,
"XSDT has correct %s pointer",
xp->signature);
presult(res, buf);
} else {
memset(buf, 0, MAX_LINE);
sprintf(buf,
"XSDT entry %d does not point to a valid table",
ii);
presult(res, buf);
}
}
}
- } else {
printf("? XSDT can not be found in table list\n");
exit(1);
- }
+}
+void check_fadt_relocs(unsigned char *blob, int size, uint64_t paddr) +{
- const int FWCTL_OFFSET = 36;
- const int DSDT_OFFSET = 40;
- const int XFWCTL_OFFSET = 132;
- const int XDSDT_OFFSET = 140;
- struct table *np, *xp;
- uint32_t fwctl, dsdt;
- uint64_t xfwctl, xdsdt;
- uint64_t tpaddr;
- int res;
- int offset;
- printf("\nchecking FADT relocations...\n");
- np = find_table(SIG_FACP);
- if (np) {
fwctl = *(uint32_t *)(blob + np->offset + FWCTL_OFFSET);
xfwctl = *(uint64_t *)(blob + np->offset + XFWCTL_OFFSET);
res = FAIL;
if ((fwctl == 0 && xfwctl == 0) || /* no FACS is okay */
(fwctl == 0 && xfwctl != 0) ||
(fwctl != 0 && xfwctl == 0))
res = PASS;
presult(res, "FADT has a proper 32-bit FACS pointer");
presult(res, "FADT has a proper 64-bit FACS pointer");
if (fwctl != 0 && xfwctl != 0)
presult(INFO,
"both fields have been set, not just one");
if (fwctl != 0 || xfwctl != 0) {
tpaddr = (fwctl == 0) ? xfwctl : fwctl;
offset = tpaddr - paddr;
xp = find_table(SIG_FACS);
if (xp) {
xp->ref_cnt++;
res = FAIL;
if ((tpaddr == xp->paddr) &&
(strncmp((char *)blob + xp->offset,
(char *)blob + offset,
strlen(xp->signature)) == 0))
res = PASS;
presult(res, "FADT has correct FACS pointer");
} else {
printf("? FADT refers to an FACS but ");
printf("there is no such table\n");
exit(1);
}
}
dsdt = *(uint32_t *)(blob + np->offset + DSDT_OFFSET);
xdsdt = *(uint64_t *)(blob + np->offset + XDSDT_OFFSET);
res = FAIL;
if ((dsdt == 0 && xdsdt != 0) || /* must have a DSDT */
(dsdt != 0 && xdsdt == 0))
res = PASS;
presult(res, "FADT has a proper 32-bit DSDT pointer");
presult(res, "FADT has a proper 64-bit DSDT pointer");
if (dsdt != 0 && xdsdt != 0)
presult(INFO,
"both fields have been set, not just one");
if (dsdt != 0 || xdsdt != 0) {
tpaddr = (dsdt == 0) ? xdsdt : dsdt;
offset = tpaddr - paddr;
xp = find_table(SIG_DSDT);
if (xp) {
xp->ref_cnt++;
res = FAIL;
if ((tpaddr == xp->paddr) &&
(strncmp((char *)blob + xp->offset,
(char *)blob + offset,
strlen(xp->signature)) == 0))
res = PASS;
presult(res, "FADT has correct DSDT pointer");
} else {
printf("? FADT refers to a DSDT but ");
printf("there is no such table\n");
exit(1);
}
}
- } else {
printf("? FADT (aka FACP) can not be found in table list\n");
exit(1);
- }
+}
+void check_ref_cnts(void) +{
- struct table *np;
- int res;
- char buf[MAX_LINE];
- printf("\nchecking references to tables...\n");
- LIST_FOREACH(np, &thead, tables) {
memset(buf, 0, MAX_LINE);
sprintf(buf, "%s referenced only once", np->signature);
res = (np->ref_cnt == 1) ? PASS : FAIL;
presult(res, buf);
- }
+}
+void check_relocations(unsigned char *blob, int size, uint64_t paddr) +{
- check_rsdp_relocs(blob, size, paddr);
- check_xsdt_relocs(blob, size, paddr);
- check_fadt_relocs(blob, size, paddr);
- check_ref_cnts();
+}
+void presult(int res, char *topic) +{
- if (res != 0)
passed++;
- else
failed++;
- if (res >= 0)
printf("[%4s] %s\n", (res != 0) ? "PASS" : "FAIL", topic);
- else
printf("[%4s] %s\n", "INFO", topic);
+}
+int check_print_summary(void) +{
- check_print_summary();
- printf("\nTotal tests: %d\n", passed + failed);
- printf("Passed: %d\n", passed);
- printf("Failed: %d\n", failed);
- printf("Success rate: %0.1f%\n",
(100.0 * (float)passed) / (float)(passed + failed));
- return failed;
+} diff --git a/tools/common/include/build_aml.h b/tools/common/include/build_aml.h new file mode 100644 index 0000000..91334d7 --- /dev/null +++ b/tools/common/include/build_aml.h @@ -0,0 +1,74 @@ +/*
- mab.h: tool to Make A Blob of ACPI tables
Wrong file name in the comment.
- This file is subject to the terms and conditions of the GNU General
- Public License. See the file "COPYING" in the main directory of this
- archive for more details.
- Copyright (c) 2013, Al Stone al.stone@linaro.org
- NB: all values are assumed to be little-endian in the blob.
- */
+#ifndef COMMON_H_ +#define COMMON_H_
+#include <ctype.h> +#include <endian.h> +#include <errno.h> +#include <libgen.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h>
+#include <sys/queue.h> +#include <sys/types.h> +#include <sys/stat.h>
+#define BLOB_HEADER_SIZE 8 +#define BLOB_MAGIC "ACPI" +#define BLOB_MAGIC_SIZE 4 +#define MAX_LINE 1024 +#define NOT_REQUIRED 0 +#define REQUIRED 1 +#define SIG_LENGTH 4
+LIST_HEAD(table_head, table) thead; +struct table_head *theadp;
+struct table {
- char *signature; /* an ACPI table name/signature */
- char *asl_name; /* ASL file name */
- char *aml_name; /* corresponding AML name */
- int file_size; /* aka table size */
- int offset; /* location in the blob */
- int len; /* reported table length */
- uint64_t paddr; /* where it should live in RAM */
- int ref_cnt; /* reference count */
- LIST_ENTRY(table) tables;
+};
+int add_table(unsigned char **blob, char *table_name, int offset, int reqd); +void build_aml(int q, char *dir, char *iasl_cmd, struct table *tp); +struct table *build_table_entry(char *dir, char *buf); +struct table *find_table(char *sig); +int get_file_size(char *fname); +int read_manifest(char *dir, char *fname); +void set_blob_header(unsigned char *blob, int blob_size); +void set_checksum(unsigned char *start, int len, uint8_t *cksum); +void write_blob(char *dir, char *fname, unsigned char *blob, int size); +void write_table(unsigned char *blob, struct table *tp, int offset); +int valid_sig(char *sig);
+void fixup_facp(unsigned char *blob, int *offset, unsigned long paddr,
int facs64);
+void fixup_rsdp(unsigned char *blob, unsigned long paddr); +void fixup_xsdt(unsigned char **blob, int *offset, unsigned long paddr);
+/* Currently a hack to avoid issues on 4k pages on armv7 */ +#define PAGE_SIZE 0x1000
+#endif /* COMMON_H_ */ diff --git a/tools/common/include/check_aml.h b/tools/common/include/check_aml.h new file mode 100644 index 0000000..69e4ae8 --- /dev/null +++ b/tools/common/include/check_aml.h @@ -0,0 +1,99 @@ +/*
- cab.h: tool to Check A Blob of ACPI tables
Wrong file name in the comment.
- This file is subject to the terms and conditions of the GNU General
- Public License. See the file "COPYING" in the main directory of this
- archive for more details.
- Copyright (c) 2013, Al Stone al.stone@linaro.org
- NB: all values are assumed to be little-endian in the blob.
- */
+#ifndef CHECK_AML_H_ +#define CHECK_AML_H_
+#include <sys/queue.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h>
+#include <ctype.h> +#include <endian.h> +#include <errno.h> +#include <fcntl.h> +#include <libgen.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h>
+#define PASS 1 +#define FAIL 0 +#define INFO (-1)
+#define BLOB_HEADER_SIZE 8 +#define BLOB_MAGIC "ACPI" +#define BLOB_MAGIC_SIZE 4 +#define MAX_LINE 1024 +#define MIN_TABLE_LENGTH 36 +#define NOT_REQUIRED 0 +#define REQUIRED 1 +#define RSDP_LEN_OFFSET 20 +#define SIG_LENGTH 4 +#define TABLE_LEN_OFFSET 4
+#define SIG_APIC "APIC" +#define SIG_BERT "BERT" +#define SIG_CPEP "CPEP" +#define SIG_DSDT "DSDT" +#define SIG_ECDT "ECDT" +#define SIG_EINJ "EINJ" +#define SIG_ERST "ERST" +#define SIG_FACP "FACP" +#define SIG_FACS "FACS" +#define SIG_FPDT "FPDT" +#define SIG_GTDT "GTDT" +#define SIG_HEST "HEST" +#define SIG_MCFG "MCFG" +#define SIG_MCHI "MCHI" +#define SIG_MPST "MPST" +#define SIG_MSCT "MSCT" +#define SIG_OEM "OEM" +#define SIG_PCCT "PCCT" +#define SIG_PMTT "PMTT" +#define SIG_RASF "RASF" +#define SIG_RSDP "RSD PTR" +#define SIG_RSDT "RSDT" +#define SIG_SLIT "SLIT" +#define SIG_SPMI "SPMI" +#define SIG_SRAT "SRAT" +#define SIG_SSDT "SSDT" +#define SIG_UEFI "UEFI" +#define SIG_XSDT "XSDT"
+struct known_table_info {
- char *signature; /* table signature */
- int min_revision; /* minimum allowed revision */
+};
+struct table *check_table_entry(unsigned char *buf); +void check_blob_header(unsigned char *blob); +void check_fadt_relocs(unsigned char *blob, int size, uint64_t paddr); +void check_first_table_is_rsdp(unsigned char *blob); +void check_rsdp(unsigned char *blob); +void check_ref_cnts(void); +void check_relocations(unsigned char *blob, int size, uint64_t paddr); +void check_rsdp_relocs(unsigned char *blob, int size, uint64_t paddr); +void check_table_header(char *name, unsigned char *loc); +void check_xsdt_relocs(unsigned char *blob, int size, uint64_t paddr); +int check_print_summary(void); +void presult(int res, char *topic); +void find_all_tables(unsigned char *blob, int size, int base_addr); +struct known_table_info *find_known_table_info(char *sig); +int verify_checksum(unsigned char *start, int offset, int len); +int verify_revision(unsigned char *r, int min);
+#endif /* CHECK_AML_H_ */ diff --git a/tools/mab/Makefile b/tools/mab/Makefile index 0627202..ec0f0bb 100644 --- a/tools/mab/Makefile +++ b/tools/mab/Makefile @@ -1,8 +1,13 @@ -CFLAGS := -g +CFLAGS := -g -Wall -I../common/include
-mab : mab.h mab.c
- $(CC) $(CFLAGS) -o mab mab.c
+HEADERS = $(wildcard *.h) $(wildcard ../common/include/*.h)
+SOURCES = $(wildcard *.c) $(wildcard ../common/*.c)
+$(PROG) : $(patsubst %.c,%.o, $(SOURCES)) $(HEADERS)
$(CC) $(CFLAGS) $(patsubst %.c,%.o, $(SOURCES)) -o $@
clean :
- -rm mab
- -rm -f $(patsubst %.c,%.o, $(wildcard *.c)) $(PROG)
diff --git a/tools/mab/mab.c b/tools/mab/mab.c index 2ca11fc..060ba72 100644 --- a/tools/mab/mab.c +++ b/tools/mab/mab.c @@ -11,24 +11,11 @@
*/
-#include "mab.h"
-#include <ctype.h> -#include <endian.h> -#include <errno.h> -#include <libgen.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h>
-#include <sys/queue.h> -#include <sys/types.h> -#include <sys/stat.h> +#include <build_aml.h>
+#include "mab.h"
-void usage(void) +static void usage(void) { printf("%s %s\n", PROGNAME, VERSION); printf("usage: %s -d <dir> -o <blob> -i <manifest> ", PROGNAME); @@ -45,417 +32,6 @@ void usage(void) printf(" -H => if given, do NOT add a blob header\n"); }
-int get_file_size(char *fname) -{
- struct stat buf;
- int err;
- err = stat(fname, &buf);
- if (err)
printf("? cannot stat %s (%d)\n", fname, err);
- return (err == 0 ? buf.st_size : 0);
-}
-int valid_sig(char *sig) -{
- char **p;
- p = known_sigs;
- while (*p != NULL) {
if (strcmp(*p, sig) == 0)
return 1;
p++;
- }
- return 0;
-}
-struct table *build_table_entry(char *dir, char *buf) -{
- struct table *tmp;
- char sig[MAX_LINE];
- char fname[MAX_LINE];
- int ii, n;
- char *p;
- tmp = (struct table *)malloc(sizeof(struct table));
- if (tmp != NULL) {
memset(tmp, 0, sizeof(struct table));
memset(sig, 0, MAX_LINE);
memset(fname, 0, MAX_LINE);
/* parse the line */
n = 0;
for (ii = 0; ii < strlen(buf); ii++) {
if (buf[ii] == ':' || isspace(buf[ii]))
break;
sig[n++] = buf[ii];
}
if (!valid_sig(sig)) {
free(tmp);
return NULL;
}
while (buf[ii] == ':' || isspace(buf[ii]))
ii++;
n = 0;
for (; ii < strlen(buf); ii++) {
if (buf[ii] == '\n' || !isascii(buf[ii]))
break;
fname[n++] = buf[ii];
}
/* fill in the struct */
tmp->signature = (char *)malloc(strlen(sig) + 1);
memset(tmp->signature, 0, strlen(sig) + 1);
memcpy(tmp->signature, sig, strlen(sig));
n = strlen(fname) + strlen(dir) + 2;
tmp->asl_name = (char *)malloc(n);
memset(tmp->asl_name, 0, n);
strcpy(tmp->asl_name, dir);
strcat(tmp->asl_name, "/");
strcat(tmp->asl_name, fname);
tmp->aml_name = (char *)malloc(n);
memset(tmp->aml_name, 0, n);
strcpy(tmp->aml_name, tmp->asl_name);
p = strrchr(tmp->aml_name, '.');
if (p)
strcpy(p, ".aml");
tmp->file_size = -1; /* need to build .aml file first */
tmp->offset = -1;
- }
- return tmp;
-}
-int read_manifest(char *dir, char *fname) -{
- FILE *fp;
- struct table *p;
- char line[MAX_LINE];
- char *tmp;
- char buf[MAX_LINE];
- memset(buf, 0, MAX_LINE);
- strcpy(buf, dir);
- strcat(buf, "/");
- strcat(buf, fname);
- fp = fopen(buf, "r");
- if (!fp)
return -ENOENT;
- LIST_INIT(&thead);
- memset(line, 0, MAX_LINE);
- tmp = fgets(line, MAX_LINE, fp);
- while (tmp != NULL) {
if (strlen(line) > 0 && line[0] != '#' && line[0] != '\n') {
p = build_table_entry(dir, line);
if (p)
LIST_INSERT_HEAD(&thead, p, tables);
}
memset(line, 0, MAX_LINE);
tmp = fgets(line, MAX_LINE, fp);
- }
- fclose(fp);
- return 0;
-}
-void set_blob_header(unsigned char *blob, int blob_size) -{
- uint32_t *psize;
- /* the resulting blob contents are always little-endian */
- memcpy(blob, BLOB_MAGIC, BLOB_MAGIC_SIZE);
- psize = (uint32_t *)(blob + BLOB_MAGIC_SIZE);
- *psize = (uint32_t)(htobe32(blob_size));
-}
-struct table *find_table(char *sig) -{
- struct table *np;
- LIST_FOREACH(np, &thead, tables) {
if (strcmp(np->signature, sig) == 0)
return np;
- }
- return NULL;
-}
-void write_table(unsigned char *blob, struct table *tp, int offset) -{
- unsigned char *buf;
- unsigned char *start;
- FILE *fp;
- tp->offset = offset;
- start = (unsigned char *)(blob + offset);
- fp = fopen(tp->aml_name, "r");
- if (fp) {
fread(start, 1, tp->file_size, fp);
fclose(fp);
- }
-}
-void write_blob(char *dir, char *fname, unsigned char *blob, int size) -{
- FILE *fp;
- char newname[MAX_LINE];
- memset(newname, 0, MAX_LINE);
- strcpy(newname, dir);
- strcat(newname, "/");
- strcat(newname, fname);
- fp = fopen(newname, "w+");
- if (fp) {
fwrite(blob, 1, size, fp);
fclose(fp);
- } else {
printf("? could not open the blob file: %s\n", newname);
- }
-}
-void set_checksum(unsigned char *start, int len, uint8_t *cksum) -{
- uint8_t newsum, oldsum;
- uint8_t *p;
- newsum = 0;
- for (p = (uint8_t *)start; p < (uint8_t *)(start + len); p++)
newsum += *p;
- oldsum = *cksum;
- newsum = (uint8_t)(newsum - oldsum);
- *cksum = (uint8_t)(0 - newsum);
-}
-int add_table(unsigned char **blob, char *table_name, int offset, int reqd) -{
- struct table *p;
- int new_offset;
- int adjustment = 0;
- p = find_table(table_name);
- new_offset = offset + p->file_size;
- /*
* Handle crossing of page boundaries to prevent problems
* on armv7 with small page sizes
*/
- if ((new_offset / PAGE_SIZE) != (offset / PAGE_SIZE)) {
adjustment = PAGE_SIZE - (offset % PAGE_SIZE);
/*
* If this is the first page crossing remove the
* blob header from calculations
*/
if (!(offset / PAGE_SIZE))
adjustment -= BLOB_HEADER_SIZE;
- }
- if (p) {
*blob = realloc(*blob, offset + adjustment + p->file_size);
write_table(*blob, p, offset + adjustment);
p->offset = offset + adjustment;
- } else {
if (reqd) {
printf("? %s table is required\n", table_name);
return 0;
}
- }
- /* NB: ACPI table size cannot be zero -- there must be a header */
- return p->file_size + adjustment;
-}
-void fixup_rsdp(unsigned char *blob, uint64_t paddr) -{
- /* We could use the 32-bit RSDT address but that has
* essentially been deprecated. Instead, use the 64-bit
* XSDT address though be sure to use little-endian values.
*/
- const int RSDP_FIRST_CHECKSUM_BYTES = 20;
- const int RSDP_FIRST_CHECKSUM_OFFSET = 8;
- const int RSDP_SECOND_CHECKSUM_BYTES = 36;
- const int RSDP_SECOND_CHECKSUM_OFFSET = 32;
- const int RSDT_ADDR_OFFSET = 16;
- const int XSDT_ADDR_OFFSET = 24;
- uint8_t *pcksum;
- uint32_t *stmp;
- uint64_t *ltmp;
- struct table *rsdpp;
- struct table *p;
- /* NB: there are no safety checks on the find_table()
* return value because if we've gotten this far and
* the RSDP doesn't exist, something else has gone
* seriously wrong far earlier.
*/
- rsdpp = find_table("rsdp");
- stmp = (uint32_t *)(blob + rsdpp->offset + RSDT_ADDR_OFFSET);
- ltmp = (uint64_t *)(blob + rsdpp->offset + XSDT_ADDR_OFFSET);
- p = find_table("xsdt");
- if (p)
*ltmp = p->offset + paddr;
- else
*ltmp = (uint64_t)0;
- p = find_table("rsdt");
- if (p)
*stmp = p->offset + paddr;
- else
*stmp = (uint64_t)0;
- /* always reset the checksum, even if it is seldom used */
- pcksum = (uint8_t *)(blob + rsdpp->offset + RSDP_FIRST_CHECKSUM_OFFSET);
- set_checksum((unsigned char *)(blob + rsdpp->offset),
RSDP_FIRST_CHECKSUM_BYTES, pcksum);
- pcksum = (uint8_t *)
(blob + rsdpp->offset + RSDP_SECOND_CHECKSUM_OFFSET);
- set_checksum((unsigned char *)(blob + rsdpp->offset),
RSDP_SECOND_CHECKSUM_BYTES, pcksum);
-}
-void fixup_facp(unsigned char *blob, int *offset, uint64_t paddr, int facs64) -{
- const int DSDT_ADDR_OFFSET = 40;
- const int FACP_CHECKSUM_OFFSET = 9;
- const int FIRMWARE_CTRL_OFFSET = 36;
- const int X_DSDT_ADDR_OFFSET = 140;
- const int X_FIRMWARE_CTRL_OFFSET = 132;
- struct table *facpp;
- struct table *p;
- uint32_t *stmp;
- uint64_t *ltmp;
- uint8_t *pcksum;
- facpp = find_table("facp");
- /* add in the DSDT and X_DSDT addresses */
- stmp = (uint32_t *)(blob + facpp->offset + DSDT_ADDR_OFFSET);
- ltmp = (uint64_t *)(blob + facpp->offset + X_DSDT_ADDR_OFFSET);
- p = find_table("dsdt");
- if (p) {
if (facs64) {
*stmp = (uint32_t)0;
*ltmp = (uint64_t)p->offset + paddr;
} else {
*stmp = (uint32_t)p->offset + paddr;
*ltmp = (uint64_t)0;
}
- } else {
*stmp = (uint32_t)0;
*ltmp = (uint64_t)0;
return;
- }
- /* add in the FIRMWARE_CTRL and X_FIRMWARE_CTRL addresses */
- stmp = (uint32_t *)(blob + facpp->offset + FIRMWARE_CTRL_OFFSET);
- ltmp = (uint64_t *)(blob + facpp->offset + X_FIRMWARE_CTRL_OFFSET);
- p = find_table("facs");
- if (p) {
if (facs64) {
*stmp = (uint32_t)0;
*ltmp = (uint64_t)p->offset + paddr;
} else {
*stmp = (uint32_t)p->offset + paddr;
*ltmp = (uint64_t)0;
}
- } else {
*stmp = (uint32_t)0;
*ltmp = (uint64_t)0;
return;
- }
- /* always reset the checksum, even if it is seldom used */
- pcksum = (uint8_t *)(blob + facpp->offset + FACP_CHECKSUM_OFFSET);
- set_checksum((unsigned char *)(blob + facpp->offset),
facpp->file_size, pcksum);
-}
-void fixup_xsdt(unsigned char **blob, int *offset, uint64_t paddr) -{
- const int FACP_ADDR_OFFSET = 36;
- const int XSDT_CHECKSUM_OFFSET = 9;
- const int XSDT_HEADER_SIZE = 36;
- struct table *xsdtp;
- struct table *p;
- uint64_t *tmp;
- uint8_t *pcksum;
- int delta;
- int allowed;
- xsdtp = find_table("xsdt");
- tmp = (uint64_t *)(*blob + xsdtp->offset + FACP_ADDR_OFFSET);
- allowed = (xsdtp->file_size - XSDT_HEADER_SIZE) / sizeof(uint64_t);
- /* first table must be FACP (aka FADT) */
- p = find_table("facp");
- if (p)
*tmp = p->offset + paddr;
- else {
*tmp = (uint64_t)0;
return;
- }
- /* any tables not already in use go here */
- allowed--;
- tmp++;
- LIST_FOREACH(p, &thead, tables) {
if (p->offset < 0) {
if ((unsigned long long)tmp <
(unsigned long long)
(xsdtp + xsdtp->file_size)) {
delta = add_table(blob, p->signature,
*offset, NOT_REQUIRED);
*offset += delta;
*tmp++ = p->offset + paddr;
allowed--;
if (allowed < 1)
break;
}
}
- }
- /* always reset the checksum, even if it is seldom used */
- pcksum = (uint8_t *)(*blob + xsdtp->offset + XSDT_CHECKSUM_OFFSET);
- set_checksum((unsigned char *)(*blob + xsdtp->offset),
xsdtp->file_size, pcksum);
-}
-void build_aml(int q, char *dir, char *iasl_cmd, struct table *tp) -{
- char cmd[MAX_LINE];
- struct stat mbuf;
- struct stat sbuf;
- if (!tp)
return;
- if ((stat(tp->aml_name, &mbuf) == 0) &&
(stat(tp->asl_name, &sbuf) == 0)) {
if (mbuf.st_mtime > sbuf.st_mtime)
return; /* AML file is newer than ASL file */
- }
- strcpy(cmd, iasl_cmd);
- strcat(cmd, " ");
- strcat(cmd, tp->asl_name);
- if (q)
strcat(cmd, " >/dev/null 2&1");
- system(cmd);
-}
- int main(int argc, char *argv[]) { int err = 0;
diff --git a/tools/mab/mab.h b/tools/mab/mab.h index 15fb441..64bfbee 100644 --- a/tools/mab/mab.h +++ b/tools/mab/mab.h @@ -13,85 +13,8 @@
*/
-#include <stdint.h> -#include <string.h>
-#include <sys/queue.h>
-#define BLOB_HEADER_SIZE 8 -#define BLOB_MAGIC "ACPI" -#define BLOB_MAGIC_SIZE 4 -#define MAX_LINE 1024 -#define NOT_REQUIRED 0 -#define REQUIRED 1 -#define SIG_LENGTH 4
- /* VERSION a.b.c = <public release>.<functionality changes>.<bug fixes> */ const char VERSION[] = { "0.28.1" }; const char PROGNAME[] = { "mab" };
-char *known_sigs[] = {
- "apic",
- "bert",
- "cpep",
- "dsdt",
- "ecdt",
- "einj",
- "erst",
- "facp",
- "facs",
- "fpdt",
- "gtdt",
- "hest",
- "mcfg",
- "mchi",
- "mpst",
- "msct",
- "oem",
- "pcct",
- "pmtt",
- "rasf",
- "rsdp",
- "slit",
- "spmi",
- "srat",
- "ssdt",
- "uefi",
- "xsdt",
- NULL
-};
-LIST_HEAD(table_head, table) thead; -struct table_head *theadp;
-struct table {
- char *signature; /* an ACPI table name/signature */
- char *asl_name; /* ASL file name */
- char *aml_name; /* corresponding AML name */
- int file_size; /* aka table size */
- int offset; /* location in the blob */
- LIST_ENTRY(table) tables;
-};
-int add_table(unsigned char **blob, char *table_name, int offset, int reqd); -void build_aml(int q, char *dir, char *iasl_cmd, struct table *tp); -struct table *build_table_entry(char *dir, char *buf); -struct table *find_table(char *sig); -int get_file_size(char *fname); -int read_manifest(char *dir, char *fname); -void set_blob_header(unsigned char *blob, int blob_size); -void set_checksum(unsigned char *start, int len, uint8_t *cksum); -void write_blob(char *dir, char *fname, unsigned char *blob, int size); -void write_table(unsigned char *blob, struct table *tp, int offset); -void usage(void); -int valid_sig(char *sig);
-void fixup_facp(unsigned char *blob, int *offset, unsigned long paddr,
int facs64);
-void fixup_rsdp(unsigned char *blob, unsigned long paddr); -void fixup_xsdt(unsigned char **blob, int *offset, unsigned long paddr);
-/* Currently a hack to avoid issues on 4k pages on armv7 */ -#define PAGE_SIZE 0x1000
- #endif
After these changes, I'm also getting a bunch of compiler warnings that I had not seen before:
make PADDR=0x42010000 exynos5250-arndale.acpi make -C tools/mab/ PROG=mab make[1]: Entering directory `/srv/figaro/acpi-asl/tools/mab' cc -g -Wall -I../common/include -c -o mab.o mab.c mab.c: In function ‘main’: mab.c:115:4: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘uint64_t’ [-Wformat=] printf("relocating blob to 0x%llx\n", paddr); ^ mab.c:198:11: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 4 has type ‘uint64_t’ [-Wformat=] np->offset + paddr); ^ cc -g -Wall -I../common/include -c -o ../common/check_aml.o ../common/check_aml.c ../common/check_aml.c: In function ‘find_all_tables’: ../common/check_aml.c:241:3: warning: pointer targets in passing argument 1 of ‘valid_sig’ differ in signedness [-Wpointer-sign] if (valid_sig(p)) { ^ In file included from ../common/check_aml.c:14:0: ../common/include/build_aml.h:64:5: note: expected ‘char *’ but argument is of type ‘unsigned char *’ int valid_sig(char *sig); ^ ../common/check_aml.c:263:5: warning: pointer targets in passing argument 1 of ‘valid_sig’ differ in signedness [-Wpointer-sign] if (isalpha(*p) && valid_sig(p)) ^ In file included from ../common/check_aml.c:14:0: ../common/include/build_aml.h:64:5: note: expected ‘char *’ but argument is of type ‘unsigned char *’ int valid_sig(char *sig); ^ ../common/check_aml.c: In function ‘check_xsdt_relocs’: ../common/check_aml.c:345:4: warning: pointer targets in passing argument 1 of ‘valid_sig’ differ in signedness [-Wpointer-sign] if (valid_sig((unsigned char *)blob + offset)) { ^ In file included from ../common/check_aml.c:14:0: ../common/include/build_aml.h:64:5: note: expected ‘char *’ but argument is of type ‘unsigned char *’ int valid_sig(char *sig); ^ ../common/check_aml.c: In function ‘check_print_summary’: ../common/check_aml.c:509:9: warning: unknown conversion type character 0xa in format [-Wformat=] (100.0 * (float)passed) / (float)(passed + failed)); ^ cc -g -Wall -I../common/include -c -o ../common/build_aml.o ../common/build_aml.c ../common/build_aml.c: In function ‘build_table_entry’: ../common/build_aml.c:92:3: warning: pointer targets in passing argument 1 of ‘valid_sig’ differ in signedness [-Wpointer-sign] if (!valid_sig((unsigned char*)sig)) { ^ ../common/build_aml.c:58:5: note: expected ‘char *’ but argument is of type ‘unsigned char *’ int valid_sig(char *sig) ^ cc -g -Wall -I../common/include mab.o ../common/check_aml.o ../common/build_aml.o -o mab make[1]: Leaving directory `/srv/figaro/acpi-asl/tools/mab' make -C tools/cab/ PROG=cab make[1]: Entering directory `/srv/figaro/acpi-asl/tools/cab' cc -g -Wall -I../common/include -c -o cab.o cab.c cab.c: In function ‘main’: cab.c:81:4: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘uint64_t’ [-Wformat=] printf("assume blob was relocated to 0x%llx\n", paddr); ^ cab.c:118:8: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 6 has type ‘uint64_t’ [-Wformat=] ii, np->signature, np->len, np->offset, np->paddr); ^ cc -g -Wall -I../common/include cab.o ../common/check_aml.o ../common/build_aml.o -o cab make[1]: Leaving directory `/srv/figaro/acpi-asl/tools/cab' make -C tools/bfapei/ PROG=bfapei make[1]: Entering directory `/srv/figaro/acpi-asl/tools/bfapei' cc -g -Wall -I../common/include -c -o bfapei.o bfapei.c bfapei.c: In function ‘bfapei_einj’: bfapei.c:132:27: warning: variable ‘mem_err’ set but not used [-Wunused-but-set-variable] struct cper_sec_mem_err *mem_err; ^ bfapei.c: In function ‘main’: bfapei.c:263:2: warning: pointer targets in passing argument 3 of ‘write_blob’ differ in signedness [-Wpointer-sign] write_blob(homedir, apei_blob_name, buf, size); ^ In file included from bfapei.c:28:0: ../common/include/build_aml.h:62:6: note: expected ‘unsigned char *’ but argument is of type ‘char *’ void write_blob(char *dir, char *fname, unsigned char *blob, int size); ^ bfapei.c:267:3: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘uint64_t’ [-Wformat=] printf("Physical address: 0x%llx\n", paddr); ^ cc -g -Wall -I../common/include bfapei.o ../common/check_aml.o ../common/build_aml.o -o bfapei make[1]: Leaving directory `/srv/figaro/acpi-asl/tools/bfapei'