acpica5 update part 3/3: Bring the usr.sbin/acpi tools into the base system
authorMatthew Dillon <dillon@dragonflybsd.org>
Mon, 5 Jul 2004 00:22:43 +0000 (00:22 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Mon, 5 Jul 2004 00:22:43 +0000 (00:22 +0000)
and integrate it into the build.

Submitted-by: YONETANI Tomokazu <qhwt+dragonfly-submit@les.ath.cx>
20 files changed:
etc/MAKEDEV
etc/rc.resume
etc/rc.suspend
usr.sbin/Makefile
usr.sbin/acpi/Makefile [new file with mode: 0644]
usr.sbin/acpi/Makefile.inc [new file with mode: 0644]
usr.sbin/acpi/acpiconf/Makefile [new file with mode: 0644]
usr.sbin/acpi/acpiconf/acpiconf.8 [new file with mode: 0644]
usr.sbin/acpi/acpiconf/acpiconf.c [new file with mode: 0644]
usr.sbin/acpi/acpidb/Makefile [new file with mode: 0644]
usr.sbin/acpi/acpidb/acpidb.8 [new file with mode: 0644]
usr.sbin/acpi/acpidb/acpidb.c [new file with mode: 0644]
usr.sbin/acpi/acpidump/Makefile [new file with mode: 0644]
usr.sbin/acpi/acpidump/acpi.c [new file with mode: 0644]
usr.sbin/acpi/acpidump/acpi_user.c [new file with mode: 0644]
usr.sbin/acpi/acpidump/acpidump.8 [new file with mode: 0644]
usr.sbin/acpi/acpidump/acpidump.c [new file with mode: 0644]
usr.sbin/acpi/acpidump/acpidump.h [new file with mode: 0644]
usr.sbin/acpi/iasl/Makefile [new file with mode: 0644]
usr.sbin/acpi/iasl/iasl.8 [new file with mode: 0644]

index d0d32ef..86fa2ea 100644 (file)
@@ -21,7 +21,7 @@
 #
 #      @(#)MAKEDEV     5.2 (Berkeley) 6/22/90
 # $FreeBSD: src/etc/MAKEDEV,v 1.243.2.57 2003/02/10 11:35:53 simokawa Exp $
-# $DragonFly: src/etc/MAKEDEV,v 1.8 2004/06/18 23:50:34 drhodus Exp $
+# $DragonFly: src/etc/MAKEDEV,v 1.9 2004/07/05 00:22:38 dillon Exp $
 #
 # Device "make" file.  Valid arguments:
 #      all     makes all known devices, standard number of units (or close)
 #      i4brbch* raw b channel access device(s)
 #
 # Special purpose devices:
+#      acpi    ACPI control device
 #      apm     Advanced Power Management BIOS
 #      apmctl  APM BIOS control device
 #      bpf*    packet filter
@@ -339,6 +340,7 @@ all)
        sh MAKEDEV ipl tun0 tun1 tun2 tun3              # cdev, network
        sh MAKEDEV tap0 tap1 tap2 tap3                  # cdev, network
        sh MAKEDEV ch0 perfmon tw0                      # cdev, miscellaneous
+       sh MAKEDEV acpi                                 # cdev, laptop
        sh MAKEDEV apm apmctl card0 card1 card2 card3   # cdev, laptop
        sh MAKEDEV pass4 xpt2                           # cdev, CAM
        sh MAKEDEV i4b i4bctl i4btrc0 i4btrc1           # cdev, ISDN
@@ -1609,6 +1611,10 @@ gsc*)
        chmod 666 gsc${unit}*
        ;;
 
+acpi)
+       mknod acpi c 152 0 root:operator
+       chmod 664 acpi
+       ;;
 apm)
        mknod apm c 39 0 root:operator
        chmod 664 apm
index 24d4891..69b940b 100644 (file)
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 #
-# $FreeBSD: src/etc/rc.resume,v 1.3.2.4 2001/03/06 02:22:00 obrien Exp $
-# $DragonFly: src/etc/rc.resume,v 1.2 2003/06/17 04:24:45 dillon Exp $
+# $FreeBSD: src/etc/rc.resume,v 1.7 2003/12/30 17:30:39 njl Exp $
+# $DragonFly: src/etc/rc.resume,v 1.3 2004/07/05 00:22:38 dillon Exp $
 #
 
 # sample run command file for APM Resume Event
 
