Add support for SSDT tables. Dumping or disassembling the DSDT will
now include the contents if any SSDT table as well. This makes use of the property that one can concatenate the body of SSDT tables to the DSDT, updating the DSDT header (length and checksum) and end up with a larger and valid DSDT table. Hence, this also works with -f. Reviewed by: njl@
This commit is contained in:
parent
873a41c7fa
commit
fdae0159aa
@ -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))
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user