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$ # $FreeBSD$
PROG= acpidump PROG= acpidump
MAN= acpidump.8 MAN= acpidump.8
SRCS= acpi.c acpi_user.c asl_dump.c aml_dump.c acpidump.c SRCS= acpi.c acpi_user.c acpidump.c
SRCS+= aml_parse.c aml_name.c aml_amlmem.c aml_memman.c aml_store.c \ WARNS?= 6
aml_obj.c aml_evalobj.c aml_common.c
CFLAGS+= -I${.CURDIR}/../amldb
.include <bsd.prog.mk> .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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: acpi.c,v 1.4 2000/08/09 14:47:52 iwasaki Exp $
* $FreeBSD$ * $FreeBSD$
*/ */
#include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h>
#include <assert.h> #include <assert.h>
#include <err.h> #include <err.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include "acpidump.h" #include "acpidump.h"
#include "aml/aml_env.h"
#include "aml/aml_common.h"
#define BEGIN_COMMENT "/*\n" #define BEGIN_COMMENT "/*\n"
#define END_COMMENT " */\n" #define END_COMMENT " */\n"
struct ACPIsdt dsdt_header = { static void acpi_print_string(char *s, size_t length);
"DSDT", 0, 1, 0, "OEMID", "OEMTBLID", 0x12345678, "CRTR", 0x12345678 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,
static void u_int32_t flags);
acpi_trim_string(char *s, size_t length) 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);
/* Trim trailing spaces and NULLs */ static void acpi_print_intr(u_int32_t intr, u_int16_t mps_flags);
while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0')) static void acpi_print_apic(struct MADT_APIC *mp);
s[length-- - 1] = '\0'; 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 static void acpi_print_facp(struct FACPbody *facp);
acpi_print_dsdt_definition(void) static void acpi_print_dsdt(struct ACPIsdt *dsdp);
{ static struct ACPIsdt *
char oemid[6 + 1]; acpi_map_sdt(vm_offset_t pa);
char oemtblid[8 + 1]; static void acpi_print_rsd_ptr(struct ACPIrsdp *rp);
static void acpi_handle_rsdt(struct ACPIsdt *rsdp);
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 static void
acpi_print_string(char *s, size_t length) 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 static void
acpi_handle_facp(struct FACPbody *facp) acpi_handle_facp(struct FACPbody *facp)
{ {
struct ACPIsdt *dsdp; struct ACPIsdt *dsdp;
acpi_print_facp(facp); 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)) if (acpi_checksum(dsdp, dsdp->len))
errx(1, "DSDT is corrupt\n"); errx(1, "DSDT is corrupt");
acpi_handle_dsdt(dsdp); acpi_print_dsdt(dsdp);
aml_dump(dsdp);
} }
static void static void
@ -149,17 +117,9 @@ acpi_print_local_apic(u_char cpu_id, u_char apic_id, u_int32_t flags)
static void static void
acpi_print_io_apic(u_char apic_id, u_int32_t int_base, u_int64_t apic_addr) 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("\tAPIC ID=%d\n", (u_int)apic_id);
printf("\tINT BASE=%d\n", int_base); printf("\tINT BASE=%d\n", int_base);
printf("\tADDR=0x"); printf("\tADDR=0x%016jx\n", apic_addr);
addr_hi = apic_addr >> 32;
if (addr_hi != 0) {
printf("%08x", addr_hi);
apic_addr &= 0xffffffff;
}
printf("%08x\n", (u_int)apic_addr);
} }
static void static void
@ -242,9 +202,8 @@ acpi_print_apic(struct MADT_APIC *mp)
acpi_print_mps_flags(mp->body.local_nmi.mps_flags); acpi_print_mps_flags(mp->body.local_nmi.mps_flags);
break; break;
case ACPI_MADT_APIC_TYPE_LOCAL_OVERRIDE: case ACPI_MADT_APIC_TYPE_LOCAL_OVERRIDE:
printf("\tLocal APIC ADDR=0x%08x%08x\n", printf("\tLocal APIC ADDR=0x%016jx\n",
(u_int)(mp->body.local_apic_override.apic_addr >> 32), mp->body.local_apic_override.apic_addr);
(u_int)(mp->body.local_apic_override.apic_addr & 0xffffffff));
break; break;
case ACPI_MADT_APIC_TYPE_IO_SAPIC: case ACPI_MADT_APIC_TYPE_IO_SAPIC:
acpi_print_io_apic(mp->body.io_sapic.apic_id, acpi_print_io_apic(mp->body.io_sapic.apic_id,
@ -268,6 +227,7 @@ acpi_print_apic(struct MADT_APIC *mp)
break; break;
default: default:
printf("\tUnknown type %d\n", (u_int)mp->type); printf("\tUnknown type %d\n", (u_int)mp->type);
break;
} }
} }
@ -277,15 +237,14 @@ acpi_handle_apic(struct ACPIsdt *sdp)
struct MADTbody *madtp; struct MADTbody *madtp;
struct MADT_APIC *madt_apicp; struct MADT_APIC *madt_apicp;
acpi_print_sdt(sdp); acpi_print_sdt(sdp, /*endcomment*/0);
madtp = (struct MADTbody *) sdp->body; madtp = (struct MADTbody *) sdp->body;
printf(BEGIN_COMMENT);
printf("\tLocal APIC ADDR=0x%08x\n", madtp->lapic_addr); printf("\tLocal APIC ADDR=0x%08x\n", madtp->lapic_addr);
printf("\tFlags={"); printf("\tFlags={");
if (madtp->flags & ACPI_APIC_FLAG_PCAT_COMPAT) if (madtp->flags & ACPI_APIC_FLAG_PCAT_COMPAT)
printf("PC-AT"); printf("PC-AT");
printf("}\n"); 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) { while (((uintptr_t)madt_apicp) - ((uintptr_t)sdp) < sdp->len) {
printf("\n"); printf("\n");
acpi_print_apic(madt_apicp); acpi_print_apic(madt_apicp);
@ -300,9 +259,8 @@ acpi_handle_hpet(struct ACPIsdt *sdp)
{ {
struct HPETbody *hpetp; struct HPETbody *hpetp;
acpi_print_sdt(sdp); acpi_print_sdt(sdp, /*endcomment*/0);
hpetp = (struct HPETbody *) sdp->body; hpetp = (struct HPETbody *) sdp->body;
printf(BEGIN_COMMENT);
printf("\tHPET Number=%d\n", hpetp->hpet_number); printf("\tHPET Number=%d\n", hpetp->hpet_number);
printf("\tADDR=0x%08x\n", hpetp->base_addr); printf("\tADDR=0x%08x\n", hpetp->base_addr);
printf("\tHW Rev=0x%x\n", hpetp->block_hwrev); printf("\tHW Rev=0x%x\n", hpetp->block_hwrev);
@ -319,58 +277,9 @@ acpi_handle_hpet(struct ACPIsdt *sdp)
} }
static void static void
init_namespace() acpi_print_sdt(struct ACPIsdt *sdp, int endcomment)
{ {
struct aml_environ env; printf(BEGIN_COMMENT " ");
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);
acpi_print_string(sdp->signature, 4); acpi_print_string(sdp->signature, 4);
printf(": Length=%d, Revision=%d, Checksum=%d,\n", printf(": Length=%d, Revision=%d, Checksum=%d,\n",
sdp->len, sdp->rev, sdp->check); sdp->len, sdp->rev, sdp->check);
@ -382,20 +291,17 @@ acpi_print_sdt(struct ACPIsdt *sdp)
printf("\tCreator ID="); printf("\tCreator ID=");
acpi_print_string(sdp->creator, 4); acpi_print_string(sdp->creator, 4);
printf(", Creator Revision=0x%x\n", sdp->crerev); printf(", Creator Revision=0x%x\n", sdp->crerev);
printf(END_COMMENT); if (endcomment)
if (!memcmp(sdp->signature, "DSDT", 4)) { printf(END_COMMENT);
memcpy(&dsdt_header, sdp, sizeof(dsdt_header));
}
} }
void static void
acpi_print_rsdt(struct ACPIsdt *rsdp) acpi_print_rsdt(struct ACPIsdt *rsdp)
{ {
int i, entries; int i, entries;
acpi_print_sdt(rsdp); acpi_print_sdt(rsdp, /*endcomment*/0);
entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t); entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t);
printf(BEGIN_COMMENT);
printf("\tEntries={ "); printf("\tEntries={ ");
for (i = 0; i < entries; i++) { for (i = 0; i < entries; i++) {
if (i > 0) if (i > 0)
@ -406,13 +312,13 @@ acpi_print_rsdt(struct ACPIsdt *rsdp)
printf(END_COMMENT); printf(END_COMMENT);
} }
void static void
acpi_print_facp(struct FACPbody *facp) acpi_print_facp(struct FACPbody *facp)
{ {
char sep; char sep;
printf(BEGIN_COMMENT); 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("\tINT_MODEL=%s\n", facp->int_model ? "APIC" : "PIC");
printf("\tSCI_INT=%d\n", facp->sci_int); printf("\tSCI_INT=%d\n", facp->sci_int);
printf("\tSMI_CMD=0x%x, ", facp->smi_cmd); printf("\tSMI_CMD=0x%x, ", facp->smi_cmd);
@ -486,11 +392,10 @@ acpi_print_facp(struct FACPbody *facp)
printf(END_COMMENT); printf(END_COMMENT);
} }
void static void
acpi_print_dsdt(struct ACPIsdt *dsdp) acpi_print_dsdt(struct ACPIsdt *dsdp)
{ {
acpi_print_sdt(dsdp, /*endcomment*/1);
acpi_print_sdt(dsdp);
} }
int int
@ -507,7 +412,7 @@ acpi_checksum(void *p, size_t length)
return (sum); return (sum);
} }
struct ACPIsdt * static struct ACPIsdt *
acpi_map_sdt(vm_offset_t pa) acpi_map_sdt(vm_offset_t pa)
{ {
struct ACPIsdt *sp; struct ACPIsdt *sp;
@ -517,18 +422,18 @@ acpi_map_sdt(vm_offset_t pa)
return (sp); return (sp);
} }
void static void
acpi_print_rsd_ptr(struct ACPIrsdp *rp) acpi_print_rsd_ptr(struct ACPIrsdp *rp)
{ {
printf(BEGIN_COMMENT); 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); acpi_print_string(rp->oem, 6);
printf(", RsdtAddress=0x%08x\n", rp->rsdt_addr); printf(", RsdtAddress=0x%08x\n", rp->rsdt_addr);
printf(END_COMMENT); printf(END_COMMENT);
} }
void static void
acpi_handle_rsdt(struct ACPIsdt *rsdp) acpi_handle_rsdt(struct ACPIsdt *rsdp)
{ {
int i; int i;
@ -538,100 +443,134 @@ acpi_handle_rsdt(struct ACPIsdt *rsdp)
entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t); entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t);
acpi_print_rsdt(rsdp); acpi_print_rsdt(rsdp);
for (i = 0; i < entries; i++) { 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)) if (acpi_checksum(sdp, sdp->len))
errx(1, "RSDT entry %d is corrupt\n", i); errx(1, "RSDT entry %d is corrupt", i);
if (!memcmp(sdp->signature, "FACP", 4)) { if (!memcmp(sdp->signature, "FACP", 4))
acpi_handle_facp((struct FACPbody *) sdp->body); 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); acpi_handle_apic(sdp);
} else if (!memcmp(sdp->signature, "HPET", 4)) { else if (!memcmp(sdp->signature, "HPET", 4))
acpi_handle_hpet(sdp); acpi_handle_hpet(sdp);
} else { else
acpi_print_sdt(sdp); acpi_print_sdt(sdp, /*endcomment*/1);
}
} }
} }
/* struct ACPIsdt *
* Dummy functions 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 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 void
aml_region_read_simple(struct aml_region_handle *h, vm_offset_t offset, aml_disassemble(struct ACPIsdt *dsdp)
u_int32_t *valuep)
{ {
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 void
aml_region_write_simple(struct aml_region_handle *h, vm_offset_t offset, sdt_print_all(struct ACPIsdt *rsdp)
u_int32_t value)
{ {
return (0); acpi_handle_rsdt(rsdp);
} }
u_int32_t /* Fetch a table matching the given signature via the RSDT */
aml_region_prompt_read(struct aml_region_handle *h, u_int32_t value) 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 struct ACPIsdt *
aml_region_prompt_write(struct aml_region_handle *h, u_int32_t value) dsdt_from_facp(struct FACPbody *facp)
{ {
return (0); struct ACPIsdt *sdt;
}
int sdt = (struct ACPIsdt *)acpi_map_sdt(facp->dsdt_ptr);
aml_region_prompt_update_value(u_int32_t orgval, u_int32_t value, if (acpi_checksum(sdt, sdt->len))
struct aml_region_handle *h) errx(1, "DSDT is corrupt\n");
{ return (sdt);
return (0);
} }
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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: acpi_user.c,v 1.5 2000/08/09 14:47:52 iwasaki Exp $
* $FreeBSD$ * $FreeBSD$
*/ */
@ -32,6 +31,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/queue.h> #include <sys/queue.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/sysctl.h>
#include <err.h> #include <err.h>
#include <fcntl.h> #include <fcntl.h>
@ -41,8 +41,7 @@
#include "acpidump.h" #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; static int acpi_mem_fd = -1;
struct acpi_user_mapping { struct acpi_user_mapping {
@ -55,7 +54,7 @@ struct acpi_user_mapping {
LIST_HEAD(acpi_user_mapping_list, acpi_user_mapping) maplist; LIST_HEAD(acpi_user_mapping_list, acpi_user_mapping) maplist;
static void static void
acpi_user_init() acpi_user_init(void)
{ {
if (acpi_mem_fd == -1) { if (acpi_mem_fd == -1) {
@ -96,31 +95,32 @@ acpi_user_find_mapping(vm_offset_t pa, size_t size)
/* /*
* Public interfaces * Public interfaces
*/ */
struct ACPIrsdp * struct ACPIrsdp *
acpi_find_rsd_ptr() acpi_find_rsd_ptr()
{ {
struct ACPIrsdp rsdp; struct ACPIrsdp rsdp;
u_long addr; u_long addr;
int len; size_t len;
acpi_user_init(); acpi_user_init();
/* Attempt to use sysctl to find RSD PTR record */
len = sizeof(addr); len = sizeof(addr);
if (sysctlbyname(machdep_acpi_root, &addr, &len, NULL, 0) == 0) { if (sysctlbyname(machdep_acpi_root, &addr, &len, NULL, 0) == 0) {
pread(acpi_mem_fd, &rsdp, sizeof(rsdp), addr); pread(acpi_mem_fd, &rsdp, sizeof(rsdp), addr);
if (memcmp(rsdp.signature, "RSD PTR ", 8)) if (memcmp(rsdp.signature, "RSD PTR ", 8) != 0)
errx(1, "sysctl %s does not point to RSDP\n", errx(1, "sysctl %s does not point to RSDP",
machdep_acpi_root); machdep_acpi_root);
len = 20; /* size of ACPI 1.0 table */ len = 20; /* size of ACPI 1.0 table */
if (acpi_checksum(&rsdp, len)) if (acpi_checksum(&rsdp, len))
warnx("RSDP has invalid checksum\n"); warnx("RSDP has invalid checksum");
if (rsdp.revision > 0) if (rsdp.revision > 0)
len = rsdp.length; len = rsdp.length;
return (acpi_map_physical(addr, len)); 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) { for (addr = 0UL; addr < 1024UL * 1024UL; addr += 16UL) {
pread(acpi_mem_fd, &rsdp, 8, addr); pread(acpi_mem_fd, &rsdp, 8, addr);
if (memcmp(rsdp.signature, "RSD PTR ", 8)) 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)); return (map->va + (pa - map->pa));
} }
void struct ACPIsdt *
acpi_load_dsdt(char *dumpfile, u_int8_t **dpp, u_int8_t **endp) dsdt_load_file(char *infile)
{ {
u_int8_t *dp; struct ACPIsdt *sdt;
u_int8_t *end; uint8_t *dp;
struct stat sb; struct stat sb;
if ((acpi_mem_fd = open(dumpfile, O_RDONLY)) == -1) { if ((acpi_mem_fd = open(infile, O_RDONLY)) == -1)
errx(1, "opening %s\n", dumpfile); errx(1, "opening %s", infile);
}
LIST_INIT(&maplist); LIST_INIT(&maplist);
if (fstat(acpi_mem_fd, &sb) == -1) { if (fstat(acpi_mem_fd, &sb) == -1)
errx(1, "fstat %s\n", dumpfile); errx(1, "fstat %s", infile);
}
dp = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, acpi_mem_fd, 0); dp = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, acpi_mem_fd, 0);
if (dp == NULL) { if (dp == NULL)
errx(1, "mmap %s\n", dumpfile); errx(1, "mmap %s", infile);
}
if (strncmp(dp, "DSDT", 4) == 0) { sdt = (struct ACPIsdt *)dp;
memcpy(&dsdt_header, dp, SIZEOF_SDT_HDR); if (strncmp(dp, "DSDT", 4) != 0 || acpi_checksum(sdt, sdt->len) != 0)
dp += SIZEOF_SDT_HDR; return (NULL);
sb.st_size -= SIZEOF_SDT_HDR;
}
end = (u_int8_t *) dp + sb.st_size; return (sdt);
*dpp = dp;
*endp = end;
} }

View File

@ -34,47 +34,45 @@
.Os .Os
.Sh NAME .Sh NAME
.Nm acpidump .Nm acpidump
.Nd dump ACPI tables .Nd dump ACPI tables and ASL
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl r .Op Fl d
.Nm .Op Fl t
.Op Fl r .Op Fl h
.Op Fl o Ar dsdt_file_for_output .Op Fl v
.Nm .Op Fl f Ar dsdt_input
.Op Fl r .Op Fl o Ar dsdt_output
.Op Fl f Ar dsdt_file_for_input
.Sh DESCRIPTION .Sh DESCRIPTION
The The
.Nm .Nm
utility analyzes ACPI tables in physical memory and dumps them to utility analyzes ACPI tables in physical memory and can dump them to a file.
standard output.
In addition, In addition,
.Nm .Nm
can disassemble AML can call
.Xr iasl 8
to disassemble AML
(ACPI Machine Language) (ACPI Machine Language)
found in these tables and dump them as ASL found in these tables and dump them as ASL
(ACPI Source Language). (ACPI Source Language)
to stdout.
.Pp .Pp
ACPI tables have an essential data block (the DSDT, 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 that includes information used on the kernel side such as
detailed information about PnP hardware, procedures for controlling detailed information about PnP hardware, procedures for controlling
power management support and so on. power management support, and so on.
The The
.Nm .Nm
utility can extract the DSDT data block from physical memory and store it into 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 a DSDT output file and optionally also disassemble it.
from a given DSDT data file.
.Pp .Pp
When When
.Nm .Nm
is invoked without the is invoked without the
.Fl f .Fl f
option, it will read ACPI tables from physical option, it will read ACPI tables from physical memory via
memory via a special file .Pa /dev/mem .
.Pa /dev/mem
and dump them.
First it searches for the RSDP First it searches for the RSDP
(Root System Description Pointer), (Root System Description Pointer),
which has the signature which has the signature
@ -89,65 +87,74 @@ called SDTs
and their header has a common format which consists of items and their header has a common format which consists of items
such as Signature, Length, Revision, Checksum, OEMID, OEM Table ID, such as Signature, Length, Revision, Checksum, OEMID, OEM Table ID,
OEM Revision, Creator ID and Creator Revision. OEM Revision, Creator ID and Creator Revision.
The When invoked with the
.Fl t
flag, the
.Nm .Nm
utility dumps contents of these SDTs. utility dumps contents of the following tables:
For further information about formats of each table,
see chapter 5:
.Dq ACPI Software Programming Model
from the ACPI specifications referenced below.
.Pp .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). (Fixed ACPI Description Table).
The FACP defines static system information about power management support The FACP defines static system information about power management support
(ACPI Hardware Register Implementation) (ACPI Hardware Register Implementation)
such as interrupt mode such as interrupt mode (INT_MODEL),
(INT_MODEL), SCI interrupt number, SMI command port (SMI_CMD)
SCI interrupt number, SMI command port and the location of ACPI registers.
(SMI_CMD) The FACP also has a pointer to a physical memory address for the DSDT.
and location of ACPI registers. While the other tables are fixed format,
The FACP also has a pointer to a physical memory address for DSDT, the DSDT consists of free-formatted AML data.
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.
.Sh OPTIONS .Sh OPTIONS
The following options are supported by The following options are supported by
.Nm : .Nm :
.Bl -tag -width indent .Bl -tag -width indent
.It Fl o Ar dsdt_file_for_output .It Fl d
Stores DSDT data block from physical memory into a file specified in Disassemble the DSDT into ASL using
.Ar dsdt_file_for_output .Xr iasl 8
in addition to behavior with no option. and print the results to stdout.
.It Fl f Ar dsdt_file_for_input .It Fl t
Interprets AML data in DSDT from a file specified in Dump the contents of the various fixed tables listed above.
.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 h .It Fl h
Displays usage and exit. 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 .El
.Sh EXAMPLES .Sh EXAMPLES
This is an example to get a dump of SDTs and a DSDT data file This example dumps the DSDT from physical memory to foo.dsdt.
simultaneously on a machine that supports ACPI BIOS. 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 .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 .Ed
.Sh BUGS .Sh BUGS
In the current implementation, In the current implementation,
.Nm .Nm
doesn't dump any information of Firmware ACPI Control Structure doesn't dump the Firmware ACPI Control Structure (FACS),
(FACS) Secondary System Descriptor Table (SSDT),
specified by a pointer in FACP. Embedded Controller Descriptor Table (ECDT),
or BOOT structures.
.Sh FILES .Sh FILES
.Bl -tag -width /dev/mem .Bl -tag -width /dev/mem
.It Pa /dev/mem .It Pa /dev/mem
@ -156,16 +163,8 @@ specified by a pointer in FACP.
.Xr acpi 4 , .Xr acpi 4 ,
.Xr mem 4 , .Xr mem 4 ,
.Xr acpiconf 8 , .Xr acpiconf 8 ,
.Xr amldb 8 .Xr acpidb 8 ,
.Pp .Xr iasl 8
.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/>
.Sh AUTHORS .Sh AUTHORS
.An Doug Rabson Aq dfr@FreeBSD.org .An Doug Rabson Aq dfr@FreeBSD.org
.An Mitsuru IWASAKI Aq iwasaki@FreeBSD.org .An Mitsuru IWASAKI Aq iwasaki@FreeBSD.org
@ -183,5 +182,9 @@ and
.Sh HISTORY .Sh HISTORY
The The
.Nm .Nm
utility appeared in utility first appeared in
.Fx 5.0 . .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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: acpidump.c,v 1.3 2000/08/08 14:12:21 iwasaki Exp $
* $FreeBSD$ * $FreeBSD$
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <assert.h> #include <assert.h>
#include <err.h> #include <err.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include "acpidump.h" #include "acpidump.h"
static void int dflag; /* Disassemble AML using iasl(8) */
asl_dump_from_file(char *file) int tflag; /* Dump contents of SDT tables */
{ int vflag; /* Use verbose messages */
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);
}
static void static void
usage(const char *progname) usage(const char *progname)
{ {
printf("usage:\t%s [-r] [-o dsdt_file_for_output]\n", progname); fprintf(stderr, "usage: %s [-d] [-t] [-h] [-v] [-f dsdt_input] "
printf("\t%s [-r] [-f dsdt_file_for_input]\n", progname); "[-o dsdt_output]\n", progname);
printf("\t%s [-h]\n", progname);
exit(1); exit(1);
} }
@ -80,28 +53,87 @@ int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char c, *progname; char c, *progname;
char *dsdt_input_file, *dsdt_output_file;
struct ACPIsdt *sdt;
dsdt_input_file = dsdt_output_file = NULL;
progname = argv[0]; 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) { switch (c) {
case 'd':
dflag = 1;
break;
case 't':
tflag = 1;
break;
case 'v':
vflag = 1;
break;
case 'f': case 'f':
asl_dump_from_file(optarg); dsdt_input_file = optarg;
return (0); break;
case 'o': case 'o':
aml_dumpfile = optarg; dsdt_output_file = optarg;
break; break;
case 'h': case 'h':
usage(progname);
break;
case 'r':
rflag++;
break;
default: default:
argc -= optind; usage(progname);
argv += optind; /* NOTREACHED */
} }
} }
argc -= optind;
argv += optind;
asl_dump_from_devmem(); /* Get input either from file or /dev/mem */
return (0); 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: acpidump.h,v 1.3 2000/08/09 14:47:52 iwasaki Exp $
* $FreeBSD$ * $FreeBSD$
*/ */
@ -154,9 +153,9 @@ struct FACS {
u_int32_t g_lock; /* bit field */ u_int32_t g_lock; /* bit field */
/* 5.2.6.1 Global Lock */ /* 5.2.6.1 Global Lock */
#define ACPI_GLOBAL_LOCK_PENDING 1 #define ACPI_GLOBAL_LOCK_PENDING 1
#define ACPI_GLOBAL_LOCK_OWNED 2 #define ACPI_GLOBAL_LOCK_OWNED 2
u_int32_t flags; /* bit field */ 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]; char reserved[40];
} __packed; } __packed;
@ -261,7 +260,7 @@ struct MADT_APIC {
struct MADTbody { struct MADTbody {
u_int32_t lapic_addr; u_int32_t lapic_addr;
u_int32_t flags; 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]; u_char body[1];
} __packed; } __packed;
@ -278,6 +277,7 @@ struct HPETbody {
u_int16_t clock_tick __packed; u_int16_t clock_tick __packed;
} __packed; } __packed;
#if 0
void *acpi_map_physical(vm_offset_t, size_t); void *acpi_map_physical(vm_offset_t, size_t);
struct ACPIrsdp *acpi_find_rsd_ptr(void); struct ACPIrsdp *acpi_find_rsd_ptr(void);
int acpi_checksum(void *, size_t); 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_rsdt(struct ACPIsdt *);
void acpi_print_facp(struct FACPbody *); void acpi_print_facp(struct FACPbody *);
void acpi_print_dsdt(struct ACPIsdt *); 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_handle_rsdt(struct ACPIsdt *);
void acpi_load_dsdt(char *, u_int8_t **, u_int8_t **); void acpi_load_dsdt(char *, u_int8_t **, u_int8_t **);
void acpi_dump_dsdt(u_int8_t *, u_int8_t *); void acpi_dump_dsdt(u_int8_t *, u_int8_t *);
extern char *aml_dumpfile; #endif
extern struct ACPIsdt dsdt_header;
extern int rflag; /* 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_ */ #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