diff options
author | Len Brown <len.brown@intel.com> | 2012-09-22 22:49:25 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2012-09-22 22:49:25 -0400 |
commit | 981efe9ab9e91e13ec75836300515428a30017df (patch) | |
tree | 185ce51b852487192db051334b68882cdd42e9ea /tools | |
parent | 4f1004207ed67903c60ed6476da0cc571b19a220 (diff) |
tools/power/acpi/acpidump: version 20070714
This is unchanged version 20070714, 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')
-rw-r--r-- | tools/power/acpi/Makefile | 7 | ||||
-rw-r--r-- | tools/power/acpi/acpidump.c | 127 |
2 files changed, 103 insertions, 31 deletions
diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile index faf5ff5c8f8f..dad79a69b679 100644 --- a/tools/power/acpi/Makefile +++ b/tools/power/acpi/Makefile | |||
@@ -1,11 +1,10 @@ | |||
1 | PROG= acpidump | 1 | PROG= acpidump |
2 | SRCS= acpidump.c | 2 | SRCS= acpidump.c |
3 | KERNEL_INCLUDE := ../../../include | 3 | KERNEL_INCLUDE := ../../../include |
4 | CFLAGS += -Wall -Wstrict-prototypes -Os -s -D_LINUX -DDEFINE_ALTERNATE_TYPES -I$(KERNEL_INCLUDE) | 4 | CFLAGS += -Wall -Wstrict-prototypes -Wdeclaration-after-statement -Os -s -D_LINUX -DDEFINE_ALTERNATE_TYPES -I$(KERNEL_INCLUDE) |
5 | 5 | ||
6 | all: acpidump | 6 | all: acpidump |
7 | 7 | $(PROG) : $(SRCS) | |
8 | acpidump : $(SRCS) | ||
9 | $(CC) $(CFLAGS) $(SRCS) -o $(PROG) | 8 | $(CC) $(CFLAGS) $(SRCS) -o $(PROG) |
10 | 9 | ||
11 | CLEANFILES= $(PROG) | 10 | CLEANFILES= $(PROG) |
diff --git a/tools/power/acpi/acpidump.c b/tools/power/acpi/acpidump.c index 3bb8e820ba43..8e5e19451ce1 100644 --- a/tools/power/acpi/acpidump.c +++ b/tools/power/acpi/acpidump.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * (c) Alexey Starikovskiy, Intel, 2005-2006. | 2 | * (c) Alexey Starikovskiy, Intel, 2005-2006. |
3 | * (c) Len Brown, Intel, 2007. | ||
3 | * All rights reserved. | 4 | * All rights reserved. |
4 | * | 5 | * |
5 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without |
@@ -185,6 +186,40 @@ static void acpi_show_data(int fd, u8 * data, int size) | |||
185 | /* | 186 | /* |
186 | * Output ACPI table | 187 | * Output ACPI table |
187 | */ | 188 | */ |
189 | |||
190 | #define MAX_TABLES 128 | ||
191 | int next_table_dump; | ||
192 | u64 dumped_tables[MAX_TABLES]; | ||
193 | |||
194 | void | ||
195 | set_table_dumped(u64 address) { | ||
196 | if (next_table_dump >= MAX_TABLES) { | ||
197 | printf("increase MAX_TABLES\n"); | ||
198 | exit(1); | ||
199 | } | ||
200 | dumped_tables[next_table_dump++] = address; | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * list the tables as they are dumped | ||
205 | * check the list so that they are not dumped twice. | ||
206 | * | ||
207 | * this is needed because we follow both the XSDT and RSDT | ||
208 | * which generally point to all duplicate tables | ||
209 | * except the FADT | ||
210 | */ | ||
211 | int | ||
212 | check_table_dumped(u64 address) { | ||
213 | int i; | ||
214 | |||
215 | for (i = 0; i < MAX_TABLES; ++i) { | ||
216 | if (address == dumped_tables[i]) | ||
217 | return 1; | ||
218 | if (dumped_tables[i] == 0) | ||
219 | return 0; | ||
220 | } | ||
221 | return 0; | ||
222 | } | ||
188 | static void acpi_show_table(int fd, struct acpi_table_header *table, unsigned long addr) | 223 | static void acpi_show_table(int fd, struct acpi_table_header *table, unsigned long addr) |
189 | { | 224 | { |
190 | char buff[80]; | 225 | char buff[80]; |
@@ -198,6 +233,10 @@ static void acpi_show_table(int fd, struct acpi_table_header *table, unsigned lo | |||
198 | static void write_table(int fd, struct acpi_table_header *tbl, unsigned long addr) | 233 | static void write_table(int fd, struct acpi_table_header *tbl, unsigned long addr) |
199 | { | 234 | { |
200 | static int select_done = 0; | 235 | static int select_done = 0; |
236 | |||
237 | if (check_table_dumped((u64)addr)) | ||
238 | return; | ||
239 | |||
201 | if (!select_sig[0]) { | 240 | if (!select_sig[0]) { |
202 | if (print) { | 241 | if (print) { |
203 | acpi_show_table(fd, tbl, addr); | 242 | acpi_show_table(fd, tbl, addr); |
@@ -216,6 +255,7 @@ static void write_table(int fd, struct acpi_table_header *tbl, unsigned long add | |||
216 | } | 255 | } |
217 | select_done = 1; | 256 | select_done = 1; |
218 | } | 257 | } |
258 | set_table_dumped((u64) addr); | ||
219 | } | 259 | } |
220 | 260 | ||
221 | static void acpi_dump_FADT(int fd, struct acpi_table_header *tbl, unsigned long xaddr) { | 261 | static void acpi_dump_FADT(int fd, struct acpi_table_header *tbl, unsigned long xaddr) { |
@@ -272,30 +312,26 @@ no_facs: | |||
272 | write_table(fd, (struct acpi_table_header *)&x, xaddr); | 312 | write_table(fd, (struct acpi_table_header *)&x, xaddr); |
273 | } | 313 | } |
274 | 314 | ||
275 | static int acpi_dump_SDT(int fd, struct acpi_rsdp_descriptor *rsdp) | 315 | |
316 | static int acpi_dump_RSDT(int fd, struct acpi_rsdp_descriptor *rsdp) | ||
276 | { | 317 | { |
277 | struct acpi_table_header *sdt, *tbl = 0; | 318 | struct acpi_table_header *sdt, *tbl = 0; |
278 | int xsdt = 1, i, num; | 319 | int i, num; |
279 | char *offset; | 320 | char *offset; |
280 | unsigned long addr; | 321 | unsigned long addr; |
281 | if (rsdp->revision > 1 && rsdp->xsdt_physical_address) { | 322 | |
282 | tbl = acpi_map_table(rsdp->xsdt_physical_address, "XSDT"); | 323 | tbl = acpi_map_table(rsdp->rsdt_physical_address, "RSDT"); |
283 | } | ||
284 | if (!tbl && rsdp->rsdt_physical_address) { | ||
285 | xsdt = 0; | ||
286 | tbl = acpi_map_table(rsdp->rsdt_physical_address, "RSDT"); | ||
287 | } | ||
288 | if (!tbl) return 0; | 324 | if (!tbl) return 0; |
325 | |||
289 | sdt = malloc(tbl->length); | 326 | sdt = malloc(tbl->length); |
290 | memcpy(sdt, tbl, tbl->length); | 327 | memcpy(sdt, tbl, tbl->length); |
291 | acpi_unmap_table(tbl); | 328 | acpi_unmap_table(tbl); |
292 | if (checksum((u8 *)sdt, sdt->length)) | 329 | if (checksum((u8 *)sdt, sdt->length)) |
293 | fprintf(stderr, "Wrong checksum for %s!\n", (xsdt)?"XSDT":"RSDT"); | 330 | fprintf(stderr, "Wrong checksum for %s!\n", "RSDT"); |
294 | num = (sdt->length - sizeof(struct acpi_table_header))/((xsdt)?sizeof(u64):sizeof(u32)); | 331 | num = (sdt->length - sizeof(struct acpi_table_header))/sizeof(u32); |
295 | offset = (char *)sdt + sizeof(struct acpi_table_header); | 332 | offset = (char *)sdt + sizeof(struct acpi_table_header); |
296 | for (i = 0; i < num; ++i, offset += ((xsdt) ? sizeof(u64) : sizeof(u32))) { | 333 | for (i = 0; i < num; ++i, offset += sizeof(u32)) { |
297 | addr = (xsdt) ? (unsigned long)(*(u64 *)offset): | 334 | addr = (unsigned long)(*(u32 *)offset); |
298 | (unsigned long)(*(u32 *)offset); | ||
299 | if (!addr) continue; | 335 | if (!addr) continue; |
300 | tbl = acpi_map_table(addr, 0); | 336 | tbl = acpi_map_table(addr, 0); |
301 | if (!tbl) continue; | 337 | if (!tbl) continue; |
@@ -303,28 +339,63 @@ static int acpi_dump_SDT(int fd, struct acpi_rsdp_descriptor *rsdp) | |||
303 | acpi_dump_FADT(fd, tbl, addr); | 339 | acpi_dump_FADT(fd, tbl, addr); |
304 | } else { | 340 | } else { |
305 | if (checksum((u8 *)tbl, tbl->length)) | 341 | if (checksum((u8 *)tbl, tbl->length)) |
306 | fprintf(stderr, "Wrong checksum for generic table!\n"); | 342 | fprintf(stderr, "Wrong checksum for %.4s!\n", tbl->signature); |
307 | write_table(fd, tbl, addr); | 343 | write_table(fd, tbl, addr); |
308 | } | 344 | } |
309 | acpi_unmap_table(tbl); | 345 | acpi_unmap_table(tbl); |
310 | if (connect) { | 346 | if (connect) { |
311 | if (xsdt) | 347 | (*(u32*)offset) = lseek(fd, 0, SEEK_CUR); |
312 | (*(u64*)offset) = lseek(fd, 0, SEEK_CUR); | ||
313 | else | ||
314 | (*(u32*)offset) = lseek(fd, 0, SEEK_CUR); | ||
315 | } | 348 | } |
316 | } | 349 | } |
317 | if (xsdt) { | 350 | addr = (unsigned long)rsdp->rsdt_physical_address; |
318 | addr = (unsigned long)rsdp->xsdt_physical_address; | 351 | if (connect) { |
319 | if (connect) { | 352 | rsdp->rsdt_physical_address = lseek(fd, 0, SEEK_CUR); |
320 | rsdp->xsdt_physical_address = lseek(fd, 0, SEEK_CUR); | 353 | } |
354 | write_table(fd, sdt, addr); | ||
355 | free (sdt); | ||
356 | return 1; | ||
357 | } | ||
358 | |||
359 | |||
360 | static int acpi_dump_XSDT(int fd, struct acpi_rsdp_descriptor *rsdp) | ||
361 | { | ||
362 | struct acpi_table_header *sdt, *tbl = 0; | ||
363 | int i, num; | ||
364 | char *offset; | ||
365 | unsigned long addr; | ||
366 | if (rsdp->revision > 1 && rsdp->xsdt_physical_address) { | ||
367 | tbl = acpi_map_table(rsdp->xsdt_physical_address, "XSDT"); | ||
368 | } | ||
369 | if (!tbl) return 0; | ||
370 | |||
371 | sdt = malloc(tbl->length); | ||
372 | memcpy(sdt, tbl, tbl->length); | ||
373 | acpi_unmap_table(tbl); | ||
374 | if (checksum((u8 *)sdt, sdt->length)) | ||
375 | fprintf(stderr, "Wrong checksum for %s!\n", "XSDT"); | ||
376 | num = (sdt->length - sizeof(struct acpi_table_header))/sizeof(u64); | ||
377 | offset = (char *)sdt + sizeof(struct acpi_table_header); | ||
378 | for (i = 0; i < num; ++i, offset += sizeof(u64)) { | ||
379 | addr = (unsigned long)(*(u64 *)offset); | ||
380 | if (!addr) continue; | ||
381 | tbl = acpi_map_table(addr, 0); | ||
382 | if (!tbl) continue; | ||
383 | if (!memcmp(tbl->signature, FADT_SIG, 4)) { | ||
384 | acpi_dump_FADT(fd, tbl, addr); | ||
385 | } else { | ||
386 | if (checksum((u8 *)tbl, tbl->length)) | ||
387 | fprintf(stderr, "Wrong checksum for %.4s\n", tbl->signature); | ||
388 | write_table(fd, tbl, addr); | ||
321 | } | 389 | } |
322 | } else { | 390 | acpi_unmap_table(tbl); |
323 | addr = (unsigned long)rsdp->rsdt_physical_address; | ||
324 | if (connect) { | 391 | if (connect) { |
325 | rsdp->rsdt_physical_address = lseek(fd, 0, SEEK_CUR); | 392 | (*(u64*)offset) = lseek(fd, 0, SEEK_CUR); |
326 | } | 393 | } |
327 | } | 394 | } |
395 | addr = (unsigned long)rsdp->xsdt_physical_address; | ||
396 | if (connect) { | ||
397 | rsdp->xsdt_physical_address = lseek(fd, 0, SEEK_CUR); | ||
398 | } | ||
328 | write_table(fd, sdt, addr); | 399 | write_table(fd, sdt, addr); |
329 | free (sdt); | 400 | free (sdt); |
330 | return 1; | 401 | return 1; |
@@ -469,7 +540,9 @@ int main(int argc, char **argv) | |||
469 | if (connect) { | 540 | if (connect) { |
470 | lseek(fd, sizeof(struct acpi_rsdp_descriptor), SEEK_SET); | 541 | lseek(fd, sizeof(struct acpi_rsdp_descriptor), SEEK_SET); |
471 | } | 542 | } |
472 | if (!acpi_dump_SDT(fd, &rsdpx)) | 543 | if (!acpi_dump_XSDT(fd, &rsdpx)) |
544 | goto not_found; | ||
545 | if (!acpi_dump_RSDT(fd, &rsdpx)) | ||
473 | goto not_found; | 546 | goto not_found; |
474 | if (connect) { | 547 | if (connect) { |
475 | lseek(fd, 0, SEEK_SET); | 548 | lseek(fd, 0, SEEK_SET); |