38 #ifdef DEFINE_ALTERNATE_TYPES
40 #define acpi_fadt_descriptor acpi_table_fadt
41 #define acpi_rsdp_descriptor acpi_table_rsdp
42 #define DSDT_SIG ACPI_SIG_DSDT
43 #define FACS_SIG ACPI_SIG_FACS
44 #define FADT_SIG ACPI_SIG_FADT
45 #define xfirmware_ctrl Xfacs
46 #define firmware_ctrl facs
49 typedef unsigned char u8;
50 typedef unsigned short u16;
51 typedef unsigned int u32;
52 typedef unsigned long long u64;
53 typedef long long s64;
57 #include <sys/types.h>
81 static int print, connect,
skip;
82 static u8 select_sig[4];
84 static unsigned long read_efi_systab(
void )
88 FILE *
f = fopen(
"/sys/firmware/efi/systab",
"r");
90 while (fgets(buffer, 80, f)) {
91 if (
sscanf(buffer,
"ACPI20=0x%lx", &addr) == 1)
99 static u8 *acpi_map_memory(
unsigned long where,
unsigned length)
105 fprintf(stderr,
"acpi_os_map_memory: cannot open /dev/mem\n");
108 offset = where % psz;
112 if (there == MAP_FAILED)
return 0;
113 return (there + offset);
116 static void acpi_unmap_memory(
u8 * there,
unsigned length)
118 unsigned long offset = (
unsigned long)there % psz;
119 munmap(there - offset, length + offset);
135 acpi_unmap_memory((
u8 *)tbl, tbl->
length);
138 static struct acpi_rsdp_descriptor *acpi_scan_for_rsdp(
u8 *begin,
u32 length)
140 struct acpi_rsdp_descriptor *rsdp;
145 if (
memcmp((
char *)i,
"RSD PTR ", 8))
continue;
146 rsdp = (
struct acpi_rsdp_descriptor *)i;
148 if (!
checksum((
u8 *) rsdp, (rsdp->revision < 2) ?
161 static void acpi_show_data(
int fd,
u8 *
data,
int size)
165 int i, remain =
size;
167 len =
snprintf(buffer, 256,
" %04x:", size - remain);
168 for (i = 0; i < 16 && i < remain; i++) {
170 snprintf(&buffer[len], 256 - len,
" %02x", data[i]);
172 for (; i < 16; i++) {
173 len +=
snprintf(&buffer[len], 256 - len,
" ");
175 len +=
snprintf(&buffer[len], 256 - len,
" ");
176 for (i = 0; i < 16 && i < remain; i++) {
177 buffer[len++] = (
isprint(data[i])) ? data[i] :
'.';
179 buffer[len++] =
'\n';
180 write(fd, buffer, len);
193 write(fd, buff, len);
194 acpi_show_data(fd, (
u8 *) table, table->
length);
199 static void write_table(
int fd,
struct acpi_table_header *tbl,
unsigned long addr)
201 static int select_done = 0;
202 if (!select_sig[0]) {
204 acpi_show_table(fd, tbl, addr);
214 acpi_show_table(fd, tbl, addr);
222 static void acpi_dump_FADT(
int fd,
struct acpi_table_header *tbl,
unsigned long xaddr) {
223 struct acpi_fadt_descriptor
x;
225 size_t len =
sizeof(
struct acpi_fadt_descriptor);
228 x.header.length = len;
230 fprintf(stderr,
"Wrong checksum for FADT!\n");
232 if (
x.header.length >= 148 &&
x.Xdsdt) {
233 addr = (
unsigned long)
x.Xdsdt;
237 }
else if (
x.header.length >= 44 &&
x.dsdt) {
238 addr = (
unsigned long)
x.dsdt;
243 fprintf(stderr,
"No DSDT in FADT!\n");
246 tbl = acpi_map_table(addr, DSDT_SIG);
247 if (!tbl)
goto no_dsdt;
249 fprintf(stderr,
"Wrong checksum for DSDT!\n");
250 write_table(fd, tbl, addr);
251 acpi_unmap_table(tbl);
253 if (
x.header.length >= 140 &&
x.xfirmware_ctrl) {
254 addr = (
unsigned long)
x.xfirmware_ctrl;
256 x.xfirmware_ctrl = lseek(fd, 0,
SEEK_CUR);
258 }
else if (
x.header.length >= 40 &&
x.firmware_ctrl) {
259 addr = (
unsigned long)
x.firmware_ctrl;
261 x.firmware_ctrl = lseek(fd, 0,
SEEK_CUR);
264 fprintf(stderr,
"No FACS in FADT!\n");
267 tbl = acpi_map_table(addr, FACS_SIG);
268 if (!tbl)
goto no_facs;
270 write_table(fd, tbl, addr);
271 acpi_unmap_table(tbl);
276 static int acpi_dump_SDT(
int fd,
struct acpi_rsdp_descriptor *rsdp)
279 int xsdt = 1,
i,
num;
282 if (rsdp->revision > 1 && rsdp->xsdt_physical_address) {
283 tbl = acpi_map_table(rsdp->xsdt_physical_address,
"XSDT");
285 if (!tbl && rsdp->rsdt_physical_address) {
287 tbl = acpi_map_table(rsdp->rsdt_physical_address,
"RSDT");
292 acpi_unmap_table(tbl);
294 fprintf(stderr,
"Wrong checksum for %s!\n", (xsdt)?
"XSDT":
"RSDT");
296 offset = (char *)sdt +
sizeof(struct acpi_table_header);
297 for (i = 0; i < num; ++i, offset += ((xsdt) ? sizeof(u64) : sizeof(u32))) {
298 addr = (xsdt) ? (unsigned long)(*(u64 *)offset):
299 (unsigned long)(*(u32 *)offset);
301 tbl = acpi_map_table(addr, 0);
303 if (!memcmp(tbl->signature, FADT_SIG, 4)) {
304 acpi_dump_FADT(fd, tbl, addr);
307 fprintf(stderr,
"Wrong checksum for generic table!\n");
308 write_table(fd, tbl, addr);
310 acpi_unmap_table(tbl);
319 addr = (
unsigned long)rsdp->xsdt_physical_address;
321 rsdp->xsdt_physical_address = lseek(fd, 0,
SEEK_CUR);
324 addr = (
unsigned long)rsdp->rsdt_physical_address;
326 rsdp->rsdt_physical_address = lseek(fd, 0,
SEEK_CUR);
329 write_table(fd, sdt, addr);
334 #define DYNAMIC_SSDT "/sys/firmware/acpi/tables/dynamic"
336 static void acpi_dump_dynamic_SSDT(
int fd)
338 struct stat file_stat;
356 while ((entry = readdir(tabledir)) != 0){
358 if (entry->d_name[0] ==
'.')
362 fp = fopen(filename,
"r");
364 fprintf(stderr,
"Can't open the file of %s\n",
370 if (count <
sizeof(table_header)) {
375 length = table_header.
length;
379 while(!feof(fp) && readcount < length) {
380 count = fread(ptr + readcount, 1, 256, fp);
386 fprintf(stderr,
"Wrong checksum "
387 "for dynamic SSDT table!\n");
388 write_table(fd, ptable, 0);
395 static void usage(
const char *progname)
398 printf(
"%s [--addr 0x1234][--table DSDT][--output filename]"
399 "[--binary][--length 0x456][--help]\n", progname);
400 puts(
"\t--addr 0x1234 or -a 0x1234 -- look for tables at this physical address");
401 puts(
"\t--table DSDT or -t DSDT -- only dump table with DSDT signature");
402 puts(
"\t--output filename or -o filename -- redirect output from stdin to filename");
403 puts(
"\t--binary or -b -- dump data in binary form rather than in hex-dump format");
404 puts(
"\t--length 0x456 or -l 0x456 -- works only with --addr, dump physical memory"
405 "\n\t\tregion without trying to understand it's contents");
406 puts(
"\t--skip 2 or -s 2 -- skip 2 tables of the given name and output only 3rd one");
407 puts(
"\t--help or -h -- this help message");
411 static struct option long_options[] = {
423 int option_index,
c,
fd;
425 struct acpi_rsdp_descriptor rsdpx, *
x = 0;
435 c = getopt_long(argc, argv,
"a:t:o:bl:s:h",
436 long_options, &option_index);
442 switch (option_index) {
444 addr = strtoul(optarg, (
char **)
NULL, 16);
447 memcpy(select_sig, optarg, 4);
456 length = strtoul(optarg, (
char **)
NULL, 16);
459 skip = strtoul(optarg, (
char **)
NULL, 10);
467 addr = strtoul(optarg, (
char **)
NULL, 16);
470 memcpy(select_sig, optarg, 4);
479 length = strtoul(optarg, (
char **)
NULL, 16);
482 skip = strtoul(optarg, (
char **)
NULL, 10);
488 printf(
"Unknown option!\n");
501 if (!select_sig[0] && !print) {
505 psz = sysconf(_SC_PAGESIZE);
506 if (length && addr) {
508 if (!(raw = acpi_map_memory(addr, length)))
510 write(fd, raw, length);
511 acpi_unmap_memory(raw, length);
516 length =
sizeof(
struct acpi_rsdp_descriptor);
518 addr = read_efi_systab();
525 if (!(raw = acpi_map_memory(addr, length)) ||
526 !(x = acpi_scan_for_rsdp(raw, length)))
530 memcpy(&rsdpx, x,
sizeof(
struct acpi_rsdp_descriptor));
531 acpi_unmap_memory(raw, length);
533 lseek(fd,
sizeof(
struct acpi_rsdp_descriptor),
SEEK_SET);
535 if (!acpi_dump_SDT(fd, &rsdpx))
539 write(fd, x, (rsdpx.revision < 2) ?
541 }
else if (!select_sig[0] || !
memcmp(
"RSD PTR ", select_sig, 4)) {
543 length =
snprintf(buff, 80,
"RSD PTR @ %p\n", (
void *)addr);
544 write(fd, buff, length);
545 acpi_show_data(fd, (
u8 *) & rsdpx, (rsdpx.revision < 2) ?
550 acpi_dump_dynamic_SSDT(fd);
555 fprintf(stderr,
"ACPI tables were not found. If you know location "
556 "of RSD PTR table (from dmesg, etc), "
557 "supply it with either --addr or -a option\n");