Modify acpidump to use iasl(8) as the backend for disassembling AML.

Also clean up the output of dumped tables.  Update the man page for the
new usage.  Make WARNS=6 clean.
This commit is contained in:
njl 2003-08-28 03:33:07 +00:00
parent 3a01d6b42e
commit f51148df74
8 changed files with 371 additions and 2091 deletions

View File

@ -1,13 +1,8 @@
# $Id: Makefile,v 1.2 2000/07/14 18:16:29 iwasaki Exp $
# $FreeBSD$
PROG= acpidump
MAN= acpidump.8
SRCS= acpi.c acpi_user.c asl_dump.c aml_dump.c acpidump.c
SRCS+= aml_parse.c aml_name.c aml_amlmem.c aml_memman.c aml_store.c \
aml_obj.c aml_evalobj.c aml_common.c
CFLAGS+= -I${.CURDIR}/../amldb
SRCS= acpi.c acpi_user.c acpidump.c
WARNS?= 6
.include <bsd.prog.mk>
.PATH: ${.CURDIR}/../amldb/aml

View File

@ -24,62 +24,44 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: acpi.c,v 1.4 2000/08/09 14:47:52 iwasaki Exp $
* $FreeBSD$
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <assert.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "acpidump.h"
#include "aml/aml_env.h"
#include "aml/aml_common.h"
#define BEGIN_COMMENT "/*\n"
#define END_COMMENT " */\n"
struct ACPIsdt dsdt_header = {
"DSDT", 0, 1, 0, "OEMID", "OEMTBLID", 0x12345678, "CRTR", 0x12345678
};
static void
acpi_trim_string(char *s, size_t length)
{
/* Trim trailing spaces and NULLs */
while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
s[length-- - 1] = '\0';
}
static void
acpi_print_dsdt_definition(void)
{
char oemid[6 + 1];
char oemtblid[8 + 1];
acpi_trim_string(dsdt_header.oemid, 6);
acpi_trim_string(dsdt_header.oemtblid, 8);
strncpy(oemid, dsdt_header.oemid, 6);
oemid[6] = '\0';
strncpy(oemtblid, dsdt_header.oemtblid, 8);
oemtblid[8] = '\0';
printf("DefinitionBlock (\n"
" \"acpi_dsdt.aml\", //Output filename\n"
" \"DSDT\", //Signature\n"
" 0x%x, //DSDT Revision\n"
" \"%s\", //OEMID\n"
" \"%s\", //TABLE ID\n"
" 0x%x //OEM Revision\n)\n",
dsdt_header.rev, oemid, oemtblid, dsdt_header.oemrev);
}
static void acpi_print_string(char *s, size_t length);
static void acpi_handle_facp(struct FACPbody *facp);
static void acpi_print_cpu(u_char cpu_id);
static void acpi_print_local_apic(u_char cpu_id, u_char apic_id,
u_int32_t flags);
static void acpi_print_io_apic(u_char apic_id, u_int32_t int_base,
u_int64_t apic_addr);
static void acpi_print_mps_flags(u_int16_t flags);
static void acpi_print_intr(u_int32_t intr, u_int16_t mps_flags);
static void acpi_print_apic(struct MADT_APIC *mp);
static void acpi_handle_apic(struct ACPIsdt *sdp);
static void acpi_handle_hpet(struct ACPIsdt *sdp);
static void acpi_print_sdt(struct ACPIsdt *sdp, int endcomment);
static void acpi_print_facp(struct FACPbody *facp);
static void acpi_print_dsdt(struct ACPIsdt *dsdp);
static struct ACPIsdt *
acpi_map_sdt(vm_offset_t pa);
static void acpi_print_rsd_ptr(struct ACPIrsdp *rp);
static void acpi_handle_rsdt(struct ACPIsdt *rsdp);
static void
acpi_print_string(char *s, size_t length)
@ -96,30 +78,16 @@ acpi_print_string(char *s, size_t length)
}
}
static void
acpi_handle_dsdt(struct ACPIsdt *dsdp)
{
u_int8_t *dp;
u_int8_t *end;
acpi_print_dsdt(dsdp);
dp = (u_int8_t *)dsdp->body;
end = (u_int8_t *)dsdp + dsdp->len;
acpi_dump_dsdt(dp, end);
}
static void
acpi_handle_facp(struct FACPbody *facp)
{
struct ACPIsdt *dsdp;
acpi_print_facp(facp);
dsdp = (struct ACPIsdt *) acpi_map_sdt(facp->dsdt_ptr);
dsdp = (struct ACPIsdt *)acpi_map_sdt(facp->dsdt_ptr);
if (acpi_checksum(dsdp, dsdp->len))
errx(1, "DSDT is corrupt\n");
acpi_handle_dsdt(dsdp);
aml_dump(dsdp);
errx(1, "DSDT is corrupt");
acpi_print_dsdt(dsdp);
}
static void
@ -149,17 +117,9 @@ acpi_print_local_apic(u_char cpu_id, u_char apic_id, u_int32_t flags)
static void
acpi_print_io_apic(u_char apic_id, u_int32_t int_base, u_int64_t apic_addr)
{
u_int addr_hi;
printf("\tAPIC ID=%d\n", (u_int)apic_id);
printf("\tINT BASE=%d\n", int_base);
printf("\tADDR=0x");
addr_hi = apic_addr >> 32;
if (addr_hi != 0) {
printf("%08x", addr_hi);
apic_addr &= 0xffffffff;
}
printf("%08x\n", (u_int)apic_addr);
printf("\tADDR=0x%016jx\n", apic_addr);
}
static void
@ -242,9 +202,8 @@ acpi_print_apic(struct MADT_APIC *mp)
acpi_print_mps_flags(mp->body.local_nmi.mps_flags);
break;
case ACPI_MADT_APIC_TYPE_LOCAL_OVERRIDE:
printf("\tLocal APIC ADDR=0x%08x%08x\n",
(u_int)(mp->body.local_apic_override.apic_addr >> 32),
(u_int)(mp->body.local_apic_override.apic_addr & 0xffffffff));
printf("\tLocal APIC ADDR=0x%016jx\n",
mp->body.local_apic_override.apic_addr);
break;
case ACPI_MADT_APIC_TYPE_IO_SAPIC:
acpi_print_io_apic(mp->body.io_sapic.apic_id,
@ -268,6 +227,7 @@ acpi_print_apic(struct MADT_APIC *mp)
break;
default:
printf("\tUnknown type %d\n", (u_int)mp->type);
break;
}
}
@ -277,15 +237,14 @@ acpi_handle_apic(struct ACPIsdt *sdp)
struct MADTbody *madtp;
struct MADT_APIC *madt_apicp;
acpi_print_sdt(sdp);
acpi_print_sdt(sdp, /*endcomment*/0);
madtp = (struct MADTbody *) sdp->body;
printf(BEGIN_COMMENT);
printf("\tLocal APIC ADDR=0x%08x\n", madtp->lapic_addr);
printf("\tFlags={");
if (madtp->flags & ACPI_APIC_FLAG_PCAT_COMPAT)
printf("PC-AT");
printf("}\n");
madt_apicp = (struct MADT_APIC *) madtp->body;
madt_apicp = (struct MADT_APIC *)madtp->body;
while (((uintptr_t)madt_apicp) - ((uintptr_t)sdp) < sdp->len) {
printf("\n");
acpi_print_apic(madt_apicp);
@ -300,9 +259,8 @@ acpi_handle_hpet(struct ACPIsdt *sdp)
{
struct HPETbody *hpetp;
acpi_print_sdt(sdp);
acpi_print_sdt(sdp, /*endcomment*/0);
hpetp = (struct HPETbody *) sdp->body;
printf(BEGIN_COMMENT);
printf("\tHPET Number=%d\n", hpetp->hpet_number);
printf("\tADDR=0x%08x\n", hpetp->base_addr);
printf("\tHW Rev=0x%x\n", hpetp->block_hwrev);
@ -319,58 +277,9 @@ acpi_handle_hpet(struct ACPIsdt *sdp)
}
static void
init_namespace()
acpi_print_sdt(struct ACPIsdt *sdp, int endcomment)
{
struct aml_environ env;
struct aml_name *newname;
aml_new_name_group(AML_NAME_GROUP_OS_DEFINED);
env.curname = aml_get_rootname();
newname = aml_create_name(&env, "\\_OS_");
newname->property = aml_alloc_object(aml_t_string, NULL);
newname->property->str.needfree = 0;
newname->property->str.string = "Microsoft Windows NT";
}
/*
* Public interfaces
*/
void
acpi_dump_dsdt(u_int8_t *dp, u_int8_t *end)
{
extern struct aml_environ asl_env;
acpi_print_dsdt_definition();
/* 1st stage: parse only w/o printing */
init_namespace();
aml_new_name_group((int)dp);
bzero(&asl_env, sizeof(asl_env));
asl_env.dp = dp;
asl_env.end = end;
asl_env.curname = aml_get_rootname();
aml_local_stack_push(aml_local_stack_create());
aml_parse_objectlist(&asl_env, 0);
aml_local_stack_delete(aml_local_stack_pop());
assert(asl_env.dp == asl_env.end);
asl_env.dp = dp;
/* 2nd stage: dump whole object list */
printf("\n{\n");
asl_dump_objectlist(&dp, end, 0);
printf("\n}\n");
assert(dp == end);
}
void
acpi_print_sdt(struct ACPIsdt *sdp)
{
printf(BEGIN_COMMENT);
printf(BEGIN_COMMENT " ");
acpi_print_string(sdp->signature, 4);
printf(": Length=%d, Revision=%d, Checksum=%d,\n",
sdp->len, sdp->rev, sdp->check);
@ -382,20 +291,17 @@ acpi_print_sdt(struct ACPIsdt *sdp)
printf("\tCreator ID=");
acpi_print_string(sdp->creator, 4);
printf(", Creator Revision=0x%x\n", sdp->crerev);
printf(END_COMMENT);
if (!memcmp(sdp->signature, "DSDT", 4)) {
memcpy(&dsdt_header, sdp, sizeof(dsdt_header));
}
if (endcomment)
printf(END_COMMENT);
}
void
static void
acpi_print_rsdt(struct ACPIsdt *rsdp)
{
int i, entries;
acpi_print_sdt(rsdp);
acpi_print_sdt(rsdp, /*endcomment*/0);
entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t);
printf(BEGIN_COMMENT);
printf("\tEntries={ ");
for (i = 0; i < entries; i++) {
if (i > 0)
@ -406,13 +312,13 @@ acpi_print_rsdt(struct ACPIsdt *rsdp)
printf(END_COMMENT);
}
void
static void
acpi_print_facp(struct FACPbody *facp)
{
char sep;
printf(BEGIN_COMMENT);
printf("\tDSDT=0x%x\n", facp->dsdt_ptr);
printf(" FACP:\tDSDT=0x%x\n", facp->dsdt_ptr);
printf("\tINT_MODEL=%s\n", facp->int_model ? "APIC" : "PIC");
printf("\tSCI_INT=%d\n", facp->sci_int);
printf("\tSMI_CMD=0x%x, ", facp->smi_cmd);
@ -486,11 +392,10 @@ acpi_print_facp(struct FACPbody *facp)
printf(END_COMMENT);
}
void
static void
acpi_print_dsdt(struct ACPIsdt *dsdp)
{
acpi_print_sdt(dsdp);
acpi_print_sdt(dsdp, /*endcomment*/1);
}
int
@ -507,7 +412,7 @@ acpi_checksum(void *p, size_t length)
return (sum);
}
struct ACPIsdt *
static struct ACPIsdt *
acpi_map_sdt(vm_offset_t pa)
{
struct ACPIsdt *sp;
@ -517,18 +422,18 @@ acpi_map_sdt(vm_offset_t pa)
return (sp);
}
void
static void
acpi_print_rsd_ptr(struct ACPIrsdp *rp)
{
printf(BEGIN_COMMENT);
printf("RSD PTR: Checksum=%d, OEMID=", rp->sum);
printf(" RSD PTR: Checksum=%d, OEMID=", rp->sum);
acpi_print_string(rp->oem, 6);
printf(", RsdtAddress=0x%08x\n", rp->rsdt_addr);
printf(END_COMMENT);
}
void
static void
acpi_handle_rsdt(struct ACPIsdt *rsdp)
{
int i;
@ -538,100 +443,134 @@ acpi_handle_rsdt(struct ACPIsdt *rsdp)
entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t);
acpi_print_rsdt(rsdp);
for (i = 0; i < entries; i++) {
sdp = (struct ACPIsdt *) acpi_map_sdt(rsdp->body[i]);
sdp = (struct ACPIsdt *)acpi_map_sdt(rsdp->body[i]);
if (acpi_checksum(sdp, sdp->len))
errx(1, "RSDT entry %d is corrupt\n", i);
if (!memcmp(sdp->signature, "FACP", 4)) {
errx(1, "RSDT entry %d is corrupt", i);
if (!memcmp(sdp->signature, "FACP", 4))
acpi_handle_facp((struct FACPbody *) sdp->body);
} else if (!memcmp(sdp->signature, "APIC", 4)) {
else if (!memcmp(sdp->signature, "APIC", 4))
acpi_handle_apic(sdp);
} else if (!memcmp(sdp->signature, "HPET", 4)) {
else if (!memcmp(sdp->signature, "HPET", 4))
acpi_handle_hpet(sdp);
} else {
acpi_print_sdt(sdp);
}
else
acpi_print_sdt(sdp, /*endcomment*/1);
}
}
/*
* Dummy functions
*/
struct ACPIsdt *
sdt_load_devmem()
{
struct ACPIrsdp *rp;
struct ACPIsdt *rsdp;
rp = acpi_find_rsd_ptr();
if (!rp)
errx(1, "Can't find ACPI information");
if (tflag)
acpi_print_rsd_ptr(rp);
rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->rsdt_addr);
if (memcmp(rsdp->signature, "RSDT", 4) != 0 ||
acpi_checksum(rsdp, rsdp->len) != 0)
errx(1, "RSDT is corrupted");
return (rsdp);
}
void
aml_dbgr(struct aml_environ *env1, struct aml_environ *env2)
dsdt_save_file(char *outfile, struct ACPIsdt *dsdp)
{
/* do nothing */
int fd;
mode_t mode;
assert(outfile != NULL);
mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
if (fd == -1) {
perror("dsdt_save_file");
return;
}
write(fd, dsdp, SIZEOF_SDT_HDR);
write(fd, dsdp->body, dsdp->len - SIZEOF_SDT_HDR);
close(fd);
}
int
aml_region_read_simple(struct aml_region_handle *h, vm_offset_t offset,
u_int32_t *valuep)
void
aml_disassemble(struct ACPIsdt *dsdp)
{
return (0);
char tmpstr[32], buf[256];
FILE *fp;
int fd, len;
strcpy(tmpstr, "/tmp/acpidump.XXXXXX");
fd = mkstemp(tmpstr);
if (fd < 0) {
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);
close(fd);
/* Run iasl -d on the temp file */
if (fork() == 0) {
close(STDOUT_FILENO);
if (vflag == 0)
close(STDERR_FILENO);
execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, 0);
err(1, "exec");
}
wait(NULL);
unlink(tmpstr);
/* Dump iasl's output to stdout */
fp = fopen("acpidump.dsl", "r");
unlink("acpidump.dsl");
if (fp == NULL) {
perror("iasl tmp file (read)");
return;
}
while ((len = fread(buf, 1, sizeof(buf), fp)) > 0)
fwrite(buf, 1, len, stdout);
fclose(fp);
}
int
aml_region_write_simple(struct aml_region_handle *h, vm_offset_t offset,
u_int32_t value)
void
sdt_print_all(struct ACPIsdt *rsdp)
{
return (0);
acpi_handle_rsdt(rsdp);
}
u_int32_t
aml_region_prompt_read(struct aml_region_handle *h, u_int32_t value)
/* Fetch a table matching the given signature via the RSDT */
struct ACPIsdt *
sdt_from_rsdt(struct ACPIsdt *rsdt, const char *sig)
{
return (0);
int i;
int entries;
struct ACPIsdt *sdt;
entries = (rsdt->len - SIZEOF_SDT_HDR) / sizeof(uint32_t);
for (i = 0; i < entries; i++) {
sdt = (struct ACPIsdt *)acpi_map_sdt(rsdt->body[i]);
if (acpi_checksum(sdt, sdt->len))
errx(1, "RSDT entry %d is corrupt", i);
if (!memcmp(sdt->signature, sig, strlen(sig)))
return (sdt);
}
return (NULL);
}
u_int32_t
aml_region_prompt_write(struct aml_region_handle *h, u_int32_t value)
struct ACPIsdt *
dsdt_from_facp(struct FACPbody *facp)
{
return (0);
}
struct ACPIsdt *sdt;
int
aml_region_prompt_update_value(u_int32_t orgval, u_int32_t value,
struct aml_region_handle *h)
{
return (0);
sdt = (struct ACPIsdt *)acpi_map_sdt(facp->dsdt_ptr);
if (acpi_checksum(sdt, sdt->len))
errx(1, "DSDT is corrupt\n");
return (sdt);
}
u_int32_t
aml_region_read(struct aml_environ *env, int regtype, u_int32_t flags,
u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen)
{
return (0);
}
int
aml_region_write(struct aml_environ *env, int regtype, u_int32_t flags,
u_int32_t value, u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen)
{
return (0);
}
int
aml_region_write_from_buffer(struct aml_environ *env, int regtype,
u_int32_t flags, u_int8_t *buffer, u_int32_t addr, u_int32_t bitoffset,
u_int32_t bitlen)
{
return (0);
}
int
aml_region_bcopy(struct aml_environ *env, int regtype, u_int32_t flags,
u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen,
u_int32_t dflags, u_int32_t daddr,
u_int32_t dbitoffset, u_int32_t dbitlen)
{
return (0);
}
int
aml_region_read_into_buffer(struct aml_environ *env, int regtype,
u_int32_t flags, u_int32_t addr, u_int32_t bitoffset,
u_int32_t bitlen, u_int8_t *buffer)
{
return (0);
}

