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