summaryrefslogtreecommitdiff
path: root/usr.sbin/acpitools
diff options
context:
space:
mode:
authorjmcneill <jmcneill@NetBSD.org>2020-12-06 02:57:29 +0000
committerjmcneill <jmcneill@NetBSD.org>2020-12-06 02:57:29 +0000
commitf6eb4f393b2c41561c7222ffd4fb1a638e92a582 (patch)
treee9ab2de1d4a6c78358bfde911662fba617af4891 /usr.sbin/acpitools
parent5a320838d14a9c1e35a26de81bf684cc346da20f (diff)
acpi: add character device for accessing ACPI tables
The /dev/acpi character device gives an aperture into physical memory that allows only read access to known ACPI tables: RSDP, XSDT/RSDT, and the root tables. Adapt acpidump(8) to use this interface by default, falling back to the old /dev/mem method if it is not available or if ACPIDUMP_USE_DEVMEM=1 is set in the environment. The user visible benefit of this change is that "options INSECURE" is no longer required to dump ACPI tables.
Diffstat (limited to 'usr.sbin/acpitools')
-rw-r--r--usr.sbin/acpitools/acpidump/acpi_user.c61
-rw-r--r--usr.sbin/acpitools/acpidump/acpidump.810
-rw-r--r--usr.sbin/acpitools/acpidump/acpidump.c10
3 files changed, 61 insertions, 20 deletions
diff --git a/usr.sbin/acpitools/acpidump/acpi_user.c b/usr.sbin/acpitools/acpidump/acpi_user.c
index a392dd54ebb..a498b9cc99c 100644
--- a/usr.sbin/acpitools/acpidump/acpi_user.c
+++ b/usr.sbin/acpitools/acpidump/acpi_user.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_user.c,v 1.5 2020/08/20 15:54:12 riastradh Exp $ */
+/* $NetBSD: acpi_user.c,v 1.6 2020/12/06 02:57:30 jmcneill Exp $ */
/*-
* Copyright (c) 1999 Doug Rabson
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: acpi_user.c,v 1.5 2020/08/20 15:54:12 riastradh Exp $");
+__RCSID("$NetBSD: acpi_user.c,v 1.6 2020/12/06 02:57:30 jmcneill Exp $");
#include <sys/param.h>
#include <sys/mman.h>
@@ -39,6 +39,7 @@ __RCSID("$NetBSD: acpi_user.c,v 1.5 2020/08/20 15:54:12 riastradh Exp $");
#include <sys/sysctl.h>
#include <err.h>
+#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
@@ -48,6 +49,7 @@ __RCSID("$NetBSD: acpi_user.c,v 1.5 2020/08/20 15:54:12 riastradh Exp $");
static char machdep_acpi_root[] = "hw.acpi.root";
static int acpi_mem_fd = -1;
+static bool acpi_mem_mmap = false;
struct acpi_user_mapping {
LIST_ENTRY(acpi_user_mapping) link;
@@ -61,15 +63,48 @@ static LIST_HEAD(acpi_user_mapping_list, acpi_user_mapping) maplist;
static void
acpi_user_init(void)
{
+ int saved_errno, use_devmem;
+ const char *s;
if (acpi_mem_fd == -1) {
- acpi_mem_fd = open("/dev/mem", O_RDONLY);
- if (acpi_mem_fd == -1)
- err(EXIT_FAILURE, "opening /dev/mem");
+ s = getenv("ACPIDUMP_USE_DEVMEM");
+ use_devmem = s != NULL && *s == '1';
+ if (!use_devmem) {
+ acpi_mem_fd = open("/dev/acpi", O_RDONLY);
+ }
+ if (acpi_mem_fd == -1) {
+ saved_errno = errno;
+ acpi_mem_fd = open("/dev/mem", O_RDONLY);
+ if (acpi_mem_fd == -1) {
+ errno = saved_errno;
+ } else {
+ acpi_mem_mmap = true;
+ }
+ }
+ if (acpi_mem_fd == -1) {
+ err(EXIT_FAILURE, "opening /dev/acpi");
+ }
LIST_INIT(&maplist);
}
}
+static void *
+acpi_user_read_table(vm_offset_t pa, size_t psize)
+{
+ void *data;
+ ssize_t len;
+
+ data = calloc(1, psize);
+ if (!data)
+ errx(EXIT_FAILURE, "out of memory");
+
+ len = pread(acpi_mem_fd, data, psize, pa);
+ if (len == -1)
+ errx(EXIT_FAILURE, "can't read table");
+
+ return data;
+}
+
static struct acpi_user_mapping *
acpi_user_find_mapping(vm_offset_t pa, size_t size)
{
@@ -82,16 +117,22 @@ acpi_user_find_mapping(vm_offset_t pa, size_t size)
}
/* Then create a new one */
- size = round_page(pa + size) - trunc_page(pa);
- pa = trunc_page(pa);
+ if (acpi_mem_mmap) {
+ size = round_page(pa + size) - trunc_page(pa);
+ pa = trunc_page(pa);
+ }
map = malloc(sizeof(struct acpi_user_mapping));
if (!map)
errx(EXIT_FAILURE, "out of memory");
map->pa = pa;
- map->va = mmap(0, size, PROT_READ, MAP_SHARED, acpi_mem_fd, pa);
+ if (acpi_mem_mmap) {
+ map->va = mmap(0, size, PROT_READ, MAP_SHARED, acpi_mem_fd, pa);
+ if ((intptr_t) map->va == -1)
+ err(EXIT_FAILURE, "can't map address");
+ } else {
+ map->va = acpi_user_read_table(pa, size);
+ }
map->size = size;
- if ((intptr_t) map->va == -1)
- err(EXIT_FAILURE, "can't map address");
LIST_INSERT_HEAD(&maplist, map, link);
return map;
diff --git a/usr.sbin/acpitools/acpidump/acpidump.8 b/usr.sbin/acpitools/acpidump/acpidump.8
index 664f17bede7..8d4bc318915 100644
--- a/usr.sbin/acpitools/acpidump/acpidump.8
+++ b/usr.sbin/acpitools/acpidump/acpidump.8
@@ -1,4 +1,4 @@
-.\" $NetBSD: acpidump.8,v 1.16 2019/06/22 12:39:40 maxv Exp $
+.\" $NetBSD: acpidump.8,v 1.17 2020/12/06 02:57:30 jmcneill Exp $
.\" ACPI (ACPI Package)
.\"
.\" Copyright (c) 1999 Doug Rabson <dfr@FreeBSD.org>
@@ -30,7 +30,7 @@
.\"
.\" $FreeBSD: head/usr.sbin/acpi/acpidump/acpidump.8 267668 2014-06-20 09:57:27Z bapt $
.\"
-.Dd June 22, 2019
+.Dd December 4, 2020
.Dt ACPIDUMP 8
.Os
.Sh NAME
@@ -73,7 +73,7 @@ When
is invoked without the
.Fl f
option, it will read ACPI tables from physical memory via
-.Pa /dev/mem .
+.Pa /dev/acpi .
First it searches for the RSDP
(Root System Description Pointer),
which has the signature
@@ -173,8 +173,8 @@ Dump the contents of the various fixed tables listed above.
Enable verbose messages.
.El
.Sh FILES
-.Bl -tag -width /dev/mem
-.It Pa /dev/mem
+.Bl -tag -width /dev/acpi
+.It Pa /dev/acpi
.El
.Sh EXAMPLES
If a developer requests a copy of your ASL, please use the following
diff --git a/usr.sbin/acpitools/acpidump/acpidump.c b/usr.sbin/acpitools/acpidump/acpidump.c
index bb3bf3614f9..22a699f355d 100644
--- a/usr.sbin/acpitools/acpidump/acpidump.c
+++ b/usr.sbin/acpitools/acpidump/acpidump.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acpidump.c,v 1.7 2017/08/04 06:30:36 msaitoh Exp $ */
+/* $NetBSD: acpidump.c,v 1.8 2020/12/06 02:57:30 jmcneill Exp $ */
/*-
* Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: acpidump.c,v 1.7 2017/08/04 06:30:36 msaitoh Exp $");
+__RCSID("$NetBSD: acpidump.c,v 1.8 2020/12/06 02:57:30 jmcneill Exp $");
#include <sys/param.h>
@@ -104,7 +104,7 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
- /* Get input either from file or /dev/mem */
+ /* Get input either from file or /dev/acpi */
if (dsdt_input_file != NULL) {
if (dflag == 0 && tflag == 0) {
warnx("Need to specify -d or -t with DSDT input file");
@@ -118,11 +118,11 @@ main(int argc, char *argv[])
rsdt = dsdt_load_file(dsdt_input_file);
} else {
if (vflag)
- warnx("loading RSD PTR from /dev/mem");
+ warnx("loading RSD PTR from /dev/acpi");
rsdt = sdt_load_devmem();
}
- /* Display misc. SDT tables (only available when using /dev/mem) */
+ /* Display misc. SDT tables (only available when using /dev/acpi) */
if (tflag) {
if (vflag)
warnx("printing various SDT tables");