NetBSD/usr.sbin/acpitools/acpidump/asl_dump.c

1651 lines
36 KiB
C

/* $NetBSD: asl_dump.c,v 1.2 2007/01/14 05:33:18 dogcow Exp $ */
/*-
* Copyright (c) 1999 Doug Rabson
* 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: asl_dump.c,v 1.6 2000/08/09 14:47:52 iwasaki Exp
* $FreeBSD: src/usr.sbin/acpi/acpidump/asl_dump.c,v 1.7 2002/03/02 15:05:26 takawata Exp $
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: asl_dump.c,v 1.2 2007/01/14 05:33:18 dogcow Exp $");
#include <sys/param.h>
#include <assert.h>
#include <err.h>
#include <stdio.h>
#include <acpi_common.h>
#include "acpidump.h"
#include "aml/aml_env.h"
struct aml_environ asl_env;
int rflag;
static u_int32_t
asl_dump_pkglength(u_int8_t **dpp)
{
u_int8_t *dp;
u_int32_t pkglength;
dp = *dpp;
pkglength = *dp++;
switch (pkglength >> 6) {
case 0:
break;
case 1:
pkglength = (pkglength & 0xf) + (dp[0] << 4);
dp += 1;
break;
case 2:
pkglength = (pkglength & 0xf) + (dp[0] << 4) + (dp[1] << 12);
dp += 2;
break;
case 3:
pkglength = (pkglength & 0xf)
+ (dp[0] << 4) + (dp[1] << 12) + (dp[2] << 20);
dp += 3;
break;
}
*dpp = dp;
return (pkglength);
}
static void
print_nameseg(u_int8_t *dp)
{
if (dp[3] != '_')
printf("%c%c%c%c", dp[0], dp[1], dp[2], dp[3]);
else if (dp[2] != '_')
printf("%c%c%c_", dp[0], dp[1], dp[2]);
else if (dp[1] != '_')
printf("%c%c__", dp[0], dp[1]);
else if (dp[0] != '_')
printf("%c___", dp[0]);
}
static u_int8_t
asl_dump_bytedata(u_int8_t **dpp)
{
u_int8_t *dp;
u_int8_t data;
dp = *dpp;
data = dp[0];
*dpp = dp + 1;
return (data);
}
static u_int16_t
asl_dump_worddata(u_int8_t **dpp)
{
u_int8_t *dp;
u_int16_t data;
dp = *dpp;
data = dp[0] + (dp[1] << 8);
*dpp = dp + 2;
return (data);
}
static u_int32_t
asl_dump_dworddata(u_int8_t **dpp)
{
u_int8_t *dp;
u_int32_t data;
dp = *dpp;
data = dp[0] + (dp[1] << 8) + (dp[2] << 16) + (dp[3] << 24);
*dpp = dp + 4;
return (data);
}
static u_int8_t *
asl_dump_namestring(u_int8_t **dpp)
{
u_int8_t *dp;
u_int8_t *name;
dp = *dpp;
name = dp;
if (dp[0] == '\\')
dp++;
else if (dp[0] == '^')
while (dp[0] == '^')
dp++;
if (dp[0] == 0x00) /* NullName */
dp++;
else if (dp[0] == 0x2e) /* DualNamePrefix */
dp += 1 + 4 + 4;/* NameSeg, NameSeg */
else if (dp[0] == 0x2f) { /* MultiNamePrefix */
int segcount = dp[1];
dp += 1 + 1 + segcount * 4; /* segcount * NameSeg */
} else
dp += 4; /* NameSeg */
*dpp = dp;
return (name);
}
static void
print_namestring(u_int8_t *dp)
{
if (dp[0] == '\\') {
putchar(dp[0]);
dp++;
} else if (dp[0] == '^') {
while (dp[0] == '^') {
putchar(dp[0]);
dp++;
}
}
if (dp[0] == 0x00) { /* NullName */
/* printf("<null>"); */
dp++;
} else if (dp[0] == 0x2e) { /* DualNamePrefix */
print_nameseg(dp + 1);
putchar('.');
print_nameseg(dp + 5);
} else if (dp[0] == 0x2f) { /* MultiNamePrefix */
int segcount = dp[1];
int i;
for (i = 0, dp += 2; i < segcount; i++, dp += 4) {
if (i > 0)
putchar('.');
print_nameseg(dp);
}
} else /* NameSeg */
print_nameseg(dp);
}
static void
print_indent(int indent)
{
int i;
for (i = 0; i < indent; i++)
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)
#define ASL_CREATE_LOCALNAMEOBJ(dp) do { \
if(scope_within_method){ \
aml_create_name(&asl_env, dp); \
} \
}while(0);
static void
asl_dump_defscope(u_int8_t **dpp, int indent)
{
u_int8_t *dp;
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;
asl_dump_objectlist(&dp, end, indent + 1);
print_indent(indent);
printf("}");
assert(dp == end);
ASL_LEAVE_SCOPE(oname);
*dpp = dp;
}
static void
asl_dump_resourcebuffer(u_int8_t *dp, u_int8_t *end, int indent)
{
u_int8_t *p;
int print, len, name, indep, ofs;
print = 0;
indep = 0;
restart:
if (print) {
printf("\n");
print_indent(indent);
printf("/* ResourceTemplate() {\n");
}
for (p = dp; p < end; ) {
ofs = p - dp;
if (*p & 0x80) { /* large resource */
if ((end - p) < 3) {
return;
}
name = *p;
len = ((int)*(p + 2) << 8) + *(p + 1);
p += 3;
} else { /* small resource */
name = (*p >> 3) & 0x0f;
len = *p & 0x7;
p++;
}
if (name == 0xf) { /* end tag */
if (print == 0) {
print = 1;
goto restart;
} else {
print_indent(indent);
printf("} */\n");
print_indent(indent);
break;
}
}
if (print) {
print_indent(indent);
switch (name) {
case 0x06:
if (indep) {
printf(" }\n");
print_indent(indent);
}
printf(" StartDependentFn(");
if (len == 1)
printf("%d, %d",
*p & 0x3,
(*p >> 2) & 0x3);
printf(") {\n");
indep = 1;
continue;
case 0x07:
if (indep)
printf(" }\n");
print_indent(indent);
printf(" EndDependentFn() {}\n");
indep = 0;
continue;
}
printf("%s 0x%-4.4x ", indep ? " " : "", ofs);
switch (name) {
case 0x04: /* IRQ() { } */
{
int i, first;
printf("IRQ(");
if (len == 3) {
printf("%s, Active%s, %s",
*(p + 2) & 0x01 ? "Edge" : "Level",
*(p + 2) & 0x08 ? "Low" : "High",
*(p + 2) & 0x10 ? "Shared" :
"Exclusive");
}
printf(")");
first = 1;
for (i = 0; i < 16; i++) {
if (*(p + (i / 8)) & (1 << (i % 8))) {
if (first) {
printf(" {");
first = 0;
} else {
printf(", ");
}
printf("%d", i);
}
}
if (!first)
printf("}");
printf("\n");
break;
}
case 0x05: /* DMA() { } */
{
int i, first;
printf("DMA(%s, %sBusMaster, Transfer%s)",
(*(p + 1) & 0x60) == 0 ? "Compatibility" :
(*(p + 1) & 0x60) == 1 ? "TypeA" :
(*(p + 1) & 0x60) == 2 ? "TypeB" : "TypeF",
*(p + 1) & 0x04 ? "" : "Not",
(*(p + 1) & 0x03) == 0 ? "8" :
(*(p + 1) & 0x03) == 1 ? "8_16" : "16");
first = 1;
for (i = 0; i < 8; i++) {
if (*p & (1 << i)) {
if (first) {
printf(" {");
first = 0;
} else {
printf(", ");
}
printf("%d", i);
}
}
if (!first)
printf("}");
printf("\n");
break;
}
case 0x08: /* IO() */
printf("IO(Decode%s, 0x%x, 0x%x, 0x%x, 0x%x)\n",
*p & 0x01 ? "16" : "10",
(int)*(u_int16_t *)(p + 1),
(int)*(u_int16_t *)(p + 3),
*(p + 5),
*(p + 6));
break;
case 0x09: /* FixedIO() */
printf("FixedIO(0x%x, 0x%x)\n",
*p + ((int)*(p + 1) << 8),
*(p + 2));
break;
case 0x0e: /* VendorShort() { }*/
case 0x84: /* VendorLong() { } */
{
int i, first;
printf("Vendor%s()", name == 0x0e ? "Short" : "Long");
first = 0;
for (i = 0; i < len; i++) {
if (first) {
printf(" {");
first = 0;
} else {
printf(", ");
}
printf("0x%02x", *(p + i));
}
if (!first)
printf("}");
printf("\n");
break;
}
case 0x81: /* Memory24() */
printf("Memory24(Read%s, 0x%06x, 0x%06x, 0x%x, 0x%x)\n",
*p & 0x01 ? "Write" : "Only",
(u_int32_t)*(u_int16_t *)(p + 1) << 8,
(u_int32_t)*(u_int16_t *)(p + 3) << 8,
(int)*(u_int16_t *)(p + 5),
(int)*(u_int16_t *)(p + 7));
break;
case 0x82: /* Register() */
printf("Register(%s, %d, %d, 0x%016"
PRIx64 "\n",
*p == 0x00 ? "SystemMemory" :
*p == 0x01 ? "SystemIO" :
*p == 0x02 ? "PCIConfigSpace" :
*p == 0x03 ? "EmbeddedController" :
*p == 0x04 ? "SMBus" :
*p == 0x7f ? "FunctionalFixedHardware" : "Unknown",
*(p + 1),
*(p + 2),
*(u_int64_t *)(p + 3));
break;
case 0x85: /* Memory32() */
printf("Memory32(Read%s, 0x%08x, 0x%08x, 0x%x, 0x%x)\n",
*p & 0x01 ? "Write" : "Only",
*(u_int32_t *)(p + 1),
*(u_int32_t *)(p + 5),
*(u_int32_t *)(p + 9),
*(u_int32_t *)(p + 13));
break;
case 0x86: /* Memory32Fixed() */
printf("Memory32Fixed(Read%s, 0x%08x, 0x%x)\n",
*p & 0x01 ? "Write" : "Only",
*(u_int32_t *)(p + 1),
*(u_int32_t *)(p + 5));
break;
case 0x87: /* DWordMemory() / DWordIO() */
case 0x88: /* WordMemory() / WordIO() */
case 0x8a: /* QWordMemory() / QWordIO() */
{
u_int64_t granularity=0, minimum=0, maximum=0, translation=0, length=0;
const char *size = NULL, *source=NULL;
int index=0, slen=0;
switch (name) {
case 0x87:
size = "D";
granularity = *(u_int32_t *)(p + 3);
minimum = *(u_int32_t *)(p + 7);
maximum = *(u_int32_t *)(p + 11);
translation = *(u_int32_t *)(p + 15);
length = *(u_int32_t *)(p + 19);
index = *(p + 23);
source = (char *)(p + 24);
slen = len - 24;
break;
case 0x88:
size = "";
granularity = *(u_int16_t *)(p + 3);
minimum = *(u_int16_t *)(p + 5);
maximum = *(u_int16_t *)(p + 7);
translation = *(u_int16_t *)(p + 9);
length = *(u_int16_t *)(p + 11);
index = *(p + 13);
source = (char *)(p + 14);
slen = len - 14;
break;
case 0x8a:
size = "Q";
granularity = *(u_int64_t *)(p + 3);
minimum = *(u_int64_t *)(p + 11);
maximum = *(u_int64_t *)(p + 19);
translation = *(u_int64_t *)(p + 27);
length = *(u_int64_t *)(p + 35);
index = *(p + 43);
source = (char *)(p + 44);
slen = len - 44;
break;
}
switch(*p) {
case 0:
printf("%sWordMemory("
"Resource%s, "
"%sDecode, "
"Min%sFixed, "
"Max%sFixed, "
"%s, "
"Read%s, "
"0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", "
"%d, '%.*s', "
"AddressRange%s, "
"Type%s)\n",
size,
*(p + 1) & 0x01 ? "Consumer" : "Producer",
*(p + 1) & 0x02 ? "Sub" : "Pos",
*(p + 1) & 0x04 ? "" : "Not",
*(p + 1) & 0x08 ? "" : "Not",
(*(p + 2) >> 1) == 0 ? "NonCacheable" :
(*(p + 2) >> 1) == 1 ? "Cacheable" :
(*(p + 2) >> 1) == 2 ? "WriteCombining" :
"Prefetchable",
*(p + 2) & 0x01 ? "Write" : "Only",
granularity, minimum, maximum, translation, length,
index, slen, source,
((*(p + 2) >> 3) & 0x03) == 0 ? "Memory" :
((*(p + 2) >> 3) & 0x03) == 1 ? "Reserved" :
((*(p + 2) >> 3) & 0x03) == 2 ? "ACPI" : "NVS",
*(p + 2) & 0x20 ? "Translation" : "Static");
break;
case 1:
printf("%sWordIO("
"Resource%s, "
"Min%sFixed, "
"Max%sFixed, "
"%sDecode, "
"%s, "
"0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", "
"%d, '%.*s', "
"Type%s, "
"%sTranslation)\n",
size,
*(p + 1) & 0x01 ? "Consumer" : "Producer",
*(p + 1) & 0x04 ? "" : "Not",
*(p + 1) & 0x08 ? "" : "Not",
*(p + 1) & 0x02 ? "Sub" : "Pos",
(*(p + 2) & 0x03) == 0 ? "EntireRange" :
(*(p + 2) & 0x03) == 1 ? "NonISAOnlyRanges" :
(*(p + 2) & 0x03) == 2 ? "ISAOnlyRanges" : "EntireRange",
granularity, minimum, maximum, translation, length,
index, slen, source,
*(p + 2) & 0x10 ? "Translation" : "Static",
*(p + 2) & 0x20 ? "Sparse" : "Dense");
break;
case 2:
printf("%sWordBus("
"Resource%s, "
"%sDecode, "
"Min%sFixed, "
"Max%sFixed, "
"0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", "
"%d, '%.*s')\n",
size,
*(p + 1) & 0x01 ? "Consumer" : "Producer",
*(p + 1) & 0x02 ? "Sub" : "Pos",
*(p + 1) & 0x04 ? "" : "Not",
*(p + 1) & 0x08 ? "" : "Not",
granularity, minimum, maximum, translation, length,
index, slen, source);
break;
default:
printf("%sWordUnknown()\n", size);
}
break;
}
case 0x89: /* Interrupt() { } */
{
int i, first, pad, sl;
char *rp;
pad = *(p + 1) * 4;
rp = (char *)(p + 1 + pad);
sl = len - pad - 3;
printf("Interrupt(Resource%s, %s, Active%s, %s, %d, %.*s)",
*p & 0x01 ? "Producer" : "Consumer",
*p & 0x02 ? "Edge" : "Level",
*p & 0x04 ? "Low" : "High",
*p & 0x08 ? "Shared" : "Exclusive",
(int)*(p + 1 + pad),
sl,
rp);
first = 1;
for (i = 0; i < *(p + 1); i++) {
if (first) {
printf(" {");
first = 0;
} else {
printf(", ");
}
printf("%u", *(u_int32_t *)(p + 2 + (i * 4)));
}
if (!first)
printf("}");
printf("\n");
break;
}
default:
printf("Unknown(0x%x, %d)\n", name, len);
break;
}
}
p += len;
}
}
static void
asl_dump_defbuffer(u_int8_t **dpp, int indent)
{
u_int8_t *dp;
u_int8_t *start;
u_int8_t *end;
u_int32_t pkglength;
dp = *dpp;
start = dp;
pkglength = asl_dump_pkglength(&dp);
end = start + pkglength;
printf("Buffer(");
asl_dump_termobj(&dp, indent);
start = dp;
printf(") {");
while (dp < end) {
printf("0x%x", *dp++);
if (dp < end)
printf(", ");
}
if (rflag)
asl_dump_resourcebuffer(start, end, indent);
printf(" }");
*dpp = dp;
}
static void
asl_dump_defpackage(u_int8_t **dpp, int indent)
{
u_int8_t *dp;
u_int8_t *start;
u_int8_t *end;
u_int8_t numelements;
u_int32_t pkglength;
dp = *dpp;
start = dp;
pkglength = asl_dump_pkglength(&dp);
numelements = asl_dump_bytedata(&dp);
end = start + pkglength;
printf("Package(0x%x) {\n", numelements);
while (dp < end) {
print_indent(indent + 1);
asl_dump_termobj(&dp, indent + 1);
printf(",\n");
}
print_indent(indent);
printf("}");
dp = end;
*dpp = dp;
}
int scope_within_method = 0;
static void
asl_dump_defmethod(u_int8_t **dpp, int indent)
{
u_int8_t *dp;
u_int8_t *start;
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) {
printf(", %d", flags & 7);
if (flags & 8) {
printf(", Serialized");
}
}
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;
}
static void
asl_dump_defopregion(u_int8_t **dpp, int indent)
{
u_int8_t *dp;
const char *regions[] = {
"SystemMemory",
"SystemIO",
"PCI_Config",
"EmbeddedControl",
"SMBus",
};
dp = *dpp;
printf("OperationRegion(");
ASL_CREATE_LOCALNAMEOBJ(dp);
asl_dump_termobj(&dp, indent); /* Name */
printf(", %s, ", regions[*dp++]); /* Space */
asl_dump_termobj(&dp, indent); /* Offset */
printf(", ");
asl_dump_termobj(&dp, indent); /* Length */
printf(")");
*dpp = dp;
}
static const char *accessnames[] = {
"AnyAcc",
"ByteAcc",
"WordAcc",
"DWordAcc",
"BlockAcc",
"SMBSendRecvAcc",
"SMBQuickAcc"
};
static int
asl_dump_field(u_int8_t **dpp, u_int32_t offset)
{
u_int8_t *dp;
u_int8_t *name;
u_int8_t access, attribute;
u_int32_t width;
dp = *dpp;
switch (*dp) {
case '\\':
case '^':
case 'A' ... 'Z':
case '_':
case '.':
case '/':
ASL_CREATE_LOCALNAMEOBJ(dp);
name = asl_dump_namestring(&dp);
width = asl_dump_pkglength(&dp);
offset += width;
print_namestring(name);
printf(",\t%d", width);
break;
case 0x00:
dp++;
width = asl_dump_pkglength(&dp);
offset += width;
if ((offset % 8) == 0) {
printf("Offset(0x%x)", offset / 8);
} else {
printf(",\t%d", width);
}
break;
case 0x01:
access = dp[1];
attribute = dp[2];
dp += 3;
printf("AccessAs(%s, %d)", accessnames[access], attribute);
break;
}
*dpp = dp;
return (offset);
}
static void
asl_dump_fieldlist(u_int8_t **dpp, u_int8_t *end, int indent)
{
u_int8_t *dp;
u_int32_t offset;
dp = *dpp;
offset = 0;
while (dp < end) {
print_indent(indent);
offset = asl_dump_field(&dp, offset);
if (dp < end)
printf(",\n");
else
printf("\n");
}
*dpp = dp;
}
static void
asl_dump_deffield(u_int8_t **dpp, int indent)
{
u_int8_t *dp;
u_int8_t *start;
u_int8_t *end;
u_int8_t flags;
u_int32_t pkglength;
static const char *lockrules[] = {"NoLock", "Lock"};
static const char *updaterules[] = {"Preserve", "WriteAsOnes",
"WriteAsZeros", "*Error*"};
dp = *dpp;
start = dp;
pkglength = asl_dump_pkglength(&dp);
end = start + pkglength;
printf("Field(");
asl_dump_termobj(&dp, indent); /* Name */
flags = asl_dump_bytedata(&dp);
printf(", %s, %s, %s) {\n",
accessnames[flags & 0xf],
lockrules[(flags >> 4) & 1],
updaterules[(flags >> 5) & 3]);
asl_dump_fieldlist(&dp, end, indent + 1);
print_indent(indent);
printf("}");
assert(dp == end);
*dpp = dp;
}
static void
asl_dump_defindexfield(u_int8_t **dpp, int indent)
{
u_int8_t *dp;
u_int8_t *start;
u_int8_t *end;
u_int8_t flags;
u_int32_t pkglength;
static const char *lockrules[] = {"NoLock", "Lock"};
static const char *updaterules[] = {"Preserve", "WriteAsOnes",
"WriteAsZeros", "*Error*"};
dp = *dpp;
start = dp;
pkglength = asl_dump_pkglength(&dp);
end = start + pkglength;
printf("IndexField(");
asl_dump_termobj(&dp, indent); /* Name1 */
printf(", ");
asl_dump_termobj(&dp, indent); /* Name2 */
flags = asl_dump_bytedata(&dp);
printf(", %s, %s, %s) {\n",
accessnames[flags & 0xf],
lockrules[(flags >> 4) & 1],
updaterules[(flags >> 5) & 3]);
asl_dump_fieldlist(&dp, end, indent + 1);
print_indent(indent);
printf("}");
assert(dp == end);
*dpp = dp;
}
static void
asl_dump_defbankfield(u_int8_t **dpp, int indent)
{
u_int8_t *dp;
u_int8_t *start;
u_int8_t *end;
u_int8_t flags;
u_int32_t pkglength;
static const char *lockrules[] = {"NoLock", "Lock"};
static const char *updaterules[] = {"Preserve", "WriteAsOnes",
"WriteAsZeros", "*Error*"};
dp = *dpp;
start = dp;
pkglength = asl_dump_pkglength(&dp);
end = start + pkglength;
printf("BankField(");
asl_dump_termobj(&dp, indent); /* Name1 */
printf(", ");
asl_dump_termobj(&dp, indent); /* Name2 */
printf(", ");
asl_dump_termobj(&dp, indent); /* BankValue */
flags = asl_dump_bytedata(&dp);
printf(", %s, %s, %s) {\n",
accessnames[flags & 0xf],
lockrules[(flags >> 4) & 1],
updaterules[(flags >> 5) & 3]);
asl_dump_fieldlist(&dp, end, indent + 1);
print_indent(indent);
printf("}");
assert(dp == end);
*dpp = dp;
}
static void
asl_dump_defdevice(u_int8_t **dpp, int indent)
{
u_int8_t *dp;
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);
end = start + pkglength;
printf("Device(");
ASL_ENTER_SCOPE(dp, oname);
asl_dump_termobj(&dp, indent);
printf(") {\n");
asl_dump_objectlist(&dp, end, indent + 1);
print_indent(indent);
printf("}");
assert(dp == end);
ASL_LEAVE_SCOPE(oname);
*dpp = dp;
}
static void
asl_dump_defprocessor(u_int8_t **dpp, int indent)
{
u_int8_t *dp;
u_int8_t *start;
u_int8_t *end;
u_int8_t procid;
u_int8_t pblklen;
u_int32_t pkglength;
u_int32_t pblkaddr;
struct aml_name *oname;
dp = *dpp;
start = dp;
pkglength = asl_dump_pkglength(&dp);
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);
pblklen = asl_dump_bytedata(&dp);
printf(", %d, 0x%x, 0x%x) {\n", procid, pblkaddr, pblklen);
asl_dump_objectlist(&dp, end, indent + 1);
print_indent(indent);
printf("}");
assert(dp == end);
ASL_LEAVE_SCOPE(oname);
*dpp = dp;
}
static void
asl_dump_defpowerres(u_int8_t **dpp, int indent)
{
u_int8_t *dp;
u_int8_t *start;
u_int8_t *end;
u_int8_t systemlevel;
u_int16_t resourceorder;
u_int32_t pkglength;
struct aml_name *oname;
dp = *dpp;
start = dp;
pkglength = asl_dump_pkglength(&dp);
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);
printf(", %d, %d) {\n", systemlevel, resourceorder);
asl_dump_objectlist(&dp, end, indent + 1);
print_indent(indent);
printf("}");
assert(dp == end);
ASL_LEAVE_SCOPE(oname);
*dpp = dp;
}
static void
asl_dump_defthermalzone(u_int8_t **dpp, int indent)
{
u_int8_t *dp;
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);
end = start + pkglength;
printf("ThermalZone(");
ASL_ENTER_SCOPE(dp, oname);
asl_dump_termobj(&dp, indent);
printf(") {\n");
asl_dump_objectlist(&dp, end, indent + 1);
print_indent(indent);
printf("}");
assert(dp == end);
ASL_LEAVE_SCOPE(oname);
*dpp = dp;
}
static void
asl_dump_defif(u_int8_t **dpp, int indent)
{
u_int8_t *dp;
u_int8_t *start;
u_int8_t *end;
u_int32_t pkglength;
dp = *dpp;
start = dp;
pkglength = asl_dump_pkglength(&dp);
end = start + pkglength;
printf("If(");
asl_dump_termobj(&dp, indent);
printf(") {\n");
asl_dump_objectlist(&dp, end, indent + 1);
print_indent(indent);
printf("}");
assert(dp == end);
*dpp = dp;
}
static void
asl_dump_defelse(u_int8_t **dpp, int indent)
{
u_int8_t *dp;
u_int8_t *start;
u_int8_t *end;
u_int32_t pkglength;
dp = *dpp;
start = dp;
pkglength = asl_dump_pkglength(&dp);
end = start + pkglength;
printf("Else {\n");
asl_dump_objectlist(&dp, end, indent + 1);
print_indent(indent);
printf("}");
assert(dp == end);
*dpp = dp;
}
static void
asl_dump_defwhile(u_int8_t **dpp, int indent)
{
u_int8_t *dp;
u_int8_t *start;
u_int8_t *end;
u_int32_t pkglength;
dp = *dpp;
start = dp;
pkglength = asl_dump_pkglength(&dp);
end = start + pkglength;
printf("While(");
asl_dump_termobj(&dp, indent);
printf(") {\n");
asl_dump_objectlist(&dp, end, indent + 1);
print_indent(indent);
printf("}");
assert(dp == end);
*dpp = dp;
}
/*
* Public interfaces
*/
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",
};
#define OPTARG() do { \
printf(", "); \
if (*dp == 0x00) { \
dp++; \
} else { \
asl_dump_termobj(&dp, indent); \
} \
} while (0)
dp = *dpp;
opcode = *dp++;
switch (opcode) {
case '\\':
case '^':
case 'A' ... 'Z':
case '_':
case '.':
case '/':
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));
break;
case 0x0b: /* WordPrefix */
printf("0x%04x", asl_dump_worddata(&dp));
break;
case 0x0c: /* DWordPrefix */
printf("0x%08x", asl_dump_dworddata(&dp));
break;
case 0x0d: /* StringPrefix */
printf("\"%s\"", (const char *) dp);
while (*dp)
dp++;
dp++; /* NUL terminate */
break;
case 0x00: /* ZeroOp */
printf("Zero");
break;
case 0x01: /* OneOp */
printf("One");
break;
case 0xff: /* OnesOp */
printf("Ones");
break;
case 0x06: /* AliasOp */
printf("Alias(");
ASL_CREATE_LOCALNAMEOBJ(dp);
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x08: /* NameOp */
printf("Name(");
ASL_CREATE_LOCALNAMEOBJ(dp);
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x10: /* ScopeOp */
asl_dump_defscope(&dp, indent);
break;
case 0x11: /* BufferOp */
asl_dump_defbuffer(&dp, indent);
break;
case 0x12: /* PackageOp */
asl_dump_defpackage(&dp, indent);
break;
case 0x14: /* MethodOp */
asl_dump_defmethod(&dp, indent);
break;
case 0x5b: /* ExtOpPrefix */
opcode = *dp++;
switch (opcode) {
case 0x01: /* MutexOp */
printf("Mutex(");
ASL_CREATE_LOCALNAMEOBJ(dp);
asl_dump_termobj(&dp, indent);
printf(", %d)", *dp++);
break;
case 0x02: /* EventOp */
printf("Event(");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x12: /* CondRefOfOp */
printf("CondRefOf(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x13: /* CreateFieldOp */
printf("CreateField(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(", ");
ASL_CREATE_LOCALNAMEOBJ(dp);
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x20: /* LoadOp */
printf("Load(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x21: /* StallOp */
printf("Stall(");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x22: /* SleepOp */
printf("Sleep(");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x23: /* AcquireOp */
printf("Acquire(");
asl_dump_termobj(&dp, indent);
printf(", 0x%x)", asl_dump_worddata(&dp));
break;
case 0x24: /* SignalOp */
printf("Signal(");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x25: /* WaitOp */
printf("Wait(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x26: /* ResetOp */
printf("Reset(");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x27: /* ReleaseOp */
printf("Release(");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x28: /* FromBCDOp */
printf("FromBCD(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x29: /* ToBCDOp */
printf("ToBCD(");
asl_dump_termobj(&dp, indent);
OPTARG();
printf(")");
break;
case 0x2a: /* UnloadOp */
printf("Unload(");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x30:
printf("Revision");
break;
case 0x31:
printf("Debug");
break;
case 0x32: /* FatalOp */
printf("Fatal(");
printf("0x%x, ", asl_dump_bytedata(&dp));
printf("0x%x, ", asl_dump_dworddata(&dp));
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x80: /* OpRegionOp */
asl_dump_defopregion(&dp, indent);
break;
case 0x81: /* FieldOp */
asl_dump_deffield(&dp, indent);
break;
case 0x82: /* DeviceOp */
asl_dump_defdevice(&dp, indent);
break;
case 0x83: /* ProcessorOp */
asl_dump_defprocessor(&dp, indent);
break;
case 0x84: /* PowerResOp */
asl_dump_defpowerres(&dp, indent);
break;
case 0x85: /* ThermalZoneOp */
asl_dump_defthermalzone(&dp, indent);
break;
case 0x86: /* IndexFieldOp */
asl_dump_defindexfield(&dp, indent);
break;
case 0x87: /* BankFieldOp */
asl_dump_defbankfield(&dp, indent);
break;
default:
errx(1, "strange opcode 0x5b, 0x%x\n", opcode);
}
break;
case 0x68 ... 0x6e: /* ArgN */
printf("Arg%d", opcode - 0x68);
break;
case 0x60 ... 0x67:
printf("Local%d", opcode - 0x60);
break;
case 0x70: /* StoreOp */
printf("Store(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x71: /* RefOfOp */
printf("RefOf(");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x72: /* AddOp */
printf("Add(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
OPTARG();
printf(")");
break;
case 0x73: /* ConcatenateOp */
printf("Concatenate(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x74: /* SubtractOp */
printf("Subtract(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
OPTARG();
printf(")");
break;
case 0x75: /* IncrementOp */
printf("Increment(");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x76: /* DecrementOp */
printf("Decrement(");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x77: /* MultiplyOp */
printf("Multiply(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
OPTARG();
printf(")");
break;
case 0x78: /* DivideOp */
printf("Divide(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
OPTARG();
OPTARG();
printf(")");
break;
case 0x79: /* ShiftLeftOp */
printf("ShiftLeft(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
OPTARG();
printf(")");
break;
case 0x7a: /* ShiftRightOp */
printf("ShiftRight(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
OPTARG();
printf(")");
break;
case 0x7b: /* AndOp */
printf("And(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
OPTARG();
printf(")");
break;
case 0x7c: /* NAndOp */
printf("NAnd(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
OPTARG();
printf(")");
break;
case 0x7d: /* OrOp */
printf("Or(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
OPTARG();
printf(")");
break;
case 0x7e: /* NOrOp */
printf("NOr(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
OPTARG();
printf(")");
break;
case 0x7f: /* XOrOp */
printf("XOr(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
OPTARG();
printf(")");
break;
case 0x80: /* NotOp */
printf("Not(");
asl_dump_termobj(&dp, indent);
OPTARG();
printf(")");
break;
case 0x81: /* FindSetLeftBitOp */
printf("FindSetLeftBit(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x82: /* FindSetRightBitOp */
printf("FindSetRightBit(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x83: /* DerefOp */
printf("DerefOf(");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x86: /* NotifyOp */
printf("Notify(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x87: /* SizeOfOp */
printf("SizeOf(");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x88: /* IndexOp */
printf("Index(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
OPTARG();
printf(")");
break;
case 0x89: /* MatchOp */
printf("Match(");
asl_dump_termobj(&dp, indent);
printf(", %s, ", matchstr[*dp++]);
asl_dump_termobj(&dp, indent);
printf(", %s, ", matchstr[*dp++]);
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x8a: /* CreateDWordFieldOp */
printf("CreateDWordField(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(", ");
ASL_CREATE_LOCALNAMEOBJ(dp);
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x8b: /* CreateWordFieldOp */
printf("CreateWordField(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(", ");
ASL_CREATE_LOCALNAMEOBJ(dp);
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x8c: /* CreateByteFieldOp */
printf("CreateByteField(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(", ");
ASL_CREATE_LOCALNAMEOBJ(dp);
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x8d: /* CreateBitFieldOp */
printf("CreateBitField(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(", ");
ASL_CREATE_LOCALNAMEOBJ(dp);
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x8e: /* ObjectTypeOp */
printf("ObjectType(");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x90:
printf("LAnd(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x91:
printf("LOr(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x92:
printf("LNot(");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x93:
printf("LEqual(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x94:
printf("LGreater(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0x95:
printf("LLess(");
asl_dump_termobj(&dp, indent);
printf(", ");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0xa0: /* IfOp */
asl_dump_defif(&dp, indent);
break;
case 0xa1: /* ElseOp */
asl_dump_defelse(&dp, indent);
break;
case 0xa2: /* WhileOp */
asl_dump_defwhile(&dp, indent);
break;
case 0xa3: /* NoopOp */
printf("Noop");
break;
case 0xa5: /* BreakOp */
printf("Break");
break;
case 0xa4: /* ReturnOp */
printf("Return(");
asl_dump_termobj(&dp, indent);
printf(")");
break;
case 0xcc: /* BreakPointOp */
printf("BreakPoint");
break;
default:
errx(1, "strange opcode 0x%x\n", opcode);
}
*dpp = dp;
}
void
asl_dump_objectlist(u_int8_t **dpp, u_int8_t *end, int indent)
{
u_int8_t *dp;
dp = *dpp;
while (dp < end) {
print_indent(indent);
asl_dump_termobj(&dp, indent);
printf("\n");
}
*dpp = dp;
}