diff options
author | Len Brown <len.brown@intel.com> | 2012-09-22 22:43:08 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2012-09-22 22:43:08 -0400 |
commit | 4f1004207ed67903c60ed6476da0cc571b19a220 (patch) | |
tree | 42880b00bb0fd2deda69ed109ece1484f059e0b9 /tools/power | |
parent | 0efea7b6b2ac2a6e7d7b223a6c70299099285103 (diff) |
tools/power/acpi/acpidump: version 20060606
This is unchanged version 20060606, plus a small bit in
DEFINE_ALTERNATE_TYPES to enable building with latest kernel headers.
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'tools/power')
-rw-r--r-- | tools/power/acpi/acpidump.c | 97 |
1 files changed, 59 insertions, 38 deletions
diff --git a/tools/power/acpi/acpidump.c b/tools/power/acpi/acpidump.c index 3f0a9da6df9f..3bb8e820ba43 100644 --- a/tools/power/acpi/acpidump.c +++ b/tools/power/acpi/acpidump.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * (c) Alexey Starikovskiy, Intel, 2005. | 2 | * (c) Alexey Starikovskiy, Intel, 2005-2006. |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
@@ -77,16 +77,16 @@ static inline u8 checksum(u8 * buffer, u32 length) | |||
77 | } | 77 | } |
78 | 78 | ||
79 | static unsigned long psz, addr, length; | 79 | static unsigned long psz, addr, length; |
80 | static int print, connect; | 80 | static int print, connect, skip; |
81 | static u8 select_sig[4]; | 81 | static u8 select_sig[4]; |
82 | 82 | ||
83 | static unsigned long read_efi_systab( void ) | 83 | static unsigned long read_efi_systab( void ) |
84 | { | 84 | { |
85 | char buffer[80]; | ||
86 | unsigned long addr; | ||
85 | FILE *f = fopen("/sys/firmware/efi/systab", "r"); | 87 | FILE *f = fopen("/sys/firmware/efi/systab", "r"); |
86 | if (f) { | 88 | if (f) { |
87 | char buffer[80]; | ||
88 | while (fgets(buffer, 80, f)) { | 89 | while (fgets(buffer, 80, f)) { |
89 | unsigned long addr; | ||
90 | if (sscanf(buffer, "ACPI20=0x%lx", &addr) == 1) | 90 | if (sscanf(buffer, "ACPI20=0x%lx", &addr) == 1) |
91 | return addr; | 91 | return addr; |
92 | } | 92 | } |
@@ -97,13 +97,15 @@ static unsigned long read_efi_systab( void ) | |||
97 | 97 | ||
98 | static u8 *acpi_map_memory(unsigned long where, unsigned length) | 98 | static u8 *acpi_map_memory(unsigned long where, unsigned length) |
99 | { | 99 | { |
100 | unsigned long offset; | ||
101 | u8 *there; | ||
100 | int fd = open("/dev/mem", O_RDONLY); | 102 | int fd = open("/dev/mem", O_RDONLY); |
101 | if (fd < 0) { | 103 | if (fd < 0) { |
102 | fprintf(stderr, "acpi_os_map_memory: cannot open /dev/mem\n"); | 104 | fprintf(stderr, "acpi_os_map_memory: cannot open /dev/mem\n"); |
103 | exit(1); | 105 | exit(1); |
104 | } | 106 | } |
105 | unsigned long offset = where % psz; | 107 | offset = where % psz; |
106 | u8 *there = mmap(NULL, length + offset, PROT_READ, MAP_PRIVATE, | 108 | there = mmap(NULL, length + offset, PROT_READ, MAP_PRIVATE, |
107 | fd, where - offset); | 109 | fd, where - offset); |
108 | close(fd); | 110 | close(fd); |
109 | if (there == MAP_FAILED) return 0; | 111 | if (there == MAP_FAILED) return 0; |
@@ -118,10 +120,11 @@ static void acpi_unmap_memory(u8 * there, unsigned length) | |||
118 | 120 | ||
119 | static struct acpi_table_header *acpi_map_table(unsigned long where, char *sig) | 121 | static struct acpi_table_header *acpi_map_table(unsigned long where, char *sig) |
120 | { | 122 | { |
123 | unsigned size; | ||
121 | struct acpi_table_header *tbl = (struct acpi_table_header *) | 124 | struct acpi_table_header *tbl = (struct acpi_table_header *) |
122 | acpi_map_memory(where, sizeof(struct acpi_table_header)); | 125 | acpi_map_memory(where, sizeof(struct acpi_table_header)); |
123 | if (!tbl || (sig && memcmp(sig, tbl->signature, 4))) return 0; | 126 | if (!tbl || (sig && memcmp(sig, tbl->signature, 4))) return 0; |
124 | unsigned size = tbl->length; | 127 | size = tbl->length; |
125 | acpi_unmap_memory((u8 *) tbl, sizeof(struct acpi_table_header)); | 128 | acpi_unmap_memory((u8 *) tbl, sizeof(struct acpi_table_header)); |
126 | return (struct acpi_table_header *)acpi_map_memory(where, size); | 129 | return (struct acpi_table_header *)acpi_map_memory(where, size); |
127 | } | 130 | } |
@@ -133,12 +136,13 @@ static void acpi_unmap_table(struct acpi_table_header *tbl) | |||
133 | 136 | ||
134 | static struct acpi_rsdp_descriptor *acpi_scan_for_rsdp(u8 *begin, u32 length) | 137 | static struct acpi_rsdp_descriptor *acpi_scan_for_rsdp(u8 *begin, u32 length) |
135 | { | 138 | { |
139 | struct acpi_rsdp_descriptor *rsdp; | ||
136 | u8 *i, *end = begin + length; | 140 | u8 *i, *end = begin + length; |
137 | /* Search from given start address for the requested length */ | 141 | /* Search from given start address for the requested length */ |
138 | for (i = begin; i < end; i += ACPI_RSDP_SCAN_STEP) { | 142 | for (i = begin; i < end; i += ACPI_RSDP_SCAN_STEP) { |
139 | /* The signature and checksum must both be correct */ | 143 | /* The signature and checksum must both be correct */ |
140 | if (memcmp((char *)i, "RSD PTR ", 8)) continue; | 144 | if (memcmp((char *)i, "RSD PTR ", 8)) continue; |
141 | struct acpi_rsdp_descriptor *rsdp = (struct acpi_rsdp_descriptor *)i; | 145 | rsdp = (struct acpi_rsdp_descriptor *)i; |
142 | /* Signature matches, check the appropriate checksum */ | 146 | /* Signature matches, check the appropriate checksum */ |
143 | if (!checksum((u8 *) rsdp, (rsdp->revision < 2) ? | 147 | if (!checksum((u8 *) rsdp, (rsdp->revision < 2) ? |
144 | ACPI_RSDP_CHECKSUM_LENGTH : | 148 | ACPI_RSDP_CHECKSUM_LENGTH : |
@@ -156,9 +160,10 @@ static struct acpi_rsdp_descriptor *acpi_scan_for_rsdp(u8 *begin, u32 length) | |||
156 | static void acpi_show_data(int fd, u8 * data, int size) | 160 | static void acpi_show_data(int fd, u8 * data, int size) |
157 | { | 161 | { |
158 | char buffer[256]; | 162 | char buffer[256]; |
163 | int len; | ||
159 | int i, remain = size; | 164 | int i, remain = size; |
160 | while (remain > 0) { | 165 | while (remain > 0) { |
161 | int len = snprintf(buffer, 256, " %04x:", size - remain); | 166 | len = snprintf(buffer, 256, " %04x:", size - remain); |
162 | for (i = 0; i < 16 && i < remain; i++) { | 167 | for (i = 0; i < 16 && i < remain; i++) { |
163 | len += | 168 | len += |
164 | snprintf(&buffer[len], 256 - len, " %02x", data[i]); | 169 | snprintf(&buffer[len], 256 - len, " %02x", data[i]); |
@@ -200,6 +205,10 @@ static void write_table(int fd, struct acpi_table_header *tbl, unsigned long add | |||
200 | write(fd, tbl, tbl->length); | 205 | write(fd, tbl, tbl->length); |
201 | } | 206 | } |
202 | } else if (!select_done && !memcmp(select_sig, tbl->signature, 4)) { | 207 | } else if (!select_done && !memcmp(select_sig, tbl->signature, 4)) { |
208 | if (skip > 0) { | ||
209 | --skip; | ||
210 | return; | ||
211 | } | ||
203 | if (print) { | 212 | if (print) { |
204 | acpi_show_table(fd, tbl, addr); | 213 | acpi_show_table(fd, tbl, addr); |
205 | } else { | 214 | } else { |
@@ -265,8 +274,10 @@ no_facs: | |||
265 | 274 | ||
266 | static int acpi_dump_SDT(int fd, struct acpi_rsdp_descriptor *rsdp) | 275 | static int acpi_dump_SDT(int fd, struct acpi_rsdp_descriptor *rsdp) |
267 | { | 276 | { |
268 | struct acpi_table_header *tbl = 0; | 277 | struct acpi_table_header *sdt, *tbl = 0; |
269 | int xsdt = 1; | 278 | int xsdt = 1, i, num; |
279 | char *offset; | ||
280 | unsigned long addr; | ||
270 | if (rsdp->revision > 1 && rsdp->xsdt_physical_address) { | 281 | if (rsdp->revision > 1 && rsdp->xsdt_physical_address) { |
271 | tbl = acpi_map_table(rsdp->xsdt_physical_address, "XSDT"); | 282 | tbl = acpi_map_table(rsdp->xsdt_physical_address, "XSDT"); |
272 | } | 283 | } |
@@ -275,17 +286,17 @@ static int acpi_dump_SDT(int fd, struct acpi_rsdp_descriptor *rsdp) | |||
275 | tbl = acpi_map_table(rsdp->rsdt_physical_address, "RSDT"); | 286 | tbl = acpi_map_table(rsdp->rsdt_physical_address, "RSDT"); |
276 | } | 287 | } |
277 | if (!tbl) return 0; | 288 | if (!tbl) return 0; |
278 | struct acpi_table_header *sdt = malloc(tbl->length); | 289 | sdt = malloc(tbl->length); |
279 | memcpy(sdt, tbl, tbl->length); | 290 | memcpy(sdt, tbl, tbl->length); |
280 | acpi_unmap_table(tbl); | 291 | acpi_unmap_table(tbl); |
281 | if (checksum((u8 *)sdt, sdt->length)) | 292 | if (checksum((u8 *)sdt, sdt->length)) |
282 | fprintf(stderr, "Wrong checksum for %s!\n", (xsdt)?"XSDT":"RSDT"); | 293 | fprintf(stderr, "Wrong checksum for %s!\n", (xsdt)?"XSDT":"RSDT"); |
283 | int i, num = (sdt->length - sizeof(struct acpi_table_header))/((xsdt)?sizeof(u64):sizeof(u32)); | 294 | num = (sdt->length - sizeof(struct acpi_table_header))/((xsdt)?sizeof(u64):sizeof(u32)); |
284 | char *offset = (char *)sdt + sizeof(struct acpi_table_header); | 295 | offset = (char *)sdt + sizeof(struct acpi_table_header); |
285 | unsigned long addr; | ||
286 | for (i = 0; i < num; ++i, offset += ((xsdt) ? sizeof(u64) : sizeof(u32))) { | 296 | for (i = 0; i < num; ++i, offset += ((xsdt) ? sizeof(u64) : sizeof(u32))) { |
287 | addr = (xsdt) ? (unsigned long)(*(u64 *)offset): | 297 | addr = (xsdt) ? (unsigned long)(*(u64 *)offset): |
288 | (unsigned long)(*(u32 *)offset); | 298 | (unsigned long)(*(u32 *)offset); |
299 | if (!addr) continue; | ||
289 | tbl = acpi_map_table(addr, 0); | 300 | tbl = acpi_map_table(addr, 0); |
290 | if (!tbl) continue; | 301 | if (!tbl) continue; |
291 | if (!memcmp(tbl->signature, FADT_SIG, 4)) { | 302 | if (!memcmp(tbl->signature, FADT_SIG, 4)) { |
@@ -330,29 +341,36 @@ static void usage(const char *progname) | |||
330 | puts("\t--binary or -b -- dump data in binary form rather than in hex-dump format"); | 341 | puts("\t--binary or -b -- dump data in binary form rather than in hex-dump format"); |
331 | puts("\t--length 0x456 or -l 0x456 -- works only with --addr, dump physical memory" | 342 | puts("\t--length 0x456 or -l 0x456 -- works only with --addr, dump physical memory" |
332 | "\n\t\tregion without trying to understand it's contents"); | 343 | "\n\t\tregion without trying to understand it's contents"); |
344 | puts("\t--skip 2 or -s 2 -- skip 2 tables of the given name and output only 3rd one"); | ||
333 | puts("\t--help or -h -- this help message"); | 345 | puts("\t--help or -h -- this help message"); |
334 | exit(0); | 346 | exit(0); |
335 | } | 347 | } |
336 | 348 | ||
349 | static struct option long_options[] = { | ||
350 | {"addr", 1, 0, 0}, | ||
351 | {"table", 1, 0, 0}, | ||
352 | {"output", 1, 0, 0}, | ||
353 | {"binary", 0, 0, 0}, | ||
354 | {"length", 1, 0, 0}, | ||
355 | {"skip", 1, 0, 0}, | ||
356 | {"help", 0, 0, 0}, | ||
357 | {0, 0, 0, 0} | ||
358 | }; | ||
337 | int main(int argc, char **argv) | 359 | int main(int argc, char **argv) |
338 | { | 360 | { |
361 | int option_index, c, fd; | ||
362 | u8 *raw; | ||
363 | struct acpi_rsdp_descriptor rsdpx, *x = 0; | ||
364 | char *filename = 0; | ||
365 | char buff[80]; | ||
339 | memset(select_sig, 0, 4); | 366 | memset(select_sig, 0, 4); |
340 | print = 1; | 367 | print = 1; |
341 | connect = 0; | 368 | connect = 0; |
342 | char *filename = 0; | ||
343 | addr = length = 0; | 369 | addr = length = 0; |
370 | skip = 0; | ||
344 | while (1) { | 371 | while (1) { |
345 | int option_index = 0; | 372 | option_index = 0; |
346 | static struct option long_options[] = { | 373 | c = getopt_long(argc, argv, "a:t:o:bl:s:h", |
347 | {"addr", 1, 0, 0}, | ||
348 | {"table", 1, 0, 0}, | ||
349 | {"output", 1, 0, 0}, | ||
350 | {"binary", 0, 0, 0}, | ||
351 | {"length", 1, 0, 0}, | ||
352 | {"help", 0, 0, 0}, | ||
353 | {0, 0, 0, 0} | ||
354 | }; | ||
355 | int c = getopt_long(argc, argv, "a:t:o:bl:h", | ||
356 | long_options, &option_index); | 374 | long_options, &option_index); |
357 | if (c == -1) | 375 | if (c == -1) |
358 | break; | 376 | break; |
@@ -376,6 +394,9 @@ int main(int argc, char **argv) | |||
376 | length = strtoul(optarg, (char **)NULL, 16); | 394 | length = strtoul(optarg, (char **)NULL, 16); |
377 | break; | 395 | break; |
378 | case 5: | 396 | case 5: |
397 | skip = strtoul(optarg, (char **)NULL, 10); | ||
398 | break; | ||
399 | case 6: | ||
379 | usage(argv[0]); | 400 | usage(argv[0]); |
380 | exit(0); | 401 | exit(0); |
381 | } | 402 | } |
@@ -395,6 +416,9 @@ int main(int argc, char **argv) | |||
395 | case 'l': | 416 | case 'l': |
396 | length = strtoul(optarg, (char **)NULL, 16); | 417 | length = strtoul(optarg, (char **)NULL, 16); |
397 | break; | 418 | break; |
419 | case 's': | ||
420 | skip = strtoul(optarg, (char **)NULL, 10); | ||
421 | break; | ||
398 | case 'h': | 422 | case 'h': |
399 | usage(argv[0]); | 423 | usage(argv[0]); |
400 | exit(0); | 424 | exit(0); |
@@ -404,20 +428,19 @@ int main(int argc, char **argv) | |||
404 | exit(0); | 428 | exit(0); |
405 | } | 429 | } |
406 | } | 430 | } |
407 | 431 | ||
408 | int fd = STDOUT_FILENO; | 432 | fd = STDOUT_FILENO; |
409 | if (filename) { | 433 | if (filename) { |
410 | fd = creat(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); | 434 | fd = creat(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); |
411 | if (fd < 0) | 435 | if (fd < 0) |
412 | return fd; | 436 | return fd; |
413 | } | 437 | } |
414 | 438 | ||
415 | if (!select_sig[0] && !print) { | 439 | if (!select_sig[0] && !print) { |
416 | connect = 1; | 440 | connect = 1; |
417 | } | 441 | } |
418 | 442 | ||
419 | psz = sysconf(_SC_PAGESIZE); | 443 | psz = sysconf(_SC_PAGESIZE); |
420 | u8 *raw; | ||
421 | if (length && addr) { | 444 | if (length && addr) { |
422 | /* We know length and address, it means we just want a memory dump */ | 445 | /* We know length and address, it means we just want a memory dump */ |
423 | if (!(raw = acpi_map_memory(addr, length))) | 446 | if (!(raw = acpi_map_memory(addr, length))) |
@@ -426,7 +449,7 @@ int main(int argc, char **argv) | |||
426 | acpi_unmap_memory(raw, length); | 449 | acpi_unmap_memory(raw, length); |
427 | return 0; | 450 | return 0; |
428 | } | 451 | } |
429 | 452 | ||
430 | length = sizeof(struct acpi_rsdp_descriptor); | 453 | length = sizeof(struct acpi_rsdp_descriptor); |
431 | if (!addr) { | 454 | if (!addr) { |
432 | addr = read_efi_systab(); | 455 | addr = read_efi_systab(); |
@@ -435,12 +458,11 @@ int main(int argc, char **argv) | |||
435 | length = ACPI_HI_RSDP_WINDOW_SIZE; | 458 | length = ACPI_HI_RSDP_WINDOW_SIZE; |
436 | } | 459 | } |
437 | } | 460 | } |
438 | 461 | ||
439 | struct acpi_rsdp_descriptor rsdpx, *x = 0; | ||
440 | if (!(raw = acpi_map_memory(addr, length)) || | 462 | if (!(raw = acpi_map_memory(addr, length)) || |
441 | !(x = acpi_scan_for_rsdp(raw, length))) | 463 | !(x = acpi_scan_for_rsdp(raw, length))) |
442 | goto not_found; | 464 | goto not_found; |
443 | 465 | ||
444 | /* Find RSDP and print all found tables */ | 466 | /* Find RSDP and print all found tables */ |
445 | memcpy(&rsdpx, x, sizeof(struct acpi_rsdp_descriptor)); | 467 | memcpy(&rsdpx, x, sizeof(struct acpi_rsdp_descriptor)); |
446 | acpi_unmap_memory(raw, length); | 468 | acpi_unmap_memory(raw, length); |
@@ -454,7 +476,6 @@ int main(int argc, char **argv) | |||
454 | write(fd, x, (rsdpx.revision < 2) ? | 476 | write(fd, x, (rsdpx.revision < 2) ? |
455 | ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH); | 477 | ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH); |
456 | } else if (!select_sig[0] || !memcmp("RSD PTR ", select_sig, 4)) { | 478 | } else if (!select_sig[0] || !memcmp("RSD PTR ", select_sig, 4)) { |
457 | char buff[80]; | ||
458 | addr += (long)x - (long)raw; | 479 | addr += (long)x - (long)raw; |
459 | length = snprintf(buff, 80, "RSD PTR @ %p\n", (void *)addr); | 480 | length = snprintf(buff, 80, "RSD PTR @ %p\n", (void *)addr); |
460 | write(fd, buff, length); | 481 | write(fd, buff, length); |