summaryrefslogtreecommitdiff
path: root/tools/power/acpi/tools/acpidump
diff options
context:
space:
mode:
Diffstat (limited to 'tools/power/acpi/tools/acpidump')
-rw-r--r--tools/power/acpi/tools/acpidump/acpidump.c559
-rw-r--r--tools/power/acpi/tools/acpidump/acpidump.h131
-rw-r--r--tools/power/acpi/tools/acpidump/apdump.c451
-rw-r--r--tools/power/acpi/tools/acpidump/apfiles.c228
-rw-r--r--tools/power/acpi/tools/acpidump/apmain.c340
5 files changed, 1150 insertions, 559 deletions
diff --git a/tools/power/acpi/tools/acpidump/acpidump.c b/tools/power/acpi/tools/acpidump/acpidump.c
deleted file mode 100644
index a84553a0e0df..000000000000
--- a/tools/power/acpi/tools/acpidump/acpidump.c
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * (c) Alexey Starikovskiy, Intel, 2005-2006.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- * substantially similar to the "NO WARRANTY" disclaimer below
- * ("Disclaimer") and any redistribution must be conditioned upon
- * including a substantially similar Disclaimer requirement for further
- * binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- * of any contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGES.
- */
-
-#ifdef DEFINE_ALTERNATE_TYPES
-/* hack to enable building old application with new headers -lenb */
-#define acpi_fadt_descriptor acpi_table_fadt
-#define acpi_rsdp_descriptor acpi_table_rsdp
-#define DSDT_SIG ACPI_SIG_DSDT
-#define FACS_SIG ACPI_SIG_FACS
-#define FADT_SIG ACPI_SIG_FADT
-#define xfirmware_ctrl Xfacs
-#define firmware_ctrl facs
-
-typedef int s32;
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-typedef unsigned long long u64;
-typedef long long s64;
-#endif
-
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <getopt.h>
-
-#include <dirent.h>
-
-#include <acpi/acconfig.h>
-#include <acpi/platform/acenv.h>
-#include <acpi/actypes.h>
-#include <acpi/actbl.h>
-
-static inline u8 checksum(u8 * buffer, u32 length)
-{
- u8 sum = 0, *i = buffer;
- buffer += length;
- for (; i < buffer; sum += *(i++));
- return sum;
-}
-
-static unsigned long psz, addr, length;
-static int print, connect, skip;
-static u8 select_sig[4];
-
-static unsigned long read_efi_systab( void )
-{
- char buffer[80];
- unsigned long addr;
- FILE *f = fopen("/sys/firmware/efi/systab", "r");
- if (f) {
- while (fgets(buffer, 80, f)) {
- if (sscanf(buffer, "ACPI20=0x%lx", &addr) == 1)
- return addr;
- }
- fclose(f);
- }
- return 0;
-}
-
-static u8 *acpi_map_memory(unsigned long where, unsigned length)
-{
- unsigned long offset;
- u8 *there;
- int fd = open("/dev/mem", O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, "acpi_os_map_memory: cannot open /dev/mem\n");
- exit(1);
- }
- offset = where % psz;
- there = mmap(NULL, length + offset, PROT_READ, MAP_PRIVATE,
- fd, where - offset);
- close(fd);
- if (there == MAP_FAILED) return 0;
- return (there + offset);
-}
-
-static void acpi_unmap_memory(u8 * there, unsigned length)
-{
- unsigned long offset = (unsigned long)there % psz;
- munmap(there - offset, length + offset);
-}
-
-static struct acpi_table_header *acpi_map_table(unsigned long where, char *sig)
-{
- unsigned size;
- struct acpi_table_header *tbl = (struct acpi_table_header *)
- acpi_map_memory(where, sizeof(struct acpi_table_header));
- if (!tbl || (sig && memcmp(sig, tbl->signature, 4))) return 0;
- size = tbl->length;
- acpi_unmap_memory((u8 *) tbl, sizeof(struct acpi_table_header));
- return (struct acpi_table_header *)acpi_map_memory(where, size);
-}
-
-static void acpi_unmap_table(struct acpi_table_header *tbl)
-{
- acpi_unmap_memory((u8 *)tbl, tbl->length);
-}
-
-static struct acpi_rsdp_descriptor *acpi_scan_for_rsdp(u8 *begin, u32 length)
-{
- struct acpi_rsdp_descriptor *rsdp;
- u8 *i, *end = begin + length;
- /* Search from given start address for the requested length */
- for (i = begin; i < end; i += ACPI_RSDP_SCAN_STEP) {
- /* The signature and checksum must both be correct */
- if (memcmp((char *)i, "RSD PTR ", 8)) continue;
- rsdp = (struct acpi_rsdp_descriptor *)i;
- /* Signature matches, check the appropriate checksum */
- if (!checksum((u8 *) rsdp, (rsdp->revision < 2) ?
- ACPI_RSDP_CHECKSUM_LENGTH :
- ACPI_RSDP_XCHECKSUM_LENGTH))
- /* Checksum valid, we have found a valid RSDP */
- return rsdp;
- }
- /* Searched entire block, no RSDP was found */
- return 0;
-}
-
-/*
- * Output data
- */
-static void acpi_show_data(int fd, u8 * data, int size)
-{
- char buffer[256];
- int len;
- int i, remain = size;
- while (remain > 0) {
- len = snprintf(buffer, 256, " %04x:", size - remain);
- for (i = 0; i < 16 && i < remain; i++) {
- len +=
- snprintf(&buffer[len], 256 - len, " %02x", data[i]);
- }
- for (; i < 16; i++) {
- len += snprintf(&buffer[len], 256 - len, " ");
- }
- len += snprintf(&buffer[len], 256 - len, " ");
- for (i = 0; i < 16 && i < remain; i++) {
- buffer[len++] = (isprint(data[i])) ? data[i] : '.';
- }
- buffer[len++] = '\n';
- write(fd, buffer, len);
- data += 16;
- remain -= 16;
- }
-}
-
-/*
- * Output ACPI table
- */
-static void acpi_show_table(int fd, struct acpi_table_header *table, unsigned long addr)
-{
- char buff[80];
- int len = snprintf(buff, 80, "%.4s @ %p\n", table->signature, (void *)addr);
- write(fd, buff, len);
- acpi_show_data(fd, (u8 *) table, table->length);
- buff[0] = '\n';
- write(fd, buff, 1);
-}
-
-static void write_table(int fd, struct acpi_table_header *tbl, unsigned long addr)
-{
- static int select_done = 0;
- if (!select_sig[0]) {
- if (print) {
- acpi_show_table(fd, tbl, addr);
- } else {
- write(fd, tbl, tbl->length);
- }
- } else if (!select_done && !memcmp(select_sig, tbl->signature, 4)) {
- if (skip > 0) {
- --skip;
- return;
- }
- if (print) {
- acpi_show_table(fd, tbl, addr);
- } else {
- write(fd, tbl, tbl->length);
- }
- select_done = 1;
- }
-}
-
-static void acpi_dump_FADT(int fd, struct acpi_table_header *tbl, unsigned long xaddr) {
- struct acpi_fadt_descriptor x;
- unsigned long addr;
- size_t len = sizeof(struct acpi_fadt_descriptor);
- if (len > tbl->length) len = tbl->length;
- memcpy(&x, tbl, len);
- x.header.length = len;
- if (checksum((u8 *)tbl, len)) {
- fprintf(stderr, "Wrong checksum for FADT!\n");
- }
- if (x.header.length >= 148 && x.Xdsdt) {
- addr = (unsigned long)x.Xdsdt;
- if (connect) {
- x.Xdsdt = lseek(fd, 0, SEEK_CUR);
- }
- } else if (x.header.length >= 44 && x.dsdt) {
- addr = (unsigned long)x.dsdt;
- if (connect) {
- x.dsdt = lseek(fd, 0, SEEK_CUR);
- }
- } else {
- fprintf(stderr, "No DSDT in FADT!\n");
- goto no_dsdt;
- }
- tbl = acpi_map_table(addr, DSDT_SIG);
- if (!tbl) goto no_dsdt;
- if (checksum((u8 *)tbl, tbl->length))
- fprintf(stderr, "Wrong checksum for DSDT!\n");
- write_table(fd, tbl, addr);
- acpi_unmap_table(tbl);
-no_dsdt:
- if (x.header.length >= 140 && x.xfirmware_ctrl) {
- addr = (unsigned long)x.xfirmware_ctrl;
- if (connect) {
- x.xfirmware_ctrl = lseek(fd, 0, SEEK_CUR);
- }
- } else if (x.header.length >= 40 && x.firmware_ctrl) {
- addr = (unsigned long)x.firmware_ctrl;
- if (connect) {
- x.firmware_ctrl = lseek(fd, 0, SEEK_CUR);
- }
- } else {
- fprintf(stderr, "No FACS in FADT!\n");
- goto no_facs;
- }
- tbl = acpi_map_table(addr, FACS_SIG);
- if (!tbl) goto no_facs;
- /* do not checksum FACS */
- write_table(fd, tbl, addr);
- acpi_unmap_table(tbl);
-no_facs:
- write_table(fd, (struct acpi_table_header *)&x, xaddr);
-}
-
-static int acpi_dump_SDT(int fd, struct acpi_rsdp_descriptor *rsdp)
-{
- struct acpi_table_header *sdt, *tbl = 0;
- int xsdt = 1, i, num;
- char *offset;
- unsigned long addr;
- if (rsdp->revision > 1 && rsdp->xsdt_physical_address) {
- tbl = acpi_map_table(rsdp->xsdt_physical_address, "XSDT");
- }
- if (!tbl && rsdp->rsdt_physical_address) {
- xsdt = 0;
- tbl = acpi_map_table(rsdp->rsdt_physical_address, "RSDT");
- }
- if (!tbl) return 0;
- sdt = malloc(tbl->length);
- memcpy(sdt, tbl, tbl->length);
- acpi_unmap_table(tbl);
- if (checksum((u8 *)sdt, sdt->length))
- fprintf(stderr, "Wrong checksum for %s!\n", (xsdt)?"XSDT":"RSDT");
- num = (sdt->length - sizeof(struct acpi_table_header))/((xsdt)?sizeof(u64):sizeof(u32));
- offset = (char *)sdt + sizeof(struct acpi_table_header);
- for (i = 0; i < num; ++i, offset += ((xsdt) ? sizeof(u64) : sizeof(u32))) {
- addr = (xsdt) ? (unsigned long)(*(u64 *)offset):
- (unsigned long)(*(u32 *)offset);
- if (!addr) continue;
- tbl = acpi_map_table(addr, 0);
- if (!tbl) continue;
- if (!memcmp(tbl->signature, FADT_SIG, 4)) {
- acpi_dump_FADT(fd, tbl, addr);
- } else {
- if (checksum((u8 *)tbl, tbl->length))
- fprintf(stderr, "Wrong checksum for generic table!\n");
- write_table(fd, tbl, addr);
- }
- acpi_unmap_table(tbl);
- if (connect) {
- if (xsdt)
- (*(u64*)offset) = lseek(fd, 0, SEEK_CUR);
- else
- (*(u32*)offset) = lseek(fd, 0, SEEK_CUR);
- }
- }
- if (xsdt) {
- addr = (unsigned long)rsdp->xsdt_physical_address;
- if (connect) {
- rsdp->xsdt_physical_address = lseek(fd, 0, SEEK_CUR);
- }
- } else {
- addr = (unsigned long)rsdp->rsdt_physical_address;
- if (connect) {
- rsdp->rsdt_physical_address = lseek(fd, 0, SEEK_CUR);
- }
- }
- write_table(fd, sdt, addr);
- free (sdt);
- return 1;
-}
-
-#define DYNAMIC_SSDT "/sys/firmware/acpi/tables/dynamic"
-
-static void acpi_dump_dynamic_SSDT(int fd)
-{
- struct stat file_stat;
- char filename[256], *ptr;
- DIR *tabledir;
- struct dirent *entry;
- FILE *fp;
- int count, readcount, length;
- struct acpi_table_header table_header, *ptable;
-
- if (stat(DYNAMIC_SSDT, &file_stat) == -1) {
- /* The directory doesn't exist */
- return;
- }
- tabledir = opendir(DYNAMIC_SSDT);
- if(!tabledir){
- /*can't open the directory */
- return;
- }
-
- while ((entry = readdir(tabledir)) != 0){
- /* skip the file of . /.. */
- if (entry->d_name[0] == '.')
- continue;
-
- sprintf(filename, "%s/%s", DYNAMIC_SSDT, entry->d_name);
- fp = fopen(filename, "r");
- if (fp == NULL) {
- fprintf(stderr, "Can't open the file of %s\n",
- filename);
- continue;
- }
- /* Read the Table header to parse the table length */
- count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp);
- if (count < sizeof(table_header)) {
- /* the length is lessn than ACPI table header. skip it */
- fclose(fp);
- continue;
- }
- length = table_header.length;
- ptr = malloc(table_header.length);
- fseek(fp, 0, SEEK_SET);
- readcount = 0;
- while(!feof(fp) && readcount < length) {
- count = fread(ptr + readcount, 1, 256, fp);
- readcount += count;
- }
- fclose(fp);
- ptable = (struct acpi_table_header *) ptr;
- if (checksum((u8 *) ptable, ptable->length))
- fprintf(stderr, "Wrong checksum "
- "for dynamic SSDT table!\n");
- write_table(fd, ptable, 0);
- free(ptr);
- }
- closedir(tabledir);
- return;
-}
-
-static void usage(const char *progname)
-{
- puts("Usage:");
- printf("%s [--addr 0x1234][--table DSDT][--output filename]"
- "[--binary][--length 0x456][--help]\n", progname);
- puts("\t--addr 0x1234 or -a 0x1234 -- look for tables at this physical address");
- puts("\t--table DSDT or -t DSDT -- only dump table with DSDT signature");
- puts("\t--output filename or -o filename -- redirect output from stdin to filename");
- puts("\t--binary or -b -- dump data in binary form rather than in hex-dump format");
- puts("\t--length 0x456 or -l 0x456 -- works only with --addr, dump physical memory"
- "\n\t\tregion without trying to understand it's contents");
- puts("\t--skip 2 or -s 2 -- skip 2 tables of the given name and output only 3rd one");
- puts("\t--help or -h -- this help message");
- exit(0);
-}
-
-static struct option long_options[] = {
- {"addr", 1, 0, 0},
- {"table", 1, 0, 0},
- {"output", 1, 0, 0},
- {"binary", 0, 0, 0},
- {"length", 1, 0, 0},
- {"skip", 1, 0, 0},
- {"help", 0, 0, 0},
- {0, 0, 0, 0}
-};
-int main(int argc, char **argv)
-{
- int option_index, c, fd;
- u8 *raw;
- struct acpi_rsdp_descriptor rsdpx, *x = 0;
- char *filename = 0;
- char buff[80];
- memset(select_sig, 0, 4);
- print = 1;
- connect = 0;
- addr = length = 0;
- skip = 0;
- while (1) {
- option_index = 0;
- c = getopt_long(argc, argv, "a:t:o:bl:s:h",
- long_options, &option_index);
- if (c == -1)
- break;
-
- switch (c) {
- case 0:
- switch (option_index) {
- case 0:
- addr = strtoul(optarg, (char **)NULL, 16);
- break;
- case 1:
- memcpy(select_sig, optarg, 4);
- break;
- case 2:
- filename = optarg;
- break;
- case 3:
- print = 0;
- break;
- case 4:
- length = strtoul(optarg, (char **)NULL, 16);
- break;
- case 5:
- skip = strtoul(optarg, (char **)NULL, 10);
- break;
- case 6:
- usage(argv[0]);
- exit(0);
- }
- break;
- case 'a':
- addr = strtoul(optarg, (char **)NULL, 16);
- break;
- case 't':
- memcpy(select_sig, optarg, 4);
- break;
- case 'o':
- filename = optarg;
- break;
- case 'b':
- print = 0;
- break;
- case 'l':
- length = strtoul(optarg, (char **)NULL, 16);
- break;
- case 's':
- skip = strtoul(optarg, (char **)NULL, 10);
- break;
- case 'h':
- usage(argv[0]);
- exit(0);
- default:
- printf("Unknown option!\n");
- usage(argv[0]);
- exit(0);
- }
- }
-
- fd = STDOUT_FILENO;
- if (filename) {
- fd = creat(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
- if (fd < 0)
- return fd;
- }
-
- if (!select_sig[0] && !print) {
- connect = 1;
- }
-
- psz = sysconf(_SC_PAGESIZE);
- if (length && addr) {
- /* We know length and address, it means we just want a memory dump */
- if (!(raw = acpi_map_memory(addr, length)))
- goto not_found;
- write(fd, raw, length);
- acpi_unmap_memory(raw, length);
- close(fd);
- return 0;
- }
-
- length = sizeof(struct acpi_rsdp_descriptor);
- if (!addr) {
- addr = read_efi_systab();
- if (!addr) {
- addr = ACPI_HI_RSDP_WINDOW_BASE;
- length = ACPI_HI_RSDP_WINDOW_SIZE;
- }
- }
-
- if (!(raw = acpi_map_memory(addr, length)) ||
- !(x = acpi_scan_for_rsdp(raw, length)))
- goto not_found;
-
- /* Find RSDP and print all found tables */
- memcpy(&rsdpx, x, sizeof(struct acpi_rsdp_descriptor));
- acpi_unmap_memory(raw, length);
- if (connect) {
- lseek(fd, sizeof(struct acpi_rsdp_descriptor), SEEK_SET);
- }
- if (!acpi_dump_SDT(fd, &rsdpx))
- goto not_found;
- if (connect) {
- lseek(fd, 0, SEEK_SET);
- write(fd, x, (rsdpx.revision < 2) ?
- ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
- } else if (!select_sig[0] || !memcmp("RSD PTR ", select_sig, 4)) {
- addr += (long)x - (long)raw;
- length = snprintf(buff, 80, "RSD PTR @ %p\n", (void *)addr);
- write(fd, buff, length);
- acpi_show_data(fd, (u8 *) & rsdpx, (rsdpx.revision < 2) ?
- ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
- buff[0] = '\n';
- write(fd, buff, 1);
- }
- acpi_dump_dynamic_SSDT(fd);
- close(fd);
- return 0;
-not_found:
- close(fd);
- fprintf(stderr, "ACPI tables were not found. If you know location "
- "of RSD PTR table (from dmesg, etc), "
- "supply it with either --addr or -a option\n");
- return 1;
-}
diff --git a/tools/power/acpi/tools/acpidump/acpidump.h b/tools/power/acpi/tools/acpidump/acpidump.h
new file mode 100644
index 000000000000..3361b9e04d9c
--- /dev/null
+++ b/tools/power/acpi/tools/acpidump/acpidump.h
@@ -0,0 +1,131 @@
+/******************************************************************************
+ *
+ * Module Name: acpidump.h - Include file for acpi_dump utility
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "actables.h"
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+/*
+ * Global variables. Defined in main.c only, externed in all other files
+ */
+#ifdef _DECLARE_GLOBALS
+#define EXTERN
+#define INIT_GLOBAL(a,b) a=b
+#else
+#define EXTERN extern
+#define INIT_GLOBAL(a,b) a
+#endif
+
+/* Globals */
+
+EXTERN u8 INIT_GLOBAL(gbl_summary_mode, FALSE);
+EXTERN u8 INIT_GLOBAL(gbl_verbose_mode, FALSE);
+EXTERN u8 INIT_GLOBAL(gbl_binary_mode, FALSE);
+EXTERN u8 INIT_GLOBAL(gbl_dump_customized_tables, FALSE);
+EXTERN FILE INIT_GLOBAL(*gbl_output_file, NULL);
+EXTERN char INIT_GLOBAL(*gbl_output_filename, NULL);
+EXTERN u64 INIT_GLOBAL(gbl_rsdp_base, 0);
+
+/* Globals required for use with ACPICA modules */
+
+#ifdef _DECLARE_GLOBALS
+u8 acpi_gbl_enable_interpreter_slack = FALSE;
+u8 acpi_gbl_integer_byte_width = 8;
+u32 acpi_dbg_level = 0;
+u32 acpi_dbg_layer = 0;
+#endif
+
+/* Action table used to defer requested options */
+
+struct ap_dump_action {
+ char *argument;
+ u32 to_be_done;
+};
+
+#define AP_MAX_ACTIONS 32
+
+#define AP_DUMP_ALL_TABLES 0
+#define AP_DUMP_TABLE_BY_ADDRESS 1
+#define AP_DUMP_TABLE_BY_NAME 2
+#define AP_DUMP_TABLE_BY_FILE 3
+
+#define AP_MAX_ACPI_FILES 256 /* Prevent infinite loops */
+
+/* Minimum FADT sizes for various table addresses */
+
+#define MIN_FADT_FOR_DSDT (ACPI_FADT_OFFSET (dsdt) + sizeof (u32))
+#define MIN_FADT_FOR_FACS (ACPI_FADT_OFFSET (facs) + sizeof (u32))
+#define MIN_FADT_FOR_XDSDT (ACPI_FADT_OFFSET (Xdsdt) + sizeof (u64))
+#define MIN_FADT_FOR_XFACS (ACPI_FADT_OFFSET (Xfacs) + sizeof (u64))
+
+/*
+ * apdump - Table get/dump routines
+ */
+int ap_dump_table_from_file(char *pathname);
+
+int ap_dump_table_by_name(char *signature);
+
+int ap_dump_table_by_address(char *ascii_address);
+
+int ap_dump_all_tables(void);
+
+u8 ap_is_valid_header(struct acpi_table_header *table);
+
+u8 ap_is_valid_checksum(struct acpi_table_header *table);
+
+u32 ap_get_table_length(struct acpi_table_header *table);
+
+/*
+ * apfiles - File I/O utilities
+ */
+int ap_open_output_file(char *pathname);
+
+int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance);
+
+struct acpi_table_header *ap_get_table_from_file(char *pathname,
+ u32 *file_size);
diff --git a/tools/power/acpi/tools/acpidump/apdump.c b/tools/power/acpi/tools/acpidump/apdump.c
new file mode 100644
index 000000000000..3cac12378366
--- /dev/null
+++ b/tools/power/acpi/tools/acpidump/apdump.c
@@ -0,0 +1,451 @@
+/******************************************************************************
+ *
+ * Module Name: apdump - Dump routines for ACPI tables (acpidump)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "acpidump.h"
+
+/* Local prototypes */
+
+static int
+ap_dump_table_buffer(struct acpi_table_header *table,
+ u32 instance, acpi_physical_address address);
+
+/******************************************************************************
+ *
+ * FUNCTION: ap_is_valid_header
+ *
+ * PARAMETERS: table - Pointer to table to be validated
+ *
+ * RETURN: TRUE if the header appears to be valid. FALSE otherwise
+ *
+ * DESCRIPTION: Check for a valid ACPI table header
+ *
+ ******************************************************************************/
+
+u8 ap_is_valid_header(struct acpi_table_header *table)
+{
+
+ if (!ACPI_VALIDATE_RSDP_SIG(table->signature)) {
+
+ /* Make sure signature is all ASCII and a valid ACPI name */
+
+ if (!acpi_ut_valid_acpi_name(table->signature)) {
+ fprintf(stderr,
+ "Table signature (0x%8.8X) is invalid\n",
+ *(u32 *)table->signature);
+ return (FALSE);
+ }
+
+ /* Check for minimum table length */
+
+ if (table->length < sizeof(struct acpi_table_header)) {
+ fprintf(stderr, "Table length (0x%8.8X) is invalid\n",
+ table->length);
+ return (FALSE);
+ }
+ }
+
+ return (TRUE);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: ap_is_valid_checksum
+ *
+ * PARAMETERS: table - Pointer to table to be validated
+ *
+ * RETURN: TRUE if the checksum appears to be valid. FALSE otherwise.
+ *
+ * DESCRIPTION: Check for a valid ACPI table checksum.
+ *
+ ******************************************************************************/
+
+u8 ap_is_valid_checksum(struct acpi_table_header *table)
+{
+ acpi_status status;
+ struct acpi_table_rsdp *rsdp;
+
+ if (ACPI_VALIDATE_RSDP_SIG(table->signature)) {
+ /*
+ * Checksum for RSDP.
+ * Note: Other checksums are computed during the table dump.
+ */
+ rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table);
+ status = acpi_tb_validate_rsdp(rsdp);
+ } else {
+ status = acpi_tb_verify_checksum(table, table->length);
+ }
+
+ if (ACPI_FAILURE(status)) {
+ fprintf(stderr, "%4.4s: Warning: wrong checksum in table\n",
+ table->signature);
+ }
+
+ return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: ap_get_table_length
+ *
+ * PARAMETERS: table - Pointer to the table
+ *
+ * RETURN: Table length
+ *
+ * DESCRIPTION: Obtain table length according to table signature.
+ *
+ ******************************************************************************/
+
+u32 ap_get_table_length(struct acpi_table_header *table)
+{
+ struct acpi_table_rsdp *rsdp;
+
+ /* Check if table is valid */
+
+ if (!ap_is_valid_header(table)) {
+ return (0);
+ }
+
+ if (ACPI_VALIDATE_RSDP_SIG(table->signature)) {
+ rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table);
+ return (rsdp->length);
+ }
+
+ /* Normal ACPI table */
+
+ return (table->length);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: ap_dump_table_buffer
+ *
+ * PARAMETERS: table - ACPI table to be dumped
+ * instance - ACPI table instance no. to be dumped
+ * address - Physical address of the table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump an ACPI table in standard ASCII hex format, with a
+ * header that is compatible with the acpi_xtract utility.
+ *
+ ******************************************************************************/
+
+static int
+ap_dump_table_buffer(struct acpi_table_header *table,
+ u32 instance, acpi_physical_address address)
+{
+ u32 table_length;
+
+ table_length = ap_get_table_length(table);
+
+ /* Print only the header if requested */
+
+ if (gbl_summary_mode) {
+ acpi_tb_print_table_header(address, table);
+ return (0);
+ }
+
+ /* Dump to binary file if requested */
+
+ if (gbl_binary_mode) {
+ return (ap_write_to_binary_file(table, instance));
+ }
+
+ /*
+ * Dump the table with header for use with acpixtract utility.
+ * Note: simplest to just always emit a 64-bit address. acpi_xtract
+ * utility can handle this.
+ */
+ printf("%4.4s @ 0x%8.8X%8.8X\n", table->signature,
+ ACPI_FORMAT_UINT64(address));
+
+ acpi_ut_dump_buffer(ACPI_CAST_PTR(u8, table), table_length,
+ DB_BYTE_DISPLAY, 0);
+ printf("\n");
+ return (0);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: ap_dump_all_tables
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get all tables from the RSDT/XSDT (or at least all of the
+ * tables that we can possibly get).
+ *
+ ******************************************************************************/
+
+int ap_dump_all_tables(void)
+{
+ struct acpi_table_header *table;
+ u32 instance = 0;
+ acpi_physical_address address;
+ acpi_status status;
+ int table_status;
+ u32 i;
+
+ /* Get and dump all available ACPI tables */
+
+ for (i = 0; i < AP_MAX_ACPI_FILES; i++) {
+ status =
+ acpi_os_get_table_by_index(i, &table, &instance, &address);
+ if (ACPI_FAILURE(status)) {
+
+ /* AE_LIMIT means that no more tables are available */
+
+ if (status == AE_LIMIT) {
+ return (0);
+ } else if (i == 0) {
+ fprintf(stderr,
+ "Could not get ACPI tables, %s\n",
+ acpi_format_exception(status));
+ return (-1);
+ } else {
+ fprintf(stderr,
+ "Could not get ACPI table at index %u, %s\n",
+ i, acpi_format_exception(status));
+ continue;
+ }
+ }
+
+ table_status = ap_dump_table_buffer(table, instance, address);
+ free(table);
+
+ if (table_status) {
+ break;
+ }
+ }
+
+ /* Something seriously bad happened if the loop terminates here */
+
+ return (-1);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: ap_dump_table_by_address
+ *
+ * PARAMETERS: ascii_address - Address for requested ACPI table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get an ACPI table via a physical address and dump it.
+ *
+ ******************************************************************************/
+
+int ap_dump_table_by_address(char *ascii_address)
+{
+ acpi_physical_address address;
+ struct acpi_table_header *table;
+ acpi_status status;
+ int table_status;
+ u64 long_address;
+
+ /* Convert argument to an integer physical address */
+
+ status = acpi_ut_strtoul64(ascii_address, 0, &long_address);
+ if (ACPI_FAILURE(status)) {
+ fprintf(stderr, "%s: Could not convert to a physical address\n",
+ ascii_address);
+ return (-1);
+ }
+
+ address = (acpi_physical_address) long_address;
+ status = acpi_os_get_table_by_address(address, &table);
+ if (ACPI_FAILURE(status)) {
+ fprintf(stderr, "Could not get table at 0x%8.8X%8.8X, %s\n",
+ ACPI_FORMAT_UINT64(address),
+ acpi_format_exception(status));
+ return (-1);
+ }
+
+ table_status = ap_dump_table_buffer(table, 0, address);
+ free(table);
+ return (table_status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: ap_dump_table_by_name
+ *
+ * PARAMETERS: signature - Requested ACPI table signature
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get an ACPI table via a signature and dump it. Handles
+ * multiple tables with the same signature (SSDTs).
+ *
+ ******************************************************************************/
+
+int ap_dump_table_by_name(char *signature)
+{
+ char local_signature[ACPI_NAME_SIZE + 1];
+ u32 instance;
+ struct acpi_table_header *table;
+ acpi_physical_address address;
+ acpi_status status;
+ int table_status;
+
+ if (strlen(signature) != ACPI_NAME_SIZE) {
+ fprintf(stderr,
+ "Invalid table signature [%s]: must be exactly 4 characters\n",
+ signature);
+ return (-1);
+ }
+
+ /* Table signatures are expected to be uppercase */
+
+ strcpy(local_signature, signature);
+ acpi_ut_strupr(local_signature);
+
+ /* To be friendly, handle tables whose signatures do not match the name */
+
+ if (ACPI_COMPARE_NAME(local_signature, "FADT")) {
+ strcpy(local_signature, ACPI_SIG_FADT);
+ } else if (ACPI_COMPARE_NAME(local_signature, "MADT")) {
+ strcpy(local_signature, ACPI_SIG_MADT);
+ }
+
+ /* Dump all instances of this signature (to handle multiple SSDTs) */
+
+ for (instance = 0; instance < AP_MAX_ACPI_FILES; instance++) {
+ status = acpi_os_get_table_by_name(local_signature, instance,
+ &table, &address);
+ if (ACPI_FAILURE(status)) {
+
+ /* AE_LIMIT means that no more tables are available */
+
+ if (status == AE_LIMIT) {
+ return (0);
+ }
+
+ fprintf(stderr,
+ "Could not get ACPI table with signature [%s], %s\n",
+ local_signature, acpi_format_exception(status));
+ return (-1);
+ }
+
+ table_status = ap_dump_table_buffer(table, instance, address);
+ free(table);
+
+ if (table_status) {
+ break;
+ }
+ }
+
+ /* Something seriously bad happened if the loop terminates here */
+
+ return (-1);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: ap_dump_table_from_file
+ *
+ * PARAMETERS: pathname - File containing the binary ACPI table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Dump an ACPI table from a binary file
+ *
+ ******************************************************************************/
+
+int ap_dump_table_from_file(char *pathname)
+{
+ struct acpi_table_header *table;
+ u32 file_size = 0;
+ int table_status = -1;
+
+ /* Get the entire ACPI table from the file */
+
+ table = ap_get_table_from_file(pathname, &file_size);
+ if (!table) {
+ return (-1);
+ }
+
+ /* File must be at least as long as the table length */
+
+ if (table->length > file_size) {
+ fprintf(stderr,
+ "Table length (0x%X) is too large for input file (0x%X) %s\n",
+ table->length, file_size, pathname);
+ goto exit;
+ }
+
+ if (gbl_verbose_mode) {
+ fprintf(stderr,
+ "Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n",
+ pathname, table->signature, file_size, file_size);
+ }
+
+ table_status = ap_dump_table_buffer(table, 0, 0);
+
+exit:
+ free(table);
+ return (table_status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_os* print functions
+ *
+ * DESCRIPTION: Used for linkage with ACPICA modules
+ *
+ ******************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ vfprintf(stdout, fmt, args);
+ va_end(args);
+}
+
+void acpi_os_vprintf(const char *fmt, va_list args)
+{
+ vfprintf(stdout, fmt, args);
+}
diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c
new file mode 100644
index 000000000000..4488accc010b
--- /dev/null
+++ b/tools/power/acpi/tools/acpidump/apfiles.c
@@ -0,0 +1,228 @@
+/******************************************************************************
+ *
+ * Module Name: apfiles - File-related functions for acpidump utility
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "acpidump.h"
+#include "acapps.h"
+
+/******************************************************************************
+ *
+ * FUNCTION: ap_open_output_file
+ *
+ * PARAMETERS: pathname - Output filename
+ *
+ * RETURN: Open file handle
+ *
+ * DESCRIPTION: Open a text output file for acpidump. Checks if file already
+ * exists.
+ *
+ ******************************************************************************/
+
+int ap_open_output_file(char *pathname)
+{
+ struct stat stat_info;
+ FILE *file;
+
+ /* If file exists, prompt for overwrite */
+
+ if (!stat(pathname, &stat_info)) {
+ fprintf(stderr,
+ "Target path already exists, overwrite? [y|n] ");
+
+ if (getchar() != 'y') {
+ return (-1);
+ }
+ }
+
+ /* Point stdout to the file */
+
+ file = freopen(pathname, "w", stdout);
+ if (!file) {
+ perror("Could not open output file");
+ return (-1);
+ }
+
+ /* Save the file and path */
+
+ gbl_output_file = file;
+ gbl_output_filename = pathname;
+ return (0);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: ap_write_to_binary_file
+ *
+ * PARAMETERS: table - ACPI table to be written
+ * instance - ACPI table instance no. to be written
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write an ACPI table to a binary file. Builds the output
+ * filename from the table signature.
+ *
+ ******************************************************************************/
+
+int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)
+{
+ char filename[ACPI_NAME_SIZE + 16];
+ char instance_str[16];
+ FILE *file;
+ size_t actual;
+ u32 table_length;
+
+ /* Obtain table length */
+
+ table_length = ap_get_table_length(table);
+
+ /* Construct lower-case filename from the table local signature */
+
+ if (ACPI_VALIDATE_RSDP_SIG(table->signature)) {
+ ACPI_MOVE_NAME(filename, ACPI_RSDP_NAME);
+ } else {
+ ACPI_MOVE_NAME(filename, table->signature);
+ }
+ filename[0] = (char)ACPI_TOLOWER(filename[0]);
+ filename[1] = (char)ACPI_TOLOWER(filename[1]);
+ filename[2] = (char)ACPI_TOLOWER(filename[2]);
+ filename[3] = (char)ACPI_TOLOWER(filename[3]);
+ filename[ACPI_NAME_SIZE] = 0;
+
+ /* Handle multiple SSDts - create different filenames for each */
+
+ if (instance > 0) {
+ sprintf(instance_str, "%u", instance);
+ strcat(filename, instance_str);
+ }
+
+ strcat(filename, ACPI_TABLE_FILE_SUFFIX);
+
+ if (gbl_verbose_mode) {
+ fprintf(stderr,
+ "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n",
+ table->signature, filename, table->length,
+ table->length);
+ }
+
+ /* Open the file and dump the entire table in binary mode */
+
+ file = fopen(filename, "wb");
+ if (!file) {
+ perror("Could not open output file");
+ return (-1);
+ }
+
+ actual = fwrite(table, 1, table_length, file);
+ if (actual != table_length) {
+ perror("Error writing binary output file");
+ fclose(file);
+ return (-1);
+ }
+
+ fclose(file);
+ return (0);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: ap_get_table_from_file
+ *
+ * PARAMETERS: pathname - File containing the binary ACPI table
+ * out_file_size - Where the file size is returned
+ *
+ * RETURN: Buffer containing the ACPI table. NULL on error.
+ *
+ * DESCRIPTION: Open a file and read it entirely into a new buffer
+ *
+ ******************************************************************************/
+
+struct acpi_table_header *ap_get_table_from_file(char *pathname,
+ u32 *out_file_size)
+{
+ struct acpi_table_header *buffer = NULL;
+ FILE *file;
+ u32 file_size;
+ size_t actual;
+
+ /* Must use binary mode */
+
+ file = fopen(pathname, "rb");
+ if (!file) {
+ perror("Could not open input file");
+ return (NULL);
+ }
+
+ /* Need file size to allocate a buffer */
+
+ file_size = cm_get_file_size(file);
+ if (file_size == ACPI_UINT32_MAX) {
+ fprintf(stderr,
+ "Could not get input file size: %s\n", pathname);
+ goto cleanup;
+ }
+
+ /* Allocate a buffer for the entire file */
+
+ buffer = calloc(1, file_size);
+ if (!buffer) {
+ fprintf(stderr,
+ "Could not allocate file buffer of size: %u\n",
+ file_size);
+ goto cleanup;
+ }
+
+ /* Read the entire file */
+
+ actual = fread(buffer, 1, file_size, file);
+ if (actual != file_size) {
+ fprintf(stderr, "Could not read input file: %s\n", pathname);
+ free(buffer);
+ buffer = NULL;
+ goto cleanup;
+ }
+
+ *out_file_size = file_size;
+
+cleanup:
+ fclose(file);
+ return (buffer);
+}
diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c
new file mode 100644
index 000000000000..70d71ec687a5
--- /dev/null
+++ b/tools/power/acpi/tools/acpidump/apmain.c
@@ -0,0 +1,340 @@
+/******************************************************************************
+ *
+ * Module Name: apmain - Main module for the acpidump utility
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#define _DECLARE_GLOBALS
+#include "acpidump.h"
+#include "acapps.h"
+
+/*
+ * acpidump - A portable utility for obtaining system ACPI tables and dumping
+ * them in an ASCII hex format suitable for binary extraction via acpixtract.
+ *
+ * Obtaining the system ACPI tables is an OS-specific operation.
+ *
+ * This utility can be ported to any host operating system by providing a
+ * module containing system-specific versions of these interfaces:
+ *
+ * acpi_os_get_table_by_address
+ * acpi_os_get_table_by_index
+ * acpi_os_get_table_by_name
+ *
+ * See the ACPICA Reference Guide for the exact definitions of these
+ * interfaces. Also, see these ACPICA source code modules for example
+ * implementations:
+ *
+ * source/os_specific/service_layers/oswintbl.c
+ * source/os_specific/service_layers/oslinuxtbl.c
+ */
+
+/* Local prototypes */
+
+static void ap_display_usage(void);
+
+static int ap_do_options(int argc, char **argv);
+
+static void ap_insert_action(char *argument, u32 to_be_done);
+
+/* Table for deferred actions from command line options */
+
+struct ap_dump_action action_table[AP_MAX_ACTIONS];
+u32 current_action = 0;
+
+#define AP_UTILITY_NAME "ACPI Binary Table Dump Utility"
+#define AP_SUPPORTED_OPTIONS "?a:bcf:hn:o:r:svz"
+
+/******************************************************************************
+ *
+ * FUNCTION: ap_display_usage
+ *
+ * DESCRIPTION: Usage message for the acpi_dump utility
+ *
+ ******************************************************************************/
+
+static void ap_display_usage(void)
+{
+
+ ACPI_USAGE_HEADER("acpidump [options]");
+
+ ACPI_OPTION("-b", "Dump tables to binary files");
+ ACPI_OPTION("-c", "Dump customized tables");
+ ACPI_OPTION("-h -?", "This help message");
+ ACPI_OPTION("-o <File>", "Redirect output to file");
+ ACPI_OPTION("-r <Address>", "Dump tables from specified RSDP");
+ ACPI_OPTION("-s", "Print table summaries only");
+ ACPI_OPTION("-v", "Display version information");
+ ACPI_OPTION("-z", "Verbose mode");
+
+ printf("\nTable Options:\n");
+
+ ACPI_OPTION("-a <Address>", "Get table via a physical address");
+ ACPI_OPTION("-f <BinaryFile>", "Get table via a binary file");
+ ACPI_OPTION("-n <Signature>", "Get table via a name/signature");
+
+ printf("\n"
+ "Invocation without parameters dumps all available tables\n"
+ "Multiple mixed instances of -a, -f, and -n are supported\n\n");
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: ap_insert_action
+ *
+ * PARAMETERS: argument - Pointer to the argument for this action
+ * to_be_done - What to do to process this action
+ *
+ * RETURN: None. Exits program if action table becomes full.
+ *
+ * DESCRIPTION: Add an action item to the action table
+ *
+ ******************************************************************************/
+
+static void ap_insert_action(char *argument, u32 to_be_done)
+{
+
+ /* Insert action and check for table overflow */
+
+ action_table[current_action].argument = argument;
+ action_table[current_action].to_be_done = to_be_done;
+
+ current_action++;
+ if (current_action > AP_MAX_ACTIONS) {
+ fprintf(stderr, "Too many table options (max %u)\n",
+ AP_MAX_ACTIONS);
+ exit(-1);
+ }
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: ap_do_options
+ *
+ * PARAMETERS: argc/argv - Standard argc/argv
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Command line option processing. The main actions for getting
+ * and dumping tables are deferred via the action table.
+ *
+ *****************************************************************************/
+
+static int ap_do_options(int argc, char **argv)
+{
+ int j;
+ acpi_status status;
+
+ /* Command line options */
+
+ while ((j = acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != EOF)
+ switch (j) {
+ /*
+ * Global options
+ */
+ case 'b': /* Dump all input tables to binary files */
+
+ gbl_binary_mode = TRUE;
+ continue;
+
+ case 'c': /* Dump customized tables */
+
+ gbl_dump_customized_tables = TRUE;
+ continue;
+
+ case 'h':
+ case '?':
+
+ ap_display_usage();
+ exit(0);
+
+ case 'o': /* Redirect output to a single file */
+
+ if (ap_open_output_file(acpi_gbl_optarg)) {
+ exit(-1);
+ }
+ continue;
+
+ case 'r': /* Dump tables from specified RSDP */
+
+ status =
+ acpi_ut_strtoul64(acpi_gbl_optarg, 0,
+ &gbl_rsdp_base);
+ if (ACPI_FAILURE(status)) {
+ fprintf(stderr,
+ "%s: Could not convert to a physical address\n",
+ acpi_gbl_optarg);
+ exit(-1);
+ }
+ continue;
+
+ case 's': /* Print table summaries only */
+
+ gbl_summary_mode = TRUE;
+ continue;
+
+ case 'v': /* Revision/version */
+
+ printf(ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
+ exit(0);
+
+ case 'z': /* Verbose mode */
+
+ gbl_verbose_mode = TRUE;
+ fprintf(stderr, ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
+ continue;
+
+ /*
+ * Table options
+ */
+ case 'a': /* Get table by physical address */
+
+ ap_insert_action(acpi_gbl_optarg,
+ AP_DUMP_TABLE_BY_ADDRESS);
+ break;
+
+ case 'f': /* Get table from a file */
+
+ ap_insert_action(acpi_gbl_optarg,
+ AP_DUMP_TABLE_BY_FILE);
+ break;
+
+ case 'n': /* Get table by input name (signature) */
+
+ ap_insert_action(acpi_gbl_optarg,
+ AP_DUMP_TABLE_BY_NAME);
+ break;
+
+ default:
+
+ ap_display_usage();
+ exit(-1);
+ }
+
+ /* If there are no actions, this means "get/dump all tables" */
+
+ if (current_action == 0) {
+ ap_insert_action(NULL, AP_DUMP_ALL_TABLES);
+ }
+
+ return (0);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: main
+ *
+ * PARAMETERS: argc/argv - Standard argc/argv
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: C main function for acpidump utility
+ *
+ ******************************************************************************/
+
+int ACPI_SYSTEM_XFACE main(int argc, char *argv[])
+{
+ int status = 0;
+ struct ap_dump_action *action;
+ u32 file_size;
+ u32 i;
+
+ ACPI_DEBUG_INITIALIZE(); /* For debug version only */
+
+ /* Process command line options */
+
+ if (ap_do_options(argc, argv)) {
+ return (-1);
+ }
+
+ /* Get/dump ACPI table(s) as requested */
+
+ for (i = 0; i < current_action; i++) {
+ action = &action_table[i];
+ switch (action->to_be_done) {
+ case AP_DUMP_ALL_TABLES:
+
+ status = ap_dump_all_tables();
+ break;
+
+ case AP_DUMP_TABLE_BY_ADDRESS:
+
+ status = ap_dump_table_by_address(action->argument);
+ break;
+
+ case AP_DUMP_TABLE_BY_NAME:
+
+ status = ap_dump_table_by_name(action->argument);
+ break;
+
+ case AP_DUMP_TABLE_BY_FILE:
+
+ status = ap_dump_table_from_file(action->argument);
+ break;
+
+ default:
+
+ fprintf(stderr,
+ "Internal error, invalid action: 0x%X\n",
+ action->to_be_done);
+ return (-1);
+ }
+
+ if (status) {
+ return (status);
+ }
+ }
+
+ if (gbl_output_file) {
+ if (gbl_verbose_mode) {
+
+ /* Summary for the output file */
+
+ file_size = cm_get_file_size(gbl_output_file);
+ fprintf(stderr,
+ "Output file %s contains 0x%X (%u) bytes\n\n",
+ gbl_output_filename, file_size, file_size);
+ }
+
+ fclose(gbl_output_file);
+ }
+
+ return (status);
+}