summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/acpi/acpidump/acpi.c54
-rw-r--r--usr.sbin/acpi/acpidump/acpidump.c17
-rw-r--r--usr.sbin/acpi/acpidump/acpidump.h7
3 files changed, 58 insertions, 20 deletions
diff --git a/usr.sbin/acpi/acpidump/acpi.c b/usr.sbin/acpi/acpidump/acpi.c
index 971e021..e22aad4 100644
--- a/usr.sbin/acpi/acpidump/acpi.c
+++ b/usr.sbin/acpi/acpidump/acpi.c
@@ -716,8 +716,41 @@ sdt_load_devmem(void)
return (rsdp);
}
+static int
+write_dsdt(int fd, struct ACPIsdt *rsdt, struct ACPIsdt *dsdt)
+{
+ struct ACPIsdt sdt;
+ struct ACPIsdt *ssdt;
+ uint8_t sum;
+
+ sdt = *dsdt;
+ if (rsdt != NULL) {
+ sdt.check = 0;
+ sum = acpi_checksum(dsdt->body, dsdt->len - SIZEOF_SDT_HDR);
+ ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
+ while (ssdt != NULL) {
+ sdt.len += ssdt->len - SIZEOF_SDT_HDR;
+ sum += acpi_checksum(ssdt->body,
+ ssdt->len - SIZEOF_SDT_HDR);
+ ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
+ }
+ sum += acpi_checksum(&sdt, SIZEOF_SDT_HDR);
+ sdt.check -= sum;
+ }
+ write(fd, &sdt, SIZEOF_SDT_HDR);
+ write(fd, dsdt->body, dsdt->len - SIZEOF_SDT_HDR);
+ if (rsdt != NULL) {
+ ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
+ while (ssdt != NULL) {
+ write(fd, ssdt->body, ssdt->len - SIZEOF_SDT_HDR);
+ ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
+ }
+ }
+ return (0);
+}
+
void
-dsdt_save_file(char *outfile, struct ACPIsdt *dsdp)
+dsdt_save_file(char *outfile, struct ACPIsdt *rsdt, struct ACPIsdt *dsdp)
{
int fd;
mode_t mode;
@@ -729,13 +762,12 @@ dsdt_save_file(char *outfile, struct ACPIsdt *dsdp)
perror("dsdt_save_file");
return;
}
- write(fd, dsdp, SIZEOF_SDT_HDR);
- write(fd, dsdp->body, dsdp->len - SIZEOF_SDT_HDR);
+ write_dsdt(fd, rsdt, dsdp);
close(fd);
}
void
-aml_disassemble(struct ACPIsdt *dsdp)
+aml_disassemble(struct ACPIsdt *rsdt, struct ACPIsdt *dsdp)
{
char tmpstr[32], buf[256];
FILE *fp;
@@ -747,10 +779,7 @@ aml_disassemble(struct ACPIsdt *dsdp)
perror("iasl tmp file");
return;
}
-
- /* Dump DSDT to the temp file */
- write(fd, dsdp, SIZEOF_SDT_HDR);
- write(fd, dsdp->body, dsdp->len - SIZEOF_SDT_HDR);
+ write_dsdt(fd, rsdt, dsdp);
close(fd);
/* Run iasl -d on the temp file */
@@ -783,9 +812,9 @@ sdt_print_all(struct ACPIsdt *rsdp)
acpi_handle_rsdt(rsdp);
}
-/* Fetch a table matching the given signature via the RSDT */
+/* Fetch a table matching the given signature via the RSDT. */
struct ACPIsdt *
-sdt_from_rsdt(struct ACPIsdt *rsdt, const char *sig)
+sdt_from_rsdt(struct ACPIsdt *rsdt, const char *sig, struct ACPIsdt *last)
{
struct ACPIsdt *sdt;
vm_offset_t addr;
@@ -804,6 +833,11 @@ sdt_from_rsdt(struct ACPIsdt *rsdt, const char *sig)
assert((addr = 0));
}
sdt = (struct ACPIsdt *)acpi_map_sdt(addr);
+ if (last != NULL) {
+ if (sdt == last)
+ last = NULL;
+ continue;
+ }
if (memcmp(sdt->signature, sig, strlen(sig)))
continue;
if (acpi_checksum(sdt, sdt->len))
diff --git a/usr.sbin/acpi/acpidump/acpidump.c b/usr.sbin/acpi/acpidump/acpidump.c
index 269a595..b9b8b0a 100644
--- a/usr.sbin/acpi/acpidump/acpidump.c
+++ b/usr.sbin/acpi/acpidump/acpidump.c
@@ -54,7 +54,7 @@ main(int argc, char *argv[])
{
char c, *progname;
char *dsdt_input_file, *dsdt_output_file;
- struct ACPIsdt *sdt;
+ struct ACPIsdt *rsdt, *sdt;
dsdt_input_file = dsdt_output_file = NULL;
progname = argv[0];
@@ -99,38 +99,41 @@ main(int argc, char *argv[])
}
if (vflag)
warnx("loading DSDT file: %s", dsdt_input_file);
- sdt = dsdt_load_file(dsdt_input_file);
+ rsdt = dsdt_load_file(dsdt_input_file);
} else {
if (vflag)
warnx("loading RSD PTR from /dev/mem");
- sdt = sdt_load_devmem();
+ rsdt = sdt_load_devmem();
}
/* Display misc. SDT tables (only available when using /dev/mem) */
if (tflag) {
if (vflag)
warnx("printing various SDT tables");
- sdt_print_all(sdt);
+ sdt_print_all(rsdt);
}
/* Translate RSDT to DSDT pointer */
if (dsdt_input_file == NULL) {
- sdt = sdt_from_rsdt(sdt, "FACP");
+ sdt = sdt_from_rsdt(rsdt, "FACP", NULL);
sdt = dsdt_from_fadt((struct FADTbody *)sdt->body);
+ } else {
+ sdt = rsdt;
+ rsdt = NULL;
}
/* Dump the DSDT to a file */
if (dsdt_output_file != NULL) {
if (vflag)
warnx("saving DSDT file: %s", dsdt_output_file);
- dsdt_save_file(dsdt_output_file, sdt);
+ dsdt_save_file(dsdt_output_file, rsdt, sdt);
}
/* Disassemble the DSDT into ASL */
if (dflag) {
if (vflag)
warnx("disassembling DSDT, iasl messages follow");
- aml_disassemble(sdt);
+ aml_disassemble(rsdt, sdt);
if (vflag)
warnx("iasl processing complete");
}
diff --git a/usr.sbin/acpi/acpidump/acpidump.h b/usr.sbin/acpi/acpidump/acpidump.h
index 1ebc56d..ca56398 100644
--- a/usr.sbin/acpi/acpidump/acpidump.h
+++ b/usr.sbin/acpi/acpidump/acpidump.h
@@ -314,18 +314,19 @@ struct ACPIsdt *sdt_load_devmem(void);
struct ACPIsdt *dsdt_load_file(char *);
/* Save the DSDT to a file */
-void dsdt_save_file(char *, struct ACPIsdt *);
+void dsdt_save_file(char *, struct ACPIsdt *, struct ACPIsdt *);
/* Print out as many fixed tables as possible, given the RSD PTR */
void sdt_print_all(struct ACPIsdt *);
/* Disassemble the AML in the DSDT */
-void aml_disassemble(struct ACPIsdt *);
+void aml_disassemble(struct ACPIsdt *, struct ACPIsdt *);
/* Routines for accessing tables in physical memory */
struct ACPIrsdp *acpi_find_rsd_ptr(void);
void *acpi_map_physical(vm_offset_t, size_t);
-struct ACPIsdt *sdt_from_rsdt(struct ACPIsdt *, const char *);
+struct ACPIsdt *sdt_from_rsdt(struct ACPIsdt *, const char *,
+ struct ACPIsdt *);
struct ACPIsdt *dsdt_from_fadt(struct FADTbody *);
int acpi_checksum(void *, size_t);
OpenPOWER on IntegriCloud