Home | History | Annotate | Line # | Download | only in acpidump
acpi.c revision 1.15.8.2
      1  1.15.8.2    martin /* $NetBSD: acpi.c,v 1.15.8.2 2018/12/04 11:58:10 martin Exp $ */
      2       1.1  christos 
      3       1.1  christos /*-
      4       1.1  christos  * Copyright (c) 1998 Doug Rabson
      5       1.1  christos  * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki (at) FreeBSD.org>
      6       1.1  christos  * All rights reserved.
      7       1.1  christos  *
      8       1.1  christos  * Redistribution and use in source and binary forms, with or without
      9       1.1  christos  * modification, are permitted provided that the following conditions
     10       1.1  christos  * are met:
     11       1.1  christos  * 1. Redistributions of source code must retain the above copyright
     12       1.1  christos  *    notice, this list of conditions and the following disclaimer.
     13       1.1  christos  * 2. Redistributions in binary form must reproduce the above copyright
     14       1.1  christos  *    notice, this list of conditions and the following disclaimer in the
     15       1.1  christos  *    documentation and/or other materials provided with the distribution.
     16       1.1  christos  *
     17       1.1  christos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     18       1.1  christos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19       1.1  christos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20       1.1  christos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     21       1.1  christos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22       1.1  christos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     23       1.1  christos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     24       1.1  christos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     25       1.1  christos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     26       1.1  christos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27       1.1  christos  * SUCH DAMAGE.
     28       1.1  christos  *
     29  1.15.8.1    martin  *	$FreeBSD: head/usr.sbin/acpi/acpidump/acpi.c 321299 2017-07-20 17:36:17Z emaste $
     30       1.1  christos  */
     31       1.1  christos 
     32       1.5    cegger #include <sys/cdefs.h>
     33  1.15.8.2    martin __RCSID("$NetBSD: acpi.c,v 1.15.8.2 2018/12/04 11:58:10 martin Exp $");
     34       1.5    cegger 
     35       1.5    cegger #include <sys/param.h>
     36       1.5    cegger #include <sys/endian.h>
     37       1.5    cegger #include <sys/stat.h>
     38       1.5    cegger #include <sys/wait.h>
     39       1.5    cegger #include <assert.h>
     40       1.5    cegger #include <err.h>
     41       1.5    cegger #include <fcntl.h>
     42       1.5    cegger #include <paths.h>
     43  1.15.8.2    martin #include <stdbool.h>
     44       1.5    cegger #include <stdio.h>
     45       1.5    cegger #include <stdint.h>
     46       1.5    cegger #include <stdlib.h>
     47       1.5    cegger #include <string.h>
     48       1.5    cegger #include <unistd.h>
     49       1.5    cegger #include <stddef.h>
     50  1.15.8.1    martin #include <uuid.h>
     51       1.5    cegger 
     52       1.5    cegger #include "acpidump.h"
     53       1.5    cegger 
     54       1.5    cegger #define BEGIN_COMMENT	"/*\n"
     55       1.5    cegger #define END_COMMENT	" */\n"
     56       1.5    cegger 
     57  1.15.8.2    martin /* Commonly used helper functions */
     58       1.5    cegger static void	acpi_print_string(char *s, size_t length);
     59  1.15.8.2    martin static void	acpi_print_tabs(unsigned int n);
     60  1.15.8.2    martin static void	acpi_dump_bytes(uint8_t *p, uint32_t len, unsigned int ntabs);
     61  1.15.8.2    martin static void	acpi_dump_table(ACPI_TABLE_HEADER *sdp);
     62       1.5    cegger static void	acpi_print_gas(ACPI_GENERIC_ADDRESS *gas);
     63       1.5    cegger static void	acpi_print_pci(uint16_t vendorid, uint16_t deviceid,
     64       1.5    cegger 		    uint8_t seg, uint8_t bus, uint8_t device, uint8_t func);
     65  1.15.8.1    martin static void	acpi_print_pci_sbdf(uint8_t seg, uint8_t bus, uint8_t device,
     66       1.5    cegger 		    uint8_t func);
     67       1.5    cegger #ifdef notyet
     68       1.5    cegger static void	acpi_print_hest_generic_status(ACPI_HEST_GENERIC_STATUS *);
     69       1.5    cegger static void	acpi_print_hest_generic_data(ACPI_HEST_GENERIC_DATA *);
     70       1.5    cegger #endif
     71       1.5    cegger static void	acpi_print_whea(ACPI_WHEA_HEADER *whea,
     72       1.5    cegger 		    void (*print_action)(ACPI_WHEA_HEADER *),
     73       1.5    cegger 		    void (*print_ins)(ACPI_WHEA_HEADER *),
     74       1.5    cegger 		    void (*print_flags)(ACPI_WHEA_HEADER *));
     75  1.15.8.1    martin static uint64_t	acpi_select_address(uint32_t, uint64_t);
     76  1.15.8.2    martin 
     77  1.15.8.2    martin /* Handlers for each table */
     78       1.5    cegger static void	acpi_handle_fadt(ACPI_TABLE_HEADER *fadt);
     79       1.5    cegger static void	acpi_print_cpu(u_char cpu_id);
     80       1.5    cegger static void	acpi_print_cpu_uid(uint32_t uid, char *uid_string);
     81       1.5    cegger static void	acpi_print_local_apic(uint32_t apic_id, uint32_t flags);
     82       1.5    cegger static void	acpi_print_io_apic(uint32_t apic_id, uint32_t int_base,
     83       1.5    cegger 		    uint64_t apic_addr);
     84       1.5    cegger static void	acpi_print_mps_flags(uint16_t flags);
     85       1.5    cegger static void	acpi_print_intr(uint32_t intr, uint16_t mps_flags);
     86       1.5    cegger static void	acpi_print_local_nmi(u_int lint, uint16_t mps_flags);
     87       1.5    cegger static void	acpi_print_madt(ACPI_SUBTABLE_HEADER *mp);
     88       1.5    cegger static void	acpi_handle_bert(ACPI_TABLE_HEADER *sdp);
     89       1.5    cegger static void	acpi_handle_boot(ACPI_TABLE_HEADER *sdp);
     90       1.5    cegger static void	acpi_handle_cpep(ACPI_TABLE_HEADER *sdp);
     91  1.15.8.2    martin static void	acpi_handle_csrt(ACPI_TABLE_HEADER *sdp);
     92       1.5    cegger static void	acpi_handle_dbgp(ACPI_TABLE_HEADER *sdp);
     93  1.15.8.1    martin static void	acpi_handle_dbg2(ACPI_TABLE_HEADER *sdp);
     94       1.5    cegger static void	acpi_handle_einj(ACPI_TABLE_HEADER *sdp);
     95       1.5    cegger static void	acpi_handle_erst(ACPI_TABLE_HEADER *sdp);
     96  1.15.8.2    martin static void	acpi_handle_gtdt(ACPI_TABLE_HEADER *sdp);
     97       1.5    cegger static void	acpi_handle_hest(ACPI_TABLE_HEADER *sdp);
     98  1.15.8.2    martin static void	acpi_handle_lpit(ACPI_TABLE_HEADER *sdp);
     99       1.5    cegger static void	acpi_handle_madt(ACPI_TABLE_HEADER *sdp);
    100       1.5    cegger static void	acpi_handle_msct(ACPI_TABLE_HEADER *sdp);
    101       1.5    cegger static void	acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp);
    102       1.5    cegger static void	acpi_handle_hpet(ACPI_TABLE_HEADER *sdp);
    103       1.5    cegger static void	acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp);
    104       1.5    cegger static void	acpi_handle_sbst(ACPI_TABLE_HEADER *sdp);
    105       1.5    cegger static void	acpi_handle_slit(ACPI_TABLE_HEADER *sdp);
    106       1.5    cegger static void	acpi_handle_spcr(ACPI_TABLE_HEADER *sdp);
    107  1.15.8.1    martin static void	acpi_handle_spmi(ACPI_TABLE_HEADER *sdp);
    108       1.5    cegger static void	acpi_print_srat_cpu(uint32_t apic_id,
    109       1.5    cegger 		    uint32_t proximity_domain,
    110       1.5    cegger 		    uint32_t flags, uint32_t clockdomain);
    111       1.5    cegger static void	acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp);
    112       1.5    cegger static void	acpi_print_srat(ACPI_SUBTABLE_HEADER *srat);
    113       1.5    cegger static void	acpi_handle_srat(ACPI_TABLE_HEADER *sdp);
    114       1.5    cegger static void	acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp);
    115  1.15.8.1    martin static void	acpi_print_nfit(ACPI_NFIT_HEADER *nfit);
    116  1.15.8.1    martin static void	acpi_handle_nfit(ACPI_TABLE_HEADER *sdp);
    117  1.15.8.1    martin static void	acpi_handle_uefi(ACPI_TABLE_HEADER *sdp);
    118       1.5    cegger static void	acpi_handle_waet(ACPI_TABLE_HEADER *sdp);
    119       1.5    cegger static void	acpi_handle_wdat(ACPI_TABLE_HEADER *sdp);
    120  1.15.8.1    martin static void	acpi_handle_wddt(ACPI_TABLE_HEADER *sdp);
    121       1.5    cegger static void	acpi_handle_wdrt(ACPI_TABLE_HEADER *sdp);
    122       1.5    cegger static void	acpi_print_sdt(ACPI_TABLE_HEADER *sdp);
    123       1.5    cegger static void	acpi_print_fadt(ACPI_TABLE_HEADER *sdp);
    124       1.5    cegger static void	acpi_print_facs(ACPI_TABLE_FACS *facs);
    125       1.5    cegger static void	acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp);
    126       1.5    cegger static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa);
    127       1.5    cegger static void	acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp);
    128       1.5    cegger static void	acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp);
    129       1.5    cegger static void	acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
    130       1.5    cegger 		    void (*action)(ACPI_SUBTABLE_HEADER *));
    131  1.15.8.1    martin static void	acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
    132  1.15.8.1    martin 		    void (*action)(ACPI_NFIT_HEADER *));
    133       1.5    cegger 
    134       1.5    cegger /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
    135       1.5    cegger static int addr_size;
    136       1.5    cegger 
    137  1.15.8.1    martin /* Strings used in the TCPA table */
    138  1.15.8.1    martin static const char *tcpa_event_type_strings[] = {
    139  1.15.8.1    martin 	"PREBOOT Certificate",
    140  1.15.8.1    martin 	"POST Code",
    141  1.15.8.1    martin 	"Unused",
    142  1.15.8.1    martin 	"No Action",
    143  1.15.8.1    martin 	"Separator",
    144  1.15.8.1    martin 	"Action",
    145  1.15.8.1    martin 	"Event Tag",
    146  1.15.8.1    martin 	"S-CRTM Contents",
    147  1.15.8.1    martin 	"S-CRTM Version",
    148  1.15.8.1    martin 	"CPU Microcode",
    149  1.15.8.1    martin 	"Platform Config Flags",
    150  1.15.8.1    martin 	"Table of Devices",
    151  1.15.8.1    martin 	"Compact Hash",
    152  1.15.8.1    martin 	"IPL",
    153  1.15.8.1    martin 	"IPL Partition Data",
    154  1.15.8.1    martin 	"Non-Host Code",
    155  1.15.8.1    martin 	"Non-Host Config",
    156  1.15.8.1    martin 	"Non-Host Info"
    157  1.15.8.1    martin };
    158  1.15.8.1    martin 
    159  1.15.8.1    martin static const char *TCPA_pcclient_strings[] = {
    160  1.15.8.1    martin 	"<undefined>",
    161  1.15.8.1    martin 	"SMBIOS",
    162  1.15.8.1    martin 	"BIS Certificate",
    163  1.15.8.1    martin 	"POST BIOS ROM Strings",
    164  1.15.8.1    martin 	"ESCD",
    165  1.15.8.1    martin 	"CMOS",
    166  1.15.8.1    martin 	"NVRAM",
    167  1.15.8.1    martin 	"Option ROM Execute",
    168  1.15.8.1    martin 	"Option ROM Configurateion",
    169  1.15.8.1    martin 	"<undefined>",
    170  1.15.8.1    martin 	"Option ROM Microcode Update ",
    171  1.15.8.1    martin 	"S-CRTM Version String",
    172  1.15.8.1    martin 	"S-CRTM Contents",
    173  1.15.8.1    martin 	"POST Contents",
    174  1.15.8.1    martin 	"Table of Devices",
    175  1.15.8.1    martin };
    176  1.15.8.1    martin 
    177  1.15.8.1    martin #define	PRINTFLAG_END()		printflag_end()
    178  1.15.8.1    martin 
    179  1.15.8.1    martin static char pf_sep = '{';
    180  1.15.8.1    martin 
    181  1.15.8.1    martin static void
    182  1.15.8.1    martin printflag_end(void)
    183  1.15.8.1    martin {
    184  1.15.8.1    martin 
    185  1.15.8.1    martin 	if (pf_sep == ',') {
    186  1.15.8.1    martin 		printf("}");
    187  1.15.8.1    martin 	} else if (pf_sep == '{') {
    188  1.15.8.1    martin 		printf("{}");
    189  1.15.8.1    martin 	}
    190  1.15.8.1    martin 	pf_sep = '{';
    191  1.15.8.1    martin 	printf("\n");
    192  1.15.8.1    martin }
    193  1.15.8.1    martin 
    194  1.15.8.1    martin static void
    195  1.15.8.1    martin printflag(uint64_t var, uint64_t mask, const char *name)
    196  1.15.8.1    martin {
    197  1.15.8.1    martin 
    198  1.15.8.1    martin 	if (var & mask) {
    199  1.15.8.1    martin 		printf("%c%s", pf_sep, name);
    200  1.15.8.1    martin 		pf_sep = ',';
    201  1.15.8.1    martin 	}
    202  1.15.8.1    martin }
    203  1.15.8.1    martin 
    204       1.5    cegger static void
    205       1.5    cegger acpi_print_string(char *s, size_t length)
    206       1.5    cegger {
    207       1.5    cegger 	int	c;
    208       1.5    cegger 
    209       1.5    cegger 	/* Trim trailing spaces and NULLs */
    210       1.5    cegger 	while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
    211       1.5    cegger 		length--;
    212       1.5    cegger 
    213       1.5    cegger 	while (length--) {
    214       1.5    cegger 		c = *s++;
    215       1.5    cegger 		putchar(c);
    216       1.5    cegger 	}
    217       1.5    cegger }
    218       1.5    cegger 
    219       1.5    cegger static void
    220       1.5    cegger acpi_print_gas(ACPI_GENERIC_ADDRESS *gas)
    221       1.5    cegger {
    222  1.15.8.2    martin 	switch (gas->SpaceId) {
    223  1.15.8.1    martin 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
    224  1.15.8.1    martin 		if (gas->BitWidth <= 32)
    225  1.15.8.1    martin 			printf("0x%08x:%u[%u] (Memory)",
    226  1.15.8.1    martin 			    (u_int)gas->Address, gas->BitOffset,
    227  1.15.8.1    martin 			    gas->BitWidth);
    228  1.15.8.1    martin 		else
    229  1.15.8.1    martin 			printf("0x%016jx:%u[%u] (Memory)",
    230  1.15.8.1    martin 			    (uintmax_t)gas->Address, gas->BitOffset,
    231  1.15.8.1    martin 			    gas->BitWidth);
    232  1.15.8.1    martin 		break;
    233  1.15.8.1    martin 	case ACPI_ADR_SPACE_SYSTEM_IO:
    234  1.15.8.1    martin 		printf("0x%02x:%u[%u] (IO)", (u_int)gas->Address,
    235  1.15.8.1    martin 		    gas->BitOffset, gas->BitWidth);
    236       1.5    cegger 		break;
    237  1.15.8.1    martin 	case ACPI_ADR_SPACE_PCI_CONFIG:
    238       1.5    cegger 		printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->Address >> 32),
    239       1.5    cegger 		       (uint16_t)((gas->Address >> 16) & 0xffff),
    240       1.5    cegger 		       (uint16_t)gas->Address);
    241       1.5    cegger 		break;
    242       1.5    cegger 	/* XXX How to handle these below? */
    243  1.15.8.1    martin 	case ACPI_ADR_SPACE_EC:
    244       1.5    cegger 		printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address,
    245       1.5    cegger 		       gas->BitOffset, gas->BitWidth);
    246       1.5    cegger 		break;
    247  1.15.8.1    martin 	case ACPI_ADR_SPACE_SMBUS:
    248       1.5    cegger 		printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address,
    249       1.5    cegger 		       gas->BitOffset, gas->BitWidth);
    250       1.5    cegger 		break;
    251  1.15.8.1    martin 	case ACPI_ADR_SPACE_CMOS:
    252  1.15.8.1    martin 	case ACPI_ADR_SPACE_PCI_BAR_TARGET:
    253  1.15.8.1    martin 	case ACPI_ADR_SPACE_IPMI:
    254  1.15.8.1    martin 	case ACPI_ADR_SPACE_GPIO:
    255  1.15.8.1    martin 	case ACPI_ADR_SPACE_GSBUS:
    256  1.15.8.1    martin 	case ACPI_ADR_SPACE_PLATFORM_COMM:
    257  1.15.8.1    martin 	case ACPI_ADR_SPACE_FIXED_HARDWARE:
    258       1.5    cegger 	default:
    259  1.15.8.1    martin 		printf("0x%016jx (SpaceID=%hhu)", (uintmax_t)gas->Address,
    260  1.15.8.1    martin 		    gas->SpaceId);
    261       1.5    cegger 		break;
    262       1.5    cegger 	}
    263       1.5    cegger }
    264       1.5    cegger 
    265       1.5    cegger static void
    266       1.5    cegger acpi_print_pci(uint16_t vendorid, uint16_t deviceid,
    267       1.5    cegger     uint8_t seg, uint8_t bus, uint8_t device, uint8_t func)
    268       1.5    cegger {
    269       1.5    cegger 	if (vendorid == 0xffff && deviceid == 0xffff) {
    270       1.5    cegger 		printf("\tPCI Device=NONE\n");
    271       1.5    cegger 		return;
    272       1.5    cegger 	}
    273       1.5    cegger 
    274       1.5    cegger 	printf("\tPCI device={\n");
    275       1.5    cegger 	printf("\t\tVendor=0x%x\n", vendorid);
    276       1.5    cegger 	printf("\t\tDevice=0x%x\n", deviceid);
    277       1.5    cegger 	printf("\n");
    278       1.5    cegger 	printf("\t\tSegment Group=%d\n", seg);
    279       1.5    cegger 	printf("\t\tBus=%d\n", bus);
    280       1.5    cegger 	printf("\t\tDevice=%d\n", device);
    281       1.5    cegger 	printf("\t\tFunction=%d\n", func);
    282       1.5    cegger 	printf("\t}\n");
    283       1.5    cegger }
    284       1.5    cegger 
    285       1.5    cegger static void
    286  1.15.8.1    martin acpi_print_pci_sbdf(uint8_t seg, uint8_t bus, uint8_t device, uint8_t func)
    287       1.5    cegger {
    288       1.5    cegger 	if (bus == 0xff && device == 0xff && func == 0xff) {
    289       1.5    cegger 		printf("\tPCI Device=NONE\n");
    290       1.5    cegger 		return;
    291       1.5    cegger 	}
    292       1.5    cegger 
    293       1.5    cegger 	printf("\tPCI device={\n");
    294       1.5    cegger 	printf("\t\tSegment Group=%d\n", seg);
    295       1.5    cegger 	printf("\t\tBus=%d\n", bus);
    296       1.5    cegger 	printf("\t\tDevice=%d\n", device);
    297       1.5    cegger 	printf("\t\tFunction=%d\n", func);
    298       1.5    cegger 	printf("\t}\n");
    299       1.5    cegger }
    300       1.5    cegger 
    301       1.5    cegger #ifdef notyet
    302       1.5    cegger static void
    303       1.5    cegger acpi_print_hest_errorseverity(uint32_t error)
    304       1.5    cegger {
    305       1.5    cegger 	printf("\tError Severity={ ");
    306       1.5    cegger 	switch (error) {
    307       1.5    cegger 	case 0:
    308       1.5    cegger 		printf("Recoverable");
    309       1.5    cegger 		break;
    310       1.5    cegger 	case 1:
    311       1.5    cegger 		printf("Fatal");
    312       1.5    cegger 		break;
    313       1.5    cegger 	case 2:
    314       1.5    cegger 		printf("Corrected");
    315       1.5    cegger 		break;
    316       1.5    cegger 	case 3:
    317       1.5    cegger 		printf("None");
    318       1.5    cegger 		break;
    319       1.5    cegger 	default:
    320       1.5    cegger 		printf("%d (reserved)", error);
    321       1.5    cegger 		break;
    322       1.5    cegger 	}
    323       1.5    cegger 	printf("}\n");
    324       1.5    cegger }
    325       1.5    cegger #endif
    326       1.5    cegger 
    327       1.5    cegger static void
    328       1.5    cegger acpi_print_hest_errorbank(ACPI_HEST_IA_ERROR_BANK *bank)
    329       1.5    cegger {
    330       1.5    cegger 	printf("\n");
    331       1.5    cegger 	printf("\tBank Number=%d\n", bank->BankNumber);
    332  1.15.8.1    martin 	printf("\tClear Status On Init={%s}\n",
    333       1.5    cegger 		bank->ClearStatusOnInit ? "NO" : "YES");
    334       1.5    cegger 	printf("\tStatus Data Format={ ");
    335       1.5    cegger 	switch (bank->StatusFormat) {
    336       1.5    cegger 	case 0:
    337       1.5    cegger 		printf("IA32 MCA");
    338       1.5    cegger 		break;
    339       1.5    cegger 	case 1:
    340       1.5    cegger 		printf("EMT64 MCA");
    341       1.5    cegger 		break;
    342       1.5    cegger 	case 2:
    343       1.5    cegger 		printf("AMD64 MCA");
    344       1.5    cegger 		break;
    345       1.5    cegger 	}
    346       1.5    cegger 	printf(" }\n");
    347       1.5    cegger 
    348       1.5    cegger 	if (bank->ControlRegister)
    349       1.5    cegger 		printf("\tControl Register=0x%x\n", bank->ControlRegister);
    350       1.5    cegger 	printf("\tControl Init Data=0x%"PRIx64"\n", bank->ControlData);
    351       1.5    cegger 	printf("\tStatus MSR=0x%x\n", bank->StatusRegister);
    352       1.5    cegger 	printf("\tAddress MSR=0x%x\n", bank->AddressRegister);
    353       1.5    cegger 	printf("\tMisc MSR=0x%x\n", bank->MiscRegister);
    354       1.5    cegger }
    355       1.5    cegger 
    356       1.5    cegger static void
    357       1.5    cegger acpi_print_hest_header(ACPI_HEST_HEADER *hest)
    358       1.5    cegger {
    359  1.15.8.1    martin 	printf("\tType={");
    360       1.5    cegger 	switch (hest->Type) {
    361       1.5    cegger 	case ACPI_HEST_TYPE_IA32_CHECK:
    362       1.5    cegger 		printf("IA32 Machine Check Exception");
    363       1.5    cegger 		break;
    364       1.5    cegger 	case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
    365  1.15.8.1    martin 		printf("IA32 Corrected Machine Check");
    366       1.5    cegger 		break;
    367       1.5    cegger 	case ACPI_HEST_TYPE_IA32_NMI:
    368  1.15.8.1    martin 		printf("IA32 Non-Maskable Interrupt");
    369       1.5    cegger 		break;
    370       1.5    cegger 	case ACPI_HEST_TYPE_NOT_USED3:
    371       1.5    cegger 	case ACPI_HEST_TYPE_NOT_USED4:
    372       1.5    cegger 	case ACPI_HEST_TYPE_NOT_USED5:
    373  1.15.8.1    martin 		printf("unused type: %d", hest->Type);
    374       1.5    cegger 		break;
    375       1.5    cegger 	case ACPI_HEST_TYPE_AER_ROOT_PORT:
    376  1.15.8.1    martin 		printf("PCI Express Root Port AER");
    377       1.5    cegger 		break;
    378       1.5    cegger 	case ACPI_HEST_TYPE_AER_ENDPOINT:
    379  1.15.8.1    martin 		printf("PCI Express Endpoint AER");
    380       1.5    cegger 		break;
    381       1.5    cegger 	case ACPI_HEST_TYPE_AER_BRIDGE:
    382  1.15.8.1    martin 		printf("PCI Express/PCI-X Bridge AER");
    383       1.5    cegger 		break;
    384       1.5    cegger 	case ACPI_HEST_TYPE_GENERIC_ERROR:
    385  1.15.8.1    martin 		printf("Generic Hardware Error Source");
    386  1.15.8.1    martin 		break;
    387  1.15.8.1    martin 	case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
    388  1.15.8.1    martin 		printf("Generic Hardware Error Source version 2");
    389       1.5    cegger 		break;
    390       1.5    cegger 	case ACPI_HEST_TYPE_RESERVED:
    391       1.5    cegger 	default:
    392  1.15.8.1    martin 		printf("Reserved (%d)", hest->Type);
    393       1.5    cegger 		break;
    394       1.5    cegger 	}
    395  1.15.8.1    martin 	printf("}\n");
    396       1.5    cegger 	printf("\tSourceId=%d\n", hest->SourceId);
    397       1.5    cegger }
    398       1.5    cegger 
    399       1.5    cegger static void
    400       1.5    cegger acpi_print_hest_aer_common(ACPI_HEST_AER_COMMON *data)
    401       1.5    cegger {
    402       1.5    cegger 	printf("\tFlags={ ");
    403       1.5    cegger 	if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
    404       1.5    cegger 		printf("FIRMWARE_FIRST");
    405       1.5    cegger 	if (data->Flags & ACPI_HEST_GLOBAL)
    406       1.5    cegger 		printf("GLOBAL");
    407       1.5    cegger 	printf(" }\n");
    408       1.5    cegger 	printf("\tEnabled={ %s ", data->Flags ? "YES" : "NO");
    409       1.5    cegger 	if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
    410       1.5    cegger 		printf("(ignored) ");
    411       1.5    cegger 	printf("}\n");
    412       1.5    cegger 	printf("\tNumber of Record to pre-allocate=%d\n",
    413       1.5    cegger 		data->RecordsToPreallocate);
    414       1.5    cegger 	printf("\tMax. Sections per Record=%d\n", data->MaxSectionsPerRecord);
    415       1.5    cegger 	if (!(data->Flags & ACPI_HEST_GLOBAL))
    416  1.15.8.1    martin 		acpi_print_pci_sbdf(0, data->Bus, data->Device, data->Function);
    417       1.5    cegger 	printf("\tDevice Control=0x%x\n", data->DeviceControl);
    418       1.5    cegger 	printf("\tUncorrectable Error Mask Register=0x%x\n",
    419       1.5    cegger 		data->UncorrectableMask);
    420       1.5    cegger 	printf("\tUncorrectable Error Severity Register=0x%x\n",
    421       1.5    cegger 		data->UncorrectableSeverity);
    422       1.5    cegger 	printf("\tCorrectable Error Mask Register=0x%x\n",
    423       1.5    cegger 		data->CorrectableMask);
    424       1.5    cegger 	printf("\tAdvanced Capabilities Register=0x%x\n",
    425       1.5    cegger 		data->AdvancedCapabilities);
    426       1.5    cegger }
    427       1.5    cegger 
    428       1.5    cegger static void
    429       1.5    cegger acpi_print_hest_notify(ACPI_HEST_NOTIFY *notify)
    430       1.5    cegger {
    431       1.5    cegger 	printf("\tHW Error Notification={\n");
    432  1.15.8.1    martin 	printf("\t\tType={");
    433       1.5    cegger 	switch (notify->Type) {
    434       1.5    cegger 	case ACPI_HEST_NOTIFY_POLLED:
    435       1.5    cegger 		printf("POLLED");
    436       1.5    cegger 		break;
    437       1.5    cegger 	case ACPI_HEST_NOTIFY_EXTERNAL:
    438       1.5    cegger 		printf("EXTERN");
    439       1.5    cegger 		break;
    440       1.5    cegger 	case ACPI_HEST_NOTIFY_LOCAL:
    441       1.5    cegger 		printf("LOCAL");
    442       1.5    cegger 		break;
    443       1.5    cegger 	case ACPI_HEST_NOTIFY_SCI:
    444       1.5    cegger 		printf("SCI");
    445       1.5    cegger 		break;
    446       1.5    cegger 	case ACPI_HEST_NOTIFY_NMI:
    447       1.5    cegger 		printf("NMI");
    448       1.5    cegger 		break;
    449  1.15.8.1    martin 	case ACPI_HEST_NOTIFY_CMCI:
    450  1.15.8.1    martin 		printf("CMCI");
    451  1.15.8.1    martin 		break;
    452  1.15.8.1    martin 	case ACPI_HEST_NOTIFY_MCE:
    453  1.15.8.1    martin 		printf("MCE");
    454  1.15.8.1    martin 		break;
    455  1.15.8.1    martin 	case ACPI_HEST_NOTIFY_GPIO:
    456  1.15.8.1    martin 		printf("GPIO-Signal");
    457  1.15.8.1    martin 		break;
    458  1.15.8.1    martin 	case ACPI_HEST_NOTIFY_SEA:
    459  1.15.8.1    martin 		printf("ARMv8 SEA");
    460  1.15.8.1    martin 		break;
    461  1.15.8.1    martin 	case ACPI_HEST_NOTIFY_SEI:
    462  1.15.8.1    martin 		printf("ARMv8 SEI");
    463  1.15.8.1    martin 		break;
    464  1.15.8.1    martin 	case ACPI_HEST_NOTIFY_GSIV:
    465  1.15.8.1    martin 		printf("External Interrupt - GSIV");
    466  1.15.8.1    martin 		break;
    467       1.5    cegger 	case ACPI_HEST_NOTIFY_RESERVED:
    468       1.5    cegger 		printf("RESERVED");
    469       1.5    cegger 		break;
    470       1.5    cegger 	default:
    471  1.15.8.1    martin 		printf("%d (reserved)", notify->Type);
    472       1.5    cegger 		break;
    473       1.5    cegger 	}
    474  1.15.8.1    martin 	printf("}\n");
    475       1.5    cegger 
    476       1.5    cegger 	printf("\t\tLength=%d\n", notify->Length);
    477  1.15.8.1    martin 
    478  1.15.8.1    martin #define PRINTFLAG(var, flag)	printflag((var), ACPI_HEST_## flag, #flag)
    479  1.15.8.1    martin 
    480  1.15.8.1    martin 	printf("\t\tConfig Write Enable=");
    481  1.15.8.1    martin 	PRINTFLAG(notify->ConfigWriteEnable, TYPE);
    482  1.15.8.1    martin 	PRINTFLAG(notify->ConfigWriteEnable, POLL_INTERVAL);
    483  1.15.8.1    martin 	PRINTFLAG(notify->ConfigWriteEnable, POLL_THRESHOLD_VALUE);
    484  1.15.8.1    martin 	PRINTFLAG(notify->ConfigWriteEnable, POLL_THRESHOLD_WINDOW);
    485  1.15.8.1    martin 	PRINTFLAG(notify->ConfigWriteEnable, ERR_THRESHOLD_VALUE);
    486  1.15.8.1    martin 	PRINTFLAG(notify->ConfigWriteEnable, ERR_THRESHOLD_WINDOW);
    487  1.15.8.1    martin 	PRINTFLAG_END();
    488  1.15.8.1    martin 
    489  1.15.8.1    martin #undef PRINTFLAG
    490       1.5    cegger 
    491       1.5    cegger 	printf("\t\tPoll Interval=%d msec\n", notify->PollInterval);
    492       1.5    cegger 	printf("\t\tInterrupt Vector=%d\n", notify->Vector);
    493       1.5    cegger 	printf("\t\tSwitch To Polling Threshold Value=%d\n",
    494       1.5    cegger 		notify->PollingThresholdValue);
    495       1.5    cegger 	printf("\t\tSwitch To Polling Threshold Window=%d msec\n",
    496       1.5    cegger 		notify->PollingThresholdWindow);
    497       1.5    cegger 	printf("\t\tError Threshold Value=%d\n",
    498       1.5    cegger 		notify->ErrorThresholdValue);
    499       1.5    cegger 	printf("\t\tError Threshold Window=%d msec\n",
    500       1.5    cegger 		notify->ErrorThresholdWindow);
    501       1.5    cegger 	printf("\t}\n");
    502       1.5    cegger }
    503       1.5    cegger 
    504       1.5    cegger #ifdef notyet
    505       1.5    cegger static void
    506       1.5    cegger acpi_print_hest_generic_status(ACPI_HEST_GENERIC_STATUS *data)
    507       1.5    cegger {
    508       1.5    cegger 	uint32_t i, pos, entries;
    509       1.5    cegger 	ACPI_HEST_GENERIC_DATA *gen;
    510       1.5    cegger 
    511       1.5    cegger 	entries = data->BlockStatus & ACPI_HEST_ERROR_ENTRY_COUNT;
    512       1.5    cegger 
    513       1.5    cegger 	printf("\tGeneric Error Status={\n");
    514       1.5    cegger 	printf("\t\tBlock Status={ ");
    515       1.5    cegger 	if (data->BlockStatus & ACPI_HEST_UNCORRECTABLE)
    516       1.5    cegger 		printf("UNCORRECTABLE");
    517       1.5    cegger 	if (data->BlockStatus & ACPI_HEST_CORRECTABLE)
    518       1.5    cegger 		printf("CORRECTABLE");
    519       1.5    cegger 	if (data->BlockStatus & ACPI_HEST_MULTIPLE_UNCORRECTABLE)
    520       1.5    cegger 		printf("MULTIPLE UNCORRECTABLE");
    521       1.5    cegger 	if (data->BlockStatus & ACPI_HEST_MULTIPLE_CORRECTABLE)
    522       1.5    cegger 		printf("MULTIPLE CORRECTABLE");
    523       1.5    cegger 	printf(" }\n");
    524       1.5    cegger 	printf("\t\tEntry Count=%d\n", entries);
    525       1.5    cegger 	printf("\t\tRaw Data Offset=%d\n", data->RawDataOffset);
    526       1.5    cegger 	printf("\t\tRaw Data Length=%d\n", data->RawDataLength);
    527       1.5    cegger 	printf("\t\tData Length=%d\n", data->DataLength);
    528       1.5    cegger 	printf("\t");
    529       1.5    cegger 	acpi_print_hest_errorseverity(data->ErrorSeverity);
    530       1.5    cegger 	printf("\t}\n");
    531       1.5    cegger 
    532       1.5    cegger 	pos = sizeof(ACPI_HEST_GENERIC_STATUS);
    533       1.5    cegger 	for (i = 0; i < entries; i++) {
    534       1.5    cegger 		gen = (ACPI_HEST_GENERIC_DATA *)((char *)data + pos);
    535       1.5    cegger 		acpi_print_hest_generic_data(gen);
    536       1.5    cegger 		pos += sizeof(ACPI_HEST_GENERIC_DATA);
    537       1.5    cegger 	}
    538       1.5    cegger }
    539       1.5    cegger #endif
    540       1.5    cegger 
    541       1.5    cegger #ifdef notyet
    542       1.5    cegger static void
    543       1.5    cegger acpi_print_hest_generic_data(ACPI_HEST_GENERIC_DATA *data)
    544       1.5    cegger {
    545       1.5    cegger 	printf("\tGeneric Error Data={\n");
    546       1.5    cegger 	printf("\t\tSectionType=");
    547       1.5    cegger 	acpi_print_string((char *)data->SectionType, sizeof(data->SectionType));
    548       1.5    cegger 	printf("\n\t");
    549       1.5    cegger 	acpi_print_hest_errorseverity(data->ErrorSeverity);
    550       1.5    cegger 	printf("\t\tRevision=0x%x\n", data->Revision);
    551       1.5    cegger 	printf("\t\tValidation Bits=0x%x\n", data->ValidationBits);
    552       1.5    cegger 	printf("\t\tFlags=0x%x\n", data->Flags);
    553       1.5    cegger 	printf("\t\tData Length=%d\n", data->ErrorDataLength);
    554       1.5    cegger 	printf("\t\tField Replication Unit Id=");
    555       1.5    cegger 	acpi_print_string((char *)data->FruId, sizeof(data->FruId));
    556       1.5    cegger 	printf("\n");
    557       1.5    cegger 	printf("\t\tField Replication Unit=");
    558       1.5    cegger 	acpi_print_string((char *)data->FruText, sizeof(data->FruText));
    559       1.5    cegger 	printf("\n");
    560       1.5    cegger 	printf("\t}\n");
    561       1.5    cegger }
    562       1.5    cegger #endif
    563       1.5    cegger 
    564       1.5    cegger static void
    565       1.5    cegger acpi_print_whea(ACPI_WHEA_HEADER *whea,
    566       1.5    cegger     void (*print_action)(ACPI_WHEA_HEADER *),
    567       1.5    cegger     void (*print_ins)(ACPI_WHEA_HEADER *),
    568       1.5    cegger     void (*print_flags)(ACPI_WHEA_HEADER *))
    569       1.5    cegger {
    570       1.5    cegger 	printf("\n");
    571       1.5    cegger 
    572       1.5    cegger 	print_action(whea);
    573       1.5    cegger 	print_ins(whea);
    574       1.5    cegger 	if (print_flags)
    575       1.5    cegger 		print_flags(whea);
    576       1.5    cegger 	printf("\tRegisterRegion=");
    577       1.5    cegger 	acpi_print_gas(&whea->RegisterRegion);
    578       1.5    cegger 	printf("\n");
    579       1.5    cegger 	printf("\tMASK=0x%08"PRIx64"\n", whea->Mask);
    580       1.5    cegger }
    581       1.5    cegger 
    582       1.5    cegger static void
    583       1.5    cegger acpi_print_hest_ia32_check(ACPI_HEST_IA_MACHINE_CHECK *data)
    584       1.5    cegger {
    585       1.5    cegger 	uint32_t i, pos;
    586       1.5    cegger 	ACPI_HEST_IA_ERROR_BANK *bank;
    587       1.5    cegger 
    588       1.5    cegger 	acpi_print_hest_header(&data->Header);
    589       1.5    cegger 	printf("\tFlags={ ");
    590       1.5    cegger 	if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
    591       1.5    cegger 		printf("FIRMWARE_FIRST");
    592       1.5    cegger 	printf(" }\n");
    593       1.5    cegger 	printf("\tEnabled={ %s }\n", data->Enabled ? "YES" : "NO");
    594       1.5    cegger 	printf("\tNumber of Record to pre-allocate=%d\n",
    595       1.5    cegger 		data->RecordsToPreallocate);
    596       1.5    cegger 	printf("\tMax Sections per Record=%d\n",
    597       1.5    cegger 		data->MaxSectionsPerRecord);
    598       1.5    cegger 	printf("\tGlobal Capability Init Data=0x%"PRIx64"\n",
    599       1.5    cegger 		data->GlobalCapabilityData);
    600       1.5    cegger 	printf("\tGlobal Control Init Data=0x%"PRIx64"\n",
    601       1.5    cegger 		data->GlobalControlData);
    602       1.5    cegger 	printf("\tNumber of Hardware Error Reporting Banks=%d\n",
    603       1.5    cegger 		data->NumHardwareBanks);
    604       1.5    cegger 
    605       1.5    cegger 	pos = sizeof(ACPI_HEST_IA_MACHINE_CHECK);
    606       1.5    cegger 	for (i = 0; i < data->NumHardwareBanks; i++) {
    607       1.5    cegger 		bank = (ACPI_HEST_IA_ERROR_BANK *)((char *)data + pos);
    608       1.5    cegger 		acpi_print_hest_errorbank(bank);
    609       1.5    cegger 		pos += sizeof(ACPI_HEST_IA_ERROR_BANK);
    610       1.5    cegger 	}
    611       1.5    cegger }
    612       1.5    cegger 
    613       1.5    cegger static void
    614       1.5    cegger acpi_print_hest_ia32_correctedcheck(ACPI_HEST_IA_CORRECTED *data)
    615       1.5    cegger {
    616       1.5    cegger 	uint32_t i, pos;
    617       1.5    cegger 	ACPI_HEST_IA_ERROR_BANK *bank;
    618       1.5    cegger 
    619       1.5    cegger 	acpi_print_hest_header(&data->Header);
    620       1.5    cegger 	printf("\tFlags={ ");
    621       1.5    cegger 	if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
    622       1.5    cegger 		printf("FIRMWARE_FIRST");
    623       1.5    cegger 	printf(" }\n");
    624       1.5    cegger 	printf("\tEnabled={ %s }\n", data->Enabled ? "YES" : "NO");
    625       1.5    cegger 	printf("\tNumber of Record to pre-allocate=%d\n",
    626       1.5    cegger 		data->RecordsToPreallocate);
    627       1.5    cegger 	printf("\tMax Sections per Record=%d\n",
    628       1.5    cegger 		data->MaxSectionsPerRecord);
    629       1.5    cegger 	acpi_print_hest_notify(&data->Notify);
    630       1.5    cegger 
    631       1.5    cegger 	printf("\tNumber of Hardware Error Reporting Banks=%d\n",
    632       1.5    cegger 		data->NumHardwareBanks);
    633       1.5    cegger 
    634       1.5    cegger 	pos = sizeof(ACPI_HEST_IA_MACHINE_CHECK);
    635       1.5    cegger 	for (i = 0; i < data->NumHardwareBanks; i++) {
    636       1.5    cegger 		bank = (ACPI_HEST_IA_ERROR_BANK *)((char *)data + pos);
    637       1.5    cegger 		acpi_print_hest_errorbank(bank);
    638       1.5    cegger 		pos += sizeof(ACPI_HEST_IA_ERROR_BANK);
    639       1.5    cegger 	}
    640       1.5    cegger }
    641       1.5    cegger 
    642       1.5    cegger static void
    643       1.5    cegger acpi_print_hest_ia32_nmi(ACPI_HEST_IA_NMI *data)
    644       1.5    cegger {
    645       1.5    cegger 	acpi_print_hest_header(&data->Header);
    646       1.5    cegger 	printf("\tNumber of Record to pre-allocate=%d\n",
    647       1.5    cegger 		data->RecordsToPreallocate);
    648       1.5    cegger 	printf("\tMax Sections per Record=%d\n",
    649       1.5    cegger 		data->MaxSectionsPerRecord);
    650       1.5    cegger 	printf("\tMax Raw Data Length=%d\n",
    651       1.5    cegger 		data->MaxRawDataLength);
    652       1.5    cegger }
    653       1.5    cegger 
    654       1.5    cegger static void
    655       1.5    cegger acpi_print_hest_aer_root(ACPI_HEST_AER_ROOT *data)
    656       1.5    cegger {
    657       1.5    cegger 	acpi_print_hest_header(&data->Header);
    658       1.5    cegger 	acpi_print_hest_aer_common(&data->Aer);
    659       1.5    cegger 	printf("Root Error Command Register=0x%x\n", data->RootErrorCommand);
    660       1.5    cegger }
    661       1.5    cegger 
    662       1.5    cegger static void
    663       1.5    cegger acpi_print_hest_aer_endpoint(ACPI_HEST_AER *data)
    664       1.5    cegger {
    665       1.5    cegger 	acpi_print_hest_header(&data->Header);
    666       1.5    cegger 	acpi_print_hest_aer_common(&data->Aer);
    667       1.5    cegger }
    668       1.5    cegger 
    669       1.5    cegger static void
    670       1.5    cegger acpi_print_hest_aer_bridge(ACPI_HEST_AER_BRIDGE *data)
    671       1.5    cegger {
    672       1.5    cegger 	acpi_print_hest_header(&data->Header);
    673       1.5    cegger 	acpi_print_hest_aer_common(&data->Aer);
    674       1.5    cegger 
    675       1.5    cegger 	printf("\tSecondary Uncorrectable Error Mask Register=0x%x\n",
    676       1.5    cegger 		data->UncorrectableMask2);
    677       1.5    cegger 	printf("\tSecondary Uncorrectable Error Severity Register=0x%x\n",
    678       1.5    cegger 		data->UncorrectableSeverity2);
    679       1.5    cegger 	printf("\tSecondory Advanced Capabilities Register=0x%x\n",
    680       1.5    cegger 		data->AdvancedCapabilities2);
    681       1.5    cegger }
    682       1.5    cegger 
    683       1.5    cegger static void
    684       1.5    cegger acpi_print_hest_generic(ACPI_HEST_GENERIC *data)
    685       1.5    cegger {
    686       1.5    cegger 	acpi_print_hest_header(&data->Header);
    687       1.5    cegger 	if (data->RelatedSourceId != 0xffff)
    688       1.5    cegger 		printf("\tReleated SourceId=%d\n", data->RelatedSourceId);
    689  1.15.8.1    martin 	printf("\tEnabled={%s}\n", data->Enabled ? "YES" : "NO");
    690  1.15.8.1    martin 	printf("\tNumber of Records to pre-allocate=%u\n",
    691       1.5    cegger 		data->RecordsToPreallocate);
    692  1.15.8.1    martin 	printf("\tMax Sections per Record=%u\n", data->MaxSectionsPerRecord);
    693  1.15.8.1    martin 	printf("\tMax Raw Data Length=%u\n", data->MaxRawDataLength);
    694       1.5    cegger 	printf("\tError Status Address=");
    695       1.5    cegger 	acpi_print_gas(&data->ErrorStatusAddress);
    696  1.15.8.1    martin 	printf("\n");
    697       1.5    cegger 	acpi_print_hest_notify(&data->Notify);
    698  1.15.8.1    martin 	printf("\tError Block Length=%u\n", data->ErrorBlockLength);
    699  1.15.8.1    martin }
    700  1.15.8.1    martin 
    701  1.15.8.1    martin static void
    702  1.15.8.1    martin acpi_print_hest_generic_v2(ACPI_HEST_GENERIC_V2 *data)
    703  1.15.8.1    martin {
    704  1.15.8.1    martin 
    705  1.15.8.1    martin 	/* The first 64 bytes are the same as ACPI_HEST_GENERIC */
    706  1.15.8.1    martin 	acpi_print_hest_generic((ACPI_HEST_GENERIC *)data);
    707  1.15.8.1    martin 
    708  1.15.8.1    martin 	printf("\tError Status Address");
    709  1.15.8.1    martin 	acpi_print_gas(&data->ReadAckRegister);
    710  1.15.8.1    martin 	printf("\tRead Ack Preserve=0x%016jx\n",
    711  1.15.8.1    martin 	    (uintmax_t)data->ReadAckPreserve);
    712  1.15.8.1    martin 	printf("\tRead Ack Write=0x%016jx\n",
    713  1.15.8.1    martin 	    (uintmax_t)data->ReadAckWrite);
    714       1.5    cegger }
    715       1.5    cegger 
    716       1.5    cegger static void
    717       1.5    cegger acpi_handle_hest(ACPI_TABLE_HEADER *sdp)
    718       1.5    cegger {
    719       1.5    cegger 	ACPI_TABLE_HEST *hest;
    720       1.5    cegger 	ACPI_HEST_HEADER *subhest;
    721       1.5    cegger 	uint32_t i, pos;
    722       1.5    cegger 
    723       1.5    cegger 	printf(BEGIN_COMMENT);
    724       1.5    cegger 	acpi_print_sdt(sdp);
    725       1.5    cegger 	hest = (ACPI_TABLE_HEST *)sdp;
    726       1.5    cegger 
    727       1.5    cegger 	printf("\tError Source Count=%d\n", hest->ErrorSourceCount);
    728       1.5    cegger 	pos = sizeof(ACPI_TABLE_HEST);
    729       1.5    cegger 	for (i = 0; i < hest->ErrorSourceCount; i++) {
    730       1.5    cegger 		subhest = (ACPI_HEST_HEADER *)((char *)hest + pos);
    731       1.5    cegger 		printf("\n");
    732       1.5    cegger 
    733       1.5    cegger 		switch (subhest->Type) {
    734       1.5    cegger 		case ACPI_HEST_TYPE_IA32_CHECK:
    735  1.15.8.1    martin 			acpi_print_hest_ia32_check(
    736  1.15.8.1    martin 				(ACPI_HEST_IA_MACHINE_CHECK *)subhest);
    737       1.5    cegger 			pos += sizeof(ACPI_HEST_IA_MACHINE_CHECK);
    738       1.5    cegger 			break;
    739       1.5    cegger 
    740       1.5    cegger 		case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
    741  1.15.8.1    martin 			acpi_print_hest_ia32_correctedcheck(
    742  1.15.8.1    martin 				(ACPI_HEST_IA_CORRECTED *)subhest);
    743       1.5    cegger 			pos += sizeof(ACPI_HEST_IA_CORRECTED);
    744       1.5    cegger 			break;
    745       1.5    cegger 
    746       1.5    cegger 		case ACPI_HEST_TYPE_IA32_NMI:
    747  1.15.8.1    martin 			acpi_print_hest_ia32_nmi(
    748  1.15.8.1    martin 				(ACPI_HEST_IA_NMI *)subhest);
    749       1.5    cegger 			pos += sizeof(ACPI_HEST_IA_NMI);
    750       1.5    cegger 			break;
    751       1.5    cegger 
    752       1.5    cegger 		case ACPI_HEST_TYPE_NOT_USED3:
    753       1.5    cegger 		case ACPI_HEST_TYPE_NOT_USED4:
    754       1.5    cegger 		case ACPI_HEST_TYPE_NOT_USED5:
    755       1.5    cegger 			pos += sizeof(ACPI_HEST_HEADER);
    756       1.5    cegger 			break;
    757       1.5    cegger 
    758       1.5    cegger 		case ACPI_HEST_TYPE_AER_ROOT_PORT:
    759  1.15.8.1    martin 			acpi_print_hest_aer_root((ACPI_HEST_AER_ROOT *)subhest);
    760       1.5    cegger 			pos += sizeof(ACPI_HEST_AER_ROOT);
    761       1.5    cegger 			break;
    762       1.5    cegger 
    763       1.5    cegger 		case ACPI_HEST_TYPE_AER_ENDPOINT:
    764  1.15.8.1    martin 			acpi_print_hest_aer_endpoint((ACPI_HEST_AER *)subhest);
    765  1.15.8.1    martin 			pos += sizeof(ACPI_HEST_AER);
    766       1.5    cegger 			break;
    767       1.5    cegger 
    768       1.5    cegger 		case ACPI_HEST_TYPE_AER_BRIDGE:
    769  1.15.8.1    martin 			acpi_print_hest_aer_bridge((ACPI_HEST_AER_BRIDGE *)subhest);
    770       1.5    cegger 			pos += sizeof(ACPI_HEST_AER_BRIDGE);
    771       1.5    cegger 			break;
    772       1.5    cegger 
    773       1.5    cegger 		case ACPI_HEST_TYPE_GENERIC_ERROR:
    774  1.15.8.1    martin 			acpi_print_hest_generic((ACPI_HEST_GENERIC *)subhest);
    775       1.5    cegger 			pos += sizeof(ACPI_HEST_GENERIC);
    776       1.5    cegger 			break;
    777       1.5    cegger 
    778  1.15.8.1    martin 		case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
    779  1.15.8.1    martin 			acpi_print_hest_generic_v2(
    780  1.15.8.1    martin 				(ACPI_HEST_GENERIC_V2 *)subhest);
    781  1.15.8.1    martin 			pos += sizeof(ACPI_HEST_GENERIC_V2);
    782  1.15.8.1    martin 			break;
    783  1.15.8.1    martin 
    784       1.5    cegger 		case ACPI_HEST_TYPE_RESERVED:
    785       1.5    cegger 		default:
    786       1.5    cegger 			pos += sizeof(ACPI_HEST_HEADER);
    787       1.5    cegger 			break;
    788       1.5    cegger 		}
    789       1.5    cegger 	}
    790       1.5    cegger 
    791       1.5    cegger 	printf(END_COMMENT);
    792       1.5    cegger }
    793       1.5    cegger 
    794  1.15.8.1    martin static uint64_t
    795  1.15.8.1    martin acpi_select_address(uint32_t addr32, uint64_t addr64)
    796       1.5    cegger {
    797       1.5    cegger 
    798  1.15.8.1    martin 	if (addr64 == 0)
    799  1.15.8.1    martin 		return addr32;
    800       1.5    cegger 
    801  1.15.8.1    martin 	if ((addr32 != 0) && ((addr64 & 0xfffffff) != addr32)) {
    802       1.5    cegger 		/*
    803       1.5    cegger 		 * A few systems (e.g., IBM T23) have an RSDP that claims
    804       1.5    cegger 		 * revision 2 but the 64 bit addresses are invalid.  If
    805       1.5    cegger 		 * revision 2 and the 32 bit address is non-zero but the
    806       1.5    cegger 		 * 32 and 64 bit versions don't match, prefer the 32 bit
    807       1.5    cegger 		 * version for all subsequent tables.
    808       1.5    cegger 		 */
    809  1.15.8.1    martin 		return addr32;
    810  1.15.8.1    martin 	}
    811  1.15.8.1    martin 
    812  1.15.8.1    martin 	return addr64;
    813       1.5    cegger }
    814       1.5    cegger 
    815       1.5    cegger static void
    816       1.5    cegger acpi_handle_fadt(ACPI_TABLE_HEADER *sdp)
    817       1.5    cegger {
    818       1.5    cegger 	ACPI_TABLE_HEADER *dsdp;
    819       1.5    cegger 	ACPI_TABLE_FACS	*facs;
    820       1.5    cegger 	ACPI_TABLE_FADT *fadt;
    821       1.5    cegger 
    822       1.5    cegger 	fadt = (ACPI_TABLE_FADT *)sdp;
    823       1.5    cegger 	acpi_print_fadt(sdp);
    824       1.5    cegger 
    825  1.15.8.2    martin 	if (acpi_select_address(fadt->Facs, fadt->XFacs) == 0) {
    826  1.15.8.2    martin 		if ((fadt->Flags & ACPI_FADT_HW_REDUCED) == 0)
    827  1.15.8.2    martin 			errx(EXIT_FAILURE, "Missing FACS and HW_REDUCED_ACPI flag not set in FADT");
    828  1.15.8.2    martin 	} else {
    829  1.15.8.2    martin 		facs = (ACPI_TABLE_FACS *)acpi_map_sdt(
    830  1.15.8.2    martin 			acpi_select_address(fadt->Facs, fadt->XFacs));
    831  1.15.8.2    martin 		if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || facs->Length < 64)
    832  1.15.8.2    martin 			errx(EXIT_FAILURE, "FACS is corrupt");
    833  1.15.8.2    martin 		acpi_print_facs(facs);
    834  1.15.8.2    martin 	}
    835       1.5    cegger 
    836  1.15.8.1    martin 	dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(
    837  1.15.8.1    martin 		acpi_select_address(fadt->Dsdt, fadt->XDsdt));
    838  1.15.8.1    martin 	if (memcmp(dsdp->Signature, ACPI_SIG_DSDT, 4) != 0)
    839  1.15.8.1    martin 		errx(EXIT_FAILURE, "DSDT signature mismatch");
    840       1.5    cegger 	if (acpi_checksum(dsdp, dsdp->Length))
    841       1.5    cegger 		errx(EXIT_FAILURE, "DSDT is corrupt");
    842       1.5    cegger 	acpi_print_dsdt(dsdp);
    843       1.5    cegger }
    844       1.5    cegger 
    845       1.5    cegger static void
    846       1.5    cegger acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
    847       1.5    cegger     void (*action)(ACPI_SUBTABLE_HEADER *))
    848       1.5    cegger {
    849       1.5    cegger 	ACPI_SUBTABLE_HEADER *subtable;
    850       1.5    cegger 	char *end;
    851       1.5    cegger 
    852       1.5    cegger 	subtable = first;
    853       1.5    cegger 	end = (char *)table + table->Length;
    854       1.5    cegger 	while ((char *)subtable < end) {
    855       1.5    cegger 		printf("\n");
    856  1.15.8.1    martin 		if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) {
    857  1.15.8.1    martin 			warnx("invalid subtable length %u", subtable->Length);
    858  1.15.8.1    martin 			return;
    859  1.15.8.1    martin 		}
    860       1.5    cegger 		action(subtable);
    861       1.5    cegger 		subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable +
    862       1.5    cegger 		    subtable->Length);
    863       1.5    cegger 	}
    864       1.5    cegger }
    865       1.5    cegger 
    866       1.5    cegger static void
    867  1.15.8.1    martin acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
    868  1.15.8.1    martin     void (*action)(ACPI_NFIT_HEADER *))
    869  1.15.8.1    martin {
    870  1.15.8.1    martin 	ACPI_NFIT_HEADER *subtable;
    871  1.15.8.1    martin 	char *end;
    872  1.15.8.1    martin 
    873  1.15.8.1    martin 	subtable = first;
    874  1.15.8.1    martin 	end = (char *)table + table->Length;
    875  1.15.8.1    martin 	while ((char *)subtable < end) {
    876  1.15.8.1    martin 		printf("\n");
    877  1.15.8.1    martin 		if (subtable->Length < sizeof(ACPI_NFIT_HEADER)) {
    878  1.15.8.1    martin 			warnx("invalid subtable length %u", subtable->Length);
    879  1.15.8.1    martin 			return;
    880  1.15.8.1    martin 		}
    881  1.15.8.1    martin 		action(subtable);
    882  1.15.8.1    martin 		subtable = (ACPI_NFIT_HEADER *)((char *)subtable +
    883  1.15.8.1    martin 		    subtable->Length);
    884  1.15.8.1    martin 	}
    885  1.15.8.1    martin }
    886  1.15.8.1    martin 
    887  1.15.8.1    martin static void
    888       1.5    cegger acpi_print_cpu(u_char cpu_id)
    889       1.5    cegger {
    890       1.5    cegger 
    891       1.5    cegger 	printf("\tACPI CPU=");
    892       1.5    cegger 	if (cpu_id == 0xff)
    893       1.5    cegger 		printf("ALL\n");
    894       1.5    cegger 	else
    895       1.5    cegger 		printf("%d\n", (u_int)cpu_id);
    896       1.5    cegger }
    897       1.5    cegger 
    898       1.5    cegger static void
    899       1.5    cegger acpi_print_cpu_uid(uint32_t uid, char *uid_string)
    900       1.5    cegger {
    901       1.5    cegger 
    902       1.5    cegger 	printf("\tUID=%d", uid);
    903       1.5    cegger 	if (uid_string != NULL)
    904       1.5    cegger 		printf(" (%s)", uid_string);
    905       1.5    cegger 	printf("\n");
    906       1.5    cegger }
    907       1.5    cegger 
    908       1.5    cegger static void
    909       1.5    cegger acpi_print_local_apic(uint32_t apic_id, uint32_t flags)
    910       1.5    cegger {
    911       1.5    cegger 
    912       1.5    cegger 	printf("\tFlags={");
    913       1.5    cegger 	if (flags & ACPI_MADT_ENABLED)
    914       1.5    cegger 		printf("ENABLED");
    915       1.5    cegger 	else
    916       1.5    cegger 		printf("DISABLED");
    917       1.5    cegger 	printf("}\n");
    918       1.5    cegger 	printf("\tAPIC ID=%d\n", apic_id);
    919       1.5    cegger }
    920       1.5    cegger 
    921       1.5    cegger static void
    922       1.5    cegger acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr)
    923       1.5    cegger {
    924       1.5    cegger 
    925       1.5    cegger 	printf("\tAPIC ID=%d\n", apic_id);
    926       1.5    cegger 	printf("\tINT BASE=%d\n", int_base);
    927       1.5    cegger 	printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr);
    928       1.5    cegger }
    929       1.5    cegger 
    930       1.5    cegger static void
    931       1.5    cegger acpi_print_mps_flags(uint16_t flags)
    932       1.5    cegger {
    933       1.5    cegger 
    934       1.5    cegger 	printf("\tFlags={Polarity=");
    935       1.5    cegger 	switch (flags & ACPI_MADT_POLARITY_MASK) {
    936       1.5    cegger 	case ACPI_MADT_POLARITY_CONFORMS:
    937       1.5    cegger 		printf("conforming");
    938       1.5    cegger 		break;
    939       1.5    cegger 	case ACPI_MADT_POLARITY_ACTIVE_HIGH:
    940       1.5    cegger 		printf("active-hi");
    941       1.5    cegger 		break;
    942       1.5    cegger 	case ACPI_MADT_POLARITY_ACTIVE_LOW:
    943       1.5    cegger 		printf("active-lo");
    944       1.5    cegger 		break;
    945       1.5    cegger 	default:
    946       1.5    cegger 		printf("0x%x", flags & ACPI_MADT_POLARITY_MASK);
    947       1.5    cegger 		break;
    948       1.5    cegger 	}
    949       1.5    cegger 	printf(", Trigger=");
    950       1.5    cegger 	switch (flags & ACPI_MADT_TRIGGER_MASK) {
    951       1.5    cegger 	case ACPI_MADT_TRIGGER_CONFORMS:
    952       1.5    cegger 		printf("conforming");
    953       1.5    cegger 		break;
    954       1.5    cegger 	case ACPI_MADT_TRIGGER_EDGE:
    955       1.5    cegger 		printf("edge");
    956       1.5    cegger 		break;
    957       1.5    cegger 	case ACPI_MADT_TRIGGER_LEVEL:
    958       1.5    cegger 		printf("level");
    959       1.5    cegger 		break;
    960       1.5    cegger 	default:
    961       1.5    cegger 		printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2);
    962       1.5    cegger 	}
    963       1.5    cegger 	printf("}\n");
    964       1.5    cegger }
    965       1.5    cegger 
    966       1.5    cegger static void
    967  1.15.8.1    martin acpi_print_gicc_flags(uint32_t flags)
    968  1.15.8.1    martin {
    969  1.15.8.1    martin 
    970  1.15.8.1    martin 	printf("\tFlags={Performance intr=");
    971  1.15.8.1    martin 	if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE)
    972  1.15.8.1    martin 		printf("edge");
    973  1.15.8.1    martin 	else
    974  1.15.8.1    martin 		printf("level");
    975  1.15.8.1    martin 	printf(", VGIC intr=");
    976  1.15.8.1    martin 	if (flags & ACPI_MADT_VGIC_IRQ_MODE)
    977  1.15.8.1    martin 		printf("edge");
    978  1.15.8.1    martin 	else
    979  1.15.8.1    martin 		printf("level");
    980  1.15.8.1    martin 	printf("}\n");
    981  1.15.8.1    martin }
    982  1.15.8.1    martin 
    983  1.15.8.1    martin static void
    984       1.5    cegger acpi_print_intr(uint32_t intr, uint16_t mps_flags)
    985       1.5    cegger {
    986       1.5    cegger 
    987       1.5    cegger 	printf("\tINTR=%d\n", intr);
    988       1.5    cegger 	acpi_print_mps_flags(mps_flags);
    989       1.5    cegger }
    990       1.5    cegger 
    991       1.5    cegger static void
    992       1.5    cegger acpi_print_local_nmi(u_int lint, uint16_t mps_flags)
    993       1.5    cegger {
    994       1.5    cegger 
    995       1.5    cegger 	printf("\tLINT Pin=%d\n", lint);
    996       1.5    cegger 	acpi_print_mps_flags(mps_flags);
    997       1.5    cegger }
    998       1.5    cegger 
    999  1.15.8.1    martin static const char *apic_types[] = {
   1000  1.15.8.1    martin     [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC",
   1001  1.15.8.1    martin     [ACPI_MADT_TYPE_IO_APIC] = "IO APIC",
   1002  1.15.8.1    martin     [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override",
   1003  1.15.8.1    martin     [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI",
   1004  1.15.8.1    martin     [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI",
   1005  1.15.8.1    martin     [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override",
   1006  1.15.8.1    martin     [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC",
   1007  1.15.8.1    martin     [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC",
   1008  1.15.8.1    martin     [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt",
   1009  1.15.8.1    martin     [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC",
   1010  1.15.8.1    martin     [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI",
   1011  1.15.8.1    martin     [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure",
   1012  1.15.8.1    martin     [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure",
   1013  1.15.8.1    martin     [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame",
   1014  1.15.8.1    martin     [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure",
   1015  1.15.8.1    martin     [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure"
   1016  1.15.8.1    martin };
   1017  1.15.8.1    martin 
   1018  1.15.8.1    martin static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT",
   1019  1.15.8.1    martin 					    "Corrected Platform Error" };
   1020  1.15.8.1    martin 
   1021  1.15.8.1    martin static void
   1022  1.15.8.1    martin acpi_print_gicm_flags(ACPI_MADT_GENERIC_MSI_FRAME *gicm)
   1023  1.15.8.1    martin {
   1024  1.15.8.1    martin 	uint32_t flags = gicm->Flags;
   1025  1.15.8.1    martin 
   1026  1.15.8.1    martin 	printf("\tFLAGS={");
   1027  1.15.8.1    martin 	if (flags & ACPI_MADT_OVERRIDE_SPI_VALUES)
   1028  1.15.8.1    martin 		printf("SPI Count/Base Select");
   1029  1.15.8.1    martin 	printf("}\n");
   1030  1.15.8.1    martin }
   1031       1.5    cegger 
   1032       1.5    cegger static void
   1033       1.5    cegger acpi_print_madt(ACPI_SUBTABLE_HEADER *mp)
   1034       1.5    cegger {
   1035       1.5    cegger 	ACPI_MADT_LOCAL_APIC *lapic;
   1036       1.5    cegger 	ACPI_MADT_IO_APIC *ioapic;
   1037       1.5    cegger 	ACPI_MADT_INTERRUPT_OVERRIDE *over;
   1038       1.5    cegger 	ACPI_MADT_NMI_SOURCE *nmi;
   1039       1.5    cegger 	ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi;
   1040       1.5    cegger 	ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over;
   1041       1.5    cegger 	ACPI_MADT_IO_SAPIC *iosapic;
   1042       1.5    cegger 	ACPI_MADT_LOCAL_SAPIC *lsapic;
   1043       1.5    cegger 	ACPI_MADT_INTERRUPT_SOURCE *isrc;
   1044       1.5    cegger 	ACPI_MADT_LOCAL_X2APIC *x2apic;
   1045       1.5    cegger 	ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi;
   1046  1.15.8.1    martin 	ACPI_MADT_GENERIC_INTERRUPT *gicc;
   1047  1.15.8.1    martin 	ACPI_MADT_GENERIC_DISTRIBUTOR *gicd;
   1048  1.15.8.1    martin 	ACPI_MADT_GENERIC_MSI_FRAME *gicm;
   1049  1.15.8.1    martin 	ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr;
   1050  1.15.8.1    martin 	ACPI_MADT_GENERIC_TRANSLATOR *gict;
   1051       1.5    cegger 
   1052  1.15.8.1    martin 	if (mp->Type < __arraycount(apic_types))
   1053       1.5    cegger 		printf("\tType=%s\n", apic_types[mp->Type]);
   1054       1.5    cegger 	else
   1055       1.5    cegger 		printf("\tType=%d (unknown)\n", mp->Type);
   1056       1.5    cegger 	switch (mp->Type) {
   1057       1.5    cegger 	case ACPI_MADT_TYPE_LOCAL_APIC:
   1058       1.5    cegger 		lapic = (ACPI_MADT_LOCAL_APIC *)mp;
   1059       1.5    cegger 		acpi_print_cpu(lapic->ProcessorId);
   1060       1.5    cegger 		acpi_print_local_apic(lapic->Id, lapic->LapicFlags);
   1061       1.5    cegger 		break;
   1062       1.5    cegger 	case ACPI_MADT_TYPE_IO_APIC:
   1063       1.5    cegger 		ioapic = (ACPI_MADT_IO_APIC *)mp;
   1064       1.5    cegger 		acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase,
   1065       1.5    cegger 		    ioapic->Address);
   1066       1.5    cegger 		break;
   1067       1.5    cegger 	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
   1068       1.5    cegger 		over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp;
   1069       1.5    cegger 		printf("\tBUS=%d\n", (u_int)over->Bus);
   1070       1.5    cegger 		printf("\tIRQ=%d\n", (u_int)over->SourceIrq);
   1071       1.5    cegger 		acpi_print_intr(over->GlobalIrq, over->IntiFlags);
   1072       1.5    cegger 		break;
   1073       1.5    cegger 	case ACPI_MADT_TYPE_NMI_SOURCE:
   1074       1.5    cegger 		nmi = (ACPI_MADT_NMI_SOURCE *)mp;
   1075       1.5    cegger 		acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags);
   1076       1.5    cegger 		break;
   1077       1.5    cegger 	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
   1078       1.5    cegger 		lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp;
   1079       1.5    cegger 		acpi_print_cpu(lapic_nmi->ProcessorId);
   1080       1.5    cegger 		acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags);
   1081       1.5    cegger 		break;
   1082       1.5    cegger 	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
   1083       1.5    cegger 		lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp;
   1084       1.5    cegger 		printf("\tLocal APIC ADDR=0x%016jx\n",
   1085       1.5    cegger 		    (uintmax_t)lapic_over->Address);
   1086       1.5    cegger 		break;
   1087       1.5    cegger 	case ACPI_MADT_TYPE_IO_SAPIC:
   1088       1.5    cegger 		iosapic = (ACPI_MADT_IO_SAPIC *)mp;
   1089       1.5    cegger 		acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase,
   1090       1.5    cegger 		    iosapic->Address);
   1091       1.5    cegger 		break;
   1092       1.5    cegger 	case ACPI_MADT_TYPE_LOCAL_SAPIC:
   1093       1.5    cegger 		lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp;
   1094       1.5    cegger 		acpi_print_cpu(lsapic->ProcessorId);
   1095       1.5    cegger 		acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags);
   1096       1.5    cegger 		printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid);
   1097       1.5    cegger 		if (mp->Length > offsetof(ACPI_MADT_LOCAL_SAPIC, Uid))
   1098       1.5    cegger 			acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString);
   1099       1.5    cegger 		break;
   1100       1.5    cegger 	case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
   1101       1.5    cegger 		isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp;
   1102  1.15.8.1    martin 		if (isrc->Type < __arraycount(platform_int_types))
   1103       1.5    cegger 			printf("\tType=%s\n", platform_int_types[isrc->Type]);
   1104       1.5    cegger 		else
   1105       1.5    cegger 			printf("\tType=%d (unknown)\n", isrc->Type);
   1106       1.5    cegger 		printf("\tAPIC ID=%d\n", (u_int)isrc->Id);
   1107       1.5    cegger 		printf("\tAPIC EID=%d\n", (u_int)isrc->Eid);
   1108       1.5    cegger 		printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector);
   1109       1.5    cegger 		acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags);
   1110       1.5    cegger 		break;
   1111       1.5    cegger 	case ACPI_MADT_TYPE_LOCAL_X2APIC:
   1112       1.5    cegger 		x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp;
   1113       1.5    cegger 		acpi_print_cpu_uid(x2apic->Uid, NULL);
   1114       1.5    cegger 		acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags);
   1115       1.5    cegger 		break;
   1116       1.5    cegger 	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
   1117       1.5    cegger 		x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp;
   1118       1.5    cegger 		acpi_print_cpu_uid(x2apic_nmi->Uid, NULL);
   1119       1.5    cegger 		acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags);
   1120       1.5    cegger 		break;
   1121  1.15.8.1    martin 	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
   1122  1.15.8.1    martin 		gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp;
   1123  1.15.8.1    martin 		acpi_print_cpu_uid(gicc->Uid, NULL);
   1124  1.15.8.1    martin 		printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber);
   1125  1.15.8.1    martin 		acpi_print_gicc_flags(gicc->Flags);
   1126  1.15.8.1    martin 		printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion);
   1127  1.15.8.1    martin 		printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt);
   1128  1.15.8.1    martin 		printf("\tParked ADDR=%016jx\n",
   1129  1.15.8.1    martin 		    (uintmax_t)gicc->ParkedAddress);
   1130  1.15.8.1    martin 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress);
   1131  1.15.8.1    martin 		printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress);
   1132  1.15.8.1    martin 		printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress);
   1133  1.15.8.1    martin 		printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt);
   1134  1.15.8.1    martin 		printf("\tGICR ADDR=%016jx\n",
   1135  1.15.8.1    martin 		    (uintmax_t)gicc->GicrBaseAddress);
   1136  1.15.8.1    martin 		printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr);
   1137  1.15.8.1    martin 		printf("\tEfficency Class=%d\n", (u_int)gicc->EfficiencyClass);
   1138  1.15.8.1    martin 		break;
   1139  1.15.8.1    martin 	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
   1140  1.15.8.1    martin 		gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp;
   1141  1.15.8.1    martin 		printf("\tGIC ID=%d\n", (u_int)gicd->GicId);
   1142  1.15.8.1    martin 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress);
   1143  1.15.8.1    martin 		printf("\tVector Base=%d\n", gicd->GlobalIrqBase);
   1144  1.15.8.1    martin 		printf("\tGIC VERSION=%d\n", (u_int)gicd->Version);
   1145  1.15.8.1    martin 		break;
   1146  1.15.8.1    martin 	case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
   1147  1.15.8.1    martin 		gicm = (ACPI_MADT_GENERIC_MSI_FRAME*)mp;
   1148  1.15.8.1    martin 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicm->BaseAddress);
   1149  1.15.8.1    martin 		acpi_print_gicm_flags(gicm);
   1150  1.15.8.1    martin 		printf("\tSPI Count=%u\n", gicm->SpiCount);
   1151  1.15.8.1    martin 		printf("\tSPI Base=%u\n", gicm->SpiBase);
   1152  1.15.8.1    martin 		break;
   1153  1.15.8.1    martin 	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
   1154  1.15.8.1    martin 		gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp;
   1155  1.15.8.1    martin 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress);
   1156  1.15.8.1    martin 		printf("\tLength=%08x\n", gicr->Length);
   1157  1.15.8.1    martin 		break;
   1158  1.15.8.1    martin 	case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
   1159  1.15.8.1    martin 		gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp;
   1160  1.15.8.1    martin 		printf("\tGIC ITS ID=%d\n", gict->TranslationId);
   1161  1.15.8.1    martin 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress);
   1162  1.15.8.1    martin 		break;
   1163       1.5    cegger 	}
   1164       1.5    cegger }
   1165       1.5    cegger 
   1166       1.5    cegger #ifdef notyet
   1167       1.5    cegger static void
   1168       1.5    cegger acpi_print_bert_region(ACPI_BERT_REGION *region)
   1169       1.5    cegger {
   1170       1.5    cegger 	uint32_t i, pos, entries;
   1171       1.5    cegger 	ACPI_HEST_GENERIC_DATA *data;
   1172       1.5    cegger 
   1173       1.5    cegger 	printf("\n");
   1174       1.5    cegger 	printf("\tBlockStatus={ ");
   1175       1.5    cegger 
   1176       1.5    cegger 	if (region->BlockStatus & ACPI_BERT_UNCORRECTABLE)
   1177       1.5    cegger 		printf("Uncorrectable");
   1178       1.5    cegger 	if (region->BlockStatus & ACPI_BERT_CORRECTABLE)
   1179       1.5    cegger 		printf("Correctable");
   1180       1.5    cegger 	if (region->BlockStatus & ACPI_BERT_MULTIPLE_UNCORRECTABLE)
   1181       1.5    cegger 		printf("Multiple Uncorrectable");
   1182       1.5    cegger 	if (region->BlockStatus & ACPI_BERT_MULTIPLE_CORRECTABLE)
   1183       1.5    cegger 		printf("Multiple Correctable");
   1184       1.5    cegger 	entries = region->BlockStatus & ACPI_BERT_ERROR_ENTRY_COUNT;
   1185       1.5    cegger 	printf(", Error Entry Count=%d", entries);
   1186       1.5    cegger 	printf("}\n");
   1187       1.5    cegger 
   1188       1.5    cegger 	printf("\tRaw Data Offset=0x%x\n", region->RawDataOffset);
   1189       1.5    cegger 	printf("\tRaw Data Length=0x%x\n", region->RawDataLength);
   1190       1.5    cegger 	printf("\tData Length=0x%x\n", region->DataLength);
   1191       1.5    cegger 
   1192       1.5    cegger 	acpi_print_hest_errorseverity(region->ErrorSeverity);
   1193       1.5    cegger 
   1194       1.5    cegger 	pos = sizeof(ACPI_BERT_REGION);
   1195       1.5    cegger 	for (i = 0; i < entries; i++) {
   1196       1.5    cegger 		data = (ACPI_HEST_GENERIC_DATA *)((char *)region + pos);
   1197       1.5    cegger 		acpi_print_hest_generic_data(data);
   1198       1.5    cegger 		pos += sizeof(ACPI_HEST_GENERIC_DATA);
   1199       1.5    cegger 	}
   1200       1.5    cegger }
   1201       1.5    cegger #endif
   1202       1.5    cegger 
   1203       1.5    cegger static void
   1204       1.5    cegger acpi_handle_bert(ACPI_TABLE_HEADER *sdp)
   1205       1.5    cegger {
   1206       1.5    cegger 	ACPI_TABLE_BERT *bert;
   1207       1.5    cegger 
   1208       1.5    cegger 	printf(BEGIN_COMMENT);
   1209       1.5    cegger 	acpi_print_sdt(sdp);
   1210       1.5    cegger 	bert = (ACPI_TABLE_BERT *)sdp;
   1211       1.5    cegger 
   1212       1.5    cegger 	printf("\tLength of Boot Error Region=%d bytes\n", bert->RegionLength);
   1213       1.5    cegger 	printf("\tPhysical Address of Region=0x%"PRIx64"\n", bert->Address);
   1214       1.5    cegger 
   1215       1.5    cegger 	printf(END_COMMENT);
   1216       1.5    cegger }
   1217       1.5    cegger 
   1218       1.5    cegger static void
   1219       1.5    cegger acpi_handle_boot(ACPI_TABLE_HEADER *sdp)
   1220       1.5    cegger {
   1221       1.5    cegger 	ACPI_TABLE_BOOT *boot;
   1222       1.5    cegger 
   1223       1.5    cegger 	printf(BEGIN_COMMENT);
   1224       1.5    cegger 	acpi_print_sdt(sdp);
   1225       1.5    cegger 	boot = (ACPI_TABLE_BOOT *)sdp;
   1226       1.5    cegger 	printf("\tCMOS Index=0x%02x\n", boot->CmosIndex);
   1227       1.5    cegger 	printf(END_COMMENT);
   1228       1.5    cegger }
   1229       1.5    cegger 
   1230       1.5    cegger static void
   1231       1.5    cegger acpi_handle_cpep(ACPI_TABLE_HEADER *sdp)
   1232       1.5    cegger {
   1233       1.5    cegger 	ACPI_TABLE_CPEP *cpep;
   1234       1.5    cegger 	ACPI_CPEP_POLLING *poll;
   1235       1.5    cegger 	uint32_t cpep_pos;
   1236       1.5    cegger 
   1237       1.5    cegger 	printf(BEGIN_COMMENT);
   1238       1.5    cegger 	acpi_print_sdt(sdp);
   1239       1.5    cegger 	cpep = (ACPI_TABLE_CPEP *)sdp;
   1240       1.5    cegger 
   1241       1.5    cegger 	cpep_pos = sizeof(ACPI_TABLE_CPEP);
   1242       1.5    cegger 	while (cpep_pos < sdp->Length) {
   1243       1.5    cegger 		poll = (ACPI_CPEP_POLLING *)((char *)cpep + cpep_pos);
   1244       1.5    cegger 		acpi_print_cpu(poll->Id);
   1245       1.5    cegger 		printf("\tACPI CPU EId=%d\n", poll->Eid);
   1246       1.5    cegger 		printf("\tPoll Interval=%d msec\n", poll->Interval);
   1247       1.5    cegger 		cpep_pos += sizeof(ACPI_CPEP_POLLING);
   1248       1.5    cegger 	}
   1249       1.5    cegger 	printf(END_COMMENT);
   1250       1.5    cegger }
   1251       1.5    cegger 
   1252       1.5    cegger static void
   1253  1.15.8.2    martin acpi_print_csrt_resource_group(ACPI_CSRT_GROUP *grp)
   1254  1.15.8.2    martin {
   1255  1.15.8.2    martin 	ACPI_CSRT_DESCRIPTOR *desc;
   1256  1.15.8.2    martin 
   1257  1.15.8.2    martin 	printf("\tLength=%u\n", grp->Length);
   1258  1.15.8.2    martin 	printf("\tVendorId=");
   1259  1.15.8.2    martin 	acpi_print_string((char *)&grp->VendorId, 4);
   1260  1.15.8.2    martin 	printf("\n");
   1261  1.15.8.2    martin 	if (grp->SubvendorId != 0) {
   1262  1.15.8.2    martin 		printf("\tSubvendorId=");
   1263  1.15.8.2    martin 		acpi_print_string((char *)&grp->SubvendorId, 4);
   1264  1.15.8.2    martin 		printf("\n");
   1265  1.15.8.2    martin 	}
   1266  1.15.8.2    martin 	printf("\tDeviceId=0x%08x\n", grp->DeviceId);
   1267  1.15.8.2    martin 	if (grp->SubdeviceId != 0)
   1268  1.15.8.2    martin 		printf("\tSubdeviceId=0x%08x\n", grp->SubdeviceId);
   1269  1.15.8.2    martin 	printf("\tRevision=%hu\n", grp->Revision);
   1270  1.15.8.2    martin 	printf("\tSharedInfoLength=%u\n", grp->SharedInfoLength);
   1271  1.15.8.2    martin 
   1272  1.15.8.2    martin 	/* Next is Shared Info */
   1273  1.15.8.2    martin 	if (grp->SharedInfoLength != 0) {
   1274  1.15.8.2    martin 		printf("\tShared Info ");
   1275  1.15.8.2    martin 		acpi_dump_bytes((uint8_t *)(grp + 1),
   1276  1.15.8.2    martin 		    grp->SharedInfoLength, 1);
   1277  1.15.8.2    martin 	}
   1278  1.15.8.2    martin 
   1279  1.15.8.2    martin 	/* And then, Resource Descriptors */
   1280  1.15.8.2    martin 	desc = (ACPI_CSRT_DESCRIPTOR *)
   1281  1.15.8.2    martin 	    ((vaddr_t)(grp + 1) + grp->SharedInfoLength);
   1282  1.15.8.2    martin 	while (desc < (ACPI_CSRT_DESCRIPTOR *)((vaddr_t)grp + grp->Length)) {
   1283  1.15.8.2    martin 		bool unknownsubytpe = false;
   1284  1.15.8.2    martin 		printf("\n\tLength=%u\n", desc->Length);
   1285  1.15.8.2    martin 		printf("\tResource Type=");
   1286  1.15.8.2    martin 		switch (desc->Type) {
   1287  1.15.8.2    martin 		case ACPI_CSRT_TYPE_INTERRUPT:
   1288  1.15.8.2    martin 			printf("Interrupt");
   1289  1.15.8.2    martin 			switch (desc->Subtype) {
   1290  1.15.8.2    martin 			case ACPI_CSRT_XRUPT_LINE:
   1291  1.15.8.2    martin 				printf("(Interrupt line)\n");
   1292  1.15.8.2    martin 				break;
   1293  1.15.8.2    martin 			case ACPI_CSRT_XRUPT_CONTROLLER:
   1294  1.15.8.2    martin 				printf("(Interrupt controller)\n");
   1295  1.15.8.2    martin 				break;
   1296  1.15.8.2    martin 			default:
   1297  1.15.8.2    martin 				unknownsubytpe = true;
   1298  1.15.8.2    martin 				break;
   1299  1.15.8.2    martin 			}
   1300  1.15.8.2    martin 			break;
   1301  1.15.8.2    martin 		case ACPI_CSRT_TYPE_TIMER:
   1302  1.15.8.2    martin 			printf("Timer");
   1303  1.15.8.2    martin 			switch (desc->Subtype) {
   1304  1.15.8.2    martin 			case ACPI_CSRT_TIMER:
   1305  1.15.8.2    martin 				printf("\n");
   1306  1.15.8.2    martin 				break;
   1307  1.15.8.2    martin 			default:
   1308  1.15.8.2    martin 				unknownsubytpe = true;
   1309  1.15.8.2    martin 				break;
   1310  1.15.8.2    martin 			}
   1311  1.15.8.2    martin 			break;
   1312  1.15.8.2    martin 		case ACPI_CSRT_TYPE_DMA:
   1313  1.15.8.2    martin 			printf("DMA");
   1314  1.15.8.2    martin 			switch (desc->Subtype) {
   1315  1.15.8.2    martin 			case ACPI_CSRT_DMA_CHANNEL:
   1316  1.15.8.2    martin 				printf("(DMA channel)\n");
   1317  1.15.8.2    martin 				break;
   1318  1.15.8.2    martin 			case ACPI_CSRT_DMA_CONTROLLER:
   1319  1.15.8.2    martin 				printf("(DMA controller)\n");
   1320  1.15.8.2    martin 				break;
   1321  1.15.8.2    martin 			default:
   1322  1.15.8.2    martin 				unknownsubytpe = true;
   1323  1.15.8.2    martin 				break;
   1324  1.15.8.2    martin 			}
   1325  1.15.8.2    martin 			break;
   1326  1.15.8.2    martin 		case 0x0004: /* XXX Platform Security */
   1327  1.15.8.2    martin 			printf("Platform Security");
   1328  1.15.8.2    martin 			switch (desc->Subtype) {
   1329  1.15.8.2    martin 			case 0x0001:
   1330  1.15.8.2    martin 				printf("\n");
   1331  1.15.8.2    martin 				/* Platform Security */
   1332  1.15.8.2    martin 				break;
   1333  1.15.8.2    martin 			default:
   1334  1.15.8.2    martin 				unknownsubytpe = true;
   1335  1.15.8.2    martin 				break;
   1336  1.15.8.2    martin 			}
   1337  1.15.8.2    martin 			break;
   1338  1.15.8.2    martin 		default:
   1339  1.15.8.2    martin 			printf("Unknown (%hx)\n", desc->Type);
   1340  1.15.8.2    martin 			break;
   1341  1.15.8.2    martin 		}
   1342  1.15.8.2    martin 		if (unknownsubytpe)
   1343  1.15.8.2    martin 			printf("(unknown subtype(%hx))\n", desc->Subtype);
   1344  1.15.8.2    martin 
   1345  1.15.8.2    martin 		printf("\tUID=0x%08x\n", desc->Uid);
   1346  1.15.8.2    martin 		printf("\tVendor defined info ");
   1347  1.15.8.2    martin 		acpi_dump_bytes((uint8_t *)(desc + 1),
   1348  1.15.8.2    martin 		    desc->Length - sizeof(ACPI_CSRT_DESCRIPTOR), 1);
   1349  1.15.8.2    martin 
   1350  1.15.8.2    martin 		/* Next */
   1351  1.15.8.2    martin 		desc = (ACPI_CSRT_DESCRIPTOR *)((vaddr_t)desc + desc->Length);
   1352  1.15.8.2    martin 	}
   1353  1.15.8.2    martin }
   1354  1.15.8.2    martin 
   1355  1.15.8.2    martin static void
   1356  1.15.8.2    martin acpi_handle_csrt(ACPI_TABLE_HEADER *sdp)
   1357  1.15.8.2    martin {
   1358  1.15.8.2    martin 	ACPI_CSRT_GROUP *grp;
   1359  1.15.8.2    martin 	uint totallen = sdp->Length;
   1360  1.15.8.2    martin 
   1361  1.15.8.2    martin 	printf(BEGIN_COMMENT);
   1362  1.15.8.2    martin 	acpi_print_sdt(sdp);
   1363  1.15.8.2    martin 	grp = (ACPI_CSRT_GROUP *)(sdp + 1);
   1364  1.15.8.2    martin 
   1365  1.15.8.2    martin 	while (grp < (ACPI_CSRT_GROUP *)((vaddr_t)sdp + totallen)) {
   1366  1.15.8.2    martin 		printf("\n");
   1367  1.15.8.2    martin 		acpi_print_csrt_resource_group(grp);
   1368  1.15.8.2    martin 
   1369  1.15.8.2    martin 		/* Next */
   1370  1.15.8.2    martin 		grp = (ACPI_CSRT_GROUP *)((vaddr_t)grp + grp->Length);
   1371  1.15.8.2    martin 	}
   1372  1.15.8.2    martin 
   1373  1.15.8.2    martin 	printf(END_COMMENT);
   1374  1.15.8.2    martin }
   1375  1.15.8.2    martin 
   1376  1.15.8.2    martin static void
   1377       1.5    cegger acpi_handle_dbgp(ACPI_TABLE_HEADER *sdp)
   1378       1.5    cegger {
   1379       1.5    cegger 	ACPI_TABLE_DBGP *dbgp;
   1380       1.5    cegger 
   1381       1.5    cegger 	printf(BEGIN_COMMENT);
   1382       1.5    cegger 	acpi_print_sdt(sdp);
   1383       1.5    cegger 	dbgp = (ACPI_TABLE_DBGP *)sdp;
   1384       1.5    cegger 	printf("\tType={");
   1385       1.5    cegger 	switch (dbgp->Type) {
   1386       1.5    cegger 	case 0:
   1387       1.5    cegger 		printf("full 16550");
   1388       1.5    cegger 		break;
   1389       1.5    cegger 	case 1:
   1390       1.5    cegger 		printf("subset of 16550");
   1391       1.5    cegger 		break;
   1392       1.5    cegger 	}
   1393       1.5    cegger 	printf("}\n");
   1394  1.15.8.1    martin 	printf("\tDebugPort=");
   1395       1.5    cegger 	acpi_print_gas(&dbgp->DebugPort);
   1396  1.15.8.1    martin 	printf("\n");
   1397  1.15.8.1    martin 	printf(END_COMMENT);
   1398  1.15.8.1    martin }
   1399  1.15.8.1    martin 
   1400  1.15.8.2    martin /* This function is used by DBG2 and SPCR. */
   1401  1.15.8.2    martin static void
   1402  1.15.8.2    martin acpi_print_dbg2_serial_subtype(uint16_t subtype)
   1403  1.15.8.2    martin {
   1404  1.15.8.2    martin 
   1405  1.15.8.2    martin 	switch (subtype) {
   1406  1.15.8.2    martin 	case ACPI_DBG2_16550_COMPATIBLE:
   1407  1.15.8.2    martin 		printf("Fully 16550 compatible\n");
   1408  1.15.8.2    martin 		break;
   1409  1.15.8.2    martin 	case ACPI_DBG2_16550_SUBSET:
   1410  1.15.8.2    martin 		printf("16550 subset with DBGP Rev. 1\n");
   1411  1.15.8.2    martin 		break;
   1412  1.15.8.2    martin 	case ACPI_DBG2_ARM_PL011:
   1413  1.15.8.2    martin 		printf("ARM PL011\n");
   1414  1.15.8.2    martin 		break;
   1415  1.15.8.2    martin 	case ACPI_DBG2_ARM_SBSA_32BIT:
   1416  1.15.8.2    martin 		printf("ARM SBSA 32bit only\n");
   1417  1.15.8.2    martin 		break;
   1418  1.15.8.2    martin 	case ACPI_DBG2_ARM_SBSA_GENERIC:
   1419  1.15.8.2    martin 		printf("ARM SBSA Generic\n");
   1420  1.15.8.2    martin 		break;
   1421  1.15.8.2    martin 	case ACPI_DBG2_ARM_DCC:
   1422  1.15.8.2    martin 		printf("ARM DCC\n");
   1423  1.15.8.2    martin 		break;
   1424  1.15.8.2    martin 	case ACPI_DBG2_BCM2835:
   1425  1.15.8.2    martin 		printf("BCM2835\n");
   1426  1.15.8.2    martin 		break;
   1427  1.15.8.2    martin 	default:
   1428  1.15.8.2    martin 		printf("reserved (%04hx)\n", subtype);
   1429  1.15.8.2    martin 		break;
   1430  1.15.8.2    martin 	}
   1431  1.15.8.2    martin }
   1432  1.15.8.2    martin 
   1433  1.15.8.1    martin static void
   1434  1.15.8.1    martin acpi_print_dbg2_device(ACPI_DBG2_DEVICE *dev)
   1435  1.15.8.1    martin {
   1436  1.15.8.1    martin 
   1437  1.15.8.1    martin 	printf("\t\tRevision=%u\n", dev->Revision);
   1438  1.15.8.1    martin 	printf("\t\tLength=%u\n", dev->Length);
   1439  1.15.8.1    martin 	printf("\t\tRegisterCount=%u\n", dev->RegisterCount);
   1440  1.15.8.1    martin 
   1441  1.15.8.1    martin 	printf("\t\tNamepath=");
   1442  1.15.8.1    martin 	acpi_print_string((char *)((vaddr_t)dev + dev->NamepathOffset),
   1443  1.15.8.1    martin 	    dev->NamepathLength);
   1444  1.15.8.1    martin 	printf("\n");
   1445  1.15.8.1    martin 
   1446  1.15.8.1    martin 	if (dev->OemDataLength) {
   1447  1.15.8.1    martin 		printf("\t\tOemDataLength=%u\n", dev->OemDataLength);
   1448  1.15.8.1    martin 		printf("\t\tOemDataOffset=%u\n", dev->OemDataOffset);
   1449  1.15.8.1    martin 		/* XXX need dump */
   1450  1.15.8.1    martin 	}
   1451  1.15.8.1    martin 
   1452  1.15.8.1    martin 	printf("\t\tPortType=");
   1453  1.15.8.1    martin 	switch (dev->PortType) {
   1454  1.15.8.1    martin 	case ACPI_DBG2_SERIAL_PORT:
   1455  1.15.8.1    martin 		printf("Serial\n" "\t\tPortSubtype=");
   1456  1.15.8.2    martin 		acpi_print_dbg2_serial_subtype(dev->PortSubtype);
   1457  1.15.8.1    martin 		break;
   1458  1.15.8.1    martin 	case ACPI_DBG2_1394_PORT:
   1459  1.15.8.1    martin 		printf("IEEE1394\n" "\t\tPortSubtype=");
   1460  1.15.8.1    martin 		if (dev->PortSubtype == ACPI_DBG2_1394_STANDARD)
   1461  1.15.8.1    martin 			printf("Standard\n");
   1462  1.15.8.1    martin 		else
   1463  1.15.8.1    martin 			printf("reserved (%04hx)\n", dev->PortSubtype);
   1464  1.15.8.1    martin 		break;
   1465  1.15.8.1    martin 	case ACPI_DBG2_USB_PORT:
   1466  1.15.8.1    martin 		printf("USB\n" "\t\tPortSubtype=");
   1467  1.15.8.1    martin 		switch (dev->PortSubtype) {
   1468  1.15.8.1    martin 		case ACPI_DBG2_USB_XHCI:
   1469  1.15.8.1    martin 			printf("XHCIn");
   1470  1.15.8.1    martin 			break;
   1471  1.15.8.1    martin 		case ACPI_DBG2_USB_EHCI:
   1472  1.15.8.1    martin 			printf("EHCI\n");
   1473  1.15.8.1    martin 			break;
   1474  1.15.8.1    martin 		default:
   1475  1.15.8.1    martin 			printf("reserved (%04hx)\n", dev->PortSubtype);
   1476  1.15.8.1    martin 			break;
   1477  1.15.8.1    martin 		}
   1478  1.15.8.1    martin 		break;
   1479  1.15.8.1    martin 	case ACPI_DBG2_NET_PORT:
   1480  1.15.8.1    martin 		printf("Net\n" "\t\tPciVendorID=%04x\n", dev->PortSubtype);
   1481  1.15.8.1    martin 		break;
   1482  1.15.8.1    martin 	default:
   1483  1.15.8.1    martin 		printf("reserved (%04hx)\n", dev->PortType);
   1484  1.15.8.1    martin 		printf("\t\tPortSubtype=reserved (%04hx)\n", dev->PortSubtype);
   1485  1.15.8.1    martin 		break;
   1486  1.15.8.1    martin 	}
   1487  1.15.8.1    martin 
   1488  1.15.8.1    martin 	printf("\t\tBaseAddressOffset=0x%04x\n", dev->BaseAddressOffset);
   1489  1.15.8.1    martin 	printf("\t\tAddressSizeOffset=0x%04x\n", dev->AddressSizeOffset);
   1490  1.15.8.1    martin }
   1491  1.15.8.1    martin 
   1492  1.15.8.1    martin static void
   1493  1.15.8.1    martin acpi_handle_dbg2(ACPI_TABLE_HEADER *sdp)
   1494  1.15.8.1    martin {
   1495  1.15.8.1    martin 	ACPI_TABLE_DBG2 *dbg2;
   1496  1.15.8.1    martin 	ACPI_DBG2_DEVICE *device;
   1497  1.15.8.1    martin 	unsigned int i;
   1498  1.15.8.1    martin 
   1499  1.15.8.1    martin 	printf(BEGIN_COMMENT);
   1500  1.15.8.1    martin 	acpi_print_sdt(sdp);
   1501  1.15.8.1    martin 	dbg2 = (ACPI_TABLE_DBG2 *)sdp;
   1502  1.15.8.1    martin 
   1503  1.15.8.1    martin 	printf("\tCount=%u\n", dbg2->InfoCount);
   1504  1.15.8.1    martin 	device = (ACPI_DBG2_DEVICE *)((vaddr_t)sdp + dbg2->InfoOffset);
   1505  1.15.8.1    martin 	for (i = 0; i < dbg2->InfoCount; i++) {
   1506  1.15.8.1    martin 		printf("\tDevice %u={\n", i);
   1507  1.15.8.1    martin 		acpi_print_dbg2_device(device);
   1508  1.15.8.1    martin 		printf("\t}\n");
   1509  1.15.8.1    martin 		device++;
   1510  1.15.8.1    martin 	}
   1511  1.15.8.1    martin 
   1512       1.5    cegger 	printf(END_COMMENT);
   1513       1.5    cegger }
   1514       1.5    cegger 
   1515       1.5    cegger static void
   1516       1.5    cegger acpi_print_einj_action(ACPI_WHEA_HEADER *whea)
   1517       1.5    cegger {
   1518       1.5    cegger 	printf("\tACTION={");
   1519       1.5    cegger 	switch (whea->Action) {
   1520       1.5    cegger 	case ACPI_EINJ_BEGIN_OPERATION:
   1521       1.5    cegger 		printf("Begin Operation");
   1522       1.5    cegger 		break;
   1523       1.5    cegger 	case ACPI_EINJ_GET_TRIGGER_TABLE:
   1524       1.5    cegger 		printf("Get Trigger Table");
   1525       1.5    cegger 		break;
   1526       1.5    cegger 	case ACPI_EINJ_SET_ERROR_TYPE:
   1527       1.5    cegger 		printf("Set Error Type");
   1528       1.5    cegger 		break;
   1529       1.5    cegger 	case ACPI_EINJ_GET_ERROR_TYPE:
   1530       1.5    cegger 		printf("Get Error Type");
   1531       1.5    cegger 		break;
   1532       1.5    cegger 	case ACPI_EINJ_END_OPERATION:
   1533       1.5    cegger 		printf("End Operation");
   1534       1.5    cegger 		break;
   1535       1.5    cegger 	case ACPI_EINJ_EXECUTE_OPERATION:
   1536       1.5    cegger 		printf("Execute Operation");
   1537       1.5    cegger 		break;
   1538       1.5    cegger 	case ACPI_EINJ_CHECK_BUSY_STATUS:
   1539       1.5    cegger 		printf("Check Busy Status");
   1540       1.5    cegger 		break;
   1541       1.5    cegger 	case ACPI_EINJ_GET_COMMAND_STATUS:
   1542       1.5    cegger 		printf("Get Command Status");
   1543       1.5    cegger 		break;
   1544  1.15.8.1    martin 	case ACPI_EINJ_SET_ERROR_TYPE_WITH_ADDRESS:
   1545  1.15.8.1    martin 		printf("Set Error Type With Address");
   1546  1.15.8.1    martin 		break;
   1547  1.15.8.1    martin 	case ACPI_EINJ_GET_EXECUTE_TIMINGS:
   1548  1.15.8.1    martin 		printf("Get Execute Operation Timings");
   1549  1.15.8.1    martin 		break;
   1550       1.5    cegger 	case ACPI_EINJ_ACTION_RESERVED:
   1551       1.5    cegger 		printf("Preserved");
   1552       1.5    cegger 		break;
   1553       1.5    cegger 	case ACPI_EINJ_TRIGGER_ERROR:
   1554       1.5    cegger 		printf("Trigger Error");
   1555       1.5    cegger 		break;
   1556       1.5    cegger 	default:
   1557       1.5    cegger 		printf("%d", whea->Action);
   1558       1.5    cegger 		break;
   1559       1.5    cegger 	}
   1560       1.5    cegger 	printf("}\n");
   1561       1.5    cegger }
   1562       1.5    cegger 
   1563       1.5    cegger static void
   1564       1.5    cegger acpi_print_einj_instruction(ACPI_WHEA_HEADER *whea)
   1565       1.5    cegger {
   1566       1.5    cegger 	uint32_t ins = whea->Instruction;
   1567       1.5    cegger 
   1568       1.5    cegger 	printf("\tINSTRUCTION={");
   1569       1.5    cegger 	switch (ins) {
   1570       1.5    cegger 	case ACPI_EINJ_READ_REGISTER:
   1571       1.5    cegger 		printf("Read Register");
   1572       1.5    cegger 		break;
   1573       1.5    cegger 	case ACPI_EINJ_READ_REGISTER_VALUE:
   1574       1.5    cegger 		printf("Read Register Value");
   1575       1.5    cegger 		break;
   1576       1.5    cegger 	case ACPI_EINJ_WRITE_REGISTER:
   1577       1.5    cegger 		printf("Write Register");
   1578       1.5    cegger 		break;
   1579       1.5    cegger 	case ACPI_EINJ_WRITE_REGISTER_VALUE:
   1580       1.5    cegger 		printf("Write Register Value");
   1581       1.5    cegger 		break;
   1582       1.5    cegger 	case ACPI_EINJ_NOOP:
   1583       1.5    cegger 		printf("Noop");
   1584       1.5    cegger 		break;
   1585       1.5    cegger 	case ACPI_EINJ_INSTRUCTION_RESERVED:
   1586       1.5    cegger 		printf("Reserved");
   1587       1.5    cegger 		break;
   1588       1.5    cegger 	default:
   1589       1.5    cegger 		printf("%d", ins);
   1590       1.5    cegger 		break;
   1591       1.5    cegger 	}
   1592       1.5    cegger 	printf("}\n");
   1593       1.5    cegger }
   1594       1.5    cegger 
   1595       1.5    cegger static void
   1596       1.5    cegger acpi_print_einj_flags(ACPI_WHEA_HEADER *whea)
   1597       1.5    cegger {
   1598       1.5    cegger 	uint32_t flags = whea->Flags;
   1599       1.5    cegger 
   1600  1.15.8.1    martin 	printf("\tFLAGS={");
   1601       1.5    cegger 	if (flags & ACPI_EINJ_PRESERVE)
   1602       1.5    cegger 		printf("PRESERVED");
   1603       1.5    cegger 	printf("}\n");
   1604       1.5    cegger }
   1605       1.5    cegger 
   1606       1.5    cegger static void
   1607       1.5    cegger acpi_handle_einj(ACPI_TABLE_HEADER *sdp)
   1608       1.5    cegger {
   1609       1.5    cegger 	ACPI_TABLE_EINJ *einj;
   1610       1.5    cegger 	ACPI_EINJ_ENTRY *einj_entry;
   1611       1.5    cegger 	uint32_t einj_pos;
   1612       1.5    cegger 	u_int i;
   1613       1.5    cegger 
   1614       1.5    cegger 	printf(BEGIN_COMMENT);
   1615       1.5    cegger 	acpi_print_sdt(sdp);
   1616       1.5    cegger 	einj = (ACPI_TABLE_EINJ *)sdp;
   1617       1.5    cegger 
   1618       1.5    cegger 	printf("\tHeader Length=%d\n", einj->HeaderLength);
   1619       1.5    cegger 	printf("\tFlags=0x%x\n", einj->Flags);
   1620       1.5    cegger 	printf("\tEntries=%d\n", einj->Entries);
   1621       1.5    cegger 
   1622       1.5    cegger 	einj_pos = sizeof(ACPI_TABLE_EINJ);
   1623       1.5    cegger 	for (i = 0; i < einj->Entries; i++) {
   1624       1.5    cegger 		einj_entry = (ACPI_EINJ_ENTRY *)((char *)einj + einj_pos);
   1625       1.5    cegger 		acpi_print_whea(&einj_entry->WheaHeader,
   1626       1.5    cegger 		    acpi_print_einj_action, acpi_print_einj_instruction,
   1627       1.5    cegger 		    acpi_print_einj_flags);
   1628       1.5    cegger 		einj_pos += sizeof(ACPI_EINJ_ENTRY);
   1629       1.5    cegger 	}
   1630       1.5    cegger 	printf(END_COMMENT);
   1631       1.5    cegger }
   1632       1.5    cegger 
   1633       1.5    cegger static void
   1634       1.5    cegger acpi_print_erst_action(ACPI_WHEA_HEADER *whea)
   1635       1.5    cegger {
   1636       1.5    cegger 	printf("\tACTION={");
   1637       1.5    cegger 	switch (whea->Action) {
   1638       1.5    cegger 	case ACPI_ERST_BEGIN_WRITE:
   1639       1.5    cegger 		printf("Begin Write");
   1640       1.5    cegger 		break;
   1641       1.5    cegger 	case ACPI_ERST_BEGIN_READ:
   1642       1.5    cegger 		printf("Begin Read");
   1643       1.5    cegger 		break;
   1644       1.5    cegger 	case ACPI_ERST_BEGIN_CLEAR:
   1645       1.5    cegger 		printf("Begin Clear");
   1646       1.5    cegger 		break;
   1647       1.5    cegger 	case ACPI_ERST_END:
   1648       1.5    cegger 		printf("End");
   1649       1.5    cegger 		break;
   1650       1.5    cegger 	case ACPI_ERST_SET_RECORD_OFFSET:
   1651       1.5    cegger 		printf("Set Record Offset");
   1652       1.5    cegger 		break;
   1653       1.5    cegger 	case ACPI_ERST_EXECUTE_OPERATION:
   1654       1.5    cegger 		printf("Execute Operation");
   1655       1.5    cegger 		break;
   1656       1.5    cegger 	case ACPI_ERST_CHECK_BUSY_STATUS:
   1657       1.5    cegger 		printf("Check Busy Status");
   1658       1.5    cegger 		break;
   1659       1.5    cegger 	case ACPI_ERST_GET_COMMAND_STATUS:
   1660       1.5    cegger 		printf("Get Command Status");
   1661       1.5    cegger 		break;
   1662       1.5    cegger 	case ACPI_ERST_GET_RECORD_ID:
   1663       1.5    cegger 		printf("Get Record ID");
   1664       1.5    cegger 		break;
   1665       1.5    cegger 	case ACPI_ERST_SET_RECORD_ID:
   1666       1.5    cegger 		printf("Set Record ID");
   1667       1.5    cegger 		break;
   1668       1.5    cegger 	case ACPI_ERST_GET_RECORD_COUNT:
   1669       1.5    cegger 		printf("Get Record Count");
   1670       1.5    cegger 		break;
   1671       1.5    cegger 	case ACPI_ERST_BEGIN_DUMMY_WRIITE:
   1672       1.5    cegger 		printf("Begin Dummy Write");
   1673       1.5    cegger 		break;
   1674       1.5    cegger 	case ACPI_ERST_NOT_USED:
   1675       1.5    cegger 		printf("Unused");
   1676       1.5    cegger 		break;
   1677       1.5    cegger 	case ACPI_ERST_GET_ERROR_RANGE:
   1678       1.5    cegger 		printf("Get Error Range");
   1679       1.5    cegger 		break;
   1680       1.5    cegger 	case ACPI_ERST_GET_ERROR_LENGTH:
   1681       1.5    cegger 		printf("Get Error Length");
   1682       1.5    cegger 		break;
   1683       1.5    cegger 	case ACPI_ERST_GET_ERROR_ATTRIBUTES:
   1684       1.5    cegger 		printf("Get Error Attributes");
   1685       1.5    cegger 		break;
   1686  1.15.8.1    martin 	case ACPI_ERST_EXECUTE_TIMINGS:
   1687  1.15.8.1    martin 		printf("Execute Operation Timings");
   1688  1.15.8.1    martin 		break;
   1689       1.5    cegger 	case ACPI_ERST_ACTION_RESERVED:
   1690       1.5    cegger 		printf("Reserved");
   1691       1.5    cegger 		break;
   1692       1.5    cegger 	default:
   1693       1.5    cegger 		printf("%d", whea->Action);
   1694       1.5    cegger 		break;
   1695       1.5    cegger 	}
   1696       1.5    cegger 	printf("}\n");
   1697       1.5    cegger }
   1698       1.5    cegger 
   1699       1.5    cegger static void
   1700       1.5    cegger acpi_print_erst_instruction(ACPI_WHEA_HEADER *whea)
   1701       1.5    cegger {
   1702       1.5    cegger 	printf("\tINSTRUCTION={");
   1703       1.5    cegger 	switch (whea->Instruction) {
   1704       1.5    cegger 	case ACPI_ERST_READ_REGISTER:
   1705       1.5    cegger 		printf("Read Register");
   1706       1.5    cegger 		break;
   1707       1.5    cegger 	case ACPI_ERST_READ_REGISTER_VALUE:
   1708       1.5    cegger 		printf("Read Register Value");
   1709       1.5    cegger 		break;
   1710       1.5    cegger 	case ACPI_ERST_WRITE_REGISTER:
   1711       1.5    cegger 		printf("Write Register");
   1712       1.5    cegger 		break;
   1713       1.5    cegger 	case ACPI_ERST_WRITE_REGISTER_VALUE:
   1714       1.5    cegger 		printf("Write Register Value");
   1715       1.5    cegger 		break;
   1716       1.5    cegger 	case ACPI_ERST_NOOP:
   1717       1.5    cegger 		printf("Noop");
   1718       1.5    cegger 		break;
   1719       1.5    cegger 	case ACPI_ERST_LOAD_VAR1:
   1720       1.5    cegger 		printf("Load Var1");
   1721       1.5    cegger 		break;
   1722       1.5    cegger 	case ACPI_ERST_LOAD_VAR2:
   1723       1.5    cegger 		printf("Load Var2");
   1724       1.5    cegger 		break;
   1725       1.5    cegger 	case ACPI_ERST_STORE_VAR1:
   1726       1.5    cegger 		printf("Store Var1");
   1727       1.5    cegger 		break;
   1728       1.5    cegger 	case ACPI_ERST_ADD:
   1729       1.5    cegger 		printf("Add");
   1730       1.5    cegger 		break;
   1731       1.5    cegger 	case ACPI_ERST_SUBTRACT:
   1732       1.5    cegger 		printf("Subtract");
   1733       1.5    cegger 		break;
   1734       1.5    cegger 	case ACPI_ERST_ADD_VALUE:
   1735       1.5    cegger 		printf("Add Value");
   1736       1.5    cegger 		break;
   1737       1.5    cegger 	case ACPI_ERST_SUBTRACT_VALUE:
   1738       1.5    cegger 		printf("Subtract Value");
   1739       1.5    cegger 		break;
   1740       1.5    cegger 	case ACPI_ERST_STALL:
   1741       1.5    cegger 		printf("Stall");
   1742       1.5    cegger 		break;
   1743       1.5    cegger 	case ACPI_ERST_STALL_WHILE_TRUE:
   1744       1.5    cegger 		printf("Stall While True");
   1745       1.5    cegger 		break;
   1746       1.5    cegger 	case ACPI_ERST_SKIP_NEXT_IF_TRUE:
   1747       1.5    cegger 		printf("Skip Next If True");
   1748       1.5    cegger 		break;
   1749       1.5    cegger 	case ACPI_ERST_GOTO:
   1750       1.5    cegger 		printf("Goto");
   1751       1.5    cegger 		break;
   1752       1.5    cegger 	case ACPI_ERST_SET_SRC_ADDRESS_BASE:
   1753       1.5    cegger 		printf("Set Src Address Base");
   1754       1.5    cegger 		break;
   1755       1.5    cegger 	case ACPI_ERST_SET_DST_ADDRESS_BASE:
   1756       1.5    cegger 		printf("Set Dst Address Base");
   1757       1.5    cegger 		break;
   1758       1.5    cegger 	case ACPI_ERST_MOVE_DATA:
   1759       1.5    cegger 		printf("Move Data");
   1760       1.5    cegger 		break;
   1761       1.5    cegger 	case ACPI_ERST_INSTRUCTION_RESERVED:
   1762       1.5    cegger 		printf("Reserved");
   1763       1.5    cegger 		break;
   1764       1.5    cegger 	default:
   1765       1.5    cegger 		printf("%d (reserved)", whea->Instruction);
   1766       1.5    cegger 		break;
   1767       1.5    cegger 	}
   1768       1.5    cegger 	printf("}\n");
   1769       1.5    cegger }
   1770       1.5    cegger 
   1771       1.5    cegger static void
   1772       1.5    cegger acpi_print_erst_flags(ACPI_WHEA_HEADER *whea)
   1773       1.5    cegger {
   1774       1.5    cegger 	uint32_t flags = whea->Flags;
   1775       1.5    cegger 
   1776  1.15.8.1    martin 	printf("\tFLAGS={");
   1777       1.5    cegger 	if (flags & ACPI_ERST_PRESERVE)
   1778       1.5    cegger 		printf("PRESERVED");
   1779       1.5    cegger 	printf("}\n");
   1780       1.5    cegger }
   1781       1.5    cegger 
   1782       1.5    cegger static void
   1783       1.5    cegger acpi_handle_erst(ACPI_TABLE_HEADER *sdp)
   1784       1.5    cegger {
   1785       1.5    cegger 	ACPI_TABLE_ERST *erst;
   1786       1.5    cegger 	ACPI_ERST_ENTRY *erst_entry;
   1787       1.5    cegger 	uint32_t erst_pos;
   1788       1.5    cegger 	u_int i;
   1789       1.5    cegger 
   1790       1.5    cegger 	printf(BEGIN_COMMENT);
   1791       1.5    cegger 	acpi_print_sdt(sdp);
   1792       1.5    cegger 	erst = (ACPI_TABLE_ERST *)sdp;
   1793       1.5    cegger 
   1794       1.5    cegger 	printf("\tHeader Length=%d\n", erst->HeaderLength);
   1795       1.5    cegger 	printf("\tEntries=%d\n", erst->Entries);
   1796       1.5    cegger 
   1797       1.5    cegger 	erst_pos = sizeof(ACPI_TABLE_ERST);
   1798       1.5    cegger 	for (i = 0; i < erst->Entries; i++) {
   1799       1.5    cegger 		erst_entry = (ACPI_ERST_ENTRY *)((char *)erst + erst_pos);
   1800       1.5    cegger 		acpi_print_whea(&erst_entry->WheaHeader,
   1801       1.5    cegger 		    acpi_print_erst_action, acpi_print_erst_instruction,
   1802       1.5    cegger 		    acpi_print_erst_flags);
   1803       1.5    cegger 		erst_pos += sizeof(ACPI_ERST_ENTRY);
   1804       1.5    cegger 	}
   1805       1.5    cegger 	printf(END_COMMENT);
   1806       1.5    cegger }
   1807       1.5    cegger 
   1808       1.5    cegger static void
   1809  1.15.8.2    martin acpi_print_gtd_timer(const char *name, uint32_t interrupt, uint32_t flags)
   1810  1.15.8.2    martin {
   1811  1.15.8.2    martin 
   1812  1.15.8.2    martin 	printf("\t%s Timer GSIV=%d\n", name, interrupt);
   1813  1.15.8.2    martin 	printf("\t%s Flags={Mode=", name);
   1814  1.15.8.2    martin 	if (flags & ACPI_GTDT_INTERRUPT_MODE)
   1815  1.15.8.2    martin 		printf("edge");
   1816  1.15.8.2    martin 	else
   1817  1.15.8.2    martin 		printf("level");
   1818  1.15.8.2    martin 	printf(", Polarity=");
   1819  1.15.8.2    martin 	if (flags & ACPI_GTDT_INTERRUPT_POLARITY)
   1820  1.15.8.2    martin 		printf("active-lo");
   1821  1.15.8.2    martin 	else
   1822  1.15.8.2    martin 		printf("active-hi");
   1823  1.15.8.2    martin 	if (flags & ACPI_GTDT_ALWAYS_ON)
   1824  1.15.8.2    martin 		printf(", always-on");
   1825  1.15.8.2    martin 	printf("}\n");
   1826  1.15.8.2    martin }
   1827  1.15.8.2    martin 
   1828  1.15.8.2    martin static void
   1829  1.15.8.2    martin acpi_print_gtd_block_timer_flags(const char *name, uint32_t interrupt,
   1830  1.15.8.2    martin     uint32_t flags)
   1831  1.15.8.2    martin {
   1832  1.15.8.2    martin 
   1833  1.15.8.2    martin 	printf("\t\t%s Timer GSIV=%d\n", name, interrupt);
   1834  1.15.8.2    martin 	printf("\t\t%s Timer Flags={Mode=", name);
   1835  1.15.8.2    martin 	if (flags & ACPI_GTDT_GT_IRQ_MODE)
   1836  1.15.8.2    martin 		printf("Secure");
   1837  1.15.8.2    martin 	else
   1838  1.15.8.2    martin 		printf("Non-Secure");
   1839  1.15.8.2    martin 	printf(", Polarity=");
   1840  1.15.8.2    martin 	if (flags & ACPI_GTDT_GT_IRQ_POLARITY)
   1841  1.15.8.2    martin 		printf("active-lo");
   1842  1.15.8.2    martin 	else
   1843  1.15.8.2    martin 		printf("active-hi");
   1844  1.15.8.2    martin 	printf("}\n");
   1845  1.15.8.2    martin }
   1846  1.15.8.2    martin 
   1847  1.15.8.2    martin static void
   1848  1.15.8.2    martin acpi_print_gtblock(ACPI_GTDT_TIMER_BLOCK *gtblock)
   1849  1.15.8.2    martin {
   1850  1.15.8.2    martin 	ACPI_GTDT_TIMER_ENTRY *entry;
   1851  1.15.8.2    martin 	unsigned int i;
   1852  1.15.8.2    martin 
   1853  1.15.8.2    martin 	printf("\tType=GT Block\n");
   1854  1.15.8.2    martin 	printf("\tLength=%d\n", gtblock->Header.Length);
   1855  1.15.8.2    martin 	/* XXX might not 8byte aligned */
   1856  1.15.8.2    martin 	printf("\tBlockAddress=%016jx\n",
   1857  1.15.8.2    martin 	    (uintmax_t)gtblock->BlockAddress);
   1858  1.15.8.2    martin 
   1859  1.15.8.2    martin 	printf("\tGT Block Timer Count=%d\n", gtblock->TimerCount);
   1860  1.15.8.2    martin 	entry = (ACPI_GTDT_TIMER_ENTRY *)((vaddr_t)gtblock
   1861  1.15.8.2    martin 	    + gtblock->TimerOffset);
   1862  1.15.8.2    martin 	for (i = 0; i < gtblock->TimerCount; i++) {
   1863  1.15.8.2    martin 		printf("\n");
   1864  1.15.8.2    martin 		if (entry >= (ACPI_GTDT_TIMER_ENTRY *)((vaddr_t)gtblock
   1865  1.15.8.2    martin 		    + gtblock->Header.Length)) {
   1866  1.15.8.2    martin 			printf("\\ttWrong Timer entry\n");
   1867  1.15.8.2    martin 			break;
   1868  1.15.8.2    martin 		}
   1869  1.15.8.2    martin 		printf("\t\tFrame Number=%d\n", entry->FrameNumber);
   1870  1.15.8.2    martin 		/* XXX might not 8byte aligned */
   1871  1.15.8.2    martin 		printf("\t\tBaseAddress=%016jx\n",
   1872  1.15.8.2    martin 		    (uintmax_t)entry->BaseAddress);
   1873  1.15.8.2    martin 		/* XXX might not 8byte aligned */
   1874  1.15.8.2    martin 		printf("\t\tEl0BaseAddress=%016jx\n",
   1875  1.15.8.2    martin 		    (uintmax_t)entry->El0BaseAddress);
   1876  1.15.8.2    martin 
   1877  1.15.8.2    martin 		acpi_print_gtd_block_timer_flags("Physical",
   1878  1.15.8.2    martin 		    entry->TimerInterrupt, entry->TimerFlags);
   1879  1.15.8.2    martin 		acpi_print_gtd_block_timer_flags("Virtual",
   1880  1.15.8.2    martin 		    entry->VirtualTimerInterrupt, entry->VirtualTimerFlags);
   1881  1.15.8.2    martin 
   1882  1.15.8.2    martin 		printf("\t\tCommon Flags={Mode=");
   1883  1.15.8.2    martin 		if (entry->CommonFlags & ACPI_GTDT_GT_IS_SECURE_TIMER)
   1884  1.15.8.2    martin 			printf("Secure");
   1885  1.15.8.2    martin 		else
   1886  1.15.8.2    martin 			printf("Non-Secure");
   1887  1.15.8.2    martin 		if (entry->CommonFlags & ACPI_GTDT_GT_ALWAYS_ON)
   1888  1.15.8.2    martin 			printf(", always-on");
   1889  1.15.8.2    martin 		printf("}\n");
   1890  1.15.8.2    martin 
   1891  1.15.8.2    martin 		entry++;
   1892  1.15.8.2    martin 	}
   1893  1.15.8.2    martin }
   1894  1.15.8.2    martin 
   1895  1.15.8.2    martin static void
   1896  1.15.8.2    martin acpi_print_sbsa_watchdog(ACPI_GTDT_WATCHDOG *wdog)
   1897  1.15.8.2    martin {
   1898  1.15.8.2    martin 
   1899  1.15.8.2    martin 	printf("\tType=Watchdog GT\n");
   1900  1.15.8.2    martin 	printf("\tLength=%d\n", wdog->Header.Length);
   1901  1.15.8.2    martin 	/* XXX might not 8byte aligned */
   1902  1.15.8.2    martin 	printf("\tRefreshFrameAddress=%016jx\n",
   1903  1.15.8.2    martin 	    (uintmax_t)wdog->RefreshFrameAddress);
   1904  1.15.8.2    martin 	/* XXX might not 8byte aligned */
   1905  1.15.8.2    martin 	printf("\tControlFrameAddress=%016jx\n",
   1906  1.15.8.2    martin 	    (uintmax_t)wdog->ControlFrameAddress);
   1907  1.15.8.2    martin 	printf("\tGSIV=%d\n", wdog->TimerInterrupt);
   1908  1.15.8.2    martin 
   1909  1.15.8.2    martin 	printf("\tFlags={Mode=");
   1910  1.15.8.2    martin 	if (wdog->TimerFlags & ACPI_GTDT_WATCHDOG_IRQ_MODE)
   1911  1.15.8.2    martin 		printf("edge");
   1912  1.15.8.2    martin 	else
   1913  1.15.8.2    martin 		printf("level");
   1914  1.15.8.2    martin 	printf(", Polarity=");
   1915  1.15.8.2    martin 	if (wdog->TimerFlags & ACPI_GTDT_WATCHDOG_IRQ_POLARITY)
   1916  1.15.8.2    martin 		printf("active-lo");
   1917  1.15.8.2    martin 	else
   1918  1.15.8.2    martin 		printf("active-hi");
   1919  1.15.8.2    martin 	if (wdog->TimerFlags & ACPI_GTDT_WATCHDOG_SECURE)
   1920  1.15.8.2    martin 		printf(", Secure");
   1921  1.15.8.2    martin 	else
   1922  1.15.8.2    martin 		printf(", Non-Secure");
   1923  1.15.8.2    martin 	printf("}\n");
   1924  1.15.8.2    martin }
   1925  1.15.8.2    martin 
   1926  1.15.8.2    martin static void
   1927  1.15.8.2    martin acpi_handle_gtdt(ACPI_TABLE_HEADER *sdp)
   1928  1.15.8.2    martin {
   1929  1.15.8.2    martin 	ACPI_TABLE_GTDT *gtdt;
   1930  1.15.8.2    martin 	ACPI_GTDT_HEADER *hdr;
   1931  1.15.8.2    martin 	u_int i;
   1932  1.15.8.2    martin 
   1933  1.15.8.2    martin 	printf(BEGIN_COMMENT);
   1934  1.15.8.2    martin 	acpi_print_sdt(sdp);
   1935  1.15.8.2    martin 	gtdt = (ACPI_TABLE_GTDT *)sdp;
   1936  1.15.8.2    martin 
   1937  1.15.8.2    martin 	printf("\tCounterBlockAddresss=%016jx\n",
   1938  1.15.8.2    martin 	    (uintmax_t)gtdt->CounterBlockAddresss); /* XXX not 8byte aligned */
   1939  1.15.8.2    martin 	printf("\tCounterReadBlockAddress=%016jx\n",
   1940  1.15.8.2    martin 	    (uintmax_t)gtdt->CounterReadBlockAddress);
   1941  1.15.8.2    martin 
   1942  1.15.8.2    martin #define PRINTTIMER(gtdt, name) acpi_print_gtd_timer(	\
   1943  1.15.8.2    martin 		#name, (gtdt)-> name## Interrupt,	\
   1944  1.15.8.2    martin 	(gtdt)-> name ## Flags)
   1945  1.15.8.2    martin 
   1946  1.15.8.2    martin 	PRINTTIMER(gtdt, SecureEl1);
   1947  1.15.8.2    martin 	PRINTTIMER(gtdt, NonSecureEl1);
   1948  1.15.8.2    martin 	PRINTTIMER(gtdt, VirtualTimer);
   1949  1.15.8.2    martin 	PRINTTIMER(gtdt, NonSecureEl2);
   1950  1.15.8.2    martin 
   1951  1.15.8.2    martin #undef PRINTTIMER
   1952  1.15.8.2    martin 
   1953  1.15.8.2    martin 	printf("\tPlatform Timer Count=%d\n", gtdt->PlatformTimerCount);
   1954  1.15.8.2    martin 
   1955  1.15.8.2    martin 	hdr = (ACPI_GTDT_HEADER *)((vaddr_t)sdp + gtdt->PlatformTimerOffset);
   1956  1.15.8.2    martin 	for (i = 0; i < gtdt->PlatformTimerCount; i++) {
   1957  1.15.8.2    martin 		printf("\n");
   1958  1.15.8.2    martin 		if (hdr >= (ACPI_GTDT_HEADER *)((vaddr_t)sdp + sdp->Length)) {
   1959  1.15.8.2    martin 			printf("\tWrong GTDT header"
   1960  1.15.8.2    martin 			    "(type = %hhu, length = %hu)\n",
   1961  1.15.8.2    martin 			    hdr->Type, hdr->Length);
   1962  1.15.8.2    martin 			break;
   1963  1.15.8.2    martin 		}
   1964  1.15.8.2    martin 
   1965  1.15.8.2    martin 		switch (hdr->Type) {
   1966  1.15.8.2    martin 		case ACPI_GTDT_TYPE_TIMER_BLOCK:
   1967  1.15.8.2    martin 			acpi_print_gtblock((ACPI_GTDT_TIMER_BLOCK *)hdr);
   1968  1.15.8.2    martin 			break;
   1969  1.15.8.2    martin 		case ACPI_GTDT_TYPE_WATCHDOG:
   1970  1.15.8.2    martin 			acpi_print_sbsa_watchdog((ACPI_GTDT_WATCHDOG *)hdr);
   1971  1.15.8.2    martin 			break;
   1972  1.15.8.2    martin 		default:
   1973  1.15.8.2    martin 			printf("\tUnknown Platform Timer Type"
   1974  1.15.8.2    martin 			    "(type = %hhu, length = %hu)\n",
   1975  1.15.8.2    martin 			    hdr->Type, hdr->Length);
   1976  1.15.8.2    martin 			break;
   1977  1.15.8.2    martin 		}
   1978  1.15.8.2    martin 		/* Next */
   1979  1.15.8.2    martin 		hdr = (ACPI_GTDT_HEADER *)((vaddr_t)hdr + hdr->Length);
   1980  1.15.8.2    martin 	}
   1981  1.15.8.2    martin 	printf(END_COMMENT);
   1982  1.15.8.2    martin }
   1983  1.15.8.2    martin 
   1984  1.15.8.2    martin static void
   1985       1.5    cegger acpi_handle_madt(ACPI_TABLE_HEADER *sdp)
   1986       1.5    cegger {
   1987       1.5    cegger 	ACPI_TABLE_MADT *madt;
   1988       1.5    cegger 
   1989       1.5    cegger 	printf(BEGIN_COMMENT);
   1990       1.5    cegger 	acpi_print_sdt(sdp);
   1991       1.5    cegger 	madt = (ACPI_TABLE_MADT *)sdp;
   1992       1.5    cegger 	printf("\tLocal APIC ADDR=0x%08x\n", madt->Address);
   1993       1.5    cegger 	printf("\tFlags={");
   1994       1.5    cegger 	if (madt->Flags & ACPI_MADT_PCAT_COMPAT)
   1995       1.5    cegger 		printf("PC-AT");
   1996       1.5    cegger 	printf("}\n");
   1997       1.5    cegger 	acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt);
   1998       1.5    cegger 	printf(END_COMMENT);
   1999       1.5    cegger }
   2000       1.5    cegger 
   2001       1.5    cegger static void
   2002       1.5    cegger acpi_handle_hpet(ACPI_TABLE_HEADER *sdp)
   2003       1.5    cegger {
   2004       1.5    cegger 	ACPI_TABLE_HPET *hpet;
   2005       1.5    cegger 
   2006       1.5    cegger 	printf(BEGIN_COMMENT);
   2007       1.5    cegger 	acpi_print_sdt(sdp);
   2008       1.5    cegger 	hpet = (ACPI_TABLE_HPET *)sdp;
   2009       1.5    cegger 	printf("\tHPET Number=%d\n", hpet->Sequence);
   2010       1.5    cegger 	printf("\tADDR=");
   2011       1.5    cegger 	acpi_print_gas(&hpet->Address);
   2012       1.5    cegger 	printf("\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID);
   2013       1.5    cegger 	printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >>
   2014       1.5    cegger 	    8);
   2015       1.5    cegger 	printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ?
   2016       1.5    cegger 	    1 : 0);
   2017       1.5    cegger 	printf("\tLegacy IRQ routing capable={");
   2018       1.5    cegger 	if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE)
   2019       1.5    cegger 		printf("TRUE}\n");
   2020       1.5    cegger 	else
   2021       1.5    cegger 		printf("FALSE}\n");
   2022       1.5    cegger 	printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16);
   2023       1.5    cegger 	printf("\tMinimal Tick=%d\n", hpet->MinimumTick);
   2024  1.15.8.1    martin 	printf("\tFlags=0x%02x\n", hpet->Flags);
   2025       1.5    cegger 	printf(END_COMMENT);
   2026       1.5    cegger }
   2027       1.5    cegger 
   2028       1.5    cegger static void
   2029  1.15.8.2    martin acpi_print_native_lpit(ACPI_LPIT_NATIVE *nl)
   2030  1.15.8.2    martin {
   2031  1.15.8.2    martin 	printf("\tEntryTrigger=");
   2032  1.15.8.2    martin 	acpi_print_gas(&nl->EntryTrigger);
   2033  1.15.8.2    martin 	printf("\tResidency=%u\n", nl->Residency);
   2034  1.15.8.2    martin 	printf("\tLatency=%u\n", nl->Latency);
   2035  1.15.8.2    martin 	if (nl->Header.Flags & ACPI_LPIT_NO_COUNTER)
   2036  1.15.8.2    martin 		printf("\tResidencyCounter=Not Present");
   2037  1.15.8.2    martin 	else {
   2038  1.15.8.2    martin 		printf("\tResidencyCounter=");
   2039  1.15.8.2    martin 		acpi_print_gas(&nl->ResidencyCounter);
   2040  1.15.8.2    martin 	}
   2041  1.15.8.2    martin 	if (nl->CounterFrequency)
   2042  1.15.8.2    martin 		printf("\tCounterFrequency=%ju\n", nl->CounterFrequency);
   2043  1.15.8.2    martin 	else
   2044  1.15.8.2    martin 		printf("\tCounterFrequency=TSC\n");
   2045  1.15.8.2    martin }
   2046  1.15.8.2    martin 
   2047  1.15.8.2    martin static void
   2048  1.15.8.2    martin acpi_print_lpit(ACPI_LPIT_HEADER *lpit)
   2049  1.15.8.2    martin {
   2050  1.15.8.2    martin 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
   2051  1.15.8.2    martin 		printf("\tType=ACPI_LPIT_TYPE_NATIVE_CSTATE\n");
   2052  1.15.8.2    martin 	else
   2053  1.15.8.2    martin 		warnx("unknown LPIT type %u", lpit->Type);
   2054  1.15.8.2    martin 
   2055  1.15.8.2    martin 	printf("\tLength=%u\n", lpit->Length);
   2056  1.15.8.2    martin 	printf("\tUniqueId=0x%04x\n", lpit->UniqueId);
   2057  1.15.8.2    martin #define	PRINTFLAG(var, flag)	printflag((var), ACPI_LPIT_## flag, #flag)
   2058  1.15.8.2    martin 	printf("\tFlags=");
   2059  1.15.8.2    martin 	PRINTFLAG(lpit->Flags, STATE_DISABLED);
   2060  1.15.8.2    martin 	PRINTFLAG_END();
   2061  1.15.8.2    martin #undef PRINTFLAG
   2062  1.15.8.2    martin 
   2063  1.15.8.2    martin 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
   2064  1.15.8.2    martin 		return acpi_print_native_lpit((ACPI_LPIT_NATIVE *)lpit);
   2065  1.15.8.2    martin }
   2066  1.15.8.2    martin 
   2067  1.15.8.2    martin static void
   2068  1.15.8.2    martin acpi_walk_lpit(ACPI_TABLE_HEADER *table, void *first,
   2069  1.15.8.2    martin     void (*action)(ACPI_LPIT_HEADER *))
   2070  1.15.8.2    martin {
   2071  1.15.8.2    martin 	ACPI_LPIT_HEADER *subtable;
   2072  1.15.8.2    martin 	char *end;
   2073  1.15.8.2    martin 
   2074  1.15.8.2    martin 	subtable = first;
   2075  1.15.8.2    martin 	end = (char *)table + table->Length;
   2076  1.15.8.2    martin 	while ((char *)subtable < end) {
   2077  1.15.8.2    martin 		printf("\n");
   2078  1.15.8.2    martin 		if (subtable->Length < sizeof(ACPI_LPIT_HEADER)) {
   2079  1.15.8.2    martin 			warnx("invalid subtable length %u", subtable->Length);
   2080  1.15.8.2    martin 			return;
   2081  1.15.8.2    martin 		}
   2082  1.15.8.2    martin 		action(subtable);
   2083  1.15.8.2    martin 		subtable = (ACPI_LPIT_HEADER *)((char *)subtable +
   2084  1.15.8.2    martin 		    subtable->Length);
   2085  1.15.8.2    martin 	}
   2086  1.15.8.2    martin }
   2087  1.15.8.2    martin 
   2088  1.15.8.2    martin static void
   2089  1.15.8.2    martin acpi_handle_lpit(ACPI_TABLE_HEADER *sdp)
   2090  1.15.8.2    martin {
   2091  1.15.8.2    martin 	ACPI_TABLE_LPIT *lpit;
   2092  1.15.8.2    martin 
   2093  1.15.8.2    martin 	printf(BEGIN_COMMENT);
   2094  1.15.8.2    martin 	acpi_print_sdt(sdp);
   2095  1.15.8.2    martin 	lpit = (ACPI_TABLE_LPIT *)sdp;
   2096  1.15.8.2    martin 	acpi_walk_lpit(sdp, (lpit + 1), acpi_print_lpit);
   2097  1.15.8.2    martin 
   2098  1.15.8.2    martin 	printf(END_COMMENT);
   2099  1.15.8.2    martin }
   2100  1.15.8.2    martin 
   2101  1.15.8.2    martin static void
   2102       1.5    cegger acpi_handle_msct(ACPI_TABLE_HEADER *sdp)
   2103       1.5    cegger {
   2104       1.5    cegger 	ACPI_TABLE_MSCT *msct;
   2105       1.5    cegger 	ACPI_MSCT_PROXIMITY *msctentry;
   2106       1.5    cegger 	uint32_t pos;
   2107       1.5    cegger 
   2108       1.5    cegger 	printf(BEGIN_COMMENT);
   2109       1.5    cegger 	acpi_print_sdt(sdp);
   2110       1.5    cegger 	msct = (ACPI_TABLE_MSCT *)sdp;
   2111       1.5    cegger 
   2112       1.5    cegger 	printf("\tProximity Offset=0x%x\n", msct->ProximityOffset);
   2113       1.5    cegger 	printf("\tMax Proximity Domains=%d\n", msct->MaxProximityDomains);
   2114       1.5    cegger 	printf("\tMax Clock Domains=%d\n", msct->MaxClockDomains);
   2115       1.5    cegger 	printf("\tMax Physical Address=0x%"PRIx64"\n", msct->MaxAddress);
   2116       1.5    cegger 
   2117       1.5    cegger 	pos = msct->ProximityOffset;
   2118       1.5    cegger 	while (pos < msct->Header.Length) {
   2119       1.5    cegger 		msctentry = (ACPI_MSCT_PROXIMITY *)((char *)msct + pos);
   2120       1.5    cegger 		pos += msctentry->Length;
   2121       1.5    cegger 
   2122       1.5    cegger 		printf("\n");
   2123       1.5    cegger 		printf("\tRevision=%d\n", msctentry->Revision);
   2124       1.5    cegger 		printf("\tLength=%d\n", msctentry->Length);
   2125       1.5    cegger 		printf("\tRange Start=%d\n", msctentry->RangeStart);
   2126       1.5    cegger 		printf("\tRange End=%d\n", msctentry->RangeEnd);
   2127       1.5    cegger 		printf("\tProcessor Capacity=%d\n",
   2128       1.5    cegger 		    msctentry->ProcessorCapacity);
   2129       1.5    cegger 		printf("\tMemory Capacity=0x%"PRIx64" byte\n",
   2130       1.5    cegger 		    msctentry->MemoryCapacity);
   2131       1.5    cegger 	}
   2132       1.1  christos 
   2133       1.5    cegger 	printf(END_COMMENT);
   2134       1.5    cegger }
   2135       1.1  christos 
   2136       1.5    cegger static void
   2137       1.5    cegger acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp)
   2138       1.5    cegger {
   2139       1.5    cegger 	ACPI_TABLE_ECDT *ecdt;
   2140       1.1  christos 
   2141       1.5    cegger 	printf(BEGIN_COMMENT);
   2142       1.5    cegger 	acpi_print_sdt(sdp);
   2143       1.5    cegger 	ecdt = (ACPI_TABLE_ECDT *)sdp;
   2144       1.5    cegger 	printf("\tEC_CONTROL=");
   2145       1.5    cegger 	acpi_print_gas(&ecdt->Control);
   2146       1.5    cegger 	printf("\n\tEC_DATA=");
   2147       1.5    cegger 	acpi_print_gas(&ecdt->Data);
   2148       1.5    cegger 	printf("\n\tUID=%#x, ", ecdt->Uid);
   2149       1.5    cegger 	printf("GPE_BIT=%#x\n", ecdt->Gpe);
   2150       1.5    cegger 	printf("\tEC_ID=%s\n", ecdt->Id);
   2151       1.5    cegger 	printf(END_COMMENT);
   2152       1.5    cegger }
   2153       1.1  christos 
   2154       1.5    cegger static void
   2155       1.5    cegger acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp)
   2156       1.5    cegger {
   2157       1.5    cegger 	ACPI_TABLE_MCFG *mcfg;
   2158       1.5    cegger 	ACPI_MCFG_ALLOCATION *alloc;
   2159       1.5    cegger 	u_int i, entries;
   2160       1.1  christos 
   2161       1.5    cegger 	printf(BEGIN_COMMENT);
   2162       1.5    cegger 	acpi_print_sdt(sdp);
   2163       1.5    cegger 	mcfg = (ACPI_TABLE_MCFG *)sdp;
   2164       1.5    cegger 	entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) /
   2165       1.5    cegger 	    sizeof(ACPI_MCFG_ALLOCATION);
   2166       1.5    cegger 	alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1);
   2167       1.5    cegger 	for (i = 0; i < entries; i++, alloc++) {
   2168       1.5    cegger 		printf("\n");
   2169  1.15.8.1    martin 		printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address);
   2170       1.5    cegger 		printf("\tSegment Group=0x%04x\n", alloc->PciSegment);
   2171       1.5    cegger 		printf("\tStart Bus=%d\n", alloc->StartBusNumber);
   2172       1.5    cegger 		printf("\tEnd Bus=%d\n", alloc->EndBusNumber);
   2173       1.5    cegger 	}
   2174       1.5    cegger 	printf(END_COMMENT);
   2175       1.5    cegger }
   2176       1.1  christos 
   2177       1.1  christos static void
   2178       1.5    cegger acpi_handle_sbst(ACPI_TABLE_HEADER *sdp)
   2179       1.1  christos {
   2180       1.5    cegger 	ACPI_TABLE_SBST *sbst;
   2181       1.5    cegger 
   2182       1.5    cegger 	printf(BEGIN_COMMENT);
   2183       1.5    cegger 	acpi_print_sdt(sdp);
   2184       1.5    cegger 	sbst = (ACPI_TABLE_SBST *)sdp;
   2185       1.5    cegger 
   2186       1.5    cegger 	printf("\tWarning Level=%d mWh\n", sbst->WarningLevel);
   2187       1.5    cegger 	printf("\tLow Level=%d mWh\n", sbst->LowLevel);
   2188       1.5    cegger 	printf("\tCritical Level=%d mWh\n", sbst->CriticalLevel);
   2189       1.1  christos 
   2190       1.5    cegger 	printf(END_COMMENT);
   2191       1.1  christos }
   2192       1.1  christos 
   2193       1.1  christos static void
   2194       1.5    cegger acpi_handle_slit(ACPI_TABLE_HEADER *sdp)
   2195       1.1  christos {
   2196       1.5    cegger 	ACPI_TABLE_SLIT *slit;
   2197       1.5    cegger 	u_int idx;
   2198       1.5    cegger 	uint64_t cnt;
   2199       1.5    cegger 
   2200       1.5    cegger 	printf(BEGIN_COMMENT);
   2201       1.5    cegger 	acpi_print_sdt(sdp);
   2202       1.5    cegger 	slit = (ACPI_TABLE_SLIT *)sdp;
   2203       1.1  christos 
   2204       1.5    cegger 	cnt = slit->LocalityCount * slit->LocalityCount;
   2205  1.15.8.1    martin 	printf("\tLocalityCount=%ju\n", (uintmax_t)slit->LocalityCount);
   2206       1.5    cegger 	printf("\tEntry=\n\t");
   2207       1.5    cegger 	for (idx = 0; idx < cnt; idx++) {
   2208       1.5    cegger 		printf("%u ", slit->Entry[idx]);
   2209       1.5    cegger 		if ((idx % slit->LocalityCount) == (slit->LocalityCount - 1)) {
   2210       1.5    cegger 			printf("\n");
   2211       1.5    cegger 			if (idx < cnt - 1)
   2212       1.5    cegger 				printf("\t");
   2213       1.5    cegger 		}
   2214       1.5    cegger 	}
   2215       1.1  christos 
   2216       1.5    cegger 	printf(END_COMMENT);
   2217       1.1  christos }
   2218       1.1  christos 
   2219       1.1  christos static void
   2220       1.5    cegger acpi_handle_spcr(ACPI_TABLE_HEADER *sdp)
   2221       1.1  christos {
   2222       1.5    cegger 	ACPI_TABLE_SPCR *spcr;
   2223       1.5    cegger 
   2224       1.5    cegger 	printf(BEGIN_COMMENT);
   2225       1.5    cegger 	acpi_print_sdt(sdp);
   2226       1.5    cegger 	spcr = (ACPI_TABLE_SPCR *)sdp;
   2227       1.5    cegger 
   2228  1.15.8.2    martin 	printf("\n\tInterface Type=");
   2229  1.15.8.2    martin 	switch (sdp->Revision) {
   2230  1.15.8.2    martin 	case 1:
   2231  1.15.8.2    martin 		printf("full 16550%s\n",
   2232  1.15.8.2    martin 		    (spcr->InterfaceType == 1) ?
   2233  1.15.8.2    martin 		    "(must also accept writing FCR register)" : "");
   2234  1.15.8.2    martin 		break;
   2235  1.15.8.2    martin 	case 2:
   2236  1.15.8.2    martin 		acpi_print_dbg2_serial_subtype(spcr->InterfaceType);
   2237  1.15.8.2    martin 		break;
   2238  1.15.8.2    martin 	default:
   2239  1.15.8.2    martin 		printf("unknown Revision\n");
   2240  1.15.8.2    martin 		break;
   2241  1.15.8.2    martin 	}
   2242  1.15.8.2    martin 
   2243       1.5    cegger 	printf("\tSerial Port=");
   2244       1.5    cegger 	acpi_print_gas(&spcr->SerialPort);
   2245       1.5    cegger 	printf("\n\tInterrupt Type={");
   2246       1.5    cegger 	if (spcr->InterruptType & 0x1) {
   2247       1.5    cegger 		printf("\n\t\tdual-8259 IRQ=");
   2248       1.5    cegger 		switch (spcr->PcInterrupt) {
   2249       1.5    cegger 		case 2 ... 7:
   2250       1.5    cegger 		case 9 ... 12:
   2251       1.5    cegger 		case 14 ... 15:
   2252       1.5    cegger 			printf("%d", spcr->PcInterrupt);
   2253       1.5    cegger 			break;
   2254       1.5    cegger 		default:
   2255       1.5    cegger 			printf("%d (invalid entry)", spcr->PcInterrupt);
   2256       1.5    cegger 			break;
   2257       1.5    cegger 		}
   2258       1.5    cegger 	}
   2259       1.5    cegger 	if (spcr->InterruptType & 0x2) {
   2260       1.5    cegger 		printf("\n\t\tIO APIC={ GSI=%d }", spcr->Interrupt);
   2261       1.5    cegger 	}
   2262       1.5    cegger 	if (spcr->InterruptType & 0x4) {
   2263       1.5    cegger 		printf("\n\t\tIO SAPIC={ GSI=%d }", spcr->Interrupt);
   2264       1.5    cegger 	}
   2265  1.15.8.2    martin 	if (spcr->InterruptType & 0x8) {
   2266  1.15.8.2    martin 		printf("\n\t\tARMH GIC={ GSI=%d }", spcr->Interrupt);
   2267  1.15.8.2    martin 	}
   2268       1.5    cegger 	printf("\n\t}\n");
   2269       1.5    cegger 
   2270       1.5    cegger 	printf("\tBaud Rate=");
   2271       1.5    cegger 	switch (spcr->BaudRate) {
   2272       1.5    cegger 	case 3:
   2273       1.5    cegger 		printf("9600");
   2274       1.5    cegger 		break;
   2275       1.5    cegger 	case 4:
   2276       1.5    cegger 		printf("19200");
   2277       1.5    cegger 		break;
   2278       1.5    cegger 	case 6:
   2279       1.5    cegger 		printf("57600");
   2280       1.5    cegger 		break;
   2281       1.5    cegger 	case 7:
   2282       1.5    cegger 		printf("115200");
   2283       1.5    cegger 		break;
   2284       1.5    cegger 	default:
   2285       1.5    cegger 		printf("unknown speed index %d", spcr->BaudRate);
   2286       1.5    cegger 		break;
   2287       1.5    cegger 	}
   2288       1.5    cegger 	printf("\n\tParity={");
   2289       1.5    cegger 	switch (spcr->Parity) {
   2290       1.5    cegger 	case 0:
   2291       1.5    cegger 		printf("OFF");
   2292       1.5    cegger 		break;
   2293       1.5    cegger 	default:
   2294       1.5    cegger 		printf("ON");
   2295       1.5    cegger 		break;
   2296       1.5    cegger 	}
   2297       1.5    cegger 	printf("}\n");
   2298       1.5    cegger 
   2299       1.5    cegger 	printf("\tStop Bits={");
   2300       1.5    cegger 	switch (spcr->StopBits) {
   2301       1.5    cegger 	case 1:
   2302       1.5    cegger 		printf("ON");
   2303       1.5    cegger 		break;
   2304       1.5    cegger 	default:
   2305       1.5    cegger 		printf("OFF");
   2306       1.5    cegger 		break;
   2307       1.5    cegger 	}
   2308       1.5    cegger 	printf("}\n");
   2309       1.1  christos 
   2310       1.5    cegger 	printf("\tFlow Control={");
   2311       1.5    cegger 	if (spcr->FlowControl & 0x1)
   2312       1.5    cegger 		printf("DCD, ");
   2313       1.5    cegger 	if (spcr->FlowControl & 0x2)
   2314       1.5    cegger 		printf("RTS/CTS hardware, ");
   2315       1.5    cegger 	if (spcr->FlowControl & 0x4)
   2316       1.5    cegger 		printf("XON/XOFF software");
   2317       1.5    cegger 	printf("}\n");
   2318       1.1  christos 
   2319       1.5    cegger 	printf("\tTerminal=");
   2320       1.5    cegger 	switch (spcr->TerminalType) {
   2321       1.5    cegger 	case 0:
   2322       1.5    cegger 		printf("VT100");
   2323       1.5    cegger 		break;
   2324       1.5    cegger 	case 1:
   2325       1.5    cegger 		printf("VT100+");
   2326       1.5    cegger 		break;
   2327       1.5    cegger 	case 2:
   2328       1.5    cegger 		printf("VT-UTF8");
   2329       1.5    cegger 		break;
   2330       1.5    cegger 	case 3:
   2331       1.5    cegger 		printf("ANSI");
   2332       1.5    cegger 		break;
   2333       1.5    cegger 	default:
   2334       1.5    cegger 		printf("unknown type %d", spcr->TerminalType);
   2335       1.5    cegger 		break;
   2336       1.1  christos 	}
   2337       1.5    cegger 	printf("\n");
   2338       1.5    cegger 
   2339       1.5    cegger 	acpi_print_pci(spcr->PciVendorId, spcr->PciDeviceId,
   2340       1.5    cegger 	    spcr->PciSegment, spcr->PciBus, spcr->PciDevice, spcr->PciFunction);
   2341       1.5    cegger 
   2342       1.5    cegger 	printf("\tPCI Flags={");
   2343       1.5    cegger 	if (spcr->PciFlags & ACPI_SPCR_DO_NOT_DISABLE)
   2344       1.5    cegger 		printf("DONOT_DISABLE");
   2345       1.5    cegger 	printf("}\n");
   2346       1.5    cegger 
   2347       1.5    cegger 	printf(END_COMMENT);
   2348       1.5    cegger }
   2349       1.5    cegger 
   2350       1.5    cegger static void
   2351  1.15.8.1    martin acpi_handle_spmi(ACPI_TABLE_HEADER *sdp)
   2352  1.15.8.1    martin {
   2353  1.15.8.1    martin 	ACPI_TABLE_SPMI *spmi;
   2354  1.15.8.1    martin 
   2355  1.15.8.1    martin 	printf(BEGIN_COMMENT);
   2356  1.15.8.1    martin 	acpi_print_sdt(sdp);
   2357  1.15.8.1    martin 	spmi = (ACPI_TABLE_SPMI *)sdp;
   2358  1.15.8.1    martin 
   2359  1.15.8.1    martin 	printf("\tInterface Type=");
   2360  1.15.8.1    martin 	switch (spmi->InterfaceType) {
   2361  1.15.8.1    martin 	case ACPI_SPMI_KEYBOARD:
   2362  1.15.8.1    martin 		printf("Keyboard Controller Stype (KCS)");
   2363  1.15.8.1    martin 		break;
   2364  1.15.8.1    martin 	case ACPI_SPMI_SMI:
   2365  1.15.8.1    martin 		printf("Server Management Interface Chip (SMIC)");
   2366  1.15.8.1    martin 		break;
   2367  1.15.8.1    martin 	case ACPI_SPMI_BLOCK_TRANSFER:
   2368  1.15.8.1    martin 		printf("Block Transfer (BT)");
   2369  1.15.8.1    martin 		break;
   2370  1.15.8.1    martin 	case ACPI_SPMI_SMBUS:
   2371  1.15.8.1    martin 		printf("SMBus System Interface (SSIF)");
   2372  1.15.8.1    martin 		break;
   2373  1.15.8.1    martin 	default:
   2374  1.15.8.1    martin 		printf("Reserved(%d)", spmi->InterfaceType);
   2375  1.15.8.1    martin 		break;
   2376  1.15.8.1    martin 	}
   2377  1.15.8.2    martin 	printf("\n\tSpecRevision=%d.%d", spmi->SpecRevision >> 8,
   2378  1.15.8.1    martin 		spmi->SpecRevision & 0xff);
   2379  1.15.8.1    martin 
   2380  1.15.8.1    martin 	printf("\n\tInterrupt Type={");
   2381  1.15.8.1    martin 	if (spmi->InterruptType & 0x1) {
   2382  1.15.8.1    martin 		printf("\n\t\tSCI triggered GPE=%d", spmi->GpeNumber);
   2383  1.15.8.1    martin 	}
   2384  1.15.8.1    martin 	if (spmi->InterruptType & 0x2) {
   2385  1.15.8.1    martin 		printf("\n\t\tIO APIC/SAPIC={ GSI=%d }", spmi->Interrupt);
   2386  1.15.8.1    martin 	}
   2387  1.15.8.1    martin 	printf("\n\t}\n");
   2388  1.15.8.1    martin 
   2389  1.15.8.1    martin 	printf("\tBase Address=");
   2390  1.15.8.1    martin 	acpi_print_gas(&spmi->IpmiRegister);
   2391  1.15.8.1    martin 	printf("\n");
   2392  1.15.8.1    martin 
   2393  1.15.8.1    martin 	if ((spmi->PciDeviceFlag & 0x01) != 0)
   2394  1.15.8.1    martin 		acpi_print_pci_sbdf(spmi->PciSegment, spmi->PciBus,
   2395  1.15.8.1    martin 		    spmi->PciDevice, spmi->PciFunction);
   2396  1.15.8.1    martin 
   2397  1.15.8.1    martin 	printf(END_COMMENT);
   2398  1.15.8.1    martin }
   2399  1.15.8.1    martin 
   2400  1.15.8.1    martin static void
   2401       1.5    cegger acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
   2402       1.5    cegger     uint32_t flags, uint32_t clockdomain)
   2403       1.5    cegger {
   2404       1.5    cegger 
   2405       1.5    cegger 	printf("\tFlags={");
   2406       1.5    cegger 	if (flags & ACPI_SRAT_CPU_ENABLED)
   2407       1.5    cegger 		printf("ENABLED");
   2408       1.5    cegger 	else
   2409       1.5    cegger 		printf("DISABLED");
   2410       1.5    cegger 	printf("}\n");
   2411       1.5    cegger 	printf("\tAPIC ID=%d\n", apic_id);
   2412       1.5    cegger 	printf("\tProximity Domain=%d\n", proximity_domain);
   2413       1.5    cegger 	printf("\tClock Domain=%d\n", clockdomain);
   2414       1.5    cegger }
   2415       1.5    cegger 
   2416       1.5    cegger static void
   2417       1.5    cegger acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp)
   2418       1.5    cegger {
   2419       1.5    cegger 
   2420       1.5    cegger 	printf("\tFlags={");
   2421       1.5    cegger 	if (mp->Flags & ACPI_SRAT_MEM_ENABLED)
   2422       1.5    cegger 		printf("ENABLED");
   2423       1.5    cegger 	else
   2424       1.5    cegger 		printf("DISABLED");
   2425       1.5    cegger 	if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
   2426       1.5    cegger 		printf(",HOT_PLUGGABLE");
   2427       1.5    cegger 	if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE)
   2428       1.5    cegger 		printf(",NON_VOLATILE");
   2429       1.5    cegger 	printf("}\n");
   2430       1.5    cegger 	printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress);
   2431       1.5    cegger 	printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length);
   2432       1.5    cegger 	printf("\tProximity Domain=%d\n", mp->ProximityDomain);
   2433       1.1  christos }
   2434       1.1  christos 
   2435  1.15.8.1    martin static const char *srat_types[] = {
   2436  1.15.8.1    martin     [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU",
   2437  1.15.8.1    martin     [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory",
   2438  1.15.8.1    martin     [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC",
   2439  1.15.8.1    martin     [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC",
   2440  1.15.8.1    martin };
   2441       1.5    cegger 
   2442       1.1  christos static void
   2443       1.5    cegger acpi_print_srat(ACPI_SUBTABLE_HEADER *srat)
   2444       1.1  christos {
   2445       1.5    cegger 	ACPI_SRAT_CPU_AFFINITY *cpu;
   2446       1.5    cegger 	ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
   2447  1.15.8.1    martin 	ACPI_SRAT_GICC_AFFINITY *gic;
   2448       1.5    cegger 
   2449  1.15.8.1    martin 	if (srat->Type < __arraycount(srat_types))
   2450       1.5    cegger 		printf("\tType=%s\n", srat_types[srat->Type]);
   2451       1.5    cegger 	else
   2452       1.5    cegger 		printf("\tType=%d (unknown)\n", srat->Type);
   2453       1.5    cegger 	switch (srat->Type) {
   2454       1.5    cegger 	case ACPI_SRAT_TYPE_CPU_AFFINITY:
   2455       1.5    cegger 		cpu = (ACPI_SRAT_CPU_AFFINITY *)srat;
   2456       1.5    cegger 		acpi_print_srat_cpu(cpu->ApicId,
   2457       1.5    cegger 		    cpu->ProximityDomainHi[2] << 24 |
   2458       1.5    cegger 		    cpu->ProximityDomainHi[1] << 16 |
   2459       1.5    cegger 		    cpu->ProximityDomainHi[0] << 0 |
   2460       1.5    cegger 		    cpu->ProximityDomainLo,
   2461       1.5    cegger 		    cpu->Flags, cpu->ClockDomain);
   2462       1.5    cegger 		break;
   2463       1.5    cegger 	case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
   2464       1.5    cegger 		acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat);
   2465       1.5    cegger 		break;
   2466       1.5    cegger 	case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
   2467       1.5    cegger 		x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat;
   2468       1.5    cegger 		acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain,
   2469       1.5    cegger 		    x2apic->Flags, x2apic->ClockDomain);
   2470       1.5    cegger 		break;
   2471  1.15.8.1    martin 	case ACPI_SRAT_TYPE_GICC_AFFINITY:
   2472  1.15.8.1    martin 		gic = (ACPI_SRAT_GICC_AFFINITY *)srat;
   2473  1.15.8.1    martin 		acpi_print_srat_cpu(gic->AcpiProcessorUid, gic->ProximityDomain,
   2474  1.15.8.1    martin 		    gic->Flags, gic->ClockDomain);
   2475  1.15.8.1    martin 		break;
   2476       1.5    cegger 	}
   2477       1.5    cegger }
   2478       1.1  christos 
   2479       1.5    cegger static void
   2480       1.5    cegger acpi_handle_srat(ACPI_TABLE_HEADER *sdp)
   2481       1.5    cegger {
   2482       1.5    cegger 	ACPI_TABLE_SRAT *srat;
   2483       1.1  christos 
   2484       1.5    cegger 	printf(BEGIN_COMMENT);
   2485       1.5    cegger 	acpi_print_sdt(sdp);
   2486       1.5    cegger 	srat = (ACPI_TABLE_SRAT *)sdp;
   2487       1.5    cegger 	printf("\tTable Revision=%d\n", srat->TableRevision);
   2488       1.5    cegger 	acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat);
   2489       1.5    cegger 	printf(END_COMMENT);
   2490       1.1  christos }
   2491       1.1  christos 
   2492  1.15.8.1    martin static const char *nfit_types[] = {
   2493  1.15.8.1    martin     [ACPI_NFIT_TYPE_SYSTEM_ADDRESS] = "System Address",
   2494  1.15.8.1    martin     [ACPI_NFIT_TYPE_MEMORY_MAP] = "Memory Map",
   2495  1.15.8.1    martin     [ACPI_NFIT_TYPE_INTERLEAVE] = "Interleave",
   2496  1.15.8.1    martin     [ACPI_NFIT_TYPE_SMBIOS] = "SMBIOS",
   2497  1.15.8.1    martin     [ACPI_NFIT_TYPE_CONTROL_REGION] = "Control Region",
   2498  1.15.8.1    martin     [ACPI_NFIT_TYPE_DATA_REGION] = "Data Region",
   2499  1.15.8.1    martin     [ACPI_NFIT_TYPE_FLUSH_ADDRESS] = "Flush Address"
   2500  1.15.8.1    martin };
   2501  1.15.8.1    martin 
   2502  1.15.8.1    martin 
   2503  1.15.8.1    martin static void
   2504  1.15.8.1    martin acpi_print_nfit(ACPI_NFIT_HEADER *nfit)
   2505  1.15.8.1    martin {
   2506  1.15.8.1    martin 	char *uuidstr;
   2507  1.15.8.1    martin 	uint32_t status;
   2508  1.15.8.1    martin 
   2509  1.15.8.1    martin 	ACPI_NFIT_SYSTEM_ADDRESS *sysaddr;
   2510  1.15.8.1    martin 	ACPI_NFIT_MEMORY_MAP *mmap;
   2511  1.15.8.1    martin 	ACPI_NFIT_INTERLEAVE *ileave;
   2512  1.15.8.1    martin 	ACPI_NFIT_SMBIOS *smbios __unused;
   2513  1.15.8.1    martin 	ACPI_NFIT_CONTROL_REGION *ctlreg;
   2514  1.15.8.1    martin 	ACPI_NFIT_DATA_REGION *datareg;
   2515  1.15.8.1    martin 	ACPI_NFIT_FLUSH_ADDRESS *fladdr;
   2516  1.15.8.1    martin 
   2517  1.15.8.1    martin 	if (nfit->Type < __arraycount(nfit_types))
   2518  1.15.8.1    martin 		printf("\tType=%s\n", nfit_types[nfit->Type]);
   2519  1.15.8.1    martin 	else
   2520  1.15.8.1    martin 		printf("\tType=%u (unknown)\n", nfit->Type);
   2521  1.15.8.1    martin 	switch (nfit->Type) {
   2522  1.15.8.1    martin 	case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
   2523  1.15.8.1    martin 		sysaddr = (ACPI_NFIT_SYSTEM_ADDRESS *)nfit;
   2524  1.15.8.1    martin 		printf("\tRangeIndex=%u\n", (u_int)sysaddr->RangeIndex);
   2525  1.15.8.1    martin 		printf("\tProximityDomain=%u\n",
   2526  1.15.8.1    martin 		    (u_int)sysaddr->ProximityDomain);
   2527  1.15.8.1    martin 		uuid_to_string((uuid_t *)(sysaddr->RangeGuid),
   2528  1.15.8.1    martin 		    &uuidstr, &status);
   2529  1.15.8.1    martin 		if (status != uuid_s_ok)
   2530  1.15.8.1    martin 			errx(1, "uuid_to_string: status=%u", status);
   2531  1.15.8.1    martin 		printf("\tRangeGuid=%s\n", uuidstr);
   2532  1.15.8.1    martin 		free(uuidstr);
   2533  1.15.8.1    martin 		printf("\tAddress=0x%016jx\n", (uintmax_t)sysaddr->Address);
   2534  1.15.8.1    martin 		printf("\tLength=0x%016jx\n", (uintmax_t)sysaddr->Length);
   2535  1.15.8.1    martin 		printf("\tMemoryMapping=0x%016jx\n",
   2536  1.15.8.1    martin 		    (uintmax_t)sysaddr->MemoryMapping);
   2537  1.15.8.1    martin 
   2538  1.15.8.1    martin #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
   2539  1.15.8.1    martin 
   2540  1.15.8.1    martin 		printf("\tFlags=");
   2541  1.15.8.1    martin 		PRINTFLAG(sysaddr->Flags, ADD_ONLINE_ONLY);
   2542  1.15.8.1    martin 		PRINTFLAG(sysaddr->Flags, PROXIMITY_VALID);
   2543  1.15.8.1    martin 		PRINTFLAG_END();
   2544  1.15.8.1    martin 
   2545  1.15.8.1    martin #undef PRINTFLAG
   2546  1.15.8.1    martin 
   2547  1.15.8.1    martin 		break;
   2548  1.15.8.1    martin 	case ACPI_NFIT_TYPE_MEMORY_MAP:
   2549  1.15.8.1    martin 		mmap = (ACPI_NFIT_MEMORY_MAP *)nfit;
   2550  1.15.8.1    martin 		printf("\tDeviceHandle=%u\n", (u_int)mmap->DeviceHandle);
   2551  1.15.8.1    martin 		printf("\tPhysicalId=%u\n", (u_int)mmap->PhysicalId);
   2552  1.15.8.1    martin 		printf("\tRegionId=%u\n", (u_int)mmap->RegionId);
   2553  1.15.8.1    martin 		printf("\tRangeIndex=%u\n", (u_int)mmap->RangeIndex);
   2554  1.15.8.1    martin 		printf("\tRegionIndex=%u\n", (u_int)mmap->RegionIndex);
   2555  1.15.8.1    martin 		printf("\tRegionSize=0x%016jx\n", (uintmax_t)mmap->RegionSize);
   2556  1.15.8.1    martin 		printf("\tRegionOffset=0x%016jx\n",
   2557  1.15.8.1    martin 		    (uintmax_t)mmap->RegionOffset);
   2558  1.15.8.1    martin 		printf("\tAddress=0x%016jx\n", (uintmax_t)mmap->Address);
   2559  1.15.8.1    martin 		printf("\tInterleaveIndex=%u\n", (u_int)mmap->InterleaveIndex);
   2560  1.15.8.1    martin 		printf("\tInterleaveWays=%u\n", (u_int)mmap->InterleaveWays);
   2561  1.15.8.1    martin 
   2562  1.15.8.1    martin #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_MEM_## flag, #flag)
   2563  1.15.8.1    martin 
   2564  1.15.8.1    martin 		printf("\tFlags=");
   2565  1.15.8.1    martin 		PRINTFLAG(mmap->Flags, SAVE_FAILED);
   2566  1.15.8.1    martin 		PRINTFLAG(mmap->Flags, RESTORE_FAILED);
   2567  1.15.8.1    martin 		PRINTFLAG(mmap->Flags, FLUSH_FAILED);
   2568  1.15.8.1    martin 		PRINTFLAG(mmap->Flags, NOT_ARMED);
   2569  1.15.8.1    martin 		PRINTFLAG(mmap->Flags, HEALTH_OBSERVED);
   2570  1.15.8.1    martin 		PRINTFLAG(mmap->Flags, HEALTH_ENABLED);
   2571  1.15.8.1    martin 		PRINTFLAG(mmap->Flags, MAP_FAILED);
   2572  1.15.8.1    martin 		PRINTFLAG_END();
   2573  1.15.8.1    martin 
   2574  1.15.8.1    martin #undef PRINTFLAG
   2575  1.15.8.1    martin 
   2576  1.15.8.1    martin 		break;
   2577  1.15.8.1    martin 	case ACPI_NFIT_TYPE_INTERLEAVE:
   2578  1.15.8.1    martin 		ileave = (ACPI_NFIT_INTERLEAVE *)nfit;
   2579  1.15.8.1    martin 		printf("\tInterleaveIndex=%u\n",
   2580  1.15.8.1    martin 		    (u_int)ileave->InterleaveIndex);
   2581  1.15.8.1    martin 		printf("\tLineCount=%u\n", (u_int)ileave->LineCount);
   2582  1.15.8.1    martin 		printf("\tLineSize=%u\n", (u_int)ileave->LineSize);
   2583  1.15.8.1    martin 		/* XXX ileave->LineOffset[i] output is not supported */
   2584  1.15.8.1    martin 		break;
   2585  1.15.8.1    martin 	case ACPI_NFIT_TYPE_SMBIOS:
   2586  1.15.8.1    martin 		smbios = (ACPI_NFIT_SMBIOS *)nfit;
   2587  1.15.8.1    martin 		/* XXX smbios->Data[x] output is not supported */
   2588  1.15.8.1    martin 		break;
   2589  1.15.8.1    martin 	case ACPI_NFIT_TYPE_CONTROL_REGION:
   2590  1.15.8.1    martin 		ctlreg = (ACPI_NFIT_CONTROL_REGION *)nfit;
   2591  1.15.8.1    martin 		printf("\tRegionIndex=%u\n", (u_int)ctlreg->RegionIndex);
   2592  1.15.8.1    martin 		printf("\tVendorId=0x%04x\n", (u_int)ctlreg->VendorId);
   2593  1.15.8.1    martin 		printf("\tDeviceId=0x%04x\n", (u_int)ctlreg->DeviceId);
   2594  1.15.8.1    martin 		printf("\tRevisionId=%u\n", (u_int)ctlreg->RevisionId);
   2595  1.15.8.1    martin 		printf("\tSubsystemVendorId=0x%04x\n",
   2596  1.15.8.1    martin 		    (u_int)ctlreg->SubsystemVendorId);
   2597  1.15.8.1    martin 		printf("\tSubsystemDeviceId=0x%04x\n",
   2598  1.15.8.1    martin 		    (u_int)ctlreg->SubsystemDeviceId);
   2599  1.15.8.1    martin 		printf("\tSubsystemRevisionId=%u\n",
   2600  1.15.8.1    martin 		    (u_int)ctlreg->SubsystemRevisionId);
   2601  1.15.8.1    martin 		printf("\tValidFields=%02x\n", (u_int)ctlreg->ValidFields);
   2602  1.15.8.1    martin 		printf("\tManufacturingLocation=%u\n",
   2603  1.15.8.1    martin 		    (u_int)ctlreg->ManufacturingLocation);
   2604  1.15.8.1    martin 		printf("\tManufacturingDate=%u\n",
   2605  1.15.8.1    martin 		    (u_int)ctlreg->ManufacturingDate);
   2606  1.15.8.1    martin 		printf("\tSerialNumber=%u\n",
   2607  1.15.8.1    martin 		    (u_int)ctlreg->SerialNumber);
   2608  1.15.8.1    martin 		printf("\tCode=0x%04x\n", (u_int)ctlreg->Code);
   2609  1.15.8.1    martin 		printf("\tWindows=%u\n", (u_int)ctlreg->Windows);
   2610  1.15.8.1    martin 		printf("\tWindowSize=0x%016jx\n",
   2611  1.15.8.1    martin 		    (uintmax_t)ctlreg->WindowSize);
   2612  1.15.8.1    martin 		printf("\tCommandOffset=0x%016jx\n",
   2613  1.15.8.1    martin 		    (uintmax_t)ctlreg->CommandOffset);
   2614  1.15.8.1    martin 		printf("\tCommandSize=0x%016jx\n",
   2615  1.15.8.1    martin 		    (uintmax_t)ctlreg->CommandSize);
   2616  1.15.8.1    martin 		printf("\tStatusOffset=0x%016jx\n",
   2617  1.15.8.1    martin 		    (uintmax_t)ctlreg->StatusOffset);
   2618  1.15.8.1    martin 		printf("\tStatusSize=0x%016jx\n",
   2619  1.15.8.1    martin 		    (uintmax_t)ctlreg->StatusSize);
   2620  1.15.8.1    martin 
   2621  1.15.8.1    martin #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
   2622  1.15.8.1    martin 
   2623  1.15.8.1    martin 		printf("\tFlags=");
   2624  1.15.8.1    martin 		PRINTFLAG(ctlreg->Flags, CONTROL_BUFFERED);
   2625  1.15.8.1    martin 		PRINTFLAG_END();
   2626  1.15.8.1    martin 
   2627  1.15.8.1    martin #undef PRINTFLAG
   2628  1.15.8.1    martin 
   2629  1.15.8.1    martin 		break;
   2630  1.15.8.1    martin 	case ACPI_NFIT_TYPE_DATA_REGION:
   2631  1.15.8.1    martin 		datareg = (ACPI_NFIT_DATA_REGION *)nfit;
   2632  1.15.8.1    martin 		printf("\tRegionIndex=%u\n", (u_int)datareg->RegionIndex);
   2633  1.15.8.1    martin 		printf("\tWindows=%u\n", (u_int)datareg->Windows);
   2634  1.15.8.1    martin 		printf("\tOffset=0x%016jx\n", (uintmax_t)datareg->Offset);
   2635  1.15.8.1    martin 		printf("\tSize=0x%016jx\n", (uintmax_t)datareg->Size);
   2636  1.15.8.1    martin 		printf("\tCapacity=0x%016jx\n", (uintmax_t)datareg->Capacity);
   2637  1.15.8.1    martin 		printf("\tStartAddress=0x%016jx\n",
   2638  1.15.8.1    martin 		    (uintmax_t)datareg->StartAddress);
   2639  1.15.8.1    martin 		break;
   2640  1.15.8.1    martin 	case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
   2641  1.15.8.1    martin 		fladdr = (ACPI_NFIT_FLUSH_ADDRESS *)nfit;
   2642  1.15.8.1    martin 		printf("\tDeviceHandle=%u\n", (u_int)fladdr->DeviceHandle);
   2643  1.15.8.1    martin 		printf("\tHintCount=%u\n", (u_int)fladdr->HintCount);
   2644  1.15.8.1    martin 		/* XXX fladdr->HintAddress[i] output is not supported */
   2645  1.15.8.1    martin 		break;
   2646  1.15.8.1    martin 	}
   2647  1.15.8.1    martin }
   2648  1.15.8.1    martin 
   2649  1.15.8.1    martin static void
   2650  1.15.8.1    martin acpi_handle_nfit(ACPI_TABLE_HEADER *sdp)
   2651  1.15.8.1    martin {
   2652  1.15.8.1    martin 	ACPI_TABLE_NFIT *nfit;
   2653  1.15.8.1    martin 
   2654  1.15.8.1    martin 	printf(BEGIN_COMMENT);
   2655  1.15.8.1    martin 	acpi_print_sdt(sdp);
   2656  1.15.8.1    martin 	nfit = (ACPI_TABLE_NFIT *)sdp;
   2657  1.15.8.1    martin 	acpi_walk_nfit(sdp, (nfit + 1), acpi_print_nfit);
   2658  1.15.8.1    martin 	printf(END_COMMENT);
   2659  1.15.8.1    martin }
   2660  1.15.8.1    martin 
   2661  1.15.8.1    martin static char *
   2662  1.15.8.1    martin acpi_tcpa_evname(struct TCPAevent *event)
   2663  1.15.8.1    martin {
   2664  1.15.8.1    martin 	struct TCPApc_event *pc_event;
   2665  1.15.8.1    martin 	char *eventname = NULL;
   2666  1.15.8.1    martin 
   2667  1.15.8.1    martin 	pc_event = (struct TCPApc_event *)(event + 1);
   2668  1.15.8.1    martin 
   2669  1.15.8.2    martin 	switch (event->event_type) {
   2670  1.15.8.1    martin 	case PREBOOT:
   2671  1.15.8.1    martin 	case POST_CODE:
   2672  1.15.8.1    martin 	case UNUSED:
   2673  1.15.8.1    martin 	case NO_ACTION:
   2674  1.15.8.1    martin 	case SEPARATOR:
   2675  1.15.8.1    martin 	case SCRTM_CONTENTS:
   2676  1.15.8.1    martin 	case SCRTM_VERSION:
   2677  1.15.8.1    martin 	case CPU_MICROCODE:
   2678  1.15.8.1    martin 	case PLATFORM_CONFIG_FLAGS:
   2679  1.15.8.1    martin 	case TABLE_OF_DEVICES:
   2680  1.15.8.1    martin 	case COMPACT_HASH:
   2681  1.15.8.1    martin 	case IPL:
   2682  1.15.8.1    martin 	case IPL_PARTITION_DATA:
   2683  1.15.8.1    martin 	case NONHOST_CODE:
   2684  1.15.8.1    martin 	case NONHOST_CONFIG:
   2685  1.15.8.1    martin 	case NONHOST_INFO:
   2686  1.15.8.1    martin 		asprintf(&eventname, "%s",
   2687  1.15.8.1    martin 		    tcpa_event_type_strings[event->event_type]);
   2688  1.15.8.1    martin 		break;
   2689  1.15.8.1    martin 
   2690  1.15.8.1    martin 	case ACTION:
   2691  1.15.8.1    martin 		eventname = calloc(event->event_size + 1, sizeof(char));
   2692  1.15.8.1    martin 		memcpy(eventname, pc_event, event->event_size);
   2693  1.15.8.1    martin 		break;
   2694  1.15.8.1    martin 
   2695  1.15.8.1    martin 	case EVENT_TAG:
   2696  1.15.8.1    martin 		switch (pc_event->event_id) {
   2697  1.15.8.1    martin 		case SMBIOS:
   2698  1.15.8.1    martin 		case BIS_CERT:
   2699  1.15.8.1    martin 		case CMOS:
   2700  1.15.8.1    martin 		case NVRAM:
   2701  1.15.8.1    martin 		case OPTION_ROM_EXEC:
   2702  1.15.8.1    martin 		case OPTION_ROM_CONFIG:
   2703  1.15.8.1    martin 		case S_CRTM_VERSION:
   2704  1.15.8.1    martin 		case POST_BIOS_ROM:
   2705  1.15.8.1    martin 		case ESCD:
   2706  1.15.8.1    martin 		case OPTION_ROM_MICROCODE:
   2707  1.15.8.1    martin 		case S_CRTM_CONTENTS:
   2708  1.15.8.1    martin 		case POST_CONTENTS:
   2709  1.15.8.1    martin 			asprintf(&eventname, "%s",
   2710  1.15.8.1    martin 			    TCPA_pcclient_strings[pc_event->event_id]);
   2711  1.15.8.1    martin 			break;
   2712  1.15.8.1    martin 
   2713  1.15.8.1    martin 		default:
   2714  1.15.8.1    martin 			asprintf(&eventname, "<unknown tag 0x%02x>",
   2715  1.15.8.1    martin 			    pc_event->event_id);
   2716  1.15.8.1    martin 			break;
   2717  1.15.8.1    martin 		}
   2718  1.15.8.1    martin 		break;
   2719  1.15.8.1    martin 
   2720  1.15.8.1    martin 	default:
   2721  1.15.8.1    martin 		asprintf(&eventname, "<unknown 0x%02x>", event->event_type);
   2722  1.15.8.1    martin 		break;
   2723  1.15.8.1    martin 	}
   2724  1.15.8.1    martin 
   2725  1.15.8.1    martin 	return eventname;
   2726  1.15.8.1    martin }
   2727  1.15.8.1    martin 
   2728  1.15.8.1    martin static void
   2729  1.15.8.1    martin acpi_print_tcpa(struct TCPAevent *event)
   2730  1.15.8.1    martin {
   2731  1.15.8.1    martin 	int i;
   2732  1.15.8.1    martin 	char *eventname;
   2733  1.15.8.1    martin 
   2734  1.15.8.1    martin 	eventname = acpi_tcpa_evname(event);
   2735  1.15.8.1    martin 
   2736  1.15.8.1    martin 	printf("\t%d", event->pcr_index);
   2737  1.15.8.1    martin 	printf(" 0x");
   2738  1.15.8.1    martin 	for (i = 0; i < 20; i++)
   2739  1.15.8.1    martin 		printf("%02x", event->pcr_value[i]);
   2740  1.15.8.1    martin 	printf(" [%s]\n", eventname ? eventname : "<unknown>");
   2741  1.15.8.1    martin 
   2742  1.15.8.1    martin 	free(eventname);
   2743  1.15.8.1    martin }
   2744  1.15.8.1    martin 
   2745       1.1  christos static void
   2746       1.5    cegger acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp)
   2747       1.1  christos {
   2748  1.15.8.1    martin 	struct TCPAbody *tcpa;
   2749  1.15.8.1    martin 	struct TCPAevent *event;
   2750  1.15.8.1    martin 	uintmax_t len, paddr;
   2751  1.15.8.1    martin 	unsigned char *vaddr = NULL;
   2752  1.15.8.1    martin 	unsigned char *vend = NULL;
   2753       1.5    cegger 
   2754       1.5    cegger 	printf(BEGIN_COMMENT);
   2755       1.5    cegger 	acpi_print_sdt(sdp);
   2756  1.15.8.1    martin 	tcpa = (struct TCPAbody *) sdp;
   2757  1.15.8.1    martin 
   2758  1.15.8.1    martin 	switch (tcpa->platform_class) {
   2759  1.15.8.1    martin 	case ACPI_TCPA_BIOS_CLIENT:
   2760  1.15.8.1    martin 		len = tcpa->client.log_max_len;
   2761  1.15.8.1    martin 		paddr = tcpa->client.log_start_addr;
   2762      1.13  christos 		break;
   2763      1.13  christos 
   2764  1.15.8.1    martin 	case ACPI_TCPA_BIOS_SERVER:
   2765  1.15.8.1    martin 		len = tcpa->server.log_max_len;
   2766  1.15.8.1    martin 		paddr = tcpa->server.log_start_addr;
   2767      1.13  christos 		break;
   2768      1.13  christos 
   2769      1.13  christos 	default:
   2770  1.15.8.1    martin 		printf("XXX");
   2771  1.15.8.1    martin 		printf(END_COMMENT);
   2772  1.15.8.1    martin 		return;
   2773  1.15.8.1    martin 	}
   2774  1.15.8.1    martin 	printf("\tClass %u Base Address 0x%jx Length %ju\n\n",
   2775  1.15.8.1    martin 	    tcpa->platform_class, paddr, len);
   2776  1.15.8.1    martin 
   2777  1.15.8.1    martin 	if (len == 0) {
   2778  1.15.8.1    martin 		printf("\tEmpty TCPA table\n");
   2779  1.15.8.1    martin 		printf(END_COMMENT);
   2780  1.15.8.1    martin 		return;
   2781  1.15.8.1    martin 	}
   2782  1.15.8.2    martin 	if (sdp->Revision == 1) {
   2783  1.15.8.1    martin 		printf("\tOLD TCPA spec log found. Dumping not supported.\n");
   2784  1.15.8.1    martin 		printf(END_COMMENT);
   2785  1.15.8.1    martin 		return;
   2786  1.15.8.1    martin 	}
   2787  1.15.8.1    martin 
   2788  1.15.8.1    martin 	vaddr = (unsigned char *)acpi_map_physical(paddr, len);
   2789  1.15.8.1    martin 	vend = vaddr + len;
   2790  1.15.8.1    martin 
   2791  1.15.8.1    martin 	while (vaddr != NULL) {
   2792  1.15.8.1    martin 		if ((vaddr + sizeof(struct TCPAevent) >= vend)||
   2793  1.15.8.1    martin 		    (vaddr + sizeof(struct TCPAevent) < vaddr))
   2794  1.15.8.1    martin 			break;
   2795  1.15.8.1    martin 		event = (struct TCPAevent *)(void *)vaddr;
   2796  1.15.8.1    martin 		if (vaddr + event->event_size >= vend)
   2797  1.15.8.1    martin 			break;
   2798  1.15.8.1    martin 		if (vaddr + event->event_size < vaddr)
   2799  1.15.8.1    martin 			break;
   2800  1.15.8.1    martin 		if (event->event_type == 0 && event->event_size == 0)
   2801  1.15.8.1    martin 			break;
   2802  1.15.8.1    martin #if 0
   2803  1.15.8.1    martin 		{
   2804  1.15.8.1    martin 		unsigned int i, j, k;
   2805  1.15.8.1    martin 
   2806  1.15.8.1    martin 		printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr);
   2807  1.15.8.1    martin 		for (j = 0, i = 0; i <
   2808  1.15.8.1    martin 		    sizeof(struct TCPAevent) + event->event_size; i++) {
   2809  1.15.8.1    martin 			printf("%02x ", vaddr[i]);
   2810  1.15.8.1    martin 			if ((i+1) % 8 == 0) {
   2811  1.15.8.1    martin 				for (k = 0; k < 8; k++)
   2812  1.15.8.1    martin 					printf("%c", isprint(vaddr[j+k]) ?
   2813  1.15.8.1    martin 					    vaddr[j+k] : '.');
   2814  1.15.8.1    martin 				printf("\n\t\t%p ", &vaddr[i + 1]);
   2815  1.15.8.1    martin 				j = i + 1;
   2816  1.15.8.1    martin 			}
   2817  1.15.8.1    martin 		}
   2818  1.15.8.1    martin 		printf("\n"); }
   2819  1.15.8.1    martin #endif
   2820  1.15.8.1    martin 		acpi_print_tcpa(event);
   2821  1.15.8.1    martin 
   2822  1.15.8.1    martin 		vaddr += sizeof(struct TCPAevent) + event->event_size;
   2823  1.15.8.1    martin 	}
   2824  1.15.8.1    martin 
   2825  1.15.8.1    martin 	printf(END_COMMENT);
   2826  1.15.8.1    martin }
   2827  1.15.8.1    martin 
   2828  1.15.8.1    martin static const char *
   2829  1.15.8.1    martin devscope_type2str(int type)
   2830  1.15.8.1    martin {
   2831  1.15.8.1    martin 	static char typebuf[16];
   2832  1.15.8.1    martin 
   2833  1.15.8.1    martin 	switch (type) {
   2834  1.15.8.1    martin 	case 1:
   2835  1.15.8.1    martin 		return ("PCI Endpoint Device");
   2836  1.15.8.1    martin 	case 2:
   2837  1.15.8.1    martin 		return ("PCI Sub-Hierarchy");
   2838  1.15.8.1    martin 	case 3:
   2839  1.15.8.1    martin 		return ("IOAPIC");
   2840  1.15.8.1    martin 	case 4:
   2841  1.15.8.1    martin 		return ("HPET");
   2842  1.15.8.2    martin 	case 5:
   2843  1.15.8.2    martin 		return ("ACPI Name space");
   2844  1.15.8.1    martin 	default:
   2845  1.15.8.1    martin 		snprintf(typebuf, sizeof(typebuf), "%d", type);
   2846  1.15.8.1    martin 		return (typebuf);
   2847  1.15.8.1    martin 	}
   2848  1.15.8.1    martin }
   2849  1.15.8.1    martin 
   2850  1.15.8.1    martin static int
   2851  1.15.8.1    martin acpi_handle_dmar_devscope(void *addr, int remaining)
   2852  1.15.8.1    martin {
   2853  1.15.8.1    martin 	char sep;
   2854  1.15.8.1    martin 	int pathlen;
   2855  1.15.8.1    martin 	ACPI_DMAR_PCI_PATH *path, *pathend;
   2856  1.15.8.1    martin 	ACPI_DMAR_DEVICE_SCOPE *devscope = addr;
   2857  1.15.8.1    martin 
   2858  1.15.8.1    martin 	if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE))
   2859  1.15.8.1    martin 		return (-1);
   2860  1.15.8.1    martin 
   2861  1.15.8.1    martin 	if (remaining < devscope->Length)
   2862  1.15.8.1    martin 		return (-1);
   2863  1.15.8.1    martin 
   2864  1.15.8.1    martin 	printf("\n");
   2865  1.15.8.1    martin 	printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType));
   2866  1.15.8.1    martin 	printf("\t\tLength=%d\n", devscope->Length);
   2867  1.15.8.1    martin 	printf("\t\tEnumerationId=%d\n", devscope->EnumerationId);
   2868  1.15.8.1    martin 	printf("\t\tStartBusNumber=%d\n", devscope->Bus);
   2869  1.15.8.1    martin 
   2870  1.15.8.1    martin 	path = (ACPI_DMAR_PCI_PATH *)(devscope + 1);
   2871  1.15.8.1    martin 	pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE);
   2872  1.15.8.1    martin 	pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH);
   2873  1.15.8.1    martin 	if (path < pathend) {
   2874  1.15.8.1    martin 		sep = '{';
   2875  1.15.8.1    martin 		printf("\t\tPath=");
   2876  1.15.8.1    martin 		do {
   2877  1.15.8.1    martin 			printf("%c%d:%d", sep, path->Device, path->Function);
   2878  1.15.8.1    martin 			sep=',';
   2879  1.15.8.1    martin 			path++;
   2880  1.15.8.1    martin 		} while (path < pathend);
   2881  1.15.8.1    martin 		printf("}\n");
   2882  1.15.8.1    martin 	}
   2883  1.15.8.1    martin 
   2884  1.15.8.1    martin 	return (devscope->Length);
   2885  1.15.8.1    martin }
   2886  1.15.8.1    martin 
   2887  1.15.8.1    martin static void
   2888  1.15.8.1    martin acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd)
   2889  1.15.8.1    martin {
   2890  1.15.8.1    martin 	char *cp;
   2891  1.15.8.1    martin 	int remaining, consumed;
   2892  1.15.8.1    martin 
   2893  1.15.8.1    martin 	printf("\n");
   2894  1.15.8.1    martin 	printf("\tType=DRHD\n");
   2895  1.15.8.1    martin 	printf("\tLength=%d\n", drhd->Header.Length);
   2896  1.15.8.1    martin 
   2897  1.15.8.1    martin #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
   2898  1.15.8.1    martin 
   2899  1.15.8.1    martin 	printf("\tFlags=");
   2900  1.15.8.1    martin 	PRINTFLAG(drhd->Flags, INCLUDE_ALL);
   2901  1.15.8.1    martin 	PRINTFLAG_END();
   2902  1.15.8.1    martin 
   2903  1.15.8.1    martin #undef PRINTFLAG
   2904  1.15.8.1    martin 
   2905  1.15.8.1    martin 	printf("\tSegment=%d\n", drhd->Segment);
   2906  1.15.8.1    martin 	printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address);
   2907  1.15.8.1    martin 
   2908  1.15.8.1    martin 	remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT);
   2909  1.15.8.1    martin 	if (remaining > 0)
   2910  1.15.8.1    martin 		printf("\tDevice Scope:");
   2911  1.15.8.1    martin 	while (remaining > 0) {
   2912  1.15.8.1    martin 		cp = (char *)drhd + drhd->Header.Length - remaining;
   2913  1.15.8.1    martin 		consumed = acpi_handle_dmar_devscope(cp, remaining);
   2914  1.15.8.1    martin 		if (consumed <= 0)
   2915  1.15.8.1    martin 			break;
   2916  1.15.8.1    martin 		else
   2917  1.15.8.1    martin 			remaining -= consumed;
   2918  1.15.8.1    martin 	}
   2919  1.15.8.1    martin }
   2920  1.15.8.1    martin 
   2921  1.15.8.1    martin static void
   2922  1.15.8.1    martin acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr)
   2923  1.15.8.1    martin {
   2924  1.15.8.1    martin 	char *cp;
   2925  1.15.8.1    martin 	int remaining, consumed;
   2926  1.15.8.1    martin 
   2927  1.15.8.1    martin 	printf("\n");
   2928  1.15.8.1    martin 	printf("\tType=RMRR\n");
   2929  1.15.8.1    martin 	printf("\tLength=%d\n", rmrr->Header.Length);
   2930  1.15.8.1    martin 	printf("\tSegment=%d\n", rmrr->Segment);
   2931  1.15.8.1    martin 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress);
   2932  1.15.8.1    martin 	printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress);
   2933  1.15.8.1    martin 
   2934  1.15.8.1    martin 	remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY);
   2935  1.15.8.1    martin 	if (remaining > 0)
   2936  1.15.8.1    martin 		printf("\tDevice Scope:");
   2937  1.15.8.1    martin 	while (remaining > 0) {
   2938  1.15.8.1    martin 		cp = (char *)rmrr + rmrr->Header.Length - remaining;
   2939  1.15.8.1    martin 		consumed = acpi_handle_dmar_devscope(cp, remaining);
   2940  1.15.8.1    martin 		if (consumed <= 0)
   2941  1.15.8.1    martin 			break;
   2942  1.15.8.1    martin 		else
   2943  1.15.8.1    martin 			remaining -= consumed;
   2944  1.15.8.1    martin 	}
   2945  1.15.8.1    martin }
   2946  1.15.8.1    martin 
   2947  1.15.8.1    martin static void
   2948  1.15.8.1    martin acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr)
   2949  1.15.8.1    martin {
   2950  1.15.8.1    martin 	char *cp;
   2951  1.15.8.1    martin 	int remaining, consumed;
   2952  1.15.8.1    martin 
   2953  1.15.8.1    martin 	printf("\n");
   2954  1.15.8.1    martin 	printf("\tType=ATSR\n");
   2955  1.15.8.1    martin 	printf("\tLength=%d\n", atsr->Header.Length);
   2956  1.15.8.1    martin 
   2957  1.15.8.1    martin #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
   2958  1.15.8.1    martin 
   2959  1.15.8.1    martin 	printf("\tFlags=");
   2960  1.15.8.1    martin 	PRINTFLAG(atsr->Flags, ALL_PORTS);
   2961  1.15.8.1    martin 	PRINTFLAG_END();
   2962  1.15.8.1    martin 
   2963  1.15.8.1    martin #undef PRINTFLAG
   2964  1.15.8.1    martin 
   2965  1.15.8.1    martin 	printf("\tSegment=%d\n", atsr->Segment);
   2966  1.15.8.1    martin 
   2967  1.15.8.1    martin 	remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR);
   2968  1.15.8.1    martin 	if (remaining > 0)
   2969  1.15.8.1    martin 		printf("\tDevice Scope:");
   2970  1.15.8.1    martin 	while (remaining > 0) {
   2971  1.15.8.1    martin 		cp = (char *)atsr + atsr->Header.Length - remaining;
   2972  1.15.8.1    martin 		consumed = acpi_handle_dmar_devscope(cp, remaining);
   2973  1.15.8.1    martin 		if (consumed <= 0)
   2974  1.15.8.1    martin 			break;
   2975  1.15.8.1    martin 		else
   2976  1.15.8.1    martin 			remaining -= consumed;
   2977  1.15.8.1    martin 	}
   2978  1.15.8.1    martin }
   2979  1.15.8.1    martin 
   2980  1.15.8.1    martin static void
   2981  1.15.8.1    martin acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa)
   2982  1.15.8.1    martin {
   2983  1.15.8.1    martin 
   2984  1.15.8.1    martin 	printf("\n");
   2985  1.15.8.1    martin 	printf("\tType=RHSA\n");
   2986  1.15.8.1    martin 	printf("\tLength=%d\n", rhsa->Header.Length);
   2987  1.15.8.1    martin 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress);
   2988  1.15.8.1    martin 	printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain);
   2989  1.15.8.1    martin }
   2990  1.15.8.1    martin 
   2991  1.15.8.2    martin static void
   2992  1.15.8.2    martin acpi_handle_dmar_andd(ACPI_DMAR_ANDD *andd)
   2993  1.15.8.2    martin {
   2994  1.15.8.2    martin 
   2995  1.15.8.2    martin 	printf("\n");
   2996  1.15.8.2    martin 	printf("\tType=ANDD\n");
   2997  1.15.8.2    martin 	printf("\tLength=%d\n", andd->Header.Length);
   2998  1.15.8.2    martin 	printf("\tDeviceNumber=%d\n", andd->DeviceNumber);
   2999  1.15.8.2    martin 	printf("\tDeviceName=0x%s\n", andd->DeviceName);
   3000  1.15.8.2    martin }
   3001  1.15.8.2    martin 
   3002  1.15.8.1    martin static int
   3003  1.15.8.1    martin acpi_handle_dmar_remapping_structure(void *addr, int remaining)
   3004  1.15.8.1    martin {
   3005  1.15.8.1    martin 	ACPI_DMAR_HEADER *hdr = addr;
   3006  1.15.8.1    martin 
   3007  1.15.8.1    martin 	if (remaining < (int)sizeof(ACPI_DMAR_HEADER))
   3008  1.15.8.1    martin 		return (-1);
   3009  1.15.8.1    martin 
   3010  1.15.8.1    martin 	if (remaining < hdr->Length)
   3011  1.15.8.1    martin 		return (-1);
   3012  1.15.8.1    martin 
   3013  1.15.8.1    martin 	switch (hdr->Type) {
   3014  1.15.8.1    martin 	case ACPI_DMAR_TYPE_HARDWARE_UNIT:
   3015  1.15.8.1    martin 		acpi_handle_dmar_drhd(addr);
   3016  1.15.8.1    martin 		break;
   3017  1.15.8.1    martin 	case ACPI_DMAR_TYPE_RESERVED_MEMORY:
   3018  1.15.8.1    martin 		acpi_handle_dmar_rmrr(addr);
   3019  1.15.8.1    martin 		break;
   3020  1.15.8.1    martin 	case ACPI_DMAR_TYPE_ROOT_ATS:
   3021  1.15.8.1    martin 		acpi_handle_dmar_atsr(addr);
   3022  1.15.8.1    martin 		break;
   3023  1.15.8.1    martin 	case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
   3024  1.15.8.1    martin 		acpi_handle_dmar_rhsa(addr);
   3025      1.13  christos 		break;
   3026  1.15.8.2    martin 	case ACPI_DMAR_TYPE_NAMESPACE:
   3027  1.15.8.2    martin 		acpi_handle_dmar_andd(addr);
   3028  1.15.8.2    martin 		break;
   3029  1.15.8.1    martin 	default:
   3030  1.15.8.1    martin 		printf("\n");
   3031  1.15.8.1    martin 		printf("\tType=%d\n", hdr->Type);
   3032  1.15.8.1    martin 		printf("\tLength=%d\n", hdr->Length);
   3033  1.15.8.1    martin 		break;
   3034  1.15.8.1    martin 	}
   3035  1.15.8.1    martin 	return (hdr->Length);
   3036  1.15.8.1    martin }
   3037  1.15.8.1    martin 
   3038  1.15.8.1    martin #ifndef ACPI_DMAR_X2APIC_OPT_OUT
   3039  1.15.8.1    martin #define	ACPI_DMAR_X2APIC_OPT_OUT	(0x2)
   3040  1.15.8.1    martin #endif
   3041  1.15.8.1    martin 
   3042  1.15.8.1    martin static void
   3043  1.15.8.1    martin acpi_handle_dmar(ACPI_TABLE_HEADER *sdp)
   3044  1.15.8.1    martin {
   3045  1.15.8.1    martin 	char *cp;
   3046  1.15.8.1    martin 	int remaining, consumed;
   3047  1.15.8.1    martin 	ACPI_TABLE_DMAR *dmar;
   3048  1.15.8.1    martin 
   3049  1.15.8.1    martin 	printf(BEGIN_COMMENT);
   3050  1.15.8.1    martin 	acpi_print_sdt(sdp);
   3051  1.15.8.1    martin 	dmar = (ACPI_TABLE_DMAR *)sdp;
   3052  1.15.8.1    martin 	printf("\tHost Address Width=%d\n", dmar->Width + 1);
   3053  1.15.8.1    martin 
   3054  1.15.8.1    martin #define PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
   3055  1.15.8.1    martin 
   3056  1.15.8.1    martin 	printf("\tFlags=");
   3057  1.15.8.1    martin 	PRINTFLAG(dmar->Flags, INTR_REMAP);
   3058  1.15.8.1    martin 	PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT);
   3059  1.15.8.2    martin 	PRINTFLAG(dmar->Flags, X2APIC_MODE);
   3060  1.15.8.1    martin 	PRINTFLAG_END();
   3061  1.15.8.1    martin 
   3062  1.15.8.1    martin #undef PRINTFLAG
   3063  1.15.8.1    martin 
   3064  1.15.8.1    martin 	remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR);
   3065  1.15.8.1    martin 	while (remaining > 0) {
   3066  1.15.8.1    martin 		cp = (char *)sdp + sdp->Length - remaining;
   3067  1.15.8.1    martin 		consumed = acpi_handle_dmar_remapping_structure(cp, remaining);
   3068  1.15.8.1    martin 		if (consumed <= 0)
   3069  1.15.8.1    martin 			break;
   3070  1.15.8.1    martin 		else
   3071  1.15.8.1    martin 			remaining -= consumed;
   3072      1.13  christos 	}
   3073       1.1  christos 
   3074      1.12  christos 	printf(END_COMMENT);
   3075       1.1  christos }
   3076       1.1  christos 
   3077       1.1  christos static void
   3078  1.15.8.1    martin acpi_handle_uefi(ACPI_TABLE_HEADER *sdp)
   3079  1.15.8.1    martin {
   3080  1.15.8.1    martin 	ACPI_TABLE_UEFI *uefi;
   3081  1.15.8.1    martin 	char *uuidstr;
   3082  1.15.8.1    martin 	uint32_t status;
   3083  1.15.8.1    martin 
   3084  1.15.8.1    martin 	printf(BEGIN_COMMENT);
   3085  1.15.8.1    martin 	acpi_print_sdt(sdp);
   3086  1.15.8.1    martin 	uefi = (ACPI_TABLE_UEFI *)sdp;
   3087  1.15.8.1    martin 
   3088  1.15.8.1    martin 	uuid_to_string((uuid_t *)(uefi->Identifier),
   3089  1.15.8.1    martin 	    &uuidstr, &status);
   3090  1.15.8.1    martin 	if (status != uuid_s_ok)
   3091  1.15.8.1    martin 		errx(1, "uuid_to_string: status=%u", status);
   3092  1.15.8.1    martin 	printf("\tUUID=%s\n", uuidstr);
   3093  1.15.8.1    martin 	free(uuidstr);
   3094  1.15.8.1    martin 
   3095  1.15.8.1    martin 	printf("\tDataOffset=%04hx\n", uefi->DataOffset);
   3096  1.15.8.1    martin 	/* XXX need write */
   3097  1.15.8.1    martin 
   3098  1.15.8.1    martin 	printf(END_COMMENT);
   3099  1.15.8.1    martin }
   3100  1.15.8.1    martin 
   3101  1.15.8.1    martin static void
   3102       1.5    cegger acpi_handle_waet(ACPI_TABLE_HEADER *sdp)
   3103       1.1  christos {
   3104       1.5    cegger 	ACPI_TABLE_WAET *waet;
   3105       1.5    cegger 
   3106       1.5    cegger 	printf(BEGIN_COMMENT);
   3107       1.5    cegger 	acpi_print_sdt(sdp);
   3108       1.5    cegger 	waet = (ACPI_TABLE_WAET *)sdp;
   3109       1.1  christos 
   3110       1.5    cegger 	printf("\tRTC Timer={");
   3111       1.5    cegger 	if (waet->Flags & ACPI_WAET_RTC_NO_ACK)
   3112       1.5    cegger 		printf("No ACK required");
   3113       1.5    cegger 	else
   3114       1.5    cegger 		printf("default behaviour");
   3115       1.5    cegger 	printf("}\n");
   3116       1.5    cegger 	printf("\t ACPI PM Timer={");
   3117       1.5    cegger 	if (waet->Flags & ACPI_WAET_TIMER_ONE_READ)
   3118       1.5    cegger 		printf("One Read sufficient");
   3119       1.5    cegger 	else
   3120       1.5    cegger 		printf("default behaviour");
   3121       1.5    cegger 	printf("}\n");
   3122       1.3     joerg 
   3123       1.5    cegger 	printf(END_COMMENT);
   3124       1.1  christos }
   3125       1.1  christos 
   3126       1.5    cegger static void
   3127       1.5    cegger acpi_print_wdat_action(ACPI_WHEA_HEADER *whea)
   3128       1.5    cegger {
   3129       1.5    cegger 	printf("\tACTION={");
   3130       1.5    cegger 	switch (whea->Action) {
   3131       1.5    cegger 	case ACPI_WDAT_RESET:
   3132       1.5    cegger 		printf("RESET");
   3133       1.5    cegger 		break;
   3134       1.5    cegger 	case ACPI_WDAT_GET_CURRENT_COUNTDOWN:
   3135       1.5    cegger 		printf("GET_CURRENT_COUNTDOWN");
   3136       1.5    cegger 		break;
   3137       1.5    cegger 	case ACPI_WDAT_GET_COUNTDOWN:
   3138       1.5    cegger 		printf("GET_COUNTDOWN");
   3139       1.5    cegger 		break;
   3140       1.5    cegger 	case ACPI_WDAT_SET_COUNTDOWN:
   3141       1.5    cegger 		printf("SET_COUNTDOWN");
   3142       1.5    cegger 		break;
   3143       1.5    cegger 	case ACPI_WDAT_GET_RUNNING_STATE:
   3144       1.5    cegger 		printf("GET_RUNNING_STATE");
   3145       1.5    cegger 		break;
   3146       1.5    cegger 	case ACPI_WDAT_SET_RUNNING_STATE:
   3147       1.5    cegger 		printf("SET_RUNNING_STATE");
   3148       1.5    cegger 		break;
   3149       1.5    cegger 	case ACPI_WDAT_GET_STOPPED_STATE:
   3150       1.5    cegger 		printf("GET_STOPPED_STATE");
   3151       1.5    cegger 		break;
   3152       1.5    cegger 	case ACPI_WDAT_SET_STOPPED_STATE:
   3153       1.5    cegger 		printf("SET_STOPPED_STATE");
   3154       1.5    cegger 		break;
   3155       1.5    cegger 	case ACPI_WDAT_GET_REBOOT:
   3156       1.5    cegger 		printf("GET_REBOOT");
   3157       1.5    cegger 		break;
   3158       1.5    cegger 	case ACPI_WDAT_SET_REBOOT:
   3159       1.5    cegger 		printf("SET_REBOOT");
   3160       1.5    cegger 		break;
   3161       1.5    cegger 	case ACPI_WDAT_GET_SHUTDOWN:
   3162       1.5    cegger 		printf("GET_SHUTDOWN");
   3163       1.5    cegger 		break;
   3164       1.5    cegger 	case ACPI_WDAT_SET_SHUTDOWN:
   3165       1.5    cegger 		printf("SET_SHUTDOWN");
   3166       1.5    cegger 		break;
   3167       1.5    cegger 	case ACPI_WDAT_GET_STATUS:
   3168       1.5    cegger 		printf("GET_STATUS");
   3169       1.5    cegger 		break;
   3170       1.5    cegger 	case ACPI_WDAT_SET_STATUS:
   3171       1.5    cegger 		printf("SET_STATUS");
   3172       1.5    cegger 		break;
   3173       1.5    cegger 	case ACPI_WDAT_ACTION_RESERVED:
   3174       1.5    cegger 		printf("ACTION_RESERVED");
   3175       1.5    cegger 		break;
   3176       1.5    cegger 	default:
   3177       1.5    cegger 		printf("%d", whea->Action);
   3178       1.5    cegger 		break;
   3179       1.5    cegger 	}
   3180       1.5    cegger 	printf("}\n");
   3181       1.5    cegger }
   3182       1.1  christos 
   3183       1.5    cegger static void
   3184       1.5    cegger acpi_print_wdat_instruction(ACPI_WHEA_HEADER *whea)
   3185       1.1  christos {
   3186       1.5    cegger 	uint32_t ins;
   3187       1.5    cegger 
   3188       1.5    cegger 	ins = whea->Instruction & ~ACPI_WDAT_PRESERVE_REGISTER;
   3189       1.5    cegger 
   3190       1.5    cegger 	printf("\tINSTRUCTION={");
   3191       1.5    cegger 	switch (ins) {
   3192       1.5    cegger 	case ACPI_WDAT_READ_VALUE:
   3193       1.5    cegger 		printf("READ_VALUE");
   3194       1.5    cegger 		break;
   3195       1.5    cegger 	case ACPI_WDAT_READ_COUNTDOWN:
   3196       1.5    cegger 		printf("READ_COUNTDOWN");
   3197       1.5    cegger 		break;
   3198       1.5    cegger 	case ACPI_WDAT_WRITE_VALUE:
   3199       1.5    cegger 		printf("WRITE_VALUE");
   3200       1.5    cegger 		break;
   3201       1.5    cegger 	case ACPI_WDAT_WRITE_COUNTDOWN:
   3202       1.5    cegger 		printf("WRITE_COUNTDOWN");
   3203       1.5    cegger 		break;
   3204       1.5    cegger 	case ACPI_WDAT_INSTRUCTION_RESERVED:
   3205       1.5    cegger 		printf("INSTRUCTION_RESERVED");
   3206       1.5    cegger 		break;
   3207       1.5    cegger 	default:
   3208       1.5    cegger 		printf("%d", ins);
   3209       1.5    cegger 		break;
   3210       1.5    cegger 	}
   3211       1.5    cegger 
   3212       1.5    cegger 	if (whea->Instruction & ACPI_WDAT_PRESERVE_REGISTER)
   3213  1.15.8.1    martin 		printf(", Preserve Register");
   3214       1.5    cegger 
   3215       1.5    cegger 	printf("}\n");
   3216       1.5    cegger }
   3217       1.1  christos 
   3218       1.5    cegger static void
   3219       1.5    cegger acpi_handle_wdat(ACPI_TABLE_HEADER *sdp)
   3220       1.5    cegger {
   3221       1.5    cegger 	ACPI_TABLE_WDAT *wdat;
   3222       1.5    cegger 	ACPI_WHEA_HEADER *whea;
   3223  1.15.8.1    martin 	ACPI_WDAT_ENTRY *wdat_pos;
   3224       1.5    cegger 	u_int i;
   3225       1.1  christos 
   3226       1.5    cegger 	printf(BEGIN_COMMENT);
   3227       1.5    cegger 	acpi_print_sdt(sdp);
   3228       1.5    cegger 	wdat = (ACPI_TABLE_WDAT *)sdp;
   3229       1.1  christos 
   3230       1.5    cegger 	printf("\tHeader Length=%d\n", wdat->HeaderLength);
   3231       1.1  christos 
   3232  1.15.8.1    martin 	acpi_print_pci_sbdf(wdat->PciSegment, wdat->PciBus, wdat->PciDevice,
   3233       1.5    cegger 	    wdat->PciFunction);
   3234       1.5    cegger 	printf("\n\tTimer Counter Period=%d msec\n", wdat->TimerPeriod);
   3235       1.5    cegger 	printf("\tTimer Maximum Counter Value=%d\n", wdat->MaxCount);
   3236       1.5    cegger 	printf("\tTimer Minimum Counter Value=%d\n", wdat->MinCount);
   3237       1.5    cegger 
   3238       1.5    cegger 	printf("\tFlags={");
   3239       1.5    cegger 	if (wdat->Flags & ACPI_WDAT_ENABLED)
   3240       1.5    cegger 		printf("ENABLED");
   3241       1.5    cegger 	if (wdat->Flags & ACPI_WDAT_STOPPED)
   3242       1.5    cegger 		printf(", STOPPED");
   3243       1.5    cegger 	printf("}\n");
   3244       1.1  christos 
   3245  1.15.8.1    martin 	wdat_pos = (ACPI_WDAT_ENTRY *)((char *)wdat + sizeof(ACPI_TABLE_WDAT));
   3246       1.1  christos 
   3247       1.5    cegger 	for (i = 0; i < wdat->Entries; i++) {
   3248       1.5    cegger 		whea = (ACPI_WHEA_HEADER *)wdat_pos;
   3249       1.5    cegger 		acpi_print_whea(whea,
   3250       1.5    cegger 		    acpi_print_wdat_action, acpi_print_wdat_instruction,
   3251       1.5    cegger 		    NULL);
   3252  1.15.8.1    martin 		wdat_pos++;
   3253       1.5    cegger 	}
   3254       1.5    cegger 	printf(END_COMMENT);
   3255       1.1  christos }
   3256       1.5    cegger 
   3257       1.5    cegger static void
   3258  1.15.8.1    martin acpi_handle_wddt(ACPI_TABLE_HEADER *sdp)
   3259  1.15.8.1    martin {
   3260  1.15.8.1    martin 	ACPI_TABLE_WDDT *wddt;
   3261  1.15.8.1    martin 
   3262  1.15.8.1    martin 	printf(BEGIN_COMMENT);
   3263  1.15.8.1    martin 	acpi_print_sdt(sdp);
   3264  1.15.8.1    martin 	wddt = (ACPI_TABLE_WDDT *)sdp;
   3265  1.15.8.1    martin 
   3266  1.15.8.1    martin 	printf("\tSpecVersion=%04hx\n", wddt->SpecVersion);
   3267  1.15.8.1    martin 	printf("\tTableVersion=%04hx\n", wddt->TableVersion);
   3268  1.15.8.1    martin 	printf("\tPciVendorID=%04hx\n", wddt->PciVendorId);
   3269  1.15.8.1    martin 	printf("\tAddress=");
   3270  1.15.8.1    martin 	acpi_print_gas(&wddt->Address);
   3271  1.15.8.1    martin 	printf("\n\tTimer Maximum Counter Value=%d\n", wddt->MaxCount);
   3272  1.15.8.1    martin 	printf("\tTimer Minimum Counter Value=%d\n", wddt->MinCount);
   3273  1.15.8.1    martin 	printf("\tTimer Counter Period=%d\n", wddt->Period);
   3274  1.15.8.1    martin 
   3275  1.15.8.1    martin #define PRINTFLAG(var, flag)	printflag((var), ACPI_WDDT_## flag, #flag)
   3276  1.15.8.1    martin 
   3277  1.15.8.1    martin 	printf("\tStatus=");
   3278  1.15.8.1    martin 	PRINTFLAG(wddt->Status, AVAILABLE);
   3279  1.15.8.1    martin 	PRINTFLAG(wddt->Status, ACTIVE);
   3280  1.15.8.1    martin 	PRINTFLAG(wddt->Status, TCO_OS_OWNED);
   3281  1.15.8.1    martin 	PRINTFLAG(wddt->Status, USER_RESET);
   3282  1.15.8.1    martin 	PRINTFLAG(wddt->Status, WDT_RESET);
   3283  1.15.8.1    martin 	PRINTFLAG(wddt->Status, POWER_FAIL);
   3284  1.15.8.1    martin 	PRINTFLAG(wddt->Status, UNKNOWN_RESET);
   3285  1.15.8.1    martin 	PRINTFLAG_END();
   3286  1.15.8.1    martin 
   3287  1.15.8.1    martin 	printf("\tCapability=");
   3288  1.15.8.1    martin 	PRINTFLAG(wddt->Capability, AUTO_RESET);
   3289  1.15.8.1    martin 	PRINTFLAG(wddt->Capability, ALERT_SUPPORT);
   3290  1.15.8.1    martin 	PRINTFLAG_END();
   3291  1.15.8.1    martin 
   3292  1.15.8.1    martin #undef PRINTFLAG
   3293  1.15.8.1    martin 
   3294  1.15.8.1    martin 	printf(END_COMMENT);
   3295  1.15.8.1    martin }
   3296  1.15.8.1    martin 
   3297  1.15.8.1    martin static void
   3298       1.5    cegger acpi_handle_wdrt(ACPI_TABLE_HEADER *sdp)
   3299       1.1  christos {
   3300       1.5    cegger 	ACPI_TABLE_WDRT *wdrt;
   3301       1.1  christos 
   3302       1.1  christos 	printf(BEGIN_COMMENT);
   3303       1.5    cegger 	acpi_print_sdt(sdp);
   3304       1.5    cegger 	wdrt = (ACPI_TABLE_WDRT *)sdp;
   3305       1.5    cegger 
   3306       1.5    cegger 	printf("\tControl Register=");
   3307       1.5    cegger 	acpi_print_gas(&wdrt->ControlRegister);
   3308       1.5    cegger 	printf("\tCount Register=");
   3309       1.5    cegger 	acpi_print_gas(&wdrt->CountRegister);
   3310       1.5    cegger 	acpi_print_pci(wdrt->PciVendorId, wdrt->PciDeviceId,
   3311       1.5    cegger 	    wdrt->PciSegment, wdrt->PciBus, wdrt->PciDevice, wdrt->PciFunction);
   3312       1.5    cegger 
   3313       1.5    cegger 	/* Value must be >= 511 and < 65535 */
   3314       1.5    cegger 	printf("\tMaxCount=%d", wdrt->MaxCount);
   3315       1.5    cegger 	if (wdrt->MaxCount < 511)
   3316       1.5    cegger 		printf(" (Out of Range. Valid range: 511 <= maxcount < 65535)");
   3317       1.5    cegger 	printf("\n");
   3318       1.5    cegger 
   3319       1.5    cegger 	printf("\tUnit={");
   3320       1.5    cegger 	switch (wdrt->Units) {
   3321       1.5    cegger 	case 0:
   3322       1.5    cegger 		printf("1 seconds/count");
   3323       1.5    cegger 		break;
   3324       1.5    cegger 	case 1:
   3325       1.5    cegger 		printf("100 milliseconds/count");
   3326       1.5    cegger 		break;
   3327       1.5    cegger 	case 2:
   3328       1.5    cegger 		printf("10 milliseconds/count");
   3329       1.5    cegger 		break;
   3330       1.5    cegger 	default:
   3331       1.5    cegger 		printf("%d", wdrt->Units);
   3332       1.5    cegger 		break;
   3333       1.5    cegger 	}
   3334       1.5    cegger 	printf("}\n");
   3335       1.5    cegger 
   3336       1.5    cegger 	printf(END_COMMENT);
   3337       1.5    cegger }
   3338       1.5    cegger 
   3339       1.5    cegger static void
   3340       1.5    cegger acpi_print_sdt(ACPI_TABLE_HEADER *sdp)
   3341       1.5    cegger {
   3342       1.5    cegger 	printf("  ");
   3343       1.5    cegger 	acpi_print_string(sdp->Signature, ACPI_NAME_SIZE);
   3344       1.8  jmcneill 	printf(": Length=%d, Revision=%d, Checksum=%d",
   3345       1.5    cegger 	       sdp->Length, sdp->Revision, sdp->Checksum);
   3346       1.8  jmcneill 	if (acpi_checksum(sdp, sdp->Length))
   3347       1.8  jmcneill 		printf(" (Incorrect)");
   3348       1.8  jmcneill 	printf(",\n\tOEMID=");
   3349       1.5    cegger 	acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE);
   3350       1.1  christos 	printf(", OEM Table ID=");
   3351       1.5    cegger 	acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
   3352       1.5    cegger 	printf(", OEM Revision=0x%x,\n", sdp->OemRevision);
   3353       1.1  christos 	printf("\tCreator ID=");
   3354       1.5    cegger 	acpi_print_string(sdp->AslCompilerId, ACPI_NAME_SIZE);
   3355       1.5    cegger 	printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision);
   3356       1.1  christos }
   3357       1.1  christos 
   3358  1.15.8.2    martin void
   3359  1.15.8.2    martin acpi_print_tabs(unsigned int n)
   3360  1.15.8.2    martin {
   3361  1.15.8.2    martin 
   3362  1.15.8.2    martin 	while (n-- > 0)
   3363  1.15.8.2    martin 		printf("\t");
   3364  1.15.8.2    martin }
   3365  1.15.8.2    martin 
   3366       1.5    cegger static void
   3367  1.15.8.2    martin acpi_dump_bytes(uint8_t *p, uint32_t len, unsigned int ntabs)
   3368       1.7  jmcneill {
   3369       1.7  jmcneill 	unsigned int i;
   3370       1.7  jmcneill 
   3371  1.15.8.2    martin 	acpi_print_tabs(ntabs);
   3372  1.15.8.2    martin 	printf("Data={");
   3373  1.15.8.2    martin 	for (i = 0; i < len; i++) {
   3374       1.7  jmcneill 		if (cflag) {
   3375  1.15.8.2    martin 			if (i % 64 == 0) {
   3376  1.15.8.2    martin 				printf("\n");
   3377  1.15.8.2    martin 				acpi_print_tabs(ntabs);
   3378  1.15.8.2    martin 				printf(" ");
   3379  1.15.8.2    martin 			}else if (i % 16 == 0)
   3380       1.7  jmcneill 				printf(" ");
   3381       1.7  jmcneill 			printf("%c", (p[i] >= ' ' && p[i] <= '~') ? p[i] : '.');
   3382       1.7  jmcneill 		} else {
   3383  1.15.8.2    martin 			if (i % 16 == 0) {
   3384  1.15.8.2    martin 				printf("\n");
   3385  1.15.8.2    martin 				acpi_print_tabs(ntabs + 1);
   3386  1.15.8.2    martin 			} else if (i % 8 == 0)
   3387       1.7  jmcneill 				printf("   ");
   3388       1.7  jmcneill 			printf(" %02x", p[i]);
   3389       1.7  jmcneill 		}
   3390       1.7  jmcneill 	}
   3391  1.15.8.2    martin 	printf("\n");
   3392  1.15.8.2    martin 	acpi_print_tabs(ntabs);
   3393  1.15.8.2    martin 	printf("}\n");
   3394  1.15.8.2    martin }
   3395  1.15.8.2    martin 
   3396  1.15.8.2    martin /* Dump data which has ACPI_TABLE_HEADER */
   3397  1.15.8.2    martin static void
   3398  1.15.8.2    martin acpi_dump_table(ACPI_TABLE_HEADER *sdp)
   3399  1.15.8.2    martin {
   3400  1.15.8.2    martin 
   3401  1.15.8.2    martin 	acpi_dump_bytes((uint8_t *)sdp, sdp->Length, 1);
   3402       1.7  jmcneill }
   3403       1.7  jmcneill 
   3404       1.7  jmcneill static void
   3405       1.5    cegger acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp)
   3406       1.1  christos {
   3407       1.5    cegger 	ACPI_TABLE_RSDT *rsdt;
   3408       1.5    cegger 	ACPI_TABLE_XSDT *xsdt;
   3409       1.1  christos 	int	i, entries;
   3410       1.1  christos 
   3411       1.5    cegger 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
   3412       1.5    cegger 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
   3413       1.5    cegger 	printf(BEGIN_COMMENT);
   3414       1.1  christos 	acpi_print_sdt(rsdp);
   3415       1.5    cegger 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
   3416       1.1  christos 	printf("\tEntries={ ");
   3417       1.1  christos 	for (i = 0; i < entries; i++) {
   3418       1.1  christos 		if (i > 0)
   3419       1.1  christos 			printf(", ");
   3420  1.15.8.1    martin 		if (addr_size == 4)
   3421  1.15.8.1    martin 			printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i]));
   3422  1.15.8.1    martin 		else
   3423  1.15.8.1    martin 			printf("0x%016jx",
   3424  1.15.8.1    martin 			    (uintmax_t)le64toh(xsdt->TableOffsetEntry[i]));
   3425       1.1  christos 	}
   3426       1.1  christos 	printf(" }\n");
   3427       1.1  christos 	printf(END_COMMENT);
   3428       1.1  christos }
   3429       1.1  christos 
   3430       1.5    cegger static const char *acpi_pm_profiles[] = {
   3431       1.5    cegger 	"Unspecified", "Desktop", "Mobile", "Workstation",
   3432  1.15.8.1    martin 	"Enterprise Server", "SOHO Server", "Appliance PC",
   3433  1.15.8.1    martin 	"Performance Server", "Tablet"
   3434       1.5    cegger };
   3435       1.5    cegger 
   3436       1.5    cegger static void
   3437       1.5    cegger acpi_print_fadt(ACPI_TABLE_HEADER *sdp)
   3438       1.1  christos {
   3439       1.5    cegger 	ACPI_TABLE_FADT *fadt;
   3440       1.5    cegger 	const char *pm;
   3441       1.1  christos 
   3442       1.5    cegger 	fadt = (ACPI_TABLE_FADT *)sdp;
   3443       1.1  christos 	printf(BEGIN_COMMENT);
   3444       1.5    cegger 	acpi_print_sdt(sdp);
   3445       1.5    cegger 	printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs,
   3446       1.5    cegger 	       fadt->Dsdt);
   3447  1.15.8.1    martin 	/* XXX ACPI 2.0 eliminated this */
   3448       1.5    cegger 	printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC");
   3449       1.5    cegger 	if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *))
   3450       1.5    cegger 		pm = "Reserved";
   3451       1.5    cegger 	else
   3452       1.5    cegger 		pm = acpi_pm_profiles[fadt->PreferredProfile];
   3453       1.5    cegger 	printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile);
   3454       1.5    cegger 	printf("\tSCI_INT=%d\n", fadt->SciInterrupt);
   3455       1.5    cegger 	printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand);
   3456       1.5    cegger 	printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable);
   3457       1.5    cegger 	printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable);
   3458       1.5    cegger 	printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest);
   3459       1.5    cegger 	printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl);
   3460       1.5    cegger 	printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
   3461       1.5    cegger 	       fadt->Pm1aEventBlock,
   3462       1.5    cegger 	       fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1);
   3463       1.5    cegger 	if (fadt->Pm1bEventBlock != 0)
   3464       1.1  christos 		printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
   3465       1.5    cegger 		       fadt->Pm1bEventBlock,
   3466       1.5    cegger 		       fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1);
   3467       1.5    cegger 	printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
   3468       1.5    cegger 	       fadt->Pm1aControlBlock,
   3469       1.5    cegger 	       fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1);
   3470       1.5    cegger 	if (fadt->Pm1bControlBlock != 0)
   3471       1.1  christos 		printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
   3472       1.5    cegger 		       fadt->Pm1bControlBlock,
   3473       1.5    cegger 		       fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1);
   3474       1.5    cegger 	if (fadt->Pm2ControlBlock != 0)
   3475       1.1  christos 		printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
   3476       1.5    cegger 		       fadt->Pm2ControlBlock,
   3477       1.5    cegger 		       fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1);
   3478  1.15.8.2    martin 	if (fadt->PmTimerBlock != 0)
   3479  1.15.8.2    martin 		printf("\tPM_TMR_BLK=0x%x-0x%x\n",
   3480  1.15.8.2    martin 		    fadt->PmTimerBlock,
   3481  1.15.8.2    martin 		    fadt->PmTimerBlock + fadt->PmTimerLength - 1);
   3482       1.5    cegger 	if (fadt->Gpe0Block != 0)
   3483       1.5    cegger 		printf("\tGPE0_BLK=0x%x-0x%x\n",
   3484       1.5    cegger 		       fadt->Gpe0Block,
   3485       1.5    cegger 		       fadt->Gpe0Block + fadt->Gpe0BlockLength - 1);
   3486       1.5    cegger 	if (fadt->Gpe1Block != 0)
   3487       1.5    cegger 		printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
   3488       1.5    cegger 		       fadt->Gpe1Block,
   3489       1.5    cegger 		       fadt->Gpe1Block + fadt->Gpe1BlockLength - 1,
   3490       1.5    cegger 		       fadt->Gpe1Base);
   3491       1.5    cegger 	if (fadt->CstControl != 0)
   3492       1.5    cegger 		printf("\tCST_CNT=0x%x\n", fadt->CstControl);
   3493       1.5    cegger 	printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
   3494       1.5    cegger 	       fadt->C2Latency, fadt->C3Latency);
   3495       1.1  christos 	printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
   3496       1.5    cegger 	       fadt->FlushSize, fadt->FlushStride);
   3497       1.1  christos 	printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
   3498       1.5    cegger 	       fadt->DutyOffset, fadt->DutyWidth);
   3499       1.1  christos 	printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
   3500       1.5    cegger 	       fadt->DayAlarm, fadt->MonthAlarm, fadt->Century);
   3501       1.1  christos 
   3502  1.15.8.1    martin #define PRINTFLAG(var, flag)	printflag((var), ACPI_FADT_## flag, #flag)
   3503       1.1  christos 
   3504       1.5    cegger 	printf("\tIAPC_BOOT_ARCH=");
   3505       1.5    cegger 	PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES);
   3506       1.5    cegger 	PRINTFLAG(fadt->BootFlags, 8042);
   3507       1.5    cegger 	PRINTFLAG(fadt->BootFlags, NO_VGA);
   3508       1.5    cegger 	PRINTFLAG(fadt->BootFlags, NO_MSI);
   3509       1.5    cegger 	PRINTFLAG(fadt->BootFlags, NO_ASPM);
   3510  1.15.8.1    martin 	PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC);
   3511  1.15.8.1    martin 	PRINTFLAG_END();
   3512       1.5    cegger 
   3513       1.5    cegger 	printf("\tFlags=");
   3514       1.5    cegger 	PRINTFLAG(fadt->Flags, WBINVD);
   3515       1.5    cegger 	PRINTFLAG(fadt->Flags, WBINVD_FLUSH);
   3516       1.5    cegger 	PRINTFLAG(fadt->Flags, C1_SUPPORTED);
   3517       1.5    cegger 	PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED);
   3518       1.5    cegger 	PRINTFLAG(fadt->Flags, POWER_BUTTON);
   3519       1.5    cegger 	PRINTFLAG(fadt->Flags, SLEEP_BUTTON);
   3520       1.5    cegger 	PRINTFLAG(fadt->Flags, FIXED_RTC);
   3521       1.5    cegger 	PRINTFLAG(fadt->Flags, S4_RTC_WAKE);
   3522       1.5    cegger 	PRINTFLAG(fadt->Flags, 32BIT_TIMER);
   3523       1.5    cegger 	PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED);
   3524       1.5    cegger 	PRINTFLAG(fadt->Flags, RESET_REGISTER);
   3525       1.5    cegger 	PRINTFLAG(fadt->Flags, SEALED_CASE);
   3526       1.5    cegger 	PRINTFLAG(fadt->Flags, HEADLESS);
   3527       1.5    cegger 	PRINTFLAG(fadt->Flags, SLEEP_TYPE);
   3528       1.5    cegger 	PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE);
   3529       1.5    cegger 	PRINTFLAG(fadt->Flags, PLATFORM_CLOCK);
   3530       1.5    cegger 	PRINTFLAG(fadt->Flags, S4_RTC_VALID);
   3531       1.5    cegger 	PRINTFLAG(fadt->Flags, REMOTE_POWER_ON);
   3532       1.5    cegger 	PRINTFLAG(fadt->Flags, APIC_CLUSTER);
   3533       1.5    cegger 	PRINTFLAG(fadt->Flags, APIC_PHYSICAL);
   3534  1.15.8.1    martin 	PRINTFLAG(fadt->Flags, HW_REDUCED);
   3535  1.15.8.1    martin 	PRINTFLAG(fadt->Flags, LOW_POWER_S0);
   3536  1.15.8.1    martin 	PRINTFLAG_END();
   3537       1.1  christos 
   3538  1.15.8.1    martin 	if (sdp->Length < ACPI_FADT_V2_SIZE)
   3539  1.15.8.1    martin 		goto out;
   3540       1.1  christos 
   3541       1.5    cegger 	if (fadt->Flags & ACPI_FADT_RESET_REGISTER) {
   3542       1.5    cegger 		printf("\tRESET_REG=");
   3543       1.5    cegger 		acpi_print_gas(&fadt->ResetRegister);
   3544       1.5    cegger 		printf(", RESET_VALUE=%#x\n", fadt->ResetValue);
   3545       1.5    cegger 	}
   3546  1.15.8.1    martin 
   3547  1.15.8.1    martin 	printf("\tArmBootFlags=");
   3548  1.15.8.1    martin 	PRINTFLAG(fadt->ArmBootFlags, PSCI_COMPLIANT);
   3549  1.15.8.1    martin 	PRINTFLAG(fadt->ArmBootFlags, PSCI_USE_HVC);
   3550  1.15.8.1    martin 	PRINTFLAG_END();
   3551  1.15.8.1    martin 
   3552  1.15.8.1    martin #undef PRINTFLAG
   3553  1.15.8.1    martin 
   3554  1.15.8.1    martin 	printf("\tMinorRevision=%u\n", fadt->MinorRevision);
   3555  1.15.8.1    martin 
   3556  1.15.8.1    martin 	if (sdp->Length < ACPI_FADT_V3_SIZE)
   3557  1.15.8.1    martin 		goto out;
   3558  1.15.8.1    martin 
   3559  1.15.8.1    martin 	printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs);
   3560  1.15.8.1    martin 	printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt);
   3561  1.15.8.1    martin 	printf("\tX_PM1a_EVT_BLK=");
   3562  1.15.8.1    martin 	acpi_print_gas(&fadt->XPm1aEventBlock);
   3563  1.15.8.1    martin 	if (fadt->XPm1bEventBlock.Address != 0) {
   3564  1.15.8.1    martin 		printf("\n\tX_PM1b_EVT_BLK=");
   3565  1.15.8.1    martin 		acpi_print_gas(&fadt->XPm1bEventBlock);
   3566  1.15.8.1    martin 	}
   3567  1.15.8.1    martin 	printf("\n\tX_PM1a_CNT_BLK=");
   3568  1.15.8.1    martin 	acpi_print_gas(&fadt->XPm1aControlBlock);
   3569  1.15.8.1    martin 	if (fadt->XPm1bControlBlock.Address != 0) {
   3570  1.15.8.1    martin 		printf("\n\tX_PM1b_CNT_BLK=");
   3571  1.15.8.1    martin 		acpi_print_gas(&fadt->XPm1bControlBlock);
   3572  1.15.8.1    martin 	}
   3573  1.15.8.1    martin 	if (fadt->XPm2ControlBlock.Address != 0) {
   3574  1.15.8.1    martin 		printf("\n\tX_PM2_CNT_BLK=");
   3575  1.15.8.1    martin 		acpi_print_gas(&fadt->XPm2ControlBlock);
   3576  1.15.8.1    martin 	}
   3577  1.15.8.2    martin 	if (fadt->XPmTimerBlock.Address != 0) {
   3578  1.15.8.2    martin 		printf("\n\tX_PM_TMR_BLK=");
   3579  1.15.8.2    martin 		acpi_print_gas(&fadt->XPmTimerBlock);
   3580  1.15.8.2    martin 	}
   3581  1.15.8.1    martin 	if (fadt->XGpe0Block.Address != 0) {
   3582  1.15.8.1    martin 		printf("\n\tX_GPE0_BLK=");
   3583  1.15.8.1    martin 		acpi_print_gas(&fadt->XGpe0Block);
   3584  1.15.8.1    martin 	}
   3585  1.15.8.1    martin 	if (fadt->XGpe1Block.Address != 0) {
   3586  1.15.8.1    martin 		printf("\n\tX_GPE1_BLK=");
   3587  1.15.8.1    martin 		acpi_print_gas(&fadt->XGpe1Block);
   3588  1.15.8.1    martin 	}
   3589  1.15.8.1    martin 	printf("\n");
   3590  1.15.8.1    martin 
   3591  1.15.8.1    martin 	if (sdp->Length < ACPI_FADT_V5_SIZE)
   3592  1.15.8.1    martin 		goto out;
   3593  1.15.8.1    martin 
   3594  1.15.8.1    martin 	if (fadt->SleepControl.Address != 0) {
   3595  1.15.8.1    martin 		printf("\tSleepControl=");
   3596  1.15.8.1    martin 		acpi_print_gas(&fadt->SleepControl);
   3597       1.5    cegger 		printf("\n");
   3598       1.5    cegger 	}
   3599  1.15.8.1    martin 	if (fadt->SleepStatus.Address != 0) {
   3600  1.15.8.1    martin 		printf("\n\tSleepStatus=");
   3601  1.15.8.1    martin 		acpi_print_gas(&fadt->SleepStatus);
   3602  1.15.8.1    martin 		printf("\n");
   3603  1.15.8.1    martin 	}
   3604  1.15.8.1    martin 
   3605  1.15.8.1    martin 	if (sdp->Length < ACPI_FADT_V6_SIZE)
   3606  1.15.8.1    martin 		goto out;
   3607       1.5    cegger 
   3608  1.15.8.1    martin 	printf("\tHypervisorId=0x%016"PRIx64"\n", fadt->HypervisorId);
   3609  1.15.8.1    martin 
   3610  1.15.8.1    martin out:
   3611       1.1  christos 	printf(END_COMMENT);
   3612       1.1  christos }
   3613       1.1  christos 
   3614       1.5    cegger static void
   3615       1.5    cegger acpi_print_facs(ACPI_TABLE_FACS *facs)
   3616       1.1  christos {
   3617       1.5    cegger 	printf(BEGIN_COMMENT);
   3618       1.5    cegger 	printf("  FACS:\tLength=%u, ", facs->Length);
   3619       1.5    cegger 	printf("HwSig=0x%08x, ", facs->HardwareSignature);
   3620       1.5    cegger 	printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector);
   3621       1.5    cegger 
   3622  1.15.8.1    martin #define PRINTFLAG(var, flag)	printflag((var), ACPI_GLOCK_## flag, #flag)
   3623  1.15.8.1    martin 
   3624       1.5    cegger 	printf("\tGlobal_Lock=");
   3625  1.15.8.1    martin 	PRINTFLAG(facs->GlobalLock, PENDING);
   3626  1.15.8.1    martin 	PRINTFLAG(facs->GlobalLock, OWNED);
   3627  1.15.8.1    martin 	PRINTFLAG_END();
   3628  1.15.8.1    martin 
   3629  1.15.8.1    martin #undef PRINTFLAG
   3630  1.15.8.1    martin 
   3631  1.15.8.1    martin #define PRINTFLAG(var, flag)	printflag((var), ACPI_FACS_## flag, #flag)
   3632       1.5    cegger 
   3633       1.5    cegger 	printf("\tFlags=");
   3634  1.15.8.1    martin 	PRINTFLAG(facs->Flags, S4_BIOS_PRESENT);
   3635  1.15.8.1    martin 	PRINTFLAG(facs->Flags, 64BIT_WAKE);
   3636  1.15.8.1    martin 	PRINTFLAG_END();
   3637       1.5    cegger 
   3638  1.15.8.1    martin #undef PRINTFLAG
   3639  1.15.8.1    martin 
   3640  1.15.8.1    martin 	if (facs->XFirmwareWakingVector != 0)
   3641  1.15.8.1    martin 		printf("\tX_Firm_Wake_Vec=%016jx\n",
   3642  1.15.8.1    martin 		    (uintmax_t)facs->XFirmwareWakingVector);
   3643       1.5    cegger 	printf("\tVersion=%u\n", facs->Version);
   3644       1.5    cegger 
   3645  1.15.8.1    martin 	printf("\tOspmFlags={");
   3646  1.15.8.1    martin 	if (facs->OspmFlags & ACPI_FACS_64BIT_ENVIRONMENT)
   3647  1.15.8.1    martin 		printf("64BIT_WAKE");
   3648  1.15.8.1    martin 	printf("}\n");
   3649  1.15.8.1    martin 
   3650       1.5    cegger 	printf(END_COMMENT);
   3651       1.5    cegger }
   3652       1.1  christos 
   3653       1.5    cegger static void
   3654       1.5    cegger acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp)
   3655       1.5    cegger {
   3656       1.5    cegger 	printf(BEGIN_COMMENT);
   3657       1.1  christos 	acpi_print_sdt(dsdp);
   3658       1.5    cegger 	printf(END_COMMENT);
   3659       1.1  christos }
   3660       1.1  christos 
   3661       1.1  christos int
   3662       1.1  christos acpi_checksum(void *p, size_t length)
   3663       1.1  christos {
   3664       1.5    cegger 	uint8_t *bp;
   3665       1.5    cegger 	uint8_t sum;
   3666       1.1  christos 
   3667       1.1  christos 	bp = p;
   3668       1.1  christos 	sum = 0;
   3669       1.1  christos 	while (length--)
   3670       1.1  christos 		sum += *bp++;
   3671       1.1  christos 
   3672       1.1  christos 	return (sum);
   3673       1.1  christos }
   3674       1.1  christos 
   3675       1.5    cegger static ACPI_TABLE_HEADER *
   3676       1.1  christos acpi_map_sdt(vm_offset_t pa)
   3677       1.1  christos {
   3678       1.5    cegger 	ACPI_TABLE_HEADER *sp;
   3679       1.1  christos 
   3680       1.5    cegger 	sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER));
   3681       1.5    cegger 	sp = acpi_map_physical(pa, sp->Length);
   3682       1.1  christos 	return (sp);
   3683       1.1  christos }
   3684       1.1  christos 
   3685       1.5    cegger static void
   3686       1.5    cegger acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp)
   3687       1.1  christos {
   3688       1.1  christos 	printf(BEGIN_COMMENT);
   3689       1.5    cegger 	printf("  RSD PTR: OEM=");
   3690       1.5    cegger 	acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE);
   3691       1.5    cegger 	printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x",
   3692       1.5    cegger 	       rp->Revision);
   3693       1.5    cegger 	if (rp->Revision < 2) {
   3694       1.5    cegger 		printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress,
   3695       1.5    cegger 		    rp->Checksum);
   3696       1.5    cegger 	} else {
   3697  1.15.8.1    martin 		printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n",
   3698  1.15.8.1    martin 		    (uintmax_t)rp->XsdtPhysicalAddress, rp->Length,
   3699       1.5    cegger 		    rp->ExtendedChecksum);
   3700       1.5    cegger 	}
   3701       1.1  christos 	printf(END_COMMENT);
   3702       1.1  christos }
   3703       1.1  christos 
   3704       1.5    cegger static void
   3705       1.5    cegger acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
   3706       1.1  christos {
   3707       1.5    cegger 	ACPI_TABLE_HEADER *sdp;
   3708       1.5    cegger 	ACPI_TABLE_RSDT *rsdt;
   3709       1.5    cegger 	ACPI_TABLE_XSDT *xsdt;
   3710      1.15  christos 	vm_offset_t addr = 0;
   3711       1.5    cegger 	int entries, i;
   3712       1.1  christos 
   3713       1.1  christos 	acpi_print_rsdt(rsdp);
   3714       1.5    cegger 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
   3715       1.5    cegger 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
   3716       1.5    cegger 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
   3717       1.1  christos 	for (i = 0; i < entries; i++) {
   3718  1.15.8.1    martin 		if (addr_size == 4)
   3719       1.5    cegger 			addr = le32toh(rsdt->TableOffsetEntry[i]);
   3720  1.15.8.1    martin 		else
   3721       1.5    cegger 			addr = le64toh(xsdt->TableOffsetEntry[i]);
   3722  1.15.8.1    martin 		if (addr == 0)
   3723  1.15.8.1    martin 			continue;
   3724       1.5    cegger 		sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
   3725       1.5    cegger 		if (acpi_checksum(sdp, sdp->Length)) {
   3726       1.5    cegger 			warnx("RSDT entry %d (sig %.4s) is corrupt", i,
   3727       1.5    cegger 			    sdp->Signature);
   3728       1.8  jmcneill 			if (sflag)
   3729       1.8  jmcneill 				continue;
   3730       1.4  drochner 		}
   3731       1.5    cegger 		if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4))
   3732       1.5    cegger 			acpi_handle_fadt(sdp);
   3733       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_BERT, 4))
   3734       1.5    cegger 			acpi_handle_bert(sdp);
   3735       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_BOOT, 4))
   3736       1.5    cegger 			acpi_handle_boot(sdp);
   3737       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_CPEP, 4))
   3738       1.5    cegger 			acpi_handle_cpep(sdp);
   3739  1.15.8.2    martin 		else if (!memcmp(sdp->Signature, ACPI_SIG_CSRT, 4))
   3740  1.15.8.2    martin 			acpi_handle_csrt(sdp);
   3741       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_DBGP, 4))
   3742       1.5    cegger 			acpi_handle_dbgp(sdp);
   3743  1.15.8.1    martin 		else if (!memcmp(sdp->Signature, ACPI_SIG_DBG2, 4))
   3744  1.15.8.1    martin 			acpi_handle_dbg2(sdp);
   3745  1.15.8.1    martin 		else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4))
   3746  1.15.8.1    martin 			acpi_handle_dmar(sdp);
   3747       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_EINJ, 4))
   3748       1.5    cegger 			acpi_handle_einj(sdp);
   3749       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_ERST, 4))
   3750       1.5    cegger 			acpi_handle_erst(sdp);
   3751  1.15.8.2    martin 		else if (!memcmp(sdp->Signature, ACPI_SIG_GTDT, 4))
   3752  1.15.8.2    martin 			acpi_handle_gtdt(sdp);
   3753       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4))
   3754       1.5    cegger 			acpi_handle_madt(sdp);
   3755       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_MSCT, 4))
   3756       1.5    cegger 			acpi_handle_msct(sdp);
   3757       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_HEST, 4))
   3758       1.5    cegger 			acpi_handle_hest(sdp);
   3759       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4))
   3760       1.5    cegger 			acpi_handle_hpet(sdp);
   3761       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4))
   3762       1.5    cegger 			acpi_handle_ecdt(sdp);
   3763  1.15.8.2    martin 		else if (!memcmp(sdp->Signature, ACPI_SIG_LPIT, 4))
   3764  1.15.8.2    martin 			acpi_handle_lpit(sdp);
   3765       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4))
   3766       1.5    cegger 			acpi_handle_mcfg(sdp);
   3767       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_SBST, 4))
   3768       1.5    cegger 			acpi_handle_sbst(sdp);
   3769       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4))
   3770       1.5    cegger 			acpi_handle_slit(sdp);
   3771       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_SPCR, 4))
   3772       1.5    cegger 			acpi_handle_spcr(sdp);
   3773  1.15.8.1    martin 		else if (!memcmp(sdp->Signature, ACPI_SIG_SPMI, 4))
   3774  1.15.8.1    martin 			acpi_handle_spmi(sdp);
   3775       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4))
   3776       1.5    cegger 			acpi_handle_srat(sdp);
   3777       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4))
   3778       1.5    cegger 			acpi_handle_tcpa(sdp);
   3779  1.15.8.1    martin 		else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4))
   3780  1.15.8.1    martin 			acpi_handle_nfit(sdp);
   3781  1.15.8.1    martin 		else if (!memcmp(sdp->Signature, ACPI_SIG_UEFI, 4))
   3782  1.15.8.1    martin 			acpi_handle_uefi(sdp);
   3783       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_WAET, 4))
   3784       1.5    cegger 			acpi_handle_waet(sdp);
   3785       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_WDAT, 4))
   3786       1.5    cegger 			acpi_handle_wdat(sdp);
   3787  1.15.8.1    martin 		else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4))
   3788  1.15.8.1    martin 			acpi_handle_wddt(sdp);
   3789       1.5    cegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_WDRT, 4))
   3790       1.5    cegger 			acpi_handle_wdrt(sdp);
   3791       1.5    cegger 		else {
   3792       1.5    cegger 			printf(BEGIN_COMMENT);
   3793       1.1  christos 			acpi_print_sdt(sdp);
   3794  1.15.8.2    martin 			printf("\n");
   3795  1.15.8.2    martin 			acpi_dump_table(sdp);
   3796       1.5    cegger 			printf(END_COMMENT);
   3797       1.1  christos 		}
   3798       1.1  christos 	}
   3799       1.1  christos }
   3800       1.1  christos 
   3801       1.5    cegger ACPI_TABLE_HEADER *
   3802       1.5    cegger sdt_load_devmem(void)
   3803       1.5    cegger {
   3804       1.5    cegger 	ACPI_TABLE_RSDP *rp;
   3805       1.5    cegger 	ACPI_TABLE_HEADER *rsdp;
   3806       1.1  christos 
   3807       1.5    cegger 	rp = acpi_find_rsd_ptr();
   3808       1.5    cegger 	if (!rp)
   3809       1.5    cegger 		errx(EXIT_FAILURE, "Can't find ACPI information");
   3810       1.5    cegger 
   3811       1.5    cegger 	if (tflag)
   3812       1.5    cegger 		acpi_print_rsd_ptr(rp);
   3813       1.5    cegger 	if (rp->Revision < 2) {
   3814       1.5    cegger 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress);
   3815       1.5    cegger 		if (memcmp(rsdp->Signature, "RSDT", 4) != 0 ||
   3816       1.5    cegger 		    acpi_checksum(rsdp, rsdp->Length) != 0)
   3817       1.5    cegger 			errx(EXIT_FAILURE, "RSDT is corrupted");
   3818       1.5    cegger 		addr_size = sizeof(uint32_t);
   3819       1.5    cegger 	} else {
   3820       1.5    cegger 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress);
   3821       1.5    cegger 		if (memcmp(rsdp->Signature, "XSDT", 4) != 0 ||
   3822       1.5    cegger 		    acpi_checksum(rsdp, rsdp->Length) != 0)
   3823       1.5    cegger 			errx(EXIT_FAILURE, "XSDT is corrupted");
   3824       1.5    cegger 		addr_size = sizeof(uint64_t);
   3825       1.5    cegger 	}
   3826       1.5    cegger 	return (rsdp);
   3827       1.1  christos }
   3828       1.1  christos 
   3829       1.5    cegger /* Write the DSDT to a file, concatenating any SSDTs (if present). */
   3830       1.5    cegger static int
   3831       1.5    cegger write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt)
   3832       1.5    cegger {
   3833       1.5    cegger 	ACPI_TABLE_HEADER sdt;
   3834       1.5    cegger 	ACPI_TABLE_HEADER *ssdt;
   3835       1.5    cegger 	uint8_t sum;
   3836       1.5    cegger 
   3837       1.5    cegger 	/* Create a new checksum to account for the DSDT and any SSDTs. */
   3838       1.5    cegger 	sdt = *dsdt;
   3839       1.5    cegger 	if (rsdt != NULL) {
   3840       1.5    cegger 		sdt.Checksum = 0;
   3841       1.5    cegger 		sum = acpi_checksum(dsdt + 1, dsdt->Length -
   3842       1.5    cegger 		    sizeof(ACPI_TABLE_HEADER));
   3843       1.5    cegger 		ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL);
   3844       1.5    cegger 		while (ssdt != NULL) {
   3845       1.5    cegger 			sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER);
   3846       1.5    cegger 			sum += acpi_checksum(ssdt + 1,
   3847       1.5    cegger 			    ssdt->Length - sizeof(ACPI_TABLE_HEADER));
   3848       1.5    cegger 			ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt);
   3849       1.5    cegger 		}
   3850       1.5    cegger 		sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER));
   3851       1.5    cegger 		sdt.Checksum -= sum;
   3852       1.5    cegger 	}
   3853       1.5    cegger 
   3854       1.5    cegger 	/* Write out the DSDT header and body. */
   3855       1.5    cegger 	write(fd, &sdt, sizeof(ACPI_TABLE_HEADER));
   3856       1.5    cegger 	write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER));
   3857       1.5    cegger 
   3858       1.5    cegger 	/* Write out any SSDTs (if present.) */
   3859       1.5    cegger 	if (rsdt != NULL) {
   3860       1.5    cegger 		ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
   3861       1.5    cegger 		while (ssdt != NULL) {
   3862       1.5    cegger 			write(fd, ssdt + 1, ssdt->Length -
   3863       1.5    cegger 			    sizeof(ACPI_TABLE_HEADER));
   3864       1.5    cegger 			ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
   3865       1.5    cegger 		}
   3866       1.5    cegger 	}
   3867       1.1  christos 	return (0);
   3868       1.1  christos }
   3869       1.1  christos 
   3870       1.5    cegger void
   3871       1.5    cegger dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
   3872       1.1  christos {
   3873       1.5    cegger 	int	fd;
   3874       1.5    cegger 	mode_t	mode;
   3875       1.5    cegger 
   3876       1.5    cegger 	assert(outfile != NULL);
   3877       1.5    cegger 	mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
   3878       1.5    cegger 	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
   3879       1.5    cegger 	if (fd == -1) {
   3880       1.5    cegger 		perror("dsdt_save_file");
   3881       1.5    cegger 		return;
   3882       1.5    cegger 	}
   3883       1.5    cegger 	write_dsdt(fd, rsdt, dsdp);
   3884       1.5    cegger 	close(fd);
   3885       1.1  christos }
   3886       1.1  christos 
   3887       1.5    cegger void
   3888       1.5    cegger aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
   3889       1.1  christos {
   3890  1.15.8.1    martin 	char buf[MAXPATHLEN], tmpstr[MAXPATHLEN], wrkdir[MAXPATHLEN];
   3891  1.15.8.1    martin 	const char *iname = "/acpdump.din";
   3892  1.15.8.1    martin 	const char *oname = "/acpdump.dsl";
   3893       1.5    cegger 	const char *tmpdir;
   3894       1.5    cegger 	FILE *fp;
   3895       1.5    cegger 	size_t len;
   3896  1.15.8.1    martin 	int fd, status;
   3897  1.15.8.1    martin 	pid_t pid;
   3898       1.5    cegger 
   3899       1.5    cegger 	if (rsdt == NULL)
   3900       1.5    cegger 		errx(EXIT_FAILURE, "aml_disassemble: invalid rsdt");
   3901       1.5    cegger 	if (dsdp == NULL)
   3902       1.5    cegger 		errx(EXIT_FAILURE, "aml_disassemble: invalid dsdp");
   3903       1.5    cegger 
   3904       1.5    cegger 	tmpdir = getenv("TMPDIR");
   3905       1.5    cegger 	if (tmpdir == NULL)
   3906       1.5    cegger 		tmpdir = _PATH_TMP;
   3907  1.15.8.1    martin 	if (realpath(tmpdir, buf) == NULL) {
   3908  1.15.8.1    martin 		perror("realpath tmp dir");
   3909  1.15.8.1    martin 		return;
   3910  1.15.8.1    martin 	}
   3911  1.15.8.1    martin 	len = sizeof(wrkdir) - strlen(iname);
   3912  1.15.8.1    martin 	if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) {
   3913  1.15.8.1    martin 		fprintf(stderr, "$TMPDIR too long\n");
   3914  1.15.8.1    martin 		return;
   3915  1.15.8.1    martin 	}
   3916  1.15.8.1    martin 	if  (mkdtemp(wrkdir) == NULL) {
   3917  1.15.8.1    martin 		perror("mkdtemp tmp working dir");
   3918       1.5    cegger 		return;
   3919       1.5    cegger 	}
   3920  1.15.8.1    martin 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname);
   3921  1.15.8.1    martin 	assert(len <= sizeof(tmpstr) - 1);
   3922  1.15.8.1    martin 	fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
   3923       1.5    cegger 	if (fd < 0) {
   3924       1.5    cegger 		perror("iasl tmp file");
   3925       1.5    cegger 		return;
   3926       1.5    cegger 	}
   3927       1.5    cegger 	write_dsdt(fd, rsdt, dsdp);
   3928       1.5    cegger 	close(fd);
   3929       1.5    cegger 
   3930       1.5    cegger 	/* Run iasl -d on the temp file */
   3931  1.15.8.1    martin 	if ((pid = fork()) == 0) {
   3932       1.5    cegger 		close(STDOUT_FILENO);
   3933       1.5    cegger 		if (vflag == 0)
   3934       1.5    cegger 			close(STDERR_FILENO);
   3935       1.5    cegger 		execl("/usr/bin/iasl", "iasl", "-d", tmpstr, NULL);
   3936       1.5    cegger 		err(EXIT_FAILURE, "exec");
   3937       1.5    cegger 	}
   3938  1.15.8.1    martin 	if (pid > 0)
   3939  1.15.8.1    martin 		wait(&status);
   3940  1.15.8.1    martin 	if (unlink(tmpstr) < 0) {
   3941  1.15.8.1    martin 		perror("unlink");
   3942  1.15.8.1    martin 		goto out;
   3943  1.15.8.1    martin 	}
   3944  1.15.8.1    martin 	if (pid < 0) {
   3945  1.15.8.1    martin 		perror("fork");
   3946  1.15.8.1    martin 		goto out;
   3947  1.15.8.1    martin 	}
   3948  1.15.8.1    martin 	if (status != 0) {
   3949  1.15.8.1    martin 		fprintf(stderr, "iast exit status = %d\n", status);
   3950  1.15.8.1    martin 	}
   3951       1.1  christos 
   3952       1.5    cegger 	/* Dump iasl's output to stdout */
   3953  1.15.8.1    martin 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname);
   3954  1.15.8.1    martin 	assert(len <= sizeof(tmpstr) - 1);
   3955       1.5    cegger 	fp = fopen(tmpstr, "r");
   3956  1.15.8.1    martin 	if (unlink(tmpstr) < 0) {
   3957  1.15.8.1    martin 		perror("unlink");
   3958  1.15.8.1    martin 		goto out;
   3959  1.15.8.1    martin 	}
   3960       1.5    cegger 	if (fp == NULL) {
   3961       1.5    cegger 		perror("iasl tmp file (read)");
   3962  1.15.8.1    martin 		goto out;
   3963       1.5    cegger 	}
   3964       1.5    cegger 	while ((len = fread(buf, 1, sizeof(buf), fp)) > 0)
   3965       1.5    cegger 		fwrite(buf, 1, len, stdout);
   3966       1.5    cegger 	fclose(fp);
   3967  1.15.8.1    martin 
   3968  1.15.8.1    martin     out:
   3969  1.15.8.1    martin 	if (rmdir(wrkdir) < 0)
   3970  1.15.8.1    martin 		perror("rmdir");
   3971       1.1  christos }
   3972       1.1  christos 
   3973       1.5    cegger void
   3974       1.5    cegger sdt_print_all(ACPI_TABLE_HEADER *rsdp)
   3975       1.1  christos {
   3976       1.5    cegger 	acpi_handle_rsdt(rsdp);
   3977       1.1  christos }
   3978       1.1  christos 
   3979       1.5    cegger /* Fetch a table matching the given signature via the RSDT. */
   3980       1.5    cegger ACPI_TABLE_HEADER *
   3981       1.5    cegger sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last)
   3982       1.1  christos {
   3983       1.5    cegger 	ACPI_TABLE_HEADER *sdt;
   3984       1.5    cegger 	ACPI_TABLE_RSDT *rsdt;
   3985       1.5    cegger 	ACPI_TABLE_XSDT *xsdt;
   3986      1.15  christos 	vm_offset_t addr = 0;
   3987       1.5    cegger 	int entries, i;
   3988       1.1  christos 
   3989       1.5    cegger 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
   3990       1.5    cegger 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
   3991       1.5    cegger 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
   3992       1.5    cegger 	for (i = 0; i < entries; i++) {
   3993  1.15.8.1    martin 		if (addr_size == 4)
   3994       1.5    cegger 			addr = le32toh(rsdt->TableOffsetEntry[i]);
   3995  1.15.8.1    martin 		else
   3996       1.5    cegger 			addr = le64toh(xsdt->TableOffsetEntry[i]);
   3997  1.15.8.1    martin 		if (addr == 0)
   3998  1.15.8.1    martin 			continue;
   3999       1.5    cegger 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
   4000       1.5    cegger 		if (last != NULL) {
   4001       1.5    cegger 			if (sdt == last)
   4002       1.5    cegger 				last = NULL;
   4003       1.5    cegger 			continue;
   4004       1.5    cegger 		}
   4005       1.5    cegger 		if (memcmp(sdt->Signature, sig, strlen(sig)))
   4006       1.5    cegger 			continue;
   4007       1.5    cegger 		if (acpi_checksum(sdt, sdt->Length))
   4008       1.5    cegger 			errx(EXIT_FAILURE, "RSDT entry %d is corrupt", i);
   4009       1.5    cegger 		return (sdt);
   4010       1.5    cegger 	}
   4011       1.1  christos 
   4012       1.5    cegger 	return (NULL);
   4013       1.1  christos }
   4014       1.1  christos 
   4015       1.5    cegger ACPI_TABLE_HEADER *
   4016       1.5    cegger dsdt_from_fadt(ACPI_TABLE_FADT *fadt)
   4017       1.1  christos {
   4018       1.5    cegger 	ACPI_TABLE_HEADER	*sdt;
   4019       1.1  christos 
   4020       1.5    cegger 	/* Use the DSDT address if it is version 1, otherwise use XDSDT. */
   4021  1.15.8.1    martin 	sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(
   4022  1.15.8.1    martin 		acpi_select_address(fadt->Dsdt, fadt->XDsdt));
   4023       1.5    cegger 	if (acpi_checksum(sdt, sdt->Length))
   4024      1.10  christos 		errx(EXIT_FAILURE, "DSDT is corrupt");
   4025       1.5    cegger 	return (sdt);
   4026       1.1  christos }
   4027