From c62f1ccc6f6ee8d63c70c63d4ceb739e6c45aa26 Mon Sep 17 00:00:00 2001 From: Mitsuru IWASAKI Date: Mon, 22 Oct 2001 17:25:32 +0000 Subject: [PATCH] Fix UserTerms disassembling. Now that dumped ASL can be compiled with ports/devel/acpitools (iasl). - Merge AML parser to build ACPI namespace - Comment header info. out so that ASL compiler ignore them - Fix DSDT header size to be discarded when DSDT file is specified for input (acpidump and amldb) - Write DSDT header as well into DSDT file for output - Fix some trivial typo (Concatenate and SizeOf) - Remove DEBUG_FLAGS from Makefile (acpidump and amldb) --- usr.sbin/acpi/acpidump/Makefile | 5 +- usr.sbin/acpi/acpidump/acpi.c | 187 ++++++++++++++++++++++++++++- usr.sbin/acpi/acpidump/acpi_user.c | 13 +- usr.sbin/acpi/acpidump/acpidump.8 | 4 - usr.sbin/acpi/acpidump/acpidump.c | 3 +- usr.sbin/acpi/acpidump/acpidump.h | 5 +- usr.sbin/acpi/acpidump/aml_dump.c | 8 +- usr.sbin/acpi/acpidump/asl_dump.c | 68 ++++++++++- usr.sbin/acpi/amldb/Makefile | 1 - usr.sbin/acpi/amldb/amldb.c | 7 +- 10 files changed, 266 insertions(+), 35 deletions(-) diff --git a/usr.sbin/acpi/acpidump/Makefile b/usr.sbin/acpi/acpidump/Makefile index bb7a454b2db0..9000dd913097 100644 --- a/usr.sbin/acpi/acpidump/Makefile +++ b/usr.sbin/acpi/acpidump/Makefile @@ -4,7 +4,10 @@ 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 -#DEBUG_FLAGS= -g +CFLAGS+= -I${.CURDIR}/../amldb .include +.PATH: ${.CURDIR}/../amldb/aml diff --git a/usr.sbin/acpi/acpidump/acpi.c b/usr.sbin/acpi/acpidump/acpi.c index 1523b0ef518d..da5c3861b52b 100644 --- a/usr.sbin/acpi/acpidump/acpi.c +++ b/usr.sbin/acpi/acpidump/acpi.c @@ -39,6 +39,48 @@ #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 ( + \"acpi_dsdt.aml\", //Output filename + \"DSDT\", //Signature + 0x%x, //DSDT Revision + \"%s\", //OEMID + \"%s\", //TABLE ID + 0x%x //OEM Revision\n)\n", + dsdt_header.rev, oemid, oemtblid, dsdt_header.oemrev); +} + static void acpi_print_string(char *s, size_t length) { @@ -63,8 +105,8 @@ acpi_handle_dsdt(struct ACPIsdt *dsdp) acpi_print_dsdt(dsdp); dp = (u_int8_t *)dsdp->body; end = (u_int8_t *)dsdp + dsdp->len; - asl_dump_objectlist(&dp, end, 0); - assert(dp == end); + + acpi_dump_dsdt(dp, end); } static void @@ -77,19 +119,63 @@ acpi_handle_facp(struct FACPbody *facp) if (acpi_checksum(dsdp, dsdp->len)) errx(1, "DSDT is corrupt\n"); acpi_handle_dsdt(dsdp); - aml_dump(dsdp->body, dsdp->len - SIZEOF_SDT_HDR); + aml_dump(dsdp); +} + +static void +init_namespace() +{ + 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); acpi_print_string(sdp->signature, 4); - printf(": Lenth=%d, Revision=%d, Checksum=%d,\n", + printf(": Length=%d, Revision=%d, Checksum=%d,\n", sdp->len, sdp->rev, sdp->check); printf("\tOEMID="); acpi_print_string(sdp->oemid, 6); @@ -99,6 +185,10 @@ 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)); + } } void @@ -108,6 +198,7 @@ acpi_print_rsdt(struct ACPIsdt *rsdp) acpi_print_sdt(rsdp); entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t); + printf(BEGIN_COMMENT); printf("\tEntries={ "); for (i = 0; i < entries; i++) { if (i > 0) @@ -115,6 +206,7 @@ acpi_print_rsdt(struct ACPIsdt *rsdp) printf("0x%08x", rsdp->body[i]); } printf(" }\n"); + printf(END_COMMENT); } void @@ -122,6 +214,7 @@ acpi_print_facp(struct FACPbody *facp) { char sep; + printf(BEGIN_COMMENT); printf("\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); @@ -193,6 +286,7 @@ acpi_print_facp(struct FACPbody *facp) #undef PRINTFLAG printf("}\n"); + printf(END_COMMENT); } void @@ -230,9 +324,11 @@ void acpi_print_rsd_ptr(struct ACPIrsdp *rp) { + printf(BEGIN_COMMENT); printf("RSD PTR: Checksum=%d, OEMID=", rp->sum); acpi_print_string(rp->oem, 6); printf(", RsdtAddress=0x%08x\n", rp->addr); + printf(END_COMMENT); } void @@ -255,3 +351,86 @@ acpi_handle_rsdt(struct ACPIsdt *rsdp) } } } + +/* + * Dummy functions + */ + +void +aml_dbgr(struct aml_environ *env1, struct aml_environ *env2) +{ + /* do nothing */ +} + +int +aml_region_read_simple(struct aml_region_handle *h, vm_offset_t offset, + u_int32_t *valuep) +{ + return (0); +} + +int +aml_region_write_simple(struct aml_region_handle *h, vm_offset_t offset, + u_int32_t value) +{ + return (0); +} + +u_int32_t +aml_region_prompt_read(struct aml_region_handle *h, u_int32_t value) +{ + return (0); +} + +u_int32_t +aml_region_prompt_write(struct aml_region_handle *h, u_int32_t value) +{ + return (0); +} + +int +aml_region_prompt_update_value(u_int32_t orgval, u_int32_t value, + struct aml_region_handle *h) +{ + 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); +} + diff --git a/usr.sbin/acpi/acpidump/acpi_user.c b/usr.sbin/acpi/acpidump/acpi_user.c index 4691247b7f73..c6a8d997053f 100644 --- a/usr.sbin/acpi/acpidump/acpi_user.c +++ b/usr.sbin/acpi/acpidump/acpi_user.c @@ -149,14 +149,11 @@ acpi_load_dsdt(char *dumpfile, u_int8_t **dpp, u_int8_t **endp) errx(1, "mmap %s\n", dumpfile); } - /* - * Microsoft asl.exe generates 0x23 byte additional info. - * at the begining of the file, so just ignore it. - */ - if (strncmp(dp, "DSDT", 4) == 0) { - dp += 0x23; - sb.st_size -= 0x23; - } + if (strncmp(dp, "DSDT", 4) == 0) { + memcpy(&dsdt_header, dp, SIZEOF_SDT_HDR); + dp += SIZEOF_SDT_HDR; + sb.st_size -= SIZEOF_SDT_HDR; + } end = (u_int8_t *) dp + sb.st_size; *dpp = dp; diff --git a/usr.sbin/acpi/acpidump/acpidump.8 b/usr.sbin/acpi/acpidump/acpidump.8 index 4363c6b58b7e..f37ae54f1b39 100644 --- a/usr.sbin/acpi/acpidump/acpidump.8 +++ b/usr.sbin/acpi/acpidump/acpidump.8 @@ -133,10 +133,6 @@ In the current implementation, doesn't dump any information of Firmware ACPI Control Structure (FACS) specified by a pointer in FACP. -Some parts of output in ASL are incomplete. To obtain a complete -output, it would need to change the implementation into another one -that analyzes a whole DSDT and builds an ACPI namespace as preprocess, -and then interprets the DSDT again referring to namespace. .Sh FILES .Bl -tag -width /dev/mem .It Pa /dev/mem diff --git a/usr.sbin/acpi/acpidump/acpidump.c b/usr.sbin/acpi/acpidump/acpidump.c index 765f4fe217c4..c7ca5d271b96 100644 --- a/usr.sbin/acpi/acpidump/acpidump.c +++ b/usr.sbin/acpi/acpidump/acpidump.c @@ -41,9 +41,10 @@ asl_dump_from_file(char *file) { u_int8_t *dp; u_int8_t *end; + struct ACPIsdt *dsdt; acpi_load_dsdt(file, &dp, &end); - asl_dump_objectlist(&dp, end, 0); + acpi_dump_dsdt(dp, end); } static void diff --git a/usr.sbin/acpi/acpidump/acpidump.h b/usr.sbin/acpi/acpidump/acpidump.h index 37e3d6d5ce06..29905ed6d7b2 100644 --- a/usr.sbin/acpi/acpidump/acpidump.h +++ b/usr.sbin/acpi/acpidump/acpidump.h @@ -169,11 +169,12 @@ 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(u_int32_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; #endif /* !_ACPIDUMP_H_ */ diff --git a/usr.sbin/acpi/acpidump/aml_dump.c b/usr.sbin/acpi/acpidump/aml_dump.c index 5901baae1a73..434001fbda6e 100644 --- a/usr.sbin/acpi/acpidump/aml_dump.c +++ b/usr.sbin/acpi/acpidump/aml_dump.c @@ -39,7 +39,7 @@ char *aml_dumpfile = NULL; void -aml_dump(u_int32_t *ptr, int len) +aml_dump(struct ACPIsdt *dsdp) { int fd; mode_t mode; @@ -49,10 +49,12 @@ aml_dump(u_int32_t *ptr, int len) } mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - fd = open(aml_dumpfile, O_WRONLY | O_CREAT, mode); + fd = open(aml_dumpfile, O_WRONLY | O_CREAT | O_TRUNC, mode); if (fd == -1) { return; } - write(fd, ptr, len); + write(fd, dsdp, SIZEOF_SDT_HDR); + write(fd, dsdp->body, dsdp->len - SIZEOF_SDT_HDR); close(fd); } + diff --git a/usr.sbin/acpi/acpidump/asl_dump.c b/usr.sbin/acpi/acpidump/asl_dump.c index 9e7706b030a6..58f71f643459 100644 --- a/usr.sbin/acpi/acpidump/asl_dump.c +++ b/usr.sbin/acpi/acpidump/asl_dump.c @@ -36,6 +36,10 @@ #include "acpidump.h" +#include "aml/aml_env.h" + +struct aml_environ asl_env; + static u_int32_t asl_dump_pkglength(u_int8_t **dpp) { @@ -184,6 +188,19 @@ print_indent(int indent) printf(" "); } +#define ASL_ENTER_SCOPE(dp_orig, old_name) do { \ + u_int8_t *dp_copy; \ + u_int8_t *name; \ + old_name = asl_env.curname; \ + dp_copy = dp_orig; \ + name = asl_dump_namestring(&dp_copy); \ + asl_env.curname = aml_search_name(&asl_env, name); \ +} while(0) + +#define ASL_LEAVE_SCOPE(old_name) do { \ + asl_env.curname = old_name; \ +} while(0) + static void asl_dump_defscope(u_int8_t **dpp, int indent) { @@ -191,12 +208,14 @@ asl_dump_defscope(u_int8_t **dpp, int indent) u_int8_t *start; u_int8_t *end; u_int32_t pkglength; + struct aml_name *oname; dp = *dpp; start = dp; pkglength = asl_dump_pkglength(&dp); printf("Scope("); + ASL_ENTER_SCOPE(dp, oname); asl_dump_termobj(&dp, indent); printf(") {\n"); end = start + pkglength; @@ -205,7 +224,7 @@ asl_dump_defscope(u_int8_t **dpp, int indent) printf("}"); assert(dp == end); - + ASL_LEAVE_SCOPE(oname); *dpp = dp; } @@ -263,6 +282,8 @@ asl_dump_defpackage(u_int8_t **dpp, int indent) *dpp = dp; } +int scope_within_method = 0; + static void asl_dump_defmethod(u_int8_t **dpp, int indent) { @@ -271,12 +292,14 @@ asl_dump_defmethod(u_int8_t **dpp, int indent) u_int8_t *end; u_int8_t flags; u_int32_t pkglength; + struct aml_name *oname; dp = *dpp; start = dp; pkglength = asl_dump_pkglength(&dp); printf("Method("); + ASL_ENTER_SCOPE(dp, oname); asl_dump_termobj(&dp, indent); flags = *dp++; if (flags) { @@ -287,12 +310,14 @@ asl_dump_defmethod(u_int8_t **dpp, int indent) } printf(") {\n"); end = start + pkglength; + scope_within_method = 1; asl_dump_objectlist(&dp, end, indent + 1); + scope_within_method = 0; print_indent(indent); printf("}"); assert(dp == end); - + ASL_LEAVE_SCOPE(oname); *dpp = dp; } @@ -506,6 +531,7 @@ asl_dump_defdevice(u_int8_t **dpp, int indent) u_int8_t *start; u_int8_t *end; u_int32_t pkglength; + struct aml_name *oname; dp = *dpp; start = dp; @@ -513,6 +539,7 @@ asl_dump_defdevice(u_int8_t **dpp, int indent) end = start + pkglength; printf("Device("); + ASL_ENTER_SCOPE(dp, oname); asl_dump_termobj(&dp, indent); printf(") {\n"); asl_dump_objectlist(&dp, end, indent + 1); @@ -521,6 +548,7 @@ asl_dump_defdevice(u_int8_t **dpp, int indent) assert(dp == end); + ASL_LEAVE_SCOPE(oname); *dpp = dp; } @@ -534,6 +562,7 @@ asl_dump_defprocessor(u_int8_t **dpp, int indent) u_int8_t pblklen; u_int32_t pkglength; u_int32_t pblkaddr; + struct aml_name *oname; dp = *dpp; start = dp; @@ -541,6 +570,7 @@ asl_dump_defprocessor(u_int8_t **dpp, int indent) end = start + pkglength; printf("Processor("); + ASL_ENTER_SCOPE(dp, oname); asl_dump_termobj(&dp, indent); procid = asl_dump_bytedata(&dp); pblkaddr = asl_dump_dworddata(&dp); @@ -552,6 +582,7 @@ asl_dump_defprocessor(u_int8_t **dpp, int indent) assert(dp == end); + ASL_LEAVE_SCOPE(oname); *dpp = dp; } @@ -564,6 +595,7 @@ asl_dump_defpowerres(u_int8_t **dpp, int indent) u_int8_t systemlevel; u_int16_t resourceorder; u_int32_t pkglength; + struct aml_name *oname; dp = *dpp; start = dp; @@ -571,6 +603,7 @@ asl_dump_defpowerres(u_int8_t **dpp, int indent) end = start + pkglength; printf("PowerResource("); + ASL_ENTER_SCOPE(dp, oname); asl_dump_termobj(&dp, indent); systemlevel = asl_dump_bytedata(&dp); resourceorder = asl_dump_worddata(&dp); @@ -581,6 +614,7 @@ asl_dump_defpowerres(u_int8_t **dpp, int indent) assert(dp == end); + ASL_LEAVE_SCOPE(oname); *dpp = dp; } @@ -591,6 +625,7 @@ asl_dump_defthermalzone(u_int8_t **dpp, int indent) u_int8_t *start; u_int8_t *end; u_int32_t pkglength; + struct aml_name *oname; dp = *dpp; start = dp; @@ -598,6 +633,7 @@ asl_dump_defthermalzone(u_int8_t **dpp, int indent) end = start + pkglength; printf("ThermalZone("); + ASL_ENTER_SCOPE(dp, oname); asl_dump_termobj(&dp, indent); printf(") {\n"); asl_dump_objectlist(&dp, end, indent + 1); @@ -606,6 +642,7 @@ asl_dump_defthermalzone(u_int8_t **dpp, int indent) assert(dp == end); + ASL_LEAVE_SCOPE(oname); *dpp = dp; } @@ -690,7 +727,9 @@ void asl_dump_termobj(u_int8_t **dpp, int indent) { u_int8_t *dp; + u_int8_t *name; u_int8_t opcode; + struct aml_name *method; const char *matchstr[] = { "MTR", "MEQ", "MLE", "MLT", "MGE", "MGT", }; @@ -713,7 +752,24 @@ asl_dump_termobj(u_int8_t **dpp, int indent) case '_': case '.': dp--; - print_namestring(asl_dump_namestring(&dp)); + print_namestring((name = asl_dump_namestring(&dp))); + if (scope_within_method == 1) { + method = aml_search_name(&asl_env, name); + if (method != NULL && method->property != NULL && + method->property->type == aml_t_method) { + int i, argnum; + + argnum = method->property->meth.argnum & 7; + printf("("); + for (i = 0; i < argnum; i++) { + asl_dump_termobj(&dp, indent); + if (i < (argnum-1)) { + printf(", "); + } + } + printf(")"); + } + } break; case 0x0a: /* BytePrefix */ printf("0x%x", asl_dump_bytedata(&dp)); @@ -925,8 +981,8 @@ asl_dump_termobj(u_int8_t **dpp, int indent) OPTARG(); printf(")"); break; - case 0x73: /* ConcatOp */ - printf("Concat("); + case 0x73: /* ConcatenateOp */ + printf("Concatenate("); asl_dump_termobj(&dp, indent); printf(", "); asl_dump_termobj(&dp, indent); @@ -1058,7 +1114,7 @@ asl_dump_termobj(u_int8_t **dpp, int indent) printf(")"); break; case 0x87: /* SizeOfOp */ - printf("Sizeof("); + printf("SizeOf("); asl_dump_termobj(&dp, indent); printf(")"); break; diff --git a/usr.sbin/acpi/amldb/Makefile b/usr.sbin/acpi/amldb/Makefile index 3d5b65613ea8..68cf9feb9bb6 100644 --- a/usr.sbin/acpi/amldb/Makefile +++ b/usr.sbin/acpi/amldb/Makefile @@ -7,7 +7,6 @@ SRCS= amldb.c debug.c region.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 -#DEBUG_FLAGS= -g CFLAGS+= -I${.CURDIR} .include diff --git a/usr.sbin/acpi/amldb/amldb.c b/usr.sbin/acpi/amldb/amldb.c index ede55beaee66..c35d5a84c5e3 100644 --- a/usr.sbin/acpi/amldb/amldb.c +++ b/usr.sbin/acpi/amldb/amldb.c @@ -94,12 +94,9 @@ load_dsdt(const char *dsdtfile) aml_new_name_group((int)code); bzero(&env, sizeof(env)); - /* - * Microsoft asl.exe generates 0x23 byte additional info. - * at the begining of the file, so just ignore it. - */ +#define SIZEOF_SDT_HDR 36 /* struct size except body */ if (strncmp(code, "DSDT", 4) == 0) { - env.dp = code + 0x23; + env.dp = code + SIZEOF_SDT_HDR; } else { env.dp = code; }