diff options
author | kettenis <kettenis@openbsd.org> | 2018-06-24 10:39:59 +0000 |
---|---|---|
committer | kettenis <kettenis@openbsd.org> | 2018-06-24 10:39:59 +0000 |
commit | 6988a5d702ea0122c41a250f62242f3b9bbab6e8 (patch) | |
tree | 9e20602dc90f135c36447286149ca9305969034f | |
parent | If ACPI tables are present, set a global variable to point at their (diff) | |
download | wireguard-openbsd-6988a5d702ea0122c41a250f62242f3b9bbab6e8.tar.xz wireguard-openbsd-6988a5d702ea0122c41a250f62242f3b9bbab6e8.zip |
Add support for parsing XSDT tables. Add support for arm64.
ok deraadt@
-rw-r--r-- | usr.sbin/acpidump/Makefile | 5 | ||||
-rw-r--r-- | usr.sbin/acpidump/acpidump.c | 185 |
2 files changed, 148 insertions, 42 deletions
diff --git a/usr.sbin/acpidump/Makefile b/usr.sbin/acpidump/Makefile index 342a9023086..492f8850c9e 100644 --- a/usr.sbin/acpidump/Makefile +++ b/usr.sbin/acpidump/Makefile @@ -1,6 +1,7 @@ -# $OpenBSD: Makefile,v 1.6 2017/01/24 00:20:28 deraadt Exp $ +# $OpenBSD: Makefile,v 1.7 2018/06/24 10:39:59 kettenis Exp $ -.if (${MACHINE} == "i386") || (${MACHINE} == "amd64") +.if ${MACHINE} == "amd64" || ${MACHINE} == "arm64" || \ + ${MACHINE} == "i386" PROG= acpidump SRCS= acpidump.c LDADD= -lkvm diff --git a/usr.sbin/acpidump/acpidump.c b/usr.sbin/acpidump/acpidump.c index 4a499e2f47e..fdad67a7895 100644 --- a/usr.sbin/acpidump/acpidump.c +++ b/usr.sbin/acpidump/acpidump.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpidump.c,v 1.17 2016/09/26 19:58:26 kettenis Exp $ */ +/* $OpenBSD: acpidump.c,v 1.18 2018/06/24 10:39:59 kettenis Exp $ */ /* * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org> * All rights reserved. @@ -30,7 +30,6 @@ #include <sys/mman.h> #include <sys/queue.h> #include <sys/stat.h> -#include <machine/biosvar.h> #include <assert.h> #include <err.h> @@ -58,8 +57,13 @@ struct ACPIrsdp { u_char signature[8]; u_char sum; u_char oem[6]; - u_char res; + u_char rev; u_int32_t addr; +#define SIZEOF_RSDP_REV_0 20 + u_int32_t len; + u_int64_t xaddr; + u_char xsum; + u_char xres[3]; } __packed; struct ACPIsdt { @@ -174,6 +178,7 @@ int acpi_checksum(void *_p, size_t _length); struct acpi_user_mapping *acpi_user_find_mapping(vm_offset_t _pa, size_t _size); void *acpi_map_physical(vm_offset_t _pa, size_t _size); void acpi_user_init(void); +struct ACPIrsdp *acpi_check_rsd_ptr(vm_offset_t _pa); struct ACPIrsdp *acpi_find_rsd_ptr(void); void acpi_print_string(char *_s, size_t _length); void acpi_print_rsd_ptr(struct ACPIrsdp *_rp); @@ -181,14 +186,16 @@ struct ACPIsdt *acpi_map_sdt(vm_offset_t _pa); void aml_dump(struct ACPIsdt *_hdr); void acpi_print_sdt(struct ACPIsdt *_sdp); void acpi_print_rsdt(struct ACPIsdt *_rsdp); +void acpi_print_xsdt(struct ACPIsdt *_rsdp); void acpi_print_facp(struct FACPbody *_facp); void acpi_print_dsdt(struct ACPIsdt *_dsdp); void acpi_handle_dsdt(struct ACPIsdt *_dsdp); void acpi_handle_facp(struct FACPbody *_facp); void acpi_handle_rsdt(struct ACPIsdt *_rsdp); +void acpi_handle_xsdt(struct ACPIsdt *_rsdp); void asl_dump_from_devmem(void); void usage(void); -u_long bios_acpi_addr(void); +u_long efi_acpi_addr(void); struct ACPIsdt dsdt_header = { @@ -264,41 +271,47 @@ acpi_user_init(void) } struct ACPIrsdp * +acpi_check_rsd_ptr(vm_offset_t pa) +{ + struct ACPIrsdp rp; + + lseek(acpi_mem_fd, pa, SEEK_SET); + read(acpi_mem_fd, &rp, SIZEOF_RSDP_REV_0); + if (memcmp(rp.signature, "RSD PTR ", 8) != 0) + return NULL; + + if (rp.rev >= 2) { + read(acpi_mem_fd, &(rp.len), + sizeof(struct ACPIrsdp) - SIZEOF_RSDP_REV_0); + if (acpi_checksum(&rp, sizeof(struct ACPIrsdp)) == 0) + return acpi_map_physical(pa, sizeof(struct ACPIrsdp)); + } + + if (acpi_checksum(&rp, SIZEOF_RSDP_REV_0) == 0) + return (acpi_map_physical(pa, SIZEOF_RSDP_REV_0)); + + return NULL; +} + +struct ACPIrsdp * acpi_find_rsd_ptr(void) { - int i; - u_int8_t buf[sizeof(struct ACPIrsdp)]; + struct ACPIrsdp *rp; u_long addr; - if ((addr = bios_acpi_addr()) != 0) { - lseek(acpi_mem_fd, addr, SEEK_SET); - read(acpi_mem_fd, buf, 16); - if (!memcmp(buf, "RSD PTR ", 8)) { - read(acpi_mem_fd, buf + 16, - sizeof(struct ACPIrsdp) - 16); - if (!acpi_checksum(buf, sizeof(struct ACPIrsdp))) - return (acpi_map_physical(addr, - sizeof(struct ACPIrsdp))); - } - lseek(acpi_mem_fd, 0, SEEK_SET); + if ((addr = efi_acpi_addr()) != 0) { + if ((rp = acpi_check_rsd_ptr(addr))) + return rp; } - for (i = 0; i < 1024 * 1024; i += 16) { - lseek(acpi_mem_fd, i, SEEK_SET); - read(acpi_mem_fd, buf, 16); - if (!memcmp(buf, "RSD PTR ", 8)) { - /* Read the rest of the structure */ - read(acpi_mem_fd, buf + 16, - sizeof(struct ACPIrsdp) - 16); - - /* Verify checksum before accepting it. */ - if (acpi_checksum(buf, sizeof(struct ACPIrsdp))) - continue; - - return (acpi_map_physical(i, sizeof(struct ACPIrsdp))); - } + +#if defined(__amd64__) || defined (__i386__) + for (addr = 0; addr < 1024 * 1024; addr += 16) { + if ((rp = acpi_check_rsd_ptr(addr))) + return rp; } +#endif - return (0); + return NULL; } void @@ -322,7 +335,13 @@ acpi_print_rsd_ptr(struct ACPIrsdp *rp) fprintf(fhdr, "\n"); fprintf(fhdr, "RSD PTR: Checksum=%d, OEMID=", rp->sum); acpi_print_string(rp->oem, 6); + fprintf(fhdr, ", Revision=%d", rp->rev); fprintf(fhdr, ", RsdtAddress=0x%08x\n", rp->addr); + if (rp->rev >= 2) { + fprintf(fhdr, "\tLength=%d", rp->len); + fprintf(fhdr, ", XsdtAddress=0x%016llx", rp->xaddr); + fprintf(fhdr, ", Extended Checksum=%d\n", rp->xsum); + } fprintf(fhdr, "\n"); } @@ -399,6 +418,25 @@ acpi_print_rsdt(struct ACPIsdt *rsdp) } void +acpi_print_xsdt(struct ACPIsdt *rsdp) +{ + int i, entries; + u_int64_t *body = (u_int64_t *) rsdp->body; + + acpi_print_sdt(rsdp); + entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int64_t); + fprintf(fhdr, "\n"); + fprintf(fhdr, "\tEntries={ "); + for (i = 0; i < entries; i++) { + if (i > 0) + fprintf(fhdr, ", "); + fprintf(fhdr, "0x%016llx", body[i]); + } + fprintf(fhdr, " }\n"); + fprintf(fhdr, "\n"); +} + +void acpi_print_facp(struct FACPbody *facp) { char sep; @@ -525,6 +563,30 @@ acpi_handle_rsdt(struct ACPIsdt *rsdp) } void +acpi_handle_xsdt(struct ACPIsdt *rsdp) +{ + int i; + int entries; + struct ACPIsdt *sdp; + u_int64_t *body = (u_int64_t *) rsdp->body; + + aml_dump(rsdp); + entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int64_t); + acpi_print_xsdt(rsdp); + for (i = 0; i < entries; i++) { + sdp = (struct ACPIsdt *) acpi_map_sdt(body[i]); + if (acpi_checksum(sdp, sdp->len)) + errx(1, "XSDT entry %d is corrupt", i); + aml_dump(sdp); + if (!memcmp(sdp->signature, "FACP", 4)) { + acpi_handle_facp((struct FACPbody *) sdp->body); + } else { + acpi_print_sdt(sdp); + } + } +} + +void asl_dump_from_devmem(void) { struct ACPIrsdp *rp; @@ -548,12 +610,21 @@ asl_dump_from_devmem(void) err(1, "asl_dump_from_devmem"); acpi_print_rsd_ptr(rp); - rsdp = (struct ACPIsdt *) acpi_map_sdt(rp->addr); - if (memcmp(rsdp->signature, "RSDT", 4) || - acpi_checksum(rsdp, rsdp->len)) - errx(1, "RSDT is corrupted"); - - acpi_handle_rsdt(rsdp); + if (rp->addr != 0) { + rsdp = (struct ACPIsdt *) acpi_map_sdt(rp->addr); + if (memcmp(rsdp->signature, "RSDT", 4) || + acpi_checksum(rsdp, rsdp->len)) + errx(1, "RSDT is corrupted"); + + acpi_handle_rsdt(rsdp); + } else { + rsdp = (struct ACPIsdt *) acpi_map_sdt(rp->xaddr); + if (memcmp(rsdp->signature, "XSDT", 4) || + acpi_checksum(rsdp, rsdp->len)) + errx(1, "XSDT is corrupted"); + + acpi_handle_xsdt(rsdp); + } fclose(fhdr); } @@ -571,7 +642,7 @@ int main(int argc, char *argv[]) { struct stat st; - char c; + int c; while ((c = getopt(argc, argv, "o:")) != -1) { switch (c) { @@ -595,8 +666,40 @@ main(int argc, char *argv[]) return (0); } +#ifdef __aarch64__ + u_long -bios_acpi_addr(void) +efi_acpi_addr(void) +{ + kvm_t *kd; + struct nlist nl[2]; + uint64_t table; + + memset(&nl, 0, sizeof(nl)); + kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, NULL); + if (kd == NULL) + goto on_error; + nl[0].n_name = "efi_acpi_table"; + if (kvm_nlist(kd, nl) == -1) + goto on_error; + if (kvm_read(kd, nl[0].n_value, &table, sizeof(table)) == -1) + goto on_error; + + kvm_close(kd); + return table; + +on_error: + if (kd != NULL) + kvm_close(kd); + return (0); +} + +#else + +#include <machine/biosvar.h> + +u_long +efi_acpi_addr(void) { kvm_t *kd; struct nlist nl[2]; @@ -623,3 +726,5 @@ on_error: kvm_close(kd); return (0); } + +#endif |