diff options
| author | jmcneill <jmcneill@NetBSD.org> | 2020-12-06 02:57:29 +0000 |
|---|---|---|
| committer | jmcneill <jmcneill@NetBSD.org> | 2020-12-06 02:57:29 +0000 |
| commit | f6eb4f393b2c41561c7222ffd4fb1a638e92a582 (patch) | |
| tree | e9ab2de1d4a6c78358bfde911662fba617af4891 /usr.sbin/acpitools | |
| parent | 5a320838d14a9c1e35a26de81bf684cc346da20f (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.c | 61 | ||||
| -rw-r--r-- | usr.sbin/acpitools/acpidump/acpidump.8 | 10 | ||||
| -rw-r--r-- | usr.sbin/acpitools/acpidump/acpidump.c | 10 |
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"); |
