On Sat, Jun 23, 2018 at 04:48:14PM +0200, Mark Kettenis wrote:
> 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?
>
ok on this one too, if you are still looking for oks
>
> 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
>