The diff below adds arm64 support to acpidump(8).  It renames
bios_acpi_addr() into efi_acpi_addr() and duplicates the function
because on arm64 I just need to read a 64-bit integer I'm considering
changing amd64 to use a variable with the same name to get rid of the
#ifdef.  The code that grovels through low memory to discover the ACPI
tables is only enabled for amd64 and i386 now.

Since on my arm64 system there is no RSDT, this adds support for using
the XSDT instead.  There is a fair bit of code reorg to handle the
discovery of the RSD PTR table as the pointer to the XSDT won't be
there on ACPI 1.0 systems.

ok?


Index: usr.sbin/acpidump/Makefile
===================================================================
RCS file: /cvs/src/usr.sbin/acpidump/Makefile,v
retrieving revision 1.6
diff -u -p -r1.6 Makefile
--- usr.sbin/acpidump/Makefile  24 Jan 2017 00:20:28 -0000      1.6
+++ usr.sbin/acpidump/Makefile  23 Jun 2018 14:37:02 -0000
@@ -1,6 +1,7 @@
 # $OpenBSD: Makefile,v 1.6 2017/01/24 00:20:28 deraadt Exp $
 
-.if (${MACHINE} == "i386") || (${MACHINE} == "amd64")
+.if ${MACHINE} == "amd64" || ${MACHINE} == "arm64" || \
+    ${MACHINE} == "i386"
 PROG= acpidump
 SRCS= acpidump.c
 LDADD= -lkvm
Index: usr.sbin/acpidump/acpidump.c
===================================================================
RCS file: /cvs/src/usr.sbin/acpidump/acpidump.c,v
retrieving revision 1.17
diff -u -p -r1.17 acpidump.c
--- usr.sbin/acpidump/acpidump.c        26 Sep 2016 19:58:26 -0000      1.17
+++ usr.sbin/acpidump/acpidump.c        23 Jun 2018 14:37:02 -0000
@@ -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 _leng
 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
 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");
+       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_rsdt(rsdp);
+               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
+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
-bios_acpi_addr(void)
+efi_acpi_addr(void)
 {
        kvm_t           *kd;
        struct nlist     nl[2];
@@ -623,3 +726,5 @@ on_error:
                kvm_close(kd);
        return (0);
 }
+
+#endif

Reply via email to