+if [ $# -ne 2 ]; then
+       echo "Usage: $0 [apm|acpi] [standby,suspend|1-5]"
+       exit 1
+fi
+
+subsystem=$1
+state=$2
+
 if [ -r /var/run/rc.suspend.pid ]; then
        kill -9 `cat /var/run/rc.suspend.pid`
        rm -f /var/run/rc.suspend.pid
-       echo 'rc.suspend is killed'
+       echo 'rc.resume: killed rc.suspend that was still around'
 fi
 
 # Turns on a power supply of a card in the slot inactivated.
@@ -41,7 +49,11 @@ fi
 # pccardq | awk -F '~' '$5 == "inactive" \
 #      { printf("pccardc power %d 1", $1); }' | sh
 
-logger -t apmd resumed at `date +'%Y%m%d %H:%M:%S'`
+# UHCI has trouble resuming so we just load/unload it.  You
+# should add any other kernel modules you want reloaded here.
+# kldload usb
+
+logger -t $subsystem resumed at `date +'%Y%m%d %H:%M:%S'`
 sync && sync && sync
 
 exit 0
index cc91093..5cf22d9 100644 (file)
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 #
-# $FreeBSD: src/etc/rc.suspend,v 1.3.2.3 2001/03/06 02:22:00 obrien Exp $
-# $DragonFly: src/etc/rc.suspend,v 1.2 2003/06/17 04:24:45 dillon Exp $
+# $FreeBSD: src/etc/rc.suspend,v 1.6 2004/01/21 03:03:40 njl Exp $
+# $DragonFly: src/etc/rc.suspend,v 1.3 2004/07/05 00:22:38 dillon Exp $
 #
 
 # sample run command file for APM Suspend Event
 
+if [ $# -ne 2 ]; then
+       echo "Usage: $0 [apm|acpi] [standby,suspend|1-5]"
+       exit 1
+fi
+
+subsystem=$1
+state=$2
+
 if [ -r /var/run/rc.suspend.pid ]; then
        exit 1
 fi
 
-echo $$ > /var/run/rc.suspend.pid
+echo $$ 2> /dev/null > /var/run/rc.suspend.pid
 
 # If you have troubles on suspending with PC-CARD modem, try this.
 # See also contrib/pccardq.c (Only for PAO users).
 # pccardq | awk -F '~' '$5 == "filled" && $4 ~ /sio/ \
 #      { printf("pccardc power %d 0", $1); }' | sh
 
-logger -t apmd suspend at `date +'%Y%m%d %H:%M:%S'`
+# UHCI has trouble resuming so we just load/unload it.  You
+# should add any other kernel modules you want unloaded here.
+# kldunload usb
+
+logger -t $subsystem suspend at `date +'%Y%m%d %H:%M:%S'`
 sync && sync && sync
-sleep 3
+[ $subsystem = "apm" ] && sleep 3
 
 rm -f /var/run/rc.suspend.pid
-zzz
+[ $subsystem = "apm" ] && zzz
 
 exit 0
index 42d993e..4e30c55 100644 (file)
@@ -1,11 +1,12 @@
 #      From: @(#)Makefile      5.20 (Berkeley) 6/12/93
 # $FreeBSD: src/usr.sbin/Makefile,v 1.183.2.14 2003/04/16 11:01:51 ru Exp $
-# $DragonFly: src/usr.sbin/Makefile,v 1.10 2004/06/20 02:36:01 hmp Exp $
+# $DragonFly: src/usr.sbin/Makefile,v 1.11 2004/07/05 00:22:39 dillon Exp $
 
 # XXX MISSING:         mkproto
 SUBDIR=        IPXrouted \
        ac \
        accton \
+       acpi \
        adduser \
        amd \
        ancontrol \
diff --git a/usr.sbin/acpi/Makefile b/usr.sbin/acpi/Makefile
new file mode 100644 (file)
index 0000000..5006f51
--- /dev/null
@@ -0,0 +1,8 @@
+# Makefile for acpi tools
+# $Id: Makefile,v 1.1 2000/07/14 18:16:22 iwasaki Exp $
+# $FreeBSD: src/usr.sbin/acpi/Makefile,v 1.3 2003/08/08 03:20:59 njl Exp $
+# $DragonFly: src/usr.sbin/acpi/Makefile,v 1.1 2004/07/05 00:22:40 dillon Exp $
+
+SUBDIR= acpiconf acpidb acpidump iasl
+
+.include <bsd.subdir.mk>
diff --git a/usr.sbin/acpi/Makefile.inc b/usr.sbin/acpi/Makefile.inc
new file mode 100644 (file)
index 0000000..346705d
--- /dev/null
@@ -0,0 +1,58 @@
+# $Id: Makefile.inc,v 1.1 2000/07/14 18:16:22 iwasaki Exp $
+# $FreeBSD: src/usr.sbin/acpi/Makefile.inc,v 1.8 2003/08/07 16:51:50 njl Exp $
+# $DragonFly: src/usr.sbin/acpi/Makefile.inc,v 1.1 2004/07/05 00:22:40 dillon Exp $
+
+# XXX use /sys/dev/acpica5/Makefile.inc
+SYSDIR?= ${.CURDIR}/../../../sys
+OSACPI_DIR= ${SYSDIR}/dev/acpica5
+.include "${OSACPI_DIR}/Makefile.inc"
+ACPICA_DIR?=   ${SYSDIR}/${SYSACPICA}
+
+CFLAGS+= -I${.OBJDIR}          \
+       -I${SYSDIR}             \
+       -I${OSACPI_DIR}         \
+       -I${ACPICA_DIR}/include \
+       -I${ACPICA_DIR}/compiler
+
+.if exists(${.CURDIR}/../../Makefile.inc)
+.include "${.CURDIR}/../../Makefile.inc"
+.endif
+
+# XXX share this with /sys/dev/acpica5/Makefile.inc?
+.PATH: ${ACPICA_DIR}                           \
+       ${ACPICA_DIR}/compiler                  \
+       ${ACPICA_DIR}/common                    \
+       ${ACPICA_DIR}/debugger                  \
+       ${ACPICA_DIR}/disassembler              \
+       ${ACPICA_DIR}/events                    \
+       ${ACPICA_DIR}/include                   \
+       ${ACPICA_DIR}/hardware                  \
+       ${ACPICA_DIR}/interpreter/dispatcher    \
+       ${ACPICA_DIR}/interpreter/executer      \
+       ${ACPICA_DIR}/interpreter/parser        \
+       ${ACPICA_DIR}/namespace                 \
+       ${ACPICA_DIR}/resources                 \
+       ${ACPICA_DIR}/tables                    \
+       ${ACPICA_DIR}/utilities                 \
+       ${ACPICA_DIR}/EVENTS                    \
+       ${ACPICA_DIR}/HARDWARE                  \
+       ${ACPICA_DIR}/INTERPRETER/DISPATCHER    \
+       ${ACPICA_DIR}/INTERPRETER/EXECUTER      \
+       ${ACPICA_DIR}/INTERPRETER/PARSER        \
+       ${ACPICA_DIR}/NAMESPACE                 \
+       ${ACPICA_DIR}/TABLES                    \
+
+# acpi.h includes "platform/acenv.h".  This is the easiest way to create
+# a modified acenv.h
+#
+${.OBJDIR}/acpi.h: ${ACPICA_DIR}/include/acpi.h
+       cp ${.ALLSRC} ${.TARGET}
+
+${.OBJDIR}/platform/acenv.h: ${ACPICA_DIR}/include/platform/acenv.h
+       if [ ! -d ${.OBJDIR}/platform ]; then mkdir ${.OBJDIR}/platform; fi
+       cat ${.ALLSRC} | \
+       sed -e 's/__FreeBSD__/__DragonFly__/' | \
+       sed -e 's/acfreebsd.h/acdragonfly.h/' > ${.TARGET}.new
+       mv -f ${.TARGET}.new ${.TARGET}
+
+SRCS+= ${.OBJDIR}/acpi.h ${.OBJDIR}/platform/acenv.h
diff --git a/usr.sbin/acpi/acpiconf/Makefile b/usr.sbin/acpi/acpiconf/Makefile
new file mode 100644 (file)
index 0000000..4216f3e
--- /dev/null
@@ -0,0 +1,9 @@
+# $Id: Makefile,v 1.2 2000/07/14 18:16:25 iwasaki Exp $
+# $FreeBSD: src/usr.sbin/acpi/acpiconf/Makefile,v 1.4 2001/03/26 14:39:17 ru Exp $
+# $DragonFly: src/usr.sbin/acpi/acpiconf/Makefile,v 1.1 2004/07/05 00:22:43 dillon Exp $
+
+SRCS+= acpiconf.c
+PROG=  acpiconf
+MAN=   acpiconf.8
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/acpi/acpiconf/acpiconf.8 b/usr.sbin/acpi/acpiconf/acpiconf.8
new file mode 100644 (file)
index 0000000..54dbd29
--- /dev/null
@@ -0,0 +1,97 @@
+.\"-
+.\" Copyright (c) 2000 Dag-Erling Coïdan Smørgrav
+.\" 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
+.\"    in this position and unchanged.
+.\" 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.
+.\" 3. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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/acpiconf/acpiconf.8,v 1.13 2004/06/04 19:20:43 ru Exp $
+.\"      $DragonFly: src/usr.sbin/acpi/acpiconf/acpiconf.8,v 1.1 2004/07/05 00:22:43 dillon Exp $
+.\"
+.Dd January 12, 2001
+.Dt ACPICONF 8
+.Os
+.Sh NAME
+.Nm acpiconf
+.Nd control ACPI power management
+.Sh SYNOPSIS
+.Nm
+.Op Fl deh
+.Op Fl i Ar batt
+.Op Fl s Ar type
+.Sh DESCRIPTION
+The
+.Nm
+utility allows the user control of the ACPI power management
+functions.
+The following command-line options are recognized:
+.Bl -tag -width ".Fl s Ar type"
+.It Fl d
+Disables ACPI power management.
+.It Fl e
+Enables ACPI power management.
+.It Fl h
+Displays a summary of available options.
+.It Fl i Ar batt
+Get design information about the specified battery.
+.It Fl s Ar type
+Enters the specified sleep mode.
+Recognized types are
+.Cm 1
+(only the CPU clock is stopped),
+.Cm 2
+(not implemented on most systems but similar to S1),
+.Cm 3
+(the CPU context is lost and memory context is preserved),
+.Cm 4
+(the CPU context is lost and memory context is stored to disk)
+and
+.Cm 5
+(soft off).
+Sleep states may also be given as S1, S2, etc.
+The supported states depend on BIOS implementation, including ACPI
+byte code (AML).
+If the
+.Pa /etc/rc.suspend
+and
+.Pa /etc/rc.resume
+scripts are executable, they will be run before and after entering
+the given sleep state.
+.El
+.Sh SEE ALSO
+.Xr acpi 4 ,
+.Xr acpidump 8 ,
+.Xr apm 8
+.Sh HISTORY
+The
+.Nm
+utility appeared in
+.Fx 5.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+utility was written by
+.An Mitsuru Iwasaki Aq iwasaki@FreeBSD.org .
+This manual page was written by
+.An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org .
diff --git a/usr.sbin/acpi/acpiconf/acpiconf.c b/usr.sbin/acpi/acpiconf/acpiconf.c
new file mode 100644 (file)
index 0000000..1cb19e7
--- /dev/null
@@ -0,0 +1,193 @@
+/*-
+ * 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: acpiconf.c,v 1.5 2000/08/08 14:12:19 iwasaki Exp $
+ *     $FreeBSD: src/usr.sbin/acpi/acpiconf/acpiconf.c,v 1.14 2004/03/05 02:48:22 takawata Exp $
+ *     $DragonFly: src/usr.sbin/acpi/acpiconf/acpiconf.c,v 1.1 2004/07/05 00:22:43 dillon Exp $
+ */
+
+#include <sys/param.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+#include "acpiio.h"
+#include "acpi.h"
+
+#define ACPIDEV                "/dev/acpi"
+#define RC_SUSPEND_PATH        "/etc/rc.suspend"
+#define RC_RESUME_PATH "/etc/rc.resume"
+
+static int     acpifd;
+
+static int
+acpi_init()
+{
+       acpifd = open(ACPIDEV, O_RDWR);
+       if (acpifd == -1){
+               acpifd = open(ACPIDEV, O_RDONLY);
+       }
+       if (acpifd == -1){
+               err(EX_OSFILE, ACPIDEV);
+       }
+}
+
+static int
+acpi_enable_disable(int enable)
+{
+       if (ioctl(acpifd, enable, NULL) == -1) {
+               if (enable == ACPIIO_ENABLE)
+                       err(EX_IOERR, "enable failed");
+               else
+                       err(EX_IOERR, "disable failed");
+       }
+
+       return (0);
+}
+
+static int
+acpi_sleep(int sleep_type)
+{
+       char cmd[64];
+       int ret;
+
+       /* Run the suspend rc script, if available. */
+       if (access(RC_SUSPEND_PATH, X_OK) == 0) {
+               snprintf(cmd, sizeof(cmd), "%s acpi %d", RC_SUSPEND_PATH,
+                   sleep_type);
+               system(cmd);
+       }
+
+       ret = ioctl(acpifd, ACPIIO_SETSLPSTATE, &sleep_type);
+
+       /* Run the resume rc script, if available. */
+       if (access(RC_RESUME_PATH, X_OK) == 0) {
+               snprintf(cmd, sizeof(cmd), "%s acpi %d", RC_RESUME_PATH,
+                   sleep_type);
+               system(cmd);
+       }
+
+       if (ret != 0)
+               err(EX_IOERR, "sleep type (%d) failed", sleep_type);
+
+       return (0);
+}
+
+static int
+acpi_battinfo(int num)
+{
+       union acpi_battery_ioctl_arg battio;
+       const char *pwr_units;
+
+       if (num < 0 || num > 64)
+               err(EX_USAGE, "invalid battery %d", num);
+
+       battio.unit = num;
+       if (ioctl(acpifd, ACPIIO_CMBAT_GET_BIF, &battio) == -1)
+               err(EX_IOERR, "get battery info (%d) failed", num);
+       printf("Battery %d information\n", num);
+       if (battio.bif.units == 0)
+               pwr_units = "mWh";
+       else
+               pwr_units = "mAh";
+
+       printf("Design capacity:\t%d %s\n", battio.bif.dcap, pwr_units);
+       printf("Last full capacity:\t%d %s\n", battio.bif.lfcap, pwr_units);
+       printf("Technology:\t\t%s\n", battio.bif.btech == 0 ?
+           "primary (non-rechargeable)" : "secondary (rechargeable)");
+       printf("Design voltage:\t\t%d mV\n", battio.bif.dvol);
+       printf("Capacity (warn):\t%d %s\n", battio.bif.wcap, pwr_units);
+       printf("Capacity (low):\t\t%d %s\n", battio.bif.lcap, pwr_units);
+       printf("Low/warn granularity:\t%d %s\n", battio.bif.gra1, pwr_units);
+       printf("Warn/full granularity:\t%d %s\n", battio.bif.gra2, pwr_units);
+       printf("Model number:\t\t%s\n", battio.bif.model);
+       printf("Serial number:\t\t%s\n", battio.bif.serial);
+       printf("Type:\t\t\t%s\n", battio.bif.type);
+       printf("OEM info:\t\t%s\n", battio.bif.oeminfo);
+
+       return (0);
+}
+
+static void
+usage(const char* prog)
+{
+       printf("usage: %s [-deh] [-i batt] [-s 1-5]\n", prog);
+       exit(0);
+}
+
+int
+main(int argc, char *argv[])
+{
+       char    c, *prog;
+       int     sleep_type;
+
+       prog = argv[0];
+       if (argc < 2)
+               usage(prog);
+               /* NOTREACHED */
+
+       sleep_type = -1;
+       acpi_init();
+       while ((c = getopt(argc, argv, "dehi:s:")) != -1) {
+               switch (c) {
+               case 'i':
+                       acpi_battinfo(atoi(optarg));
+                       break;
+               case 'd':
+                       acpi_enable_disable(ACPIIO_DISABLE);
+                       break;
+               case 'e':
+                       acpi_enable_disable(ACPIIO_ENABLE);
+                       break;
+               case 's':
+                       if (optarg[0] == 'S')
+                               sleep_type = optarg[1] - '0';
+                       else
+                               sleep_type = optarg[0] - '0';
+                       if (sleep_type < 0 || sleep_type > 5)
+                               errx(EX_USAGE, "invalid sleep type (%d)",
+                                    sleep_type);
+                       break;
+               case 'h':
+               default:
+                       usage(prog);
+                       /* NOTREACHED */
+               }
+       }
+       argc -= optind;
+       argv += optind;
+
+       if (sleep_type != -1) {
+               sleep(1);       /* wait 1 sec. for key-release event */
+               acpi_sleep(sleep_type);
+       }
+
+       close(acpifd);
+       exit (0);
+}
diff --git a/usr.sbin/acpi/acpidb/Makefile b/usr.sbin/acpi/acpidb/Makefile
new file mode 100644 (file)
index 0000000..d0cb25e
--- /dev/null
@@ -0,0 +1,43 @@
+# $FreeBSD: src/usr.sbin/acpi/acpidb/Makefile,v 1.5 2004/05/25 02:56:55 njl Exp $
+# $DragonFly: src/usr.sbin/acpi/acpidb/Makefile,v 1.1 2004/07/05 00:22:43 dillon Exp $
+
+PROG=  acpidb
+SRCS+= acpidb.c
+SRCS+= osunixxf.c
+SRCS+= dbcmds.c dbdisply.c dbexec.c dbfileio.c \
+       dbhistry.c dbinput.c dbstats.c dbutils.c \
+       dbxface.c dmbuffer.c dmnames.c dmobject.c \
+       dmopcode.c dmresrc.c dmresrcl.c dmresrcs.c \
+       dmutils.c dmwalk.c dsfield.c dsinit.c \
+       dsmethod.c dsmthdat.c dsobject.c dsopcode.c \
+       dsutils.c dswexec.c dswload.c dswscope.c dswstate.c \
+       evevent.c evgpe.c evgpeblk.c evmisc.c \
+       evregion.c evrgnini.c evsci.c evxface.c \
+       evxfevnt.c evxfregn.c exconfig.c exconvrt.c \
+       excreate.c exdump.c exfield.c exfldio.c \
+       exmisc.c exmutex.c exnames.c exoparg1.c \
+       exoparg2.c exoparg3.c exoparg6.c exprep.c \
+       exregion.c exresnte.c exresolv.c exresop.c \
+       exstore.c exstoren.c exstorob.c exsystem.c exutils.c \
+       hwacpi.c hwgpe.c hwregs.c hwsleep.c \
+       nsaccess.c nsalloc.c nsdump.c nseval.c \
+       nsinit.c nsload.c nsnames.c nsobject.c \
+       nsparse.c nssearch.c nsutils.c nswalk.c \
+       nsxfeval.c nsxfname.c nsxfobj.c \
+       psargs.c psopcode.c psparse.c psscope.c \
+       pstree.c psutils.c pswalk.c psxface.c \
+       rsaddr.c rscalc.c rscreate.c rsdump.c \
+       rsio.c rsirq.c rslist.c rsmemory.c \
+       rsmisc.c rsutils.c rsxface.c \
+       tbconvrt.c tbget.c tbgetall.c tbinstal.c \
+       tbrsdt.c tbutils.c tbxface.c tbxfroot.c \
+       utalloc.c utcopy.c utdebug.c utdelete.c \
+       uteval.c utglobal.c utinit.c utmath.c \
+       utmisc.c utobject.c utxface.c
+
+MAN=   acpidb.8
+
+CFLAGS+= -DACPI_APPLICATION -DACPI_DEBUG_OUTPUT -DACPI_DEBUGGER \
+       -DACPI_DISASSEMBLER
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/acpi/acpidb/acpidb.8 b/usr.sbin/acpi/acpidb/acpidb.8
new file mode 100644 (file)
index 0000000..5d3f146
--- /dev/null
@@ -0,0 +1,168 @@
+.\"-
+.\" Copyright (c) 2003 Nate Lawson
+.\" 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
+.\"    in this position and unchanged.
+.\" 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.
+.\" 3. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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/acpidb/acpidb.8,v 1.2 2004/06/06 17:49:57 ru Exp $
+.\" $DragonFly: src/usr.sbin/acpi/acpidb/acpidb.8,v 1.1 2004/07/05 00:22:43 dillon Exp $
+.\"
+.Dd August 7, 2003
+.Dt ACPIDB 8
+.Os
+.Sh NAME
+.Nm acpidb
+.Nd ACPI DSDT debugger
+.Sh SYNOPSIS
+.Nm
+.Ar input-file
+.Sh DESCRIPTION
+The
+.Nm
+utility is a debugger for the ACPI DSDT.
+It can parse and execute various
+AML methods and display the result.
+.Sh COMMANDS
+.Ss General-Purpose Commands
+.Bl -tag -width indent
+.It Ic Allocations
+Display list of current memory allocations
+.It Ic Dump Ar Address | Namepath Op Cm Byte | Word | Dword | Qword
+Display ACPI objects or memory
+.It Ic EnableAcpi
+Enable ACPI (hardware) mode
+.It Ic Help
+Show various help screens
+.It Ic History
+Display command history buffer
+.It Ic Level Ar DebugLevel Op Cm console
+Get/Set debug level for file or console
+.It Ic Locks
+Current status of internal mutexes
+.It Ic Quit No or Ic Exit
+Exit the debugger
+.It Ic Stats Op Cm Allocations | Memory | Misc | Objects | Tables
+Display namespace and memory statistics
+.It Ic Tables
+Display info about loaded ACPI tables
+.It Ic Unload Ar TableSig Op Ar Instance
+Unload an ACPI table
+.It Ic !\& Ar CommandNumber
+Execute command from history buffer
+.It Ic !!
+Execute last command again
+.El
+.Ss Namespace Access Commands
+.Bl -tag -width indent
+.It Ic Event Cm F | G Ar Value
+Generate AcpiEvent (Fixed/GPE)
+.It Ic Find Ar Name
+Find ACPI name(s) with wildcards
+.Ql ( ?\&
+is wildcard)
+.It Ic Method
+Display list of loaded control methods
+.It Ic Namespace Oo Ar Addr | Path Oc Op Ar Depth
+Display loaded namespace tree/subtree
+.It Ic Notify Ar NamePath Value
+Send a notification
+.It Ic Objects Ar ObjectType
+Display all objects of the given type
+.It Ic Owner Ar OwnerId Op Ar Depth
+Display loaded namespace by object owner
+.It Ic Prefix Op Ar NamePath
+Set or Get current execution prefix
+.It Ic References Ar Addr
+Find all references to object at addr
+.It Ic Resources
+Get and display resources
+.It Ic Terminate
+Delete namespace and all internal objects
+.It Ic Thread Ar Threads Loops NamePath
+Spawn threads to execute method(s)
+.El
+.Ss Control Method Execution Commands
+.Bl -tag -width indent
+.It Ic Arguments
+.Pq Ic Args
+Display method arguments
+.It Ic Breakpoint Ar AmlOffset
+Set an AML execution breakpoint
+.It Ic Call
+Run to next control method invocation
+.It Ic Debug Ar Namepath Op Ar Arguments
+Single Step a control method
+.It Ic Execute Ar Namepath Op Arguments
+Execute control method
+.It Ic Go
+Allow method to run to completion
+.It Ic Information
+Display info about the current method
+.It Ic Into
+Step into (not over) a method call
+.It Ic List Op OpcodeCount
+Display method ASL statements
+.It Ic Locals
+Display method local variables
+.It Ic Results
+Display method result stack
+.It Ic Set Cm A | L Ar # Value
+Set method data (Arguments/Locals)
+.It Ic Stop
+Terminate control method
+.It Ic Tree
+Display control method calling tree
+.It Ic <Enter>
+Single step next AML opcode (over calls)
+.El
+.Ss File I/O Commands
+.Bl -tag -width indent
+.It Ic Close
+Close debug output file
+.It Ic Open Ar Filename
+Open a file for debug output
+.It Ic Load Ar Filename
+Load ACPI table from a file
+.El
+.Sh SEE ALSO
+.Xr acpi 4 ,
+.Xr acpidump 8 ,
+.Xr iasl 8
+.Sh HISTORY
+The
+.Nm
+utility first appeared in the
+.Nm acpicatools
+port.
+It was imported for
+.Fx 5.2 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+utility was written by
+.An Mitsuru Iwasaki Aq iwasaki@FreeBSD.org
+and uses Intel ACPI-CA for the backend.
+This manual page was written by
+.An Nate Lawson .
diff --git a/usr.sbin/acpi/acpidb/acpidb.c b/usr.sbin/acpi/acpidb/acpidb.c
new file mode 100644 (file)
index 0000000..76b0d7d
--- /dev/null
@@ -0,0 +1,498 @@
+/*-
+ * Copyright (c) 2000-2002 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.
+ *
+ *     $FreeBSD: src/usr.sbin/acpi/acpidb/acpidb.c,v 1.1 2003/08/07 16:51:50 njl Exp $
+ *     $DragonFly: src/usr.sbin/acpi/acpidb/acpidb.c,v 1.1 2004/07/05 00:22:43 dillon Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <err.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <acpi.h>
+#include <acnamesp.h>
+#include <acdebug.h>
+
+/*
+ * Dummy DSDT Table Header
+ */
+
+ACPI_TABLE_HEADER      dummy_dsdt_table = {
+       "DSDT", 123, 1, 123, "OEMID", "OEMTBLID", 1, "CRID", 1
+};
+
+/*
+ * Region space I/O routines on virtual machine
+ */
+
+int    aml_debug_prompt = 1;
+
+struct ACPIRegionContent {
+       TAILQ_ENTRY(ACPIRegionContent) links;
+       int                     regtype;
+       ACPI_PHYSICAL_ADDRESS   addr;
+       UINT8                   value;
+};
+
+TAILQ_HEAD(ACPIRegionContentList, ACPIRegionContent);
+struct ACPIRegionContentList RegionContentList;
+
+static int              aml_simulation_initialized = 0;
+
+static void             aml_simulation_init(void);
+static int              aml_simulate_regcontent_add(int regtype,
+                            ACPI_PHYSICAL_ADDRESS addr,
+                            UINT8 value);
+static int              aml_simulate_regcontent_read(int regtype,
+                            ACPI_PHYSICAL_ADDRESS addr,
+                            UINT8 *valuep); 
+static int              aml_simulate_regcontent_write(int regtype,
+                            ACPI_PHYSICAL_ADDRESS addr,
+                            UINT8 *valuep);
+static ACPI_INTEGER     aml_simulate_prompt(char *msg, ACPI_INTEGER def_val);
+static void             aml_simulation_regload(const char *dumpfile);
+static void             aml_simulation_regdump(const char *dumpfile);
+
+static void
+aml_simulation_init(void)
+{
+
+       aml_simulation_initialized = 1;
+       TAILQ_INIT(&RegionContentList);
+       aml_simulation_regload("region.ini");
+}
+
+static int
+aml_simulate_regcontent_add(int regtype, ACPI_PHYSICAL_ADDRESS addr, UINT8 value)
+{
+       struct  ACPIRegionContent *rc;
+
+       rc = malloc(sizeof(struct ACPIRegionContent));
+       if (rc == NULL) {
+               return (-1);    /* malloc fail */
+       }
+       rc->regtype = regtype;
+       rc->addr = addr;
+       rc->value = value;
+
+       TAILQ_INSERT_TAIL(&RegionContentList, rc, links);
+       return (0);
+}
+
+static int
+aml_simulate_regcontent_read(int regtype, ACPI_PHYSICAL_ADDRESS addr, UINT8 *valuep)
+{
+       struct  ACPIRegionContent *rc;
+
+       if (!aml_simulation_initialized) {
+               aml_simulation_init();
+       }
+       TAILQ_FOREACH(rc, &RegionContentList, links) {
+               if (rc->regtype == regtype && rc->addr == addr) {
+                       *valuep = rc->value;
+                       return (1);     /* found */
+               }
+       }
+
+       *valuep = 0;
+       return (aml_simulate_regcontent_add(regtype, addr, *valuep));
+}
+
+static int
+aml_simulate_regcontent_write(int regtype, ACPI_PHYSICAL_ADDRESS addr, UINT8 *valuep)
+{
+       struct  ACPIRegionContent *rc;
+
+       if (!aml_simulation_initialized) {
+               aml_simulation_init();
+       }
+       TAILQ_FOREACH(rc, &RegionContentList, links) {
+               if (rc->regtype == regtype && rc->addr == addr) {
+                       rc->value = *valuep;
+                       return (1);     /* exists */
+               }
+       }
+
+       return (aml_simulate_regcontent_add(regtype, addr, *valuep));
+}
+
+static ACPI_INTEGER
+aml_simulate_prompt(char *msg, ACPI_INTEGER def_val)
+{
+       char            buf[16], *ep;
+       ACPI_INTEGER    val;
+
+       val = def_val;
+       printf("DEBUG");
+       if (msg != NULL) {
+               printf("%s", msg);
+       }
+       printf("(default: 0x%x ", val);
+       printf(" / %u) >>", val);
+       fflush(stdout);
+
+       bzero(buf, sizeof buf);
+       while (1) {
+               if (read(0, buf, sizeof buf) == 0) {
+                       continue;
+               }
+               if (buf[0] == '\n') {
+                       break;  /* use default value */
+               }
+               if (buf[0] == '0' && buf[1] == 'x') {
+                       val = strtoq(buf, &ep, 16);
+               } else {
+                       val = strtoq(buf, &ep, 10);
+               }
+               break;
+       }
+       return (val);
+}
+
+static void
+aml_simulation_regload(const char *dumpfile)
+{
+       char    buf[256], *np, *ep;
+       struct  ACPIRegionContent rc;
+       FILE    *fp;
+
+       if (!aml_simulation_initialized) {
+               return;
+       }
+
+       if ((fp = fopen(dumpfile, "r")) == NULL) {
+               return;
+       }
+
+       while (fgets(buf, sizeof buf, fp) != NULL) {
+               np = buf;
+               /* reading region type */
+               rc.regtype = strtoq(np, &ep, 10);
+               if (np == ep) {
+                       continue;
+               }
+               np = ep;
+
+               /* reading address */
+               rc.addr = strtoq(np, &ep, 16);
+               if (np == ep) {
+                       continue;
+               }
+               np = ep;
+
+               /* reading value */
+               rc.value = strtoq(np, &ep, 16);
+               if (np == ep) {
+                       continue;
+               }
+               aml_simulate_regcontent_write(rc.regtype, rc.addr, &rc.value);
+       }
+
+       fclose(fp);
+}
+
+static void
+aml_simulation_regdump(const char *dumpfile)
+{
+       struct  ACPIRegionContent *rc;
+       FILE    *fp;
+
+       if (!aml_simulation_initialized) {
+               return;
+       }
+       if ((fp = fopen(dumpfile, "w")) == NULL) {
+               warn("%s", dumpfile);
+               return;
+       }
+       while (!TAILQ_EMPTY(&RegionContentList)) {
+               rc = TAILQ_FIRST(&RegionContentList);
+               fprintf(fp, "%d 0x%x    0x%x\n",
+                   rc->regtype, rc->addr, rc->value);
+               TAILQ_REMOVE(&RegionContentList, rc, links);
+               free(rc);
+       }
+
+       fclose(fp);
+       TAILQ_INIT(&RegionContentList);
+}
+
+/*
+ * Space handlers on virtual machine
+ */
+
+static ACPI_STATUS
+aml_vm_space_handler(
+       UINT32                  SpaceID,
+       UINT32                  Function,
+       ACPI_PHYSICAL_ADDRESS   Address,
+       UINT32                  BitWidth,
+       ACPI_INTEGER            *Value,
+       int                     Prompt)
+{
+       int             state;
+       UINT8           val;
+       ACPI_INTEGER    value, i;
+       char            msg[256];
+       static char     *space_names[] = {
+               "SYSTEM_MEMORY", "SYSTEM_IO", "PCI_CONFIG",
+               "EC", "SMBUS", "CMOS", "PCI_BAR_TARGET"};
+
+       switch (Function) {
+       case ACPI_READ:
+               value = 0;
+               for (i = 0; (i * 8) < BitWidth; i++) {
+                       state = aml_simulate_regcontent_read(SpaceID,
+                                                            Address + i, &val);
+                       if (state == -1) {
+                               return (AE_NO_MEMORY);
+                       }
+                       value |= val << (i * 8);
+               }
+               *Value = value;
+               if (Prompt) {
+                       sprintf(msg, "[read (%s, %2d, 0x%x)]",
+                               space_names[SpaceID], BitWidth, Address);
+                       *Value = aml_simulate_prompt(msg, value);
+                       if (*Value != value) {
+                               return(aml_vm_space_handler(SpaceID,
+                                               ACPI_WRITE,
+                                               Address, BitWidth, Value, 0));
+                       }
+               }
+               break;
+
+       case ACPI_WRITE:
+               value = *Value;
+               if (Prompt) {
+                       sprintf(msg, "[write(%s, %2d, 0x%x)]",
+                               space_names[SpaceID], BitWidth, Address);
+                       value = aml_simulate_prompt(msg, *Value);
+               }
+               *Value = value;
+               for (i = 0; (i * 8) < BitWidth; i++) {
+                       val = value & 0xff;
+                       state = aml_simulate_regcontent_write(SpaceID,
+                                                             Address + i, &val);
+                       if (state == -1) {
+                               return (AE_NO_MEMORY);
+                       }
+                       value = value >> 8;
+               }
+       }
+
+       return (AE_OK);
+}
+
+#define DECLARE_VM_SPACE_HANDLER(name, id);                    \
+static ACPI_STATUS                                             \
+aml_vm_space_handler_##name (                                  \
+       UINT32                  Function,                       \
+       ACPI_PHYSICAL_ADDRESS   Address,                        \
+       UINT32                  BitWidth,                       \
+       ACPI_INTEGER            *Value,                         \
+       void                    *HandlerContext,                \
+       void                    *RegionContext)                 \
+{                                                              \
+       return (aml_vm_space_handler(id, Function, Address,     \
+               BitWidth, Value, aml_debug_prompt));            \
+}
+
+DECLARE_VM_SPACE_HANDLER(system_memory,        ACPI_ADR_SPACE_SYSTEM_MEMORY);
+DECLARE_VM_SPACE_HANDLER(system_io,    ACPI_ADR_SPACE_SYSTEM_IO);
+DECLARE_VM_SPACE_HANDLER(pci_config,   ACPI_ADR_SPACE_PCI_CONFIG);
+DECLARE_VM_SPACE_HANDLER(ec,           ACPI_ADR_SPACE_EC);
+DECLARE_VM_SPACE_HANDLER(smbus,                ACPI_ADR_SPACE_SMBUS);
+DECLARE_VM_SPACE_HANDLER(cmos,         ACPI_ADR_SPACE_CMOS);
+DECLARE_VM_SPACE_HANDLER(pci_bar_target,ACPI_ADR_SPACE_PCI_BAR_TARGET);
+
+/*
+ * Load DSDT data file and invoke debugger
+ */
+
+static UINT32  DummyGlobalLock;
+
+static int
+load_dsdt(const char *dsdtfile)
+{
+       char                    filetmp[PATH_MAX];
+       u_int8_t                *code, *amlptr;
+       struct stat              sb;
+       int                      fd, fd2;
+       int                      error;
+       ACPI_TABLE_HEADER       *tableptr;
+
+       fd = open(dsdtfile, O_RDONLY, 0);
+       if (fd == -1) {
+               perror("open");
+               return (-1);
+       }
+       if (fstat(fd, &sb) == -1) {
+               perror("fstat");
+               return (-1);
+       }
+       code = mmap(NULL, (size_t)sb.st_size, PROT_READ, MAP_PRIVATE, fd, (off_t)0);
+       if (code == NULL) {
+               perror("mmap");
+               return (-1);
+       }
+       if ((error = AcpiInitializeSubsystem()) != AE_OK) {
+               return (-1);
+       }
+
+       /*
+        * make sure DSDT data contains table header or not.
+        */
+       if (strncmp((char *)code, "DSDT", 4) == 0) {
+               strncpy(filetmp, dsdtfile, sizeof(filetmp));
+       } else {
+               mode_t  mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+               dummy_dsdt_table.Length = sizeof(ACPI_TABLE_HEADER) + sb.st_size;
+               snprintf(filetmp, sizeof(filetmp), "%s.tmp", dsdtfile);
+               fd2 = open(filetmp, O_WRONLY | O_CREAT | O_TRUNC, mode);
+               if (fd2 == -1) {
+                       perror("open");
+                       return (-1);
+               }
+               write(fd2, &dummy_dsdt_table, sizeof(ACPI_TABLE_HEADER));
+
+               write(fd2, code, sb.st_size);
+               close(fd2);
+       }
+
+       /*
+        * Install the virtual machine version of address space handlers.
+        */
+       if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
+                       ACPI_ADR_SPACE_SYSTEM_MEMORY,
+                       aml_vm_space_handler_system_memory,
+                       NULL, NULL)) != AE_OK) {
+               fprintf(stderr, "could not initialise SystemMemory handler: %d\n", error);
+               return (-1);
+       }
+       if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
+                       ACPI_ADR_SPACE_SYSTEM_IO,
+                       aml_vm_space_handler_system_io,
+                       NULL, NULL)) != AE_OK) {
+               fprintf(stderr, "could not initialise SystemIO handler: %d\n", error);
+               return (-1);
+       }
+       if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
+                       ACPI_ADR_SPACE_PCI_CONFIG,
+                       aml_vm_space_handler_pci_config,
+                       NULL, NULL)) != AE_OK) {
+               fprintf(stderr, "could not initialise PciConfig handler: %d\n", error);
+               return (-1);
+       }
+       if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
+                       ACPI_ADR_SPACE_EC,
+                       aml_vm_space_handler_ec,
+                       NULL, NULL)) != AE_OK) {
+               fprintf(stderr, "could not initialise EC handler: %d\n", error);
+               return (-1);
+       }
+       if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
+                       ACPI_ADR_SPACE_SMBUS,
+                       aml_vm_space_handler_smbus,
+                       NULL, NULL)) != AE_OK) {
+               fprintf(stderr, "could not initialise SMBUS handler: %d\n", error);
+               return (-1);
+       }
+       if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
+                       ACPI_ADR_SPACE_CMOS,
+                       aml_vm_space_handler_cmos,
+                       NULL, NULL)) != AE_OK) {
+               fprintf(stderr, "could not initialise CMOS handler: %d\n", error);
+               return (-1);
+       }
+       if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
+                       ACPI_ADR_SPACE_PCI_BAR_TARGET,
+                       aml_vm_space_handler_pci_bar_target,
+                       NULL, NULL)) != AE_OK) {
+               fprintf(stderr, "could not initialise PCI BAR TARGET handler: %d\n", error);
+               return (-1);
+       }
+
+       AcpiGbl_FACS = malloc(sizeof (ACPI_COMMON_FACS));
+       if (AcpiGbl_FACS == NULL) {
+               fprintf(stderr, "could not allocate memory for FACS\n");
+               return (-1);
+       }
+       DummyGlobalLock = 0;
+       AcpiGbl_CommonFACS.GlobalLock = &DummyGlobalLock;
+       AcpiGbl_GlobalLockPresent = TRUE;
+
+       AcpiDbGetTableFromFile(filetmp, NULL);
+       AcpiUtSetIntegerWidth (AcpiGbl_DSDT->Revision);
+
+       AcpiDbInitialize();
+       AcpiGbl_DebuggerConfiguration = 0;
+       AcpiDbUserCommands(':', NULL);
+
+       if (strcmp(dsdtfile, filetmp) != 0) {
+               unlink(filetmp);
+       }
+
+       return (0);
+}
+
+static void
+usage(const char *progname)
+{
+
+       printf("usage: %s dsdt_file\n", progname);
+       exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+       char    *progname;
+
+       progname = argv[0];
+
+       if (argc == 1) {
+               usage(progname);
+       }
+
+       AcpiDbgLevel = ACPI_DEBUG_DEFAULT;
+
+       aml_simulation_regload("region.ini");
+       if (load_dsdt(argv[1]) == 0) {
+               aml_simulation_regdump("region.dmp");
+       }
+
+       return (0);
+}
diff --git a/usr.sbin/acpi/acpidump/Makefile b/usr.sbin/acpi/acpidump/Makefile
new file mode 100644 (file)
index 0000000..3cf5b50
--- /dev/null
@@ -0,0 +1,9 @@
+# $FreeBSD: src/usr.sbin/acpi/acpidump/Makefile,v 1.7 2003/08/28 03:33:07 njl Exp $
+# $DragonFly: src/usr.sbin/acpi/acpidump/Makefile,v 1.1 2004/07/05 00:22:43 dillon Exp $
+
+PROG=  acpidump
+MAN=   acpidump.8
+SRCS=  acpi.c acpi_user.c acpidump.c
+WARNS?=        6
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/acpi/acpidump/acpi.c b/usr.sbin/acpi/acpidump/acpi.c
new file mode 100644 (file)
index 0000000..473878a
--- /dev/null
@@ -0,0 +1,850 @@
+/*-
+ * 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.
+ *
+ *     $FreeBSD: src/usr.sbin/acpi/acpidump/acpi.c,v 1.25 2004/06/30 03:23:51 njl Exp $
+ *     $DragonFly: src/usr.sbin/acpi/acpidump/acpi.c,v 1.1 2004/07/05 00:22:43 dillon Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/endian.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <assert.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "acpidump.h"
+
+#define BEGIN_COMMENT  "/*\n"
+#define END_COMMENT    " */\n"
+
+static void    acpi_print_string(char *s, size_t length);
+static void    acpi_print_gas(struct ACPIgas *gas);
+static int     acpi_get_fadt_revision(struct FADTbody *fadt);
+static void    acpi_handle_fadt(struct ACPIsdt *fadt);
+static void    acpi_print_cpu(u_char cpu_id);
+static void    acpi_print_local_apic(u_char cpu_id, u_char apic_id,
+                                     u_int32_t flags);
+static void    acpi_print_io_apic(u_char apic_id, u_int32_t int_base,
+                                  u_int64_t apic_addr);
+static void    acpi_print_mps_flags(u_int16_t flags);
+static void    acpi_print_intr(u_int32_t intr, u_int16_t mps_flags);
+static void    acpi_print_apic(struct MADT_APIC *mp);
+static void    acpi_handle_apic(struct ACPIsdt *sdp);
+static void    acpi_handle_hpet(struct ACPIsdt *sdp);
+static void    acpi_print_sdt(struct ACPIsdt *sdp);
+static void    acpi_print_fadt(struct ACPIsdt *sdp);
+static void    acpi_print_facs(struct FACSbody *facs);
+static void    acpi_print_dsdt(struct ACPIsdt *dsdp);
+static struct ACPIsdt *acpi_map_sdt(vm_offset_t pa);
+static void    acpi_print_rsd_ptr(struct ACPIrsdp *rp);
+static void    acpi_handle_rsdt(struct ACPIsdt *rsdp);
+
+/* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
+static int addr_size;
+
+/*
+ * XXX: borrow endian-conversion functions from FreeBSD-CURRENT's endian.h
+ */
+static __inline uint32_t
+le32dec(const void *pp)
+{
+       unsigned char const *p = (unsigned char const *)pp;
+
+       return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
+}
+
+static __inline uint64_t
+le64dec(const void *pp)
+{
+       unsigned char const *p = (unsigned char const *)pp;
+
+       return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p));
+}
+
+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_print_gas(struct ACPIgas *gas)
+{
+       switch(gas->address_space_id) {
+       case ACPI_GAS_MEMORY:
+               printf("0x%08lx:%u[%u] (Memory)", (u_long)gas->address,
+                      gas->bit_offset, gas->bit_width);
+               break;
+       case ACPI_GAS_IO:
+               printf("0x%02lx:%u[%u] (IO)", (u_long)gas->address,
+                      gas->bit_offset, gas->bit_width);
+               break;
+       case ACPI_GAS_PCI:
+               printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->address >> 32),
+                      (uint16_t)((gas->address >> 16) & 0xffff),
+                      (uint16_t)gas->address);
+               break;
+       /* XXX How to handle these below? */
+       case ACPI_GAS_EMBEDDED:
+               printf("0x%x:%u[%u] (EC)", (uint16_t)gas->address,
+                      gas->bit_offset, gas->bit_width);
+               break;
+       case ACPI_GAS_SMBUS:
+               printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->address,
+                      gas->bit_offset, gas->bit_width);
+               break;
+       case ACPI_GAS_FIXED:
+       default:
+               printf("0x%08lx (?)", (u_long)gas->address);
+               break;
+       }
+}
+
+/* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */
+static int
+acpi_get_fadt_revision(struct FADTbody *fadt)
+{
+       int fadt_revision;
+
+       /* Set the FADT revision separately from the RSDP version. */
+       if (addr_size == 8) {
+               fadt_revision = 2;
+
+               /*
+                * A few systems (e.g., IBM T23) have an RSDP that claims
+                * revision 2 but the 64 bit addresses are invalid.  If
+                * revision 2 and the 32 bit address is non-zero but the
+                * 32 and 64 bit versions don't match, prefer the 32 bit
+                * version for all subsequent tables.
+                */
+               if (fadt->facs_ptr != 0 &&
+                   (fadt->x_facs_ptr & 0xffffffff) != fadt->facs_ptr)
+                       fadt_revision = 1;
+       } else
+               fadt_revision = 1;
+       return (fadt_revision);
+}
+
+static void
+acpi_handle_fadt(struct ACPIsdt *sdp)
+{
+       struct ACPIsdt  *dsdp;
+       struct FACSbody *facs;
+       struct FADTbody *fadt;
+       int             fadt_revision;
+
+       fadt = (struct FADTbody *)sdp->body;
+       acpi_print_fadt(sdp);
+
+       fadt_revision = acpi_get_fadt_revision(fadt);
+       if (fadt_revision == 1)
+               facs = (struct FACSbody *)acpi_map_sdt(fadt->facs_ptr);
+       else
+               facs = (struct FACSbody *)acpi_map_sdt(fadt->x_facs_ptr);
+       if (memcmp(facs->signature, "FACS", 4) != 0 || facs->len < 64)
+               errx(1, "FACS is corrupt");
+       acpi_print_facs(facs);
+
+       if (fadt_revision == 1)
+               dsdp = (struct ACPIsdt *)acpi_map_sdt(fadt->dsdt_ptr);
+       else
+               dsdp = (struct ACPIsdt *)acpi_map_sdt(fadt->x_dsdt_ptr);
+       if (acpi_checksum(dsdp, dsdp->len))
+               errx(1, "DSDT is corrupt");
+       acpi_print_dsdt(dsdp);
+}
+
+static void
+acpi_print_cpu(u_char cpu_id)
+{
+
+       printf("\tACPI CPU=");
+       if (cpu_id == 0xff)
+               printf("ALL\n");
+       else
+               printf("%d\n", (u_int)cpu_id);
+}
+
+static void
+acpi_print_local_apic(u_char cpu_id, u_char apic_id, u_int32_t flags)
+{
+       acpi_print_cpu(cpu_id);
+       printf("\tFlags={");
+       if (flags & ACPI_MADT_APIC_LOCAL_FLAG_ENABLED)
+               printf("ENABLED");
+       else
+               printf("DISABLED");
+       printf("}\n");
+       printf("\tAPIC ID=%d\n", (u_int)apic_id);
+}
+
+static void
+acpi_print_io_apic(u_char apic_id, u_int32_t int_base, u_int64_t apic_addr)
+{
+       printf("\tAPIC ID=%d\n", (u_int)apic_id);
+       printf("\tINT BASE=%d\n", int_base);
+       printf("\tADDR=0x%016jx\n", apic_addr);
+}
+
+static void
+acpi_print_mps_flags(u_int16_t flags)
+{
+
+       printf("\tFlags={Polarity=");
+       switch (flags & MPS_INT_FLAG_POLARITY_MASK) {
+       case MPS_INT_FLAG_POLARITY_CONFORM:
+               printf("conforming");
+               break;
+       case MPS_INT_FLAG_POLARITY_HIGH:
+               printf("active-hi");
+               break;
+       case MPS_INT_FLAG_POLARITY_LOW:
+               printf("active-lo");
+               break;
+       default:
+               printf("0x%x", flags & MPS_INT_FLAG_POLARITY_MASK);
+               break;
+       }
+       printf(", Trigger=");
+       switch (flags & MPS_INT_FLAG_TRIGGER_MASK) {
+       case MPS_INT_FLAG_TRIGGER_CONFORM:
+               printf("conforming");
+               break;
+       case MPS_INT_FLAG_TRIGGER_EDGE:
+               printf("edge");
+               break;
+       case MPS_INT_FLAG_TRIGGER_LEVEL:
+               printf("level");
+               break;
+       default:
+               printf("0x%x", (flags & MPS_INT_FLAG_TRIGGER_MASK) >> 2);
+       }
+       printf("}\n");
+}
+
+static void
+acpi_print_intr(u_int32_t intr, u_int16_t mps_flags)
+{
+
+       printf("\tINTR=%d\n", (u_int)intr);
+       acpi_print_mps_flags(mps_flags);
+}
+
+const char *apic_types[] = { "Local APIC", "IO APIC", "INT Override", "NMI",
+                            "Local NMI", "Local APIC Override", "IO SAPIC",
+                            "Local SAPIC", "Platform Interrupt" };
+const char *platform_int_types[] = { "PMI", "INIT",
+                                    "Corrected Platform Error" };
+
+static void
+acpi_print_apic(struct MADT_APIC *mp)
+{
+
+       printf("\tType=%s\n", apic_types[mp->type]);
+       switch (mp->type) {
+       case ACPI_MADT_APIC_TYPE_LOCAL_APIC:
+               acpi_print_local_apic(mp->body.local_apic.cpu_id,
+                   mp->body.local_apic.apic_id, mp->body.local_apic.flags);
+               break;
+       case ACPI_MADT_APIC_TYPE_IO_APIC:
+               acpi_print_io_apic(mp->body.io_apic.apic_id,
+                   mp->body.io_apic.int_base,
+                   mp->body.io_apic.apic_addr);
+               break;
+       case ACPI_MADT_APIC_TYPE_INT_OVERRIDE:
+               printf("\tBUS=%d\n", (u_int)mp->body.int_override.bus);
+               printf("\tIRQ=%d\n", (u_int)mp->body.int_override.source);
+               acpi_print_intr(mp->body.int_override.intr,
+                   mp->body.int_override.mps_flags);
+               break;
+       case ACPI_MADT_APIC_TYPE_NMI:
+               acpi_print_intr(mp->body.nmi.intr, mp->body.nmi.mps_flags);
+               break;
+       case ACPI_MADT_APIC_TYPE_LOCAL_NMI:
+               acpi_print_cpu(mp->body.local_nmi.cpu_id);
+               printf("\tLINT Pin=%d\n", mp->body.local_nmi.lintpin);
+               acpi_print_mps_flags(mp->body.local_nmi.mps_flags);
+               break;
+       case ACPI_MADT_APIC_TYPE_LOCAL_OVERRIDE:
+               printf("\tLocal APIC ADDR=0x%016jx\n",
+                   mp->body.local_apic_override.apic_addr);
+               break;
+       case ACPI_MADT_APIC_TYPE_IO_SAPIC:
+               acpi_print_io_apic(mp->body.io_sapic.apic_id,
+                   mp->body.io_sapic.int_base,
+                   mp->body.io_sapic.apic_addr);
+               break;
+       case ACPI_MADT_APIC_TYPE_LOCAL_SAPIC:
+               acpi_print_local_apic(mp->body.local_sapic.cpu_id,
+                   mp->body.local_sapic.apic_id, mp->body.local_sapic.flags);
+               printf("\tAPIC EID=%d\n", (u_int)mp->body.local_sapic.apic_eid);
+               break;
+       case ACPI_MADT_APIC_TYPE_INT_SRC:
+               printf("\tType=%s\n",
+                   platform_int_types[mp->body.int_src.type]);
+               printf("\tCPU ID=%d\n", (u_int)mp->body.int_src.cpu_id);
+               printf("\tCPU EID=%d\n", (u_int)mp->body.int_src.cpu_id);
+               printf("\tSAPIC Vector=%d\n",
+                   (u_int)mp->body.int_src.sapic_vector);
+               acpi_print_intr(mp->body.int_src.intr,
+                   mp->body.int_src.mps_flags);
+               break;
+       default:
+               printf("\tUnknown type %d\n", (u_int)mp->type);
+               break;
+       }
+}
+
+static void
+acpi_handle_apic(struct ACPIsdt *sdp)
+{
+       struct MADTbody *madtp;
+       struct MADT_APIC *madt_apicp;
+
+       printf(BEGIN_COMMENT);
+       acpi_print_sdt(sdp);
+       madtp = (struct MADTbody *) sdp->body;
+       printf("\tLocal APIC ADDR=0x%08x\n", madtp->lapic_addr);
+       printf("\tFlags={");
+       if (madtp->flags & ACPI_APIC_FLAG_PCAT_COMPAT)
+               printf("PC-AT");
+       printf("}\n");
+       madt_apicp = (struct MADT_APIC *)madtp->body;
+       while (((uintptr_t)madt_apicp) - ((uintptr_t)sdp) < sdp->len) {
+               printf("\n");
+               acpi_print_apic(madt_apicp);
+               madt_apicp = (struct MADT_APIC *) ((char *)madt_apicp +
+                   madt_apicp->len);
+       }
+       printf(END_COMMENT);
+}
+
+static void
+acpi_handle_hpet(struct ACPIsdt *sdp)
+{
+       struct HPETbody *hpetp;
+
+       printf(BEGIN_COMMENT);
+       acpi_print_sdt(sdp);
+       hpetp = (struct HPETbody *) sdp->body;
+       printf("\tHPET Number=%d\n", hpetp->hpet_number);
+       printf("\tADDR=0x%08x\n", hpetp->base_addr);
+       printf("\tHW Rev=0x%x\n", hpetp->block_hwrev);
+       printf("\tComparitors=%d\n", hpetp->block_comparitors);
+       printf("\tCounter Size=%d\n", hpetp->block_counter_size);
+       printf("\tLegacy IRQ routing capable={");
+       if (hpetp->block_legacy_capable)
+               printf("TRUE}\n");
+       else
+               printf("FALSE}\n");
+       printf("\tPCI Vendor ID=0x%04x\n", hpetp->block_pcivendor);
+       printf("\tMinimal Tick=%d\n", hpetp->clock_tick);
+       printf(END_COMMENT);
+}
+
+static void
+acpi_handle_ecdt(struct ACPIsdt *sdp)
+{
+       struct ECDTbody *ecdt;
+
+       printf(BEGIN_COMMENT);
+       acpi_print_sdt(sdp);
+       ecdt = (struct ECDTbody *) sdp->body;
+       printf("\tEC_CONTROL=");
+       acpi_print_gas(&ecdt->ec_control);
+       printf("\n\tEC_DATA=");
+       acpi_print_gas(&ecdt->ec_data);
+       printf("\n\tUID=%#x, ", ecdt->uid);
+       printf("GPE_BIT=%#x\n", ecdt->gpe_bit);
+       printf("\tEC_ID=%s\n", ecdt->ec_id);
+       printf(END_COMMENT);
+}
+
+static void
+acpi_print_sdt(struct ACPIsdt *sdp)
+{
+       printf("  ");
+       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);
+}
+
+static void
+acpi_print_rsdt(struct ACPIsdt *rsdp)
+{
+       int     i, entries;
+       u_long  addr;
+
+       printf(BEGIN_COMMENT);
+       acpi_print_sdt(rsdp);
+       entries = (rsdp->len - SIZEOF_SDT_HDR) / addr_size;
+       printf("\tEntries={ ");
+       for (i = 0; i < entries; i++) {
+               if (i > 0)
+                       printf(", ");
+               switch (addr_size) {
+               case 4:
+                       addr = le32dec((char*)rsdp->body + i * addr_size);
+                       break;
+               case 8:
+                       addr = le64dec((char*)rsdp->body + i * addr_size);
+                       break;
+               default:
+                       addr = 0;
+               }
+               assert(addr != 0);
+               printf("0x%08lx", addr);
+       }
+       printf(" }\n");
+       printf(END_COMMENT);
+}
+
+static const char *acpi_pm_profiles[] = {
+       "Unspecified", "Desktop", "Mobile", "Workstation",
+       "Enterprise Server", "SOHO Server", "Appliance PC"
+};
+
+static void
+acpi_print_fadt(struct ACPIsdt *sdp)
+{
+       struct FADTbody *fadt;
+       const char *pm;
+       char        sep;
+
+       fadt = (struct FADTbody *)sdp->body;
+       printf(BEGIN_COMMENT);
+       acpi_print_sdt(sdp);
+       printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->facs_ptr,
+              fadt->dsdt_ptr);
+       printf("\tINT_MODEL=%s\n", fadt->int_model ? "APIC" : "PIC");
+       if (fadt->pm_profile >= sizeof(acpi_pm_profiles) / sizeof(char *))
+               pm = "Reserved";
+       else
+               pm = acpi_pm_profiles[fadt->pm_profile];
+       printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->pm_profile);
+       printf("\tSCI_INT=%d\n", fadt->sci_int);
+       printf("\tSMI_CMD=0x%x, ", fadt->smi_cmd);
+       printf("ACPI_ENABLE=0x%x, ", fadt->acpi_enable);
+       printf("ACPI_DISABLE=0x%x, ", fadt->acpi_disable);
+       printf("S4BIOS_REQ=0x%x\n", fadt->s4biosreq);
+       printf("\tPSTATE_CNT=0x%x\n", fadt->pstate_cnt);
+       printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
+              fadt->pm1a_evt_blk,
+              fadt->pm1a_evt_blk + fadt->pm1_evt_len - 1);
+       if (fadt->pm1b_evt_blk != 0)
+               printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
+                      fadt->pm1b_evt_blk,
+                      fadt->pm1b_evt_blk + fadt->pm1_evt_len - 1);
+       printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
+              fadt->pm1a_cnt_blk,
+              fadt->pm1a_cnt_blk + fadt->pm1_cnt_len - 1);
+       if (fadt->pm1b_cnt_blk != 0)
+               printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
+                      fadt->pm1b_cnt_blk,
+                      fadt->pm1b_cnt_blk + fadt->pm1_cnt_len - 1);
+       if (fadt->pm2_cnt_blk != 0)
+               printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
+                      fadt->pm2_cnt_blk,
+                      fadt->pm2_cnt_blk + fadt->pm2_cnt_len - 1);
+       printf("\tPM_TMR_BLK=0x%x-0x%x\n",
+              fadt->pm_tmr_blk,
+              fadt->pm_tmr_blk + fadt->pm_tmr_len - 1);
+       if (fadt->gpe0_blk != 0)
+               printf("\tGPE0_BLK=0x%x-0x%x\n",
+                      fadt->gpe0_blk,
+                      fadt->gpe0_blk + fadt->gpe0_len - 1);
+       if (fadt->gpe1_blk != 0)
+               printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
+                      fadt->gpe1_blk,
+                      fadt->gpe1_blk + fadt->gpe1_len - 1,
+                      fadt->gpe1_base);
+       if (fadt->cst_cnt != 0)
+               printf("\tCST_CNT=0x%x\n", fadt->cst_cnt);
+       printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
+              fadt->p_lvl2_lat, fadt->p_lvl3_lat);
+       printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
+              fadt->flush_size, fadt->flush_stride);
+       printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
+              fadt->duty_off, fadt->duty_width);
+       printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
+              fadt->day_alrm, fadt->mon_alrm, fadt->century);
+
+#define PRINTFLAG(var, flag) do {                      \
+       if ((var) & FADT_FLAG_## flag) {                \
+               printf("%c%s", sep, #flag); sep = ',';  \
+       }                                               \
+} while (0)
+
+       printf("\tIAPC_BOOT_ARCH=");
+       sep = '{';
+       PRINTFLAG(fadt->iapc_boot_arch, LEGACY_DEV);
+       PRINTFLAG(fadt->iapc_boot_arch, 8042);
+       if (fadt->iapc_boot_arch != 0)
+               printf("}");
+       printf("\n");
+
+       printf("\tFlags=");
+       sep = '{';
+       PRINTFLAG(fadt->flags, WBINVD);
+       PRINTFLAG(fadt->flags, WBINVD_FLUSH);
+       PRINTFLAG(fadt->flags, PROC_C1);
+       PRINTFLAG(fadt->flags, P_LVL2_UP);
+       PRINTFLAG(fadt->flags, PWR_BUTTON);
+       PRINTFLAG(fadt->flags, SLP_BUTTON);
+       PRINTFLAG(fadt->flags, FIX_RTC);
+       PRINTFLAG(fadt->flags, RTC_S4);
+       PRINTFLAG(fadt->flags, TMR_VAL_EXT);
+       PRINTFLAG(fadt->flags, DCK_CAP);
+       PRINTFLAG(fadt->flags, RESET_REG);
+       PRINTFLAG(fadt->flags, SEALED_CASE);
+       PRINTFLAG(fadt->flags, HEADLESS);
+       PRINTFLAG(fadt->flags, CPU_SW_SLP);
+       if (fadt->flags != 0)
+               printf("}\n");
+
+#undef PRINTFLAG
+
+       if (fadt->flags & FADT_FLAG_RESET_REG) {
+               printf("\tRESET_REG=");
+               acpi_print_gas(&fadt->reset_reg);
+               printf(", RESET_VALUE=%#x\n", fadt->reset_value);
+       }
+       if (acpi_get_fadt_revision(fadt) > 1) {
+               printf("\tX_FACS=0x%08lx, ", (u_long)fadt->x_facs_ptr);
+               printf("X_DSDT=0x%08lx\n", (u_long)fadt->x_dsdt_ptr);
+               printf("\tX_PM1a_EVT_BLK=");
+               acpi_print_gas(&fadt->x_pm1a_evt_blk);
+               if (fadt->x_pm1b_evt_blk.address != 0) {
+                       printf("\n\tX_PM1b_EVT_BLK=");
+                       acpi_print_gas(&fadt->x_pm1b_evt_blk);
+               }
+               printf("\n\tX_PM1a_CNT_BLK=");
+               acpi_print_gas(&fadt->x_pm1a_cnt_blk);
+               if (fadt->x_pm1b_cnt_blk.address != 0) {
+                       printf("\n\tX_PM1b_CNT_BLK=");
+                       acpi_print_gas(&fadt->x_pm1b_cnt_blk);
+               }
+               if (fadt->x_pm1b_cnt_blk.address != 0) {
+                       printf("\n\tX_PM2_CNT_BLK=");
+                       acpi_print_gas(&fadt->x_pm2_cnt_blk);
+               }
+               printf("\n\tX_PM_TMR_BLK=");
+               acpi_print_gas(&fadt->x_pm_tmr_blk);
+               if (fadt->x_gpe0_blk.address != 0) {
+                       printf("\n\tX_GPE0_BLK=");
+                       acpi_print_gas(&fadt->x_gpe0_blk);
+               }
+               if (fadt->x_gpe1_blk.address != 0) {
+                       printf("\n\tX_GPE1_BLK=");
+                       acpi_print_gas(&fadt->x_gpe1_blk);
+               }
+               printf("\n");
+       }
+
+       printf(END_COMMENT);
+}
+
+static void
+acpi_print_facs(struct FACSbody *facs)
+{
+       printf(BEGIN_COMMENT);
+       printf("  FACS:\tLength=%u, ", facs->len);
+       printf("HwSig=0x%08x, ", facs->hw_sig);
+       printf("Firm_Wake_Vec=0x%08x\n", facs->firm_wake_vec);
+
+       printf("\tGlobal_Lock=");
+       if (facs->global_lock != 0) {
+               if (facs->global_lock & FACS_FLAG_LOCK_PENDING)
+                       printf("PENDING,");
+               if (facs->global_lock & FACS_FLAG_LOCK_OWNED)
+                       printf("OWNED");
+       }
+       printf("\n");
+
+       printf("\tFlags=");
+       if (facs->flags & FACS_FLAG_S4BIOS_F)
+               printf("S4BIOS");
+       printf("\n");
+
+       if (facs->x_firm_wake_vec != 0) {
+               printf("\tX_Firm_Wake_Vec=%08lx\n",
+                      (u_long)facs->x_firm_wake_vec);
+       }
+       printf("\tVersion=%u\n", facs->version);
+
+       printf(END_COMMENT);
+}
+
+static void
+acpi_print_dsdt(struct ACPIsdt *dsdp)
+{
+       printf(BEGIN_COMMENT);
+       acpi_print_sdt(dsdp);
+       printf(END_COMMENT);
+}
+
+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);
+}
+
+static 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);
+}
+
+static void
+acpi_print_rsd_ptr(struct ACPIrsdp *rp)
+{
+       printf(BEGIN_COMMENT);
+       printf("  RSD PTR: OEM=");
+       acpi_print_string(rp->oem, 6);
+       printf(", ACPI_Rev=%s (%d)\n", rp->revision < 2 ? "1.0x" : "2.0x",
+              rp->revision);
+       if (rp->revision < 2) {
+               printf("\tRSDT=0x%08x, cksum=%u\n", rp->rsdt_addr, rp->sum);
+       } else {
+               printf("\tXSDT=0x%08lx, length=%u, cksum=%u\n",
+                   (u_long)rp->xsdt_addr, rp->length, rp->xsum);
+       }
+       printf(END_COMMENT);
+}
+
+static void
+acpi_handle_rsdt(struct ACPIsdt *rsdp)
+{
+       struct ACPIsdt *sdp;
+       vm_offset_t addr;
+       int entries, i;
+
+       acpi_print_rsdt(rsdp);
+       entries = (rsdp->len - SIZEOF_SDT_HDR) / addr_size;
+       for (i = 0; i < entries; i++) {
+               switch (addr_size) {
+               case 4:
+                       addr = le32dec((char*)rsdp->body + i * addr_size);
+                       break;
+               case 8:
+                       addr = le64dec((char*)rsdp->body + i * addr_size);
+                       break;
+               default:
+                       assert((addr = 0));
+               }
+
+               sdp = (struct ACPIsdt *)acpi_map_sdt(addr);
+               if (acpi_checksum(sdp, sdp->len))
+                       errx(1, "RSDT entry %d is corrupt", i);
+               if (!memcmp(sdp->signature, "FACP", 4))
+                       acpi_handle_fadt(sdp);
+               else if (!memcmp(sdp->signature, "APIC", 4))
+                       acpi_handle_apic(sdp);
+               else if (!memcmp(sdp->signature, "HPET", 4))
+                       acpi_handle_hpet(sdp);
+               else if (!memcmp(sdp->signature, "ECDT", 4))
+                       acpi_handle_ecdt(sdp);
+               else {
+                       printf(BEGIN_COMMENT);
+                       acpi_print_sdt(sdp);
+                       printf(END_COMMENT);
+               }
+       }
+}
+
+struct ACPIsdt *
+sdt_load_devmem(void)
+{
+       struct  ACPIrsdp *rp;
+       struct  ACPIsdt *rsdp;
+
+       rp = acpi_find_rsd_ptr();
+       if (!rp)
+               errx(1, "Can't find ACPI information");
+
+       if (tflag)
+               acpi_print_rsd_ptr(rp);
+       if (rp->revision < 2) {
+               rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->rsdt_addr);
+               if (memcmp(rsdp->signature, "RSDT", 4) != 0 ||
+                   acpi_checksum(rsdp, rsdp->len) != 0)
+                       errx(1, "RSDT is corrupted");
+               addr_size = sizeof(uint32_t);
+       } else {
+               rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->xsdt_addr);
+               if (memcmp(rsdp->signature, "XSDT", 4) != 0 ||
+                   acpi_checksum(rsdp, rsdp->len) != 0)
+                       errx(1, "XSDT is corrupted");
+               addr_size = sizeof(uint64_t);
+       }
+       return (rsdp);
+}
+
+void
+dsdt_save_file(char *outfile, struct ACPIsdt *dsdp)
+{
+       int     fd;
+       mode_t  mode;
+
+       assert(outfile != NULL);
+       mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+       fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
+       if (fd == -1) {
+               perror("dsdt_save_file");
+               return;
+       }
+       write(fd, dsdp, SIZEOF_SDT_HDR);
+       write(fd, dsdp->body, dsdp->len - SIZEOF_SDT_HDR);
+       close(fd);
+}
+
+void
+aml_disassemble(struct ACPIsdt *dsdp)
+{
+       char tmpstr[32], buf[256];
+       FILE *fp;
+       int fd, len;
+
+       strcpy(tmpstr, "/tmp/acpidump.XXXXXX");
+       fd = mkstemp(tmpstr);
+       if (fd < 0) {
+               perror("iasl tmp file");
+               return;
+       }
+
+       /* Dump DSDT to the temp file */
+       write(fd, dsdp, SIZEOF_SDT_HDR);
+       write(fd, dsdp->body, dsdp->len - SIZEOF_SDT_HDR);
+       close(fd);
+
+       /* Run iasl -d on the temp file */
+       if (fork() == 0) {
+               close(STDOUT_FILENO);
+               if (vflag == 0)
+                       close(STDERR_FILENO);
+               execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, 0);
+               err(1, "exec");
+       }
+
+       wait(NULL);
+       unlink(tmpstr);
+
+       /* Dump iasl's output to stdout */
+       fp = fopen("acpidump.dsl", "r");
+       unlink("acpidump.dsl");
+       if (fp == NULL) {
+               perror("iasl tmp file (read)");
+               return;
+       }
+       while ((len = fread(buf, 1, sizeof(buf), fp)) > 0)
+               fwrite(buf, 1, len, stdout);
+       fclose(fp);
+}
+
+void
+sdt_print_all(struct ACPIsdt *rsdp)
+{
+       acpi_handle_rsdt(rsdp);
+}
+
+/* Fetch a table matching the given signature via the RSDT */
+struct ACPIsdt *
+sdt_from_rsdt(struct ACPIsdt *rsdt, const char *sig)
+{
+       struct ACPIsdt *sdt;
+       vm_offset_t addr;
+       int entries, i;
+
+       entries = (rsdt->len - SIZEOF_SDT_HDR) / addr_size;
+       for (i = 0; i < entries; i++) {
+               switch (addr_size) {
+               case 4:
+                       addr = le32dec((char*)rsdt->body + i * addr_size);
+                       break;
+               case 8:
+                       addr = le64dec((char*)rsdt->body + i * addr_size);
+                       break;
+               default:
+                       assert((addr = 0));
+               }
+               sdt = (struct ACPIsdt *)acpi_map_sdt(addr);
+               if (memcmp(sdt->signature, sig, strlen(sig)))
+                       continue;
+               if (acpi_checksum(sdt, sdt->len))
+                       errx(1, "RSDT entry %d is corrupt", i);
+               return (sdt);
+       }
+
+       return (NULL);
+}
+
+struct ACPIsdt *
+dsdt_from_fadt(struct FADTbody *fadt)
+{
+       struct  ACPIsdt *sdt;
+
+       /* Use the DSDT address if it is version 1, otherwise use X_DSDT. */
+       if (acpi_get_fadt_revision(fadt) == 1)
+               sdt = (struct ACPIsdt *)acpi_map_sdt(fadt->dsdt_ptr);
+       else
+               sdt = (struct ACPIsdt *)acpi_map_sdt(fadt->x_dsdt_ptr);
+       if (acpi_checksum(sdt, sdt->len))
+               errx(1, "DSDT is corrupt\n");
+       return (sdt);
+}
diff --git a/usr.sbin/acpi/acpidump/acpi_user.c b/usr.sbin/acpi/acpidump/acpi_user.c
new file mode 100644 (file)
index 0000000..d154849
--- /dev/null
@@ -0,0 +1,213 @@
+/*-
+ * 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.
+ *
+ *     $FreeBSD: src/usr.sbin/acpi/acpidump/acpi_user.c,v 1.12 2004/05/28 07:25:23 njl Exp $
+ *     $DragonFly: src/usr.sbin/acpi/acpidump/acpi_user.c,v 1.1 2004/07/05 00:22:43 dillon Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "acpidump.h"
+
+static char    machdep_acpi_root[] = "machdep.acpi_root";
+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(void)
+{
+
+       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 ((intptr_t) map->va == -1)
+               err(1, "can't map address");
+       LIST_INSERT_HEAD(&maplist, map, link);
+
+       return (map);
+}
+
+static struct ACPIrsdp *
+acpi_get_rsdp(u_long addr)
+{
+       struct ACPIrsdp rsdp;
+       size_t len;
+
+       /* Read in the table signature and check it. */
+       pread(acpi_mem_fd, &rsdp, 8, addr);
+       if (memcmp(rsdp.signature, "RSD PTR ", 8))
+               return (NULL);
+
+       /* Read the entire table. */
+       pread(acpi_mem_fd, &rsdp, sizeof(rsdp), addr);
+
+       /* Run the checksum only over the version 1 header. */
+       if (acpi_checksum(&rsdp, 20))
+               return (NULL);
+
+       /* If the revision is 0, assume a version 1 length. */
+       if (rsdp.revision == 0)
+               len = 20;
+       else
+               len = rsdp.length;
+
+       /* XXX Should handle ACPI 2.0 RSDP extended checksum here. */
+
+       return (acpi_map_physical(addr, len));
+}
+
+static struct ACPIrsdp *
+acpi_scan_rsd_ptr(void)
+{
+#if defined(__i386__)
+       struct ACPIrsdp *rsdp;
+       u_long          addr, end;
+
+       /*
+        * On ia32, scan physical memory for the RSD PTR if above failed.
+        * According to section 5.2.2 of the ACPI spec, we only consider
+        * two regions for the base address:
+        * 1. EBDA (1 KB area addressed by the 16 bit pointer at 0x40E
+        * 2. High memory (0xE0000 - 0xFFFFF)
+        */
+       addr = RSDP_EBDA_PTR;
+       pread(acpi_mem_fd, &addr, sizeof(uint16_t), addr);
+       addr <<= 4;
+       end = addr + RSDP_EBDA_SIZE;
+       for (; addr < end; addr += 16)
+               if ((rsdp = acpi_get_rsdp(addr)) != NULL)
+                       return (rsdp);
+       addr = RSDP_HI_START;
+       end = addr + RSDP_HI_SIZE;
+       for (; addr < end; addr += 16)
+               if ((rsdp = acpi_get_rsdp(addr)) != NULL)
+                       return (rsdp);
+#endif /* __i386__ */
+       return (NULL);
+}
+
+/*
+ * Public interfaces
+ */
+struct ACPIrsdp *
+acpi_find_rsd_ptr(void)
+{
+       struct ACPIrsdp *rsdp;
+       u_long          addr;
+       size_t          len;
+
+       acpi_user_init();
+
+       /* Attempt to use sysctl to find RSD PTR record. */
+       len = sizeof(addr);
+       if (sysctlbyname(machdep_acpi_root, &addr, &len, NULL, 0) == 0) {       
+               if ((rsdp = acpi_get_rsdp(addr)) != NULL)
+                       return (rsdp);
+               else
+                       warnx("sysctl %s does not point to RSDP",
+                           machdep_acpi_root);
+       }
+
+       return (acpi_scan_rsd_ptr());
+}
+
+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));
+}
+
+struct ACPIsdt *
+dsdt_load_file(char *infile)
+{
+       struct ACPIsdt  *sdt;
+       uint8_t         *dp;
+       struct stat      sb;
+
+       if ((acpi_mem_fd = open(infile, O_RDONLY)) == -1)
+               errx(1, "opening %s", infile);
+
+       LIST_INIT(&maplist);
+
+       if (fstat(acpi_mem_fd, &sb) == -1)
+               errx(1, "fstat %s", infile);
+
+       dp = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, acpi_mem_fd, 0);
+       if (dp == NULL)
+               errx(1, "mmap %s", infile);
+
+       sdt = (struct ACPIsdt *)dp;
+       if (strncmp(dp, "DSDT", 4) != 0 || acpi_checksum(sdt, sdt->len) != 0)
+               return (NULL);
+
+       return (sdt);
+}
diff --git a/usr.sbin/acpi/acpidump/acpidump.8 b/usr.sbin/acpi/acpidump/acpidump.8
new file mode 100644 (file)
index 0000000..1316336
--- /dev/null
@@ -0,0 +1,191 @@
+.\" ACPI (ACPI Package)
+.\"
+.\" 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.16 2004/06/04 19:21:06 ru Exp $
+.\" $DragonFly: src/usr.sbin/acpi/acpidump/acpidump.8,v 1.1 2004/07/05 00:22:43 dillon Exp $
+.\"
+.Dd August 31, 2000
+.Dt ACPIDUMP 8
+.Os
+.Sh NAME
+.Nm acpidump
+.Nd dump ACPI tables and ASL
+.Sh SYNOPSIS
+.Nm
+.Op Fl d
+.Op Fl t
+.Op Fl h
+.Op Fl v
+.Op Fl f Ar dsdt_input
+.Op Fl o Ar dsdt_output
+.Sh DESCRIPTION
+The
+.Nm
+utility analyzes ACPI tables in physical memory and can dump them to a file.
+In addition,
+.Nm
+can call
+.Xr iasl 8
+to disassemble AML
+(ACPI Machine Language)
+found in these tables and dump them as ASL
+(ACPI Source Language)
+to stdout.
+.Pp
+ACPI tables have an essential data block (the DSDT,
+Differentiated System Description Table)
+that includes information used on the kernel side such as
+detailed information about PnP hardware, procedures for controlling
+power management support, and so on.
+The
+.Nm
+utility can extract the DSDT data block from physical memory and store it into
+a DSDT output file and optionally also disassemble it.
+.Pp
+When
+.Nm
+is invoked without the
+.Fl f
+option, it will read ACPI tables from physical memory via
+.Pa /dev/mem .
+First it searches for the RSDP
+(Root System Description Pointer),
+which has the signature
+.Qq RSD PTR\ \& ,
+and then gets the RSDT
+(Root System Description Table),
+which includes a list of pointers to physical memory addresses
+for other tables.
+The RSDT itself and all other tables linked from RSDT are generically
+called SDTs
+(System Description Tables)
+and their header has a common format which consists of items
+such as Signature, Length, Revision, Checksum, OEMID, OEM Table ID,
+OEM Revision, Creator ID and Creator Revision.
+When invoked with the
+.Fl t
+flag, the
+.Nm
+utility dumps contents of the following tables:
+.Pp
+.Bl -tag -offset indent -width 12345 -compact
+.It DSDT
+.It FADT
+.It HPET
+.It MADT
+.It RSD PTR
+.It RSDT
+.El
+.Pp
+The RSDT contains a pointer to the physical memory address of the FACP
+(Fixed ACPI Description Table).
+The FACP defines static system information about power management support
+(ACPI Hardware Register Implementation)
+such as interrupt mode (INT_MODEL),
+SCI interrupt number, SMI command port (SMI_CMD)
+and the location of ACPI registers.
+The FACP also has a pointer to a physical memory address for the DSDT.
+While the other tables are fixed format,
+the DSDT consists of free-formatted AML data.
+.Sh OPTIONS
+The following options are supported by
+.Nm :
+.Bl -tag -width indent
+.It Fl d
+Disassemble the DSDT into ASL using
+.Xr iasl 8
+and print the results to stdout.
+.It Fl t
+Dump the contents of the various fixed tables listed above.
+.It Fl h
+Displays usage and exit.
+.It Fl v
+Enable verbose messages.
+.It Fl f Ar dsdt_input
+Load the DSDT from the specified file instead of physical memory.
+Since only the DSDT is stored in the file, the
+.Fl t
+flag may not be used with this option.
+.It Fl o Ar dsdt_output
+Store the DSDT data block from physical memory into the specified file.
+.El
+.Sh EXAMPLES
+This example dumps the DSDT from physical memory to foo.dsdt.
+It also prints the contents of various system tables and disassembles
+the AML contained in the DSDT to stdout, redirecting the output
+to foo.asl.
+.Bd -literal -offset indent
+# acpidump -t -d -o foo.dsdt > foo.asl
+.Ed
+.Pp
+This example reads a DSDT file and disassembles it to stdout.
+Verbose messages are enabled.
+.Bd -literal -offset indent
+# acpidump -v -d -f foo.dsdt
+.Ed
+.Sh BUGS
+In the current implementation,
+.Nm
+does not dump the
+Secondary System Descriptor Table (SSDT), 
+Embedded Controller Descriptor Table (ECDT), 
+or BOOT structures.
+.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 acpidb 8 ,
+.Xr iasl 8
+.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
+.An -nosplit
+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 ,
+.An Michael Lucas Aq mwlucas@blackhelicopters.org
+and
+.An Michael Smith Aq msmith@FreeBSD.org .
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 5.0
+and was rewritten to use
+.Xr iasl 8
+for
+.Fx 5.2 .
diff --git a/usr.sbin/acpi/acpidump/acpidump.c b/usr.sbin/acpi/acpidump/acpidump.c
new file mode 100644 (file)
index 0000000..63a40ed
--- /dev/null
@@ -0,0 +1,140 @@
+/*-
+ * 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.
+ *
+ *     $FreeBSD: src/usr.sbin/acpi/acpidump/acpidump.c,v 1.8 2003/09/09 08:31:58 njl Exp $
+ *     $DragonFly: src/usr.sbin/acpi/acpidump/acpidump.c,v 1.1 2004/07/05 00:22:43 dillon Exp $
+ */
+
+#include <sys/param.h>
+#include <assert.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "acpidump.h"
+
+int    dflag;  /* Disassemble AML using iasl(8) */
+int    tflag;  /* Dump contents of SDT tables */
+int    vflag;  /* Use verbose messages */
+
+static void
+usage(const char *progname)
+{
+
+       fprintf(stderr, "usage: %s [-d] [-t] [-h] [-v] [-f dsdt_input] "
+                       "[-o dsdt_output]\n", progname);
+       exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+       char    c, *progname;
+       char    *dsdt_input_file, *dsdt_output_file;
+       struct  ACPIsdt *sdt;
+
+       dsdt_input_file = dsdt_output_file = NULL;
+       progname = argv[0];
+
+       if (argc < 2)
+               usage(progname);
+
+       while ((c = getopt(argc, argv, "dhtvf:o:")) != -1) {
+               switch (c) {
+               case 'd':
+                       dflag = 1;
+                       break;
+               case 't':
+                       tflag = 1;
+                       break;
+               case 'v':
+                       vflag = 1;
+                       break;
+               case 'f':
+                       dsdt_input_file = optarg;
+                       break;
+               case 'o':
+                       dsdt_output_file = optarg;
+                       break;
+               case 'h':
+               default:
+                       usage(progname);
+                       /* NOTREACHED */
+               }
+       }
+       argc -= optind;
+       argv += optind;
+
+       /* Get input either from file or /dev/mem */
+       if (dsdt_input_file != NULL) {
+               if (dflag == 0 && tflag == 0) {
+                       warnx("Need to specify -d or -t with DSDT input file");
+                       usage(progname);
+               } else if (tflag != 0) {
+                       warnx("Can't use -t with DSDT input file");
+                       usage(progname);
+               }
+               if (vflag)
+                       warnx("loading DSDT file: %s", dsdt_input_file);
+               sdt = dsdt_load_file(dsdt_input_file);
+       } else {
+               if (vflag)
+                       warnx("loading RSD PTR from /dev/mem");
+               sdt = sdt_load_devmem();
+       }
+
+       /* Display misc. SDT tables (only available when using /dev/mem) */
+       if (tflag) {
+               if (vflag)
+                       warnx("printing various SDT tables");
+               sdt_print_all(sdt);
+       }
+
+       /* Translate RSDT to DSDT pointer */
+       if (dsdt_input_file == NULL) {
+               sdt = sdt_from_rsdt(sdt, "FACP");
+               sdt = dsdt_from_fadt((struct FADTbody *)sdt->body);
+       }
+
+       /* Dump the DSDT to a file */
+       if (dsdt_output_file != NULL) {
+               if (vflag)
+                       warnx("saving DSDT file: %s", dsdt_output_file);
+               dsdt_save_file(dsdt_output_file, sdt);
+       }
+
+       /* Disassemble the DSDT into ASL */
+       if (dflag) {
+               if (vflag)
+                       warnx("disassembling DSDT, iasl messages follow");
+               aml_disassemble(sdt);
+               if (vflag)
+                       warnx("iasl processing complete");
+       }
+
+       exit(0);
+}
diff --git a/usr.sbin/acpi/acpidump/acpidump.h b/usr.sbin/acpi/acpidump/acpidump.h
new file mode 100644 (file)
index 0000000..d4641b1
--- /dev/null
@@ -0,0 +1,338 @@
+/*-
+ * 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.
+ *
+ *     $FreeBSD: src/usr.sbin/acpi/acpidump/acpidump.h,v 1.16 2004/05/28 07:25:23 njl Exp $
+ *     $DragonFly: src/usr.sbin/acpi/acpidump/acpidump.h,v 1.1 2004/07/05 00:22:43 dillon Exp $
+ */
+
+#ifndef _ACPIDUMP_H_
+#define _ACPIDUMP_H_
+
+/* 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        bit_width;
+       u_int8_t        bit_offset;
+       u_int8_t        _reserved;
+       u_int64_t       address;
+} __packed;
+
+/* Root System Description Pointer */
+struct ACPIrsdp {
+       u_char          signature[8];
+       u_char          sum;
+       u_char          oem[6];
+       u_char          revision;
+       u_int32_t       rsdt_addr;
+       u_int32_t       length;
+       u_int64_t       xsdt_addr;
+       u_char          xsum;
+       u_char          _reserved_[3];
+} __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 */
+} __packed;
+
+/* Fixed ACPI Description Table (body) */
+struct FADTbody {
+       u_int32_t       facs_ptr;
+       u_int32_t       dsdt_ptr;
+       u_int8_t        int_model;
+#define ACPI_FADT_INTMODEL_PIC 0       /* Standard PC-AT PIC */
+#define ACPI_FADT_INTMODEL_APIC        1       /* Multiple APIC */
+       u_int8_t        pm_profile;
+       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        pstate_cnt;
+       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        cst_cnt;
+       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;
+#define FADT_FLAG_LEGACY_DEV   1       /* System has legacy devices */
+#define FADT_FLAG_8042         2       /* 8042 keyboard controller */
+       u_char          reserved4[1];
+       u_int32_t       flags;
+#define FADT_FLAG_WBINVD       1       /* WBINVD is correctly supported */
+#define FADT_FLAG_WBINVD_FLUSH 2       /* WBINVD flushes caches */
+#define FADT_FLAG_PROC_C1      4       /* C1 power state supported */
+#define FADT_FLAG_P_LVL2_UP    8       /* C2 power state works on SMP */
+#define FADT_FLAG_PWR_BUTTON   16      /* Power button uses control method */
+#define FADT_FLAG_SLP_BUTTON   32      /* Sleep button uses control method */
+#define FADT_FLAG_FIX_RTC      64      /* RTC wakeup not supported */
+#define FADT_FLAG_RTC_S4       128     /* RTC can wakeup from S4 state */
+#define FADT_FLAG_TMR_VAL_EXT  256     /* TMR_VAL is 32bit */
+#define FADT_FLAG_DCK_CAP      512     /* Can support docking */
+#define FADT_FLAG_RESET_REG    1024    /* Supports RESET_REG */
+#define FADT_FLAG_SEALED_CASE  2048    /* Case cannot be opened */
+#define FADT_FLAG_HEADLESS     4096    /* No monitor */
+#define FADT_FLAG_CPU_SW_SLP   8192    /* Supports CPU software sleep */
+       struct ACPIgas  reset_reg;
+       u_int8_t        reset_value;
+       u_int8_t        reserved5[3];
+       u_int64_t       x_facs_ptr;
+       u_int64_t       x_dsdt_ptr;
+       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;
+} __packed;
+
+/* Firmware ACPI Control Structure */
+struct FACSbody {
+       u_char          signature[4];
+       u_int32_t       len;
+       u_int32_t       hw_sig;
+       /*
+        * NOTE This should be filled with physical address below 1MB!!
+        * sigh....
+        */
+       u_int32_t       firm_wake_vec;
+       u_int32_t       global_lock;
+#define FACS_FLAG_LOCK_PENDING 1       /* 5.2.6.1 Global Lock */
+#define FACS_FLAG_LOCK_OWNED   2
+       u_int32_t       flags;
+#define FACS_FLAG_S4BIOS_F     1       /* Supports S4BIOS_SEQ */
+       u_int64_t       x_firm_wake_vec;
+       u_int8_t        version;
+       char            reserved[31];
+} __packed;
+
+struct MADT_local_apic {
+       u_char          cpu_id;
+       u_char          apic_id;
+       u_int32_t       flags;
+#define        ACPI_MADT_APIC_LOCAL_FLAG_ENABLED       1
+} __packed;
+
+struct MADT_io_apic {
+       u_char          apic_id;
+       u_char          reserved;
+       u_int32_t       apic_addr;
+       u_int32_t       int_base;
+} __packed;
+
+struct MADT_int_override {
+       u_char          bus;
+       u_char          source;
+       u_int32_t       intr;
+       u_int16_t       mps_flags;
+#define        MPS_INT_FLAG_POLARITY_MASK      0x3
+#define        MPS_INT_FLAG_POLARITY_CONFORM   0x0
+#define        MPS_INT_FLAG_POLARITY_HIGH      0x1
+#define        MPS_INT_FLAG_POLARITY_LOW       0x3
+#define        MPS_INT_FLAG_TRIGGER_MASK       0xc
+#define        MPS_INT_FLAG_TRIGGER_CONFORM    0x0
+#define        MPS_INT_FLAG_TRIGGER_EDGE       0x4
+#define        MPS_INT_FLAG_TRIGGER_LEVEL      0xc
+} __packed;
+
+struct MADT_nmi {
+       u_int16_t       mps_flags;
+       u_int32_t       intr;
+} __packed;
+
+struct MADT_local_nmi {
+       u_char          cpu_id;
+       u_int16_t       mps_flags;
+       u_char          lintpin;
+} __packed;
+
+struct MADT_local_apic_override {
+       u_char          reserved[2];
+       u_int64_t       apic_addr;
+} __packed;
+
+struct MADT_io_sapic {
+       u_char          apic_id;
+       u_char          reserved;
+       u_int32_t       int_base;
+       u_int64_t       apic_addr;
+} __packed;
+
+struct MADT_local_sapic {
+       u_char          cpu_id;
+       u_char          apic_id;
+       u_char          apic_eid;
+       u_char          reserved[3];
+       u_int32_t       flags;
+} __packed;
+
+struct MADT_int_src {
+       u_int16_t       mps_flags;
+       u_char          type;
+#define        ACPI_MADT_APIC_INT_SOURCE_PMI   1
+#define        ACPI_MADT_APIC_INT_SOURCE_INIT  2
+#define        ACPI_MADT_APIC_INT_SOURCE_CPEI  3       /* Corrected Platform Error */
+       u_char          cpu_id;
+       u_char          cpu_eid;
+       u_char          sapic_vector;
+       u_int32_t       intr;
+       u_char          reserved[4];
+} __packed;
+
+struct MADT_APIC {
+       u_char          type;
+#define        ACPI_MADT_APIC_TYPE_LOCAL_APIC  0
+#define        ACPI_MADT_APIC_TYPE_IO_APIC     1
+#define        ACPI_MADT_APIC_TYPE_INT_OVERRIDE 2
+#define        ACPI_MADT_APIC_TYPE_NMI         3
+#define        ACPI_MADT_APIC_TYPE_LOCAL_NMI   4
+#define        ACPI_MADT_APIC_TYPE_LOCAL_OVERRIDE 5
+#define        ACPI_MADT_APIC_TYPE_IO_SAPIC    6
+#define        ACPI_MADT_APIC_TYPE_LOCAL_SAPIC 7
+#define        ACPI_MADT_APIC_TYPE_INT_SRC     8
+       u_char          len;
+       union {
+               struct MADT_local_apic local_apic;
+               struct MADT_io_apic io_apic;
+               struct MADT_int_override int_override;
+               struct MADT_nmi nmi;
+               struct MADT_local_nmi local_nmi;
+               struct MADT_local_apic_override local_apic_override;
+               struct MADT_io_sapic io_sapic;
+               struct MADT_local_sapic local_sapic;
+               struct MADT_int_src int_src;
+       } body;
+} __packed;
+
+struct MADTbody {
+       u_int32_t       lapic_addr;
+       u_int32_t       flags;
+#define        ACPI_APIC_FLAG_PCAT_COMPAT 1    /* System has dual-8259 setup. */
+       u_char          body[1];
+} __packed;
+
+struct HPETbody {
+       u_int32_t       block_hwrev:8,
+                       block_comparitors:5,
+                       block_counter_size:1,
+                       :1,
+                       block_legacy_capable:1,
+                       block_pcivendor:16;
+       u_int32_t       base_addr;
+       u_int64_t       reserved1;
+       u_int8_t        hpet_number;
+       u_int16_t       clock_tick __packed;
+} __packed;
+
+/* Embedded Controller Description Table */
+struct ECDTbody {
+       struct ACPIgas  ec_control;     /* Control register */
+       struct ACPIgas  ec_data;        /* Data register */
+       uint32_t        uid;            /* Same value as _UID in namespace */
+       uint8_t         gpe_bit;        /* GPE bit for the EC */
+       u_char          ec_id[1];       /* Variable length name string */
+} __packed;
+
+/*
+ * Addresses to scan on ia32 for the RSD PTR.  According to section 5.2.2
+ * of the ACPI spec, we only consider two regions for the base address:
+ * 1. EBDA (1 KB area addressed to by 16 bit pointer at 0x40E)
+ * 2. High memory (0xE0000 - 0xFFFFF)
+ */
+#define RSDP_EBDA_PTR  0x40E
+#define RSDP_EBDA_SIZE 0x400
+#define RSDP_HI_START  0xE0000
+#define RSDP_HI_SIZE   0x20000
+
+/* Find and map the RSD PTR structure and return it for parsing */
+struct ACPIsdt  *sdt_load_devmem(void);
+
+/*
+ * Load the DSDT from a previous save file.  Note that other tables are
+ * not saved (i.e. FADT)
+ */
+struct ACPIsdt  *dsdt_load_file(char *);
+
+/* Save the DSDT to a file */
+void            dsdt_save_file(char *, struct ACPIsdt *);
+
+/* Print out as many fixed tables as possible, given the RSD PTR */
+void            sdt_print_all(struct ACPIsdt *);
+
+/* Disassemble the AML in the DSDT */
+void            aml_disassemble(struct ACPIsdt *);
+
+/* Routines for accessing tables in physical memory */
+struct ACPIrsdp        *acpi_find_rsd_ptr(void);
+void           *acpi_map_physical(vm_offset_t, size_t);
+struct ACPIsdt *sdt_from_rsdt(struct ACPIsdt *, const char *);
+struct ACPIsdt *dsdt_from_fadt(struct FADTbody *);
+int             acpi_checksum(void *, size_t);
+
+/* Command line flags */
+extern int     dflag;
+extern int     tflag;
+extern int     vflag;
+
+#endif /* !_ACPIDUMP_H_ */
diff --git a/usr.sbin/acpi/iasl/Makefile b/usr.sbin/acpi/iasl/Makefile
new file mode 100644 (file)
index 0000000..f4e0a4b
--- /dev/null
@@ -0,0 +1,49 @@
+# $FreeBSD: src/usr.sbin/acpi/iasl/Makefile,v 1.5 2004/01/13 20:53:56 ru Exp $
+# $DragonFly: src/usr.sbin/acpi/iasl/Makefile,v 1.1 2004/07/05 00:22:43 dillon Exp $
+
+PROG=  iasl
+SRCS=  aslcompiler.y.h aslcompilerlex.l aslcompilerparse.y \
+       aslanalyze.c aslcodegen.c \
+       aslcompile.c aslerror.c aslfiles.c asllength.c \
+       asllisting.c aslload.c asllookup.c aslmain.c \
+       aslmap.c aslopcodes.c asloperands.c aslresource.c \
+       aslrestype1.c aslrestype2.c asltree.c aslutils.c \
+       asltransform.c aslfold.c aslstubs.c aslopt.c
+SRCS+= adisasm.c getopt.c osunixxf.c
+SRCS+= dbfileio.c dmbuffer.c dmnames.c dmopcode.c dmobject.c \
+        dmresrc.c dmresrcl.c dmresrcs.c dmutils.c dmwalk.c \
+        dsopcode.c dsutils.c dswexec.c dswload.c \
+       dswscope.c dswstate.c dsfield.c dsobject.c \
+        exconvrt.c excreate.c exdump.c exmisc.c \
+        exmutex.c exnames.c exoparg1.c exoparg2.c \
+        exoparg3.c exoparg6.c exprep.c exregion.c \
+        exresnte.c exresolv.c exresop.c exstore.c \
+        exstoren.c exstorob.c exsystem.c exutils.c \
+        nsaccess.c nsalloc.c nsdump.c nsnames.c nsobject.c \
+       nsparse.c nssearch.c nsutils.c nswalk.c nsxfobj.c \
+        psargs.c psopcode.c psparse.c psscope.c \
+        pstree.c psutils.c pswalk.c \
+        tbinstal.c tbutils.c \
+       utalloc.c utcopy.c utdebug.c utdelete.c \
+        utglobal.c utobject.c utmisc.c utmath.c
+
+MAN=   iasl.8
+
+CFLAGS+= -D_ACPI_ASL_COMPILER -I.
+
+CFLAGS+= -D_USE_BERKELEY_YACC
+LFLAGS=        -i -PAslCompiler
+YFLAGS=        -d -pAslCompiler
+
+CLEANFILES= aslcompiler.y.h aslcompilerlex.l aslcompilerparse.y
+
+aslcompiler.y.h: aslcompilerparse.h
+       cat ${.ALLSRC} > ${.TARGET}
+
+aslcompilerlex.l: aslcompiler.l
+       cat ${.ALLSRC} > ${.TARGET}
+
+aslcompilerparse.y: aslcompiler.y
+       cat ${.ALLSRC} > ${.TARGET}
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/acpi/iasl/iasl.8 b/usr.sbin/acpi/iasl/iasl.8
new file mode 100644 (file)
index 0000000..98f7fff
--- /dev/null
@@ -0,0 +1,175 @@
+.\"-
+.\" Copyright (c) 2003 Nate Lawson
+.\" 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
+.\"    in this position and unchanged.
+.\" 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.
+.\" 3. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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/iasl/iasl.8,v 1.2 2004/06/13 18:03:39 ru Exp $
+.\" $DragonFly: src/usr.sbin/acpi/iasl/iasl.8,v 1.1 2004/07/05 00:22:43 dillon Exp $
+.\"
+.Dd August 7, 2003
+.Dt IASL 8
+.Os
+.Sh NAME
+.Nm iasl
+.Nd Intel ACPI compiler/decompiler
+.Sh SYNOPSIS
+.Nm
+.Op Fl cefghl
+.Op Fl b Ar type
+.Op Fl d Ar file
+.Op Fl dc Ar file
+.Op Fl hc
+.Op Fl hr
+.Op Fl i Ar type
+.Op Fl ln
+.Op Fl ls
+.Op Fl oa
+.Op Fl of
+.Op Fl oi
+.Op Fl on
+.Op Fl ot
+.Op Fl p Ar prefix
+.Op Fl s Ar type
+.Op Fl t Ar type
+.Op Fl vi
+.Op Fl vo
+.Op Fl vr
+.Op Fl vs
+.Op Fl x Ar level
+.Ar input-file
+.Sh DESCRIPTION
+The
+.Nm
+utility is a compiler/decompiler for ACPI Source Language (ASL)
+and ACPI Machine Language (AML).
+Major features of
+.Nm
+include:
+.Bl -bullet -offset indent
+.It
+Full support for the ACPI 2.0b Specification including ASL grammar
+elements and operators.
+.It
+Extensive compiler syntax and semantic error checking, especially in
+the area of control methods.
+This reduces the number of errors that are
+not discovered until the AML code is actually interpreted (i.e., the
+compile-time error checking reduces the number of run-time errors).
+.It
+Multiple types of output files, including formatted listing files with
+intermixed source, several types of AML files, and error messages.
+.El
+.Sh OPTIONS
+.Bl -tag -width indent
+.It Fl b Sm Cm p | t | b Sm
+Create compiler debug/trace file
+.Pq Pa *.txt .
+Types: Parse/Tree/Both.
+.It Fl c
+Parse only, no output generation.
+.It Fl d Ar file
+Disassemble AML to ASL source code file
+.Pq Pa *.dsl .
+.It Fl dc Ar file
+Disassemble AML and immediately compile it.
+(Obtain DSDT from current system if no input file.)
+.It Fl e
+Generate
+.Fn External
+statements for unresolved symbols.
+.It Fl f
+Ignore errors, force creation of AML output file(s).
+.It Fl g
+Get ACPI tables and write to files
+.Pq Pa *.dat .
+.It Fl h
+Additional help and compiler debug options.
+.It Fl hc
+Display operators allowed in constant expressions.
+.It Fl hr
+Display ACPI reserved method names.
+.It Fl i Sm Cm a | c Sm
+Create assembler or C include file
+.Pa ( *.inc
+or
+.Pa *.h ) .
+.It Fl l
+Create mixed listing file (ASL source and AML)
+.Pq Pa *.lst .
+.It Fl ln
+Create namespace file
+.Pq Pa *.nsp .
+.It Fl ls
+Create combined source file (expanded includes)
+.Pq Pa *.src .
+.It Fl oa
+Disable all optimizations (compatibility mode).
+.It Fl of
+Disable constant folding.
+.It Fl oi
+Disable integer optimization to Zero/One/Ones.
+.It Fl on
+Disable named reference string optimization.
+.It Fl ot
+Display compile times.
+.It Fl p Ar prefix
+Specify filename prefix for all output files (including
+.Pa .aml ) .
+.It Fl s Sm Cm a | c Sm
+Create AML in assembler or C source file
+.Pa ( *.asm
+or
+.Pa *.c ) .
+.It Fl t Ar a|c
+Create AML in assembler or C hex table
+.Pq Pa *.hex .
+.It Fl vi
+Less verbose errors and warnings for use with IDEs.
+.It Fl vo
+Enable optimization comments.
+.It Fl vr
+Disable remarks.
+.It Fl vs
+Disable signon.
+.It Fl x Ar level
+Set debug level for trace output.
+.El
+.Sh SEE ALSO
+.Xr acpi 4 ,
+.Xr acpidump 8
+.Sh HISTORY
+The
+.Nm
+utility is provided with Intel ACPI-CA.
+It first appeared in
+.Fx 5.2 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+utility was written by
+.An Intel .
+This manual page was written by
+.An Nate Lawson .