summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/Makefile4
-rw-r--r--usr.sbin/acpiscan/Makefile17
-rw-r--r--usr.sbin/acpiscan/acpiscan.865
-rw-r--r--usr.sbin/acpiscan/acpiscan.c619
-rw-r--r--usr.sbin/acpiscan/oslib.c441
-rw-r--r--usr.sbin/acpiscan/oslib.h205
6 files changed, 1349 insertions, 2 deletions
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index f3db1998404..95e625e2e43 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -1,8 +1,8 @@
-# $OpenBSD: Makefile,v 1.129 2006/10/29 18:06:07 norby Exp $
+# $OpenBSD: Makefile,v 1.130 2006/11/03 19:33:56 marco Exp $
.include <bsd.own.mk>
-SUBDIR= ac accton acpid acpidump adduser amd apm apmd arp authpf \
+SUBDIR= ac accton acpid acpidump acpiscan adduser amd apm apmd arp authpf \
bgpctl bgpd bind chroot config cron dev_mkdb dhcpd dhcrelay \
dvmrpctl dvmrpd \
edquota eeprom fdformat ftp-proxy gpioctl hostapd hotplugd httpd \
diff --git a/usr.sbin/acpiscan/Makefile b/usr.sbin/acpiscan/Makefile
new file mode 100644
index 00000000000..2569b8f5a4e
--- /dev/null
+++ b/usr.sbin/acpiscan/Makefile
@@ -0,0 +1,17 @@
+# $OpenBSD: Makefile,v 1.1 2006/11/03 19:33:56 marco Exp $
+
+.if (${MACHINE} == "i386") || (${MACHINE} == "amd64")
+PROG= acpiscan
+SRCS= acpiscan.c oslib.c
+.else
+NOPROG= yes
+.endif
+
+MAN= acpiscan.8
+
+CFLAGS+=-I${.CURDIR}
+LDADD=-l${MACHINE}
+
+BINDIR?=/usr/sbin
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/acpiscan/acpiscan.8 b/usr.sbin/acpiscan/acpiscan.8
new file mode 100644
index 00000000000..9daba1eff6d
--- /dev/null
+++ b/usr.sbin/acpiscan/acpiscan.8
@@ -0,0 +1,65 @@
+.\" $OpenBSD: acpiscan.8,v 1.1 2006/11/03 19:33:56 marco Exp $
+.\"
+.\" Copyright (c) 2006 Marco Peereboom
+.\"
+.\" 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 AUTHORS 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 AUTHORS 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.
+.\"
+.Dd November 3, 2006
+.Dt ACPISCAN 8
+.Os
+.Sh NAME
+.Nm acpiscan
+.Nd ACPI table dump utility
+.Sh SYNOPSIS
+.Nm acpiscan
+.Bk -words
+.Op Fl D filename
+.Op Fl f filename
+.Ek
+.Sh DESCRIPTION
+Dump relevant ACPI tables. For example: APIC, RSDT, DSDT etc
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It -D filename
+Dump the tables to human readable format from the supplied filename.
+The input file has to be a raw dump from the BIOS region.
+.It Fl f filename
+Dump BIOS memory region that contains ACPI tables and AML into multiple
+files where the name starts with the supplied filename. This dump can be
+dumped in human readable format with the -D command.
+.El
+.Pp
+Omitting these options will cause the program to dump the ACPI tables drectly
+from the BIOS memory region as human readable format.
+.Sh SEE ALSO
+.Xr acpi 4
+.Sh HISTORY
+The
+.Nm
+command first appeared in
+.Ox 4.1 .
+.Sh AUTHORS
+This
+.Nm
+utility was written by
+.An Jordan Hargrave Aq jordan@openbsd.org .
diff --git a/usr.sbin/acpiscan/acpiscan.c b/usr.sbin/acpiscan/acpiscan.c
new file mode 100644
index 00000000000..e0249038c13
--- /dev/null
+++ b/usr.sbin/acpiscan/acpiscan.c
@@ -0,0 +1,619 @@
+/* $OpenBSD: acpiscan.c,v 1.1 2006/11/03 19:33:56 marco Exp $ */
+/*
+ * Copyright (c) 2006 Jordan Hargrave <jordan@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "oslib.h"
+
+static const char *savename;
+
+#define ACPI_LAPIC 0x00
+#define ACPI_IOAPIC 0x01
+#define ACPI_INTSRC 0x02
+#define ACPI_NMISRC 0x03
+#define ACPI_LAPICNMI 0x04
+
+#define MPC_CPU 0x00
+#define MPC_BUS 0x01
+#define MPC_APIC 0x02
+#define MPC_INT 0x03
+#define MPC_LINT 0x04
+
+/* MPBIOS Structures */
+typedef struct _mps_root
+{
+ char mph_signature[4]; /* _MP_ */
+ uint32_t mph_physaddr;
+ uint8_t mph_length;
+ uint8_t mph_spec;
+ uint8_t mph_cksum;
+ uint8_t mph_feature[5];
+} PACKED mps_root;
+
+typedef struct _mps_header
+{
+ char mpc_signature[4];
+ uint16_t mpc_length;
+ uint8_t mpc_spec;
+ uint8_t mpc_cksum;
+ char mpc_oem[8];
+ char mpc_product[12];
+ uint32_t mpc_oemptr;
+ uint16_t mpc_oemsize;
+ uint16_t mpc_oemcount;
+ uint32_t mpc_lapic;
+ uint32_t reserved;
+} PACKED mps_header;
+
+typedef struct _mps_cpu
+{
+ uint8_t type;
+ uint8_t apicid;
+ uint8_t apicver;
+ uint8_t cpuflag;
+ uint32_t cpufeature;
+ uint32_t featureflag;
+ uint32_t reserved[2];
+} PACKED mps_cpu;
+
+typedef struct _mps_bus
+{
+ uint8_t type;
+ uint8_t busid;
+ char bustype[6];
+} PACKED mps_bus;
+
+typedef struct _mps_ioapic
+{
+ uint8_t type;
+ uint8_t apicid;
+ uint8_t apicver;
+ uint8_t flags;
+ uint32_t apicaddr;
+} PACKED mps_ioapic;
+
+typedef struct _mps_intsrc
+{
+ uint8_t type;
+ uint8_t irqtype;
+ uint16_t irqflag;
+ uint8_t srcbus;
+ uint8_t srcbusirq;
+ uint8_t dstapic;
+ uint8_t dstirq;
+} PACKED mps_intsrc;
+
+typedef struct _mps_lintsrc
+{
+ uint8_t type;
+ uint8_t irqtype;
+ uint16_t irqflag;
+ uint8_t srcbus;
+ uint8_t srcbusirq;
+ uint8_t dstapic;
+ uint8_t dstapiclint;
+} PACKED mps_lintsrc;
+
+typedef union _mps_entry
+{
+ uint8_t type;
+ mps_cpu m_cpu;
+ mps_bus m_bus;
+ mps_ioapic m_ioapic;
+ mps_intsrc m_int;
+ mps_lintsrc m_lint;
+} PACKED mps_entry;
+
+/* ACPI Structures */
+typedef struct _acpi_table_rsdp
+{
+ char signature[8];
+ uint8_t checksum;
+ char oem_id[6];
+ uint8_t revision;
+ uint32_t rsdt_address;
+ uint32_t length;
+ uint64_t xsdt_address;
+ uint8_t xchecksum;
+ uint8_t reserved[3];
+} PACKED acpi_table_rsdp;
+
+typedef struct _acpi_table_header
+{
+ uint8_t sig[4];
+ uint32_t length;
+ uint8_t rev;
+ uint8_t checksum;
+ uint8_t oem[6];
+ uint8_t oem_table[8];
+ uint32_t oem_rev;
+ char asl_compiler_id[4];
+ uint32_t asl_compiler_rev;
+} PACKED acpi_table_header;
+
+typedef struct _acpi_table_madt
+{
+ uint32_t local_apic_addr;
+ uint32_t compat;
+} PACKED acpi_table_madt;
+
+typedef struct _acpi_table_entry_header
+{
+ uint8_t type;
+ uint8_t length;
+} PACKED acpi_table_entry_header;
+
+typedef struct _acpi_facp
+{
+ uint32_t facs;
+ uint32_t dsdt;
+ uint8_t model;
+ uint8_t resvd;
+ uint16_t sciint;
+ uint32_t smicmd;
+ uint8_t enable;
+ uint8_t disable;
+ uint8_t s4bios;
+ uint8_t resvd2;
+ uint32_t pm1a_evt;
+ uint32_t pm1b_evt;
+ uint32_t pm1a_cnt;
+ uint32_t pm1b_cnt;
+ uint32_t pm2_cnt;
+ uint32_t pm_tmr;
+ uint32_t gpe0;
+ uint32_t gpe1;
+ uint8_t pm1_evt_len;
+ uint8_t pm1_cnt_len;
+ uint8_t pm2_cnt_len;
+ uint8_t pm_tm_len;
+ uint8_t gpe0_len;
+ uint8_t gpe1_len;
+ uint8_t gpe1_base;
+ uint8_t resvd3;
+ uint16_t lvl2;
+ uint16_t lvl3;
+ uint16_t size;
+ uint16_t stride;
+ uint8_t offset;
+ uint8_t width;
+ uint8_t day;
+ uint8_t mon;
+ uint8_t century;
+ uint16_t arch;
+ uint8_t resvd4;
+ uint32_t flags;
+ uint8_t reset_reg[12];
+ uint8_t reset_val;
+ uint8_t resvd5[3];
+ uint64_t x_facs;
+ uint64_t x_dsdt;
+} PACKED acpi_facp;
+
+typedef struct _acpi_table_lapic
+{
+ uint8_t acpi_id;
+ uint8_t apic_id;
+ uint32_t enabled;
+} PACKED acpi_table_lapic;
+
+typedef struct _acpi_table_ioapic
+{
+ uint8_t id;
+ uint8_t resvd;
+ uint32_t address;
+ uint32_t irq_base;
+} PACKED acpi_table_ioapic;
+
+typedef struct _acpi_table_int_src_ovr
+{
+ uint8_t bus;
+ uint8_t bus_irq;
+ uint8_t global_irq;
+ uint16_t flags;
+} PACKED acpi_table_int_src_ovr;
+
+typedef struct _acpi_table_lapic_nmi
+{
+ uint8_t acpi_id;
+ uint16_t flags;
+ uint8_t lint;
+} PACKED acpi_table_lapic_nmi;
+
+typedef struct _acpi_table_entry
+{
+ acpi_table_entry_header hdr;
+ union {
+ acpi_table_lapic m_lapic;
+ acpi_table_ioapic m_ioapic;
+ acpi_table_int_src_ovr m_intsrc;
+ //acpi_table_nmi_src m_nmisrc;
+ acpi_table_lapic_nmi m_lapicnmi;
+ } PACKED x;
+} PACKED acpi_table_entry;
+
+#ifdef MSDOS
+#pragma pack()
+#endif
+
+/* Show Table Entry */
+void show_acpitab(uint64_t addr);
+
+/* Return a string of n bytes */
+const char FAR
+*zstr(const char FAR *src, int n)
+{
+ static char tmp[32];
+
+ if (n >= sizeof(tmp)) {
+ n = sizeof(tmp)-1;
+ }
+ strncpy(tmp, src, n);
+ tmp[n] = 0;
+ return tmp;
+}
+
+void
+dump_facp(int rev, long len, void *buf)
+{
+ acpi_facp *afp = (acpi_facp *)buf;
+ uint8_t buf2[128];
+
+ if (rev == 3) {
+ printf(" XFACS : %llx\n", afp->x_facs);
+ printf(" XDSDT : %llx\n", afp->x_dsdt);
+ }
+ else {
+ printf(" FACS : %lx\n", afp->facs);
+ printf(" DSDT : %lx\n", afp->dsdt);
+ }
+ printf(" Model : %x\n", afp->model);
+ printf(" SCI Int : %x\n", afp->sciint);
+ printf(" SMI Cmd : %x\n", afp->smicmd);
+ printf(" S4 BIOS : %x\n", afp->s4bios);
+ printf(" enable : %x\n", afp->enable);
+ printf(" disable : %x\n", afp->disable);
+ printf(" PM1A : %.8x/%.8x\n", afp->pm1a_evt, afp->pm1a_cnt);
+ printf(" PM1B : %.8x/%.8x\n", afp->pm1b_evt, afp->pm1b_cnt);
+ printf(" PM2 : %x\n", afp->pm2_cnt);
+
+ if (physmemcpy(buf2, afp->facs, 128) == 0) {
+ printf("------ (facs) ------\n");
+ dump(buf2, 128);
+ }
+
+ /* Show DSDT */
+ if (rev == 3) {
+ show_acpitab(afp->x_dsdt);
+ }
+ else {
+ show_acpitab(afp->dsdt);
+ }
+}
+
+void dump_madt(int rev, long len, void *buf)
+{
+ acpi_table_madt *pmad = (acpi_table_madt *)buf;
+ acpi_table_entry *phdr = (acpi_table_entry *)&pmad[1];
+
+ printf("------------( madt ) ------------\n");
+ printf(" Local APIC: %lx\n", (long)pmad->local_apic_addr);
+ printf(" Compat : %lx\n", (long)pmad->compat);
+ len -= sizeof(acpi_table_madt);
+
+ while(len > 0) {
+ if (phdr->hdr.length == 0) {
+ printf("Invalid entry\n");
+ break;
+ }
+ len -= phdr->hdr.length;
+ printf(" type : %x length: %x", phdr->hdr.type, phdr->hdr.length);
+ switch(phdr->hdr.type) {
+ case ACPI_LAPIC:
+ printf(" (lapic)\tacpi_id:%.2x id:%.2x en:%.2x\n",
+ phdr->x.m_lapic.acpi_id, phdr->x.m_lapic.apic_id, phdr->x.m_lapic.enabled);
+ break;
+ case ACPI_IOAPIC:
+ printf(" (ioapic)\tioapic :%.2x addr:%.8x irq:%.4x\n",
+ phdr->x.m_ioapic.id, phdr->x.m_ioapic.address, phdr->x.m_ioapic.irq_base);
+ break;
+ case ACPI_INTSRC:
+ printf(" (int_src_ovr)\tbus:%.2x busirq:%.2x globalirq:%.2x flags:%.4x\n",
+ phdr->x.m_intsrc.bus, phdr->x.m_intsrc.bus_irq, phdr->x.m_intsrc.global_irq,
+ phdr->x.m_intsrc.flags);
+ break;
+ case ACPI_NMISRC:
+ printf(" nmi_src\n");
+ break;
+ case ACPI_LAPICNMI:
+ printf(" (lapic_nmi)\tacpi_id:%.2x flags:%.4x lint:%.2x\n",
+ phdr->x.m_lapicnmi.acpi_id, phdr->x.m_lapicnmi.flags, phdr->x.m_lapicnmi.lint);
+ break;
+ default:
+ printf(" unknown : %x\n", phdr->hdr.type);
+ break;
+ }
+ phdr = (acpi_table_entry *)((uint8_t *)phdr + phdr->hdr.length);
+ }
+}
+
+void
+dump_xsdt(int rev, uint32_t len, void *buf)
+{
+ uint64_t *pb = (uint64_t *)buf;
+
+ len /= sizeof(*pb);
+ while(len--) {
+ show_acpitab(*(pb++));
+ }
+}
+
+void
+dump_rsdt(int rev, uint32_t len, void *buf)
+{
+ uint32_t *pb = (uint32_t *)buf;
+
+ len /= sizeof(*pb);
+ while(len--) {
+ show_acpitab(*(pb++));
+ }
+}
+
+void
+dump_dsdt(int rev, uint32_t len, void *buf)
+{
+}
+
+/*========================================================================*
+ * Parse ACPI Table contents
+ *========================================================================*/
+void
+parse_acpitab(acpi_table_header *atab, uint32_t physaddr, uint32_t len)
+{
+ void *buf;
+ FILE *fp;
+ char name[64];
+ static int tid;
+
+ if ((buf = malloc(len)) == NULL) {
+ return;
+ }
+ physmemcpy(buf, physaddr, len);
+ dump(buf, len);
+
+ /* Save Table data */
+ if (savename != NULL) {
+ snprintf(name, sizeof(name), "%s.%s.%d", savename, zstr(atab->sig, 4), tid++);
+ if ((fp = fopen(name, "wb")) != NULL) {
+ fwrite(atab, sizeof(*atab), 1, fp);
+ fwrite(buf, len, 1, fp);
+ fclose(fp);
+ }
+ }
+ if (!strncmp(atab->sig, "SSDT", 4)) dump_dsdt(atab->rev, len, buf);
+ if (!strncmp(atab->sig, "DSDT", 4)) dump_dsdt(atab->rev, len, buf);
+ if (!strncmp(atab->sig, "XSDT", 4)) dump_xsdt(atab->rev, len, buf);
+ if (!strncmp(atab->sig, "RSDT", 4)) dump_rsdt(atab->rev, len, buf);
+ if (!strncmp(atab->sig, "APIC", 4)) dump_madt(atab->rev, len, buf);
+ if (!strncmp(atab->sig, "FACP", 4)) dump_facp(atab->rev, len, buf);
+ free(buf);
+}
+
+/*========================================================================*
+ * Display ACPI Table header
+ *========================================================================*/
+void
+show_acpitab(uint64_t addr)
+{
+ acpi_table_header atab;
+
+ if (physmemcpy(&atab, addr, sizeof(atab)) != 0) {
+ return;
+ }
+ printf("--------------------------------------\n");
+ printf("%s @ 0x%lx\n", zstr(atab.sig, 4), (long)addr);
+ printf(" length : %x\n", atab.length);
+ printf(" rev : %x\n", atab.rev);
+ printf(" cksum : %x\n", atab.checksum);
+ printf(" oem : %s\n", zstr(atab.oem, 6));
+ printf(" oemtab : %s\n", zstr(atab.oem_table, 8));
+ printf(" oem_rev: %x\n", atab.oem_rev);
+ printf(" asl id : %s\n", zstr(atab.asl_compiler_id, 4));
+ printf(" asl rev: %x\n", atab.asl_compiler_rev);
+
+ parse_acpitab(&atab, addr + sizeof(atab), atab.length - sizeof(atab));
+}
+
+/*===============================================================
+ * Display ACPI Table root header
+ *===============================================================*/
+void
+show_acpi(uint32_t addr)
+{
+ acpi_table_rsdp rsdp;
+
+ if (physmemcpy(&rsdp, addr, sizeof(rsdp)) != 0) {
+ return;
+ }
+ printf("===================== (ACPI TABLE) ======================\n");
+ printf("RSDP: 0x%lx\n", (long)addr);
+ printf(" signature: %s\n", zstr(rsdp.signature, 8));
+ printf(" checksum : %x\n", rsdp.checksum);
+ printf(" oem id : %s\n", zstr(rsdp.oem_id, 6));
+ printf(" revision : %x\n", rsdp.revision);
+ printf(" rsdt addr: %lx\n", rsdp.rsdt_address);
+ if (rsdp.revision == 2) {
+ /* ACPI 2.0 uses XSDT */
+ printf(" length : %lx\n", rsdp.length);
+ printf(" xsdt addr: %llx\n", rsdp.xsdt_address);
+ show_acpitab(rsdp.xsdt_address);
+ }
+ else {
+ /* ACPI 1.x uses RSDT */
+ show_acpitab(rsdp.rsdt_address);
+ }
+}
+
+/*===============================================================
+ *
+ * Display MPBIOS Table
+ *
+ *===============================================================*/
+const char *
+mp_inttype(int id)
+{
+ switch(id) {
+ case 0: return "int";
+ case 1: return "nmi";
+ case 2: return "smi";
+ case 3: return "ext";
+ }
+ return "xxx";
+}
+
+void
+show_mptable(uint32_t addr)
+{
+ mps_root root;
+ mps_header hdr;
+ mps_entry entry;
+ uint32_t ptbl;
+ uint8_t type;
+ int idx;
+
+ printf("===================== (MP TABLE) ======================\n");
+ physmemcpy(&root, addr, sizeof(root));
+ printf("Conf addr: %lx\n", root.mph_physaddr);
+ printf("Length : %x\n", root.mph_length);
+ printf("Spec Rev : %x\n", root.mph_spec);
+ printf("Checksum : %x\n", root.mph_cksum);
+ printf("Feature : %2x.%2x.%2x.%2x.%2x\n",
+ root.mph_feature[0], root.mph_feature[1], root.mph_feature[2],
+ root.mph_feature[3], root.mph_feature[4]);
+
+ ptbl = root.mph_physaddr + sizeof(hdr);
+ physmemcpy(&hdr, root.mph_physaddr, sizeof(hdr));
+
+ printf(" OEM ID : '%s'\n", zstr(hdr.mpc_oem, 8));
+ printf(" Prod ID : '%s'\n", zstr(hdr.mpc_product, 12));
+ printf(" Base len : %x\n", hdr.mpc_length);
+ printf(" Checksum : %x\n", hdr.mpc_cksum);
+ printf(" Ptr : %x\n", hdr.mpc_oemptr);
+ printf(" Size : %x\n", hdr.mpc_oemsize);
+ printf(" Count : %x\n", hdr.mpc_oemcount);
+ printf(" LAPIC : %x\n", hdr.mpc_lapic);
+
+ printf("---------\n");
+ for(idx=0; idx<hdr.mpc_oemcount; idx++) {
+ physmemcpy(&entry, ptbl, sizeof(entry));
+ switch(entry.type) {
+ case MPC_CPU:
+ printf(" cpu : id:%.2x apicver:%.2x cpuflags:%.2x cpusig:%.08x fflags:%.08x\n",
+ entry.m_cpu.apicid, entry.m_cpu.apicver, entry.m_cpu.cpuflag,
+ entry.m_cpu.cpufeature, entry.m_cpu.featureflag);
+ ptbl += sizeof(mps_cpu);
+ break;
+ case MPC_BUS:
+ printf(" bus : id:%.2x type:%s\n",
+ entry.m_bus.busid, zstr(entry.m_bus.bustype, 6));
+ ptbl += sizeof(mps_bus);
+ break;
+ case MPC_APIC:
+ printf(" apic: id:%.2x apicver:%.2x apicflag:%.2x addr:%.08x\n",
+ entry.m_ioapic.apicid, entry.m_ioapic.apicver, entry.m_ioapic.flags,
+ entry.m_ioapic.apicaddr);
+ ptbl += sizeof(mps_ioapic);
+ break;
+ case MPC_INT:
+ printf(" int : type:%.2x[%s] pol:%x trig:%x bus:%.2x irq:%.2x -> apic:%.2x irq:%.2x\n",
+ entry.m_int.irqtype, mp_inttype(entry.m_int.irqtype), entry.m_int.irqflag&3,
+ (entry.m_int.irqflag>>2)&3, entry.m_int.srcbus, entry.m_int.srcbusirq,
+ entry.m_int.dstapic, entry.m_int.dstirq);
+ ptbl += sizeof(mps_intsrc);
+ break;
+ case MPC_LINT:
+ printf(" lint: type:%.2x[%s] pol:%x trig:%x bus:%.2x irq:%.2x -> apic:%.2x lint:%.2x\n",
+ entry.m_lint.irqtype, mp_inttype(entry.m_lint.irqtype), entry.m_lint.irqflag&3,
+ (entry.m_lint.irqflag>>2)&3, entry.m_lint.srcbus, entry.m_lint.srcbusirq,
+ entry.m_lint.dstapic, entry.m_lint.dstapiclint);
+ ptbl += sizeof(mps_lintsrc);
+ break;
+ default:
+ printf(" unknown: %x\n", type);
+ return;
+ }
+ }
+}
+
+/* Uses neat feature of physmemcpy */
+void
+showtable(const char *name)
+{
+ FILE *fp;
+ long len;
+ void *buf;
+
+ set_physmemfile(name, 0);
+ show_acpitab(0);
+}
+
+void
+usage(void)
+{
+ extern char *__progname;
+
+ fprintf(stderr, "usage: %s [-p filename] [-f filename]\n", __progname);
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ uint32_t addr;
+ int ch;
+
+ while ((ch = getopt(argc, argv, "f:p:")) != -1) {
+ switch (ch) {
+ case 'f': /* save */
+ savename = optarg;
+ break;
+ case 'p': /* print */
+ showtable(optarg);
+ return (0);
+ break;
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+ }
+
+ /* Dump MP Table */
+ addr = scanmem(0xF0000L, 0xFFFFFL, 16, 4, "_MP_");
+ if (addr != 0)
+ show_mptable(addr);
+
+ /* Dump ACPI Table */
+ addr = scanmem(0xF0000L, 0xFFFFFL, 16, 8, "RSD PTR ");
+ if (addr != 0)
+ show_acpi(addr);
+
+ return (0);
+}
diff --git a/usr.sbin/acpiscan/oslib.c b/usr.sbin/acpiscan/oslib.c
new file mode 100644
index 00000000000..2a624272575
--- /dev/null
+++ b/usr.sbin/acpiscan/oslib.c
@@ -0,0 +1,441 @@
+/* $OpenBSD: oslib.c,v 1.1 2006/11/03 19:33:56 marco Exp $ */
+/*
+ * Copyright (c) 2006 Jordan Hargrave <jordan@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <oslib.h>
+
+#define need_pciio 1
+#define need_physmem 1
+#define need_portio 1
+//#define need_pthread 1
+
+/*=====================================================================
+ *
+ * OpenBSD User Mode
+ *
+ *=====================================================================*/
+#ifdef __OpenBSD__
+void set_iopl(int x)
+{
+ i386_iopl(x);
+}
+#endif
+
+/*=====================================================================
+ *
+ * Solaris User Mode
+ *
+ *=====================================================================*/
+#if defined(__sun__)
+void set_iopl(int x)
+{
+ sysi86(SI86V86,V86SC_IOPL,0x3000);
+}
+#endif
+
+/*=====================================================================
+ *
+ * UnixWare User Mode
+ *
+ *=====================================================================*/
+#if defined(SCO)
+void set_iopl(int x)
+{
+ sysi86(SI86IOPL, x);
+}
+#endif
+
+/*=====================================================================
+ *
+ * Linux Kernel Mode
+ *
+ *=====================================================================*/
+#if defined(linux) && defined(__KERNEL__)
+
+#if (LINUX_KERNEL_VERSION >= 0x020400)
+MODULE_LICENSE("GPL");
+#endif
+
+char kernel_version[] = UTS_RELEASE;
+
+#define printf printk
+
+#ifndef min
+#define min(a,b) ((a)<(b)?(a):(b))
+#endif
+
+void ZeroMem(void *a, int c)
+{
+ uint8_t *b = (uint8_t *)a;
+ while(c--) {
+ *(b++) = 0;
+ }
+}
+
+void CopyMem(void *d, const void *s, int c)
+{
+ uint8_t *a = (uint8_t *)d;
+ uint8_t *b = (uint8_t *)s;
+
+ while(c--) {
+ *(a++) = *(b++);
+ }
+}
+
+#undef need_pthread
+#undef need_physmem
+int physmemcpy(void *dest, uint32_t src, size_t len)
+{
+ memcpy(dest, phys_to_virt(src), len);
+ return 0;
+}
+
+int physmemcmp(const void *dest, uint32_t src, size_t len)
+{
+ uint8_t buf[len];
+
+ physmemcpy(buf, src, len);
+ return memcmp(dest, buf, len);
+}
+#endif
+
+/*=====================================================================
+ *
+ * Linux User Mode
+ *
+ *=====================================================================*/
+#if defined(linux) && !defined(__KERNEL__)
+void set_iopl(int x)
+{
+ iopl(x);
+}
+
+#define need_mmap 1
+
+#undef need_pciio
+int pci_read_n(int b, int d, int f, int reg, int len, void *buf)
+{
+ char dev[32];
+ int fd;
+
+ memset(buf, 0, len);
+ sprintf(dev,"/proc/bus/pci/%.02x/%.02x.%x", b,d,f);
+ if ((fd = open(dev,O_RDWR)) >= 0) {
+ pread(fd,buf,len,reg);
+ close(fd);
+ return 0;
+ }
+ return -1;
+}
+#endif
+
+/*=====================================================================
+ *
+ * DOS 16-bit Mode
+ *
+ *=====================================================================*/
+#ifdef MSDOS
+
+/* Converts linear address to 16:16 pointer */
+void FAR *lintoseg(uint32_t v);
+#pragma aux lintoseg = "shl dx, 12" parm caller [dx ax] value [dx ax];
+
+void set_iopl(int x)
+{
+}
+
+#undef need_portio
+uint8_t os_inb(uint16_t port)
+{
+ return inb(port);
+}
+uint16_t os_inw(uint16_t port)
+{
+ return inw(port);
+}
+uint32_t os_inl(uint16_t port)
+{
+ return inl(port);
+}
+void os_outb(uint16_t port, uint8_t val)
+{
+ outb(port, val);
+}
+void os_outw(uint16_t port, uint16_t val)
+{
+ outw(port, val);
+}
+void os_outl(uint16_t port, uint32_t val)
+{
+ outl(port, val);
+}
+
+#ifdef WATCOM
+#pragma aux os_inb = "in al, dx" value [al] parms [dx];
+#pragma aux os_inw = "in ax, dx" value [ax] parms [dx];
+#pragma aux os_inl = \
+ "in eax, dx" \
+"mov dx, ax" \
+"shr eax, 16", \
+"xchg dx, ax" value [dx ax] parms [dx];
+
+#pragma aux os_outb = "out dx, al" parms [dx] [al];
+#pragma aux os_outw = "out dx, ax" parms [dx] [ax];
+#pragma aux os_outl = \
+ "mov ax, cx" \
+"shl eax, 16" \
+"mov ax, bx" \
+"out dx, eax" parm [dx] [cx bx] modifies [ax];
+#endif
+
+#undef need_physmem
+int physmemcpy(void FAR *dest, uint32_t src, int len)
+{
+ _fmemcpy(dest, lintoseg(src), len);
+ return 0;
+}
+
+int physmemcmp(const void FAR *dest, uint32_t src, int len)
+{
+ return _fmemcmp(dest, lintoseg(src), len);
+}
+#endif /* end dos */
+
+/*=====================================================================
+ *
+ * Common Physmem code
+ *
+ *=====================================================================*/
+#ifdef need_physmem
+
+#define PAGE_OFFSET(x) (uint64_t)((x) & ~PAGE_MASK)
+
+static const char *memfile = "/dev/mem";
+static uint64_t memoff;
+
+int physmemcpy(void FAR *dest, uint32_t src, size_t len)
+{
+ int fd,rc;
+ uint64_t memlimit;
+
+ memset(dest, 0, len);
+ if ((fd = open(memfile, O_RDONLY)) < 0) {
+ printf("Can't open: %s\n", memfile);
+ exit(0);
+ }
+#if 0
+ memlimit = lseek(fd, 0, SEEK_END);
+ if (src < (unsigned)memoff || src+len > memlimit + memoff) {
+ close(fd);
+ return -1;
+ }
+#endif
+ src -= memoff;
+#ifdef need_mmap
+ {
+ uint64_t offset;
+ void *ptr;
+
+ offset = PAGE_OFFSET(src);
+ ptr = mmap(NULL, offset+len, PROT_READ, MAP_PRIVATE, fd, src-offset);
+ if (ptr == (void *)-1L) {
+ printf("Can't mmap @ 0x%.08lx! %d\n", src, errno);
+ }
+ else {
+ memcpy(dest, ptr+offset, len);
+ munmap(ptr, offset+len);
+ }
+ }
+#else
+ rc=pread(fd, dest, len, (off_t)(src - memoff));
+ if (rc < 0) {
+ printf("Can't pread64 @ 0x%.08x %d\n", src, errno);
+ }
+#endif
+ close(fd);
+ return 0;
+}
+
+int physmemcmp(const void FAR *dest, uint32_t src, size_t len)
+{
+ unsigned char bufr[len];
+
+ physmemcpy(bufr, src, len);
+ return memcmp(bufr, dest, len);
+}
+#endif
+
+/*=====================================================================
+ *
+ * Common PCI Access code
+ *
+ *=====================================================================*/
+#ifdef need_pciio
+#define PCI_ADDR(b,d,f,r) (0x80000000+((b)<<16)+((d)<<10)+((f)<<8)+(r))
+int pci_read_n(int b, int d, int f, int reg, int len, void *buf)
+{
+ uint8_t *ptr = (uint8_t *)buf;
+ while(len--) {
+ os_outl(0xCF8, PCI_ADDR(b,d,f,reg++));
+ *(ptr++) = os_inb(0xCF8);
+ }
+}
+#endif
+
+/*=====================================================================
+ *
+ * Common Port code
+ *
+ *=====================================================================*/
+#ifdef need_portio
+uint8_t os_inb(uint16_t port)
+{
+ uint8_t v;
+
+ __asm__ __volatile__ ("inb %w1,%b0" : "=a" (v) : "Nd" (port));
+ return v;
+}
+uint16_t os_inw(uint16_t port)
+{
+ uint16_t v;
+
+ __asm__ __volatile__ ("inw %w1,%w0" : "=a" (v) : "Nd" (port));
+ return v;
+}
+uint32_t os_inl(uint16_t port)
+{
+ uint32_t v;
+
+ __asm__ __volatile__ ("inl %w1,%0" : "=a" (v) : "Nd" (port));
+ return v;
+}
+void os_outb(uint16_t port, uint8_t v)
+{
+ __asm__ __volatile__ ("outb %b0,%w1" : "=a" (v) : "Nd" (port));
+}
+void os_outw(uint16_t port, uint16_t v)
+{
+ __asm__ __volatile__ ("outw %w0,%w1" : "=a" (v) : "Nd" (port));
+}
+void os_outl(uint16_t port, uint32_t v)
+{
+ __asm__ __volatile__ ("outl %0,%w1" : "=a" (v) : "Nd" (port));
+}
+#endif
+
+
+/*==================================================================
+ * common pthread routines
+ *==================================================================*/
+#ifdef need_pthread
+#include <pthread.h>
+
+typedef int (*threadproc_t)(void *);
+
+typedef struct
+{
+ pthread_t tid;
+ threadproc_t proc;
+ void *arg;
+} osthread_t;
+
+static void *os_threadhelper(void *arg)
+{
+ osthread_t *thrd = (osthread_t *)arg;
+
+ thrd->proc(thrd->arg);
+ return NULL;
+}
+
+osthread_t *os_create_thread(threadproc_t threadproc, void *arg)
+{
+ osthread_t *thrd;
+
+ if ((thrd = (osthread_t *)malloc(sizeof(osthread_t))) == NULL) {
+ return NULL;
+ }
+ thrd->proc = threadproc;
+ thrd->arg = arg;
+ pthread_create(&thrd->tid, NULL, os_threadhelper, thrd);
+ return thrd;
+}
+
+int os_destroy_thread(osthread_t *thrd)
+{
+ void *rcval;
+
+ pthread_join(thrd->tid, &rcval);
+ free(thrd);
+}
+#endif
+
+/*====================================================================*
+ * Common code
+ *====================================================================*/
+uint32_t scanmem(uint32_t src, uint32_t end, int step, int sz,
+ const void FAR *mem)
+{
+ while(src < end) {
+ if (physmemcmp(mem, src, sz) == 0) {
+ return src;
+ }
+ src += step;
+ }
+ return 0;
+}
+
+void set_physmemfile(const char *name, uint64_t offset)
+{
+#ifdef need_physmem
+ memfile = name;
+ memoff = offset;
+#endif
+}
+
+char dxc(char v, int t)
+{
+ if (v < ' ' || v > 'z' || t) {
+ return '.';
+ }
+ return v;
+}
+uint8_t dxb(uint8_t v, int t)
+{
+ return (t) ? 0xFF : v;
+}
+
+void dump(void FAR *dest, int len)
+{
+ uint8_t FAR *b = (uint8_t FAR *)dest;
+ int i,j;
+
+ for(i=0;i<len;i+=16) {
+ printf("%.06x: ", i);
+ for(j=0;j<16;j++) {
+ if (i+j >= len) {
+ printf("-- ");
+ }
+ else {
+ printf("%.02x ", dxb(b[i+j],i+j>=len));
+ }
+ }
+ printf(" ");
+ for(j=0;j<16;j++) {
+ printf("%c", dxc(b[i+j],i+j>=len));
+ }
+ printf("\n");
+ }
+}
diff --git a/usr.sbin/acpiscan/oslib.h b/usr.sbin/acpiscan/oslib.h
new file mode 100644
index 00000000000..218fa1e9b1b
--- /dev/null
+++ b/usr.sbin/acpiscan/oslib.h
@@ -0,0 +1,205 @@
+/* $OpenBSD: oslib.h,v 1.1 2006/11/03 19:33:56 marco Exp $ */
+/*
+ * Copyright (c) 2006 Jordan Hargrave <jordan@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __oslib_h__
+#define __oslib_h__
+
+/*=========== ( DOS 16-bit ) ============================= */
+#ifdef MSDOS
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <stddef.h>
+#include <dos.h>
+#include <time.h>
+
+#define FAR far
+#define PACKED
+
+typedef unsigned __int64 uint64_t;
+typedef unsigned long uint32_t;
+typedef unsigned short uint16_t;
+typedef unsigned char uint8_t;
+
+#define ZeroMem(a,c) _fmemset((void FAR *)a,0,c)
+#define CopyMem(a,b,c) _fmemcpy((void FAR *)(a),(void FAR *)b,c)
+#endif
+
+/*==== ( OpenBSD user mode ) ============================= */
+#ifdef __OpenBSD__
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <fcntl.h>
+#include <time.h>
+#include <machine/pio.h>
+#include <i386/sysarch.h>
+
+#define ZeroMem(buf,len) bzero(buf,len)
+#define CopyMem(dest,src,len) bcopy(src,dest,len)
+
+#define cpu_to_be16 be16toh
+#define cpu_to_be32 be32toh
+#define cpu_to_be64 be64toh
+#define be16_to_cpu htobe16
+#define be32_to_cpu htobe32
+#define be64_to_cpu htobe64
+#endif
+
+/*==== ( FreeBSD user mode ) ============================= */
+#ifdef __FreeBSD__
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <stdint.h>
+#include <fcntl.h>
+#include <time.h>
+
+#define ZeroMem(buf,len) bzero(buf,len)
+#define CopyMem(dest,src,len) bcopy(src,dest,len)
+#endif
+
+/*==== ( SCO UNIXWARE user mode ) ============================= */
+#ifdef SCO
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <sys/sysi86.h>
+#include <sys/inline.h>
+#include <inttypes.h>
+
+#define ZeroMem(buf,len) bzero(buf,len)
+#define CopyMem(dest,src,len) bcopy(src,dest,len)
+#endif
+
+/*==== ( Solaris user mode ) ============================= */
+#ifdef __sun__
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <sys/sysi86.h>
+//#include <sys/inline.h>
+
+#define ZeroMem(buf,len) bzero(buf,len)
+#define CopyMem(dest,src,len) bcopy(src,dest,len)
+
+#endif
+
+/*==== ( Linux kernel mode ) ============================= */
+#if defined(linux) && defined(__KERNEL__)
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/miscdevice.h>
+
+#endif
+
+/*==== ( Linux user mode ) ============================= */
+#if defined(linux) && !defined(__KERNEL__)
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <stddef.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/io.h>
+#include <inttypes.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <asm/page.h>
+#include <errno.h>
+#include <endian.h>
+#include <byteswap.h>
+
+#endif
+
+/*====================================================*
+ * Common code
+ *====================================================*/
+#ifndef FAR
+# define FAR
+#endif
+#ifndef PACKED
+# define PACKED __attribute__((packed))
+#endif
+
+extern void os_dump(const void FAR *, int);
+
+/* ----==== Memory I/O ====---- */
+extern void set_physmemfile(const char FAR *, uint64_t);
+extern int physmemcpy(void FAR *dest, uint32_t src, size_t len);
+extern int physmemcmp(const void FAR *dest, uint32_t src, size_t len);
+extern uint32_t scanmem(uint32_t src, uint32_t end, int step, int sz,
+ const void FAR *mem);
+
+/* ----==== Port I/O ====---- */
+extern void set_iopl(int);
+extern uint8_t os_inb(uint16_t);
+extern uint16_t os_inw(uint16_t);
+extern uint32_t os_inl(uint16_t);
+extern void os_outb(uint16_t, uint8_t);
+extern void os_outw(uint16_t, uint16_t);
+extern void os_outl(uint16_t, uint32_t);
+
+/* ----==== PCI ====---- */
+extern int pci_read_n(int, int, int, int, int, void FAR *);
+
+#define cpu_to_le16(x) (x)
+#define cpu_to_le32(x) (x)
+#define cpu_to_le64(x) (x)
+
+#define le16_to_cpu(x) (x)
+#define le32_to_cpu(x) (x)
+#define le64_to_cpu(x) (x)
+
+/* AABBCCDD
+ * xchg dh, al = DDBBCCAA
+ * xchg dl, ah = DDCCBBAA
+ */
+#ifdef WATCOM
+#pragma aux cpu_to_be16 = "xchg ah, al" parm [ax] value [ax];
+#pragma aux cpu_to_be32 = \
+ "xchg dh, al" \
+"xchg dl, ah" \
+parm caller [dx ax] value [dx ax];
+#endif
+
+#endif
+