View File

@ -24,7 +24,6 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: acpi_user.c,v 1.5 2000/08/09 14:47:52 iwasaki Exp $
* $FreeBSD$
*/
@ -32,6 +31,7 @@
#include <sys/mman.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <err.h>
#include <fcntl.h>
@ -41,8 +41,7 @@
#include "acpidump.h"
static char machdep_acpi_root[] = "machdep.acpi_root";
static char machdep_acpi_root[] = "machdep.acpi_root";
static int acpi_mem_fd = -1;
struct acpi_user_mapping {
@ -55,7 +54,7 @@ struct acpi_user_mapping {
LIST_HEAD(acpi_user_mapping_list, acpi_user_mapping) maplist;
static void
acpi_user_init()
acpi_user_init(void)
{
if (acpi_mem_fd == -1) {
@ -96,31 +95,32 @@ acpi_user_find_mapping(vm_offset_t pa, size_t size)
/*
* Public interfaces
*/
struct ACPIrsdp *
acpi_find_rsd_ptr()
{
struct ACPIrsdp rsdp;
u_long addr;
int len;
size_t len;
acpi_user_init();
/* Attempt to use sysctl to find RSD PTR record */
len = sizeof(addr);
if (sysctlbyname(machdep_acpi_root, &addr, &len, NULL, 0) == 0) {
pread(acpi_mem_fd, &rsdp, sizeof(rsdp), addr);
if (memcmp(rsdp.signature, "RSD PTR ", 8))
errx(1, "sysctl %s does not point to RSDP\n",
machdep_acpi_root);
if (memcmp(rsdp.signature, "RSD PTR ", 8) != 0)
errx(1, "sysctl %s does not point to RSDP",
machdep_acpi_root);
len = 20; /* size of ACPI 1.0 table */
if (acpi_checksum(&rsdp, len))
warnx("RSDP has invalid checksum\n");
warnx("RSDP has invalid checksum");
if (rsdp.revision > 0)
len = rsdp.length;
return (acpi_map_physical(addr, len));
}
#if !defined(__ia64__)
#if !defined(__ia64__) && !defined(__amd64__)
/* On ia32, scan physical memory for RSD PTR if above failed */
for (addr = 0UL; addr < 1024UL * 1024UL; addr += 16UL) {
pread(acpi_mem_fd, &rsdp, 8, addr);
if (memcmp(rsdp.signature, "RSD PTR ", 8))
@ -148,35 +148,28 @@ acpi_map_physical(vm_offset_t pa, size_t size)
return (map->va + (pa - map->pa));
}
void
acpi_load_dsdt(char *dumpfile, u_int8_t **dpp, u_int8_t **endp)
struct ACPIsdt *
dsdt_load_file(char *infile)
{
u_int8_t *dp;
u_int8_t *end;
struct stat sb;
struct ACPIsdt *sdt;
uint8_t *dp;
struct stat sb;
if ((acpi_mem_fd = open(dumpfile, O_RDONLY)) == -1) {
errx(1, "opening %s\n", dumpfile);
}
if ((acpi_mem_fd = open(infile, O_RDONLY)) == -1)
errx(1, "opening %s", infile);
LIST_INIT(&maplist);
if (fstat(acpi_mem_fd, &sb) == -1) {
errx(1, "fstat %s\n", dumpfile);
}
if (fstat(acpi_mem_fd, &sb) == -1)
errx(1, "fstat %s", infile);
dp = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, acpi_mem_fd, 0);
if (dp == NULL) {
errx(1, "mmap %s\n", dumpfile);
}
if (dp == NULL)
errx(1, "mmap %s", infile);
if (strncmp(dp, "DSDT", 4) == 0) {
memcpy(&dsdt_header, dp, SIZEOF_SDT_HDR);
dp += SIZEOF_SDT_HDR;
sb.st_size -= SIZEOF_SDT_HDR;
}
sdt = (struct ACPIsdt *)dp;
if (strncmp(dp, "DSDT", 4) != 0 || acpi_checksum(sdt, sdt->len) != 0)
return (NULL);
end = (u_int8_t *) dp + sb.st_size;
*dpp = dp;
*endp = end;
return (sdt);
}

View File

@ -34,47 +34,45 @@
.Os
.Sh NAME
.Nm acpidump
.Nd dump ACPI tables
.Nd dump ACPI tables and ASL
.Sh SYNOPSIS
.Nm
.Op Fl r
.Nm
.Op Fl r
.Op Fl o Ar dsdt_file_for_output
.Nm
.Op Fl r
.Op Fl f Ar dsdt_file_for_input
.Op Fl d
.Op Fl t
.Op Fl h
.Op Fl v
.Op Fl f Ar dsdt_input
.Op Fl o Ar dsdt_output
.Sh DESCRIPTION
The
.Nm
utility analyzes ACPI tables in physical memory and dumps them to
standard output.
utility analyzes ACPI tables in physical memory and can dump them to a file.
In addition,
.Nm
can disassemble AML
can call
.Xr iasl 8
to disassemble AML
(ACPI Machine Language)
found in these tables and dump them as ASL
(ACPI Source Language).
(ACPI Source Language)
to stdout.
.Pp
ACPI tables have an essential data block (the DSDT,
Differentiated System Description Table),
Differentiated System Description Table)
that includes information used on the kernel side such as
detailed information about PnP hardware, procedures for controlling
power management support and so on.
power management support, and so on.
The
.Nm
utility can extract the DSDT data block from physical memory and store it into
a DSDT data file, and also can generate an output in ASL
from a given DSDT data file.
a DSDT output file and optionally also disassemble it.
.Pp
When
.Nm
is invoked without the
.Fl f
option, it will read ACPI tables from physical
memory via a special file
.Pa /dev/mem
and dump them.
option, it will read ACPI tables from physical memory via
.Pa /dev/mem .
First it searches for the RSDP
(Root System Description Pointer),
which has the signature
@ -89,65 +87,74 @@ called SDTs
and their header has a common format which consists of items
such as Signature, Length, Revision, Checksum, OEMID, OEM Table ID,
OEM Revision, Creator ID and Creator Revision.
The
When invoked with the
.Fl t
flag, the
.Nm
utility dumps contents of these SDTs.
For further information about formats of each table,
see chapter 5:
.Dq ACPI Software Programming Model
from the ACPI specifications referenced below.
utility dumps contents of the following tables:
.Pp
There is always a pointer to a physical memory address in RSDT for FACP
.Bl -tag -offset indent -width 12345 -compact
.It DSDT
.It FADT
.It HPET
.It MADT
.It RSD PTR
.It RSDT
.El
.Pp
The RSDT contains a pointer to the physical memory address of the FACP
(Fixed ACPI Description Table).
The FACP defines static system information about power management support
(ACPI Hardware Register Implementation)
such as interrupt mode
(INT_MODEL),
SCI interrupt number, SMI command port
(SMI_CMD)
and location of ACPI registers.
The FACP also has a pointer to a physical memory address for DSDT,
which includes information used on the kernel side such as
PnP, power management support and so on.
While the other tables are described in fixed format,
the DSDT consists of AML data which is compiled from sources
written in free formated ASL, which is the description language for ACPI.
When
.Nm
outputs DSDT, it disassembles the AML data and
formats it as ASL.
such as interrupt mode (INT_MODEL),
SCI interrupt number, SMI command port (SMI_CMD)
and the location of ACPI registers.
The FACP also has a pointer to a physical memory address for the DSDT.
While the other tables are fixed format,
the DSDT consists of free-formatted AML data.
.Sh OPTIONS
The following options are supported by
.Nm :
.Bl -tag -width indent
.It Fl o Ar dsdt_file_for_output
Stores DSDT data block from physical memory into a file specified in
.Ar dsdt_file_for_output
in addition to behavior with no option.
.It Fl f Ar dsdt_file_for_input
Interprets AML data in DSDT from a file specified in
.Ar dsdt_file_for_input
and dumps them in ASL to standard output.
.It Fl r
Additionally outputs commented ResourceTemplate() macros for Buffer
objects that contain valid resource streams.
These macros are defined in the ACPI 2.0 specification section
16.2.4.
.It Fl d
Disassemble the DSDT into ASL using
.Xr iasl 8
and print the results to stdout.
.It Fl t
Dump the contents of the various fixed tables listed above.
.It Fl h
Displays usage and exit.
.It Fl v
Enable verbose messages.
.It Fl f Ar dsdt_input
Load the DSDT from the specified file instead of physical memory.
Since only the DSDT is stored in the file, the
.Fl t
flag may not be used with this option.
.It Fl o Ar dsdt_output
Store the DSDT data block from physical memory into the specified file.
.El
.Sh EXAMPLES
This is an example to get a dump of SDTs and a DSDT data file
simultaneously on a machine that supports ACPI BIOS.
This example dumps the DSDT from physical memory to foo.dsdt.
It also prints the contents of various system tables and disassembles
the AML contained in the DSDT to stdout, redirecting the output
to foo.asl.
.Bd -literal -offset indent
# acpidump -o foo.dsdt > foo.asl
# acpidump -t -d -o foo.dsdt > foo.asl
.Ed
.Pp
This example reads a DSDT file and disassembles it to stdout.
Verbose messages are enabled.
.Bd -literal -offset indent
# acpidump -v -d -f foo.dsdt
.Ed
.Sh BUGS
In the current implementation,
.Nm
doesn't dump any information of Firmware ACPI Control Structure
(FACS)
specified by a pointer in FACP.
doesn't dump the Firmware ACPI Control Structure (FACS),
Secondary System Descriptor Table (SSDT),
Embedded Controller Descriptor Table (ECDT),
or BOOT structures.
.Sh FILES
.Bl -tag -width /dev/mem
.It Pa /dev/mem
@ -156,16 +163,8 @@ specified by a pointer in FACP.
.Xr acpi 4 ,
.Xr mem 4 ,
.Xr acpiconf 8 ,
.Xr amldb 8
.Pp
.Dq Advanced Configuration and Power Interface Specification
.Bd -literal -offset indent -compact
Intel
Microsoft
Toshiba
Revision 1.0b, 2.0
.Ed
<URL:http://www.teleport.com/~acpi/>
.Xr acpidb 8 ,
.Xr iasl 8
.Sh AUTHORS
.An Doug Rabson Aq dfr@FreeBSD.org
.An Mitsuru IWASAKI Aq iwasaki@FreeBSD.org
@ -183,5 +182,9 @@ and
.Sh HISTORY
The
.Nm
utility appeared in
.Fx 5.0 .
utility first appeared in
.Fx 5.0
and was rewritten to use
.Xr iasl 8
for
.Fx 5.2 .

View File

@ -23,56 +23,29 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: acpidump.c,v 1.3 2000/08/08 14:12:21 iwasaki Exp $
* $FreeBSD$
*/
#include <sys/param.h>
#include <assert.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "acpidump.h"
static void
asl_dump_from_file(char *file)
{
u_int8_t *dp;
u_int8_t *end;
struct ACPIsdt *dsdt;
acpi_load_dsdt(file, &dp, &end);
acpi_dump_dsdt(dp, end);
}
static void
asl_dump_from_devmem()
{
struct ACPIrsdp *rp;
struct ACPIsdt *rsdp;
rp = acpi_find_rsd_ptr();
if (!rp)
errx(1, "Can't find ACPI information\n");
acpi_print_rsd_ptr(rp);
rsdp = (struct ACPIsdt *) acpi_map_sdt(rp->rsdt_addr);
if (memcmp(rsdp->signature, "RSDT", 4) ||
acpi_checksum(rsdp, rsdp->len))
errx(1, "RSDT is corrupted\n");
acpi_handle_rsdt(rsdp);
}
int dflag; /* Disassemble AML using iasl(8) */
int tflag; /* Dump contents of SDT tables */
int vflag; /* Use verbose messages */
static void
usage(const char *progname)
{
printf("usage:\t%s [-r] [-o dsdt_file_for_output]\n", progname);
printf("\t%s [-r] [-f dsdt_file_for_input]\n", progname);
printf("\t%s [-h]\n", progname);
fprintf(stderr, "usage: %s [-d] [-t] [-h] [-v] [-f dsdt_input] "
"[-o dsdt_output]\n", progname);
exit(1);
}
@ -80,28 +53,87 @@ int
main(int argc, char *argv[])
{
char c, *progname;
char *dsdt_input_file, *dsdt_output_file;
struct ACPIsdt *sdt;
dsdt_input_file = dsdt_output_file = NULL;
progname = argv[0];
while ((c = getopt(argc, argv, "f:o:hr")) != -1) {
if (argc < 2)
usage(progname);
while ((c = getopt(argc, argv, "dhtvf:o:")) != -1) {
switch (c) {
case 'd':
dflag = 1;
break;
case 't':
tflag = 1;
break;
case 'v':
vflag = 1;
break;
case 'f':
asl_dump_from_file(optarg);
return (0);
dsdt_input_file = optarg;
break;
case 'o':
aml_dumpfile = optarg;
dsdt_output_file = optarg;
break;
case 'h':
usage(progname);
break;
case 'r':
rflag++;
break;
default:
argc -= optind;
argv += optind;
usage(progname);
/* NOTREACHED */
}
}
argc -= optind;
argv += optind;
asl_dump_from_devmem();
return (0);
/* Get input either from file or /dev/mem */
if (dsdt_input_file != NULL) {
if (dflag == 0 && tflag == 0) {
warnx("Need to specify -d or -t with DSDT input file");
usage(progname);
} else if (tflag != 0) {
warnx("Can't use -t with DSDT input file");
usage(progname);
}
if (vflag)
warnx("loading DSDT file: %s", dsdt_input_file);
sdt = dsdt_load_file(dsdt_input_file);
} else {
if (vflag)
warnx("loading RSD PTR from /dev/mem");
sdt = 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);
}
/* Translate RSDT to DSDT pointer */
if (dsdt_input_file == NULL) {
sdt = sdt_from_rsdt(sdt, "FACP");
sdt = dsdt_from_facp((struct FACPbody *)sdt->body);
}
/* 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);
}
/* Disassemble the DSDT into ASL */
if (dflag) {
if (vflag)
warnx("disassembling DSDT, iasl messages follow");
aml_disassemble(sdt);
if (vflag)
warnx("iasl processing complete");
}
exit(0);
}

View File

@ -24,7 +24,6 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: acpidump.h,v 1.3 2000/08/09 14:47:52 iwasaki Exp $
* $FreeBSD$
*/
@ -154,9 +153,9 @@ struct FACS {
u_int32_t g_lock; /* bit field */
/* 5.2.6.1 Global Lock */
#define ACPI_GLOBAL_LOCK_PENDING 1
#define ACPI_GLOBAL_LOCK_OWNED 2
#define ACPI_GLOBAL_LOCK_OWNED 2
u_int32_t flags; /* bit field */
#define ACPI_FACS_FLAG_S4BIOS_F 1 /* Supports S4BIOS_SEQ */
#define ACPI_FACS_FLAG_S4BIOS_F 1 /* Supports S4BIOS_SEQ */
char reserved[40];
} __packed;
@ -261,7 +260,7 @@ struct MADT_APIC {
struct MADTbody {
u_int32_t lapic_addr;
u_int32_t flags;
#define ACPI_APIC_FLAG_PCAT_COMPAT 1 /* Syetem has dual-8259 setup. */
#define ACPI_APIC_FLAG_PCAT_COMPAT 1 /* System has dual-8259 setup. */
u_char body[1];
} __packed;
@ -278,6 +277,7 @@ struct HPETbody {
u_int16_t clock_tick __packed;
} __packed;
#if 0
void *acpi_map_physical(vm_offset_t, size_t);
struct ACPIrsdp *acpi_find_rsd_ptr(void);
int acpi_checksum(void *, size_t);
@ -287,17 +287,39 @@ void acpi_print_sdt(struct ACPIsdt *);
void acpi_print_rsdt(struct ACPIsdt *);
void acpi_print_facp(struct FACPbody *);
void acpi_print_dsdt(struct ACPIsdt *);
void asl_dump_termobj(u_int8_t **, int);
void asl_dump_objectlist(u_int8_t **, u_int8_t *, int);
void aml_dump(struct ACPIsdt *);
void acpi_handle_rsdt(struct ACPIsdt *);
void acpi_load_dsdt(char *, u_int8_t **, u_int8_t **);
void acpi_dump_dsdt(u_int8_t *, u_int8_t *);
extern char *aml_dumpfile;
extern struct ACPIsdt dsdt_header;
extern int rflag;
#endif
/* Find and map the RSD PTR structure and return it for parsing */
struct ACPIsdt *sdt_load_devmem(void);
/*
* Load the DSDT from a previous save file. Note that other tables are
* not saved (i.e. FADT)
*/
struct ACPIsdt *dsdt_load_file(char *);
/* Save the DSDT to a file */
void dsdt_save_file(char *, 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 *);
/* 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 *dsdt_from_facp(struct FACPbody *);
int acpi_checksum(void *, size_t);
/* Command line flags */
extern int dflag;
extern int tflag;
extern int vflag;
#endif /* !_ACPIDUMP_H_ */

View File

@ -1,60 +0,0 @@
/*-
* Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: aml_dump.c,v 1.3 2000/08/08 14:12:21 iwasaki Exp $
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include "acpidump.h"
char *aml_dumpfile = NULL;
void
aml_dump(struct ACPIsdt *dsdp)
{
int fd;
mode_t mode;
if (aml_dumpfile == NULL) {
return;
}
mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
fd = open(aml_dumpfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
if (fd == -1) {
return;
}
write(fd, dsdp, SIZEOF_SDT_HDR);
write(fd, dsdp->body, dsdp->len - SIZEOF_SDT_HDR);
close(fd);
}

File diff suppressed because it is too large Load Diff