On Mon, Sep 09, 2013 at 09:00:57AM +0200, Tomasz Nowicki wrote:
Hi Al,
W dniu 06.09.2013 20:33, Al Stone pisze:
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.
Ohhh... yes, I will fix it here as well as wrong file name in another places...
This is the reason kernel code stopped using the file name in the comment header. It was too often forgotten on file rename.
Graeme
- 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:
It's beacause of I added -Wall compiler flag, wornings were there, compilator just wasn't showing it. I will try to eliminate wornings :)
Tomasz
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'
Linaro-acpi mailing list Linaro-acpi@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-acpi