summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/Makefile4
-rw-r--r--usr.sbin/acpid/Makefile23
-rw-r--r--usr.sbin/acpid/acpi.h18
-rw-r--r--usr.sbin/acpid/acpid.883
-rw-r--r--usr.sbin/acpid/main.c135
-rw-r--r--usr.sbin/acpid/pathnames.h19
-rw-r--r--usr.sbin/acpid/samples/Makefile7
-rw-r--r--usr.sbin/acpid/samples/power-button3
-rw-r--r--usr.sbin/acpid/script.c54
-rw-r--r--usr.sbin/acpidump/Makefile14
-rw-r--r--usr.sbin/acpidump/acpi.c440
-rw-r--r--usr.sbin/acpidump/acpi_user.c169
-rw-r--r--usr.sbin/acpidump/acpidump.8170
-rw-r--r--usr.sbin/acpidump/acpidump.c105
-rw-r--r--usr.sbin/acpidump/acpidump.h184
-rw-r--r--usr.sbin/acpidump/aml/aml_amlmem.c91
-rw-r--r--usr.sbin/acpidump/aml/aml_amlmem.h66
-rw-r--r--usr.sbin/acpidump/aml/aml_common.c734
-rw-r--r--usr.sbin/acpidump/aml/aml_common.h162
-rw-r--r--usr.sbin/acpidump/aml/aml_env.h47
-rw-r--r--usr.sbin/acpidump/aml/aml_evalobj.c436
-rw-r--r--usr.sbin/acpidump/aml/aml_evalobj.h49
-rw-r--r--usr.sbin/acpidump/aml/aml_memman.c477
-rw-r--r--usr.sbin/acpidump/aml/aml_memman.h172
-rw-r--r--usr.sbin/acpidump/aml/aml_name.c481
-rw-r--r--usr.sbin/acpidump/aml/aml_name.h89
-rw-r--r--usr.sbin/acpidump/aml/aml_obj.c265
-rw-r--r--usr.sbin/acpidump/aml/aml_obj.h232
-rw-r--r--usr.sbin/acpidump/aml/aml_parse.c2023
-rw-r--r--usr.sbin/acpidump/aml/aml_parse.h37
-rw-r--r--usr.sbin/acpidump/aml/aml_region.h93
-rw-r--r--usr.sbin/acpidump/aml/aml_status.h42
-rw-r--r--usr.sbin/acpidump/aml/aml_store.c350
-rw-r--r--usr.sbin/acpidump/aml/aml_store.h40
-rw-r--r--usr.sbin/acpidump/aml_dump.c61
-rw-r--r--usr.sbin/acpidump/asl_dump.c1281
-rw-r--r--usr.sbin/acpidump/debug.h37
37 files changed, 8691 insertions, 2 deletions
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index 5a5e534a034..bda04d16a03 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.119 2005/05/28 01:38:14 ho Exp $
+# $OpenBSD: Makefile,v 1.120 2005/06/02 20:09:39 tholo Exp $
.include <bsd.own.mk>
@@ -17,7 +17,7 @@ SUBDIR= ac accton adduser amd arp authpf bgpctl bgpd bind chroot \
SUBDIR+=faithd ndp rip6query route6d rtadvd rtsold traceroute6
# Arch dependent tools, with manpages
-SUBDIR+=bad144 apm apmd fdformat memconfig
+SUBDIR+=bad144 acpid acpidump apm apmd fdformat memconfig
SUBDIR+=eeprom gpioctl hotplugd
SUBDIR+=wsconscfg wsfontload
diff --git a/usr.sbin/acpid/Makefile b/usr.sbin/acpid/Makefile
new file mode 100644
index 00000000000..98dd722d6da
--- /dev/null
+++ b/usr.sbin/acpid/Makefile
@@ -0,0 +1,23 @@
+# $OpenBSD: Makefile,v 1.1 2005/06/02 20:09:39 tholo Exp $
+
+.if (${MACHINE} == "i386") || (${MACHINE} == "amd64")
+PROG= acpid
+SRCS= main.c script.c
+CFLAGS+= -Wall -pedantic
+CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
+CFLAGS+= -Wmissing-declarations
+CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual
+CFLAGS+= -Wsign-compare
+.else
+NOPROG= yes
+.endif
+
+MAN= acpid.8
+MANSUBDIR= i386 amd64
+
+.if make(install)
+SUBDIR+= samples
+.endif
+
+.include <bsd.prog.mk>
+.include <bsd.subdir.mk>
diff --git a/usr.sbin/acpid/acpi.h b/usr.sbin/acpid/acpi.h
new file mode 100644
index 00000000000..b03a17a4c34
--- /dev/null
+++ b/usr.sbin/acpid/acpi.h
@@ -0,0 +1,18 @@
+/* $OpenBSD: acpi.h,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*
+ * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+void run_script(const char *);
diff --git a/usr.sbin/acpid/acpid.8 b/usr.sbin/acpid/acpid.8
new file mode 100644
index 00000000000..99343062685
--- /dev/null
+++ b/usr.sbin/acpid/acpid.8
@@ -0,0 +1,83 @@
+.\" $OpenBSD: acpid.8,v 1.1 2005/06/02 20:09:39 tholo Exp $
+.\"
+.\" Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd May 27, 2005
+.Dt ACPID 8
+.Os
+.Sh NAME
+.Nm acpid
+.Nd Advanced Configuration and Power Interface daemon
+.Sh SYNOPSIS
+.Nm acpid
+.Op Fl d
+.Sh DESCRIPTION
+.Nm
+monitors the advanced configuration and power interface (ACPI) device,
+acting of signaled events.
+For suspend and poweroff request events delivered by the BIOS,
+.Nm
+runs the appropriate program (if one exists).
+.Pp
+If the
+.Fl d
+flag is specified,
+.Nm
+enters debug mode, logging to facility
+.Dv LOG_LOCAL1
+and staying in the foreground on the controlling terminal.
+.Pp
+Actions can be configured for the following two events:
+.Cm suspend
+and
+.Cm powerdown .
+The suspend actions are run when the sleep button is pressed, while
+the powerdown action is run when the power button is pressed.
+.Sh FILES
+.Pa /etc/acpi/suspend
+and
+.Pa /etc/acpi/powerdown
+are the files that contain the host's customized actions.
+Each file must be an executable binary or shell script suitable
+for execution by the
+.Xr execve 2
+function.
+If you wish to have the same program or script control all transitions, it
+may determine which transition is in progress by examining its
+.Va argv[0]
+which is set to one of
+.Ar suspend
+and
+.Ar powerdown .
+.Pp
+.Pa /dev/acpi
+is the default device used to control the ACPI kernel driver.
+.Sh SEE ALSO
+.Xr execve 2 ,
+.Xr syslog 3 ,
+.Xr apm 4 ,
+.Xr speaker 4 ,
+.Xr apm 8 ,
+.Xr apmd 8 ,
+.Xr syslogd 8
+.Sh REFERENCES
+Advanced Configuration and Power Interface Specification (Revision 3.0),
+Hewlett-Packard Corporation, Intel Corporation, Microsoft Corporation,
+Phoenix Technologies Ltd and Toshiba Corporation.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Ox 3.8 .
diff --git a/usr.sbin/acpid/main.c b/usr.sbin/acpid/main.c
new file mode 100644
index 00000000000..787f0a3c884
--- /dev/null
+++ b/usr.sbin/acpid/main.c
@@ -0,0 +1,135 @@
+/* $OpenBSD: main.c,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*
+ * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/event.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <err.h>
+#include <syslog.h>
+#include <machine/bus.h>
+#include <sys/device.h>
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+
+#include "pathnames.h"
+#include "acpi.h"
+
+void sigexit(int);
+void usage(void);
+void run_script(const char *);
+
+int debug = 0;
+
+const char acpidev[] = _PATH_ACPI_DEV;
+
+extern char *__progname;
+
+void
+sigexit(int sig)
+{
+}
+
+void
+usage(void)
+{
+ fprintf(stderr,
+ "usage: %s [-d]\n",
+ __progname);
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ const char *fname = acpidev;
+ int acpi_fd, ch;
+ int kq;
+ struct kevent ev[2];
+
+ while ((ch = getopt(argc, argv, "qadsepmf:t:S:")) != -1)
+ switch(ch) {
+ case 'd':
+ debug = 1;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (debug)
+ openlog(__progname, LOG_CONS, LOG_LOCAL1);
+ else {
+ daemon(0, 0);
+ openlog(__progname, LOG_CONS, LOG_DAEMON);
+ setlogmask(LOG_UPTO(LOG_NOTICE));
+ }
+
+ (void) signal(SIGTERM, sigexit);
+ (void) signal(SIGHUP, sigexit);
+ (void) signal(SIGINT, sigexit);
+
+ if ((acpi_fd = open(fname, O_RDONLY)) == -1)
+ err(1, "open");
+
+ if (fcntl(acpi_fd, F_SETFD, 1) == -1)
+ err(1, "fcntl");
+
+ kq = kqueue();
+ if (kq <= 0)
+ err(1, "kqueue");
+
+ EV_SET(&ev[0], acpi_fd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_CLEAR,
+ 0, 0, NULL);
+ if (kevent(kq, ev, 1, NULL, 0, NULL) < 0)
+ err(1, "kevent");
+
+ for (;;) {
+ int rv;
+
+ if ((rv = kevent(kq, NULL, 0, ev, 1, NULL)) < 0)
+ break;
+
+ if (!rv)
+ continue;
+
+ if (ev->ident == (u_int)acpi_fd) {
+ syslog(LOG_DEBUG, "acpi event %04x index %d",
+ ACPI_EVENT_TYPE(ev->data),
+ ACPI_EVENT_INDEX(ev->data));
+
+ switch (ACPI_EVENT_TYPE(ev->data)) {
+ case ACPI_EV_PWRBTN:
+ run_script("power-button");
+ break;
+ case ACPI_EV_SLPBTN:
+ run_script("sleep-button");
+ break;
+ default:
+ break;
+ }
+
+ }
+ }
+ err(1, "kevent");
+}
diff --git a/usr.sbin/acpid/pathnames.h b/usr.sbin/acpid/pathnames.h
new file mode 100644
index 00000000000..17d8d24415d
--- /dev/null
+++ b/usr.sbin/acpid/pathnames.h
@@ -0,0 +1,19 @@
+/* $OpenBSD: pathnames.h,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*
+ * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define _PATH_ACPI_DEV "/dev/acpi"
+#define _PATH_ETC_ACPI "/etc/acpi"
diff --git a/usr.sbin/acpid/samples/Makefile b/usr.sbin/acpid/samples/Makefile
new file mode 100644
index 00000000000..d722dd75343
--- /dev/null
+++ b/usr.sbin/acpid/samples/Makefile
@@ -0,0 +1,7 @@
+# $OpenBSD: Makefile,v 1.1 2005/06/02 20:09:39 tholo Exp $
+
+FILES= power-button
+TARGETDIR= /etc/acpi
+
+install:
+ $(INSTALL) -c -m 0755 ${FILES} ${DESTDIR}${TARGETDIR}
diff --git a/usr.sbin/acpid/samples/power-button b/usr.sbin/acpid/samples/power-button
new file mode 100644
index 00000000000..38d6b6ab921
--- /dev/null
+++ b/usr.sbin/acpid/samples/power-button
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+shutdown -hp now
diff --git a/usr.sbin/acpid/script.c b/usr.sbin/acpid/script.c
new file mode 100644
index 00000000000..2100582a199
--- /dev/null
+++ b/usr.sbin/acpid/script.c
@@ -0,0 +1,54 @@
+/* $OpenBSD: script.c,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*
+ * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include "pathnames.h"
+#include "acpi.h"
+
+void
+run_script(const char *script)
+{
+ char path[MAXPATHLEN];
+ int status;
+ pid_t pid;
+
+ strlcpy(path, _PATH_ETC_ACPI, sizeof(path));
+ strlcat(path, "/", sizeof(path));
+ strlcat(path, script, sizeof(path));
+
+ if (access(path, X_OK)) {
+ strlcpy(path, _PATH_ETC_ACPI, sizeof(path));
+ strlcat(path, "/default", sizeof(path));
+
+ if (access(path, X_OK))
+ return;
+ }
+
+ switch (pid = fork()) {
+ case -1:
+ return;
+ case 0:
+ execl(path, script, (char *)NULL);
+ break;
+ default:
+ wait4(pid, &status, 0, NULL);
+ break;
+ }
+}
diff --git a/usr.sbin/acpidump/Makefile b/usr.sbin/acpidump/Makefile
new file mode 100644
index 00000000000..ebd0ae5776d
--- /dev/null
+++ b/usr.sbin/acpidump/Makefile
@@ -0,0 +1,14 @@
+# $OpenBSD: Makefile,v 1.1 2005/06/02 20:09:39 tholo Exp $
+
+PROG= acpidump
+SRCS= acpi.c acpi_user.c asl_dump.c aml_dump.c acpidump.c
+SRCS+= aml_name.c aml_parse.c aml_amlmem.c aml_memman.c aml_obj.c
+SRCS+= aml_common.c aml_evalobj.c aml_store.c
+MAN= acpidump.8
+
+VPATH= ${.CURDIR}/aml
+CFLAGS= -I${.CURDIR}
+
+BINDIR?=/usr/sbin
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/acpidump/acpi.c b/usr.sbin/acpidump/acpi.c
new file mode 100644
index 00000000000..f26cd57695f
--- /dev/null
+++ b/usr.sbin/acpidump/acpi.c
@@ -0,0 +1,440 @@
+/* $OpenBSD: acpi.c,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1998 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: acpi.c,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/acpidump/acpi.c,v 1.3 2000/11/08 02:37:00 iwasaki Exp $
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.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)
+{
+ int len;
+ char *p;
+ 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\",\t//Output filename\n"
+ "\"DSDT\",\t\t\t//Signature\n"
+ "0x%x,\t\t\t//DSDT Revision\n"
+ "\"%s\",\t\t\t//OEMID\n"
+ "\"%s\",\t\t//TABLE ID\n"
+ "0x%x\t\t\t//OEM Revision\n)\n",
+ dsdt_header.rev, oemid, oemtblid, dsdt_header.oemrev);
+}
+
+static void
+acpi_print_string(char *s, size_t length)
+{
+ int c;
+
+ /* Trim trailing spaces and NULLs */
+ while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
+ length--;
+
+ while (length--) {
+ c = *s++;
+ putchar(c);
+ }
+}
+
+static void
+acpi_handle_dsdt(struct ACPIsdt *dsdp)
+{
+ u_int8_t *dp;
+ u_int8_t *end;
+ extern struct aml_environ asl_env;
+
+ 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);
+ if (acpi_checksum(dsdp, dsdp->len))
+ errx(1, "DSDT is corrupt\n");
+ acpi_handle_dsdt(dsdp);
+ 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((long)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(": Length=%d, Revision=%d, Checksum=%d,\n",
+ sdp->len, sdp->rev, sdp->check);
+ printf("\tOEMID=");
+ acpi_print_string(sdp->oemid, 6);
+ printf(", OEM Table ID=");
+ acpi_print_string(sdp->oemtblid, 8);
+ printf(", OEM Revision=0x%x,\n", sdp->oemrev);
+ 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
+acpi_print_rsdt(struct ACPIsdt *rsdp)
+{
+ int i, entries;
+
+ 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)
+ printf(", ");
+ printf("0x%08x", rsdp->body[i]);
+ }
+ printf(" }\n");
+ printf(END_COMMENT);
+}
+
+void
+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);
+ printf("\tSMI_CMD=0x%x, ", facp->smi_cmd);
+ printf("ACPI_ENABLE=0x%x, ", facp->acpi_enable);
+ printf("ACPI_DISABLE=0x%x, ", facp->acpi_disable);
+ printf("S4BIOS_REQ=0x%x\n", facp->s4biosreq);
+ if (facp->pm1a_evt_blk)
+ printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
+ facp->pm1a_evt_blk,
+ facp->pm1a_evt_blk + facp->pm1_evt_len - 1);
+ if (facp->pm1b_evt_blk)
+ printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
+ facp->pm1b_evt_blk,
+ facp->pm1b_evt_blk + facp->pm1_evt_len - 1);
+ if (facp->pm1a_cnt_blk)
+ printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
+ facp->pm1a_cnt_blk,
+ facp->pm1a_cnt_blk + facp->pm1_cnt_len - 1);
+ if (facp->pm1b_cnt_blk)
+ printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
+ facp->pm1b_cnt_blk,
+ facp->pm1b_cnt_blk + facp->pm1_cnt_len - 1);
+ if (facp->pm2_cnt_blk)
+ printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
+ facp->pm2_cnt_blk,
+ facp->pm2_cnt_blk + facp->pm2_cnt_len - 1);
+ if (facp->pm_tmr_blk)
+ printf("\tPM2_TMR_BLK=0x%x-0x%x\n",
+ facp->pm_tmr_blk,
+ facp->pm_tmr_blk + facp->pm_tmr_len - 1);
+ if (facp->gpe0_blk)
+ printf("\tPM2_GPE0_BLK=0x%x-0x%x\n",
+ facp->gpe0_blk,
+ facp->gpe0_blk + facp->gpe0_len - 1);
+ if (facp->gpe1_blk)
+ printf("\tPM2_GPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
+ facp->gpe1_blk,
+ facp->gpe1_blk + facp->gpe1_len - 1,
+ facp->gpe1_base);
+ printf("\tP_LVL2_LAT=%dms, P_LVL3_LAT=%dms\n",
+ facp->p_lvl2_lat, facp->p_lvl3_lat);
+ printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
+ facp->flush_size, facp->flush_stride);
+ printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
+ facp->duty_off, facp->duty_width);
+ printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
+ facp->day_alrm, facp->mon_alrm, facp->century);
+ printf("\tFlags=");
+ sep = '{';
+
+#define PRINTFLAG(xx) do { \
+ if (facp->flags & ACPI_FACP_FLAG_## xx) { \
+ printf("%c%s", sep, #xx); sep = ','; \
+ } \
+} while (0)
+
+ PRINTFLAG(WBINVD);
+ PRINTFLAG(WBINVD_FLUSH);
+ PRINTFLAG(PROC_C1);
+ PRINTFLAG(P_LVL2_UP);
+ PRINTFLAG(PWR_BUTTON);
+ PRINTFLAG(SLP_BUTTON);
+ PRINTFLAG(FIX_RTC);
+ PRINTFLAG(RTC_S4);
+ PRINTFLAG(TMR_VAL_EXT);
+ PRINTFLAG(DCK_CAP);
+
+#undef PRINTFLAG
+
+ printf("}\n");
+ printf(END_COMMENT);
+}
+
+void
+acpi_print_dsdt(struct ACPIsdt *dsdp)
+{
+
+ acpi_print_sdt(dsdp);
+}
+
+int
+acpi_checksum(void *p, size_t length)
+{
+ u_int8_t *bp;
+ u_int8_t sum;
+
+ bp = p;
+ sum = 0;
+ while (length--)
+ sum += *bp++;
+
+ return (sum);
+}
+
+struct ACPIsdt *
+acpi_map_sdt(vm_offset_t pa)
+{
+ struct ACPIsdt *sp;
+
+ sp = acpi_map_physical(pa, sizeof(struct ACPIsdt));
+ sp = acpi_map_physical(pa, sp->len);
+ return (sp);
+}
+
+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
+acpi_handle_rsdt(struct ACPIsdt *rsdp)
+{
+ int i;
+ int entries;
+ struct ACPIsdt *sdp;
+
+ 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]);
+ if (acpi_checksum(sdp, sdp->len))
+ errx(1, "RSDT entry %d is corrupt\n", i);
+ if (!memcmp(sdp->signature, "FACP", 4)) {
+ acpi_handle_facp((struct FACPbody *) sdp->body);
+ } else {
+ acpi_print_sdt(sdp);
+ }
+ }
+}
+
+/*
+ * 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/acpidump/acpi_user.c b/usr.sbin/acpidump/acpi_user.c
new file mode 100644
index 00000000000..bd924fa4393
--- /dev/null
+++ b/usr.sbin/acpidump/acpi_user.c
@@ -0,0 +1,169 @@
+/* $OpenBSD: acpi_user.c,v 1.1 2005/06/02 20:09:39 tholo 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: acpi_user.c,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/acpidump/acpi_user.c,v 1.3 2000/11/08 02:37:00 iwasaki Exp $
+ */
+#ifdef __FreeBSD__
+#include <sys/param.h>
+#else
+#include <sys/types.h>
+#define PAGE_MASK (0x1000-1) /*For I386*/
+#define trunc_page(x) ((x) & ~PAGE_MASK)
+#define round_page(x) (((x) + PAGE_MASK) & ~PAGE_MASK)
+#endif
+
+#include <sys/mman.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "acpidump.h"
+
+static int acpi_mem_fd = -1;
+
+struct acpi_user_mapping {
+ LIST_ENTRY(acpi_user_mapping) link;
+ vm_offset_t pa;
+ caddr_t va;
+ size_t size;
+};
+
+LIST_HEAD(acpi_user_mapping_list, acpi_user_mapping) maplist;
+
+static void
+acpi_user_init()
+{
+
+ if (acpi_mem_fd == -1) {
+ acpi_mem_fd = open("/dev/mem", O_RDONLY);
+ if (acpi_mem_fd == -1)
+ err(1, "opening /dev/mem");
+ LIST_INIT(&maplist);
+ }
+}
+
+static struct acpi_user_mapping *
+acpi_user_find_mapping(vm_offset_t pa, size_t size)
+{
+ struct acpi_user_mapping *map;
+
+ /* First search for an existing mapping */
+ for (map = LIST_FIRST(&maplist); map; map = LIST_NEXT(map, link)) {
+ if (map->pa <= pa && map->size >= pa + size - map->pa)
+ return (map);
+ }
+
+ /* Then create a new one */
+ size = round_page(pa + size) - trunc_page(pa);
+ pa = trunc_page(pa);
+ map = malloc(sizeof(struct acpi_user_mapping));
+ if (!map)
+ errx(1, "out of memory");
+ map->pa = pa;
+ map->va = mmap(0, size, PROT_READ, MAP_SHARED, acpi_mem_fd, pa);
+ map->size = size;
+ if ((long) map->va == -1)
+ err(1, "can't map address");
+ LIST_INSERT_HEAD(&maplist, map, link);
+
+ return (map);
+}
+
+/*
+ * Public interfaces
+ */
+
+struct ACPIrsdp *
+acpi_find_rsd_ptr()
+{
+ int i;
+ u_int8_t buf[sizeof(struct ACPIrsdp)];
+
+ acpi_user_init();
+ for (i = 0; i < 1024 * 1024; i += 16) {
+ read(acpi_mem_fd, buf, 16);
+ if (!memcmp(buf, "RSD PTR ", 8)) {
+ /* Read the rest of the structure */
+ read(acpi_mem_fd, buf + 16, sizeof(struct ACPIrsdp) - 16);
+
+ /* Verify checksum before accepting it. */
+ if (acpi_checksum(buf, sizeof(struct ACPIrsdp)))
+ continue;
+ return (acpi_map_physical(i, sizeof(struct ACPIrsdp)));
+ }
+ }
+
+ return (0);
+}
+
+void *
+acpi_map_physical(vm_offset_t pa, size_t size)
+{
+ struct acpi_user_mapping *map;
+
+ map = acpi_user_find_mapping(pa, size);
+ return (map->va + (pa - map->pa));
+}
+
+void
+acpi_load_dsdt(char *dumpfile, u_int8_t **dpp, u_int8_t **endp)
+{
+ u_int8_t *dp;
+ u_int8_t *end;
+ struct stat sb;
+
+ if ((acpi_mem_fd = open(dumpfile, O_RDONLY)) == -1) {
+ errx(1, "opening %s\n", dumpfile);
+ }
+
+ LIST_INIT(&maplist);
+
+ if (fstat(acpi_mem_fd, &sb) == -1) {
+ errx(1, "fstat %s\n", dumpfile);
+ }
+
+ dp = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, acpi_mem_fd, 0);
+ if (dp == NULL) {
+ errx(1, "mmap %s\n", dumpfile);
+ }
+
+ 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;
+ *endp = end;
+}
diff --git a/usr.sbin/acpidump/acpidump.8 b/usr.sbin/acpidump/acpidump.8
new file mode 100644
index 00000000000..bf235989f9e
--- /dev/null
+++ b/usr.sbin/acpidump/acpidump.8
@@ -0,0 +1,170 @@
+.\" $OpenBSD: acpidump.8,v 1.1 2005/06/02 20:09:39 tholo Exp $
+.\"
+.\" Copyright (c) 1999 Doug Rabson <dfr@FreeBSD.org>
+.\" Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
+.\" Copyright (c) 2000 Yasuo YOKOYAMA <yokoyama@jp.FreeBSD.org>
+.\" Copyright (c) 2000 Hiroki Sato <hrs@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 REGENTS 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 REGENTS 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.
+.\"
+.\" $FreeBSD: src/usr.sbin/acpi/acpidump/acpidump.8,v 1.9 2001/09/05 19:21:25 dd Exp $
+.\"
+.Dd August 31, 2000
+.Dt ACPIDUMP 8
+.Os
+.Sh NAME
+.Nm acpidump
+.Nd dump ACPI tables
+.Sh SYNOPSIS
+.Nm
+.Nm
+.Op Fl o Ar dsdt_file_for_output
+.Nm
+.Op Fl f Ar dsdt_file_for_input
+.Sh DESCRIPTION
+The
+.Nm
+command analyzes ACPI tables in physical memory and dumps them to standard output.
+In addition,
+.Nm
+can disassemble some contents of the tables in AML
+(ACPI Machine Language)
+and dump them in ASL
+(ACPI Source Language).
+.Pp
+ACPI tables have an notably essential data block called DSDT
+(Differentiated System Description Table),
+that includes information used on the kernel side such as
+detail information about PnP hardware, procedures for controlling
+a power management support and so on.
+.Nm
+can extract a 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.
+.Pp
+When
+.Nm
+is invoked with no option, it will search ACPI tables from physical
+memory via a special file
+.Pa /dev/mem
+and dump them. First, it searches Root System Description Pointer,
+that has a signature
+.Qq RSD PTR\ \& ,
+and then gets RSDT
+(Root System Description Table),
+which includes a list of pointers to physical memory addresses
+for other tables.
+RSDT itself and all other tables linked from RSDT are generically
+called SDT
+(System Description Table)
+and their header has the common format which consists of items
+such as Signature, Length, Revision, Checksum, OEMID, OEM Table ID,
+OEM Revision, Creator ID and Creator Revision.
+.Nm
+dumps contents of these SDTs.
+For further information about formats of each table,
+see chapter 5: ACPI Software Programming Model,
+.Dq Advanced Configuration and Power Interface Specification Revision 1.0b
+from Intel/Microsoft/Toshiba.
+.Pp
+There is always a pointer to a physical memory address in RSDT for FACP
+(Fixed ACPI Description Table).
+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.
+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,
+DSDT consists of AML data which compiled from sources
+written in free formated ASL, description language for ACPI.
+When
+.Nm
+outputs DSDT, it disassembles the AML data and
+translates them into ASL.
+.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 h
+Displays usage and exit.
+.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.
+.Bd -literal -offset indent
+# acpidump -o foo.dsdt > foo.asl
+.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.
+.Sh FILES
+.Bl -tag -width /dev/mem
+.It Pa /dev/mem
+.El
+.Sh SEE ALSO
+.\" .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
+.Ed
+<URL:http://www.teleport.com/~acpi/>
+.Sh AUTHORS
+.An Doug Rabson Aq dfr@FreeBSD.org
+.An Mitsuru IWASAKI Aq iwasaki@FreeBSD.org
+.An Yasuo YOKOYAMA Aq yokoyama@jp.FreeBSD.org
+.Pp
+Some contributions made by
+.An Chitoshi Ohsawa Aq ohsawa@catv1.ccn-net.ne.jp ,
+.An Takayasu IWANASHI Aq takayasu@wendy.a.perfect-liberty.or.jp ,
+.An Yoshihiko SARUMARU Aq mistral@imasy.or.jp ,
+.An Hiroki Sato Aq hrs@FreeBSD.org ,
+and
+.An Michael Lucas Aq mwlucas@blackhelicopters.org .
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Fx 5.0 .
diff --git a/usr.sbin/acpidump/acpidump.c b/usr.sbin/acpidump/acpidump.c
new file mode 100644
index 00000000000..82c562efc32
--- /dev/null
+++ b/usr.sbin/acpidump/acpidump.c
@@ -0,0 +1,105 @@
+/* $OpenBSD: acpidump.c,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * 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: acpidump.c,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/acpidump/acpidump.c,v 1.3 2000/11/08 02:37:00 iwasaki Exp $
+ */
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <err.h>
+#include <stdio.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->addr);
+ if (memcmp(rsdp->signature, "RSDT", 4) ||
+ acpi_checksum(rsdp, rsdp->len))
+ errx(1, "RSDT is corrupted\n");
+
+ acpi_handle_rsdt(rsdp);
+}
+
+static void
+usage(const char *progname)
+{
+
+ printf("usage:\t%s [-o dsdt_file_for_output]\n", progname);
+ printf("\t%s [-f dsdt_file_for_input]\n", progname);
+ printf("\t%s [-h]\n", progname);
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char c, *progname;
+
+ progname = argv[0];
+ while ((c = getopt(argc, argv, "f:o:h")) != -1) {
+ switch (c) {
+ case 'f':
+ asl_dump_from_file(optarg);
+ return (0);
+ case 'o':
+ aml_dumpfile = optarg;
+ break;
+ case 'h':
+ usage(progname);
+ break;
+ default:
+ argc -= optind;
+ argv += optind;
+ }
+ }
+
+ asl_dump_from_devmem();
+ return (0);
+}
diff --git a/usr.sbin/acpidump/acpidump.h b/usr.sbin/acpidump/acpidump.h
new file mode 100644
index 00000000000..4d1ce79966e
--- /dev/null
+++ b/usr.sbin/acpidump/acpidump.h
@@ -0,0 +1,184 @@
+/* $OpenBSD: acpidump.h,v 1.1 2005/06/02 20:09:39 tholo 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: acpidump.h,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/acpidump/acpidump.h,v 1.2 2000/11/08 02:37:00 iwasaki Exp $
+ */
+
+#ifndef _ACPIDUMP_H_
+#define _ACPIDUMP_H_
+#include <stdlib.h>
+
+typedef unsigned long vm_offset_t;
+
+/* Generic Address structure */
+struct ACPIgas {
+ u_int8_t address_space_id;
+#define ACPI_GAS_MEMORY 0
+#define ACPI_GAS_IO 1
+#define ACPI_GAS_PCI 2
+#define ACPI_GAS_EMBEDDED 3
+#define ACPI_GAS_SMBUS 4
+#define ACPI_GAS_FIXED 0x7f
+ u_int8_t register_bit_width;
+ u_int8_t register_bit_offset;
+ u_int8_t res;
+ u_int64_t address;
+} __attribute__((packed));
+
+/* Root System Description Pointer */
+struct ACPIrsdp {
+ u_char signature[8];
+ u_char sum;
+ u_char oem[6];
+ u_char res;
+ u_int32_t addr;
+} __attribute__((packed));
+
+/* System Description Table */
+struct ACPIsdt {
+ u_char signature[4];
+ u_int32_t len;
+ u_char rev;
+ u_char check;
+ u_char oemid[6];
+ u_char oemtblid[8];
+ u_int32_t oemrev;
+ u_char creator[4];
+ u_int32_t crerev;
+#define SIZEOF_SDT_HDR 36 /* struct size except body */
+ u_int32_t body[1];/* This member should be casted */
+} __attribute__((packed));
+
+/* Fixed ACPI Description Table (body) */
+struct FACPbody {
+ u_int32_t facs_ptr;
+ u_int32_t dsdt_ptr;
+ u_int8_t int_model;
+#define ACPI_FACP_INTMODEL_PIC 0 /* Standard PC-AT PIC */
+#define ACPI_FACP_INTMODEL_APIC 1 /* Multiple APIC */
+ u_char reserved1;
+ u_int16_t sci_int;
+ u_int32_t smi_cmd;
+ u_int8_t acpi_enable;
+ u_int8_t acpi_disable;
+ u_int8_t s4biosreq;
+ u_int8_t reserved2;
+ u_int32_t pm1a_evt_blk;
+ u_int32_t pm1b_evt_blk;
+ u_int32_t pm1a_cnt_blk;
+ u_int32_t pm1b_cnt_blk;
+ u_int32_t pm2_cnt_blk;
+ u_int32_t pm_tmr_blk;
+ u_int32_t gpe0_blk;
+ u_int32_t gpe1_blk;
+ u_int8_t pm1_evt_len;
+ u_int8_t pm1_cnt_len;
+ u_int8_t pm2_cnt_len;
+ u_int8_t pm_tmr_len;
+ u_int8_t gpe0_len;
+ u_int8_t gpe1_len;
+ u_int8_t gpe1_base;
+ u_int8_t reserved3;
+ u_int16_t p_lvl2_lat;
+ u_int16_t p_lvl3_lat;
+ u_int16_t flush_size;
+ u_int16_t flush_stride;
+ u_int8_t duty_off;
+ u_int8_t duty_width;
+ u_int8_t day_alrm;
+ u_int8_t mon_alrm;
+ u_int8_t century;
+ u_int16_t iapc_boot_arch;
+ u_char reserved4[1];
+ u_int32_t flags;
+#define ACPI_FACP_FLAG_WBINVD 1 /* WBINVD is correctly supported */
+#define ACPI_FACP_FLAG_WBINVD_FLUSH 2 /* WBINVD flushes caches */
+#define ACPI_FACP_FLAG_PROC_C1 4 /* C1 power state supported */
+#define ACPI_FACP_FLAG_P_LVL2_UP 8 /* C2 power state works on SMP */
+#define ACPI_FACP_FLAG_PWR_BUTTON 16 /* Power button uses control method */
+#define ACPI_FACP_FLAG_SLP_BUTTON 32 /* Sleep button uses control method */
+#define ACPI_FACP_FLAG_FIX_RTC 64 /* RTC wakeup not supported */
+#define ACPI_FACP_FLAG_RTC_S4 128 /* RTC can wakeup from S4 state */
+#define ACPI_FACP_FLAG_TMR_VAL_EXT 256 /* TMR_VAL is 32bit */
+#define ACPI_FACP_FLAG_DCK_CAP 512 /* Can support docking */
+ struct ACPIgas reset_reg;
+ u_int8_t reset_value;
+ u_int8_t reserved5[3];
+ u_int64_t x_firmware_ctrl;
+ u_int64_t x_dsdt;
+ struct ACPIgas x_pm1a_evt_blk;
+ struct ACPIgas x_pm1b_evt_blk;
+ struct ACPIgas x_pm1a_cnt_blk;
+ struct ACPIgas x_pm1b_cnt_blk;
+ struct ACPIgas x_pm2_cnt_blk;
+ struct ACPIgas x_pm_tmr_blk;
+ struct ACPIgas x_gpe0_blk;
+ struct ACPIgas x_gpe1_blk;
+} __attribute__((packed));
+
+/* Firmware ACPI Control Structure */
+struct FACS {
+ u_char signature[4];
+ u_int32_t len;
+ u_char hard_sig[4];
+ /*
+ * NOTE This should be filled with physical address below 1MB!!
+ * sigh....
+ */
+ u_int32_t firm_wake_vec;
+ 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
+ u_int32_t flags; /* bit field */
+#define ACPI_FACS_FLAG_S4BIOS_F 1 /* Supports S4BIOS_SEQ */
+ char reserved[40];
+} __attribute__((packed));
+
+void *acpi_map_physical(vm_offset_t, size_t);
+struct ACPIrsdp *acpi_find_rsd_ptr(void);
+int acpi_checksum(void *, size_t);
+struct ACPIsdt *acpi_map_sdt(vm_offset_t);
+void acpi_print_rsd_ptr(struct ACPIrsdp *);
+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;
+
+#endif /* !_ACPIDUMP_H_ */
diff --git a/usr.sbin/acpidump/aml/aml_amlmem.c b/usr.sbin/acpidump/aml/aml_amlmem.c
new file mode 100644
index 00000000000..b696465ba64
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_amlmem.c
@@ -0,0 +1,91 @@
+/* $OpenBSD: aml_amlmem.c,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999, 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_amlmem.c,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_amlmem.c,v 1.2 2000/11/09 06:24:45 iwasaki Exp $
+ */
+
+/*
+ * AML Namespace Memory Management
+ */
+#include <sys/types.h>
+#include <aml/aml_env.h>
+#include <aml/aml_memman.h>
+#include <aml/aml_name.h>
+
+MEMMAN_INITIALSTORAGE_DESC(struct aml_namestr, _aml_namestr_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_num, _aml_num_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_string, _aml_string_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_buffer, _aml_buffer_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_package, _aml_package_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_field, _aml_field_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_method, _aml_method_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_mutex, _aml_mutex_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_opregion, _aml_opregion_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_powerres, _aml_powerres_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_processor, _aml_processor_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_bufferfield, _aml_bufferfield_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_event, _aml_event_storage);
+MEMMAN_INITIALSTORAGE_DESC(enum aml_objtype, _aml_objtype_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_name, _aml_name_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_name_group, _aml_name_group_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_objref, _aml_objref_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_regfield, _aml_regfield_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_environ, _aml_environ_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_local_stack, _aml_local_stack_storage);
+MEMMAN_INITIALSTORAGE_DESC(struct aml_mutex_queue, _aml_mutex_queue_storage);
+
+struct memman_blockman aml_blockman[] = {
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_namestr), _aml_namestr_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_num), _aml_num_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_string), _aml_string_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_buffer), _aml_buffer_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_package), _aml_package_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_field), _aml_field_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_method), _aml_method_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_mutex), _aml_mutex_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_opregion), _aml_opregion_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_powerres), _aml_powerres_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_processor), _aml_processor_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_bufferfield), _aml_bufferfield_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_event), _aml_event_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(enum aml_objtype), _aml_objtype_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_name), _aml_name_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_name_group), _aml_name_group_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_objref), _aml_objref_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_regfield), _aml_regfield_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_environ), _aml_environ_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_local_stack), _aml_local_stack_storage),
+ MEMMAN_MEMBLOCK_DESC(sizeof(struct aml_mutex_queue), _aml_mutex_queue_storage),
+};
+
+struct memman_histogram aml_histogram[MEMMAN_HISTOGRAM_SIZE];
+
+static struct memman _aml_memman = MEMMAN_MEMMANAGER_DESC(aml_blockman, 21,
+ aml_histogram, 1);
+
+struct memman *aml_memman = &_aml_memman;
+
diff --git a/usr.sbin/acpidump/aml/aml_amlmem.h b/usr.sbin/acpidump/aml/aml_amlmem.h
new file mode 100644
index 00000000000..354c6522547
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_amlmem.h
@@ -0,0 +1,66 @@
+/* $OpenBSD: aml_amlmem.h,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999 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_amlmem.h,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_amlmem.h,v 1.2 2000/11/09 06:24:45 iwasaki Exp $
+ */
+
+#ifndef _AML_AMLMEM_H_
+#define _AML_AMLMEM_H_
+
+/*
+ * AML Namespace Memory Management
+ */
+
+#include <aml/aml_memman.h>
+
+enum {
+ memid_aml_namestr = 0,
+ memid_aml_num,
+ memid_aml_string,
+ memid_aml_buffer,
+ memid_aml_package,
+ memid_aml_field,
+ memid_aml_method,
+ memid_aml_mutex,
+ memid_aml_opregion,
+ memid_aml_powerres,
+ memid_aml_processor,
+ memid_aml_bufferfield,
+ memid_aml_event,
+ memid_aml_objtype,
+ memid_aml_name,
+ memid_aml_name_group,
+ memid_aml_objref,
+ memid_aml_regfield,
+ memid_aml_environ,
+ memid_aml_local_stack,
+ memid_aml_mutex_queue,
+};
+
+extern struct memman *aml_memman;
+
+#endif /* !_AML_AMLMEM_H_ */
diff --git a/usr.sbin/acpidump/aml/aml_common.c b/usr.sbin/acpidump/aml/aml_common.c
new file mode 100644
index 00000000000..32a97d9ac78
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_common.c
@@ -0,0 +1,734 @@
+/* $OpenBSD: aml_common.c,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999 Takanori Watanabe
+ * Copyright (c) 1999, 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_common.c,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_common.c,v 1.6 2000/11/09 06:24:45 iwasaki Exp $
+ */
+#include <sys/types.h>
+#ifndef _KERNEL
+#include <assert.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#else /* _KERNEL */
+#include "opt_acpi.h"
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+#ifndef ACPI_NO_OSDFUNC_INLINE
+#include <machine/acpica_osd.h>
+#endif /* !ACPI_NO_OSDFUNC_INLINE */
+#endif /* !_KERNEL */
+
+#include <aml/aml_common.h>
+#include <aml/aml_env.h>
+#include <aml/aml_evalobj.h>
+#include <aml/aml_name.h>
+#include <aml/aml_obj.h>
+#include <aml/aml_parse.h>
+#include <aml/aml_status.h>
+#include <aml/aml_store.h>
+
+/* for debugging */
+#ifdef AML_DEBUG
+int aml_debug = 1;
+#else /* !AML_DEBUG */
+int aml_debug = 0;
+#endif /* AML_DEBUG */
+#ifdef _KERNEL
+SYSCTL_INT(_debug, OID_AUTO, aml_debug, CTLFLAG_RW, &aml_debug, 1, "");
+#endif /* _KERNEL */
+
+static void aml_print_nameseg(u_int8_t *dp);
+
+static void
+aml_print_nameseg(u_int8_t *dp)
+{
+
+ if (dp[3] != '_') {
+ AML_DEBUGPRINT("%c%c%c%c", dp[0], dp[1], dp[2], dp[3]);
+ } else if (dp[2] != '_') {
+ AML_DEBUGPRINT("%c%c%c_", dp[0], dp[1], dp[2]);
+ } else if (dp[1] != '_') {
+ AML_DEBUGPRINT("%c%c__", dp[0], dp[1]);
+ } else if (dp[0] != '_') {
+ AML_DEBUGPRINT("%c___", dp[0]);
+ }
+}
+
+void
+aml_print_namestring(u_int8_t *dp)
+{
+ int segcount;
+ int i;
+
+ if (dp[0] == '\\') {
+ AML_DEBUGPRINT("%c", dp[0]);
+ dp++;
+ } else if (dp[0] == '^') {
+ while (dp[0] == '^') {
+ AML_DEBUGPRINT("%c", dp[0]);
+ dp++;
+ }
+ }
+ if (dp[0] == 0x00) { /* NullName */
+ /* AML_DEBUGPRINT("<null>"); */
+ dp++;
+ } else if (dp[0] == 0x2e) { /* DualNamePrefix */
+ aml_print_nameseg(dp + 1);
+ AML_DEBUGPRINT("%c", '.');
+ aml_print_nameseg(dp + 5);
+ } else if (dp[0] == 0x2f) { /* MultiNamePrefix */
+ segcount = dp[1];
+ for (i = 0, dp += 2; i < segcount; i++, dp += 4) {
+ if (i > 0) {
+ AML_DEBUGPRINT("%c", '.');
+ }
+ aml_print_nameseg(dp);
+ }
+ } else /* NameSeg */
+ aml_print_nameseg(dp);
+}
+
+int
+aml_print_curname(struct aml_name *name)
+{
+ struct aml_name *root;
+
+ root = aml_get_rootname();
+ if (name == root) {
+ AML_DEBUGPRINT("\\");
+ return (0);
+ } else {
+ aml_print_curname(name->parent);
+ }
+ aml_print_nameseg(name->name);
+ AML_DEBUGPRINT(".");
+ return (0);
+}
+
+void
+aml_print_indent(int indent)
+{
+ int i;
+
+ for (i = 0; i < indent; i++)
+ AML_DEBUGPRINT(" ");
+}
+
+void
+aml_showobject(union aml_object * obj)
+{
+ int debug;
+ int i;
+
+ if (obj == NULL) {
+ printf("NO object\n");
+ return;
+ }
+ debug = aml_debug;
+ aml_debug = 1;
+ switch (obj->type) {
+ case aml_t_num:
+ printf("Num:0x%x\n", obj->num.number);
+ break;
+ case aml_t_processor:
+ printf("Processor:No %d,Port 0x%x length 0x%x\n",
+ obj->proc.id, obj->proc.addr, obj->proc.len);
+ break;
+ case aml_t_mutex:
+ printf("Mutex:Level %d\n", obj->mutex.level);
+ break;
+ case aml_t_powerres:
+ printf("PowerResource:Level %d Order %d\n",
+ obj->pres.level, obj->pres.order);
+ break;
+ case aml_t_opregion:
+ printf("OprationRegion:Busspace%d, Offset 0x%x Length 0x%x\n",
+ obj->opregion.space, obj->opregion.offset,
+ obj->opregion.length);
+ break;
+ case aml_t_field:
+ printf("Fieldelement:flag 0x%x offset 0x%x len 0x%x {",
+ obj->field.flags, obj->field.bitoffset,
+ obj->field.bitlen);
+ switch (obj->field.f.ftype) {
+ case f_t_field:
+ aml_print_namestring(obj->field.f.fld.regname);
+ break;
+ case f_t_index:
+ aml_print_namestring(obj->field.f.ifld.indexname);
+ printf(" ");
+ aml_print_namestring(obj->field.f.ifld.dataname);
+ break;
+ case f_t_bank:
+ aml_print_namestring(obj->field.f.bfld.regname);
+ printf(" ");
+ aml_print_namestring(obj->field.f.bfld.bankname);
+ printf("0x%x", obj->field.f.bfld.bankvalue);
+ break;
+ }
+ printf("}\n");
+ break;
+ case aml_t_method:
+ printf("Method: Arg %d From %p To %p\n", obj->meth.argnum,
+ obj->meth.from, obj->meth.to);
+ break;
+ case aml_t_buffer:
+ printf("Buffer: size:0x%x Data %p\n", obj->buffer.size,
+ obj->buffer.data);
+ break;
+ case aml_t_device:
+ printf("Device\n");
+ break;
+ case aml_t_bufferfield:
+ printf("Bufferfield:offset 0x%x len 0x%x Origin %p\n",
+ obj->bfld.bitoffset, obj->bfld.bitlen, obj->bfld.origin);
+ break;
+ case aml_t_string:
+ printf("String:%s\n", obj->str.string);
+ break;
+ case aml_t_package:
+ printf("Package:elements %d \n", obj->package.elements);
+ for (i = 0; i < obj->package.elements; i++) {
+ if (obj->package.objects[i] == NULL) {
+ break;
+ }
+ if (obj->package.objects[i]->type < 0) {
+ continue;
+ }
+ printf(" ");
+ aml_showobject(obj->package.objects[i]);
+ }
+ break;
+ case aml_t_therm:
+ printf("Thermalzone\n");
+ break;
+ case aml_t_event:
+ printf("Event\n");
+ break;
+ case aml_t_ddbhandle:
+ printf("DDBHANDLE\n");
+ break;
+ case aml_t_objref:
+ if (obj->objref.alias == 1) {
+ printf("Alias");
+ } else {
+ printf("Object reference");
+ if (obj->objref.offset >= 0) {
+ printf(" (offset 0x%x)", obj->objref.offset);
+ }
+ }
+ printf(" of ");
+ aml_showobject(obj->objref.ref);
+ break;
+ default:
+ printf("UNK ID=%d\n", obj->type);
+ }
+
+ aml_debug = debug;
+}
+
+void
+aml_showtree(struct aml_name * aname, int lev)
+{
+ int i;
+ struct aml_name *ptr;
+ char name[5];
+
+ for (i = 0; i < lev; i++) {
+ printf(" ");
+ }
+ strncpy(name, aname->name, 4);
+ name[4] = 0;
+ printf("%s ", name);
+ if (aname->property != NULL) {
+ aml_showobject(aname->property);
+ } else {
+ printf("\n");
+ }
+ for (ptr = aname->child; ptr; ptr = ptr->brother)
+ aml_showtree(ptr, lev + 1);
+}
+
+/*
+ * Common Region I/O Stuff
+ */
+
+static __inline u_int64_t
+aml_adjust_bitmask(u_int32_t flags, u_int32_t bitlen)
+{
+ u_int64_t bitmask;
+
+ switch (AML_FIELDFLAGS_ACCESSTYPE(flags)) {
+ case AML_FIELDFLAGS_ACCESS_ANYACC:
+ if (bitlen <= 8) {
+ bitmask = 0x000000ff;
+ break;
+ }
+ if (bitlen <= 16) {
+ bitmask = 0x0000ffff;
+ break;
+ }
+ bitmask = 0xffffffff;
+ break;
+ case AML_FIELDFLAGS_ACCESS_BYTEACC:
+ bitmask = 0x000000ff;
+ break;
+ case AML_FIELDFLAGS_ACCESS_WORDACC:
+ bitmask = 0x0000ffff;
+ break;
+ case AML_FIELDFLAGS_ACCESS_DWORDACC:
+ default:
+ bitmask = 0xffffffff;
+ break;
+ }
+
+ switch (bitlen) {
+ case 16:
+ bitmask |= 0x0000ffff;
+ break;
+ case 32:
+ bitmask |= 0xffffffff;
+ break;
+ }
+
+ return (bitmask);
+}
+
+u_int32_t
+aml_adjust_readvalue(u_int32_t flags, u_int32_t bitoffset, u_int32_t bitlen,
+ u_int32_t orgval)
+{
+ u_int32_t offset, retval;
+ u_int64_t bitmask;
+
+ offset = bitoffset; /* XXX bitoffset may change in this function! */
+ bitmask = aml_adjust_bitmask(flags, bitlen);
+ retval = (orgval >> offset) & (~(bitmask << bitlen)) & bitmask;
+
+ return (retval);
+}
+
+u_int32_t
+aml_adjust_updatevalue(u_int32_t flags, u_int32_t bitoffset, u_int32_t bitlen,
+ u_int32_t orgval, u_int32_t value)
+{
+ u_int32_t offset, retval;
+ u_int64_t bitmask;
+
+ offset = bitoffset; /* XXX bitoffset may change in this function! */
+ bitmask = aml_adjust_bitmask(flags, bitlen);
+ retval = orgval;
+ switch (AML_FIELDFLAGS_UPDATERULE(flags)) {
+ case AML_FIELDFLAGS_UPDATE_PRESERVE:
+ retval &= (~(((u_int64_t)1 << bitlen) - 1) << offset) |
+ (~(bitmask << offset));
+ break;
+ case AML_FIELDFLAGS_UPDATE_WRITEASONES:
+ retval = (~(((u_int64_t)1 << bitlen) - 1) << offset) |
+ (~(bitmask << offset));
+ retval &= bitmask; /* trim the upper bits */
+ break;
+ case AML_FIELDFLAGS_UPDATE_WRITEASZEROS:
+ retval = 0;
+ break;
+ default:
+ printf("illegal update rule: %d\n", flags);
+ return (orgval);
+ }
+
+ retval |= (value << (offset & bitmask));
+ return (retval);
+}
+
+/*
+ * BufferField I/O
+ */
+
+#define AML_BUFFER_INPUT 0
+#define AML_BUFFER_OUTPUT 1
+
+static int aml_bufferfield_io(int io, u_int32_t *valuep,
+ u_int8_t *origin, u_int32_t bitoffset,
+ u_int32_t bitlen);
+
+static int
+aml_bufferfield_io(int io, u_int32_t *valuep, u_int8_t *origin,
+ u_int32_t bitoffset, u_int32_t bitlen)
+{
+ u_int8_t val, tmp, masklow, maskhigh;
+ u_int8_t offsetlow, offsethigh;
+ u_int8_t *addr;
+ int i;
+ u_int32_t value, readval;
+ u_int32_t byteoffset, bytelen;
+
+ masklow = maskhigh = 0xff;
+ val = readval = 0;
+ value = *valuep;
+
+ byteoffset = bitoffset / 8;
+ bytelen = bitlen / 8 + ((bitlen % 8) ? 1 : 0);
+ addr = origin + byteoffset;
+
+ /* simple I/O ? */
+ if (bitlen <= 8 || bitlen == 16 || bitlen == 32) {
+ bcopy(addr, &readval, bytelen);
+ AML_DEBUGPRINT("\n\t[bufferfield:0x%x@%p:%d,%d]",
+ readval, addr, bitoffset % 8, bitlen);
+ switch (io) {
+ case AML_BUFFER_INPUT:
+ value = aml_adjust_readvalue(AML_FIELDFLAGS_ACCESS_BYTEACC,
+ bitoffset % 8, bitlen, readval);
+ *valuep = value;
+ AML_DEBUGPRINT("\n[read(bufferfield, %p)&mask:0x%x]\n",
+ addr, value);
+ break;
+ case AML_BUFFER_OUTPUT:
+ value = aml_adjust_updatevalue(AML_FIELDFLAGS_ACCESS_BYTEACC,
+ bitoffset % 8, bitlen, readval, value);
+ bcopy(&value, addr, bytelen);
+ AML_DEBUGPRINT("->[bufferfield:0x%x@%p:%d,%d]",
+ value, addr, bitoffset % 8, bitlen);
+ break;
+ }
+ goto out;
+ }
+
+ offsetlow = bitoffset % 8;
+ if (bytelen > 1) {
+ offsethigh = (bitlen - (8 - offsetlow)) % 8;
+ } else {
+ offsethigh = 0;
+ }
+
+ if (offsetlow) {
+ masklow = (~((1 << bitlen) - 1) << offsetlow) | ~(0xff << offsetlow);
+ AML_DEBUGPRINT("\t[offsetlow = 0x%x, masklow = 0x%x, ~masklow = 0x%x]\n",
+ offsetlow, masklow, ~masklow & 0xff);
+ }
+ if (offsethigh) {
+ maskhigh = 0xff << offsethigh;
+ AML_DEBUGPRINT("\t[offsethigh = 0x%x, maskhigh = 0x%x, ~maskhigh = 0x%x]\n",
+ offsethigh, maskhigh, ~maskhigh & 0xff);
+ }
+ for (i = bytelen; i > 0; i--, addr++) {
+ val = *addr;
+
+ AML_DEBUGPRINT("\t[bufferfield:0x%02x@%p]", val, addr);
+
+ switch (io) {
+ case AML_BUFFER_INPUT:
+ tmp = val;
+ /* the lowest byte? */
+ if (i == bytelen) {
+ if (offsetlow) {
+ readval = tmp & ~masklow;
+ } else {
+ readval = tmp;
+ }
+ } else {
+ if (i == 1 && offsethigh) {
+ tmp = tmp & ~maskhigh;
+ }
+ readval = (tmp << (8 * (bytelen - i))) | readval;
+ }
+
+ AML_DEBUGPRINT("\n");
+ /* goto to next byte... */
+ if (i > 1) {
+ continue;
+ }
+ /* final adjustment before finishing region access */
+ if (offsetlow) {
+ readval = readval >> offsetlow;
+ }
+ AML_DEBUGPRINT("[read(bufferfield, %p)&mask:0x%x]\n",
+ addr, readval);
+ *valuep = readval;
+
+ break;
+
+ case AML_BUFFER_OUTPUT:
+ tmp = value & 0xff;
+ /* the lowest byte? */
+ if (i == bytelen) {
+ if (offsetlow) {
+ tmp = (val & masklow) | tmp << offsetlow;
+ }
+ value = value >> (8 - offsetlow);
+ } else {
+ if (i == 1 && offsethigh) {
+ tmp = (val & maskhigh) | tmp;
+ }
+ value = value >> 8;
+ }
+
+ AML_DEBUGPRINT("->[bufferfield:0x%02x@%p]\n",
+ tmp, addr);
+ *addr = tmp;
+ }
+ }
+out:
+ return (0);
+}
+
+u_int32_t
+aml_bufferfield_read(u_int8_t *origin, u_int32_t bitoffset,
+ u_int32_t bitlen)
+{
+ int value;
+
+ value = 0;
+ aml_bufferfield_io(AML_BUFFER_INPUT, &value, origin,
+ bitoffset, bitlen);
+ return (value);
+}
+
+int
+aml_bufferfield_write(u_int32_t value, u_int8_t *origin,
+ u_int32_t bitoffset, u_int32_t bitlen)
+{
+ int status;
+
+ status = aml_bufferfield_io(AML_BUFFER_OUTPUT, &value,
+ origin, bitoffset, bitlen);
+ return (status);
+}
+
+int
+aml_region_handle_alloc(struct aml_environ *env, int regtype, u_int32_t flags,
+ u_int32_t baseaddr, u_int32_t bitoffset, u_int32_t bitlen,
+ struct aml_region_handle *h)
+{
+ int state;
+ struct aml_name *pci_info;
+
+ state = 0;
+ pci_info = NULL;
+ bzero(h, sizeof(struct aml_region_handle));
+
+ h->env = env;
+ h->regtype = regtype;
+ h->flags = flags;
+ h->baseaddr = baseaddr;
+ h->bitoffset = bitoffset;
+ h->bitlen = bitlen;
+
+ switch (AML_FIELDFLAGS_ACCESSTYPE(flags)) {
+ case AML_FIELDFLAGS_ACCESS_ANYACC:
+ if (bitlen <= 8) {
+ h->unit = 1;
+ break;
+ }
+ if (bitlen <= 16) {
+ h->unit = 2;
+ break;
+ }
+ h->unit = 4;
+ break;
+ case AML_FIELDFLAGS_ACCESS_BYTEACC:
+ h->unit = 1;
+ break;
+ case AML_FIELDFLAGS_ACCESS_WORDACC:
+ h->unit = 2;
+ break;
+ case AML_FIELDFLAGS_ACCESS_DWORDACC:
+ h->unit = 4;
+ break;
+ default:
+ h->unit = 1;
+ break;
+ }
+
+ h->addr = baseaddr + h->unit * ((bitoffset / 8) / h->unit);
+ h->bytelen = baseaddr + ((bitoffset + bitlen) / 8) - h->addr +
+ ((bitlen % 8) ? 1 : 0);
+
+#ifdef _KERNEL
+ switch (h->regtype) {
+ case AML_REGION_SYSMEM:
+ OsdMapMemory((void *)h->addr, h->bytelen, (void **)&h->vaddr);
+ break;
+
+ case AML_REGION_PCICFG:
+ /* Obtain PCI bus number */
+ pci_info = aml_search_name(env, "_BBN");
+ if (pci_info == NULL || pci_info->property->type != aml_t_num) {
+ AML_DEBUGPRINT("Cannot locate _BBN. Using default 0\n");
+ h->pci_bus = 0;
+ } else {
+ AML_DEBUGPRINT("found _BBN: %d\n",
+ pci_info->property->num.number);
+ h->pci_bus = pci_info->property->num.number & 0xff;
+ }
+
+ /* Obtain device & function number */
+ pci_info = aml_search_name(env, "_ADR");
+ if (pci_info == NULL || pci_info->property->type != aml_t_num) {
+ printf("Cannot locate: _ADR\n");
+ state = -1;
+ goto out;
+ }
+ h->pci_devfunc = pci_info->property->num.number;
+
+ AML_DEBUGPRINT("[pci%d.%d]", h->pci_bus, h->pci_devfunc);
+ break;
+
+ default:
+ break;
+ }
+
+out:
+#endif /* _KERNEL */
+ return (state);
+}
+
+void
+aml_region_handle_free(struct aml_region_handle *h)
+{
+#ifdef _KERNEL
+ switch (h->regtype) {
+ case AML_REGION_SYSMEM:
+ OsdUnMapMemory((void *)h->vaddr, h->bytelen);
+ break;
+
+ default:
+ break;
+ }
+#endif /* _KERNEL */
+}
+
+static int
+aml_region_io_simple(struct aml_environ *env, int io, int regtype,
+ u_int32_t flags, u_int32_t *valuep, u_int32_t baseaddr,
+ u_int32_t bitoffset, u_int32_t bitlen)
+{
+ int i, state;
+ u_int32_t readval, value, offset, bytelen;
+ struct aml_region_handle handle;
+
+ state = aml_region_handle_alloc(env, regtype, flags,
+ baseaddr, bitoffset, bitlen, &handle);
+ if (state == -1) {
+ goto out;
+ }
+
+ readval = 0;
+ offset = bitoffset % (handle.unit * 8);
+ /* limitation of 32 bits alignment */
+ bytelen = (handle.bytelen > 4) ? 4 : handle.bytelen;
+
+ if (io == AML_REGION_INPUT ||
+ AML_FIELDFLAGS_UPDATERULE(flags) == AML_FIELDFLAGS_UPDATE_PRESERVE) {
+ for (i = 0; i < bytelen; i += handle.unit) {
+ state = aml_region_read_simple(&handle, i, &value);
+ if (state == -1) {
+ goto out;
+ }
+ readval |= (value << (i * 8));
+ }
+ AML_DEBUGPRINT("\t[%d:0x%x@0x%x:%d,%d]",
+ regtype, readval, handle.addr, offset, bitlen);
+ }
+
+ switch (io) {
+ case AML_REGION_INPUT:
+ AML_DEBUGPRINT("\n");
+ readval = aml_adjust_readvalue(flags, offset, bitlen, readval);
+ value = readval;
+ value = aml_region_prompt_read(&handle, value);
+ state = aml_region_prompt_update_value(readval, value, &handle);
+ if (state == -1) {
+ goto out;
+ }
+
+ *valuep = value;
+ break;
+ case AML_REGION_OUTPUT:
+ value = *valuep;
+ value = aml_adjust_updatevalue(flags, offset,
+ bitlen, readval, value);
+ value = aml_region_prompt_write(&handle, value);
+ AML_DEBUGPRINT("\t->[%d:0x%x@0x%x:%d,%d]\n", regtype, value,
+ handle.addr, offset, bitlen);
+ for (i = 0; i < bytelen; i += handle.unit) {
+ state = aml_region_write_simple(&handle, i, value);
+ if (state == -1) {
+ goto out;
+ }
+ value = value >> (handle.unit * 8);
+ }
+ break;
+ }
+
+ aml_region_handle_free(&handle);
+out:
+ return (state);
+}
+
+int
+aml_region_io(struct aml_environ *env, int io, int regtype,
+ u_int32_t flags, u_int32_t *valuep, u_int32_t baseaddr,
+ u_int32_t bitoffset, u_int32_t bitlen)
+{
+ u_int32_t unit, offset;
+ u_int32_t offadj, bitadj;
+ u_int32_t value, readval;
+ int state, i;
+
+ readval = 0;
+ state = 0;
+ unit = 4; /* limitation of 32 bits alignment */
+ offset = bitoffset % (unit * 8);
+ offadj = 0;
+ bitadj = 0;
+ if (offset + bitlen > unit * 8) {
+ bitadj = bitlen - (unit * 8 - offset);
+ }
+ for (i = 0; i < offset + bitlen; i += unit * 8) {
+ value = (*valuep) >> offadj;
+ state = aml_region_io_simple(env, io, regtype, flags,
+ &value, baseaddr, bitoffset + offadj, bitlen - bitadj);
+ if (state == -1) {
+ goto out;
+ }
+ readval |= value << offadj;
+ bitadj = offadj = bitlen - bitadj;
+ }
+ *valuep = readval;
+
+out:
+ return (state);
+}
diff --git a/usr.sbin/acpidump/aml/aml_common.h b/usr.sbin/acpidump/aml/aml_common.h
new file mode 100644
index 00000000000..5ea32924a4a
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_common.h
@@ -0,0 +1,162 @@
+/* $OpenBSD: aml_common.h,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * 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_common.h,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_common.h,v 1.4 2000/10/02 08:58:47 iwasaki Exp $
+ */
+
+#ifndef _AML_COMMON_H_
+#define _AML_COMMON_H_
+
+#include "acpidump.h"
+
+/*
+ * General Stuff
+ */
+#ifdef _KERNEL
+#define AML_SYSABORT() do { \
+ printf("aml: fatal errer at %s:%d\n", __FILE__, __LINE__); \
+ panic("panic in AML interpreter!"); \
+} while(0)
+#define AML_SYSASSERT(x) do { \
+ if (!(x)) { \
+ AML_SYSABORT(); \
+ } \
+} while(0)
+#define AML_SYSERRX(eval, fmt, args...) do { \
+ printf(fmt, args); \
+} while(0)
+#define AML_DEBUGGER(x, y) /* no debugger in kernel */
+#define AML_STALL(micro) OsdSleepUsec(micro)
+#define AML_SLEEP(sec, milli) OsdSleep(sec, milli)
+#else /* !_KERNEL */
+#define AML_SYSASSERT(x) assert(x)
+#define AML_SYSABORT() abort()
+#define AML_SYSERRX(eval, fmt, args...) errx(eval, fmt, args)
+#define AML_DEBUGGER(x, y) aml_dbgr(x, y)
+#define AML_STALL(micro) /* not required in userland */
+#define AML_SLEEP(sec, milli) /* not required in userland */
+#endif /* _KERNEL */
+
+union aml_object;
+struct aml_name;
+
+extern int aml_debug;
+
+#define AML_DEBUGPRINT(args...) do { \
+ if (aml_debug) { \
+ printf(args); \
+ } \
+} while(0)
+
+void aml_showobject(union aml_object *);
+void aml_showtree(struct aml_name *, int);
+int aml_print_curname(struct aml_name *);
+void aml_print_namestring(u_int8_t *);
+void aml_print_indent(int);
+
+/*
+ * Reigion I/O Stuff for both kernel/userland.
+ */
+
+/*
+ * Field Flags
+ */
+/* bit 0 -3: AccessType */
+#define AML_FIELDFLAGS_ACCESS_ANYACC 0x00
+#define AML_FIELDFLAGS_ACCESS_BYTEACC 0x01
+#define AML_FIELDFLAGS_ACCESS_WORDACC 0x02
+#define AML_FIELDFLAGS_ACCESS_DWORDACC 0x03
+#define AML_FIELDFLAGS_ACCESS_BLOCKACC 0x04
+#define AML_FIELDFLAGS_ACCESS_SMBSENDRECVACC 0x05
+#define AML_FIELDFLAGS_ACCESS_SMBQUICKACC 0x06
+#define AML_FIELDFLAGS_ACCESSTYPE(flags) (flags & 0x0f)
+/* bit 4: LockRule */
+#define AML_FIELDFLAGS_LOCK_NOLOCK 0x00
+#define AML_FIELDFLAGS_LOCK_LOCK 0x10
+#define AML_FIELDFLAGS_LOCKRULE(flags) (flags & 0x10)
+/* bit 5 - 6: UpdateRule */
+#define AML_FIELDFLAGS_UPDATE_PRESERVE 0x00
+#define AML_FIELDFLAGS_UPDATE_WRITEASONES 0x20
+#define AML_FIELDFLAGS_UPDATE_WRITEASZEROS 0x40
+#define AML_FIELDFLAGS_UPDATERULE(flags) (flags & 0x60)
+/* bit 7: reserved (must be 0) */
+
+#define AML_REGION_INPUT 0
+#define AML_REGION_OUTPUT 1
+
+#define AML_REGION_SYSMEM 0
+#define AML_REGION_SYSIO 1
+#define AML_REGION_PCICFG 2
+#define AML_REGION_EMBCTL 3
+#define AML_REGION_SMBUS 4
+
+struct aml_region_handle {
+ /* These are copies of values used on initialization */
+ struct aml_environ *env;
+ int regtype;
+ u_int32_t flags;
+ u_int32_t baseaddr;
+ u_int32_t bitoffset;
+ u_int32_t bitlen;
+
+ /* following is determined on initialization */
+ vm_offset_t addr, bytelen;
+ u_int32_t unit; /* access unit in bytes */
+
+ /* region type dependant */
+ vm_offset_t vaddr; /* SystemMemory */
+ u_int32_t pci_bus, pci_devfunc; /* PCI_Config */
+};
+
+u_int32_t aml_adjust_readvalue(u_int32_t, u_int32_t, u_int32_t,
+ u_int32_t);
+u_int32_t aml_adjust_updatevalue(u_int32_t, u_int32_t, u_int32_t,
+ u_int32_t, u_int32_t);
+
+u_int32_t aml_bufferfield_read(u_int8_t *, u_int32_t, u_int32_t);
+int aml_bufferfield_write(u_int32_t, u_int8_t *,
+ u_int32_t, u_int32_t);
+
+int aml_region_handle_alloc(struct aml_environ *, int, u_int32_t,
+ u_int32_t, u_int32_t, u_int32_t,
+ struct aml_region_handle *);
+void aml_region_handle_free(struct aml_region_handle *);
+
+int aml_region_io(struct aml_environ *, int, int,
+ u_int32_t, u_int32_t *, u_int32_t,
+ u_int32_t, u_int32_t);
+extern int aml_region_read_simple(struct aml_region_handle *, vm_offset_t,
+ u_int32_t *);
+extern int aml_region_write_simple(struct aml_region_handle *, vm_offset_t,
+ u_int32_t);
+extern u_int32_t aml_region_prompt_read(struct aml_region_handle *,
+ u_int32_t);
+extern u_int32_t aml_region_prompt_write(struct aml_region_handle *,
+ u_int32_t);
+extern int aml_region_prompt_update_value(u_int32_t, u_int32_t,
+ struct aml_region_handle *);
+#endif /* !_AML_COMMON_H_ */
diff --git a/usr.sbin/acpidump/aml/aml_env.h b/usr.sbin/acpidump/aml/aml_env.h
new file mode 100644
index 00000000000..fe85f362458
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_env.h
@@ -0,0 +1,47 @@
+/* $OpenBSD: aml_env.h,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999 Takanori Watanabe
+ * 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_env.h,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_env.h,v 1.2 2000/11/09 06:24:45 iwasaki Exp $
+ */
+
+#ifndef _AML_ENV_H_
+#define _AML_ENV_H_
+
+#include <aml/aml_name.h>
+#include <aml/aml_obj.h>
+#include <aml/aml_status.h>
+
+struct aml_environ {
+ u_int8_t *dp;
+ u_int8_t *end;
+ enum aml_status stat;
+ struct aml_name *curname;
+ struct aml_name tempname;
+ union aml_object tempobject;
+};
+
+#endif /* !_AML_ENV_H_ */
diff --git a/usr.sbin/acpidump/aml/aml_evalobj.c b/usr.sbin/acpidump/aml/aml_evalobj.c
new file mode 100644
index 00000000000..48109bd88c5
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_evalobj.c
@@ -0,0 +1,436 @@
+/* $OpenBSD: aml_evalobj.c,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999 Takanori Watanabe
+ * Copyright (c) 1999, 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_evalobj.c,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_evalobj.c,v 1.4 2000/11/09 06:24:45 iwasaki Exp $
+ */
+
+#include <sys/types.h>
+
+#include <aml/aml_amlmem.h>
+#include <aml/aml_common.h>
+#include <aml/aml_env.h>
+#include <aml/aml_evalobj.h>
+#include <aml/aml_name.h>
+#include <aml/aml_obj.h>
+#include <aml/aml_parse.h>
+#include <aml/aml_region.h>
+#include <aml/aml_status.h>
+#include <aml/aml_store.h>
+
+#ifndef _KERNEL
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <assert.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "debug.h"
+#else /* _KERNEL */
+#include <sys/systm.h>
+#endif /* !_KERNEL */
+
+static union aml_object *aml_eval_fieldobject(struct aml_environ *env,
+ struct aml_name *name);
+
+static union aml_object *
+aml_eval_fieldobject(struct aml_environ *env, struct aml_name *name)
+{
+ int num;
+ struct aml_name *oname,*wname;
+ struct aml_field *field;
+ struct aml_opregion *or;
+ union aml_object tobj;
+
+ num = 0;
+ /* CANNOT OCCUR! */
+ if (name == NULL || name->property == NULL ||
+ name->property->type != aml_t_field) {
+ printf("????\n");
+ env->stat = aml_stat_panic;
+ return (NULL);
+ }
+ field = &name->property->field;
+ oname = env->curname;
+ if (field->bitlen > 32) {
+ env->tempobject.type = aml_t_regfield;
+ } else {
+ env->tempobject.type = aml_t_num;
+ }
+ env->curname = name;
+ if (field->f.ftype == f_t_field) {
+ wname = aml_search_name(env, field->f.fld.regname);
+ if (wname == NULL || wname->property == NULL ||
+ wname->property->type != aml_t_opregion) {
+ AML_DEBUGPRINT("Inappropreate Type\n");
+ env->stat = aml_stat_panic;
+ env->curname = oname;
+ return (NULL);
+ }
+ or = &wname->property->opregion;
+ if (env->tempobject.type == aml_t_regfield) {
+ env->tempobject.regfield.space = or->space;
+ env->tempobject.regfield.flags = field->flags;
+ env->tempobject.regfield.offset = or->offset;
+ env->tempobject.regfield.bitoffset = field->bitoffset;
+ env->tempobject.regfield.bitlen = field->bitlen;
+ } else {
+ env->tempobject.type = aml_t_num;
+ env->tempobject.num.number = aml_region_read(env,
+ or->space, field->flags, or->offset,
+ field->bitoffset, field->bitlen);
+ AML_DEBUGPRINT("[read(%d, 0x%x)->0x%x]",
+ or->space, or->offset + field->bitoffset / 8,
+ env->tempobject.num.number);
+ }
+ } else if (field->f.ftype == f_t_index) {
+ wname = aml_search_name(env, field->f.ifld.indexname);
+ tobj.type = aml_t_num;
+ tobj.num.number = field->bitoffset / 8;/* AccessType Boundary */
+ aml_store_to_name(env, &tobj, wname);
+ wname = aml_search_name(env, field->f.ifld.dataname);
+ num = aml_objtonum(env, aml_eval_name(env, wname));
+ env->tempobject.type = aml_t_num;
+ env->tempobject.num.number = (num >> (field->bitoffset & 7)) &
+ ((1 << field->bitlen) - 1);
+ }
+ env->curname = oname;
+ return (&env->tempobject);
+}
+
+union aml_object *
+aml_eval_objref(struct aml_environ *env, union aml_object *obj)
+{
+ int offset;
+ union aml_object num1;
+ union aml_object *ref, *ret;
+
+ ret = obj;
+ if (obj->objref.deref == 1) {
+ num1.type = aml_t_num;
+ offset = obj->objref.offset;
+ ref = obj->objref.ref;
+ if (ref == NULL) {
+ goto out;
+ }
+ switch (ref->type) {
+ case aml_t_package:
+ if (ref->package.elements > offset) {
+ ret = ref->package.objects[offset];
+ } else {
+ num1.num.number = 0;
+ env->tempobject = num1;
+ ret = &env->tempobject;
+ }
+ break;
+ case aml_t_buffer:
+ if (ref->buffer.size > offset) {
+ num1.num.number = ref->buffer.data[offset] & 0xff;
+ } else {
+ num1.num.number = 0;
+ }
+ env->tempobject = num1;
+ ret = &env->tempobject;
+ break;
+ default:
+ break;
+ }
+ }
+ if (obj->objref.alias == 1) {
+ ret = aml_eval_name(env, obj->objref.nameref);
+ goto out;
+ }
+out:
+ return (ret);
+}
+
+/*
+ * Eval named object.
+ */
+union aml_object *
+aml_eval_name(struct aml_environ *env, struct aml_name *aname)
+{
+ int argnum, i;
+ int num;
+ struct aml_name *tmp;
+ struct aml_environ *copy;
+ struct aml_local_stack *stack;
+ union aml_object *obj, *ret;
+ union aml_object *src;
+
+ ret = NULL;
+ if (aname == NULL || aname->property == NULL) {
+ return (NULL);
+ }
+ if (env->stat == aml_stat_panic) {
+ return (NULL);
+ }
+ copy = memman_alloc(aml_memman, memid_aml_environ);
+ if (copy == NULL) {
+ return (NULL);
+ }
+ ret = aname->property;
+ i = 0;
+reevaluate:
+ if (i > 10) {
+ env->stat = aml_stat_panic;
+ printf("TOO MANY LOOP\n");
+ ret = NULL;
+ goto out;
+ }
+ switch (aname->property->type) {
+ case aml_t_namestr:
+ tmp = aname;
+ aname = aml_search_name(env, aname->property->nstr.dp);
+ if (aname == NULL) {
+ aname = tmp;
+ }
+ i++;
+ goto reevaluate;
+ case aml_t_objref:
+ ret = aml_eval_objref(env, aname->property);
+ goto out;
+ case aml_t_num:
+ case aml_t_string:
+ case aml_t_buffer:
+ case aml_t_package:
+ case aml_t_debug:
+ ret = aname->property;
+ goto out;
+ case aml_t_field:
+ aml_free_objectcontent(&env->tempobject);
+ ret = aml_eval_fieldobject(env, aname);
+ goto out;
+ case aml_t_method:
+ aml_free_objectcontent(&env->tempobject);
+ argnum = aname->property->meth.argnum & 7;
+ *copy = *env;
+ copy->curname = aname;
+ copy->dp = aname->property->meth.from;
+ copy->end = aname->property->meth.to;
+ copy->stat = aml_stat_none;
+ stack = aml_local_stack_create();
+ AML_DEBUGPRINT("(");
+ for (i = 0; i < argnum; i++) {
+ aml_local_stack_getArgX(stack, i)->property =
+ aml_copy_object(env,
+ aml_eval_name(env,
+ aml_parse_termobj(env, 0)));
+ if (i < argnum - 1)
+ AML_DEBUGPRINT(", ");
+ }
+ AML_DEBUGPRINT(")\n");
+ aml_local_stack_push(stack);
+ if (env->stat == aml_stat_step) {
+ AML_DEBUGGER(env, copy);
+ }
+ tmp = aml_execute_method(copy);
+ obj = aml_eval_name(env, tmp);
+ if (copy->stat == aml_stat_panic) {
+ AML_DEBUGPRINT("PANIC OCCURED IN METHOD");
+ env->stat = aml_stat_panic;
+ ret = NULL;
+ aml_local_stack_delete(aml_local_stack_pop());
+ goto out;
+ }
+ if (aml_debug) {
+ aml_showobject(obj);
+ }
+
+ if (tmp)
+ tmp->property = NULL;
+ aml_local_stack_delete(aml_local_stack_pop());
+ if (obj) {
+ aml_create_local_object()->property = obj;
+ ret = obj;
+ } else {
+ env->tempobject.type = aml_t_num;
+ env->tempobject.num.number = 0;
+ }
+
+ goto out;
+ case aml_t_bufferfield:
+ aml_free_objectcontent(&env->tempobject);
+ if (aname->property->bfld.bitlen > 32) {
+ ret = aname->property;
+ } else {
+ src = aname->property;
+ num = aml_bufferfield_read(src->bfld.origin,
+ src->bfld.bitoffset, src->bfld.bitlen);
+ env->tempobject.type = aml_t_num;
+ env->tempobject.num.number = num;
+ ret = &env->tempobject;
+ }
+ goto out;
+ default:
+ AML_DEBUGPRINT("I eval the object that I should not eval, %s%d",
+ aname->name, aname->property->type);
+ AML_SYSABORT();
+ ret = NULL;
+ goto out;
+ }
+out:
+ memman_free(aml_memman, memid_aml_environ, copy);
+ return (ret);
+}
+
+/*
+ * Eval named object but env variable is not required and return
+ * status of evaluation (success is zero). This function is assumed
+ * to be called by aml_apply_foreach_found_objects().
+ * Note that no arguments are passed if object is a method.
+ */
+
+int
+aml_eval_name_simple(struct aml_name *name, va_list ap)
+{
+ struct aml_environ *env;
+ union aml_object *ret;
+
+ if (name == NULL || name->property == NULL) {
+ return (1);
+ }
+
+ env = memman_alloc(aml_memman, memid_aml_environ);
+ if (env == NULL) {
+ return (1);
+ }
+ bzero(env, sizeof(struct aml_environ));
+
+ aml_local_stack_push(aml_local_stack_create());
+
+ AML_DEBUGPRINT("Evaluating ");
+ aml_print_curname(name);
+ ret = aml_eval_name(env, name);
+ if (name->property->type != aml_t_method) {
+ AML_DEBUGPRINT("\n");
+ if (aml_debug) {
+ aml_showobject(ret);
+ }
+ }
+
+ aml_local_stack_delete(aml_local_stack_pop());
+
+ memman_free(aml_memman, memid_aml_environ, env);
+ return (0);
+}
+
+int
+aml_objtonum(struct aml_environ *env, union aml_object *obj)
+{
+
+ if (obj != NULL && obj->type == aml_t_num) {
+ return (obj->num.number);
+ } else {
+ env->stat = aml_stat_panic;
+ return (-1);
+ }
+}
+
+struct aml_name *
+aml_execute_method(struct aml_environ *env)
+{
+ struct aml_name *name;
+ struct aml_name_group *newgrp;
+
+ newgrp = aml_new_name_group(AML_NAME_GROUP_IN_METHOD);
+
+ AML_DEBUGPRINT("[");
+ aml_print_curname(env->curname);
+ AML_DEBUGPRINT(" START]\n");
+
+ name = aml_parse_objectlist(env, 0);
+ AML_DEBUGPRINT("[");
+ aml_print_curname(env->curname);
+ AML_DEBUGPRINT(" END]\n");
+
+ aml_delete_name_group(newgrp);
+ return (name);
+}
+
+union aml_object *
+aml_invoke_method(struct aml_name *name, int argc, union aml_object *argv)
+{
+ int i;
+ struct aml_name *tmp;
+ struct aml_environ *env;
+ struct aml_local_stack *stack;
+ union aml_object *retval;
+ union aml_object *obj;
+
+ retval = NULL;
+ env = memman_alloc(aml_memman, memid_aml_environ);
+ if (env == NULL) {
+ return (NULL);
+ }
+ bzero(env, sizeof(struct aml_environ));
+
+ if (name != NULL && name->property != NULL &&
+ name->property->type == aml_t_method) {
+ env->curname = name;
+ env->dp = name->property->meth.from;
+ env->end = name->property->meth.to;
+ AML_DEBUGGER(env, env);
+ stack = aml_local_stack_create();
+ for (i = 0; i < argc; i++) {
+ aml_local_stack_getArgX(stack, i)->property =
+ aml_alloc_object(argv[i].type, &argv[i]);
+ }
+ aml_local_stack_push(stack);
+ obj = aml_eval_name(env, tmp = aml_execute_method(env));
+ if (aml_debug) {
+ aml_showtree(name, 0);
+ }
+
+ if (tmp)
+ tmp->property = NULL;
+ aml_local_stack_delete(aml_local_stack_pop());
+ if (obj) {
+ aml_create_local_object()->property = obj;
+ retval = obj;
+ }
+ }
+ memman_free(aml_memman, memid_aml_environ, env);
+ return (retval);
+}
+
+union aml_object *
+aml_invoke_method_by_name(char *method, int argc, union aml_object *argv)
+{
+ struct aml_name *name;
+
+ name = aml_find_from_namespace(aml_get_rootname(), method);
+ if (name == NULL) {
+ return (NULL);
+ }
+
+ return (aml_invoke_method(name, argc, argv));
+}
diff --git a/usr.sbin/acpidump/aml/aml_evalobj.h b/usr.sbin/acpidump/aml/aml_evalobj.h
new file mode 100644
index 00000000000..e951abbe2b5
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_evalobj.h
@@ -0,0 +1,49 @@
+/* $OpenBSD: aml_evalobj.h,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999 Takanori Watanabe
+ * 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_evalobj.h,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_evalobj.h,v 1.2 2000/09/20 22:53:39 iwasaki Exp $
+ */
+
+#ifndef _AML_EVALOBJ_H_
+#define _AML_EVALOBJ_H_
+
+#include <stdarg.h>
+
+union aml_object *aml_eval_objref(struct aml_environ *,
+ union aml_object *);
+union aml_object *aml_eval_name(struct aml_environ *,
+ struct aml_name *);
+int aml_eval_name_simple(struct aml_name *, va_list);
+int aml_objtonum(struct aml_environ *,
+ union aml_object *);
+struct aml_name *aml_execute_method(struct aml_environ *);
+union aml_object *aml_invoke_method(struct aml_name *,
+ int, union aml_object *);
+union aml_object *aml_invoke_method_by_name(char *,
+ int, union aml_object *);
+
+#endif /* !_AML_EVALOBJ_H_ */
diff --git a/usr.sbin/acpidump/aml/aml_memman.c b/usr.sbin/acpidump/aml/aml_memman.c
new file mode 100644
index 00000000000..942251be2da
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_memman.c
@@ -0,0 +1,477 @@
+/* $OpenBSD: aml_memman.c,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999, 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_memman.c,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_memman.c,v 1.2 2000/11/09 06:24:45 iwasaki Exp $
+ */
+
+/*
+ * Generic Memory Management
+ */
+#include <sys/types.h>
+#include <aml/aml_memman.h>
+#ifndef roundup
+#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */
+#endif
+#ifndef _KERNEL
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#else /* _KERNEL */
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+MALLOC_DEFINE(M_MEMMAN, "memman", "Generic and Simple Memory Management");
+#endif /* !_KERNEL */
+
+unsigned int memid_unkown = 255;
+
+static int manage_block(struct memman *memman, unsigned int id,
+ void *block, unsigned static_mem,
+ unsigned entries);
+static int blockman_init(struct memman *memman, unsigned int id);
+static void memman_flexsize_add_histogram(struct memman *memman,
+ size_t size,
+ int tolerance);
+static int memman_comp_histogram_size(const void *a,
+ const void *b);
+static void memman_sort_histogram_by_size(struct memman *memman);
+static unsigned int memman_guess_memid(struct memman *memman, void *chunk);
+static void memman_statistics_fixedsize(struct memman *memman);
+static void memman_statistics_flexsize(struct memman *memman);
+
+static int
+manage_block(struct memman *memman, unsigned int id, void *block,
+ unsigned static_mem, unsigned entries)
+{
+ unsigned int i;
+ size_t alloc_size;
+ void *tmp, *realblock;
+ struct memman_blockman *bmp;
+ struct memman_block *memblock;
+ struct memman_node *memnodes;
+
+ bmp = &memman->blockman[id];
+ alloc_size = MEMMAN_BLOCKNODE_SIZE(entries);
+
+ if (static_mem) {
+ tmp = (void *)block;
+ realblock = (char *)block + alloc_size;
+ } else {
+ tmp = MEMMAN_SYSMALLOC(alloc_size);
+ if (!tmp) {
+ return (-1);
+ }
+ realblock = block;
+
+ memman->allocated_mem += alloc_size;
+ memman->salloc_called++;
+ }
+
+ memblock = (struct memman_block *)tmp;
+ memnodes = (struct memman_node *)((char *)tmp + sizeof(struct memman_block));
+
+ memblock->block = realblock;
+ memblock->static_mem = static_mem;
+ memblock->allocated = entries;
+ memblock->available = entries;
+ if (!static_mem) {
+ alloc_size += roundup(bmp->size * entries, ROUNDUP_UNIT);
+ }
+ memblock->allocated_mem = alloc_size;
+ LIST_INSERT_HEAD(&bmp->block_list, memblock, links);
+
+ for (i = 0; i < entries; ++i) {
+ memnodes[i].node = ((char *)realblock + (i * (bmp->size)));
+ memnodes[i].memblock = memblock;
+ LIST_INSERT_HEAD(&bmp->free_node_list, &memnodes[i], links);
+ }
+ bmp->available = entries;
+
+ return (0);
+}
+
+static int
+blockman_init(struct memman *memman, unsigned int id)
+{
+ int status;
+ struct memman_blockman *bmp;
+
+ bmp = &memman->blockman[id];
+ bmp->initialized = 1;
+ LIST_INIT(&bmp->block_list);
+ LIST_INIT(&bmp->free_node_list);
+ LIST_INIT(&bmp->occupied_node_list);
+ status = manage_block(memman, id, bmp->initial_block,
+ 1, MEMMAN_INITIAL_SIZE);
+ return (status);
+}
+
+void *
+memman_alloc(struct memman *memman, unsigned int id)
+{
+ size_t alloc_size;
+ void *chunk, *block;
+ struct memman_blockman *bmp;
+ struct memman_node *memnode;
+
+ if (memman->max_memid <= id) {
+ printf("memman_alloc: invalid memory type id\n");
+ return (NULL);
+ }
+ bmp = &memman->blockman[id];
+ if (!bmp->initialized) {
+ if (blockman_init(memman, id)) {
+ goto malloc_fail;
+ }
+ }
+ memman->alloc_called++;
+
+ if (bmp->available == 0) {
+ alloc_size = roundup(bmp->size * MEMMAN_INCR_SIZE,
+ ROUNDUP_UNIT);
+ block = MEMMAN_SYSMALLOC(alloc_size);
+ if (!block) {
+ goto malloc_fail;
+ }
+ memman->required_mem += bmp->size * MEMMAN_INCR_SIZE;
+ memman->allocated_mem += alloc_size;
+ memman->salloc_called++;
+
+ if (manage_block(memman, id, block, 0, MEMMAN_INCR_SIZE)) {
+ goto malloc_fail;
+ }
+ }
+ memnode = LIST_FIRST(&bmp->free_node_list);
+ LIST_REMOVE(memnode, links);
+ chunk = memnode->node;
+ LIST_INSERT_HEAD(&bmp->occupied_node_list, memnode, links);
+ memnode->memblock->available--;
+ bmp->available--;
+
+ return (chunk);
+
+malloc_fail:
+ printf("memman_alloc: could not allocate memory\n");
+ return (NULL);
+}
+
+static void
+memman_flexsize_add_histogram(struct memman *memman, size_t size,
+ int tolerance)
+{
+ int i;
+ int gap;
+
+ if (size == 0) {
+ return;
+ }
+ for (i = 0; i < memman->flex_mem_histogram_ptr; i++) {
+ gap = memman->flex_mem_histogram[i].mem_size - size;
+ if (gap >= (tolerance * -1) && gap <= tolerance) {
+ memman->flex_mem_histogram[i].count++;
+ if (memman->flex_mem_histogram[i].mem_size < size) {
+ memman->flex_mem_histogram[i].mem_size = size;
+ }
+ return;
+ }
+ }
+
+ if (memman->flex_mem_histogram_ptr == MEMMAN_HISTOGRAM_SIZE) {
+ memman_flexsize_add_histogram(memman, size, tolerance + 1);
+ return;
+ }
+ i = memman->flex_mem_histogram_ptr;
+ memman->flex_mem_histogram[i].mem_size = size;
+ memman->flex_mem_histogram[i].count = 1;
+ memman->flex_mem_histogram_ptr++;
+}
+
+static int
+memman_comp_histogram_size(const void *a, const void *b)
+{
+ int delta;
+
+ delta = ((const struct memman_histogram *)a)->mem_size -
+ ((const struct memman_histogram *)b)->mem_size;
+ return (delta);
+}
+
+static void
+memman_sort_histogram_by_size(struct memman *memman)
+{
+ qsort(memman->flex_mem_histogram, memman->flex_mem_histogram_ptr,
+ sizeof(struct memman_histogram), memman_comp_histogram_size);
+}
+
+void *
+memman_alloc_flexsize(struct memman *memman, size_t size)
+{
+ void *mem;
+ struct memman_flexmem_info *info;
+
+ if (size == 0) {
+ return (NULL);
+ }
+ if ((mem = MEMMAN_SYSMALLOC(size)) != NULL) { /* XXX */
+
+ info = MEMMAN_SYSMALLOC(sizeof(struct memman_flexmem_info));
+ if (info) {
+ if (!memman->flex_mem_initialized) {
+ LIST_INIT(&memman->flexmem_info_list);
+ bzero(memman->flex_mem_histogram,
+ sizeof(struct memman_histogram));
+ memman->flex_mem_initialized = 1;
+ }
+ info->addr = mem;
+ info->mem_size = size;
+ LIST_INSERT_HEAD(&memman->flexmem_info_list, info, links);
+ }
+ memman->flex_alloc_called++;
+ memman->flex_salloc_called++;
+ memman->flex_required_mem += size;
+ memman->flex_allocated_mem += size;
+ if (memman->flex_mem_size_min == 0 ||
+ memman->flex_mem_size_min > size) {
+ memman->flex_mem_size_min = size;
+ }
+ if (memman->flex_mem_size_max < size) {
+ memman->flex_mem_size_max = size;
+ }
+ if (memman->flex_peak_mem_usage <
+ (memman->flex_allocated_mem - memman->flex_reclaimed_mem)) {
+ memman->flex_peak_mem_usage =
+ (memman->flex_allocated_mem - memman->flex_reclaimed_mem);
+ }
+ memman_flexsize_add_histogram(memman, size,
+ memman->flex_mem_histogram_initial_tolerance);
+ }
+ return (mem);
+}
+
+static unsigned int
+memman_guess_memid(struct memman *memman, void *chunk)
+{
+ unsigned int id;
+ struct memman_blockman *bmp;
+ struct memman_node *memnode;
+
+ for (id = 0; id < memman->max_memid; id++) {
+ bmp = &memman->blockman[id];
+ if (!bmp->initialized) {
+ if (blockman_init(memman, id)) {
+ printf("memman_free: could not initialized\n");
+ }
+ }
+ LIST_FOREACH(memnode, &bmp->occupied_node_list, links) {
+ if (memnode->node == chunk) {
+ return (id); /* got it! */
+ }
+ }
+ }
+ return (memid_unkown); /* gave up */
+}
+
+void
+memman_free(struct memman *memman, unsigned int memid, void *chunk)
+{
+ unsigned int id;
+ unsigned found;
+ void *block;
+ struct memman_blockman *bmp;
+ struct memman_block *memblock;
+ struct memman_node *memnode;
+
+ id = memid;
+ if (memid == memid_unkown) {
+ id = memman_guess_memid(memman, chunk);
+ }
+ if (memman->max_memid <= id) {
+ printf("memman_free: invalid memory type id\n");
+ MEMMAN_SYSABORT();
+ return;
+ }
+ bmp = &memman->blockman[id];
+ if (!bmp->initialized) {
+ if (blockman_init(memman, id)) {
+ printf("memman_free: could not initialized\n");
+ }
+ }
+ found = 0;
+ LIST_FOREACH(memnode, &bmp->occupied_node_list, links) {
+ if (memnode->node == chunk) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ printf("memman_free: invalid address\n");
+ return;
+ }
+ memman->free_called++;
+
+ LIST_REMOVE(memnode, links);
+ memblock = memnode->memblock;
+ memblock->available++;
+ LIST_INSERT_HEAD(&bmp->free_node_list, memnode, links);
+ bmp->available++;
+
+ if (!memblock->static_mem &&
+ memblock->available == memblock->allocated) {
+ LIST_FOREACH(memnode, &bmp->free_node_list, links) {
+ if (memnode->memblock != memblock) {
+ continue;
+ }
+ LIST_REMOVE(memnode, links);
+ bmp->available--;
+ }
+ block = memblock->block;
+ MEMMAN_SYSFREE(block);
+ memman->sfree_called++;
+
+ LIST_REMOVE(memblock, links);
+ memman->sfree_called++;
+ memman->reclaimed_mem += memblock->allocated_mem;
+ MEMMAN_SYSFREE(memblock);
+ }
+}
+
+void
+memman_free_flexsize(struct memman *memman, void *chunk)
+{
+ struct memman_flexmem_info *info;
+
+ LIST_FOREACH(info, &memman->flexmem_info_list, links) {
+ if (info->addr == chunk) {
+ memman->flex_reclaimed_mem += info->mem_size;
+ LIST_REMOVE(info, links);
+ MEMMAN_SYSFREE(info);
+ break;
+ }
+ }
+ /* XXX */
+ memman->flex_free_called++;
+ memman->flex_sfree_called++;
+ MEMMAN_SYSFREE(chunk);
+}
+
+void
+memman_freeall(struct memman *memman)
+{
+ int id;
+ void *chunk;
+ struct memman_blockman *bmp;
+ struct memman_node *memnode;
+ struct memman_block *memblock;
+ struct memman_flexmem_info *info;
+
+ for (id = 0; id < memman->max_memid; id++) {
+ bmp = &memman->blockman[id];
+
+ while ((memnode = LIST_FIRST(&bmp->occupied_node_list))) {
+ chunk = memnode->node;
+ printf("memman_freeall: fixed size (id = %d)\n", id);
+ memman_free(memman, id, chunk);
+ }
+ while ((memblock = LIST_FIRST(&bmp->block_list))) {
+ LIST_REMOVE(memblock, links);
+ if (!memblock->static_mem) {
+ memman->sfree_called++;
+ memman->reclaimed_mem += memblock->allocated_mem;
+ MEMMAN_SYSFREE(memblock);
+ }
+ }
+ bmp->initialized = 0;
+ }
+
+ LIST_FOREACH(info, &memman->flexmem_info_list, links) {
+ printf("memman_freeall: flex size (size = %d, addr = %p)\n",
+ info->mem_size, info->addr);
+ memman_free_flexsize(memman, info->addr);
+ }
+}
+
+static void
+memman_statistics_fixedsize(struct memman *memman)
+{
+ printf(" fixed size memory blocks\n");
+ printf(" alloc(): %d times\n", memman->alloc_called);
+ printf(" system malloc(): %d times\n", memman->salloc_called);
+ printf(" free(): %d times\n", memman->free_called);
+ printf(" system free(): %d times\n", memman->sfree_called);
+ printf(" required memory: %d bytes\n", memman->required_mem);
+ printf(" allocated memory: %d bytes\n", memman->allocated_mem);
+ printf(" reclaimed memory: %d bytes\n", memman->reclaimed_mem);
+}
+
+static void
+memman_statistics_flexsize(struct memman *memman)
+{
+ int i;
+
+ printf(" flexible size memory blocks\n");
+ printf(" alloc(): %d times\n", memman->flex_alloc_called);
+ printf(" system malloc(): %d times\n", memman->flex_salloc_called);
+ printf(" free(): %d times\n", memman->flex_free_called);
+ printf(" system free(): %d times\n", memman->flex_sfree_called);
+ printf(" required memory: %d bytes\n", memman->flex_required_mem);
+ printf(" allocated memory: %d bytes\n", memman->flex_allocated_mem);
+ printf(" reclaimed memory: %d bytes\n", memman->flex_reclaimed_mem);
+ printf(" peak memory usage: %d bytes\n", memman->flex_peak_mem_usage);
+ printf(" min memory size: %d bytes\n", memman->flex_mem_size_min);
+ printf(" max memory size: %d bytes\n", memman->flex_mem_size_max);
+ printf(" avg memory size: %d bytes\n",
+ (memman->flex_alloc_called) ?
+ memman->flex_allocated_mem / memman->flex_alloc_called : 0);
+
+ printf(" memory size histogram (%d entries):\n",
+ memman->flex_mem_histogram_ptr);
+ printf(" size count\n");
+ memman_sort_histogram_by_size(memman);
+ for (i = 0; i < memman->flex_mem_histogram_ptr; i++) {
+ printf(" %d %d\n",
+ memman->flex_mem_histogram[i].mem_size,
+ memman->flex_mem_histogram[i].count);
+ }
+}
+
+void
+memman_statistics(struct memman *memman)
+{
+ printf("memman: reporting statistics\n");
+ memman_statistics_fixedsize(memman);
+ memman_statistics_flexsize(memman);
+}
+
+size_t
+memman_memid2size(struct memman *memman, unsigned int id)
+{
+ if (memman->max_memid <= id) {
+ printf("memman_alloc: invalid memory type id\n");
+ return (0);
+ }
+ return (memman->blockman[id].size);
+}
diff --git a/usr.sbin/acpidump/aml/aml_memman.h b/usr.sbin/acpidump/aml/aml_memman.h
new file mode 100644
index 00000000000..fce68328e72
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_memman.h
@@ -0,0 +1,172 @@
+/* $OpenBSD: aml_memman.h,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999, 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_memman.h,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_memman.h,v 1.1 2000/08/24 09:33:08 takawata Exp $
+ */
+
+#ifndef _MEMMAN_H_
+#define _MEMMAN_H_
+
+/*
+ * Generic Memory Management
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+
+/* memory block */
+struct memman_block {
+ LIST_ENTRY(memman_block) links;
+ void *block;
+ unsigned static_mem; /* static memory or not */
+ unsigned int allocated; /* number of allocated chunks */
+ unsigned int available; /* number of available chunks */
+ unsigned int allocated_mem; /* block + misc (in bytes) */
+
+}__attribute__((packed));
+
+LIST_HEAD(memman_block_list, memman_block);
+
+/* memory node in block */
+struct memman_node {
+ LIST_ENTRY(memman_node) links;
+ void *node;
+ struct memman_block *memblock;
+}__attribute__((packed));
+
+LIST_HEAD(memman_node_list, memman_node);
+
+/* memory type id */
+extern unsigned int memid_unkown;
+
+/* memory block manager */
+struct memman_blockman {
+ unsigned int size; /* size of chunk */
+ unsigned int available; /* total # of available chunks */
+ void *initial_block; /* initial memory storage */
+ unsigned initialized; /* initialized or not */
+
+ struct memman_block_list block_list;
+ struct memman_node_list free_node_list;
+ struct memman_node_list occupied_node_list;
+};
+
+/* memory size histogram */
+#define MEMMAN_HISTOGRAM_SIZE 20
+struct memman_histogram {
+ int mem_size;
+ int count;
+};
+
+/* flex size memory allocation info */
+struct memman_flexmem_info {
+ LIST_ENTRY(memman_flexmem_info) links;
+ void *addr;
+ size_t mem_size;
+}__attribute__((packed));
+
+LIST_HEAD(memman_flexmem_info_list, memman_flexmem_info);
+
+/* memory manager */
+struct memman {
+ struct memman_blockman *blockman;
+ unsigned int max_memid; /* max number of valid memid */
+
+ /* fixed size memory blocks */
+ unsigned int alloc_called; /* memman_alloc() calling */
+ unsigned int free_called; /* memman_free() calling */
+ unsigned int salloc_called; /* malloc() calling */
+ unsigned int sfree_called; /* free() calling */
+ size_t required_mem; /* total required memory (in bytes) */
+ size_t allocated_mem; /* total malloc()ed memory */
+ size_t reclaimed_mem; /* total free()ed memory */
+ /* flex size memory blocks */
+ unsigned int flex_alloc_called; /* memman_alloc_flexsize() calling */
+ unsigned int flex_free_called; /* memman_free_flexsize() calling */
+ unsigned int flex_salloc_called;/* malloc() calling */
+ unsigned int flex_sfree_called; /* free() calling */
+ size_t flex_required_mem; /* total required memory (in bytes) */
+ size_t flex_allocated_mem;/* total malloc()ed memory */
+ size_t flex_reclaimed_mem;/* total free()ed memory */
+ size_t flex_mem_size_min; /* min size of allocated memory */
+ size_t flex_mem_size_max; /* max size of allocated memory */
+ size_t flex_peak_mem_usage;/* memory usage at a peak period */
+
+ /* stuff for more detailed statistical information */
+ struct memman_histogram *flex_mem_histogram;
+ unsigned int flex_mem_histogram_ptr;
+ int flex_mem_histogram_initial_tolerance;
+ unsigned flex_mem_initialized;
+ struct memman_flexmem_info_list flexmem_info_list;
+};
+
+#define MEMMAN_BLOCKNODE_SIZE(entries) sizeof(struct memman_block) + \
+ sizeof(struct memman_node) * entries
+
+#ifndef ROUNDUP_UNIT
+#define ROUNDUP_UNIT 4
+#endif
+
+#if !defined(MEMMAN_INITIAL_SIZE) || MEMMAN_INITIAL_SIZE < 2048
+#define MEMMAN_INITIAL_SIZE 2048
+#endif
+
+#if !defined(MEMMAN_INCR_SIZE) || MEMMAN_INCR_SIZE < 512
+#define MEMMAN_INCR_SIZE 512
+#endif
+
+#define MEMMAN_INITIALSTORAGE_DESC(type, name) \
+static struct { \
+ char blocknodes[MEMMAN_BLOCKNODE_SIZE(MEMMAN_INITIAL_SIZE)]; \
+ type realblock[MEMMAN_INITIAL_SIZE]; \
+} name
+
+#define MEMMAN_MEMBLOCK_DESC(size, initial_storage) \
+ { size, MEMMAN_INITIAL_SIZE, &initial_storage, 0 }
+
+#define MEMMAN_MEMMANAGER_DESC(blockman, max_memid, histogram, tolerance) \
+ { blockman, max_memid, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, histogram, 0, tolerance, 0}
+
+void *memman_alloc(struct memman *, unsigned int);
+void *memman_alloc_flexsize(struct memman *, size_t);
+void memman_free(struct memman *, unsigned int, void *);
+void memman_free_flexsize(struct memman *, void *);
+void memman_freeall(struct memman *);
+void memman_statistics(struct memman *);
+size_t memman_memid2size(struct memman *, unsigned int);
+
+#ifdef _KERNEL
+#define MEMMAN_SYSMALLOC(size) malloc(size, M_MEMMAN, M_WAITOK)
+#define MEMMAN_SYSFREE(ptr) free(ptr, M_MEMMAN)
+#define MEMMAN_SYSABORT() /* no abort in kernel */
+#else /* !_KERNEL */
+#define MEMMAN_SYSMALLOC(size) malloc(size)
+#define MEMMAN_SYSFREE(ptr) free(ptr)
+#define MEMMAN_SYSABORT() abort()
+#endif /* _KERNEL */
+#endif /* !_MEMMAN_H_ */
diff --git a/usr.sbin/acpidump/aml/aml_name.c b/usr.sbin/acpidump/aml/aml_name.c
new file mode 100644
index 00000000000..b41698d7e2c
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_name.c
@@ -0,0 +1,481 @@
+/* $OpenBSD: aml_name.c,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999 Takanori Watanabe
+ * Copyright (c) 1999, 2000 Yasuo Yokoyama
+ * Copyright (c) 1999, 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_name.c,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_name.c,v 1.3 2000/11/09 06:24:45 iwasaki Exp $
+ */
+#include <sys/types.h>
+
+#include <aml/aml_amlmem.h>
+#include <aml/aml_common.h>
+#include <aml/aml_env.h>
+#include <aml/aml_name.h>
+
+#ifndef _KERNEL
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "debug.h"
+#else /* _KERNEL */
+#include <sys/systm.h>
+#endif /* !_KERNEL */
+
+static struct aml_name *aml_find_name(struct aml_name *, char *);
+static struct aml_name *aml_new_name(struct aml_name *, char *);
+static void aml_delete_name(struct aml_name *);
+
+static struct aml_name rootname = {"\\", NULL, NULL, NULL, NULL, NULL};
+
+static struct aml_name_group root_group = {
+ AML_NAME_GROUP_ROOT,
+ &rootname,
+ NULL
+};
+
+struct aml_name_group *name_group_list = &root_group;
+struct aml_local_stack *stack_top = NULL;
+
+struct aml_name *
+aml_get_rootname()
+{
+
+ return (&rootname);
+}
+
+static struct aml_name *
+aml_find_name(struct aml_name *parent, char *name)
+{
+ struct aml_name *result;
+
+ if (!parent)
+ parent = &rootname;
+ for (result = parent->child; result; result = result->brother)
+ if (!strncmp(result->name, name, 4))
+ break;
+ return (result);
+}
+
+/*
+ * Parse given namesppace expression and find a first matched object
+ * under given level of the tree by depth first search.
+ */
+
+struct aml_name *
+aml_find_from_namespace(struct aml_name *parent, char *name)
+{
+ char *ptr;
+ int len;
+ struct aml_name *result;
+
+ ptr = name;
+ if (!parent)
+ parent = &rootname;
+
+ if (ptr[0] == '\\') {
+ ptr++;
+ parent = &rootname;
+ }
+ for (len = 0; ptr[len] != '.' && ptr[len] != '\0'; len++)
+ ;
+
+ for (result = parent->child; result; result = result->brother) {
+ if (!strncmp(result->name, ptr, len)) {
+ if (ptr[len] == '\0' || ptr[len + 1] == '\0') {
+ return (result);
+ }
+ ptr += len;
+ if (ptr[0] != '.') {
+ return (NULL);
+ }
+ ptr++;
+ return (aml_find_from_namespace(result, ptr));
+ }
+ }
+
+ return (NULL);
+}
+
+static void
+_aml_apply_foreach_found_objects(struct aml_name *parent, char *name,
+ int len, int shallow, int (*func)(struct aml_name *, va_list), va_list ap)
+{
+ struct aml_name *child, *ptr;
+
+ child = ptr = NULL;
+
+ /* function to apply must be specified */
+ if (func == NULL) {
+ return;
+ }
+
+ for (child = parent->child; child; child = child->brother) {
+ if (!strncmp(child->name, name, len)) {
+ /* if function call was failed, stop searching */
+ if (func(child, ap) != 0) {
+ return;
+ }
+ }
+ }
+
+ if (shallow == 1) {
+ return;
+ }
+
+ for (ptr = parent->child; ptr; ptr = ptr->brother) {
+ /* do more searching */
+ _aml_apply_foreach_found_objects(ptr, name, len, 0, func, ap);
+ }
+}
+
+/*
+ * Find named objects as many as possible under given level of
+ * namespace, and apply given callback function for each
+ * named objects found. If the callback function returns non-zero
+ * value, then the search terminates immediately.
+ * Note that object name expression is used as forward substring match,
+ * not exact match. The name expression "_L" will match for objects
+ * which have name starting with "_L" such as "\_SB_.LID_._LID" and
+ * "\_GPE._L00" and so on. The name expression can include parent object
+ * name in it like "\_GPE._L". In this case, GPE X level wake handlers
+ * will be found under "\_GPE" in shallow level.
+ */
+
+void
+aml_apply_foreach_found_objects(struct aml_name *start, char *name,
+ int (*func)(struct aml_name *, va_list), ...)
+{
+ int i, len, has_dot, last_is_dot, shallow;
+ struct aml_name *child, *parent;
+ va_list ap;
+
+ shallow = 0;
+ if (start == NULL) {
+ parent = &rootname;
+ } else {
+ parent = start;
+ }
+ if (name[0] == '\\') {
+ name++;
+ parent = &rootname;
+ shallow = 1;
+ }
+
+ len = strlen(name);
+ last_is_dot = 0;
+ /* the last dot should be ignored */
+ if (len > 0 && name[len - 1] == '.') {
+ len--;
+ last_is_dot = 1;
+ }
+
+ has_dot = 0;
+ for (i = 0; i < len - 1; i++) {
+ if (name[i] == '.') {
+ has_dot = 1;
+ break;
+ }
+ }
+
+ /* try to parse expression and find any matched object. */
+ if (has_dot == 1) {
+ child = aml_find_from_namespace(parent, name);
+ if (child == NULL) {
+ return;
+ }
+
+ /*
+ * we have at least one object matched, search all objects
+ * under upper level of the found object.
+ */
+ parent = child->parent;
+
+ /* find the last `.' */
+ for (name = name + len - 1; *name != '.'; name--)
+ ;
+ name++;
+ len = strlen(name) - last_is_dot;
+ shallow = 1;
+ }
+
+ if (len > 4) {
+ return;
+ }
+
+ va_start(ap, func);
+ _aml_apply_foreach_found_objects(parent, name, len, shallow, func, ap);
+ va_end(ap);
+}
+
+struct aml_name_group *
+aml_new_name_group(int id)
+{
+ struct aml_name_group *result;
+
+ result = memman_alloc(aml_memman, memid_aml_name_group);
+ result->id = id;
+ result->head = NULL;
+ result->next = name_group_list;
+ name_group_list = result;
+ return (result);
+}
+
+void
+aml_delete_name_group(struct aml_name_group *target)
+{
+ struct aml_name_group *previous;
+
+ previous = name_group_list;
+ if (previous == target)
+ name_group_list = target->next;
+ else {
+ while (previous && previous->next != target)
+ previous = previous->next;
+ if (previous)
+ previous->next = target->next;
+ }
+ target->next = NULL;
+ if (target->head)
+ aml_delete_name(target->head);
+ memman_free(aml_memman, memid_aml_name_group, target);
+}
+
+static struct aml_name *
+aml_new_name(struct aml_name *parent, char *name)
+{
+ struct aml_name *newname;
+
+ if ((newname = aml_find_name(parent, name)) != NULL)
+ return (newname);
+
+ newname = memman_alloc(aml_memman, memid_aml_name);
+ strncpy(newname->name, name, 4);
+ newname->parent = parent;
+ newname->child = NULL;
+ newname->property = NULL;
+ if (parent->child)
+ newname->brother = parent->child;
+ else
+ newname->brother = NULL;
+ parent->child = newname;
+
+ newname->chain = name_group_list->head;
+ name_group_list->head = newname;
+
+ return (newname);
+}
+
+/*
+ * NOTE:
+ * aml_delete_name() doesn't maintain aml_name_group::{head,tail}.
+ */
+static void
+aml_delete_name(struct aml_name *target)
+{
+ struct aml_name *next;
+ struct aml_name *ptr;
+
+ for (; target; target = next) {
+ next = target->chain;
+ if (target->child) {
+ target->chain = NULL;
+ continue;
+ }
+ if (target->brother) {
+ if (target->parent) {
+ if (target->parent->child == target) {
+ target->parent->child = target->brother;
+ } else {
+ ptr = target->parent->child;
+ while (ptr && ptr->brother != target)
+ ptr = ptr->brother;
+ if (ptr)
+ ptr->brother = target->brother;
+ }
+ target->brother = NULL;
+ }
+ } else if (target->parent) {
+ target->parent->child = NULL;
+ }
+ aml_free_object(&target->property);
+ memman_free(aml_memman, memid_aml_name, target);
+ }
+}
+
+#define AML_SEARCH_NAME 0
+#define AML_CREATE_NAME 1
+static struct aml_name *aml_nameman(struct aml_environ *, u_int8_t *, int);
+
+struct aml_name *
+aml_search_name(struct aml_environ *env, u_int8_t *dp)
+{
+
+ return (aml_nameman(env, dp, AML_SEARCH_NAME));
+}
+
+struct aml_name *
+aml_create_name(struct aml_environ *env, u_int8_t *dp)
+{
+
+ return (aml_nameman(env, dp, AML_CREATE_NAME));
+}
+
+static struct aml_name *
+aml_nameman(struct aml_environ *env, u_int8_t *dp, int flag)
+{
+ int segcount;
+ int i;
+ struct aml_name *newname, *curname;
+ struct aml_name *(*searchfunc) (struct aml_name *, char *);
+
+#define CREATECHECK() do { \
+ if (newname == NULL) { \
+ AML_DEBUGPRINT("ERROR CANNOT FIND NAME\n"); \
+ env->stat = aml_stat_panic; \
+ return (NULL); \
+ } \
+} while(0)
+
+ searchfunc = (flag == AML_CREATE_NAME) ? aml_new_name : aml_find_name;
+ newname = env->curname;
+ if (dp[0] == '\\') {
+ newname = &rootname;
+ dp++;
+ } else if (dp[0] == '^') {
+ while (dp[0] == '^') {
+ newname = newname->parent;
+ CREATECHECK();
+ dp++;
+ }
+ }
+ if (dp[0] == 0x00) { /* NullName */
+ dp++;
+ } else if (dp[0] == 0x2e) { /* DualNamePrefix */
+ newname = (*searchfunc) (newname, dp + 1);
+ CREATECHECK();
+ newname = (*searchfunc) (newname, dp + 5);
+ CREATECHECK();
+ } else if (dp[0] == 0x2f) { /* MultiNamePrefix */
+ segcount = dp[1];
+ for (i = 0, dp += 2; i < segcount; i++, dp += 4) {
+ newname = (*searchfunc) (newname, dp);
+ CREATECHECK();
+ }
+ } else if (flag == AML_CREATE_NAME) { /* NameSeg */
+ newname = aml_new_name(newname, dp);
+ CREATECHECK();
+ } else {
+ curname = newname;
+ for (;;) {
+ newname = aml_find_name(curname, dp);
+ if (newname != NULL)
+ break;
+ if (curname == &rootname)
+ break;
+ curname = curname->parent;
+ }
+ }
+ return (newname);
+}
+
+#undef CREATECHECK
+
+struct aml_local_stack *
+aml_local_stack_create()
+{
+ struct aml_local_stack *result;
+
+ result = memman_alloc(aml_memman, memid_aml_local_stack);
+ memset(result, 0, sizeof(struct aml_local_stack));
+ return (result);
+}
+
+void
+aml_local_stack_push(struct aml_local_stack *stack)
+{
+
+ stack->next = stack_top;
+ stack_top = stack;
+}
+
+struct aml_local_stack *
+aml_local_stack_pop()
+{
+ struct aml_local_stack *result;
+
+ result = stack_top;
+ stack_top = result->next;
+ result->next = NULL;
+ return (result);
+}
+
+void
+aml_local_stack_delete(struct aml_local_stack *stack)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ aml_free_object(&stack->localvalue[i].property);
+ for (i = 0; i < 7; i++)
+ aml_free_object(&stack->argumentvalue[i].property);
+ aml_delete_name(stack->temporary);
+ memman_free(aml_memman, memid_aml_local_stack, stack);
+}
+
+struct aml_name *
+aml_local_stack_getLocalX(int index)
+{
+
+ if (stack_top == NULL)
+ return (NULL);
+ return (&stack_top->localvalue[index]);
+}
+
+struct aml_name *
+aml_local_stack_getArgX(struct aml_local_stack *stack, int index)
+{
+
+ if (!stack)
+ stack = stack_top;
+ if (stack == NULL)
+ return (NULL);
+ return (&stack->argumentvalue[index]);
+}
+
+struct aml_name *
+aml_create_local_object()
+{
+ struct aml_name *result;
+
+ result = memman_alloc(aml_memman, memid_aml_name);
+ result->child = result->brother = result->parent = NULL;
+ result->property = NULL;
+ result->chain = stack_top->temporary;
+ stack_top->temporary = result;
+ return (result);
+}
diff --git a/usr.sbin/acpidump/aml/aml_name.h b/usr.sbin/acpidump/aml/aml_name.h
new file mode 100644
index 00000000000..87b89ba1c0e
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_name.h
@@ -0,0 +1,89 @@
+/* $OpenBSD: aml_name.h,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999 Takanori Watanabe
+ * Copyright (c) 1999, 2000 Yasuo Yokoyama
+ * Copyright (c) 1999, 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_name.h,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_name.h,v 1.2 2000/11/09 06:24:45 iwasaki Exp $
+ */
+
+#ifndef _AML_NAME_H_
+#define _AML_NAME_H_
+
+
+#include <aml/aml_obj.h>
+#include <stdarg.h>
+
+struct aml_name {
+ char name[4];
+ union aml_object *property;
+ struct aml_name *parent;
+ struct aml_name *brother;
+ struct aml_name *child;
+ struct aml_name *chain;
+};
+
+#define AML_NAME_GROUP_ROOT 0
+#define AML_NAME_GROUP_OS_DEFINED 1
+#define AML_NAME_GROUP_IN_METHOD 2
+
+struct aml_name_group {
+ int id; /* DSDT address or DBHANDLE */
+ struct aml_name *head;
+ struct aml_name_group *next;
+};
+
+struct aml_local_stack {
+ struct aml_name localvalue[8];
+ struct aml_name argumentvalue[7];
+ struct aml_name *temporary;
+ struct aml_local_stack *next;
+};
+
+/* forward declarement */
+struct aml_envrion;
+
+struct aml_name *aml_get_rootname(void);
+struct aml_name_group *aml_new_name_group(int);
+void aml_delete_name_group(struct aml_name_group *);
+
+struct aml_name *aml_find_from_namespace(struct aml_name *, char *);
+void aml_apply_foreach_found_objects(struct aml_name *,
+ char *, int (*)(struct aml_name *, va_list), ...);
+struct aml_name *aml_search_name(struct aml_environ *, u_int8_t *);
+struct aml_name *aml_create_name(struct aml_environ *, u_int8_t *);
+
+struct aml_local_stack *aml_local_stack_create(void);
+void aml_local_stack_push(struct aml_local_stack *);
+struct aml_local_stack *aml_local_stack_pop(void);
+void aml_local_stack_delete(struct aml_local_stack *);
+struct aml_name *aml_local_stack_getLocalX(int);
+struct aml_name *aml_local_stack_getArgX(struct aml_local_stack *, int);
+struct aml_name *aml_create_local_object(void);
+
+extern struct aml_name_group *name_group_list;
+
+#endif /* !_AML_NAME_H_ */
diff --git a/usr.sbin/acpidump/aml/aml_obj.c b/usr.sbin/acpidump/aml/aml_obj.c
new file mode 100644
index 00000000000..e1de8967d48
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_obj.c
@@ -0,0 +1,265 @@
+/* $OpenBSD: aml_obj.c,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999 Takanori Watanabe
+ * Copyright (c) 1999, 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_obj.c,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_obj.c,v 1.3 2000/11/09 06:24:45 iwasaki Exp $
+ */
+
+#include <sys/types.h>
+
+#include <aml/aml_amlmem.h>
+#include <aml/aml_env.h>
+#include <aml/aml_name.h>
+#include <aml/aml_obj.h>
+#include <aml/aml_status.h>
+#include <aml/aml_store.h>
+
+#ifndef _KERNEL
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <assert.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#else /* _KERNEL */
+#include <sys/systm.h>
+#endif /* !_KERNEL */
+
+union aml_object *
+aml_copy_object(struct aml_environ *env, union aml_object *orig)
+{
+ int i;
+ union aml_object *ret;
+
+ if (orig == NULL)
+ return (NULL);
+ switch (orig->type) {
+ case aml_t_regfield:
+ ret = aml_alloc_object(aml_t_buffer, 0);
+ ret->buffer.size = (orig->regfield.bitlen / 8) +
+ ((orig->regfield.bitlen % 8) ? 1 : 0);
+ if (ret->buffer.size == 0) {
+ goto out;
+ }
+ ret->buffer.data = memman_alloc_flexsize(aml_memman, ret->buffer.size);
+ aml_store_to_object(env, orig, ret);
+ break;
+
+ default:
+ ret = aml_alloc_object(0, orig);
+ break;
+ }
+
+ if (1 || orig != &env->tempobject) { /* XXX */
+ if (orig->type == aml_t_buffer) {
+ if (orig->buffer.size == 0) {
+ goto out;
+ }
+ ret->buffer.data = memman_alloc_flexsize(aml_memman,
+ orig->buffer.size);
+ bcopy(orig->buffer.data, ret->buffer.data, orig->buffer.size);
+ } else if (orig->type == aml_t_package) {
+ if (ret->package.elements == 0) {
+ goto out;
+ }
+ ret->package.objects = memman_alloc_flexsize(aml_memman,
+ ret->package.elements * sizeof(union aml_object *));
+ for (i = 0; i < ret->package.elements; i++) {
+ ret->package.objects[i] = aml_copy_object(env, orig->package.objects[i]);
+ }
+ } else if (orig->type == aml_t_string && orig->str.needfree != 0) {
+ ret->str.string = memman_alloc_flexsize(aml_memman,
+ strlen(orig->str.string) + 1);
+ strcpy(orig->str.string, ret->str.string);
+ } else if (orig->type == aml_t_num) {
+ ret->num.constant = 0;
+ }
+ } else {
+ printf("%s:%d\n", __FILE__, __LINE__);
+ env->tempobject.type = aml_t_null;
+ }
+out:
+ return ret;
+}
+
+/*
+ * This function have two function: copy or allocate. if orig != NULL,
+ * orig is duplicated.
+ */
+
+union aml_object *
+aml_alloc_object(enum aml_objtype type, union aml_object *orig)
+{
+ unsigned int memid;
+ union aml_object *ret;
+
+ if (orig != NULL) {
+ type = orig->type;
+ }
+ switch (type) {
+ case aml_t_namestr:
+ memid = memid_aml_namestr;
+ break;
+ case aml_t_buffer:
+ memid = memid_aml_buffer;
+ break;
+ case aml_t_string:
+ memid = memid_aml_string;
+ break;
+ case aml_t_bufferfield:
+ memid = memid_aml_bufferfield;
+ break;
+ case aml_t_package:
+ memid = memid_aml_package;
+ break;
+ case aml_t_num:
+ memid = memid_aml_num;
+ break;
+ case aml_t_powerres:
+ memid = memid_aml_powerres;
+ break;
+ case aml_t_opregion:
+ memid = memid_aml_opregion;
+ break;
+ case aml_t_method:
+ memid = memid_aml_method;
+ break;
+ case aml_t_processor:
+ memid = memid_aml_processor;
+ break;
+ case aml_t_field:
+ memid = memid_aml_field;
+ break;
+ case aml_t_mutex:
+ memid = memid_aml_mutex;
+ break;
+ case aml_t_device:
+ memid = memid_aml_objtype;
+ break;
+ case aml_t_objref:
+ memid = memid_aml_objref;
+ break;
+ default:
+ memid = memid_aml_objtype;
+ break;
+ }
+ ret = memman_alloc(aml_memman, memid);
+ ret->type = type;
+
+ if (orig != NULL) {
+ bcopy(orig, ret, memman_memid2size(aml_memman, memid));
+ }
+ return (ret);
+}
+
+void
+aml_free_objectcontent(union aml_object *obj)
+{
+ int i;
+
+ if (obj->type == aml_t_buffer && obj->buffer.data != NULL) {
+ memman_free_flexsize(aml_memman, obj->buffer.data);
+ obj->buffer.data = NULL;
+ }
+ if (obj->type == aml_t_string && obj->str.string != NULL) {
+ if (obj->str.needfree != 0) {
+ memman_free_flexsize(aml_memman, obj->str.string);
+ obj->str.string = NULL;
+ }
+ }
+ if (obj->type == aml_t_package && obj->package.objects != NULL) {
+ for (i = 0; i < obj->package.elements; i++) {
+ aml_free_object(&obj->package.objects[i]);
+ }
+ memman_free_flexsize(aml_memman, obj->package.objects);
+ obj->package.objects = NULL;
+ }
+}
+
+void
+aml_free_object(union aml_object **obj)
+{
+ union aml_object *body;
+
+ body = *obj;
+ if (body == NULL) {
+ return;
+ }
+ aml_free_objectcontent(*obj);
+ memman_free(aml_memman, memid_unkown, *obj);
+ *obj = NULL;
+}
+
+void
+aml_realloc_object(union aml_object *obj, int size)
+{
+ int i;
+ enum aml_objtype type;
+ union aml_object tmp;
+
+ type = obj->type;
+ switch (type) {
+ case aml_t_buffer:
+ if (obj->buffer.size >= size) {
+ return;
+ }
+ tmp.buffer.size = size;
+ tmp.buffer.data = memman_alloc_flexsize(aml_memman, size);
+ bzero(tmp.buffer.data, size);
+ bcopy(obj->buffer.data, tmp.buffer.data, obj->buffer.size);
+ aml_free_objectcontent(obj);
+ *obj = tmp;
+ break;
+ case aml_t_string:
+ if (strlen(obj->str.string) >= size) {
+ return;
+ }
+ tmp.str.string = memman_alloc_flexsize(aml_memman, size + 1);
+ strcpy(tmp.str.string, obj->str.string);
+ aml_free_objectcontent(obj);
+ *obj = tmp;
+ break;
+ case aml_t_package:
+ if (obj->package.elements >= size) {
+ return;
+ }
+ tmp.package.objects = memman_alloc_flexsize(aml_memman,
+ size * sizeof(union aml_object *));
+ bzero(tmp.package.objects, size * sizeof(union aml_object *));
+ for (i = 0; i < obj->package.elements; i++) {
+ tmp.package.objects[i] = obj->package.objects[i];
+ }
+ memman_free_flexsize(aml_memman, obj->package.objects);
+ obj->package.objects = tmp.package.objects;
+ break;
+ default:
+ break;
+ }
+}
diff --git a/usr.sbin/acpidump/aml/aml_obj.h b/usr.sbin/acpidump/aml/aml_obj.h
new file mode 100644
index 00000000000..c38404184ed
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_obj.h
@@ -0,0 +1,232 @@
+/* $OpenBSD: aml_obj.h,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999 Takanori Watanabe
+ * Copyright (c) 1999, 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_obj.h,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_obj.h,v 1.1 2000/08/24 09:33:08 takawata Exp $
+ */
+
+#ifndef _AML_OBJ_H_
+#define _AML_OBJ_H_
+
+#include <sys/queue.h>
+
+struct aml_environ;
+enum aml_objtype {
+ aml_t_namestr = -3,
+ aml_t_regfield,
+ aml_t_objref,
+ aml_t_null = 0,
+ aml_t_num,
+ aml_t_string,
+ aml_t_buffer,
+ aml_t_package,
+ aml_t_device,
+ aml_t_field,
+ aml_t_event,
+ aml_t_method,
+ aml_t_mutex,
+ aml_t_opregion,
+ aml_t_powerres,
+ aml_t_processor,
+ aml_t_therm,
+ aml_t_bufferfield,
+ aml_t_ddbhandle,
+ aml_t_debug
+};
+
+struct aml_namestr {
+ enum aml_objtype type; /* =aml_t_namestr */
+ u_int8_t *dp;
+};
+
+struct aml_opregion {
+ enum aml_objtype type;
+ int space;
+ int offset;
+ int length;
+};
+
+struct aml_num {
+ enum aml_objtype type; /* =aml_t_num */
+ int number;
+ int constant;
+};
+
+struct aml_package {
+ enum aml_objtype type;
+ int elements;
+ union aml_object **objects;
+};
+
+struct aml_string {
+ enum aml_objtype type; /* =aml_t_string */
+ int needfree;
+ u_int8_t *string;
+};
+
+struct aml_buffer {
+ enum aml_objtype type; /* =aml_t_buffer */
+ int size;
+ u_int8_t *data; /* This should be free when
+ * this object is free.
+ */
+};
+
+enum fieldtype {
+ f_t_field,
+ f_t_index,
+ f_t_bank
+};
+
+struct nfieldd {
+ enum fieldtype ftype; /* f_t_field */
+ u_int8_t *regname; /* Namestring */
+};
+
+struct ifieldd {
+ enum fieldtype ftype; /* f_t_index */
+ u_int8_t *indexname;
+ u_int8_t *dataname;
+};
+
+struct bfieldd {
+ enum fieldtype ftype; /* f_t_bank */
+ u_int8_t *regname;
+ u_int8_t *bankname;
+ u_int32_t bankvalue;
+};
+
+struct aml_field {
+ enum aml_objtype type;
+ u_int32_t flags;
+ int bitoffset; /* Not Byte offset but bitoffset */
+ int bitlen;
+ union {
+ enum fieldtype ftype;
+ struct nfieldd fld;
+ struct ifieldd ifld;
+ struct bfieldd bfld;
+ } f;
+};
+
+struct aml_bufferfield {
+ enum aml_objtype type; /* aml_t_bufferfield */
+ int bitoffset;
+ int bitlen;
+ u_int8_t *origin; /* This should not be free
+ * when this object is free
+ * (Within Buffer object)
+ */
+};
+
+struct aml_method {
+ enum aml_objtype type;
+ int argnum; /* Not argnum but argnum|frag */
+ u_int8_t *from;
+ u_int8_t *to;
+};
+
+struct aml_powerres {
+ enum aml_objtype type;
+ int level;
+ int order;
+};
+
+struct aml_processor {
+ enum aml_objtype type;
+ int id;
+ int addr;
+ int len;
+};
+
+struct aml_mutex_queue {
+#if 0
+ STAILQ_ENTRY(aml_mutex_queue) entry;
+#endif
+};
+
+struct aml_mutex {
+ enum aml_objtype type;
+ int level;
+ volatile void *cookie; /* In kernel, struct proc? */
+#if 0
+ STAILQ_HEAD(, aml_mutex_queue) queue;
+#endif
+};
+
+struct aml_objref {
+ enum aml_objtype type;
+ struct aml_name *nameref;
+ union aml_object *ref;
+ int offset; /* of aml_buffer.data or aml_package.objects. */
+ /* if negative value, not ready to dereference for element access. */
+ unsigned deref; /* indicates whether dereffenced or not */
+ unsigned alias; /* true if this is an alias object reference */
+};
+
+struct aml_regfield {
+ enum aml_objtype type;
+ int space;
+ u_int32_t flags;
+ int offset;
+ int bitoffset;
+ int bitlen;
+};
+
+struct aml_event {
+ enum aml_objtype type; /* aml_t_event */
+ int inuse;
+};
+
+union aml_object {
+ enum aml_objtype type;
+ struct aml_num num;
+ struct aml_processor proc;
+ struct aml_powerres pres;
+ struct aml_opregion opregion;
+ struct aml_method meth;
+ struct aml_field field;
+ struct aml_mutex mutex;
+ struct aml_namestr nstr;
+ struct aml_buffer buffer;
+ struct aml_bufferfield bfld;
+ struct aml_package package;
+ struct aml_string str;
+ struct aml_objref objref;
+ struct aml_event event;
+ struct aml_regfield regfield;
+};
+
+union aml_object *aml_copy_object(struct aml_environ *,
+ union aml_object *);
+union aml_object *aml_alloc_object(enum aml_objtype,
+ union aml_object *);
+void aml_free_objectcontent(union aml_object *);
+void aml_free_object(union aml_object **);
+void aml_realloc_object(union aml_object *, int);
+
+#endif /* !_AML_OBJ_H_ */
diff --git a/usr.sbin/acpidump/aml/aml_parse.c b/usr.sbin/acpidump/aml/aml_parse.c
new file mode 100644
index 00000000000..0da801de5cd
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_parse.c
@@ -0,0 +1,2023 @@
+/* $OpenBSD: aml_parse.c,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999 Doug Rabson
+ * Copyright (c) 1999, 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_parse.c,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_parse.c,v 1.7 2001/10/23 14:54:15 takawata Exp $
+ */
+
+#include <sys/param.h>
+
+#include <aml/aml_amlmem.h>
+#include <aml/aml_common.h>
+#include <aml/aml_env.h>
+#include <aml/aml_evalobj.h>
+#include <aml/aml_name.h>
+#include <aml/aml_obj.h>
+#include <aml/aml_parse.h>
+#include <aml/aml_status.h>
+#include <aml/aml_store.h>
+
+#ifndef _KERNEL
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <assert.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "debug.h"
+#else /* _KERNEL */
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+#ifndef ACPI_NO_OSDFUNC_INLINE
+#include <machine/acpica_osd.h>
+#endif
+#endif /* !_KERNEL */
+
+static int findsetleftbit(int num);
+static int findsetrightbit(int num);
+static int frombcd(int num);
+static int tobcd(int num);
+
+static u_int32_t aml_parse_pkglength(struct aml_environ *env);
+static u_int8_t aml_parse_bytedata(struct aml_environ *env);
+static u_int16_t aml_parse_worddata(struct aml_environ *env);
+static u_int32_t aml_parse_dworddata(struct aml_environ *env);
+static u_int8_t *aml_parse_namestring(struct aml_environ *env);
+static void aml_parse_defscope(struct aml_environ *env,
+ int indent);
+static union aml_object *aml_parse_defbuffer(struct aml_environ *env,
+ int indent);
+static struct aml_name *aml_parse_concat_number(struct aml_environ *env,
+ int num1, int indent);
+static struct aml_name *aml_parse_concat_buffer(struct aml_environ *env,
+ union aml_object *obj,
+ int indent);
+static struct aml_name *aml_parse_concat_string(struct aml_environ *env,
+ union aml_object *obj,
+ int indent);
+static struct aml_name *aml_parse_concatop(struct aml_environ *env,
+ int indent);
+static union aml_object *aml_parse_defpackage(struct aml_environ *env,
+ int indent);
+static void aml_parse_defmethod(struct aml_environ *env,
+ int indent);
+static void aml_parse_defopregion(struct aml_environ *env,
+ int indent);
+static int aml_parse_field(struct aml_environ *env,
+ struct aml_field *template);
+static void aml_parse_fieldlist(struct aml_environ *env,
+ struct aml_field *template,
+ int indent);
+static void aml_parse_deffield(struct aml_environ *env,
+ int indent);
+static void aml_parse_defindexfield(struct aml_environ *env,
+ int indent);
+static void aml_parse_defbankfield(struct aml_environ *env,
+ int indent);
+static void aml_parse_defdevice(struct aml_environ *env,
+ int indent);
+static void aml_parse_defprocessor(struct aml_environ *env,
+ int indent);
+static void aml_parse_defpowerres(struct aml_environ *env,
+ int indent);
+static void aml_parse_defthermalzone(struct aml_environ *env,
+ int indent);
+static struct aml_name *aml_parse_defelse(struct aml_environ *env,
+ int indent, int num);
+static struct aml_name *aml_parse_defif(struct aml_environ *env,
+ int indent);
+static struct aml_name *aml_parse_defwhile(struct aml_environ *env,
+ int indent);
+static void aml_parse_defmutex(struct aml_environ *env,
+ int indent);
+static void aml_createfield_generic(struct aml_environ *env,
+ union aml_object *srcbuf,
+ int index, int len,
+ char *newname);
+static void aml_parse_defcreatefield(struct aml_environ *env,
+ int indent);
+
+static int
+findsetleftbit(int num)
+{
+ int i, filter;
+
+ filter = 0;
+ for (i = 0; i < 32; i++) {
+ filter = filter >> 1;
+ filter |= 1 << 31;
+ if (filter & num) {
+ break;
+ }
+ }
+ i = (i == 32) ? 0 : i + 1;
+ return (i);
+}
+
+static int
+findsetrightbit(int num)
+{
+ int i, filter;
+
+ filter = 0;
+ for (i = 0; i < 32; i++) {
+ filter = filter << 1;
+ filter |= 1;
+ if (filter & num) {
+ break;
+ }
+ }
+ i = (i == 32) ? 0 : i + 1;
+ return (i);
+}
+
+static int
+frombcd(int num)
+{
+ int res, factor;
+
+ res = 0;
+ factor = 1;
+ while (num != 0) {
+ res += ((num & 0xf) * factor);
+ num = num / 16;
+ factor *= 10;
+ }
+ return (res);
+}
+
+static int
+tobcd(int num)
+{
+ int res, factor;
+
+ res = 0;
+ factor = 1;
+ while (num != 0) {
+ res += ((num % 10) * factor);
+ num = num / 10;
+ factor *= 16;
+ }
+ return (res);
+}
+
+static u_int32_t
+aml_parse_pkglength(struct aml_environ *env)
+{
+ u_int8_t *dp;
+ u_int32_t pkglength;
+
+ dp = env->dp;
+ 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;
+ }
+
+ env->dp = dp;
+ return (pkglength);
+}
+
+static u_int8_t
+aml_parse_bytedata(struct aml_environ *env)
+{
+ u_int8_t data;
+
+ data = env->dp[0];
+ env->dp++;
+ return (data);
+}
+
+static u_int16_t
+aml_parse_worddata(struct aml_environ *env)
+{
+ u_int16_t data;
+
+ data = env->dp[0] + (env->dp[1] << 8);
+ env->dp += 2;
+ return (data);
+}
+
+static u_int32_t
+aml_parse_dworddata(struct aml_environ *env)
+{
+ u_int32_t data;
+
+ data = env->dp[0] + (env->dp[1] << 8) +
+ (env->dp[2] << 16) + (env->dp[3] << 24);
+ env->dp += 4;
+ return (data);
+}
+
+static u_int8_t *
+aml_parse_namestring(struct aml_environ *env)
+{
+ u_int8_t *name;
+ int segcount;
+
+ name = env->dp;
+ if (env->dp[0] == '\\')
+ env->dp++;
+ else if (env->dp[0] == '^')
+ while (env->dp[0] == '^')
+ env->dp++;
+ if (env->dp[0] == 0x00) /* NullName */
+ env->dp++;
+ else if (env->dp[0] == 0x2e) /* DualNamePrefix */
+ env->dp += 1 + 4 + 4; /* NameSeg, NameSeg */
+ else if (env->dp[0] == 0x2f) { /* MultiNamePrefix */
+ segcount = env->dp[1];
+ env->dp += 1 + 1 + segcount * 4; /* segcount * NameSeg */
+ } else
+ env->dp += 4; /* NameSeg */
+
+ return (name);
+}
+
+struct aml_name *
+aml_parse_objectlist(struct aml_environ *env, int indent)
+{
+ union aml_object *obj;
+
+ obj = NULL;
+ while (env->dp < env->end) {
+ aml_print_indent(indent);
+ obj = aml_eval_name(env, aml_parse_termobj(env, indent));
+ AML_DEBUGPRINT("\n");
+ if (env->stat == aml_stat_step) {
+ AML_DEBUGGER(env, env);
+ continue;
+ }
+ if (env->stat != aml_stat_none) {
+ env->tempname.property = obj;
+ return (&env->tempname);
+ }
+ }
+ return (NULL);
+}
+
+#define AML_CREATE_NAME(amlname, env, namestr, ret) do { \
+ amlname = aml_create_name(env, namestr); \
+ if (env->stat == aml_stat_panic) \
+ return ret; \
+} while(0)
+
+#define AML_COPY_OBJECT(dest, env, src, ret) do { \
+ dest = aml_copy_object(env, src); \
+ if (dest == NULL) { \
+ env->stat = aml_stat_panic; \
+ return ret; \
+ } \
+} while(0)
+
+#define AML_ALLOC_OBJECT(dest, env, type, ret) do { \
+ dest = aml_alloc_object(type, NULL); \
+ if (dest == NULL) { \
+ env->stat= aml_stat_panic; \
+ return ret; \
+ } \
+} while(0)
+
+static void
+aml_parse_defscope(struct aml_environ *env, int indent)
+{
+ u_int8_t *start, *end, *oend;
+ u_int8_t *name;
+ u_int32_t pkglength;
+ struct aml_name *oname;
+
+ start = env->dp;
+ pkglength = aml_parse_pkglength(env);
+
+ AML_DEBUGPRINT("Scope(");
+ name = aml_parse_namestring(env);
+ aml_print_namestring(name);
+ AML_DEBUGPRINT(") {\n");
+ oname = env->curname;
+ AML_CREATE_NAME(env->curname, env, name,);
+ oend = env->end;
+ env->end = end = start + pkglength;
+ aml_parse_objectlist(env, indent + 1);
+ aml_print_indent(indent);
+ AML_DEBUGPRINT("}");
+ AML_SYSASSERT(env->dp == env->end);
+ env->dp = end;
+ env->end = oend;
+ env->curname = oname;
+ env->stat = aml_stat_none;
+}
+
+static union aml_object *
+aml_parse_defbuffer(struct aml_environ *env, int indent)
+{
+ u_int8_t *start;
+ u_int8_t *end;
+ u_int8_t *buffer;
+ u_int32_t pkglength;
+ int size1, size2, size;
+ union aml_object *obj;
+
+ start = env->dp;
+ pkglength = aml_parse_pkglength(env);
+ end = start + pkglength;
+
+ AML_DEBUGPRINT("Buffer(");
+ obj = aml_eval_name(env, aml_parse_termobj(env, indent));
+ size1 = aml_objtonum(env, obj);
+ size2 = end - env->dp;
+ size = (size1 < size2) ? size1 : size2;
+ if (size1 > 0) {
+ buffer = memman_alloc_flexsize(aml_memman, size1);
+ if (buffer == NULL) {
+ AML_DEBUGPRINT("NO MEMORY\n");
+ env->stat = aml_stat_panic;
+ return (NULL);
+ }
+ bzero(buffer, size1);
+ bcopy(env->dp, buffer, size);
+ } else {
+ buffer = NULL;
+ }
+
+ obj = &env->tempobject;
+ obj->type = aml_t_buffer;
+ obj->buffer.size = size1;
+ obj->buffer.data = buffer;
+ AML_DEBUGPRINT(") ");
+ env->dp = end;
+
+ return (obj);
+}
+
+static struct aml_name *
+aml_parse_concat_number(struct aml_environ *env, int num1, int indent)
+{
+ int num2;
+ struct aml_name *destname;
+ union aml_object *obj;
+
+ num2 = aml_objtonum(env, aml_eval_name(env,
+ aml_parse_termobj(env, indent)));
+ AML_DEBUGPRINT(", ");
+ destname = aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(")");
+ obj = &env->tempobject;
+ obj->type = aml_t_buffer;
+ obj->buffer.size = 2;
+ obj->buffer.data = memman_alloc_flexsize(aml_memman, 2);
+ if (obj->buffer.data == NULL) {
+ env->stat = aml_stat_panic;
+ return (NULL);
+ }
+ obj->buffer.data[0] = num1 & 0xff;
+ obj->buffer.data[1] = num2 & 0xff;
+ aml_store_to_name(env, obj, destname);
+ return (&env->tempname);
+}
+
+static struct aml_name *
+aml_parse_concat_buffer(struct aml_environ *env, union aml_object *obj,
+ int indent)
+{
+ union aml_object *tmpobj, *tmpobj2, *resobj;
+ struct aml_name *destname;
+
+ tmpobj = aml_eval_name(env, aml_parse_termobj(env, indent));
+ AML_DEBUGPRINT(", ");
+ if (tmpobj->type != aml_t_buffer) {
+ env->stat = aml_stat_panic;
+ return (NULL);
+ }
+ AML_COPY_OBJECT(tmpobj2, env, tmpobj, NULL);
+ destname = aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(")");
+ resobj = &env->tempobject;
+ env->tempname.property = resobj;
+ resobj->buffer.type = aml_t_buffer;
+ resobj->buffer.size = tmpobj2->buffer.size + obj->buffer.size;
+ if (resobj->buffer.size > 0) {
+ resobj->buffer.data = memman_alloc_flexsize(aml_memman,
+ resobj->buffer.size);
+ if (resobj->buffer.data == NULL) {
+ env->stat = aml_stat_panic;
+ return (NULL);
+ }
+ bcopy(obj->buffer.data, resobj->buffer.data, obj->buffer.size);
+ bcopy(tmpobj2->buffer.data,
+ resobj->buffer.data + obj->buffer.size,
+ tmpobj2->buffer.size);
+ } else {
+ resobj->buffer.data = NULL;
+ }
+ aml_free_object(&tmpobj2);
+ aml_store_to_name(env, resobj, destname);
+ return (&env->tempname);
+}
+
+static struct aml_name *
+aml_parse_concat_string(struct aml_environ *env, union aml_object *obj,
+ int indent)
+{
+ int len;
+ union aml_object *tmpobj, *tmpobj2, *resobj;
+ struct aml_name *destname;
+
+ tmpobj = aml_eval_name(env, aml_parse_termobj(env, indent));
+ AML_DEBUGPRINT(", ");
+ if (tmpobj->type != aml_t_string) {
+ env->stat = aml_stat_panic;
+ return (NULL);
+ }
+ AML_COPY_OBJECT(tmpobj2, env, tmpobj, NULL);
+ destname = aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(")");
+ resobj = &env->tempobject;
+ env->tempname.property = resobj;
+ resobj->type = aml_t_buffer;
+ resobj->str.needfree = 1;
+ len = strlen(obj->str.string) + strlen(tmpobj2->str.string) + 1;
+ if (len > 0) {
+ resobj->str.string = memman_alloc_flexsize(aml_memman, len);
+ if (resobj->str.string == NULL) {
+ env->stat = aml_stat_panic;
+ return (NULL);
+ }
+ strncpy(resobj->str.string, obj->str.string, len);
+ strcat(resobj->str.string, tmpobj->str.string);
+ } else {
+ resobj->str.string = NULL;
+ }
+ aml_free_object(&tmpobj2);
+ aml_store_to_name(env, resobj, destname);
+ return (&env->tempname);
+}
+
+static struct aml_name *
+aml_parse_concatop(struct aml_environ *env, int indent)
+{
+ union aml_object *obj, *tmpobj;
+ struct aml_name *aname;
+
+ AML_DEBUGPRINT("Concat(");
+ obj = aml_eval_name(env, aml_parse_termobj(env, indent));
+ AML_DEBUGPRINT(", ");
+ switch (obj->type) {
+ case aml_t_num:
+ aname = aml_parse_concat_number(env, aml_objtonum(env, obj), indent);
+ break;
+
+ case aml_t_buffer:
+ /* obj may be temporal object */
+ AML_COPY_OBJECT(tmpobj, env, obj, NULL);
+ aname = aml_parse_concat_buffer(env, obj, indent);
+ aml_free_object(&tmpobj);
+ break;
+
+ case aml_t_string:
+ /* obj may be temporal object */
+ AML_COPY_OBJECT(tmpobj, env, obj, NULL);
+ aname = aml_parse_concat_string(env, obj, indent);
+ aml_free_object(&tmpobj);
+ break;
+
+ default:
+ env->stat = aml_stat_panic;
+ aname = NULL;
+ break;
+ }
+
+ AML_DEBUGPRINT("\n");
+ return (aname);
+}
+
+static union aml_object *
+aml_parse_defpackage(struct aml_environ *env, int indent)
+{
+ u_int8_t numelements;
+ u_int8_t *start;
+ u_int32_t pkglength;
+ int i;
+ struct aml_environ *copy;
+ struct aml_name *tmpname;
+ union aml_object *obj, **objects;
+
+ start = env->dp;
+ pkglength = aml_parse_pkglength(env);
+ numelements = aml_parse_bytedata(env);
+ copy = memman_alloc(aml_memman, memid_aml_environ);
+ if (copy == NULL) {
+ env->stat = aml_stat_panic;
+ return (NULL);
+ }
+ if (numelements > 0) {
+ objects = memman_alloc_flexsize(aml_memman,
+ numelements * sizeof(union aml_object *));
+ if (objects == NULL) {
+ env->stat = aml_stat_panic;
+ return (NULL);
+ } else {
+ bzero(objects, numelements * sizeof(union aml_object *));
+ }
+ } else {
+ objects = NULL;
+ }
+
+ *copy = *env;
+ env->dp = copy->end = start + pkglength;
+ AML_DEBUGPRINT("Package() {\n");
+ i = 0;
+ while ((copy->dp < copy->end) && (i < numelements)) {
+ aml_print_indent(indent + 1);
+ tmpname = aml_parse_termobj(copy, indent + 1);
+
+ if (tmpname != NULL) {
+ objects[i] = aml_copy_object(copy, tmpname->property);
+ }
+ AML_DEBUGPRINT(",\n");
+ i++;
+ }
+ aml_free_objectcontent(&copy->tempobject);
+
+ aml_print_indent(indent);
+ AML_DEBUGPRINT("}");
+ obj = &env->tempobject;
+ obj->type = aml_t_package;
+ obj->package.elements = numelements;
+ obj->package.objects = objects;
+
+ memman_free(aml_memman, memid_aml_environ, copy);
+ return (obj);
+}
+
+static void
+aml_parse_defmethod(struct aml_environ *env, int indent)
+{
+ u_int8_t flags;
+ u_int8_t *start;
+ u_int32_t pkglength;
+ char *name;
+ struct aml_environ *copy;
+ struct aml_method *meth;
+ struct aml_name *aname;
+ union aml_object *aobj;
+
+ start = env->dp;
+ pkglength = aml_parse_pkglength(env);
+ copy = memman_alloc(aml_memman, memid_aml_environ);
+ if (copy == NULL) {
+ env->stat = aml_stat_panic;
+ return;
+ }
+ AML_DEBUGPRINT("Method(");
+ name = aml_parse_namestring(env);
+ aml_print_namestring(name);
+ AML_CREATE_NAME(aname, env, name,);
+ if (aname->property != NULL) {
+ env->stat = aml_stat_panic;
+ AML_DEBUGPRINT("Already Defined \n");
+ goto out;
+ }
+ AML_ALLOC_OBJECT(aobj, env, aml_t_method,);
+ meth = &aobj->meth;
+ aname->property = aobj;
+ flags = *env->dp++;
+
+ if (flags) {
+ AML_DEBUGPRINT(", %d", flags);
+ }
+ AML_DEBUGPRINT(") {\n");
+ *copy = *env;
+ meth->argnum = flags;
+ meth->from = env->dp;
+ meth->to = env->dp = copy->end = start + pkglength;
+ aml_print_indent(indent);
+ AML_DEBUGPRINT("}");
+out:
+ memman_free(aml_memman, memid_aml_environ, copy);
+}
+
+static void
+aml_parse_defopregion(struct aml_environ *env, int indent)
+{
+ u_int8_t *name;
+ struct aml_name *aname;
+ struct aml_opregion *opregion;
+ union aml_object *obj;
+ const char *regions[] = {
+ "SystemMemory",
+ "SystemIO",
+ "PCI_Config",
+ "EmbeddedControl",
+ "SMBus",
+ };
+
+ AML_DEBUGPRINT("OperationRegion(");
+ /* Name */
+ name = aml_parse_namestring(env);
+ aml_print_namestring(name);
+ AML_CREATE_NAME(aname, env, name,);
+ if (aname->property != NULL) {
+ env->stat = aml_stat_panic;
+ AML_DEBUGPRINT("Already Defined \n");
+ return;
+ }
+ AML_ALLOC_OBJECT(aname->property, env, aml_t_opregion,);
+ opregion = &aname->property->opregion;
+ opregion->space = *env->dp;
+ AML_DEBUGPRINT(", %s, ", regions[*env->dp]); /* Space */
+ env->dp++;
+ obj = aml_eval_name(env, aml_parse_termobj(env, indent)); /* Offset */
+ opregion->offset = aml_objtonum(env, obj);
+ AML_DEBUGPRINT(", ");
+ obj = aml_eval_name(env, aml_parse_termobj(env, indent)); /* Length */
+ opregion->length = aml_objtonum(env, obj);
+ AML_DEBUGPRINT(")");
+}
+
+static const char *accessnames[] = {
+ "AnyAcc",
+ "ByteAcc",
+ "WordAcc",
+ "DWordAcc",
+ "BlockAcc",
+ "SMBSendRecvAcc",
+ "SMBQuickAcc"
+};
+
+static int
+aml_parse_field(struct aml_environ *env, struct aml_field *template)
+{
+ u_int8_t *name;
+ u_int8_t access, attribute;
+ u_int32_t width;
+ struct aml_name *aname;
+ struct aml_field *prop;
+
+ switch (*env->dp) {
+ case '\\':
+ case '^':
+ case 'A'...'Z':
+ case '_':
+ case '.':
+ case '/':
+ name = aml_parse_namestring(env);
+ width = aml_parse_pkglength(env);
+ template->bitlen = width;
+ aml_print_namestring(name);
+ AML_CREATE_NAME(aname, env, name, NULL);
+ /* Allignment */
+ if (width == 16) {
+ template->bitoffset += 15;
+ template->bitoffset &= (~15);
+ }
+ if (width == 32) {
+ template->bitoffset += 31;
+ template->bitoffset &= (~31);
+ } else if ((width & 7) == 0) {
+ template->bitoffset += 7;
+ template->bitoffset &= (~7);
+ } else if ((width > 32) && (width & 7) != 0) {
+ AML_DEBUGPRINT("??? Can I treat it?\n");
+ }
+ if (aname->property != NULL) {
+ env->stat = aml_stat_panic;
+ AML_DEBUGPRINT("Already Defined \n");
+ return (NULL);
+ }
+ AML_ALLOC_OBJECT(aname->property, env, aml_t_field, NULL);
+ prop = &aname->property->field;
+ *prop = *template;
+ template->bitoffset += width;
+ AML_DEBUGPRINT(",\t%d", width);
+ break;
+ case 0x00:
+ env->dp++;
+ width = aml_parse_pkglength(env);
+ template->bitoffset += width;
+ AML_DEBUGPRINT("Offset(0x%x)", template->bitoffset);
+ break;
+ case 0x01:
+ access = env->dp[1];
+ attribute = env->dp[2];
+ env->dp += 3;
+ AML_DEBUGPRINT("AccessAs(%s, %d)", accessnames[access], attribute);
+ template->bitoffset = attribute;
+ template->flags = (template->flags | 0xf0) | access;
+ break;
+ }
+ return (template->bitoffset);
+}
+
+static void
+aml_parse_fieldlist(struct aml_environ *env, struct aml_field *template,
+ int indent)
+{
+ u_int32_t offset;
+
+ offset = 0;
+ while (env->dp < env->end) {
+ aml_print_indent(indent);
+ offset = aml_parse_field(env, template);
+ if (env->dp < env->end) {
+ AML_DEBUGPRINT(",\n");
+ } else {
+ AML_DEBUGPRINT("\n");
+ }
+ }
+}
+
+static void
+aml_parse_deffield(struct aml_environ *env, int indent)
+{
+ u_int8_t flags;
+ u_int8_t *start, *name;
+ u_int32_t pkglength;
+ struct aml_environ *copy;
+ struct aml_field fieldtemplate;
+ static const char *lockrules[] = {"NoLock", "Lock"};
+ static const char *updaterules[] = {"Preserve", "WriteAsOnes",
+ "WriteAsZeros", "*Error*"};
+
+ start = env->dp;
+ pkglength = aml_parse_pkglength(env);
+ copy = memman_alloc(aml_memman, memid_aml_environ);
+ if (copy == NULL) {
+ env->stat = aml_stat_panic;
+ return;
+ }
+ AML_DEBUGPRINT("Field(");
+ aml_print_namestring(name = aml_parse_namestring(env));
+ fieldtemplate.type = aml_t_field;
+ flags = aml_parse_bytedata(env);
+ fieldtemplate.flags = fieldtemplate.flags = flags;
+
+ *copy = *env;
+ env->dp = copy->end = start + pkglength;
+ fieldtemplate.bitoffset = 0;
+ fieldtemplate.bitlen = 0;
+ fieldtemplate.f.ftype = f_t_field;
+ fieldtemplate.f.fld.regname = name;
+ AML_DEBUGPRINT(", %s, %s, %s) {\n",
+ accessnames[flags & 0xf],
+ lockrules[(flags >> 4) & 1],
+ updaterules[(flags >> 5) & 3]);
+ aml_parse_fieldlist(copy, &fieldtemplate, indent + 1);
+ aml_print_indent(indent);
+ AML_DEBUGPRINT("}");
+ aml_free_objectcontent(&copy->tempobject);
+
+ AML_SYSASSERT(copy->dp == copy->end);
+ memman_free(aml_memman, memid_aml_environ, copy);
+}
+
+static void
+aml_parse_defindexfield(struct aml_environ *env, int indent)
+{
+ u_int8_t flags;
+ u_int8_t *start, *iname, *dname;
+ u_int32_t pkglength;
+ struct aml_environ *copy;
+ struct aml_field template;
+ static const char *lockrules[] = {"NoLock", "Lock"};
+ static const char *updaterules[] = {"Preserve", "WriteAsOnes",
+ "WriteAsZeros", "*Error*"};
+
+ start = env->dp;
+ pkglength = aml_parse_pkglength(env);
+ copy = memman_alloc(aml_memman, memid_aml_environ);
+ if (copy == NULL) {
+ env->stat = aml_stat_panic;
+ return;
+ }
+ AML_DEBUGPRINT("IndexField(");
+ aml_print_namestring(iname = aml_parse_namestring(env)); /* Name1 */
+ AML_DEBUGPRINT(", ");
+ aml_print_namestring(dname = aml_parse_namestring(env)); /* Name2 */
+ template.type = aml_t_field;
+ template.flags = flags = aml_parse_bytedata(env);
+ template.bitoffset = 0;
+ template.bitlen = 0;
+ template.f.ftype = f_t_index;
+ template.f.ifld.indexname = iname;
+ template.f.ifld.dataname = dname;
+ AML_DEBUGPRINT(", %s, %s, %s) {\n",
+ accessnames[flags & 0xf],
+ lockrules[(flags >> 4) & 1],
+ updaterules[(flags >> 5) & 3]);
+ *copy = *env;
+ env->dp = copy->end = start + pkglength;
+ aml_parse_fieldlist(copy, &template, indent + 1);
+ aml_print_indent(indent);
+ AML_DEBUGPRINT("}");
+ aml_free_objectcontent(&copy->tempobject);
+
+ AML_SYSASSERT(copy->dp == copy->end);
+ memman_free(aml_memman, memid_aml_environ, copy);
+}
+
+static void
+aml_parse_defbankfield(struct aml_environ *env, int indent)
+{
+ u_int8_t flags;
+ u_int8_t *start, *rname, *bname;
+ u_int32_t pkglength, bankvalue;
+ struct aml_environ *copy;
+ struct aml_field template;
+ union aml_object *obj;
+ static const char *lockrules[] = {"NoLock", "Lock"};
+ static const char *updaterules[] = {"Preserve", "WriteAsOnes",
+ "WriteAsZeros", "*Error*"};
+
+ start = env->dp;
+ pkglength = aml_parse_pkglength(env);
+ copy = memman_alloc(aml_memman, memid_aml_environ);
+ if (copy == NULL) {
+ env->stat = aml_stat_panic;
+ return;
+ }
+ AML_DEBUGPRINT("BankField(");
+ aml_print_namestring(rname = aml_parse_namestring(env)); /* Name1 */
+ AML_DEBUGPRINT(", ");
+ aml_print_namestring(bname = aml_parse_namestring(env)); /* Name2 */
+ AML_DEBUGPRINT(", ");
+ obj = aml_eval_name(env, aml_parse_termobj(env, indent)); /* BankValue */
+ bankvalue = aml_objtonum(env, obj);
+ template.type = aml_t_field;
+ template.flags = flags = aml_parse_bytedata(env);
+ template.bitoffset = 0;
+ template.bitlen = 0;
+ template.f.ftype = f_t_bank;
+ template.f.bfld.regname = rname;
+ template.f.bfld.bankname = bname;
+ template.f.bfld.bankvalue = bankvalue;
+ *copy = *env;
+ env->dp = copy->end = start + pkglength;
+ AML_DEBUGPRINT(", %s, %s, %s) {\n",
+ accessnames[flags & 0xf],
+ lockrules[(flags >> 4) & 1],
+ updaterules[(flags >> 5) & 3]);
+ aml_parse_fieldlist(copy, &template, indent + 1);
+ aml_print_indent(indent);
+ AML_DEBUGPRINT("}");
+
+ aml_free_objectcontent(&copy->tempobject);
+ AML_SYSASSERT(copy->dp == copy->end);
+ memman_free(aml_memman, memid_aml_environ, copy);
+}
+
+static void
+aml_parse_defdevice(struct aml_environ *env, int indent)
+{
+ u_int8_t *start;
+ u_int8_t *name;
+ u_int32_t pkglength;
+ struct aml_environ *copy;
+
+ start = env->dp;
+ pkglength = aml_parse_pkglength(env);
+ copy = memman_alloc(aml_memman, memid_aml_environ);
+ if (copy == NULL) {
+ env->stat = aml_stat_panic;
+ return;
+ }
+ AML_DEBUGPRINT("Device(");
+ name = aml_parse_namestring(env);
+ aml_print_namestring(name);
+ AML_DEBUGPRINT(") {\n");
+ *copy = *env;
+ AML_CREATE_NAME(copy->curname, env, name,);
+ if (copy->curname->property != NULL) {
+ env->stat = aml_stat_panic;
+ AML_DEBUGPRINT("Already Defined \n");
+ goto out;
+ }
+ AML_ALLOC_OBJECT(copy->curname->property, env, aml_t_device,);
+ env->dp = copy->end = start + pkglength;
+ aml_parse_objectlist(copy, indent + 1);
+ aml_print_indent(indent);
+ AML_DEBUGPRINT("}");
+ aml_free_objectcontent(&copy->tempobject);
+
+ AML_SYSASSERT(copy->dp == copy->end);
+out:
+ memman_free(aml_memman, memid_aml_environ, copy);
+}
+
+static void
+aml_parse_defprocessor(struct aml_environ *env, int indent)
+{
+ u_int8_t *start;
+ u_int8_t *name;
+ u_int32_t pkglength;
+ struct aml_environ *copy;
+ struct aml_processor *proc;
+ union aml_object *obj;
+
+ start = env->dp;
+ pkglength = aml_parse_pkglength(env);
+ copy = memman_alloc(aml_memman, memid_aml_environ);
+ if (copy == NULL) {
+ env->stat = aml_stat_panic;
+ return;
+ }
+ AML_ALLOC_OBJECT(obj, env, aml_t_processor,);
+ proc = &obj->proc;
+ AML_DEBUGPRINT("Processor(");
+ name = aml_parse_namestring(env);
+ aml_print_namestring(name);
+ proc->id = aml_parse_bytedata(env);
+ proc->addr = aml_parse_dworddata(env);
+ proc->len = aml_parse_bytedata(env);
+ AML_DEBUGPRINT(", %d, 0x%x, 0x%x) {\n", proc->id, proc->addr, proc->len);
+ *copy = *env;
+ AML_CREATE_NAME(copy->curname, env, name,);
+ if (copy->curname->property != NULL) {
+ env->stat = aml_stat_panic;
+ AML_DEBUGPRINT("Already Defined \n");
+ goto out;
+ }
+ copy->curname->property = obj;
+ env->dp = copy->end = start + pkglength;
+ aml_parse_objectlist(copy, indent + 1);
+ aml_print_indent(indent);
+ AML_DEBUGPRINT("}");
+ aml_free_objectcontent(&copy->tempobject);
+
+ AML_SYSASSERT(copy->dp == copy->end);
+out:
+ memman_free(aml_memman, memid_aml_environ, copy);
+}
+
+static void
+aml_parse_defpowerres(struct aml_environ *env, int indent)
+{
+ u_int8_t *start;
+ u_int8_t *name;
+ u_int32_t pkglength;
+ struct aml_environ *copy;
+ struct aml_powerres *pres;
+ union aml_object *obj;
+
+ start = env->dp;
+ pkglength = aml_parse_pkglength(env);
+ copy = memman_alloc(aml_memman, memid_aml_environ);
+ if (copy == NULL) {
+ env->stat = aml_stat_panic;
+ return;
+ }
+ AML_DEBUGPRINT("PowerResource(");
+ AML_ALLOC_OBJECT(obj, env, aml_t_powerres,);
+ name = aml_parse_namestring(env);
+ aml_print_namestring(name);
+ pres = &obj->pres;
+ pres->level = aml_parse_bytedata(env);
+ pres->order = aml_parse_worddata(env);
+ AML_DEBUGPRINT(", %d, %d) {\n", pres->level, pres->order);
+ *copy = *env;
+ AML_CREATE_NAME(copy->curname, env, name,);
+ if (copy->curname->property != NULL) {
+ env->stat = aml_stat_panic;
+ AML_DEBUGPRINT("Already Defined \n");
+ goto out;
+ }
+ copy->curname->property = obj;
+ env->dp = copy->end = start + pkglength;
+
+ aml_parse_objectlist(copy, indent + 1);
+ aml_print_indent(indent);
+ AML_DEBUGPRINT("}");
+ aml_free_objectcontent(&copy->tempobject);
+
+ AML_SYSASSERT(copy->dp == copy->end);
+out:
+ memman_free(aml_memman, memid_aml_environ, copy);
+}
+
+static void
+aml_parse_defthermalzone(struct aml_environ *env, int indent)
+{
+ u_int8_t *start;
+ u_int8_t *name;
+ u_int32_t pkglength;
+ struct aml_environ *copy;
+
+ start = env->dp;
+ pkglength = aml_parse_pkglength(env);
+ copy = memman_alloc(aml_memman, memid_aml_environ);
+ if (copy == NULL) {
+ env->stat = aml_stat_panic;
+ return;
+ }
+ AML_DEBUGPRINT("ThermalZone(");
+ name = aml_parse_namestring(env);
+ aml_print_namestring(name);
+ AML_DEBUGPRINT(") {\n");
+ *copy = *env;
+ AML_CREATE_NAME(copy->curname, env, name,);
+ if (copy->curname->property != NULL) {
+ env->stat = aml_stat_panic;
+ AML_DEBUGPRINT("Already Defined \n");
+ goto out;
+ }
+ AML_ALLOC_OBJECT(copy->curname->property, env, aml_t_therm,);
+ env->dp = copy->end = start + pkglength;
+ aml_parse_objectlist(copy, indent + 1);
+ aml_print_indent(indent);
+ AML_DEBUGPRINT("}");
+ aml_free_objectcontent(&copy->tempobject);
+ AML_SYSASSERT(copy->dp == copy->end);
+out:
+ memman_free(aml_memman, memid_aml_environ, copy);
+}
+
+static struct aml_name *
+aml_parse_defelse(struct aml_environ *env, int indent, int num)
+{
+ u_int8_t *start, *end, *oend;
+ u_int32_t pkglength;
+ struct aml_name *aname;
+
+ start = env->dp;
+ pkglength = aml_parse_pkglength(env);
+ oend = env->end;
+ env->end = end = start + pkglength;
+ aname = NULL;
+
+ AML_DEBUGPRINT("Else {\n");
+ if (num == 0) {
+ aname = aml_parse_objectlist(env, indent + 1);
+ aml_print_indent(indent);
+ }
+ AML_DEBUGPRINT("}");
+
+ env->dp = end;
+ env->end = oend;
+ return (aname);
+}
+
+static struct aml_name *
+aml_parse_defif(struct aml_environ *env, int indent)
+{
+ u_int8_t *start, *end, *oend;
+ u_int32_t pkglength;
+ int num;
+ struct aml_name *aname, *aname1;
+
+ start = env->dp;
+ pkglength = aml_parse_pkglength(env);
+ aname = NULL;
+
+ AML_DEBUGPRINT("If(");
+ num = aml_objtonum(env, aml_eval_name
+ (env, aml_parse_termobj(env, indent)));
+ oend = env->end;
+ end = start + pkglength;
+ AML_DEBUGPRINT(")");
+ if (num) {
+ AML_DEBUGPRINT("{\n");
+ env->end = end;
+ aname = aml_parse_objectlist(env, indent + 1);
+ aml_print_indent(indent);
+ AML_DEBUGPRINT("}");
+ }
+ env->dp = end;
+ env->end = oend;
+ if ((end < oend) && *(env->dp) == 0xa1) {
+ env->dp++;
+ aname1 = aml_parse_defelse(env, indent, num);
+ aname = (num == 0) ? aname1 : aname;
+ }
+ return (aname);
+}
+
+static struct aml_name *
+aml_parse_defwhile(struct aml_environ *env, int indent)
+{
+ u_int8_t *start, *end, *oend;
+ u_int32_t pkglength;
+ int num;
+ struct aml_name *aname;
+
+ start = env->dp;
+ pkglength = aml_parse_pkglength(env);
+ oend = env->end;
+ end = start + pkglength;
+ aname = NULL;
+ for (;;) {
+ env->dp = start;
+ aml_parse_pkglength(env);
+ AML_DEBUGPRINT("While(");
+ num = aml_objtonum(env, aml_eval_name
+ (env, aml_parse_termobj(env, indent)));
+ AML_DEBUGPRINT(")");
+ if (num == 0) {
+ break;
+ }
+ AML_DEBUGPRINT(" {\n");
+ env->end = end;
+ aname = aml_parse_objectlist(env, indent + 1);
+ if (env->stat == aml_stat_step) {
+ AML_DEBUGGER(env, env);
+ continue;
+ }
+ if (env->stat != aml_stat_none)
+ break;
+ aml_print_indent(indent);
+ AML_DEBUGPRINT("}");
+ }
+ AML_DEBUGPRINT("\n");
+ env->dp = end;
+ env->end = oend;
+ if (env->stat == aml_stat_break) {
+ env->stat = aml_stat_none;
+ aname = NULL;
+ }
+ return (aname);
+}
+
+static void
+aml_parse_defmutex(struct aml_environ *env, int indent)
+{
+ char *name;
+ struct aml_name *aname;
+ struct aml_mutex *mut;
+
+ /* MutexOp */
+ AML_DEBUGPRINT("Mutex(");
+ name = aml_parse_namestring(env);
+ aml_print_namestring(name);
+ AML_CREATE_NAME(aname, env, name,);
+ if (aname->property != NULL) {
+ env->stat = aml_stat_panic;
+ AML_DEBUGPRINT("Already Defined \n");
+ return;
+ }
+ AML_ALLOC_OBJECT(aname->property, env, aml_t_mutex,);
+ mut = &aname->property->mutex;
+ mut->level = *env->dp++;
+#if 0
+ STAILQ_INIT(&mut->queue);
+#endif
+ AML_DEBUGPRINT(", %d)", mut->level);
+}
+
+static void
+aml_createfield_generic(struct aml_environ *env,
+ union aml_object *srcbuf, int index,
+ int len, char *newname)
+{
+ struct aml_bufferfield *field;
+ struct aml_name *aname;
+
+ if (srcbuf == NULL || srcbuf->type != aml_t_buffer) {
+ AML_DEBUGPRINT("Not Buffer assigned,");
+ env->stat = aml_stat_panic;
+ return;
+ }
+ AML_CREATE_NAME(aname, env, newname,);
+ if (aname->property != NULL) {
+ env->stat = aml_stat_panic;
+ AML_DEBUGPRINT("Already Defined \n");
+ return;
+ }
+ AML_ALLOC_OBJECT(aname->property, env, aml_t_bufferfield,);
+ field = &aname->property->bfld;
+ field->bitoffset = index;
+ field->bitlen = len;
+ field->origin = srcbuf->buffer.data;
+}
+
+static void
+aml_parse_defcreatefield(struct aml_environ *env, int indent)
+{
+ int index, len;
+ char *newname;
+ union aml_object *obj, *srcbuf;
+
+ /* CreateFieldOp */
+ AML_DEBUGPRINT("CreateField(");
+ srcbuf = aml_eval_name(env, aml_parse_termobj(env, indent));
+ if (srcbuf == &env->tempobject) {
+ AML_DEBUGPRINT("NONAMED BUFFER\n");
+ env->stat = aml_stat_panic;
+ return;
+ }
+ AML_DEBUGPRINT(", ");
+ obj = aml_eval_name(env, aml_parse_termobj(env, indent));
+ index = aml_objtonum(env, obj);
+ AML_DEBUGPRINT(", ");
+ obj = aml_eval_name(env, aml_parse_termobj(env, indent));
+ len = aml_objtonum(env, obj);
+ AML_DEBUGPRINT(", ");
+ newname = aml_parse_namestring(env);
+ aml_print_namestring(newname);
+ aml_createfield_generic(env, srcbuf, index, len, newname);
+ AML_DEBUGPRINT(") ");
+}
+
+/*
+ * Returns Named object or parser buffer. The object need not be free because
+ * it returns preallocated buffer in env or Contain of named object. If You
+ * need to preserve object, create a copy and then store. And The object
+ * returned from this function is not valid after another call is
+ * shared, tempolary buffer may be shared.
+ */
+struct aml_name *
+aml_parse_termobj(struct aml_environ *env, int indent)
+{
+ u_int8_t opcode;
+ u_int8_t *name;
+ int value;
+ int num1, num2;
+ int len;
+ int match1, match2, i, pkgval, start;
+ int widthindex, index;
+ char *newname;
+ struct aml_name *aname;
+ struct aml_name *destname1, *destname2;
+ struct aml_name *tmpname, *srcname;
+ struct aml_name *src;
+ union aml_object *ret;
+ union aml_object *tmpobj;
+ union aml_object anum;
+ union aml_object *objref;
+ union aml_object *srcobj;
+ union aml_object *obj;
+ union aml_object *srcbuf;
+ static int widthtbl[4] = {32, 16, 8, 1};
+ const char *opname[4] = {"CreateDWordField", "CreateWordField",
+ "CreateByteField", "CreateBitField"};
+
+ aname = &env->tempname;
+ ret = &env->tempobject;
+ anum.type = aml_t_num;
+ aname->property = ret;
+ aml_free_objectcontent(ret);
+ if (env->stat == aml_stat_panic) {
+ /*
+ * If previosuly parser panic , parsing next instruction is
+ * prohibited.
+ */
+ return (NULL);
+ }
+ aname = NULL;
+ opcode = *env->dp++;
+ switch (opcode) {
+ case '\\':
+ case '^':
+ case 'A' ... 'Z':
+ case '_':
+ case '.':
+ case '/':
+ env->dp--;
+ ret->type = aml_t_namestr;
+ ret->nstr.dp = aml_parse_namestring(env);
+ aml_print_namestring(ret->nstr.dp);
+ aname = &env->tempname;
+ break;
+ case 0x0a: /* BytePrefix */
+ ret->type = aml_t_num;
+ value = aml_parse_bytedata(env);
+ ret->num.number = value;
+ AML_DEBUGPRINT("0x%x", value);
+ aname = &env->tempname;
+ break;
+ case 0x0b: /* WordPrefix */
+ ret->type = aml_t_num;
+ value = aml_parse_worddata(env);
+ ret->num.number = value;
+ AML_DEBUGPRINT("0x%x", value);
+ aname = &env->tempname;
+ break;
+ case 0x0c: /* DWordPrefix */
+ ret->type = aml_t_num;
+ value = aml_parse_dworddata(env);
+ ret->num.number = value;
+ AML_DEBUGPRINT("0x%x", value);
+ aname = &env->tempname;
+ break;
+ case 0x0d: /* StringPrefix */
+ ret->type = aml_t_string;
+ ret->str.string = env->dp;
+ len = strlen(env->dp);
+ ret->str.needfree = 0;
+ AML_DEBUGPRINT("\"%s\"", (const char *)ret->str.string);
+ env->dp += (len + 1);
+ aname = &env->tempname;
+ break;
+ case 0x00: /* ZeroOp */
+ ret->type = aml_t_num;
+ ret->num.number = 0;
+ ret->num.constant = 1;
+ AML_DEBUGPRINT("Zero");
+ aname = &env->tempname;
+ break;
+ case 0x01: /* OneOp */
+ ret->type = aml_t_num;
+ ret->num.number = 1;
+ ret->num.constant = 1;
+ AML_DEBUGPRINT("One");
+ aname = &env->tempname;
+ break;
+ case 0xff: /* OnesOp */
+ ret->type = aml_t_num;
+ ret->num.number = 0xffffffff;
+ ret->num.constant = 1;
+ AML_DEBUGPRINT("Ones");
+ aname = &env->tempname;
+ break;
+ case 0x06: /* AliasOp */
+ AML_DEBUGPRINT("Alias(");
+ tmpname = aml_parse_termobj(env, indent);
+ if (env->stat == aml_stat_panic) {
+ return (NULL);
+ }
+ if (tmpname->property == NULL ||
+ tmpname->property->type != aml_t_namestr) {
+ env->stat = aml_stat_panic;
+ return (NULL);
+ }
+ /*
+ * XXX if srcname is deleted after this object, what
+ * shall I do?
+ */
+ srcname = aml_search_name(env, tmpname->property->nstr.dp);
+ AML_DEBUGPRINT(", ");
+ name = aml_parse_namestring(env);
+ aml_print_namestring(name);
+ AML_CREATE_NAME(aname, env, name, NULL);
+ if (aname->property != NULL) {
+ env->stat = aml_stat_panic;
+ AML_DEBUGPRINT("Already Defined \n");
+ aml_print_curname(aname);
+ return (NULL);
+ }
+ AML_ALLOC_OBJECT(aname->property, env, aml_t_objref, NULL);
+ objref = aname->property;
+ objref->objref.nameref = srcname;
+ objref->objref.ref = srcname->property;
+ objref->objref.offset = -1;
+ objref->objref.alias = 1; /* Yes, this is an alias */
+ AML_DEBUGPRINT(")");
+ /* shut the interpreter up during the namespace initializing */
+ return (NULL);
+ case 0x08: /* NameOp */
+ AML_DEBUGPRINT("Name(");
+ name = aml_parse_namestring(env);
+ aml_print_namestring(name);
+ AML_CREATE_NAME(aname, env, name, NULL);
+ if (env->stat == aml_stat_panic) {
+ AML_DEBUGPRINT("Already Defined \n");
+ aml_print_curname(aname);
+ return (NULL);
+ }
+ AML_DEBUGPRINT(", ");
+ AML_COPY_OBJECT(aname->property, env,
+ aml_eval_name(env,
+ aml_parse_termobj(env, indent)),
+ NULL);
+ AML_DEBUGPRINT(")");
+ break;
+ case 0x10: /* ScopeOp */
+ aml_parse_defscope(env, indent);
+ break;
+ case 0x11: /* BufferOp */
+ aname = &env->tempname;
+ aname->property = aml_parse_defbuffer(env, indent);
+ break;
+ case 0x12: /* PackageOp */
+ aname = &env->tempname;
+ aname->property = aml_parse_defpackage(env, indent);
+ break;
+ case 0x14: /* MethodOp */
+ aml_parse_defmethod(env, indent);
+ break;
+ case 0x5b: /* ExtOpPrefix */
+ opcode = *env->dp++;
+ switch (opcode) {
+ case 0x01:
+ aml_parse_defmutex(env, indent);
+ break;
+ case 0x02: /* EventOp */
+ AML_DEBUGPRINT("Event(");
+ name = aml_parse_namestring(env);
+ aml_print_namestring(name);
+ AML_CREATE_NAME(aname, env, name, NULL);
+ if (aname->property != NULL) {
+ env->stat = aml_stat_panic;
+ AML_DEBUGPRINT("Already Defined \n");
+ return (NULL);
+ }
+ AML_ALLOC_OBJECT(aname->property, env, aml_t_event, NULL);
+ AML_DEBUGPRINT(")");
+ return (NULL);
+ break;
+ case 0x12: /* CondRefOfOp */
+ AML_DEBUGPRINT("CondRefOf(");
+ src = aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(", ");
+ if (src == &env->tempname || src == NULL) {
+ aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(")");
+ anum.num.number = 0xffffffff;
+ env->tempobject.num = anum.num;
+ aname = &env->tempname;
+ break;
+ }
+ AML_ALLOC_OBJECT(objref, env, aml_t_objref, NULL);
+ if (src->property == NULL ||
+ src->property->type != aml_t_namestr) {
+ objref->objref.nameref = src;
+ } else {
+ objref->objref.nameref = aml_create_local_object();
+ }
+ objref->objref.ref = src->property;
+ objref->objref.offset = -1; /* different from IndexOp */
+
+ destname1 = aml_parse_termobj(env, indent);
+ aml_store_to_name(env, objref, destname1);
+ anum.num.number = 0;
+ env->tempobject.num = anum.num;
+ aname = &env->tempname;
+ AML_DEBUGPRINT(")");
+ break;
+ case 0x13:
+ aml_parse_defcreatefield(env, indent);
+ break;
+ case 0x20: /* LoadOp *//* XXX Not Impremented */
+ AML_DEBUGPRINT("Load(");
+ aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(", ");
+ aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(")");
+ break;
+ case 0x21: /* StallOp */
+ AML_DEBUGPRINT("Stall(");
+ num1 = aml_objtonum(env, aml_eval_name(env,
+ aml_parse_termobj(env, indent)));
+ AML_DEBUGPRINT(")");
+ AML_STALL(num1);
+ break;
+ case 0x22: /* SleepOp */
+ AML_DEBUGPRINT("Sleep(");
+ num1 = aml_objtonum(env, aml_eval_name(env,
+ aml_parse_termobj(env, indent)));
+ AML_SLEEP(0, num1);
+ AML_DEBUGPRINT(")");
+ break;
+ case 0x23: /* AcquireOp *//* XXX Not yet */
+ AML_DEBUGPRINT("Acquire(");
+ aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(", 0x%x)", aml_parse_worddata(env));
+ break;
+ case 0x24: /* SignalOp *//* XXX Not yet */
+ AML_DEBUGPRINT("Signal(");
+ aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(")");
+ break;
+ case 0x25: /* WaitOp *//* XXX Not yet impremented */
+ AML_DEBUGPRINT("Wait(");
+ aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(", ");
+ aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(")");
+ break;
+ case 0x26: /* ResetOp *//* XXX Not yet impremented */
+ AML_DEBUGPRINT("Reset(");
+ aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(")");
+ break;
+ case 0x27: /* ReleaseOp *//* XXX Not yet impremented */
+ AML_DEBUGPRINT("Release(");
+ aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(")");
+ break;
+#define NUMOP2(opname, operation) do { \
+ AML_DEBUGPRINT(opname); \
+ AML_DEBUGPRINT("("); \
+ num1 = aml_objtonum(env, aml_eval_name(env, \
+ aml_parse_termobj(env, indent))); \
+ AML_DEBUGPRINT(", "); \
+ anum.num.number = operation (num1); \
+ destname1 = aml_parse_termobj(env, indent); \
+ AML_DEBUGPRINT(")"); \
+ aml_store_to_name(env, &anum, destname1); \
+ env->tempobject.num = anum.num; \
+ env->tempname.property = &env->tempobject; \
+ aname = &env->tempname; \
+} while(0)
+
+ case 0x28: /* FromBCDOp */
+ NUMOP2("FromBCD", frombcd);
+ break;
+ case 0x29: /* ToBCDOp */
+ NUMOP2("ToBCD", tobcd);
+ break;
+ case 0x2a: /* UnloadOp *//* XXX Not yet impremented */
+ AML_DEBUGPRINT("Unload(");
+ aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(")");
+ break;
+ case 0x30:
+ env->tempobject.type = aml_t_num;
+ env->tempobject.num.number = 0;
+ env->tempobject.num.constant = 1;
+ AML_DEBUGPRINT("Revision");
+ break;
+ case 0x31:
+ env->tempobject.type = aml_t_debug;
+ aname = &env->tempname;
+ AML_DEBUGPRINT("Debug");
+ break;
+ case 0x32: /* FatalOp */
+ AML_DEBUGPRINT("Fatal(");
+ AML_DEBUGPRINT("0x%x, ", aml_parse_bytedata(env));
+ AML_DEBUGPRINT("0x%x, ", aml_parse_dworddata(env));
+ aml_parse_termobj(env, indent);
+ env->stat = aml_stat_panic;
+ AML_DEBUGPRINT(")");
+ break;
+ case 0x80: /* OpRegionOp */
+ aml_parse_defopregion(env, indent);
+ break;
+ case 0x81: /* FieldOp */
+ aml_parse_deffield(env, indent);
+ break;
+ case 0x82: /* DeviceOp */
+ aml_parse_defdevice(env, indent);
+ break;
+ case 0x83: /* ProcessorOp */
+ aml_parse_defprocessor(env, indent);
+ break;
+ case 0x84: /* PowerResOp */
+ aml_parse_defpowerres(env, indent);
+ break;
+ case 0x85: /* ThermalZoneOp */
+ aml_parse_defthermalzone(env, indent);
+ break;
+ case 0x86: /* IndexFieldOp */
+ aml_parse_defindexfield(env, indent);
+ break;
+ case 0x87: /* BankFieldOp */
+ aml_parse_defbankfield(env, indent);
+ break;
+ default:
+ AML_SYSERRX(1, "strange opcode 0x5b, 0x%x\n", opcode);
+ AML_SYSABORT();
+ }
+ break;
+ case 0x68 ... 0x6e: /* ArgN */
+ AML_DEBUGPRINT("Arg%d", opcode - 0x68);
+ return (aml_local_stack_getArgX(NULL, opcode - 0x68));
+ break;
+ case 0x60 ... 0x67:
+ AML_DEBUGPRINT("Local%d", opcode - 0x60);
+ return (aml_local_stack_getLocalX(opcode - 0x60));
+ break;
+ case 0x70: /* StoreOp */
+ AML_DEBUGPRINT("Store(");
+ aname = aml_create_local_object();
+ AML_COPY_OBJECT(tmpobj, env,
+ aml_eval_name(env, aml_parse_termobj(env, indent)), NULL);
+ aname->property = tmpobj;
+ AML_DEBUGPRINT(", ");
+ destname1 = aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(")");
+ /* XXX
+ * temporary object may change during aml_store_to_name()
+ * operation, so we make a copy of it on stack.
+ */
+ if (destname1 == &env->tempname &&
+ destname1->property == &env->tempobject) {
+ destname1 = aml_create_local_object();
+ AML_COPY_OBJECT(destname1->property, env,
+ &env->tempobject, NULL);
+ }
+ aml_store_to_name(env, tmpobj, destname1);
+ if (env->stat == aml_stat_panic) {
+ AML_DEBUGPRINT("StoreOp failed");
+ return (NULL);
+ }
+ aname = aml_create_local_object();
+ AML_COPY_OBJECT(tmpobj, env, destname1->property, NULL);
+ aname->property = tmpobj;
+ if (tmpobj == NULL) {
+ printf("???");
+ break;
+ }
+ break;
+ case 0x71: /* RefOfOp */
+ AML_DEBUGPRINT("RefOf(");
+ src = aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(")");
+
+ aname = aml_create_local_object();
+ AML_ALLOC_OBJECT(aname->property, env, aml_t_objref, NULL);
+ objref = aname->property;
+ if (src->property == NULL ||
+ src->property->type != aml_t_namestr) {
+ objref->objref.nameref = src;
+ } else {
+ objref->objref.nameref = aml_create_local_object();
+ }
+ objref->objref.ref = src->property;
+ objref->objref.offset = -1; /* different from IndexOp */
+ break;
+
+#define NUMOP3_2(opname, oparation, ope2) do { \
+ AML_DEBUGPRINT(opname); \
+ AML_DEBUGPRINT("("); \
+ num1 = aml_objtonum(env, aml_eval_name(env, \
+ aml_parse_termobj(env, indent))); \
+ AML_DEBUGPRINT(", "); \
+ num2 = aml_objtonum(env, aml_eval_name(env, \
+ aml_parse_termobj(env, indent))); \
+ AML_DEBUGPRINT(", "); \
+ anum.num.number = ope2(num1 oparation num2); \
+ destname1 = aml_parse_termobj(env, indent); \
+ AML_DEBUGPRINT(")"); \
+ aml_store_to_name(env, &anum, destname1); \
+ env->tempobject.num = anum.num; \
+ env->tempname.property = &env->tempobject; \
+ aname = &env->tempname; \
+} while(0)
+
+#define NUMOP3(opname, operation) NUMOP3_2(opname, operation, )
+#define NUMOPN3(opname, operation) NUMOP3_2(opname, operation, ~)
+
+ case 0x72: /* AddOp */
+ NUMOP3("Add", +);
+ break;
+ case 0x73: /* ConcatOp */
+ aname = aml_parse_concatop(env, indent);
+ break;
+ case 0x74: /* SubtractOp */
+ NUMOP3("Subtract", -);
+ break;
+ case 0x75: /* IncrementOp */
+ AML_DEBUGPRINT("Increment(");
+ aname = aml_parse_termobj(env, indent);
+ num1 = aml_objtonum(env, aml_eval_name(env, aname));
+ num1++;
+ anum.num.number = num1;
+ AML_DEBUGPRINT(")");
+ aml_store_to_name(env, &anum, aname);
+ aname = &env->tempname;
+ env->tempobject.num = anum.num;
+ break;
+ case 0x76: /* DecrementOp */
+ AML_DEBUGPRINT("Decrement(");
+ aname = aml_parse_termobj(env, indent);
+ num1 = aml_objtonum(env, aml_eval_name(env, aname));
+ num1--;
+ anum.num.number = num1;
+ AML_DEBUGPRINT(")");
+ aml_store_to_name(env, &anum, aname);
+ aname = &env->tempname;
+ env->tempobject.num = anum.num;
+ break;
+ case 0x77: /* MultiplyOp */
+ NUMOP3("Multiply", *);
+ break;
+ case 0x78: /* DivideOp */
+ AML_DEBUGPRINT("Divide(");
+ num1 = aml_objtonum(env, aml_eval_name(env,
+ aml_parse_termobj(env, indent)));
+ AML_DEBUGPRINT(", ");
+ num2 = aml_objtonum(env, aml_eval_name(env,
+ aml_parse_termobj(env, indent)));
+ AML_DEBUGPRINT(", ");
+ anum.num.number = num1 % num2;
+ destname1 = aml_parse_termobj(env, indent);
+ aml_store_to_name(env, &anum, destname1);
+ AML_DEBUGPRINT(", ");
+ anum.num.number = num1 / num2;
+ destname2 = aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(")");
+ aml_store_to_name(env, &anum, destname2);
+ env->tempobject.num = anum.num;
+ aname = &env->tempname;
+ break;
+ case 0x79: /* ShiftLeftOp */
+ NUMOP3("ShiftLeft", <<);
+ break;
+ case 0x7a: /* ShiftRightOp */
+ NUMOP3("ShiftRight", >>);
+ break;
+ case 0x7b: /* AndOp */
+ NUMOP3("And", &);
+ break;
+ case 0x7c: /* NAndOp */
+ NUMOPN3("NAnd", &);
+ break;
+ case 0x7d: /* OrOp */
+ NUMOP3("Or", |);
+ break;
+ case 0x7e: /* NOrOp */
+ NUMOPN3("NOr", |);
+ break;
+ case 0x7f: /* XOrOp */
+ NUMOP3("XOr", ^);
+ break;
+ case 0x80: /* NotOp */
+ NUMOP2("Not", ~);
+ break;
+ case 0x81: /* FindSetLeftBitOp */
+ NUMOP2("FindSetLeftBit", findsetleftbit);
+ break;
+ case 0x82: /* FindSetRightBitOp */
+ NUMOP2("FindSetRightBit", findsetrightbit);
+ break;
+ case 0x83: /* DerefOp */
+ AML_DEBUGPRINT("DerefOf(");
+ objref = aml_eval_name(env, aml_parse_termobj(env, indent));
+ AML_DEBUGPRINT(")");
+
+ if (objref->objref.ref == NULL) {
+ env->tempname.property = objref->objref.ref;
+ aname = &env->tempname;
+ break;
+ }
+ switch (objref->objref.ref->type) {
+ case aml_t_package:
+ case aml_t_buffer:
+ if (objref->objref.offset < 0) {
+ env->tempname.property = objref->objref.ref;
+ } else {
+ objref->objref.deref = 1;
+ env->tempname.property = objref;
+ }
+ break;
+ default:
+ env->tempname.property = objref->objref.ref;
+ break;
+ }
+
+ aname = &env->tempname;
+ break;
+ case 0x86: /* NotifyOp *//* XXX Not yet impremented */
+ AML_DEBUGPRINT("Notify(");
+ aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(", ");
+ aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(")");
+ break;
+ case 0x87: /* SizeOfOp */
+ AML_DEBUGPRINT("SizeOf(");
+ aname = aml_parse_termobj(env, indent);
+ tmpobj = aml_eval_name(env, aname);
+
+ AML_DEBUGPRINT(")");
+ num1 = 0;
+ switch (tmpobj->type) {
+ case aml_t_buffer:
+ num1 = tmpobj->buffer.size;
+ break;
+ case aml_t_string:
+ num1 = strlen(tmpobj->str.string);
+ break;
+ case aml_t_package:
+ num1 = tmpobj->package.elements;
+ break;
+ default:
+ AML_DEBUGPRINT("Args of SizeOf should be "
+ "buffer/string/package only\n");
+ break;
+ }
+
+ anum.num.number = num1;
+ env->tempobject.num = anum.num;
+ aname = &env->tempname;
+ break;
+ case 0x88: /* IndexOp */
+ AML_DEBUGPRINT("Index(");
+ srcobj = aml_eval_name(env, aml_parse_termobj(env, indent));
+ AML_DEBUGPRINT(", ");
+ num1 = aml_objtonum(env, aml_eval_name(env,
+ aml_parse_termobj(env, indent)));
+ AML_DEBUGPRINT(", ");
+ destname1 = aml_parse_termobj(env, indent);
+ AML_DEBUGPRINT(")");
+ aname = aml_create_local_object();
+ switch (srcobj->type) {
+ case aml_t_package:
+ case aml_t_buffer:
+ AML_ALLOC_OBJECT(objref, env, aml_t_objref, NULL);
+ aname->property = objref;
+ objref->objref.ref = srcobj;
+ objref->objref.offset = num1;
+ objref->objref.deref = 0;
+ break;
+ default:
+ AML_DEBUGPRINT("Arg0 of Index should be either "
+ "buffer or package\n");
+ return (aname);
+ }
+
+ aml_store_to_name(env, objref, destname1);
+ break;
+ case 0x89: /* MatchOp *//* XXX Not yet Impremented */
+ AML_DEBUGPRINT("Match(");
+ AML_COPY_OBJECT(obj, env, aml_eval_name(env,
+ aml_parse_termobj(env, indent)), NULL);
+ if (obj->type != aml_t_package) {
+ env->stat = aml_stat_panic;
+ return (NULL);
+ }
+ anum.num.number = 0xffffffff;
+ match1 = *env->dp;
+ AML_DEBUGPRINT(", %d", *env->dp);
+ env->dp++;
+ num1 = aml_objtonum(env, aml_eval_name(env,
+ aml_parse_termobj(env, indent)));
+ match2 = *env->dp;
+ AML_DEBUGPRINT(", %d", *env->dp);
+ env->dp++;
+ num2 = aml_objtonum(env, aml_eval_name(env,
+ aml_parse_termobj(env, indent)));
+ AML_DEBUGPRINT(", ");
+ start = aml_objtonum(env, aml_eval_name(env,
+ aml_parse_termobj(env, indent)));
+
+#define MATCHOP(opnum, arg1, arg2) ((opnum == 0) ? (1) : \
+ (opnum == 1) ? ((arg1) == (arg2)) : \
+ (opnum == 2) ? ((arg1) <= (arg2)) : \
+ (opnum == 3) ? ((arg1) < (arg2)) : \
+ (opnum == 4) ? ((arg1) >= (arg2)) : \
+ (opnum == 5) ? ((arg1) > (arg2)) : 0 )
+
+ for (i = start; i < obj->package.elements; i++) {
+ pkgval = aml_objtonum(env, obj->package.objects[i]);
+ if (MATCHOP(match1, pkgval, num1) &&
+ MATCHOP(match2, pkgval, num2)) {
+ anum.num.number = i;
+ break;
+ }
+ }
+ AML_DEBUGPRINT(")");
+ aml_free_object(&obj);
+ aname = &env->tempname;
+ env->tempname.property = &env->tempobject;
+ env->tempobject.num = anum.num;
+ break;
+#undef MATCHOP
+ case 0x8a ... 0x8d: /* CreateDWordFieldOp */
+ widthindex = *(env->dp - 1) - 0x8a;
+ AML_DEBUGPRINT("%s(", opname[widthindex]);
+ srcbuf = aml_eval_name(env, aml_parse_termobj(env, indent));
+ if (srcbuf == &env->tempobject) {
+ AML_DEBUGPRINT("NOT NAMEDBUF\n");
+ env->stat = aml_stat_panic;
+ return (NULL);
+ }
+ AML_DEBUGPRINT(", ");
+ index = aml_objtonum(env, aml_eval_name(env,
+ aml_parse_termobj(env, indent)));
+ if (widthindex != 3) {
+ index *= 8;
+ }
+ AML_DEBUGPRINT(", ");
+ newname = aml_parse_namestring(env);
+ aml_print_namestring(newname);
+ aml_createfield_generic(env, srcbuf, index,
+ widthtbl[widthindex], newname);
+ AML_DEBUGPRINT(")");
+ break;
+ case 0x8e: /* ObjectTypeOp */
+ AML_DEBUGPRINT("ObjectType(");
+ aname = aml_parse_termobj(env, indent);
+ if (aname == NULL) {
+ env->tempobject.type = aml_t_num;
+ env->tempobject.num.number = aml_t_null;
+ } else {
+ env->tempobject.type = aml_t_num;
+ env->tempobject.num.number = aname->property->type;
+ }
+ aname = &env->tempname;
+ AML_DEBUGPRINT(")");
+ break;
+
+#define CMPOP(opname,operation) do { \
+ AML_DEBUGPRINT(opname); \
+ AML_DEBUGPRINT("("); \
+ num1 = aml_objtonum(env, aml_eval_name(env, \
+ aml_parse_termobj(env, indent))); \
+ AML_DEBUGPRINT(", "); \
+ num2 = aml_objtonum(env, aml_eval_name(env, \
+ aml_parse_termobj(env, indent))); \
+ aname = &env->tempname; \
+ env->tempobject.type = aml_t_num; \
+ env->tempobject.num.number = (num1 operation num2) ? 0xffffffff : 0; \
+ aname->property = &env->tempobject; \
+ AML_DEBUGPRINT(")"); \
+} while(0)
+
+ case 0x90:
+ CMPOP("LAnd", &&);
+ break;
+ case 0x91:
+ CMPOP("LOr", ||);
+ break;
+ case 0x92:
+ AML_DEBUGPRINT("LNot(");
+ num1 = aml_objtonum(env, aml_eval_name(env,
+ aml_parse_termobj(env, indent)));
+ aname = &env->tempname;
+ env->tempobject.type = aml_t_num;
+ env->tempobject.num.number = (!num1) ? 0xffffffff : 0;
+ aname->property = &env->tempobject;
+ AML_DEBUGPRINT(")");
+ break;
+ case 0x93:
+ CMPOP("LEqual", ==);
+ break;
+ case 0x94:
+ CMPOP("LGreater", >);
+ break;
+ case 0x95:
+ CMPOP("LLess", <);
+ break;
+ case 0xa0: /* IfOp */
+ aname = aml_parse_defif(env, indent);
+ break;
+#if 0
+
+ case 0xa1: /* ElseOp should not be treated in Main parser
+ * But If Op */
+ aml_parse_defelse(env, indent);
+ break;
+#endif
+ case 0xa2: /* WhileOp */
+ aname = aml_parse_defwhile(env, indent);
+ break;
+ case 0xa3: /* NoopOp */
+ AML_DEBUGPRINT("Noop");
+ break;
+ case 0xa5: /* BreakOp */
+ AML_DEBUGPRINT("Break");
+ env->stat = aml_stat_break;
+ break;
+ case 0xa4: /* ReturnOp */
+ AML_DEBUGPRINT("Return(");
+ AML_COPY_OBJECT(env->tempname.property, env, aml_eval_name(env,
+ aml_parse_termobj(env, indent)), NULL);
+ aname = &env->tempname;
+ env->stat = aml_stat_return;
+ AML_DEBUGPRINT(")");
+ break;
+ case 0xcc: /* BreakPointOp */
+ /* XXX Not Yet Impremented (Not need?) */
+ AML_DEBUGPRINT("BreakPoint");
+ break;
+ default:
+ AML_SYSERRX(1, "strange opcode 0x%x\n", opcode);
+ AML_SYSABORT();
+ }
+
+ return (aname);
+}
diff --git a/usr.sbin/acpidump/aml/aml_parse.h b/usr.sbin/acpidump/aml/aml_parse.h
new file mode 100644
index 00000000000..b9b55b3eb5c
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_parse.h
@@ -0,0 +1,37 @@
+/* $OpenBSD: aml_parse.h,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999 Doug Rabson
+ * 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_parse.h,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_parse.h,v 1.1 2000/08/24 09:33:08 takawata Exp $
+ */
+
+#ifndef _AML_PARSE_H_
+#define _AML_PARSE_H_
+
+struct aml_name *aml_parse_objectlist(struct aml_environ *, int);
+struct aml_name *aml_parse_termobj(struct aml_environ *, int);
+
+#endif /* !_AML_PARSE_H_ */
diff --git a/usr.sbin/acpidump/aml/aml_region.h b/usr.sbin/acpidump/aml/aml_region.h
new file mode 100644
index 00000000000..97c78cfabc4
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_region.h
@@ -0,0 +1,93 @@
+/* $OpenBSD: aml_region.h,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * 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_region.h,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_region.h,v 1.2 2000/09/20 01:01:27 iwasaki Exp $
+ */
+
+#ifndef _AML_REGION_H_
+#define _AML_REGION_H_
+
+/*
+ * Note that common part of region I/O is implemented in aml_common.c.
+ */
+
+/*
+ * Debug macros for region I/O
+ */
+
+#define AML_REGION_READ_DEBUG(regtype, flags, addr, bitoffset, bitlen) \
+ AML_DEBUGPRINT("\n[aml_region_read(%d, %d, 0x%x, 0x%x, 0x%x)]\n",\
+ regtype, flags, addr, bitoffset, bitlen)
+
+#define AML_REGION_READ_INTO_BUFFER_DEBUG(regtype, flags, \
+ addr, bitoffset, bitlen) \
+ AML_DEBUGPRINT("\n[aml_region_read_into_buffer(%d, %d, 0x%x, 0x%x, 0x%x)]\n",\
+ regtype, flags, addr, bitoffset, bitlen)
+
+#define AML_REGION_WRITE_DEBUG(regtype, flags, value, \
+ addr, bitoffset, bitlen) \
+ AML_DEBUGPRINT("\n[aml_region_write(%d, %d, 0x%x, 0x%x, 0x%x, 0x%x)]\n",\
+ regtype, flags, value, addr, bitoffset, bitlen)
+
+#define AML_REGION_WRITE_FROM_BUFFER_DEBUG(regtype, flags, \
+ addr, bitoffset, bitlen) \
+ AML_DEBUGPRINT("\n[aml_region_write_from_buffer(%d, %d, 0x%x, 0x%x, 0x%x)]\n",\
+ regtype, flags, addr, bitoffset, bitlen)
+
+#define AML_REGION_BCOPY_DEBUG(regtype, flags, addr, bitoffset, bitlen, \
+ dflags, daddr, dbitoffset, dbitlen) \
+ AML_DEBUGPRINT("\n[aml_region_bcopy(%d, %d, 0x%x, 0x%x, 0x%x, %d, 0x%x, 0x%x, 0x%x)]\n",\
+ regtype, flags, addr, bitoffset, bitlen, \
+ dflags, daddr, dbitoffset, dbitlen)
+
+/*
+ * Region I/O subroutine
+ */
+
+struct aml_environ;
+
+u_int32_t aml_region_read(struct aml_environ *, int, u_int32_t,
+ u_int32_t, u_int32_t, u_int32_t);
+int aml_region_write(struct aml_environ *, int, u_int32_t,
+ u_int32_t, u_int32_t, u_int32_t, u_int32_t);
+int aml_region_read_into_buffer(struct aml_environ *, int,
+ u_int32_t, u_int32_t, u_int32_t,
+ u_int32_t, u_int8_t *);
+int aml_region_write_from_buffer(struct aml_environ *, int,
+ u_int32_t, u_int8_t *, u_int32_t,
+ u_int32_t, u_int32_t);
+int aml_region_bcopy(struct aml_environ *, int,
+ u_int32_t, u_int32_t, u_int32_t, u_int32_t,
+ u_int32_t, u_int32_t, u_int32_t, u_int32_t);
+
+#ifndef _KERNEL
+void aml_simulation_regdump(const char *);
+extern int aml_debug_prompt_regoutput;
+extern int aml_debug_prompt_reginput;
+#endif /* !_KERNEL */
+
+#endif /* !_AML_REGION_H_ */
diff --git a/usr.sbin/acpidump/aml/aml_status.h b/usr.sbin/acpidump/aml/aml_status.h
new file mode 100644
index 00000000000..d6d09be618a
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_status.h
@@ -0,0 +1,42 @@
+/* $OpenBSD: aml_status.h,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999 Takanori Watanabe
+ * 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_status.h,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_status.h,v 1.1 2000/08/24 09:33:08 takawata Exp $
+ */
+
+#ifndef _AML_STATUS_H_
+#define _AML_STATUS_H_
+
+enum aml_status {
+ aml_stat_none = 0,
+ aml_stat_return,
+ aml_stat_break,
+ aml_stat_panic,
+ aml_stat_step
+};
+
+#endif /* !_AML_STATUS_H_ */
diff --git a/usr.sbin/acpidump/aml/aml_store.c b/usr.sbin/acpidump/aml/aml_store.c
new file mode 100644
index 00000000000..0fcae246eff
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_store.c
@@ -0,0 +1,350 @@
+/* $OpenBSD: aml_store.c,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999 Takanori Watanabe
+ * Copyright (c) 1999, 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_store.c,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_store.c,v 1.3 2000/11/09 06:24:45 iwasaki Exp $
+ */
+
+#include <sys/types.h>
+
+#include <aml/aml_amlmem.h>
+#include <aml/aml_common.h>
+#include <aml/aml_env.h>
+#include <aml/aml_evalobj.h>
+#include <aml/aml_name.h>
+#include <aml/aml_obj.h>
+#include <aml/aml_region.h>
+#include <aml/aml_status.h>
+#include <aml/aml_store.h>
+
+#ifndef _KERNEL
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "debug.h"
+#else /* _KERNEL */
+#include <sys/systm.h>
+#endif /* !_KERNEL */
+
+static void
+aml_store_to_fieldname(struct aml_environ *env, union aml_object *obj,
+ struct aml_name *name)
+{
+ char *buffer;
+ struct aml_name *wname, *oname, *iname;
+ struct aml_field *field;
+ struct aml_opregion *or;
+ union aml_object tobj, iobj, *tmpobj;
+
+ field = &name->property->field;
+ oname = env->curname;
+ iname = NULL;
+ env->curname = name->parent;
+ if (field->f.ftype == f_t_field) {
+ wname = aml_search_name(env, field->f.fld.regname);
+ if (wname == NULL ||
+ wname->property == NULL ||
+ wname->property->type != aml_t_opregion) {
+ AML_DEBUGPRINT("Inappropreate Type\n");
+ env->stat = aml_stat_panic;
+ env->curname = oname;
+ return;
+ }
+ or = &wname->property->opregion;
+ switch (obj->type) {
+ case aml_t_num:
+ aml_region_write(env, or->space, field->flags,
+ obj->num.number, or->offset,
+ field->bitoffset, field->bitlen);
+ AML_DEBUGPRINT("[write(%d, 0x%x, 0x%x)]",
+ or->space, obj->num.number,
+ or->offset + field->bitoffset / 8);
+ break;
+ case aml_t_buffer:
+ case aml_t_bufferfield:
+ if (obj->type == aml_t_buffer) {
+ buffer = obj->buffer.data;
+ } else {
+ buffer = obj->bfld.origin;
+ buffer += obj->bfld.bitoffset / 8;
+ }
+ aml_region_write_from_buffer(env, or->space,
+ field->flags, buffer, or->offset, field->bitoffset,
+ field->bitlen);
+ break;
+ case aml_t_regfield:
+ if (or->space != obj->regfield.space) {
+ AML_DEBUGPRINT("aml_store_to_fieldname: "
+ "Different type of space\n");
+ break;
+ }
+ aml_region_bcopy(env, obj->regfield.space,
+ obj->regfield.flags, obj->regfield.offset,
+ obj->regfield.bitoffset, obj->regfield.bitlen,
+ field->flags, or->offset, field->bitoffset,
+ field->bitlen);
+ break;
+ default:
+ AML_DEBUGPRINT("aml_store_to_fieldname: "
+ "Inappropreate Type of src object\n");
+ break;
+ }
+ } else if (field->f.ftype == f_t_index) {
+ iname = aml_search_name(env, field->f.ifld.indexname);
+ wname = aml_search_name(env, field->f.ifld.dataname);
+ iobj.type = aml_t_num;
+ iobj.num.number = field->bitoffset / 8; /* AccessType Boundary */
+
+ /* read whole values of IndexField */
+ aml_store_to_name(env, &iobj, iname);
+ tmpobj = aml_eval_name(env, wname);
+
+ /* make the values to be written */
+ tobj.num = obj->num;
+ tobj.num.number = aml_adjust_updatevalue(field->flags,
+ field->bitoffset & 7, field->bitlen,
+ tmpobj->num.number, obj->num.number);
+
+ /* write the values to IndexField */
+ aml_store_to_name(env, &iobj, iname);
+ aml_store_to_name(env, &tobj, wname);
+ }
+ env->curname = oname;
+}
+
+static void
+aml_store_to_buffer(struct aml_environ *env, union aml_object *obj,
+ union aml_object *buf, int offset)
+{
+ int size;
+ int bitlen;
+
+ switch (obj->type) {
+ case aml_t_num:
+ if (offset > buf->buffer.size) {
+ aml_realloc_object(buf, offset);
+ }
+ buf->buffer.data[offset] = obj->num.number & 0xff;
+ AML_DEBUGPRINT("[Store number 0x%x to buffer]",
+ obj->num.number & 0xff);
+ break;
+ case aml_t_string:
+ size = strlen(obj->str.string);
+ if (buf->buffer.size - offset < size) {
+ aml_realloc_object(buf, offset + size + 1);
+ }
+ strcpy(&buf->buffer.data[offset], obj->str.string);
+ AML_DEBUGPRINT("[Store string to buffer]");
+ break;
+ case aml_t_buffer:
+ bzero(buf->buffer.data, buf->buffer.size);
+ if (obj->buffer.size > buf->buffer.size) {
+ size = buf->buffer.size;
+ } else {
+ size = obj->buffer.size;
+ }
+ bcopy(obj->buffer.data, buf->buffer.data, size);
+ break;
+ case aml_t_regfield:
+ bitlen = (buf->buffer.size - offset) * 8;
+ if (bitlen > obj->regfield.bitlen) {
+ bitlen = obj->regfield.bitlen;
+ }
+ aml_region_read_into_buffer(env, obj->regfield.space,
+ obj->regfield.flags, obj->regfield.offset,
+ obj->regfield.bitoffset, bitlen,
+ buf->buffer.data + offset);
+ break;
+ default:
+ goto not_yet;
+ }
+ return;
+not_yet:
+ AML_DEBUGPRINT("[XXX not supported yet]");
+}
+
+
+void
+aml_store_to_object(struct aml_environ *env, union aml_object *src,
+ union aml_object * dest)
+{
+ char *buffer, *srcbuf;
+ int offset, bitlen;
+
+ switch (dest->type) {
+ case aml_t_num:
+ if (src->type == aml_t_num) {
+ dest->num = src->num;
+ AML_DEBUGPRINT("[Store number 0x%x]", src->num.number);
+ } else {
+ env->stat = aml_stat_panic;
+ }
+ break;
+ case aml_t_string:
+ case aml_t_package:
+ break;
+ case aml_t_buffer:
+ aml_store_to_buffer(env, src, dest, 0);
+ break;
+ case aml_t_bufferfield:
+ buffer = dest->bfld.origin;
+ offset = dest->bfld.bitoffset;
+ bitlen = dest->bfld.bitlen;
+
+ switch (src->type) {
+ case aml_t_num:
+ if (aml_bufferfield_write(src->num.number, buffer, offset, bitlen)) {
+ AML_DEBUGPRINT("aml_bufferfield_write() failed\n");
+ }
+ break;
+ case aml_t_buffer:
+ case aml_t_bufferfield:
+ if (src->type == aml_t_buffer) {
+ srcbuf = src->buffer.data;
+ } else {
+ srcbuf = src->bfld.origin;
+ srcbuf += src->bfld.bitoffset / 8;
+ }
+ bcopy(srcbuf, buffer, bitlen / 8);
+ break;
+ case aml_t_regfield:
+ aml_region_read_into_buffer(env, src->regfield.space,
+ src->regfield.flags, src->regfield.offset,
+ src->regfield.bitoffset, src->regfield.bitlen,
+ buffer);
+ break;
+ default:
+ AML_DEBUGPRINT("not implemented yet");
+ break;
+ }
+ break;
+ case aml_t_debug:
+ aml_showobject(src);
+ break;
+ default:
+ AML_DEBUGPRINT("[Unimplemented %d]", dest->type);
+ break;
+ }
+}
+
+static void
+aml_store_to_objref(struct aml_environ *env, union aml_object *obj,
+ union aml_object *r)
+{
+ int offset;
+ union aml_object *ref;
+
+ if (r->objref.ref == NULL) {
+ r->objref.ref = aml_alloc_object(obj->type, NULL); /* XXX */
+ r->objref.nameref->property = r->objref.ref;
+ }
+ ref = r->objref.ref;
+
+ switch (ref->type) {
+ case aml_t_buffer:
+ offset = r->objref.offset;
+ aml_store_to_buffer(env, obj, ref, r->objref.offset);
+ break;
+ case aml_t_package:
+ offset = r->objref.offset;
+ if (r->objref.ref->package.elements < offset) {
+ aml_realloc_object(ref, offset);
+ }
+ if (ref->package.objects[offset] == NULL) {
+ ref->package.objects[offset] = aml_copy_object(env, obj);
+ } else {
+ aml_store_to_object(env, obj, ref->package.objects[offset]);
+ }
+ break;
+ default:
+ aml_store_to_object(env, obj, ref);
+ break;
+ }
+}
+
+/*
+ * Store to Named object
+ */
+void
+aml_store_to_name(struct aml_environ *env, union aml_object *obj,
+ struct aml_name *name)
+{
+ struct aml_name *wname;
+
+ if (env->stat == aml_stat_panic) {
+ return;
+ }
+ if (name == NULL || obj == NULL) {
+ AML_DEBUGPRINT("[Try to store no existant name ]");
+ return;
+ }
+ if (name->property == NULL) {
+ name->property = aml_copy_object(env, obj);
+ AML_DEBUGPRINT("[Copy number 0x%x]", obj->num.number);
+ return;
+ }
+ if (name->property->type == aml_t_namestr) {
+ wname = aml_search_name(env, name->property->nstr.dp);
+ name = wname;
+ }
+ if (name == NULL) {
+ env->stat = aml_stat_panic;
+ return;
+ }
+ if (name->property == NULL || name->property->type == aml_t_null) {
+ name->property = aml_copy_object(env, obj);
+ AML_DEBUGPRINT("[Copy number 0x%x]", obj->num.number);
+ return;
+ }
+ /* Writes to constant object are not allowed */
+ if (name->property != NULL && name->property->type == aml_t_num &&
+ name->property->num.constant == 1) {
+ return;
+ }
+ /* try to dereference */
+ if (obj->type == aml_t_objref && obj->objref.deref == 0) {
+ AML_DEBUGPRINT("Source object isn't dereferenced yet, "
+ "try to dereference anyway\n");
+ obj->objref.deref = 1;
+ obj = aml_eval_objref(env, obj);
+ }
+ switch (name->property->type) {
+ case aml_t_field:
+ aml_store_to_fieldname(env, obj, name);
+ break;
+ case aml_t_objref:
+ aml_store_to_objref(env, obj, name->property);
+ break;
+ case aml_t_num:
+ if (name == &env->tempname)
+ break;
+ default:
+ aml_store_to_object(env, obj, name->property);
+ break;
+ }
+}
diff --git a/usr.sbin/acpidump/aml/aml_store.h b/usr.sbin/acpidump/aml/aml_store.h
new file mode 100644
index 00000000000..7dbaf70b84e
--- /dev/null
+++ b/usr.sbin/acpidump/aml/aml_store.h
@@ -0,0 +1,40 @@
+/* $OpenBSD: aml_store.h,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999 Takanori Watanabe
+ * Copyright (c) 1999, 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_store.h,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_store.h,v 1.1 2000/08/24 09:33:08 takawata Exp $
+ */
+
+#ifndef _AML_STORE_H_
+#define _AML_STORE_H_
+
+void aml_store_to_name(struct aml_environ *, union aml_object *,
+ struct aml_name *);
+void aml_store_to_object(struct aml_environ *, union aml_object *,
+ union aml_object *);
+
+#endif /* _AML_STORE_H_ */
diff --git a/usr.sbin/acpidump/aml_dump.c b/usr.sbin/acpidump/aml_dump.c
new file mode 100644
index 00000000000..11acc4858e1
--- /dev/null
+++ b/usr.sbin/acpidump/aml_dump.c
@@ -0,0 +1,61 @@
+/* $OpenBSD: aml_dump.c,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * 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.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/acpidump/aml_dump.c,v 1.3 2000/11/08 02:37:00 iwasaki Exp $
+ */
+
+#include <sys/types.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);
+}
+
diff --git a/usr.sbin/acpidump/asl_dump.c b/usr.sbin/acpidump/asl_dump.c
new file mode 100644
index 00000000000..25cea02bb05
--- /dev/null
+++ b/usr.sbin/acpidump/asl_dump.c
@@ -0,0 +1,1281 @@
+/* $OpenBSD: asl_dump.c,v 1.1 2005/06/02 20:09:39 tholo 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.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/acpidump/asl_dump.c,v 1.5 2001/10/23 14:53:58 takawata Exp $
+ */
+
+#include <sys/param.h>
+
+#include <assert.h>
+#include <err.h>
+#include <stdio.h>
+
+#include "acpidump.h"
+
+#include "aml/aml_env.h"
+
+struct aml_environ asl_env;
+
+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_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);
+ printf(") {");
+ while (dp < end) {
+ printf("0x%x", *dp++);
+ if (dp < end)
+ printf(", ");
+ }
+ 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;
+}
diff --git a/usr.sbin/acpidump/debug.h b/usr.sbin/acpidump/debug.h
new file mode 100644
index 00000000000..db645ca1405
--- /dev/null
+++ b/usr.sbin/acpidump/debug.h
@@ -0,0 +1,37 @@
+/* $OpenBSD: debug.h,v 1.1 2005/06/02 20:09:39 tholo Exp $ */
+/*-
+ * Copyright (c) 1999 Takanori Watanabe
+ * Copyright (c) 1999, 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: debug.h,v 1.1 2005/06/02 20:09:39 tholo Exp $
+ * $FreeBSD: src/usr.sbin/acpi/amldb/debug.h,v 1.1.1.1 2000/08/31 14:45:00 iwasaki Exp $
+ */
+
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
+
+void aml_dbgr(struct aml_environ *, struct aml_environ *);
+
+#endif /* !_DEBUG_H_ */