acpi.c revision 1.18 1 1.18 msaitoh /* $NetBSD: acpi.c,v 1.18 2017/08/21 02:58:49 msaitoh 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.16 msaitoh * $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.18 msaitoh __RCSID("$NetBSD: acpi.c,v 1.18 2017/08/21 02:58:49 msaitoh 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.5 cegger #include <stdio.h>
44 1.5 cegger #include <stdint.h>
45 1.5 cegger #include <stdlib.h>
46 1.5 cegger #include <string.h>
47 1.5 cegger #include <unistd.h>
48 1.5 cegger #include <stddef.h>
49 1.5 cegger
50 1.5 cegger #include "acpidump.h"
51 1.5 cegger
52 1.5 cegger #define BEGIN_COMMENT "/*\n"
53 1.5 cegger #define END_COMMENT " */\n"
54 1.5 cegger
55 1.5 cegger static void acpi_print_string(char *s, size_t length);
56 1.5 cegger static void acpi_print_gas(ACPI_GENERIC_ADDRESS *gas);
57 1.5 cegger static void acpi_print_pci(uint16_t vendorid, uint16_t deviceid,
58 1.5 cegger uint8_t seg, uint8_t bus, uint8_t device, uint8_t func);
59 1.5 cegger static void acpi_print_pci_sbfd(uint8_t seg, uint8_t bus, uint8_t device,
60 1.5 cegger uint8_t func);
61 1.5 cegger #ifdef notyet
62 1.5 cegger static void acpi_print_hest_generic_status(ACPI_HEST_GENERIC_STATUS *);
63 1.5 cegger static void acpi_print_hest_generic_data(ACPI_HEST_GENERIC_DATA *);
64 1.5 cegger #endif
65 1.5 cegger static void acpi_print_whea(ACPI_WHEA_HEADER *whea,
66 1.5 cegger void (*print_action)(ACPI_WHEA_HEADER *),
67 1.5 cegger void (*print_ins)(ACPI_WHEA_HEADER *),
68 1.5 cegger void (*print_flags)(ACPI_WHEA_HEADER *));
69 1.5 cegger static int acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt);
70 1.18 msaitoh static uint64_t acpi_select_address(uint32_t, uint64_t);
71 1.5 cegger static void acpi_handle_fadt(ACPI_TABLE_HEADER *fadt);
72 1.5 cegger static void acpi_print_cpu(u_char cpu_id);
73 1.5 cegger static void acpi_print_cpu_uid(uint32_t uid, char *uid_string);
74 1.5 cegger static void acpi_print_local_apic(uint32_t apic_id, uint32_t flags);
75 1.5 cegger static void acpi_print_io_apic(uint32_t apic_id, uint32_t int_base,
76 1.5 cegger uint64_t apic_addr);
77 1.5 cegger static void acpi_print_mps_flags(uint16_t flags);
78 1.5 cegger static void acpi_print_intr(uint32_t intr, uint16_t mps_flags);
79 1.5 cegger static void acpi_print_local_nmi(u_int lint, uint16_t mps_flags);
80 1.5 cegger static void acpi_print_madt(ACPI_SUBTABLE_HEADER *mp);
81 1.5 cegger static void acpi_handle_bert(ACPI_TABLE_HEADER *sdp);
82 1.5 cegger static void acpi_handle_boot(ACPI_TABLE_HEADER *sdp);
83 1.5 cegger static void acpi_handle_cpep(ACPI_TABLE_HEADER *sdp);
84 1.5 cegger static void acpi_handle_dbgp(ACPI_TABLE_HEADER *sdp);
85 1.5 cegger static void acpi_handle_einj(ACPI_TABLE_HEADER *sdp);
86 1.5 cegger static void acpi_handle_erst(ACPI_TABLE_HEADER *sdp);
87 1.5 cegger static void acpi_handle_hest(ACPI_TABLE_HEADER *sdp);
88 1.5 cegger static void acpi_handle_madt(ACPI_TABLE_HEADER *sdp);
89 1.5 cegger static void acpi_handle_msct(ACPI_TABLE_HEADER *sdp);
90 1.5 cegger static void acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp);
91 1.5 cegger static void acpi_handle_hpet(ACPI_TABLE_HEADER *sdp);
92 1.5 cegger static void acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp);
93 1.5 cegger static void acpi_handle_sbst(ACPI_TABLE_HEADER *sdp);
94 1.5 cegger static void acpi_handle_slit(ACPI_TABLE_HEADER *sdp);
95 1.5 cegger static void acpi_handle_spcr(ACPI_TABLE_HEADER *sdp);
96 1.5 cegger static void acpi_print_srat_cpu(uint32_t apic_id,
97 1.5 cegger uint32_t proximity_domain,
98 1.5 cegger uint32_t flags, uint32_t clockdomain);
99 1.5 cegger static void acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp);
100 1.5 cegger static void acpi_print_srat(ACPI_SUBTABLE_HEADER *srat);
101 1.5 cegger static void acpi_handle_srat(ACPI_TABLE_HEADER *sdp);
102 1.5 cegger static void acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp);
103 1.5 cegger static void acpi_handle_waet(ACPI_TABLE_HEADER *sdp);
104 1.5 cegger static void acpi_handle_wdat(ACPI_TABLE_HEADER *sdp);
105 1.5 cegger static void acpi_handle_wdrt(ACPI_TABLE_HEADER *sdp);
106 1.5 cegger static void acpi_print_sdt(ACPI_TABLE_HEADER *sdp);
107 1.7 jmcneill static void acpi_dump_bytes(ACPI_TABLE_HEADER *sdp);
108 1.5 cegger static void acpi_print_fadt(ACPI_TABLE_HEADER *sdp);
109 1.5 cegger static void acpi_print_facs(ACPI_TABLE_FACS *facs);
110 1.5 cegger static void acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp);
111 1.5 cegger static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa);
112 1.5 cegger static void acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp);
113 1.5 cegger static void acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp);
114 1.5 cegger static void acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
115 1.5 cegger void (*action)(ACPI_SUBTABLE_HEADER *));
116 1.5 cegger
117 1.5 cegger /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
118 1.5 cegger static int addr_size;
119 1.5 cegger
120 1.16 msaitoh /* Strings used in the TCPA table */
121 1.16 msaitoh static const char *tcpa_event_type_strings[] = {
122 1.16 msaitoh "PREBOOT Certificate",
123 1.16 msaitoh "POST Code",
124 1.16 msaitoh "Unused",
125 1.16 msaitoh "No Action",
126 1.16 msaitoh "Separator",
127 1.16 msaitoh "Action",
128 1.16 msaitoh "Event Tag",
129 1.16 msaitoh "S-CRTM Contents",
130 1.16 msaitoh "S-CRTM Version",
131 1.16 msaitoh "CPU Microcode",
132 1.16 msaitoh "Platform Config Flags",
133 1.16 msaitoh "Table of Devices",
134 1.16 msaitoh "Compact Hash",
135 1.16 msaitoh "IPL",
136 1.16 msaitoh "IPL Partition Data",
137 1.16 msaitoh "Non-Host Code",
138 1.16 msaitoh "Non-Host Config",
139 1.16 msaitoh "Non-Host Info"
140 1.16 msaitoh };
141 1.16 msaitoh
142 1.16 msaitoh static const char *TCPA_pcclient_strings[] = {
143 1.16 msaitoh "<undefined>",
144 1.16 msaitoh "SMBIOS",
145 1.16 msaitoh "BIS Certificate",
146 1.16 msaitoh "POST BIOS ROM Strings",
147 1.16 msaitoh "ESCD",
148 1.16 msaitoh "CMOS",
149 1.16 msaitoh "NVRAM",
150 1.16 msaitoh "Option ROM Execute",
151 1.16 msaitoh "Option ROM Configurateion",
152 1.16 msaitoh "<undefined>",
153 1.16 msaitoh "Option ROM Microcode Update ",
154 1.16 msaitoh "S-CRTM Version String",
155 1.16 msaitoh "S-CRTM Contents",
156 1.16 msaitoh "POST Contents",
157 1.16 msaitoh "Table of Devices",
158 1.16 msaitoh };
159 1.16 msaitoh
160 1.16 msaitoh #define PRINTFLAG_END() printflag_end()
161 1.16 msaitoh
162 1.16 msaitoh static char pf_sep = '{';
163 1.16 msaitoh
164 1.16 msaitoh static void
165 1.16 msaitoh printflag_end(void)
166 1.16 msaitoh {
167 1.16 msaitoh
168 1.16 msaitoh if (pf_sep != '{') {
169 1.16 msaitoh printf("}");
170 1.16 msaitoh pf_sep = '{';
171 1.16 msaitoh }
172 1.16 msaitoh printf("\n");
173 1.16 msaitoh }
174 1.16 msaitoh
175 1.16 msaitoh static void
176 1.16 msaitoh printflag(uint64_t var, uint64_t mask, const char *name)
177 1.16 msaitoh {
178 1.16 msaitoh
179 1.16 msaitoh if (var & mask) {
180 1.16 msaitoh printf("%c%s", pf_sep, name);
181 1.16 msaitoh pf_sep = ',';
182 1.16 msaitoh }
183 1.16 msaitoh }
184 1.16 msaitoh
185 1.5 cegger static void
186 1.5 cegger acpi_print_string(char *s, size_t length)
187 1.5 cegger {
188 1.5 cegger int c;
189 1.5 cegger
190 1.5 cegger /* Trim trailing spaces and NULLs */
191 1.5 cegger while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
192 1.5 cegger length--;
193 1.5 cegger
194 1.5 cegger while (length--) {
195 1.5 cegger c = *s++;
196 1.5 cegger putchar(c);
197 1.5 cegger }
198 1.5 cegger }
199 1.5 cegger
200 1.5 cegger static void
201 1.5 cegger acpi_print_gas(ACPI_GENERIC_ADDRESS *gas)
202 1.5 cegger {
203 1.5 cegger switch(gas->SpaceId) {
204 1.5 cegger case ACPI_GAS_MEMORY:
205 1.16 msaitoh if (gas->BitWidth <= 32)
206 1.16 msaitoh printf("0x%08x:%u[%u] (Memory)",
207 1.16 msaitoh (u_int)gas->Address, gas->BitOffset,
208 1.16 msaitoh gas->BitWidth);
209 1.16 msaitoh else
210 1.16 msaitoh printf("0x%016jx:%u[%u] (Memory)",
211 1.16 msaitoh (uintmax_t)gas->Address, gas->BitOffset,
212 1.16 msaitoh gas->BitWidth);
213 1.5 cegger break;
214 1.5 cegger case ACPI_GAS_IO:
215 1.16 msaitoh printf("0x%02x:%u[%u] (IO)", (u_int)gas->Address,
216 1.16 msaitoh gas->BitOffset, gas->BitWidth);
217 1.5 cegger break;
218 1.5 cegger case ACPI_GAS_PCI:
219 1.5 cegger printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->Address >> 32),
220 1.5 cegger (uint16_t)((gas->Address >> 16) & 0xffff),
221 1.5 cegger (uint16_t)gas->Address);
222 1.5 cegger break;
223 1.5 cegger /* XXX How to handle these below? */
224 1.5 cegger case ACPI_GAS_EMBEDDED:
225 1.5 cegger printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address,
226 1.5 cegger gas->BitOffset, gas->BitWidth);
227 1.5 cegger break;
228 1.5 cegger case ACPI_GAS_SMBUS:
229 1.5 cegger printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address,
230 1.5 cegger gas->BitOffset, gas->BitWidth);
231 1.5 cegger break;
232 1.5 cegger case ACPI_GAS_CMOS:
233 1.5 cegger case ACPI_GAS_PCIBAR:
234 1.5 cegger case ACPI_GAS_DATATABLE:
235 1.5 cegger case ACPI_GAS_FIXED:
236 1.5 cegger default:
237 1.16 msaitoh printf("0x%016jx (?)", (uintmax_t)gas->Address);
238 1.5 cegger break;
239 1.5 cegger }
240 1.5 cegger }
241 1.5 cegger
242 1.5 cegger static void
243 1.5 cegger acpi_print_pci(uint16_t vendorid, uint16_t deviceid,
244 1.5 cegger uint8_t seg, uint8_t bus, uint8_t device, uint8_t func)
245 1.5 cegger {
246 1.5 cegger if (vendorid == 0xffff && deviceid == 0xffff) {
247 1.5 cegger printf("\tPCI Device=NONE\n");
248 1.5 cegger return;
249 1.5 cegger }
250 1.5 cegger
251 1.5 cegger printf("\tPCI device={\n");
252 1.5 cegger printf("\t\tVendor=0x%x\n", vendorid);
253 1.5 cegger printf("\t\tDevice=0x%x\n", deviceid);
254 1.5 cegger printf("\n");
255 1.5 cegger printf("\t\tSegment Group=%d\n", seg);
256 1.5 cegger printf("\t\tBus=%d\n", bus);
257 1.5 cegger printf("\t\tDevice=%d\n", device);
258 1.5 cegger printf("\t\tFunction=%d\n", func);
259 1.5 cegger printf("\t}\n");
260 1.5 cegger }
261 1.5 cegger
262 1.5 cegger static void
263 1.5 cegger acpi_print_pci_sbfd(uint8_t seg, uint8_t bus, uint8_t device, uint8_t func)
264 1.5 cegger {
265 1.5 cegger if (bus == 0xff && device == 0xff && func == 0xff) {
266 1.5 cegger printf("\tPCI Device=NONE\n");
267 1.5 cegger return;
268 1.5 cegger }
269 1.5 cegger
270 1.5 cegger printf("\tPCI device={\n");
271 1.5 cegger printf("\t\tSegment Group=%d\n", seg);
272 1.5 cegger printf("\t\tBus=%d\n", bus);
273 1.5 cegger printf("\t\tDevice=%d\n", device);
274 1.5 cegger printf("\t\tFunction=%d\n", func);
275 1.5 cegger printf("\t}\n");
276 1.5 cegger }
277 1.5 cegger
278 1.5 cegger #ifdef notyet
279 1.5 cegger static void
280 1.5 cegger acpi_print_hest_errorseverity(uint32_t error)
281 1.5 cegger {
282 1.5 cegger printf("\tError Severity={ ");
283 1.5 cegger switch (error) {
284 1.5 cegger case 0:
285 1.5 cegger printf("Recoverable");
286 1.5 cegger break;
287 1.5 cegger case 1:
288 1.5 cegger printf("Fatal");
289 1.5 cegger break;
290 1.5 cegger case 2:
291 1.5 cegger printf("Corrected");
292 1.5 cegger break;
293 1.5 cegger case 3:
294 1.5 cegger printf("None");
295 1.5 cegger break;
296 1.5 cegger default:
297 1.5 cegger printf("%d (reserved)", error);
298 1.5 cegger break;
299 1.5 cegger }
300 1.5 cegger printf("}\n");
301 1.5 cegger }
302 1.5 cegger #endif
303 1.5 cegger
304 1.5 cegger static void
305 1.5 cegger acpi_print_hest_errorbank(ACPI_HEST_IA_ERROR_BANK *bank)
306 1.5 cegger {
307 1.5 cegger printf("\n");
308 1.5 cegger printf("\tBank Number=%d\n", bank->BankNumber);
309 1.5 cegger printf("\tClear Status On Init={ %s }\n",
310 1.5 cegger bank->ClearStatusOnInit ? "NO" : "YES");
311 1.5 cegger printf("\tStatus Data Format={ ");
312 1.5 cegger switch (bank->StatusFormat) {
313 1.5 cegger case 0:
314 1.5 cegger printf("IA32 MCA");
315 1.5 cegger break;
316 1.5 cegger case 1:
317 1.5 cegger printf("EMT64 MCA");
318 1.5 cegger break;
319 1.5 cegger case 2:
320 1.5 cegger printf("AMD64 MCA");
321 1.5 cegger break;
322 1.5 cegger }
323 1.5 cegger printf(" }\n");
324 1.5 cegger
325 1.5 cegger if (bank->ControlRegister)
326 1.5 cegger printf("\tControl Register=0x%x\n", bank->ControlRegister);
327 1.5 cegger printf("\tControl Init Data=0x%"PRIx64"\n", bank->ControlData);
328 1.5 cegger printf("\tStatus MSR=0x%x\n", bank->StatusRegister);
329 1.5 cegger printf("\tAddress MSR=0x%x\n", bank->AddressRegister);
330 1.5 cegger printf("\tMisc MSR=0x%x\n", bank->MiscRegister);
331 1.5 cegger }
332 1.5 cegger
333 1.5 cegger static void
334 1.5 cegger acpi_print_hest_header(ACPI_HEST_HEADER *hest)
335 1.5 cegger {
336 1.5 cegger printf("\tType={ ");
337 1.5 cegger switch (hest->Type) {
338 1.5 cegger case ACPI_HEST_TYPE_IA32_CHECK:
339 1.5 cegger printf("IA32 Machine Check Exception");
340 1.5 cegger break;
341 1.5 cegger case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
342 1.5 cegger printf("IA32 Corrected Machine Check\n");
343 1.5 cegger break;
344 1.5 cegger case ACPI_HEST_TYPE_IA32_NMI:
345 1.5 cegger printf("IA32 Non-Maskable Interrupt\n");
346 1.5 cegger break;
347 1.5 cegger case ACPI_HEST_TYPE_NOT_USED3:
348 1.5 cegger case ACPI_HEST_TYPE_NOT_USED4:
349 1.5 cegger case ACPI_HEST_TYPE_NOT_USED5:
350 1.5 cegger printf("unused type: %d\n", hest->Type);
351 1.5 cegger break;
352 1.5 cegger case ACPI_HEST_TYPE_AER_ROOT_PORT:
353 1.5 cegger printf("PCI Express Root Port AER\n");
354 1.5 cegger break;
355 1.5 cegger case ACPI_HEST_TYPE_AER_ENDPOINT:
356 1.5 cegger printf("PCI Express Endpoint AER\n");
357 1.5 cegger break;
358 1.5 cegger case ACPI_HEST_TYPE_AER_BRIDGE:
359 1.5 cegger printf("PCI Express/PCI-X Bridge AER\n");
360 1.5 cegger break;
361 1.5 cegger case ACPI_HEST_TYPE_GENERIC_ERROR:
362 1.5 cegger printf("Generic Hardware Error Source\n");
363 1.5 cegger break;
364 1.5 cegger case ACPI_HEST_TYPE_RESERVED:
365 1.5 cegger default:
366 1.5 cegger printf("Reserved\n");
367 1.5 cegger break;
368 1.5 cegger }
369 1.5 cegger printf(" }\n");
370 1.5 cegger printf("\tSourceId=%d\n", hest->SourceId);
371 1.5 cegger }
372 1.5 cegger
373 1.5 cegger static void
374 1.5 cegger acpi_print_hest_aer_common(ACPI_HEST_AER_COMMON *data)
375 1.5 cegger {
376 1.5 cegger printf("\tFlags={ ");
377 1.5 cegger if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
378 1.5 cegger printf("FIRMWARE_FIRST");
379 1.5 cegger if (data->Flags & ACPI_HEST_GLOBAL)
380 1.5 cegger printf("GLOBAL");
381 1.5 cegger printf(" }\n");
382 1.5 cegger printf("\tEnabled={ %s ", data->Flags ? "YES" : "NO");
383 1.5 cegger if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
384 1.5 cegger printf("(ignored) ");
385 1.5 cegger printf("}\n");
386 1.5 cegger printf("\tNumber of Record to pre-allocate=%d\n",
387 1.5 cegger data->RecordsToPreallocate);
388 1.5 cegger printf("\tMax. Sections per Record=%d\n", data->MaxSectionsPerRecord);
389 1.5 cegger if (!(data->Flags & ACPI_HEST_GLOBAL))
390 1.5 cegger acpi_print_pci_sbfd(0, data->Bus, data->Device, data->Function);
391 1.5 cegger printf("\tDevice Control=0x%x\n", data->DeviceControl);
392 1.5 cegger printf("\tUncorrectable Error Mask Register=0x%x\n",
393 1.5 cegger data->UncorrectableMask);
394 1.5 cegger printf("\tUncorrectable Error Severity Register=0x%x\n",
395 1.5 cegger data->UncorrectableSeverity);
396 1.5 cegger printf("\tCorrectable Error Mask Register=0x%x\n",
397 1.5 cegger data->CorrectableMask);
398 1.5 cegger printf("\tAdvanced Capabilities Register=0x%x\n",
399 1.5 cegger data->AdvancedCapabilities);
400 1.5 cegger }
401 1.5 cegger
402 1.5 cegger static void
403 1.5 cegger acpi_print_hest_notify(ACPI_HEST_NOTIFY *notify)
404 1.5 cegger {
405 1.5 cegger printf("\tHW Error Notification={\n");
406 1.5 cegger printf("\t\tType={ ");
407 1.5 cegger switch (notify->Type) {
408 1.5 cegger case ACPI_HEST_NOTIFY_POLLED:
409 1.5 cegger printf("POLLED");
410 1.5 cegger break;
411 1.5 cegger case ACPI_HEST_NOTIFY_EXTERNAL:
412 1.5 cegger printf("EXTERN");
413 1.5 cegger break;
414 1.5 cegger case ACPI_HEST_NOTIFY_LOCAL:
415 1.5 cegger printf("LOCAL");
416 1.5 cegger break;
417 1.5 cegger case ACPI_HEST_NOTIFY_SCI:
418 1.5 cegger printf("SCI");
419 1.5 cegger break;
420 1.5 cegger case ACPI_HEST_NOTIFY_NMI:
421 1.5 cegger printf("NMI");
422 1.5 cegger break;
423 1.5 cegger case ACPI_HEST_NOTIFY_RESERVED:
424 1.5 cegger printf("RESERVED");
425 1.5 cegger break;
426 1.5 cegger default:
427 1.5 cegger printf(" %d (reserved)", notify->Type);
428 1.5 cegger break;
429 1.5 cegger }
430 1.5 cegger printf(" }\n");
431 1.5 cegger
432 1.5 cegger printf("\t\tLength=%d\n", notify->Length);
433 1.5 cegger printf("\t\tConfig Write Enable={\n");
434 1.5 cegger if (notify->ConfigWriteEnable & ACPI_HEST_TYPE)
435 1.5 cegger printf("TYPE");
436 1.5 cegger if (notify->ConfigWriteEnable & ACPI_HEST_POLL_INTERVAL)
437 1.5 cegger printf("POLL INTERVAL");
438 1.5 cegger if (notify->ConfigWriteEnable & ACPI_HEST_POLL_THRESHOLD_VALUE)
439 1.5 cegger printf("THRESHOLD VALUE");
440 1.5 cegger if (notify->ConfigWriteEnable & ACPI_HEST_POLL_THRESHOLD_WINDOW)
441 1.5 cegger printf("THRESHOLD WINDOW");
442 1.5 cegger if (notify->ConfigWriteEnable & ACPI_HEST_ERR_THRESHOLD_VALUE)
443 1.5 cegger printf("THRESHOLD VALUE");
444 1.5 cegger if (notify->ConfigWriteEnable & ACPI_HEST_ERR_THRESHOLD_WINDOW)
445 1.5 cegger printf("THRESHOLD WINDOW");
446 1.5 cegger printf("}\n");
447 1.5 cegger
448 1.5 cegger printf("\t\tPoll Interval=%d msec\n", notify->PollInterval);
449 1.5 cegger printf("\t\tInterrupt Vector=%d\n", notify->Vector);
450 1.5 cegger printf("\t\tSwitch To Polling Threshold Value=%d\n",
451 1.5 cegger notify->PollingThresholdValue);
452 1.5 cegger printf("\t\tSwitch To Polling Threshold Window=%d msec\n",
453 1.5 cegger notify->PollingThresholdWindow);
454 1.5 cegger printf("\t\tError Threshold Value=%d\n",
455 1.5 cegger notify->ErrorThresholdValue);
456 1.5 cegger printf("\t\tError Threshold Window=%d msec\n",
457 1.5 cegger notify->ErrorThresholdWindow);
458 1.5 cegger printf("\t}\n");
459 1.5 cegger }
460 1.5 cegger
461 1.5 cegger #ifdef notyet
462 1.5 cegger static void
463 1.5 cegger acpi_print_hest_generic_status(ACPI_HEST_GENERIC_STATUS *data)
464 1.5 cegger {
465 1.5 cegger uint32_t i, pos, entries;
466 1.5 cegger ACPI_HEST_GENERIC_DATA *gen;
467 1.5 cegger
468 1.5 cegger entries = data->BlockStatus & ACPI_HEST_ERROR_ENTRY_COUNT;
469 1.5 cegger
470 1.5 cegger printf("\tGeneric Error Status={\n");
471 1.5 cegger printf("\t\tBlock Status={ ");
472 1.5 cegger if (data->BlockStatus & ACPI_HEST_UNCORRECTABLE)
473 1.5 cegger printf("UNCORRECTABLE");
474 1.5 cegger if (data->BlockStatus & ACPI_HEST_CORRECTABLE)
475 1.5 cegger printf("CORRECTABLE");
476 1.5 cegger if (data->BlockStatus & ACPI_HEST_MULTIPLE_UNCORRECTABLE)
477 1.5 cegger printf("MULTIPLE UNCORRECTABLE");
478 1.5 cegger if (data->BlockStatus & ACPI_HEST_MULTIPLE_CORRECTABLE)
479 1.5 cegger printf("MULTIPLE CORRECTABLE");
480 1.5 cegger printf(" }\n");
481 1.5 cegger printf("\t\tEntry Count=%d\n", entries);
482 1.5 cegger printf("\t\tRaw Data Offset=%d\n", data->RawDataOffset);
483 1.5 cegger printf("\t\tRaw Data Length=%d\n", data->RawDataLength);
484 1.5 cegger printf("\t\tData Length=%d\n", data->DataLength);
485 1.5 cegger printf("\t");
486 1.5 cegger acpi_print_hest_errorseverity(data->ErrorSeverity);
487 1.5 cegger printf("\t}\n");
488 1.5 cegger
489 1.5 cegger pos = sizeof(ACPI_HEST_GENERIC_STATUS);
490 1.5 cegger for (i = 0; i < entries; i++) {
491 1.5 cegger gen = (ACPI_HEST_GENERIC_DATA *)((char *)data + pos);
492 1.5 cegger acpi_print_hest_generic_data(gen);
493 1.5 cegger pos += sizeof(ACPI_HEST_GENERIC_DATA);
494 1.5 cegger }
495 1.5 cegger }
496 1.5 cegger #endif
497 1.5 cegger
498 1.5 cegger #ifdef notyet
499 1.5 cegger static void
500 1.5 cegger acpi_print_hest_generic_data(ACPI_HEST_GENERIC_DATA *data)
501 1.5 cegger {
502 1.5 cegger printf("\tGeneric Error Data={\n");
503 1.5 cegger printf("\t\tSectionType=");
504 1.5 cegger acpi_print_string((char *)data->SectionType, sizeof(data->SectionType));
505 1.5 cegger printf("\n\t");
506 1.5 cegger acpi_print_hest_errorseverity(data->ErrorSeverity);
507 1.5 cegger printf("\t\tRevision=0x%x\n", data->Revision);
508 1.5 cegger printf("\t\tValidation Bits=0x%x\n", data->ValidationBits);
509 1.5 cegger printf("\t\tFlags=0x%x\n", data->Flags);
510 1.5 cegger printf("\t\tData Length=%d\n", data->ErrorDataLength);
511 1.5 cegger printf("\t\tField Replication Unit Id=");
512 1.5 cegger acpi_print_string((char *)data->FruId, sizeof(data->FruId));
513 1.5 cegger printf("\n");
514 1.5 cegger printf("\t\tField Replication Unit=");
515 1.5 cegger acpi_print_string((char *)data->FruText, sizeof(data->FruText));
516 1.5 cegger printf("\n");
517 1.5 cegger printf("\t}\n");
518 1.5 cegger }
519 1.5 cegger #endif
520 1.5 cegger
521 1.5 cegger static void
522 1.5 cegger acpi_print_whea(ACPI_WHEA_HEADER *whea,
523 1.5 cegger void (*print_action)(ACPI_WHEA_HEADER *),
524 1.5 cegger void (*print_ins)(ACPI_WHEA_HEADER *),
525 1.5 cegger void (*print_flags)(ACPI_WHEA_HEADER *))
526 1.5 cegger {
527 1.5 cegger printf("\n");
528 1.5 cegger
529 1.5 cegger print_action(whea);
530 1.5 cegger print_ins(whea);
531 1.5 cegger if (print_flags)
532 1.5 cegger print_flags(whea);
533 1.5 cegger printf("\tRegisterRegion=");
534 1.5 cegger acpi_print_gas(&whea->RegisterRegion);
535 1.5 cegger printf("\n");
536 1.5 cegger printf("\tMASK=0x%08"PRIx64"\n", whea->Mask);
537 1.5 cegger }
538 1.5 cegger
539 1.5 cegger static void
540 1.5 cegger acpi_print_hest_ia32_check(ACPI_HEST_IA_MACHINE_CHECK *data)
541 1.5 cegger {
542 1.5 cegger uint32_t i, pos;
543 1.5 cegger ACPI_HEST_IA_ERROR_BANK *bank;
544 1.5 cegger
545 1.5 cegger acpi_print_hest_header(&data->Header);
546 1.5 cegger printf("\tFlags={ ");
547 1.5 cegger if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
548 1.5 cegger printf("FIRMWARE_FIRST");
549 1.5 cegger printf(" }\n");
550 1.5 cegger printf("\tEnabled={ %s }\n", data->Enabled ? "YES" : "NO");
551 1.5 cegger printf("\tNumber of Record to pre-allocate=%d\n",
552 1.5 cegger data->RecordsToPreallocate);
553 1.5 cegger printf("\tMax Sections per Record=%d\n",
554 1.5 cegger data->MaxSectionsPerRecord);
555 1.5 cegger printf("\tGlobal Capability Init Data=0x%"PRIx64"\n",
556 1.5 cegger data->GlobalCapabilityData);
557 1.5 cegger printf("\tGlobal Control Init Data=0x%"PRIx64"\n",
558 1.5 cegger data->GlobalControlData);
559 1.5 cegger printf("\tNumber of Hardware Error Reporting Banks=%d\n",
560 1.5 cegger data->NumHardwareBanks);
561 1.5 cegger
562 1.5 cegger pos = sizeof(ACPI_HEST_IA_MACHINE_CHECK);
563 1.5 cegger for (i = 0; i < data->NumHardwareBanks; i++) {
564 1.5 cegger bank = (ACPI_HEST_IA_ERROR_BANK *)((char *)data + pos);
565 1.5 cegger acpi_print_hest_errorbank(bank);
566 1.5 cegger pos += sizeof(ACPI_HEST_IA_ERROR_BANK);
567 1.5 cegger }
568 1.5 cegger }
569 1.5 cegger
570 1.5 cegger static void
571 1.5 cegger acpi_print_hest_ia32_correctedcheck(ACPI_HEST_IA_CORRECTED *data)
572 1.5 cegger {
573 1.5 cegger uint32_t i, pos;
574 1.5 cegger ACPI_HEST_IA_ERROR_BANK *bank;
575 1.5 cegger
576 1.5 cegger acpi_print_hest_header(&data->Header);
577 1.5 cegger printf("\tFlags={ ");
578 1.5 cegger if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
579 1.5 cegger printf("FIRMWARE_FIRST");
580 1.5 cegger printf(" }\n");
581 1.5 cegger printf("\tEnabled={ %s }\n", data->Enabled ? "YES" : "NO");
582 1.5 cegger printf("\tNumber of Record to pre-allocate=%d\n",
583 1.5 cegger data->RecordsToPreallocate);
584 1.5 cegger printf("\tMax Sections per Record=%d\n",
585 1.5 cegger data->MaxSectionsPerRecord);
586 1.5 cegger acpi_print_hest_notify(&data->Notify);
587 1.5 cegger
588 1.5 cegger printf("\tNumber of Hardware Error Reporting Banks=%d\n",
589 1.5 cegger data->NumHardwareBanks);
590 1.5 cegger
591 1.5 cegger pos = sizeof(ACPI_HEST_IA_MACHINE_CHECK);
592 1.5 cegger for (i = 0; i < data->NumHardwareBanks; i++) {
593 1.5 cegger bank = (ACPI_HEST_IA_ERROR_BANK *)((char *)data + pos);
594 1.5 cegger acpi_print_hest_errorbank(bank);
595 1.5 cegger pos += sizeof(ACPI_HEST_IA_ERROR_BANK);
596 1.5 cegger }
597 1.5 cegger }
598 1.5 cegger
599 1.5 cegger static void
600 1.5 cegger acpi_print_hest_ia32_nmi(ACPI_HEST_IA_NMI *data)
601 1.5 cegger {
602 1.5 cegger acpi_print_hest_header(&data->Header);
603 1.5 cegger printf("\tNumber of Record to pre-allocate=%d\n",
604 1.5 cegger data->RecordsToPreallocate);
605 1.5 cegger printf("\tMax Sections per Record=%d\n",
606 1.5 cegger data->MaxSectionsPerRecord);
607 1.5 cegger printf("\tMax Raw Data Length=%d\n",
608 1.5 cegger data->MaxRawDataLength);
609 1.5 cegger }
610 1.5 cegger
611 1.5 cegger static void
612 1.5 cegger acpi_print_hest_aer_root(ACPI_HEST_AER_ROOT *data)
613 1.5 cegger {
614 1.5 cegger acpi_print_hest_header(&data->Header);
615 1.5 cegger acpi_print_hest_aer_common(&data->Aer);
616 1.5 cegger printf("Root Error Command Register=0x%x\n", data->RootErrorCommand);
617 1.5 cegger }
618 1.5 cegger
619 1.5 cegger static void
620 1.5 cegger acpi_print_hest_aer_endpoint(ACPI_HEST_AER *data)
621 1.5 cegger {
622 1.5 cegger acpi_print_hest_header(&data->Header);
623 1.5 cegger acpi_print_hest_aer_common(&data->Aer);
624 1.5 cegger }
625 1.5 cegger
626 1.5 cegger static void
627 1.5 cegger acpi_print_hest_aer_bridge(ACPI_HEST_AER_BRIDGE *data)
628 1.5 cegger {
629 1.5 cegger acpi_print_hest_header(&data->Header);
630 1.5 cegger acpi_print_hest_aer_common(&data->Aer);
631 1.5 cegger
632 1.5 cegger printf("\tSecondary Uncorrectable Error Mask Register=0x%x\n",
633 1.5 cegger data->UncorrectableMask2);
634 1.5 cegger printf("\tSecondary Uncorrectable Error Severity Register=0x%x\n",
635 1.5 cegger data->UncorrectableSeverity2);
636 1.5 cegger printf("\tSecondory Advanced Capabilities Register=0x%x\n",
637 1.5 cegger data->AdvancedCapabilities2);
638 1.5 cegger }
639 1.5 cegger
640 1.5 cegger static void
641 1.5 cegger acpi_print_hest_generic(ACPI_HEST_GENERIC *data)
642 1.5 cegger {
643 1.5 cegger acpi_print_hest_header(&data->Header);
644 1.5 cegger if (data->RelatedSourceId != 0xffff)
645 1.5 cegger printf("\tReleated SourceId=%d\n", data->RelatedSourceId);
646 1.5 cegger printf("\tEnabled={ %s }\n", data->Enabled ? "YES" : "NO");
647 1.5 cegger printf("\tNumber of Records to pre-allocate=%d\n",
648 1.5 cegger data->RecordsToPreallocate);
649 1.5 cegger printf("\tMax Sections per Record=%d\n",
650 1.5 cegger data->MaxSectionsPerRecord);
651 1.5 cegger printf("\tMax Raw Data Length=%d\n", data->MaxRawDataLength);
652 1.5 cegger printf("\tError Status Address=");
653 1.5 cegger acpi_print_gas(&data->ErrorStatusAddress);
654 1.5 cegger acpi_print_hest_notify(&data->Notify);
655 1.5 cegger printf("\tError Block Length=%d\n", data->ErrorBlockLength);
656 1.5 cegger }
657 1.5 cegger
658 1.5 cegger static void
659 1.5 cegger acpi_handle_hest(ACPI_TABLE_HEADER *sdp)
660 1.5 cegger {
661 1.5 cegger ACPI_TABLE_HEST *hest;
662 1.5 cegger ACPI_HEST_HEADER *subhest;
663 1.5 cegger uint32_t i, pos;
664 1.5 cegger void *subtable;
665 1.5 cegger
666 1.5 cegger printf(BEGIN_COMMENT);
667 1.5 cegger acpi_print_sdt(sdp);
668 1.5 cegger hest = (ACPI_TABLE_HEST *)sdp;
669 1.5 cegger
670 1.5 cegger printf("\tError Source Count=%d\n", hest->ErrorSourceCount);
671 1.5 cegger pos = sizeof(ACPI_TABLE_HEST);
672 1.5 cegger for (i = 0; i < hest->ErrorSourceCount; i++) {
673 1.5 cegger subhest = (ACPI_HEST_HEADER *)((char *)hest + pos);
674 1.5 cegger subtable = (void *)((char *)subhest + sizeof(ACPI_HEST_HEADER));
675 1.5 cegger printf("\n");
676 1.5 cegger
677 1.5 cegger printf("\tType={ ");
678 1.5 cegger switch (subhest->Type) {
679 1.5 cegger case ACPI_HEST_TYPE_IA32_CHECK:
680 1.5 cegger acpi_print_hest_ia32_check(subtable);
681 1.5 cegger pos += sizeof(ACPI_HEST_IA_MACHINE_CHECK);
682 1.5 cegger break;
683 1.5 cegger
684 1.5 cegger case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
685 1.5 cegger acpi_print_hest_ia32_correctedcheck(subtable);
686 1.5 cegger pos += sizeof(ACPI_HEST_IA_CORRECTED);
687 1.5 cegger break;
688 1.5 cegger
689 1.5 cegger case ACPI_HEST_TYPE_IA32_NMI:
690 1.5 cegger acpi_print_hest_ia32_nmi(subtable);
691 1.5 cegger pos += sizeof(ACPI_HEST_IA_NMI);
692 1.5 cegger break;
693 1.5 cegger
694 1.5 cegger case ACPI_HEST_TYPE_NOT_USED3:
695 1.5 cegger case ACPI_HEST_TYPE_NOT_USED4:
696 1.5 cegger case ACPI_HEST_TYPE_NOT_USED5:
697 1.5 cegger pos += sizeof(ACPI_HEST_HEADER);
698 1.5 cegger break;
699 1.5 cegger
700 1.5 cegger case ACPI_HEST_TYPE_AER_ROOT_PORT:
701 1.5 cegger acpi_print_hest_aer_root(subtable);
702 1.5 cegger pos += sizeof(ACPI_HEST_AER_ROOT);
703 1.5 cegger break;
704 1.5 cegger
705 1.5 cegger case ACPI_HEST_TYPE_AER_ENDPOINT:
706 1.5 cegger acpi_print_hest_aer_endpoint(subtable);
707 1.5 cegger pos += sizeof(ACPI_HEST_AER_ROOT);
708 1.5 cegger break;
709 1.5 cegger
710 1.5 cegger case ACPI_HEST_TYPE_AER_BRIDGE:
711 1.5 cegger acpi_print_hest_aer_bridge(subtable);
712 1.5 cegger pos += sizeof(ACPI_HEST_AER_BRIDGE);
713 1.5 cegger break;
714 1.5 cegger
715 1.5 cegger case ACPI_HEST_TYPE_GENERIC_ERROR:
716 1.5 cegger acpi_print_hest_generic(subtable);
717 1.5 cegger pos += sizeof(ACPI_HEST_GENERIC);
718 1.5 cegger break;
719 1.5 cegger
720 1.5 cegger case ACPI_HEST_TYPE_RESERVED:
721 1.5 cegger default:
722 1.5 cegger pos += sizeof(ACPI_HEST_HEADER);
723 1.5 cegger break;
724 1.5 cegger }
725 1.5 cegger }
726 1.5 cegger
727 1.5 cegger printf(END_COMMENT);
728 1.5 cegger }
729 1.5 cegger
730 1.5 cegger /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */
731 1.5 cegger static int
732 1.5 cegger acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt)
733 1.5 cegger {
734 1.5 cegger int fadt_revision;
735 1.5 cegger
736 1.5 cegger /* Set the FADT revision separately from the RSDP version. */
737 1.5 cegger if (addr_size == 8) {
738 1.5 cegger fadt_revision = 2;
739 1.5 cegger
740 1.5 cegger /*
741 1.5 cegger * A few systems (e.g., IBM T23) have an RSDP that claims
742 1.5 cegger * revision 2 but the 64 bit addresses are invalid. If
743 1.5 cegger * revision 2 and the 32 bit address is non-zero but the
744 1.5 cegger * 32 and 64 bit versions don't match, prefer the 32 bit
745 1.5 cegger * version for all subsequent tables.
746 1.5 cegger */
747 1.5 cegger if (fadt->Facs != 0 &&
748 1.5 cegger (fadt->XFacs & 0xffffffff) != fadt->Facs)
749 1.5 cegger fadt_revision = 1;
750 1.5 cegger } else
751 1.5 cegger fadt_revision = 1;
752 1.5 cegger return (fadt_revision);
753 1.5 cegger }
754 1.5 cegger
755 1.18 msaitoh static uint64_t
756 1.18 msaitoh acpi_select_address(uint32_t addr32, uint64_t addr64)
757 1.18 msaitoh {
758 1.18 msaitoh
759 1.18 msaitoh if (addr64 == 0)
760 1.18 msaitoh return addr32;
761 1.18 msaitoh
762 1.18 msaitoh if ((addr32 != 0) && ((addr64 & 0xfffffff) != addr32)) {
763 1.18 msaitoh /*
764 1.18 msaitoh * A few systems (e.g., IBM T23) have an RSDP that claims
765 1.18 msaitoh * revision 2 but the 64 bit addresses are invalid. If
766 1.18 msaitoh * revision 2 and the 32 bit address is non-zero but the
767 1.18 msaitoh * 32 and 64 bit versions don't match, prefer the 32 bit
768 1.18 msaitoh * version for all subsequent tables.
769 1.18 msaitoh */
770 1.18 msaitoh return addr32;
771 1.18 msaitoh }
772 1.18 msaitoh
773 1.18 msaitoh return addr64;
774 1.18 msaitoh }
775 1.18 msaitoh
776 1.5 cegger static void
777 1.5 cegger acpi_handle_fadt(ACPI_TABLE_HEADER *sdp)
778 1.5 cegger {
779 1.5 cegger ACPI_TABLE_HEADER *dsdp;
780 1.5 cegger ACPI_TABLE_FACS *facs;
781 1.5 cegger ACPI_TABLE_FADT *fadt;
782 1.5 cegger
783 1.5 cegger fadt = (ACPI_TABLE_FADT *)sdp;
784 1.5 cegger acpi_print_fadt(sdp);
785 1.5 cegger
786 1.18 msaitoh facs = (ACPI_TABLE_FACS *)acpi_map_sdt(
787 1.18 msaitoh acpi_select_address(fadt->Facs, fadt->XFacs));
788 1.5 cegger if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || facs->Length < 64)
789 1.5 cegger errx(EXIT_FAILURE, "FACS is corrupt");
790 1.5 cegger acpi_print_facs(facs);
791 1.5 cegger
792 1.18 msaitoh dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(
793 1.18 msaitoh acpi_select_address(fadt->Dsdt, fadt->XDsdt));
794 1.17 msaitoh if (memcmp(dsdp->Signature, ACPI_SIG_DSDT, 4) != 0)
795 1.17 msaitoh errx(EXIT_FAILURE, "DSDT signature mismatch");
796 1.5 cegger if (acpi_checksum(dsdp, dsdp->Length))
797 1.5 cegger errx(EXIT_FAILURE, "DSDT is corrupt");
798 1.5 cegger acpi_print_dsdt(dsdp);
799 1.5 cegger }
800 1.5 cegger
801 1.5 cegger static void
802 1.5 cegger acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
803 1.5 cegger void (*action)(ACPI_SUBTABLE_HEADER *))
804 1.5 cegger {
805 1.5 cegger ACPI_SUBTABLE_HEADER *subtable;
806 1.5 cegger char *end;
807 1.5 cegger
808 1.5 cegger subtable = first;
809 1.5 cegger end = (char *)table + table->Length;
810 1.5 cegger while ((char *)subtable < end) {
811 1.5 cegger printf("\n");
812 1.16 msaitoh if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) {
813 1.16 msaitoh warnx("invalid subtable length %u", subtable->Length);
814 1.16 msaitoh return;
815 1.16 msaitoh }
816 1.5 cegger action(subtable);
817 1.5 cegger subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable +
818 1.5 cegger subtable->Length);
819 1.5 cegger }
820 1.5 cegger }
821 1.5 cegger
822 1.5 cegger static void
823 1.5 cegger acpi_print_cpu(u_char cpu_id)
824 1.5 cegger {
825 1.5 cegger
826 1.5 cegger printf("\tACPI CPU=");
827 1.5 cegger if (cpu_id == 0xff)
828 1.5 cegger printf("ALL\n");
829 1.5 cegger else
830 1.5 cegger printf("%d\n", (u_int)cpu_id);
831 1.5 cegger }
832 1.5 cegger
833 1.5 cegger static void
834 1.5 cegger acpi_print_cpu_uid(uint32_t uid, char *uid_string)
835 1.5 cegger {
836 1.5 cegger
837 1.5 cegger printf("\tUID=%d", uid);
838 1.5 cegger if (uid_string != NULL)
839 1.5 cegger printf(" (%s)", uid_string);
840 1.5 cegger printf("\n");
841 1.5 cegger }
842 1.5 cegger
843 1.5 cegger static void
844 1.5 cegger acpi_print_local_apic(uint32_t apic_id, uint32_t flags)
845 1.5 cegger {
846 1.5 cegger
847 1.5 cegger printf("\tFlags={");
848 1.5 cegger if (flags & ACPI_MADT_ENABLED)
849 1.5 cegger printf("ENABLED");
850 1.5 cegger else
851 1.5 cegger printf("DISABLED");
852 1.5 cegger printf("}\n");
853 1.5 cegger printf("\tAPIC ID=%d\n", apic_id);
854 1.5 cegger }
855 1.5 cegger
856 1.5 cegger static void
857 1.5 cegger acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr)
858 1.5 cegger {
859 1.5 cegger
860 1.5 cegger printf("\tAPIC ID=%d\n", apic_id);
861 1.5 cegger printf("\tINT BASE=%d\n", int_base);
862 1.5 cegger printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr);
863 1.5 cegger }
864 1.5 cegger
865 1.5 cegger static void
866 1.5 cegger acpi_print_mps_flags(uint16_t flags)
867 1.5 cegger {
868 1.5 cegger
869 1.5 cegger printf("\tFlags={Polarity=");
870 1.5 cegger switch (flags & ACPI_MADT_POLARITY_MASK) {
871 1.5 cegger case ACPI_MADT_POLARITY_CONFORMS:
872 1.5 cegger printf("conforming");
873 1.5 cegger break;
874 1.5 cegger case ACPI_MADT_POLARITY_ACTIVE_HIGH:
875 1.5 cegger printf("active-hi");
876 1.5 cegger break;
877 1.5 cegger case ACPI_MADT_POLARITY_ACTIVE_LOW:
878 1.5 cegger printf("active-lo");
879 1.5 cegger break;
880 1.5 cegger default:
881 1.5 cegger printf("0x%x", flags & ACPI_MADT_POLARITY_MASK);
882 1.5 cegger break;
883 1.5 cegger }
884 1.5 cegger printf(", Trigger=");
885 1.5 cegger switch (flags & ACPI_MADT_TRIGGER_MASK) {
886 1.5 cegger case ACPI_MADT_TRIGGER_CONFORMS:
887 1.5 cegger printf("conforming");
888 1.5 cegger break;
889 1.5 cegger case ACPI_MADT_TRIGGER_EDGE:
890 1.5 cegger printf("edge");
891 1.5 cegger break;
892 1.5 cegger case ACPI_MADT_TRIGGER_LEVEL:
893 1.5 cegger printf("level");
894 1.5 cegger break;
895 1.5 cegger default:
896 1.5 cegger printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2);
897 1.5 cegger }
898 1.5 cegger printf("}\n");
899 1.5 cegger }
900 1.5 cegger
901 1.5 cegger static void
902 1.16 msaitoh acpi_print_gicc_flags(uint32_t flags)
903 1.16 msaitoh {
904 1.16 msaitoh
905 1.16 msaitoh printf("\tFlags={Performance intr=");
906 1.16 msaitoh if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE)
907 1.16 msaitoh printf("edge");
908 1.16 msaitoh else
909 1.16 msaitoh printf("level");
910 1.16 msaitoh printf(", VGIC intr=");
911 1.16 msaitoh if (flags & ACPI_MADT_VGIC_IRQ_MODE)
912 1.16 msaitoh printf("edge");
913 1.16 msaitoh else
914 1.16 msaitoh printf("level");
915 1.16 msaitoh printf("}\n");
916 1.16 msaitoh }
917 1.16 msaitoh
918 1.16 msaitoh static void
919 1.5 cegger acpi_print_intr(uint32_t intr, uint16_t mps_flags)
920 1.5 cegger {
921 1.5 cegger
922 1.5 cegger printf("\tINTR=%d\n", intr);
923 1.5 cegger acpi_print_mps_flags(mps_flags);
924 1.5 cegger }
925 1.5 cegger
926 1.5 cegger static void
927 1.5 cegger acpi_print_local_nmi(u_int lint, uint16_t mps_flags)
928 1.5 cegger {
929 1.5 cegger
930 1.5 cegger printf("\tLINT Pin=%d\n", lint);
931 1.5 cegger acpi_print_mps_flags(mps_flags);
932 1.5 cegger }
933 1.5 cegger
934 1.16 msaitoh static const char *apic_types[] = {
935 1.16 msaitoh [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC",
936 1.16 msaitoh [ACPI_MADT_TYPE_IO_APIC] = "IO APIC",
937 1.16 msaitoh [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override",
938 1.16 msaitoh [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI",
939 1.16 msaitoh [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI",
940 1.16 msaitoh [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override",
941 1.16 msaitoh [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC",
942 1.16 msaitoh [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC",
943 1.16 msaitoh [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt",
944 1.16 msaitoh [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC",
945 1.16 msaitoh [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI",
946 1.16 msaitoh [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure",
947 1.16 msaitoh [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure",
948 1.16 msaitoh [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame",
949 1.16 msaitoh [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure",
950 1.16 msaitoh [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure"
951 1.16 msaitoh };
952 1.16 msaitoh
953 1.16 msaitoh static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT",
954 1.16 msaitoh "Corrected Platform Error" };
955 1.5 cegger
956 1.5 cegger static void
957 1.5 cegger acpi_print_madt(ACPI_SUBTABLE_HEADER *mp)
958 1.5 cegger {
959 1.5 cegger ACPI_MADT_LOCAL_APIC *lapic;
960 1.5 cegger ACPI_MADT_IO_APIC *ioapic;
961 1.5 cegger ACPI_MADT_INTERRUPT_OVERRIDE *over;
962 1.5 cegger ACPI_MADT_NMI_SOURCE *nmi;
963 1.5 cegger ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi;
964 1.5 cegger ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over;
965 1.5 cegger ACPI_MADT_IO_SAPIC *iosapic;
966 1.5 cegger ACPI_MADT_LOCAL_SAPIC *lsapic;
967 1.5 cegger ACPI_MADT_INTERRUPT_SOURCE *isrc;
968 1.5 cegger ACPI_MADT_LOCAL_X2APIC *x2apic;
969 1.5 cegger ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi;
970 1.16 msaitoh ACPI_MADT_GENERIC_INTERRUPT *gicc;
971 1.16 msaitoh ACPI_MADT_GENERIC_DISTRIBUTOR *gicd;
972 1.16 msaitoh ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr;
973 1.16 msaitoh ACPI_MADT_GENERIC_TRANSLATOR *gict;
974 1.5 cegger
975 1.16 msaitoh if (mp->Type < __arraycount(apic_types))
976 1.5 cegger printf("\tType=%s\n", apic_types[mp->Type]);
977 1.5 cegger else
978 1.5 cegger printf("\tType=%d (unknown)\n", mp->Type);
979 1.5 cegger switch (mp->Type) {
980 1.5 cegger case ACPI_MADT_TYPE_LOCAL_APIC:
981 1.5 cegger lapic = (ACPI_MADT_LOCAL_APIC *)mp;
982 1.5 cegger acpi_print_cpu(lapic->ProcessorId);
983 1.5 cegger acpi_print_local_apic(lapic->Id, lapic->LapicFlags);
984 1.5 cegger break;
985 1.5 cegger case ACPI_MADT_TYPE_IO_APIC:
986 1.5 cegger ioapic = (ACPI_MADT_IO_APIC *)mp;
987 1.5 cegger acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase,
988 1.5 cegger ioapic->Address);
989 1.5 cegger break;
990 1.5 cegger case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
991 1.5 cegger over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp;
992 1.5 cegger printf("\tBUS=%d\n", (u_int)over->Bus);
993 1.5 cegger printf("\tIRQ=%d\n", (u_int)over->SourceIrq);
994 1.5 cegger acpi_print_intr(over->GlobalIrq, over->IntiFlags);
995 1.5 cegger break;
996 1.5 cegger case ACPI_MADT_TYPE_NMI_SOURCE:
997 1.5 cegger nmi = (ACPI_MADT_NMI_SOURCE *)mp;
998 1.5 cegger acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags);
999 1.5 cegger break;
1000 1.5 cegger case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1001 1.5 cegger lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp;
1002 1.5 cegger acpi_print_cpu(lapic_nmi->ProcessorId);
1003 1.5 cegger acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags);
1004 1.5 cegger break;
1005 1.5 cegger case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1006 1.5 cegger lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp;
1007 1.5 cegger printf("\tLocal APIC ADDR=0x%016jx\n",
1008 1.5 cegger (uintmax_t)lapic_over->Address);
1009 1.5 cegger break;
1010 1.5 cegger case ACPI_MADT_TYPE_IO_SAPIC:
1011 1.5 cegger iosapic = (ACPI_MADT_IO_SAPIC *)mp;
1012 1.5 cegger acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase,
1013 1.5 cegger iosapic->Address);
1014 1.5 cegger break;
1015 1.5 cegger case ACPI_MADT_TYPE_LOCAL_SAPIC:
1016 1.5 cegger lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp;
1017 1.5 cegger acpi_print_cpu(lsapic->ProcessorId);
1018 1.5 cegger acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags);
1019 1.5 cegger printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid);
1020 1.5 cegger if (mp->Length > offsetof(ACPI_MADT_LOCAL_SAPIC, Uid))
1021 1.5 cegger acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString);
1022 1.5 cegger break;
1023 1.5 cegger case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1024 1.5 cegger isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp;
1025 1.16 msaitoh if (isrc->Type < __arraycount(platform_int_types))
1026 1.5 cegger printf("\tType=%s\n", platform_int_types[isrc->Type]);
1027 1.5 cegger else
1028 1.5 cegger printf("\tType=%d (unknown)\n", isrc->Type);
1029 1.5 cegger printf("\tAPIC ID=%d\n", (u_int)isrc->Id);
1030 1.5 cegger printf("\tAPIC EID=%d\n", (u_int)isrc->Eid);
1031 1.5 cegger printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector);
1032 1.5 cegger acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags);
1033 1.5 cegger break;
1034 1.5 cegger case ACPI_MADT_TYPE_LOCAL_X2APIC:
1035 1.5 cegger x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp;
1036 1.5 cegger acpi_print_cpu_uid(x2apic->Uid, NULL);
1037 1.5 cegger acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags);
1038 1.5 cegger break;
1039 1.5 cegger case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1040 1.5 cegger x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp;
1041 1.5 cegger acpi_print_cpu_uid(x2apic_nmi->Uid, NULL);
1042 1.5 cegger acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags);
1043 1.5 cegger break;
1044 1.16 msaitoh case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
1045 1.16 msaitoh gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp;
1046 1.16 msaitoh acpi_print_cpu_uid(gicc->Uid, NULL);
1047 1.16 msaitoh printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber);
1048 1.16 msaitoh acpi_print_gicc_flags(gicc->Flags);
1049 1.16 msaitoh printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion);
1050 1.16 msaitoh printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt);
1051 1.16 msaitoh printf("\tParked ADDR=%016jx\n",
1052 1.16 msaitoh (uintmax_t)gicc->ParkedAddress);
1053 1.16 msaitoh printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress);
1054 1.16 msaitoh printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress);
1055 1.16 msaitoh printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress);
1056 1.16 msaitoh printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt);
1057 1.16 msaitoh printf("\tGICR ADDR=%016jx\n",
1058 1.16 msaitoh (uintmax_t)gicc->GicrBaseAddress);
1059 1.16 msaitoh printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr);
1060 1.16 msaitoh printf("\tEfficency Class=%d\n", (u_int)gicc->EfficiencyClass);
1061 1.16 msaitoh break;
1062 1.16 msaitoh case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
1063 1.16 msaitoh gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp;
1064 1.16 msaitoh printf("\tGIC ID=%d\n", (u_int)gicd->GicId);
1065 1.16 msaitoh printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress);
1066 1.16 msaitoh printf("\tVector Base=%d\n", gicd->GlobalIrqBase);
1067 1.16 msaitoh printf("\tGIC VERSION=%d\n", (u_int)gicd->Version);
1068 1.16 msaitoh break;
1069 1.16 msaitoh case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
1070 1.16 msaitoh gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp;
1071 1.16 msaitoh printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress);
1072 1.16 msaitoh printf("\tLength=%08x\n", gicr->Length);
1073 1.16 msaitoh break;
1074 1.16 msaitoh case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
1075 1.16 msaitoh gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp;
1076 1.16 msaitoh printf("\tGIC ITS ID=%d\n", gict->TranslationId);
1077 1.16 msaitoh printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress);
1078 1.16 msaitoh break;
1079 1.5 cegger }
1080 1.5 cegger }
1081 1.5 cegger
1082 1.5 cegger #ifdef notyet
1083 1.5 cegger static void
1084 1.5 cegger acpi_print_bert_region(ACPI_BERT_REGION *region)
1085 1.5 cegger {
1086 1.5 cegger uint32_t i, pos, entries;
1087 1.5 cegger ACPI_HEST_GENERIC_DATA *data;
1088 1.5 cegger
1089 1.5 cegger printf("\n");
1090 1.5 cegger printf("\tBlockStatus={ ");
1091 1.5 cegger
1092 1.5 cegger if (region->BlockStatus & ACPI_BERT_UNCORRECTABLE)
1093 1.5 cegger printf("Uncorrectable");
1094 1.5 cegger if (region->BlockStatus & ACPI_BERT_CORRECTABLE)
1095 1.5 cegger printf("Correctable");
1096 1.5 cegger if (region->BlockStatus & ACPI_BERT_MULTIPLE_UNCORRECTABLE)
1097 1.5 cegger printf("Multiple Uncorrectable");
1098 1.5 cegger if (region->BlockStatus & ACPI_BERT_MULTIPLE_CORRECTABLE)
1099 1.5 cegger printf("Multiple Correctable");
1100 1.5 cegger entries = region->BlockStatus & ACPI_BERT_ERROR_ENTRY_COUNT;
1101 1.5 cegger printf(", Error Entry Count=%d", entries);
1102 1.5 cegger printf("}\n");
1103 1.5 cegger
1104 1.5 cegger printf("\tRaw Data Offset=0x%x\n", region->RawDataOffset);
1105 1.5 cegger printf("\tRaw Data Length=0x%x\n", region->RawDataLength);
1106 1.5 cegger printf("\tData Length=0x%x\n", region->DataLength);
1107 1.5 cegger
1108 1.5 cegger acpi_print_hest_errorseverity(region->ErrorSeverity);
1109 1.5 cegger
1110 1.5 cegger pos = sizeof(ACPI_BERT_REGION);
1111 1.5 cegger for (i = 0; i < entries; i++) {
1112 1.5 cegger data = (ACPI_HEST_GENERIC_DATA *)((char *)region + pos);
1113 1.5 cegger acpi_print_hest_generic_data(data);
1114 1.5 cegger pos += sizeof(ACPI_HEST_GENERIC_DATA);
1115 1.5 cegger }
1116 1.5 cegger }
1117 1.5 cegger #endif
1118 1.5 cegger
1119 1.5 cegger static void
1120 1.5 cegger acpi_handle_bert(ACPI_TABLE_HEADER *sdp)
1121 1.5 cegger {
1122 1.5 cegger ACPI_TABLE_BERT *bert;
1123 1.5 cegger
1124 1.5 cegger printf(BEGIN_COMMENT);
1125 1.5 cegger acpi_print_sdt(sdp);
1126 1.5 cegger bert = (ACPI_TABLE_BERT *)sdp;
1127 1.5 cegger
1128 1.5 cegger printf("\tLength of Boot Error Region=%d bytes\n", bert->RegionLength);
1129 1.5 cegger printf("\tPhysical Address of Region=0x%"PRIx64"\n", bert->Address);
1130 1.5 cegger
1131 1.5 cegger printf(END_COMMENT);
1132 1.5 cegger }
1133 1.5 cegger
1134 1.5 cegger static void
1135 1.5 cegger acpi_handle_boot(ACPI_TABLE_HEADER *sdp)
1136 1.5 cegger {
1137 1.5 cegger ACPI_TABLE_BOOT *boot;
1138 1.5 cegger
1139 1.5 cegger printf(BEGIN_COMMENT);
1140 1.5 cegger acpi_print_sdt(sdp);
1141 1.5 cegger boot = (ACPI_TABLE_BOOT *)sdp;
1142 1.5 cegger printf("\tCMOS Index=0x%02x\n", boot->CmosIndex);
1143 1.5 cegger printf(END_COMMENT);
1144 1.5 cegger }
1145 1.5 cegger
1146 1.5 cegger static void
1147 1.5 cegger acpi_handle_cpep(ACPI_TABLE_HEADER *sdp)
1148 1.5 cegger {
1149 1.5 cegger ACPI_TABLE_CPEP *cpep;
1150 1.5 cegger ACPI_CPEP_POLLING *poll;
1151 1.5 cegger uint32_t cpep_pos;
1152 1.5 cegger
1153 1.5 cegger printf(BEGIN_COMMENT);
1154 1.5 cegger acpi_print_sdt(sdp);
1155 1.5 cegger cpep = (ACPI_TABLE_CPEP *)sdp;
1156 1.5 cegger
1157 1.5 cegger cpep_pos = sizeof(ACPI_TABLE_CPEP);
1158 1.5 cegger while (cpep_pos < sdp->Length) {
1159 1.5 cegger poll = (ACPI_CPEP_POLLING *)((char *)cpep + cpep_pos);
1160 1.5 cegger acpi_print_cpu(poll->Id);
1161 1.5 cegger printf("\tACPI CPU EId=%d\n", poll->Eid);
1162 1.5 cegger printf("\tPoll Interval=%d msec\n", poll->Interval);
1163 1.5 cegger cpep_pos += sizeof(ACPI_CPEP_POLLING);
1164 1.5 cegger }
1165 1.5 cegger printf(END_COMMENT);
1166 1.5 cegger }
1167 1.5 cegger
1168 1.5 cegger static void
1169 1.5 cegger acpi_handle_dbgp(ACPI_TABLE_HEADER *sdp)
1170 1.5 cegger {
1171 1.5 cegger ACPI_TABLE_DBGP *dbgp;
1172 1.5 cegger
1173 1.5 cegger printf(BEGIN_COMMENT);
1174 1.5 cegger acpi_print_sdt(sdp);
1175 1.5 cegger dbgp = (ACPI_TABLE_DBGP *)sdp;
1176 1.5 cegger printf("\tType={");
1177 1.5 cegger switch (dbgp->Type) {
1178 1.5 cegger case 0:
1179 1.5 cegger printf("full 16550");
1180 1.5 cegger break;
1181 1.5 cegger case 1:
1182 1.5 cegger printf("subset of 16550");
1183 1.5 cegger break;
1184 1.5 cegger }
1185 1.5 cegger printf("}\n");
1186 1.5 cegger printf("DebugPort=");
1187 1.5 cegger acpi_print_gas(&dbgp->DebugPort);
1188 1.5 cegger printf(END_COMMENT);
1189 1.5 cegger }
1190 1.5 cegger
1191 1.5 cegger static void
1192 1.5 cegger acpi_print_einj_action(ACPI_WHEA_HEADER *whea)
1193 1.5 cegger {
1194 1.5 cegger printf("\tACTION={");
1195 1.5 cegger switch (whea->Action) {
1196 1.5 cegger case ACPI_EINJ_BEGIN_OPERATION:
1197 1.5 cegger printf("Begin Operation");
1198 1.5 cegger break;
1199 1.5 cegger case ACPI_EINJ_GET_TRIGGER_TABLE:
1200 1.5 cegger printf("Get Trigger Table");
1201 1.5 cegger break;
1202 1.5 cegger case ACPI_EINJ_SET_ERROR_TYPE:
1203 1.5 cegger printf("Set Error Type");
1204 1.5 cegger break;
1205 1.5 cegger case ACPI_EINJ_GET_ERROR_TYPE:
1206 1.5 cegger printf("Get Error Type");
1207 1.5 cegger break;
1208 1.5 cegger case ACPI_EINJ_END_OPERATION:
1209 1.5 cegger printf("End Operation");
1210 1.5 cegger break;
1211 1.5 cegger case ACPI_EINJ_EXECUTE_OPERATION:
1212 1.5 cegger printf("Execute Operation");
1213 1.5 cegger break;
1214 1.5 cegger case ACPI_EINJ_CHECK_BUSY_STATUS:
1215 1.5 cegger printf("Check Busy Status");
1216 1.5 cegger break;
1217 1.5 cegger case ACPI_EINJ_GET_COMMAND_STATUS:
1218 1.5 cegger printf("Get Command Status");
1219 1.5 cegger break;
1220 1.5 cegger case ACPI_EINJ_ACTION_RESERVED:
1221 1.5 cegger printf("Preserved");
1222 1.5 cegger break;
1223 1.5 cegger case ACPI_EINJ_TRIGGER_ERROR:
1224 1.5 cegger printf("Trigger Error");
1225 1.5 cegger break;
1226 1.5 cegger default:
1227 1.5 cegger printf("%d", whea->Action);
1228 1.5 cegger break;
1229 1.5 cegger }
1230 1.5 cegger printf("}\n");
1231 1.5 cegger }
1232 1.5 cegger
1233 1.5 cegger static void
1234 1.5 cegger acpi_print_einj_instruction(ACPI_WHEA_HEADER *whea)
1235 1.5 cegger {
1236 1.5 cegger uint32_t ins = whea->Instruction;
1237 1.5 cegger
1238 1.5 cegger printf("\tINSTRUCTION={");
1239 1.5 cegger switch (ins) {
1240 1.5 cegger case ACPI_EINJ_READ_REGISTER:
1241 1.5 cegger printf("Read Register");
1242 1.5 cegger break;
1243 1.5 cegger case ACPI_EINJ_READ_REGISTER_VALUE:
1244 1.5 cegger printf("Read Register Value");
1245 1.5 cegger break;
1246 1.5 cegger case ACPI_EINJ_WRITE_REGISTER:
1247 1.5 cegger printf("Write Register");
1248 1.5 cegger break;
1249 1.5 cegger case ACPI_EINJ_WRITE_REGISTER_VALUE:
1250 1.5 cegger printf("Write Register Value");
1251 1.5 cegger break;
1252 1.5 cegger case ACPI_EINJ_NOOP:
1253 1.5 cegger printf("Noop");
1254 1.5 cegger break;
1255 1.5 cegger case ACPI_EINJ_INSTRUCTION_RESERVED:
1256 1.5 cegger printf("Reserved");
1257 1.5 cegger break;
1258 1.5 cegger default:
1259 1.5 cegger printf("%d", ins);
1260 1.5 cegger break;
1261 1.5 cegger }
1262 1.5 cegger printf("}\n");
1263 1.5 cegger }
1264 1.5 cegger
1265 1.5 cegger static void
1266 1.5 cegger acpi_print_einj_flags(ACPI_WHEA_HEADER *whea)
1267 1.5 cegger {
1268 1.5 cegger uint32_t flags = whea->Flags;
1269 1.5 cegger
1270 1.5 cegger printf("\tFLAGS={ ");
1271 1.5 cegger if (flags & ACPI_EINJ_PRESERVE)
1272 1.5 cegger printf("PRESERVED");
1273 1.5 cegger printf("}\n");
1274 1.5 cegger }
1275 1.5 cegger
1276 1.5 cegger static void
1277 1.5 cegger acpi_handle_einj(ACPI_TABLE_HEADER *sdp)
1278 1.5 cegger {
1279 1.5 cegger ACPI_TABLE_EINJ *einj;
1280 1.5 cegger ACPI_EINJ_ENTRY *einj_entry;
1281 1.5 cegger uint32_t einj_pos;
1282 1.5 cegger u_int i;
1283 1.5 cegger
1284 1.5 cegger printf(BEGIN_COMMENT);
1285 1.5 cegger acpi_print_sdt(sdp);
1286 1.5 cegger einj = (ACPI_TABLE_EINJ *)sdp;
1287 1.5 cegger
1288 1.5 cegger printf("\tHeader Length=%d\n", einj->HeaderLength);
1289 1.5 cegger printf("\tFlags=0x%x\n", einj->Flags);
1290 1.5 cegger printf("\tEntries=%d\n", einj->Entries);
1291 1.5 cegger
1292 1.5 cegger einj_pos = sizeof(ACPI_TABLE_EINJ);
1293 1.5 cegger for (i = 0; i < einj->Entries; i++) {
1294 1.5 cegger einj_entry = (ACPI_EINJ_ENTRY *)((char *)einj + einj_pos);
1295 1.5 cegger acpi_print_whea(&einj_entry->WheaHeader,
1296 1.5 cegger acpi_print_einj_action, acpi_print_einj_instruction,
1297 1.5 cegger acpi_print_einj_flags);
1298 1.5 cegger einj_pos += sizeof(ACPI_EINJ_ENTRY);
1299 1.5 cegger }
1300 1.5 cegger printf(END_COMMENT);
1301 1.5 cegger }
1302 1.5 cegger
1303 1.5 cegger static void
1304 1.5 cegger acpi_print_erst_action(ACPI_WHEA_HEADER *whea)
1305 1.5 cegger {
1306 1.5 cegger printf("\tACTION={");
1307 1.5 cegger switch (whea->Action) {
1308 1.5 cegger case ACPI_ERST_BEGIN_WRITE:
1309 1.5 cegger printf("Begin Write");
1310 1.5 cegger break;
1311 1.5 cegger case ACPI_ERST_BEGIN_READ:
1312 1.5 cegger printf("Begin Read");
1313 1.5 cegger break;
1314 1.5 cegger case ACPI_ERST_BEGIN_CLEAR:
1315 1.5 cegger printf("Begin Clear");
1316 1.5 cegger break;
1317 1.5 cegger case ACPI_ERST_END:
1318 1.5 cegger printf("End");
1319 1.5 cegger break;
1320 1.5 cegger case ACPI_ERST_SET_RECORD_OFFSET:
1321 1.5 cegger printf("Set Record Offset");
1322 1.5 cegger break;
1323 1.5 cegger case ACPI_ERST_EXECUTE_OPERATION:
1324 1.5 cegger printf("Execute Operation");
1325 1.5 cegger break;
1326 1.5 cegger case ACPI_ERST_CHECK_BUSY_STATUS:
1327 1.5 cegger printf("Check Busy Status");
1328 1.5 cegger break;
1329 1.5 cegger case ACPI_ERST_GET_COMMAND_STATUS:
1330 1.5 cegger printf("Get Command Status");
1331 1.5 cegger break;
1332 1.5 cegger case ACPI_ERST_GET_RECORD_ID:
1333 1.5 cegger printf("Get Record ID");
1334 1.5 cegger break;
1335 1.5 cegger case ACPI_ERST_SET_RECORD_ID:
1336 1.5 cegger printf("Set Record ID");
1337 1.5 cegger break;
1338 1.5 cegger case ACPI_ERST_GET_RECORD_COUNT:
1339 1.5 cegger printf("Get Record Count");
1340 1.5 cegger break;
1341 1.5 cegger case ACPI_ERST_BEGIN_DUMMY_WRIITE:
1342 1.5 cegger printf("Begin Dummy Write");
1343 1.5 cegger break;
1344 1.5 cegger case ACPI_ERST_NOT_USED:
1345 1.5 cegger printf("Unused");
1346 1.5 cegger break;
1347 1.5 cegger case ACPI_ERST_GET_ERROR_RANGE:
1348 1.5 cegger printf("Get Error Range");
1349 1.5 cegger break;
1350 1.5 cegger case ACPI_ERST_GET_ERROR_LENGTH:
1351 1.5 cegger printf("Get Error Length");
1352 1.5 cegger break;
1353 1.5 cegger case ACPI_ERST_GET_ERROR_ATTRIBUTES:
1354 1.5 cegger printf("Get Error Attributes");
1355 1.5 cegger break;
1356 1.5 cegger case ACPI_ERST_ACTION_RESERVED:
1357 1.5 cegger printf("Reserved");
1358 1.5 cegger break;
1359 1.5 cegger default:
1360 1.5 cegger printf("%d", whea->Action);
1361 1.5 cegger break;
1362 1.5 cegger }
1363 1.5 cegger printf("}\n");
1364 1.5 cegger }
1365 1.5 cegger
1366 1.5 cegger static void
1367 1.5 cegger acpi_print_erst_instruction(ACPI_WHEA_HEADER *whea)
1368 1.5 cegger {
1369 1.5 cegger printf("\tINSTRUCTION={");
1370 1.5 cegger switch (whea->Instruction) {
1371 1.5 cegger case ACPI_ERST_READ_REGISTER:
1372 1.5 cegger printf("Read Register");
1373 1.5 cegger break;
1374 1.5 cegger case ACPI_ERST_READ_REGISTER_VALUE:
1375 1.5 cegger printf("Read Register Value");
1376 1.5 cegger break;
1377 1.5 cegger case ACPI_ERST_WRITE_REGISTER:
1378 1.5 cegger printf("Write Register");
1379 1.5 cegger break;
1380 1.5 cegger case ACPI_ERST_WRITE_REGISTER_VALUE:
1381 1.5 cegger printf("Write Register Value");
1382 1.5 cegger break;
1383 1.5 cegger case ACPI_ERST_NOOP:
1384 1.5 cegger printf("Noop");
1385 1.5 cegger break;
1386 1.5 cegger case ACPI_ERST_LOAD_VAR1:
1387 1.5 cegger printf("Load Var1");
1388 1.5 cegger break;
1389 1.5 cegger case ACPI_ERST_LOAD_VAR2:
1390 1.5 cegger printf("Load Var2");
1391 1.5 cegger break;
1392 1.5 cegger case ACPI_ERST_STORE_VAR1:
1393 1.5 cegger printf("Store Var1");
1394 1.5 cegger break;
1395 1.5 cegger case ACPI_ERST_ADD:
1396 1.5 cegger printf("Add");
1397 1.5 cegger break;
1398 1.5 cegger case ACPI_ERST_SUBTRACT:
1399 1.5 cegger printf("Subtract");
1400 1.5 cegger break;
1401 1.5 cegger case ACPI_ERST_ADD_VALUE:
1402 1.5 cegger printf("Add Value");
1403 1.5 cegger break;
1404 1.5 cegger case ACPI_ERST_SUBTRACT_VALUE:
1405 1.5 cegger printf("Subtract Value");
1406 1.5 cegger break;
1407 1.5 cegger case ACPI_ERST_STALL:
1408 1.5 cegger printf("Stall");
1409 1.5 cegger break;
1410 1.5 cegger case ACPI_ERST_STALL_WHILE_TRUE:
1411 1.5 cegger printf("Stall While True");
1412 1.5 cegger break;
1413 1.5 cegger case ACPI_ERST_SKIP_NEXT_IF_TRUE:
1414 1.5 cegger printf("Skip Next If True");
1415 1.5 cegger break;
1416 1.5 cegger case ACPI_ERST_GOTO:
1417 1.5 cegger printf("Goto");
1418 1.5 cegger break;
1419 1.5 cegger case ACPI_ERST_SET_SRC_ADDRESS_BASE:
1420 1.5 cegger printf("Set Src Address Base");
1421 1.5 cegger break;
1422 1.5 cegger case ACPI_ERST_SET_DST_ADDRESS_BASE:
1423 1.5 cegger printf("Set Dst Address Base");
1424 1.5 cegger break;
1425 1.5 cegger case ACPI_ERST_MOVE_DATA:
1426 1.5 cegger printf("Move Data");
1427 1.5 cegger break;
1428 1.5 cegger case ACPI_ERST_INSTRUCTION_RESERVED:
1429 1.5 cegger printf("Reserved");
1430 1.5 cegger break;
1431 1.5 cegger default:
1432 1.5 cegger printf("%d (reserved)", whea->Instruction);
1433 1.5 cegger break;
1434 1.5 cegger }
1435 1.5 cegger printf("}\n");
1436 1.5 cegger }
1437 1.5 cegger
1438 1.5 cegger static void
1439 1.5 cegger acpi_print_erst_flags(ACPI_WHEA_HEADER *whea)
1440 1.5 cegger {
1441 1.5 cegger uint32_t flags = whea->Flags;
1442 1.5 cegger
1443 1.5 cegger printf("\tFLAGS={ ");
1444 1.5 cegger if (flags & ACPI_ERST_PRESERVE)
1445 1.5 cegger printf("PRESERVED");
1446 1.5 cegger printf("}\n");
1447 1.5 cegger }
1448 1.5 cegger
1449 1.5 cegger static void
1450 1.5 cegger acpi_handle_erst(ACPI_TABLE_HEADER *sdp)
1451 1.5 cegger {
1452 1.5 cegger ACPI_TABLE_ERST *erst;
1453 1.5 cegger ACPI_ERST_ENTRY *erst_entry;
1454 1.5 cegger uint32_t erst_pos;
1455 1.5 cegger u_int i;
1456 1.5 cegger
1457 1.5 cegger printf(BEGIN_COMMENT);
1458 1.5 cegger acpi_print_sdt(sdp);
1459 1.5 cegger erst = (ACPI_TABLE_ERST *)sdp;
1460 1.5 cegger
1461 1.5 cegger printf("\tHeader Length=%d\n", erst->HeaderLength);
1462 1.5 cegger printf("\tEntries=%d\n", erst->Entries);
1463 1.5 cegger
1464 1.5 cegger erst_pos = sizeof(ACPI_TABLE_ERST);
1465 1.5 cegger for (i = 0; i < erst->Entries; i++) {
1466 1.5 cegger erst_entry = (ACPI_ERST_ENTRY *)((char *)erst + erst_pos);
1467 1.5 cegger acpi_print_whea(&erst_entry->WheaHeader,
1468 1.5 cegger acpi_print_erst_action, acpi_print_erst_instruction,
1469 1.5 cegger acpi_print_erst_flags);
1470 1.5 cegger erst_pos += sizeof(ACPI_ERST_ENTRY);
1471 1.5 cegger }
1472 1.5 cegger printf(END_COMMENT);
1473 1.5 cegger }
1474 1.5 cegger
1475 1.5 cegger static void
1476 1.5 cegger acpi_handle_madt(ACPI_TABLE_HEADER *sdp)
1477 1.5 cegger {
1478 1.5 cegger ACPI_TABLE_MADT *madt;
1479 1.5 cegger
1480 1.5 cegger printf(BEGIN_COMMENT);
1481 1.5 cegger acpi_print_sdt(sdp);
1482 1.5 cegger madt = (ACPI_TABLE_MADT *)sdp;
1483 1.5 cegger printf("\tLocal APIC ADDR=0x%08x\n", madt->Address);
1484 1.5 cegger printf("\tFlags={");
1485 1.5 cegger if (madt->Flags & ACPI_MADT_PCAT_COMPAT)
1486 1.5 cegger printf("PC-AT");
1487 1.5 cegger printf("}\n");
1488 1.5 cegger acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt);
1489 1.5 cegger printf(END_COMMENT);
1490 1.5 cegger }
1491 1.5 cegger
1492 1.5 cegger static void
1493 1.5 cegger acpi_handle_hpet(ACPI_TABLE_HEADER *sdp)
1494 1.5 cegger {
1495 1.5 cegger ACPI_TABLE_HPET *hpet;
1496 1.5 cegger
1497 1.5 cegger printf(BEGIN_COMMENT);
1498 1.5 cegger acpi_print_sdt(sdp);
1499 1.5 cegger hpet = (ACPI_TABLE_HPET *)sdp;
1500 1.5 cegger printf("\tHPET Number=%d\n", hpet->Sequence);
1501 1.5 cegger printf("\tADDR=");
1502 1.5 cegger acpi_print_gas(&hpet->Address);
1503 1.5 cegger printf("\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID);
1504 1.5 cegger printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >>
1505 1.5 cegger 8);
1506 1.5 cegger printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ?
1507 1.5 cegger 1 : 0);
1508 1.5 cegger printf("\tLegacy IRQ routing capable={");
1509 1.5 cegger if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE)
1510 1.5 cegger printf("TRUE}\n");
1511 1.5 cegger else
1512 1.5 cegger printf("FALSE}\n");
1513 1.5 cegger printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16);
1514 1.5 cegger printf("\tMinimal Tick=%d\n", hpet->MinimumTick);
1515 1.16 msaitoh printf("\tFlags=0x%02x\n", hpet->Flags);
1516 1.5 cegger printf(END_COMMENT);
1517 1.5 cegger }
1518 1.5 cegger
1519 1.5 cegger static void
1520 1.5 cegger acpi_handle_msct(ACPI_TABLE_HEADER *sdp)
1521 1.5 cegger {
1522 1.5 cegger ACPI_TABLE_MSCT *msct;
1523 1.5 cegger ACPI_MSCT_PROXIMITY *msctentry;
1524 1.5 cegger uint32_t pos;
1525 1.5 cegger
1526 1.5 cegger printf(BEGIN_COMMENT);
1527 1.5 cegger acpi_print_sdt(sdp);
1528 1.5 cegger msct = (ACPI_TABLE_MSCT *)sdp;
1529 1.5 cegger
1530 1.5 cegger printf("\tProximity Offset=0x%x\n", msct->ProximityOffset);
1531 1.5 cegger printf("\tMax Proximity Domains=%d\n", msct->MaxProximityDomains);
1532 1.5 cegger printf("\tMax Clock Domains=%d\n", msct->MaxClockDomains);
1533 1.5 cegger printf("\tMax Physical Address=0x%"PRIx64"\n", msct->MaxAddress);
1534 1.5 cegger
1535 1.5 cegger pos = msct->ProximityOffset;
1536 1.5 cegger while (pos < msct->Header.Length) {
1537 1.5 cegger msctentry = (ACPI_MSCT_PROXIMITY *)((char *)msct + pos);
1538 1.5 cegger pos += msctentry->Length;
1539 1.5 cegger
1540 1.5 cegger printf("\n");
1541 1.5 cegger printf("\tRevision=%d\n", msctentry->Revision);
1542 1.5 cegger printf("\tLength=%d\n", msctentry->Length);
1543 1.5 cegger printf("\tRange Start=%d\n", msctentry->RangeStart);
1544 1.5 cegger printf("\tRange End=%d\n", msctentry->RangeEnd);
1545 1.5 cegger printf("\tProcessor Capacity=%d\n",
1546 1.5 cegger msctentry->ProcessorCapacity);
1547 1.5 cegger printf("\tMemory Capacity=0x%"PRIx64" byte\n",
1548 1.5 cegger msctentry->MemoryCapacity);
1549 1.5 cegger }
1550 1.1 christos
1551 1.5 cegger printf(END_COMMENT);
1552 1.5 cegger }
1553 1.1 christos
1554 1.5 cegger static void
1555 1.5 cegger acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp)
1556 1.5 cegger {
1557 1.5 cegger ACPI_TABLE_ECDT *ecdt;
1558 1.1 christos
1559 1.5 cegger printf(BEGIN_COMMENT);
1560 1.5 cegger acpi_print_sdt(sdp);
1561 1.5 cegger ecdt = (ACPI_TABLE_ECDT *)sdp;
1562 1.5 cegger printf("\tEC_CONTROL=");
1563 1.5 cegger acpi_print_gas(&ecdt->Control);
1564 1.5 cegger printf("\n\tEC_DATA=");
1565 1.5 cegger acpi_print_gas(&ecdt->Data);
1566 1.5 cegger printf("\n\tUID=%#x, ", ecdt->Uid);
1567 1.5 cegger printf("GPE_BIT=%#x\n", ecdt->Gpe);
1568 1.5 cegger printf("\tEC_ID=%s\n", ecdt->Id);
1569 1.5 cegger printf(END_COMMENT);
1570 1.5 cegger }
1571 1.1 christos
1572 1.5 cegger static void
1573 1.5 cegger acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp)
1574 1.5 cegger {
1575 1.5 cegger ACPI_TABLE_MCFG *mcfg;
1576 1.5 cegger ACPI_MCFG_ALLOCATION *alloc;
1577 1.5 cegger u_int i, entries;
1578 1.1 christos
1579 1.5 cegger printf(BEGIN_COMMENT);
1580 1.5 cegger acpi_print_sdt(sdp);
1581 1.5 cegger mcfg = (ACPI_TABLE_MCFG *)sdp;
1582 1.5 cegger entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) /
1583 1.5 cegger sizeof(ACPI_MCFG_ALLOCATION);
1584 1.5 cegger alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1);
1585 1.5 cegger for (i = 0; i < entries; i++, alloc++) {
1586 1.5 cegger printf("\n");
1587 1.16 msaitoh printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address);
1588 1.5 cegger printf("\tSegment Group=0x%04x\n", alloc->PciSegment);
1589 1.5 cegger printf("\tStart Bus=%d\n", alloc->StartBusNumber);
1590 1.5 cegger printf("\tEnd Bus=%d\n", alloc->EndBusNumber);
1591 1.5 cegger }
1592 1.5 cegger printf(END_COMMENT);
1593 1.5 cegger }
1594 1.1 christos
1595 1.1 christos static void
1596 1.5 cegger acpi_handle_sbst(ACPI_TABLE_HEADER *sdp)
1597 1.1 christos {
1598 1.5 cegger ACPI_TABLE_SBST *sbst;
1599 1.5 cegger
1600 1.5 cegger printf(BEGIN_COMMENT);
1601 1.5 cegger acpi_print_sdt(sdp);
1602 1.5 cegger sbst = (ACPI_TABLE_SBST *)sdp;
1603 1.5 cegger
1604 1.5 cegger printf("\tWarning Level=%d mWh\n", sbst->WarningLevel);
1605 1.5 cegger printf("\tLow Level=%d mWh\n", sbst->LowLevel);
1606 1.5 cegger printf("\tCritical Level=%d mWh\n", sbst->CriticalLevel);
1607 1.1 christos
1608 1.5 cegger printf(END_COMMENT);
1609 1.1 christos }
1610 1.1 christos
1611 1.1 christos static void
1612 1.5 cegger acpi_handle_slit(ACPI_TABLE_HEADER *sdp)
1613 1.1 christos {
1614 1.5 cegger ACPI_TABLE_SLIT *slit;
1615 1.5 cegger u_int idx;
1616 1.5 cegger uint64_t cnt;
1617 1.5 cegger
1618 1.5 cegger printf(BEGIN_COMMENT);
1619 1.5 cegger acpi_print_sdt(sdp);
1620 1.5 cegger slit = (ACPI_TABLE_SLIT *)sdp;
1621 1.1 christos
1622 1.5 cegger cnt = slit->LocalityCount * slit->LocalityCount;
1623 1.16 msaitoh printf("\tLocalityCount=%ju\n", (uintmax_t)slit->LocalityCount);
1624 1.5 cegger printf("\tEntry=\n\t");
1625 1.5 cegger for (idx = 0; idx < cnt; idx++) {
1626 1.5 cegger printf("%u ", slit->Entry[idx]);
1627 1.5 cegger if ((idx % slit->LocalityCount) == (slit->LocalityCount - 1)) {
1628 1.5 cegger printf("\n");
1629 1.5 cegger if (idx < cnt - 1)
1630 1.5 cegger printf("\t");
1631 1.5 cegger }
1632 1.5 cegger }
1633 1.1 christos
1634 1.5 cegger printf(END_COMMENT);
1635 1.1 christos }
1636 1.1 christos
1637 1.1 christos static void
1638 1.5 cegger acpi_handle_spcr(ACPI_TABLE_HEADER *sdp)
1639 1.1 christos {
1640 1.5 cegger ACPI_TABLE_SPCR *spcr;
1641 1.5 cegger
1642 1.5 cegger printf(BEGIN_COMMENT);
1643 1.5 cegger acpi_print_sdt(sdp);
1644 1.5 cegger spcr = (ACPI_TABLE_SPCR *)sdp;
1645 1.5 cegger
1646 1.5 cegger printf("\tSerial Port=");
1647 1.5 cegger acpi_print_gas(&spcr->SerialPort);
1648 1.5 cegger printf("\n\tInterrupt Type={");
1649 1.5 cegger if (spcr->InterruptType & 0x1) {
1650 1.5 cegger printf("\n\t\tdual-8259 IRQ=");
1651 1.5 cegger switch (spcr->PcInterrupt) {
1652 1.5 cegger case 2 ... 7:
1653 1.5 cegger case 9 ... 12:
1654 1.5 cegger case 14 ... 15:
1655 1.5 cegger printf("%d", spcr->PcInterrupt);
1656 1.5 cegger break;
1657 1.5 cegger default:
1658 1.5 cegger printf("%d (invalid entry)", spcr->PcInterrupt);
1659 1.5 cegger break;
1660 1.5 cegger }
1661 1.5 cegger }
1662 1.5 cegger if (spcr->InterruptType & 0x2) {
1663 1.5 cegger printf("\n\t\tIO APIC={ GSI=%d }", spcr->Interrupt);
1664 1.5 cegger }
1665 1.5 cegger if (spcr->InterruptType & 0x4) {
1666 1.5 cegger printf("\n\t\tIO SAPIC={ GSI=%d }", spcr->Interrupt);
1667 1.5 cegger }
1668 1.5 cegger printf("\n\t}\n");
1669 1.5 cegger
1670 1.5 cegger printf("\tBaud Rate=");
1671 1.5 cegger switch (spcr->BaudRate) {
1672 1.5 cegger case 3:
1673 1.5 cegger printf("9600");
1674 1.5 cegger break;
1675 1.5 cegger case 4:
1676 1.5 cegger printf("19200");
1677 1.5 cegger break;
1678 1.5 cegger case 6:
1679 1.5 cegger printf("57600");
1680 1.5 cegger break;
1681 1.5 cegger case 7:
1682 1.5 cegger printf("115200");
1683 1.5 cegger break;
1684 1.5 cegger default:
1685 1.5 cegger printf("unknown speed index %d", spcr->BaudRate);
1686 1.5 cegger break;
1687 1.5 cegger }
1688 1.5 cegger printf("\n\tParity={");
1689 1.5 cegger switch (spcr->Parity) {
1690 1.5 cegger case 0:
1691 1.5 cegger printf("OFF");
1692 1.5 cegger break;
1693 1.5 cegger default:
1694 1.5 cegger printf("ON");
1695 1.5 cegger break;
1696 1.5 cegger }
1697 1.5 cegger printf("}\n");
1698 1.5 cegger
1699 1.5 cegger printf("\tStop Bits={");
1700 1.5 cegger switch (spcr->StopBits) {
1701 1.5 cegger case 1:
1702 1.5 cegger printf("ON");
1703 1.5 cegger break;
1704 1.5 cegger default:
1705 1.5 cegger printf("OFF");
1706 1.5 cegger break;
1707 1.5 cegger }
1708 1.5 cegger printf("}\n");
1709 1.1 christos
1710 1.5 cegger printf("\tFlow Control={");
1711 1.5 cegger if (spcr->FlowControl & 0x1)
1712 1.5 cegger printf("DCD, ");
1713 1.5 cegger if (spcr->FlowControl & 0x2)
1714 1.5 cegger printf("RTS/CTS hardware, ");
1715 1.5 cegger if (spcr->FlowControl & 0x4)
1716 1.5 cegger printf("XON/XOFF software");
1717 1.5 cegger printf("}\n");
1718 1.1 christos
1719 1.5 cegger printf("\tTerminal=");
1720 1.5 cegger switch (spcr->TerminalType) {
1721 1.5 cegger case 0:
1722 1.5 cegger printf("VT100");
1723 1.5 cegger break;
1724 1.5 cegger case 1:
1725 1.5 cegger printf("VT100+");
1726 1.5 cegger break;
1727 1.5 cegger case 2:
1728 1.5 cegger printf("VT-UTF8");
1729 1.5 cegger break;
1730 1.5 cegger case 3:
1731 1.5 cegger printf("ANSI");
1732 1.5 cegger break;
1733 1.5 cegger default:
1734 1.5 cegger printf("unknown type %d", spcr->TerminalType);
1735 1.5 cegger break;
1736 1.1 christos }
1737 1.5 cegger printf("\n");
1738 1.5 cegger
1739 1.5 cegger acpi_print_pci(spcr->PciVendorId, spcr->PciDeviceId,
1740 1.5 cegger spcr->PciSegment, spcr->PciBus, spcr->PciDevice, spcr->PciFunction);
1741 1.5 cegger
1742 1.5 cegger printf("\tPCI Flags={");
1743 1.5 cegger if (spcr->PciFlags & ACPI_SPCR_DO_NOT_DISABLE)
1744 1.5 cegger printf("DONOT_DISABLE");
1745 1.5 cegger printf("}\n");
1746 1.5 cegger
1747 1.5 cegger printf(END_COMMENT);
1748 1.5 cegger }
1749 1.5 cegger
1750 1.5 cegger static void
1751 1.5 cegger acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
1752 1.5 cegger uint32_t flags, uint32_t clockdomain)
1753 1.5 cegger {
1754 1.5 cegger
1755 1.5 cegger printf("\tFlags={");
1756 1.5 cegger if (flags & ACPI_SRAT_CPU_ENABLED)
1757 1.5 cegger printf("ENABLED");
1758 1.5 cegger else
1759 1.5 cegger printf("DISABLED");
1760 1.5 cegger printf("}\n");
1761 1.5 cegger printf("\tAPIC ID=%d\n", apic_id);
1762 1.5 cegger printf("\tProximity Domain=%d\n", proximity_domain);
1763 1.5 cegger printf("\tClock Domain=%d\n", clockdomain);
1764 1.5 cegger }
1765 1.5 cegger
1766 1.5 cegger static void
1767 1.5 cegger acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp)
1768 1.5 cegger {
1769 1.5 cegger
1770 1.5 cegger printf("\tFlags={");
1771 1.5 cegger if (mp->Flags & ACPI_SRAT_MEM_ENABLED)
1772 1.5 cegger printf("ENABLED");
1773 1.5 cegger else
1774 1.5 cegger printf("DISABLED");
1775 1.5 cegger if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
1776 1.5 cegger printf(",HOT_PLUGGABLE");
1777 1.5 cegger if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE)
1778 1.5 cegger printf(",NON_VOLATILE");
1779 1.5 cegger printf("}\n");
1780 1.5 cegger printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress);
1781 1.5 cegger printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length);
1782 1.5 cegger printf("\tProximity Domain=%d\n", mp->ProximityDomain);
1783 1.1 christos }
1784 1.1 christos
1785 1.16 msaitoh static const char *srat_types[] = {
1786 1.16 msaitoh [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU",
1787 1.16 msaitoh [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory",
1788 1.16 msaitoh [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC",
1789 1.16 msaitoh [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC",
1790 1.16 msaitoh };
1791 1.5 cegger
1792 1.1 christos static void
1793 1.5 cegger acpi_print_srat(ACPI_SUBTABLE_HEADER *srat)
1794 1.1 christos {
1795 1.5 cegger ACPI_SRAT_CPU_AFFINITY *cpu;
1796 1.5 cegger ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
1797 1.16 msaitoh ACPI_SRAT_GICC_AFFINITY *gic;
1798 1.5 cegger
1799 1.16 msaitoh if (srat->Type < __arraycount(srat_types))
1800 1.5 cegger printf("\tType=%s\n", srat_types[srat->Type]);
1801 1.5 cegger else
1802 1.5 cegger printf("\tType=%d (unknown)\n", srat->Type);
1803 1.5 cegger switch (srat->Type) {
1804 1.5 cegger case ACPI_SRAT_TYPE_CPU_AFFINITY:
1805 1.5 cegger cpu = (ACPI_SRAT_CPU_AFFINITY *)srat;
1806 1.5 cegger acpi_print_srat_cpu(cpu->ApicId,
1807 1.5 cegger cpu->ProximityDomainHi[2] << 24 |
1808 1.5 cegger cpu->ProximityDomainHi[1] << 16 |
1809 1.5 cegger cpu->ProximityDomainHi[0] << 0 |
1810 1.5 cegger cpu->ProximityDomainLo,
1811 1.5 cegger cpu->Flags, cpu->ClockDomain);
1812 1.5 cegger break;
1813 1.5 cegger case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1814 1.5 cegger acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat);
1815 1.5 cegger break;
1816 1.5 cegger case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1817 1.5 cegger x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat;
1818 1.5 cegger acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain,
1819 1.5 cegger x2apic->Flags, x2apic->ClockDomain);
1820 1.5 cegger break;
1821 1.16 msaitoh case ACPI_SRAT_TYPE_GICC_AFFINITY:
1822 1.16 msaitoh gic = (ACPI_SRAT_GICC_AFFINITY *)srat;
1823 1.16 msaitoh acpi_print_srat_cpu(gic->AcpiProcessorUid, gic->ProximityDomain,
1824 1.16 msaitoh gic->Flags, gic->ClockDomain);
1825 1.16 msaitoh break;
1826 1.5 cegger }
1827 1.5 cegger }
1828 1.1 christos
1829 1.5 cegger static void
1830 1.5 cegger acpi_handle_srat(ACPI_TABLE_HEADER *sdp)
1831 1.5 cegger {
1832 1.5 cegger ACPI_TABLE_SRAT *srat;
1833 1.1 christos
1834 1.5 cegger printf(BEGIN_COMMENT);
1835 1.5 cegger acpi_print_sdt(sdp);
1836 1.5 cegger srat = (ACPI_TABLE_SRAT *)sdp;
1837 1.5 cegger printf("\tTable Revision=%d\n", srat->TableRevision);
1838 1.5 cegger acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat);
1839 1.5 cegger printf(END_COMMENT);
1840 1.1 christos }
1841 1.1 christos
1842 1.16 msaitoh static char *
1843 1.16 msaitoh acpi_tcpa_evname(struct TCPAevent *event)
1844 1.16 msaitoh {
1845 1.16 msaitoh struct TCPApc_event *pc_event;
1846 1.16 msaitoh char *eventname = NULL;
1847 1.16 msaitoh
1848 1.16 msaitoh pc_event = (struct TCPApc_event *)(event + 1);
1849 1.16 msaitoh
1850 1.16 msaitoh switch(event->event_type) {
1851 1.16 msaitoh case PREBOOT:
1852 1.16 msaitoh case POST_CODE:
1853 1.16 msaitoh case UNUSED:
1854 1.16 msaitoh case NO_ACTION:
1855 1.16 msaitoh case SEPARATOR:
1856 1.16 msaitoh case SCRTM_CONTENTS:
1857 1.16 msaitoh case SCRTM_VERSION:
1858 1.16 msaitoh case CPU_MICROCODE:
1859 1.16 msaitoh case PLATFORM_CONFIG_FLAGS:
1860 1.16 msaitoh case TABLE_OF_DEVICES:
1861 1.16 msaitoh case COMPACT_HASH:
1862 1.16 msaitoh case IPL:
1863 1.16 msaitoh case IPL_PARTITION_DATA:
1864 1.16 msaitoh case NONHOST_CODE:
1865 1.16 msaitoh case NONHOST_CONFIG:
1866 1.16 msaitoh case NONHOST_INFO:
1867 1.16 msaitoh asprintf(&eventname, "%s",
1868 1.16 msaitoh tcpa_event_type_strings[event->event_type]);
1869 1.16 msaitoh break;
1870 1.16 msaitoh
1871 1.16 msaitoh case ACTION:
1872 1.16 msaitoh eventname = calloc(event->event_size + 1, sizeof(char));
1873 1.16 msaitoh memcpy(eventname, pc_event, event->event_size);
1874 1.16 msaitoh break;
1875 1.16 msaitoh
1876 1.16 msaitoh case EVENT_TAG:
1877 1.16 msaitoh switch (pc_event->event_id) {
1878 1.16 msaitoh case SMBIOS:
1879 1.16 msaitoh case BIS_CERT:
1880 1.16 msaitoh case CMOS:
1881 1.16 msaitoh case NVRAM:
1882 1.16 msaitoh case OPTION_ROM_EXEC:
1883 1.16 msaitoh case OPTION_ROM_CONFIG:
1884 1.16 msaitoh case S_CRTM_VERSION:
1885 1.16 msaitoh case POST_BIOS_ROM:
1886 1.16 msaitoh case ESCD:
1887 1.16 msaitoh case OPTION_ROM_MICROCODE:
1888 1.16 msaitoh case S_CRTM_CONTENTS:
1889 1.16 msaitoh case POST_CONTENTS:
1890 1.16 msaitoh asprintf(&eventname, "%s",
1891 1.16 msaitoh TCPA_pcclient_strings[pc_event->event_id]);
1892 1.16 msaitoh break;
1893 1.16 msaitoh
1894 1.16 msaitoh default:
1895 1.16 msaitoh asprintf(&eventname, "<unknown tag 0x%02x>",
1896 1.16 msaitoh pc_event->event_id);
1897 1.16 msaitoh break;
1898 1.16 msaitoh }
1899 1.16 msaitoh break;
1900 1.16 msaitoh
1901 1.16 msaitoh default:
1902 1.16 msaitoh asprintf(&eventname, "<unknown 0x%02x>", event->event_type);
1903 1.16 msaitoh break;
1904 1.16 msaitoh }
1905 1.16 msaitoh
1906 1.16 msaitoh return eventname;
1907 1.16 msaitoh }
1908 1.16 msaitoh
1909 1.16 msaitoh static void
1910 1.16 msaitoh acpi_print_tcpa(struct TCPAevent *event)
1911 1.16 msaitoh {
1912 1.16 msaitoh int i;
1913 1.16 msaitoh char *eventname;
1914 1.16 msaitoh
1915 1.16 msaitoh eventname = acpi_tcpa_evname(event);
1916 1.16 msaitoh
1917 1.16 msaitoh printf("\t%d", event->pcr_index);
1918 1.16 msaitoh printf(" 0x");
1919 1.16 msaitoh for (i = 0; i < 20; i++)
1920 1.16 msaitoh printf("%02x", event->pcr_value[i]);
1921 1.16 msaitoh printf(" [%s]\n", eventname ? eventname : "<unknown>");
1922 1.16 msaitoh
1923 1.16 msaitoh free(eventname);
1924 1.16 msaitoh }
1925 1.16 msaitoh
1926 1.1 christos static void
1927 1.5 cegger acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp)
1928 1.1 christos {
1929 1.16 msaitoh struct TCPAbody *tcpa;
1930 1.16 msaitoh struct TCPAevent *event;
1931 1.16 msaitoh uintmax_t len, paddr;
1932 1.16 msaitoh unsigned char *vaddr = NULL;
1933 1.16 msaitoh unsigned char *vend = NULL;
1934 1.5 cegger
1935 1.5 cegger printf(BEGIN_COMMENT);
1936 1.5 cegger acpi_print_sdt(sdp);
1937 1.16 msaitoh tcpa = (struct TCPAbody *) sdp;
1938 1.16 msaitoh
1939 1.16 msaitoh switch (tcpa->platform_class) {
1940 1.16 msaitoh case ACPI_TCPA_BIOS_CLIENT:
1941 1.16 msaitoh len = tcpa->client.log_max_len;
1942 1.16 msaitoh paddr = tcpa->client.log_start_addr;
1943 1.13 christos break;
1944 1.13 christos
1945 1.16 msaitoh case ACPI_TCPA_BIOS_SERVER:
1946 1.16 msaitoh len = tcpa->server.log_max_len;
1947 1.16 msaitoh paddr = tcpa->server.log_start_addr;
1948 1.13 christos break;
1949 1.13 christos
1950 1.13 christos default:
1951 1.16 msaitoh printf("XXX");
1952 1.16 msaitoh printf(END_COMMENT);
1953 1.16 msaitoh return;
1954 1.16 msaitoh }
1955 1.16 msaitoh printf("\tClass %u Base Address 0x%jx Length %ju\n\n",
1956 1.16 msaitoh tcpa->platform_class, paddr, len);
1957 1.16 msaitoh
1958 1.16 msaitoh if (len == 0) {
1959 1.16 msaitoh printf("\tEmpty TCPA table\n");
1960 1.16 msaitoh printf(END_COMMENT);
1961 1.16 msaitoh return;
1962 1.16 msaitoh }
1963 1.16 msaitoh if(sdp->Revision == 1) {
1964 1.16 msaitoh printf("\tOLD TCPA spec log found. Dumping not supported.\n");
1965 1.16 msaitoh printf(END_COMMENT);
1966 1.16 msaitoh return;
1967 1.16 msaitoh }
1968 1.16 msaitoh
1969 1.16 msaitoh vaddr = (unsigned char *)acpi_map_physical(paddr, len);
1970 1.16 msaitoh vend = vaddr + len;
1971 1.16 msaitoh
1972 1.16 msaitoh while (vaddr != NULL) {
1973 1.16 msaitoh if ((vaddr + sizeof(struct TCPAevent) >= vend)||
1974 1.16 msaitoh (vaddr + sizeof(struct TCPAevent) < vaddr))
1975 1.16 msaitoh break;
1976 1.16 msaitoh event = (struct TCPAevent *)(void *)vaddr;
1977 1.16 msaitoh if (vaddr + event->event_size >= vend)
1978 1.16 msaitoh break;
1979 1.16 msaitoh if (vaddr + event->event_size < vaddr)
1980 1.16 msaitoh break;
1981 1.16 msaitoh if (event->event_type == 0 && event->event_size == 0)
1982 1.16 msaitoh break;
1983 1.16 msaitoh #if 0
1984 1.16 msaitoh {
1985 1.16 msaitoh unsigned int i, j, k;
1986 1.16 msaitoh
1987 1.16 msaitoh printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr);
1988 1.16 msaitoh for (j = 0, i = 0; i <
1989 1.16 msaitoh sizeof(struct TCPAevent) + event->event_size; i++) {
1990 1.16 msaitoh printf("%02x ", vaddr[i]);
1991 1.16 msaitoh if ((i+1) % 8 == 0) {
1992 1.16 msaitoh for (k = 0; k < 8; k++)
1993 1.16 msaitoh printf("%c", isprint(vaddr[j+k]) ?
1994 1.16 msaitoh vaddr[j+k] : '.');
1995 1.16 msaitoh printf("\n\t\t%p ", &vaddr[i + 1]);
1996 1.16 msaitoh j = i + 1;
1997 1.16 msaitoh }
1998 1.16 msaitoh }
1999 1.16 msaitoh printf("\n"); }
2000 1.16 msaitoh #endif
2001 1.16 msaitoh acpi_print_tcpa(event);
2002 1.16 msaitoh
2003 1.16 msaitoh vaddr += sizeof(struct TCPAevent) + event->event_size;
2004 1.16 msaitoh }
2005 1.16 msaitoh
2006 1.16 msaitoh printf(END_COMMENT);
2007 1.16 msaitoh }
2008 1.16 msaitoh
2009 1.16 msaitoh static const char *
2010 1.16 msaitoh devscope_type2str(int type)
2011 1.16 msaitoh {
2012 1.16 msaitoh static char typebuf[16];
2013 1.16 msaitoh
2014 1.16 msaitoh switch (type) {
2015 1.16 msaitoh case 1:
2016 1.16 msaitoh return ("PCI Endpoint Device");
2017 1.16 msaitoh case 2:
2018 1.16 msaitoh return ("PCI Sub-Hierarchy");
2019 1.16 msaitoh case 3:
2020 1.16 msaitoh return ("IOAPIC");
2021 1.16 msaitoh case 4:
2022 1.16 msaitoh return ("HPET");
2023 1.16 msaitoh default:
2024 1.16 msaitoh snprintf(typebuf, sizeof(typebuf), "%d", type);
2025 1.16 msaitoh return (typebuf);
2026 1.16 msaitoh }
2027 1.16 msaitoh }
2028 1.16 msaitoh
2029 1.16 msaitoh static int
2030 1.16 msaitoh acpi_handle_dmar_devscope(void *addr, int remaining)
2031 1.16 msaitoh {
2032 1.16 msaitoh char sep;
2033 1.16 msaitoh int pathlen;
2034 1.16 msaitoh ACPI_DMAR_PCI_PATH *path, *pathend;
2035 1.16 msaitoh ACPI_DMAR_DEVICE_SCOPE *devscope = addr;
2036 1.16 msaitoh
2037 1.16 msaitoh if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE))
2038 1.16 msaitoh return (-1);
2039 1.16 msaitoh
2040 1.16 msaitoh if (remaining < devscope->Length)
2041 1.16 msaitoh return (-1);
2042 1.16 msaitoh
2043 1.16 msaitoh printf("\n");
2044 1.16 msaitoh printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType));
2045 1.16 msaitoh printf("\t\tLength=%d\n", devscope->Length);
2046 1.16 msaitoh printf("\t\tEnumerationId=%d\n", devscope->EnumerationId);
2047 1.16 msaitoh printf("\t\tStartBusNumber=%d\n", devscope->Bus);
2048 1.16 msaitoh
2049 1.16 msaitoh path = (ACPI_DMAR_PCI_PATH *)(devscope + 1);
2050 1.16 msaitoh pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE);
2051 1.16 msaitoh pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH);
2052 1.16 msaitoh if (path < pathend) {
2053 1.16 msaitoh sep = '{';
2054 1.16 msaitoh printf("\t\tPath=");
2055 1.16 msaitoh do {
2056 1.16 msaitoh printf("%c%d:%d", sep, path->Device, path->Function);
2057 1.16 msaitoh sep=',';
2058 1.16 msaitoh path++;
2059 1.16 msaitoh } while (path < pathend);
2060 1.16 msaitoh printf("}\n");
2061 1.16 msaitoh }
2062 1.16 msaitoh
2063 1.16 msaitoh return (devscope->Length);
2064 1.16 msaitoh }
2065 1.16 msaitoh
2066 1.16 msaitoh static void
2067 1.16 msaitoh acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd)
2068 1.16 msaitoh {
2069 1.16 msaitoh char *cp;
2070 1.16 msaitoh int remaining, consumed;
2071 1.16 msaitoh
2072 1.16 msaitoh printf("\n");
2073 1.16 msaitoh printf("\tType=DRHD\n");
2074 1.16 msaitoh printf("\tLength=%d\n", drhd->Header.Length);
2075 1.16 msaitoh
2076 1.16 msaitoh #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag)
2077 1.16 msaitoh
2078 1.16 msaitoh printf("\tFlags=");
2079 1.16 msaitoh PRINTFLAG(drhd->Flags, INCLUDE_ALL);
2080 1.16 msaitoh PRINTFLAG_END();
2081 1.16 msaitoh
2082 1.16 msaitoh #undef PRINTFLAG
2083 1.16 msaitoh
2084 1.16 msaitoh printf("\tSegment=%d\n", drhd->Segment);
2085 1.16 msaitoh printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address);
2086 1.16 msaitoh
2087 1.16 msaitoh remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT);
2088 1.16 msaitoh if (remaining > 0)
2089 1.16 msaitoh printf("\tDevice Scope:");
2090 1.16 msaitoh while (remaining > 0) {
2091 1.16 msaitoh cp = (char *)drhd + drhd->Header.Length - remaining;
2092 1.16 msaitoh consumed = acpi_handle_dmar_devscope(cp, remaining);
2093 1.16 msaitoh if (consumed <= 0)
2094 1.16 msaitoh break;
2095 1.16 msaitoh else
2096 1.16 msaitoh remaining -= consumed;
2097 1.16 msaitoh }
2098 1.16 msaitoh }
2099 1.16 msaitoh
2100 1.16 msaitoh static void
2101 1.16 msaitoh acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr)
2102 1.16 msaitoh {
2103 1.16 msaitoh char *cp;
2104 1.16 msaitoh int remaining, consumed;
2105 1.16 msaitoh
2106 1.16 msaitoh printf("\n");
2107 1.16 msaitoh printf("\tType=RMRR\n");
2108 1.16 msaitoh printf("\tLength=%d\n", rmrr->Header.Length);
2109 1.16 msaitoh printf("\tSegment=%d\n", rmrr->Segment);
2110 1.16 msaitoh printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress);
2111 1.16 msaitoh printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress);
2112 1.16 msaitoh
2113 1.16 msaitoh remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY);
2114 1.16 msaitoh if (remaining > 0)
2115 1.16 msaitoh printf("\tDevice Scope:");
2116 1.16 msaitoh while (remaining > 0) {
2117 1.16 msaitoh cp = (char *)rmrr + rmrr->Header.Length - remaining;
2118 1.16 msaitoh consumed = acpi_handle_dmar_devscope(cp, remaining);
2119 1.16 msaitoh if (consumed <= 0)
2120 1.16 msaitoh break;
2121 1.16 msaitoh else
2122 1.16 msaitoh remaining -= consumed;
2123 1.16 msaitoh }
2124 1.16 msaitoh }
2125 1.16 msaitoh
2126 1.16 msaitoh static void
2127 1.16 msaitoh acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr)
2128 1.16 msaitoh {
2129 1.16 msaitoh char *cp;
2130 1.16 msaitoh int remaining, consumed;
2131 1.16 msaitoh
2132 1.16 msaitoh printf("\n");
2133 1.16 msaitoh printf("\tType=ATSR\n");
2134 1.16 msaitoh printf("\tLength=%d\n", atsr->Header.Length);
2135 1.16 msaitoh
2136 1.16 msaitoh #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag)
2137 1.16 msaitoh
2138 1.16 msaitoh printf("\tFlags=");
2139 1.16 msaitoh PRINTFLAG(atsr->Flags, ALL_PORTS);
2140 1.16 msaitoh PRINTFLAG_END();
2141 1.16 msaitoh
2142 1.16 msaitoh #undef PRINTFLAG
2143 1.16 msaitoh
2144 1.16 msaitoh printf("\tSegment=%d\n", atsr->Segment);
2145 1.16 msaitoh
2146 1.16 msaitoh remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR);
2147 1.16 msaitoh if (remaining > 0)
2148 1.16 msaitoh printf("\tDevice Scope:");
2149 1.16 msaitoh while (remaining > 0) {
2150 1.16 msaitoh cp = (char *)atsr + atsr->Header.Length - remaining;
2151 1.16 msaitoh consumed = acpi_handle_dmar_devscope(cp, remaining);
2152 1.16 msaitoh if (consumed <= 0)
2153 1.16 msaitoh break;
2154 1.16 msaitoh else
2155 1.16 msaitoh remaining -= consumed;
2156 1.16 msaitoh }
2157 1.16 msaitoh }
2158 1.16 msaitoh
2159 1.16 msaitoh static void
2160 1.16 msaitoh acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa)
2161 1.16 msaitoh {
2162 1.16 msaitoh
2163 1.16 msaitoh printf("\n");
2164 1.16 msaitoh printf("\tType=RHSA\n");
2165 1.16 msaitoh printf("\tLength=%d\n", rhsa->Header.Length);
2166 1.16 msaitoh printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress);
2167 1.16 msaitoh printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain);
2168 1.16 msaitoh }
2169 1.16 msaitoh
2170 1.16 msaitoh static int
2171 1.16 msaitoh acpi_handle_dmar_remapping_structure(void *addr, int remaining)
2172 1.16 msaitoh {
2173 1.16 msaitoh ACPI_DMAR_HEADER *hdr = addr;
2174 1.16 msaitoh
2175 1.16 msaitoh if (remaining < (int)sizeof(ACPI_DMAR_HEADER))
2176 1.16 msaitoh return (-1);
2177 1.16 msaitoh
2178 1.16 msaitoh if (remaining < hdr->Length)
2179 1.16 msaitoh return (-1);
2180 1.16 msaitoh
2181 1.16 msaitoh switch (hdr->Type) {
2182 1.16 msaitoh case ACPI_DMAR_TYPE_HARDWARE_UNIT:
2183 1.16 msaitoh acpi_handle_dmar_drhd(addr);
2184 1.16 msaitoh break;
2185 1.16 msaitoh case ACPI_DMAR_TYPE_RESERVED_MEMORY:
2186 1.16 msaitoh acpi_handle_dmar_rmrr(addr);
2187 1.16 msaitoh break;
2188 1.16 msaitoh case ACPI_DMAR_TYPE_ROOT_ATS:
2189 1.16 msaitoh acpi_handle_dmar_atsr(addr);
2190 1.16 msaitoh break;
2191 1.16 msaitoh case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
2192 1.16 msaitoh acpi_handle_dmar_rhsa(addr);
2193 1.16 msaitoh break;
2194 1.16 msaitoh default:
2195 1.16 msaitoh printf("\n");
2196 1.16 msaitoh printf("\tType=%d\n", hdr->Type);
2197 1.16 msaitoh printf("\tLength=%d\n", hdr->Length);
2198 1.13 christos break;
2199 1.13 christos }
2200 1.16 msaitoh return (hdr->Length);
2201 1.16 msaitoh }
2202 1.16 msaitoh
2203 1.16 msaitoh #ifndef ACPI_DMAR_X2APIC_OPT_OUT
2204 1.16 msaitoh #define ACPI_DMAR_X2APIC_OPT_OUT (0x2)
2205 1.16 msaitoh #endif
2206 1.16 msaitoh
2207 1.16 msaitoh static void
2208 1.16 msaitoh acpi_handle_dmar(ACPI_TABLE_HEADER *sdp)
2209 1.16 msaitoh {
2210 1.16 msaitoh char *cp;
2211 1.16 msaitoh int remaining, consumed;
2212 1.16 msaitoh ACPI_TABLE_DMAR *dmar;
2213 1.16 msaitoh
2214 1.16 msaitoh printf(BEGIN_COMMENT);
2215 1.16 msaitoh acpi_print_sdt(sdp);
2216 1.16 msaitoh dmar = (ACPI_TABLE_DMAR *)sdp;
2217 1.16 msaitoh printf("\tHost Address Width=%d\n", dmar->Width + 1);
2218 1.16 msaitoh
2219 1.16 msaitoh #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag)
2220 1.16 msaitoh
2221 1.16 msaitoh printf("\tFlags=");
2222 1.16 msaitoh PRINTFLAG(dmar->Flags, INTR_REMAP);
2223 1.16 msaitoh PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT);
2224 1.16 msaitoh PRINTFLAG_END();
2225 1.16 msaitoh
2226 1.16 msaitoh #undef PRINTFLAG
2227 1.16 msaitoh
2228 1.16 msaitoh remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR);
2229 1.16 msaitoh while (remaining > 0) {
2230 1.16 msaitoh cp = (char *)sdp + sdp->Length - remaining;
2231 1.16 msaitoh consumed = acpi_handle_dmar_remapping_structure(cp, remaining);
2232 1.16 msaitoh if (consumed <= 0)
2233 1.16 msaitoh break;
2234 1.16 msaitoh else
2235 1.16 msaitoh remaining -= consumed;
2236 1.16 msaitoh }
2237 1.1 christos
2238 1.12 christos printf(END_COMMENT);
2239 1.1 christos }
2240 1.1 christos
2241 1.1 christos static void
2242 1.5 cegger acpi_handle_waet(ACPI_TABLE_HEADER *sdp)
2243 1.1 christos {
2244 1.5 cegger ACPI_TABLE_WAET *waet;
2245 1.5 cegger
2246 1.5 cegger printf(BEGIN_COMMENT);
2247 1.5 cegger acpi_print_sdt(sdp);
2248 1.5 cegger waet = (ACPI_TABLE_WAET *)sdp;
2249 1.1 christos
2250 1.5 cegger printf("\tRTC Timer={");
2251 1.5 cegger if (waet->Flags & ACPI_WAET_RTC_NO_ACK)
2252 1.5 cegger printf("No ACK required");
2253 1.5 cegger else
2254 1.5 cegger printf("default behaviour");
2255 1.5 cegger printf("}\n");
2256 1.5 cegger printf("\t ACPI PM Timer={");
2257 1.5 cegger if (waet->Flags & ACPI_WAET_TIMER_ONE_READ)
2258 1.5 cegger printf("One Read sufficient");
2259 1.5 cegger else
2260 1.5 cegger printf("default behaviour");
2261 1.5 cegger printf("}\n");
2262 1.3 joerg
2263 1.5 cegger printf(END_COMMENT);
2264 1.1 christos }
2265 1.1 christos
2266 1.5 cegger static void
2267 1.5 cegger acpi_print_wdat_action(ACPI_WHEA_HEADER *whea)
2268 1.5 cegger {
2269 1.5 cegger printf("\tACTION={");
2270 1.5 cegger switch (whea->Action) {
2271 1.5 cegger case ACPI_WDAT_RESET:
2272 1.5 cegger printf("RESET");
2273 1.5 cegger break;
2274 1.5 cegger case ACPI_WDAT_GET_CURRENT_COUNTDOWN:
2275 1.5 cegger printf("GET_CURRENT_COUNTDOWN");
2276 1.5 cegger break;
2277 1.5 cegger case ACPI_WDAT_GET_COUNTDOWN:
2278 1.5 cegger printf("GET_COUNTDOWN");
2279 1.5 cegger break;
2280 1.5 cegger case ACPI_WDAT_SET_COUNTDOWN:
2281 1.5 cegger printf("SET_COUNTDOWN");
2282 1.5 cegger break;
2283 1.5 cegger case ACPI_WDAT_GET_RUNNING_STATE:
2284 1.5 cegger printf("GET_RUNNING_STATE");
2285 1.5 cegger break;
2286 1.5 cegger case ACPI_WDAT_SET_RUNNING_STATE:
2287 1.5 cegger printf("SET_RUNNING_STATE");
2288 1.5 cegger break;
2289 1.5 cegger case ACPI_WDAT_GET_STOPPED_STATE:
2290 1.5 cegger printf("GET_STOPPED_STATE");
2291 1.5 cegger break;
2292 1.5 cegger case ACPI_WDAT_SET_STOPPED_STATE:
2293 1.5 cegger printf("SET_STOPPED_STATE");
2294 1.5 cegger break;
2295 1.5 cegger case ACPI_WDAT_GET_REBOOT:
2296 1.5 cegger printf("GET_REBOOT");
2297 1.5 cegger break;
2298 1.5 cegger case ACPI_WDAT_SET_REBOOT:
2299 1.5 cegger printf("SET_REBOOT");
2300 1.5 cegger break;
2301 1.5 cegger case ACPI_WDAT_GET_SHUTDOWN:
2302 1.5 cegger printf("GET_SHUTDOWN");
2303 1.5 cegger break;
2304 1.5 cegger case ACPI_WDAT_SET_SHUTDOWN:
2305 1.5 cegger printf("SET_SHUTDOWN");
2306 1.5 cegger break;
2307 1.5 cegger case ACPI_WDAT_GET_STATUS:
2308 1.5 cegger printf("GET_STATUS");
2309 1.5 cegger break;
2310 1.5 cegger case ACPI_WDAT_SET_STATUS:
2311 1.5 cegger printf("SET_STATUS");
2312 1.5 cegger break;
2313 1.5 cegger case ACPI_WDAT_ACTION_RESERVED:
2314 1.5 cegger printf("ACTION_RESERVED");
2315 1.5 cegger break;
2316 1.5 cegger default:
2317 1.5 cegger printf("%d", whea->Action);
2318 1.5 cegger break;
2319 1.5 cegger }
2320 1.5 cegger printf("}\n");
2321 1.5 cegger }
2322 1.1 christos
2323 1.5 cegger static void
2324 1.5 cegger acpi_print_wdat_instruction(ACPI_WHEA_HEADER *whea)
2325 1.1 christos {
2326 1.5 cegger uint32_t ins;
2327 1.5 cegger
2328 1.5 cegger ins = whea->Instruction & ~ACPI_WDAT_PRESERVE_REGISTER;
2329 1.5 cegger
2330 1.5 cegger printf("\tINSTRUCTION={");
2331 1.5 cegger switch (ins) {
2332 1.5 cegger case ACPI_WDAT_READ_VALUE:
2333 1.5 cegger printf("READ_VALUE");
2334 1.5 cegger break;
2335 1.5 cegger case ACPI_WDAT_READ_COUNTDOWN:
2336 1.5 cegger printf("READ_COUNTDOWN");
2337 1.5 cegger break;
2338 1.5 cegger case ACPI_WDAT_WRITE_VALUE:
2339 1.5 cegger printf("WRITE_VALUE");
2340 1.5 cegger break;
2341 1.5 cegger case ACPI_WDAT_WRITE_COUNTDOWN:
2342 1.5 cegger printf("WRITE_COUNTDOWN");
2343 1.5 cegger break;
2344 1.5 cegger case ACPI_WDAT_INSTRUCTION_RESERVED:
2345 1.5 cegger printf("INSTRUCTION_RESERVED");
2346 1.5 cegger break;
2347 1.5 cegger default:
2348 1.5 cegger printf("%d", ins);
2349 1.5 cegger break;
2350 1.5 cegger }
2351 1.5 cegger
2352 1.5 cegger if (whea->Instruction & ACPI_WDAT_PRESERVE_REGISTER)
2353 1.5 cegger printf(", Preserve Register ");
2354 1.5 cegger
2355 1.5 cegger printf("}\n");
2356 1.5 cegger }
2357 1.1 christos
2358 1.5 cegger static void
2359 1.5 cegger acpi_handle_wdat(ACPI_TABLE_HEADER *sdp)
2360 1.5 cegger {
2361 1.5 cegger ACPI_TABLE_WDAT *wdat;
2362 1.5 cegger ACPI_WHEA_HEADER *whea;
2363 1.5 cegger char *wdat_pos;
2364 1.5 cegger u_int i;
2365 1.1 christos
2366 1.5 cegger printf(BEGIN_COMMENT);
2367 1.5 cegger acpi_print_sdt(sdp);
2368 1.5 cegger wdat = (ACPI_TABLE_WDAT *)sdp;
2369 1.1 christos
2370 1.5 cegger printf("\tHeader Length=%d\n", wdat->HeaderLength);
2371 1.1 christos
2372 1.5 cegger acpi_print_pci_sbfd(wdat->PciSegment, wdat->PciBus, wdat->PciDevice,
2373 1.5 cegger wdat->PciFunction);
2374 1.5 cegger printf("\n\tTimer Counter Period=%d msec\n", wdat->TimerPeriod);
2375 1.5 cegger printf("\tTimer Maximum Counter Value=%d\n", wdat->MaxCount);
2376 1.5 cegger printf("\tTimer Minimum Counter Value=%d\n", wdat->MinCount);
2377 1.5 cegger
2378 1.5 cegger printf("\tFlags={");
2379 1.5 cegger if (wdat->Flags & ACPI_WDAT_ENABLED)
2380 1.5 cegger printf("ENABLED");
2381 1.5 cegger if (wdat->Flags & ACPI_WDAT_STOPPED)
2382 1.5 cegger printf(", STOPPED");
2383 1.5 cegger printf("}\n");
2384 1.1 christos
2385 1.5 cegger wdat_pos = ((char *)wdat + sizeof(ACPI_TABLE_HEADER)
2386 1.5 cegger + wdat->HeaderLength);
2387 1.1 christos
2388 1.5 cegger for (i = 0; i < wdat->Entries; i++) {
2389 1.5 cegger whea = (ACPI_WHEA_HEADER *)wdat_pos;
2390 1.5 cegger acpi_print_whea(whea,
2391 1.5 cegger acpi_print_wdat_action, acpi_print_wdat_instruction,
2392 1.5 cegger NULL);
2393 1.5 cegger wdat_pos += sizeof(ACPI_WDAT_ENTRY);
2394 1.5 cegger }
2395 1.5 cegger printf(END_COMMENT);
2396 1.1 christos }
2397 1.5 cegger
2398 1.5 cegger static void
2399 1.5 cegger acpi_handle_wdrt(ACPI_TABLE_HEADER *sdp)
2400 1.1 christos {
2401 1.5 cegger ACPI_TABLE_WDRT *wdrt;
2402 1.1 christos
2403 1.1 christos printf(BEGIN_COMMENT);
2404 1.5 cegger acpi_print_sdt(sdp);
2405 1.5 cegger wdrt = (ACPI_TABLE_WDRT *)sdp;
2406 1.5 cegger
2407 1.5 cegger printf("\tControl Register=");
2408 1.5 cegger acpi_print_gas(&wdrt->ControlRegister);
2409 1.5 cegger printf("\tCount Register=");
2410 1.5 cegger acpi_print_gas(&wdrt->CountRegister);
2411 1.5 cegger acpi_print_pci(wdrt->PciVendorId, wdrt->PciDeviceId,
2412 1.5 cegger wdrt->PciSegment, wdrt->PciBus, wdrt->PciDevice, wdrt->PciFunction);
2413 1.5 cegger
2414 1.5 cegger /* Value must be >= 511 and < 65535 */
2415 1.5 cegger printf("\tMaxCount=%d", wdrt->MaxCount);
2416 1.5 cegger if (wdrt->MaxCount < 511)
2417 1.5 cegger printf(" (Out of Range. Valid range: 511 <= maxcount < 65535)");
2418 1.5 cegger printf("\n");
2419 1.5 cegger
2420 1.5 cegger printf("\tUnit={");
2421 1.5 cegger switch (wdrt->Units) {
2422 1.5 cegger case 0:
2423 1.5 cegger printf("1 seconds/count");
2424 1.5 cegger break;
2425 1.5 cegger case 1:
2426 1.5 cegger printf("100 milliseconds/count");
2427 1.5 cegger break;
2428 1.5 cegger case 2:
2429 1.5 cegger printf("10 milliseconds/count");
2430 1.5 cegger break;
2431 1.5 cegger default:
2432 1.5 cegger printf("%d", wdrt->Units);
2433 1.5 cegger break;
2434 1.5 cegger }
2435 1.5 cegger printf("}\n");
2436 1.5 cegger
2437 1.5 cegger printf(END_COMMENT);
2438 1.5 cegger }
2439 1.5 cegger
2440 1.5 cegger static void
2441 1.5 cegger acpi_print_sdt(ACPI_TABLE_HEADER *sdp)
2442 1.5 cegger {
2443 1.5 cegger printf(" ");
2444 1.5 cegger acpi_print_string(sdp->Signature, ACPI_NAME_SIZE);
2445 1.8 jmcneill printf(": Length=%d, Revision=%d, Checksum=%d",
2446 1.5 cegger sdp->Length, sdp->Revision, sdp->Checksum);
2447 1.8 jmcneill if (acpi_checksum(sdp, sdp->Length))
2448 1.8 jmcneill printf(" (Incorrect)");
2449 1.8 jmcneill printf(",\n\tOEMID=");
2450 1.5 cegger acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE);
2451 1.1 christos printf(", OEM Table ID=");
2452 1.5 cegger acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
2453 1.5 cegger printf(", OEM Revision=0x%x,\n", sdp->OemRevision);
2454 1.1 christos printf("\tCreator ID=");
2455 1.5 cegger acpi_print_string(sdp->AslCompilerId, ACPI_NAME_SIZE);
2456 1.5 cegger printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision);
2457 1.1 christos }
2458 1.1 christos
2459 1.5 cegger static void
2460 1.7 jmcneill acpi_dump_bytes(ACPI_TABLE_HEADER *sdp)
2461 1.7 jmcneill {
2462 1.7 jmcneill unsigned int i;
2463 1.7 jmcneill uint8_t *p;
2464 1.7 jmcneill
2465 1.8 jmcneill p = (uint8_t *)sdp;
2466 1.7 jmcneill printf("\n\tData={");
2467 1.7 jmcneill for (i = 0; i < sdp->Length; i++) {
2468 1.7 jmcneill if (cflag) {
2469 1.7 jmcneill if (i % 64 == 0)
2470 1.7 jmcneill printf("\n\t ");
2471 1.7 jmcneill else if (i % 16 == 0)
2472 1.7 jmcneill printf(" ");
2473 1.7 jmcneill printf("%c", (p[i] >= ' ' && p[i] <= '~') ? p[i] : '.');
2474 1.7 jmcneill } else {
2475 1.7 jmcneill if (i % 16 == 0)
2476 1.7 jmcneill printf("\n\t\t");
2477 1.7 jmcneill else if (i % 8 == 0)
2478 1.7 jmcneill printf(" ");
2479 1.7 jmcneill printf(" %02x", p[i]);
2480 1.7 jmcneill }
2481 1.7 jmcneill }
2482 1.7 jmcneill printf("\n\t}\n");
2483 1.7 jmcneill }
2484 1.7 jmcneill
2485 1.7 jmcneill static void
2486 1.5 cegger acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp)
2487 1.1 christos {
2488 1.5 cegger ACPI_TABLE_RSDT *rsdt;
2489 1.5 cegger ACPI_TABLE_XSDT *xsdt;
2490 1.1 christos int i, entries;
2491 1.1 christos
2492 1.5 cegger rsdt = (ACPI_TABLE_RSDT *)rsdp;
2493 1.5 cegger xsdt = (ACPI_TABLE_XSDT *)rsdp;
2494 1.5 cegger printf(BEGIN_COMMENT);
2495 1.1 christos acpi_print_sdt(rsdp);
2496 1.5 cegger entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2497 1.1 christos printf("\tEntries={ ");
2498 1.1 christos for (i = 0; i < entries; i++) {
2499 1.1 christos if (i > 0)
2500 1.1 christos printf(", ");
2501 1.16 msaitoh if (addr_size == 4)
2502 1.16 msaitoh printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i]));
2503 1.16 msaitoh else
2504 1.16 msaitoh printf("0x%016jx",
2505 1.16 msaitoh (uintmax_t)le64toh(xsdt->TableOffsetEntry[i]));
2506 1.1 christos }
2507 1.1 christos printf(" }\n");
2508 1.1 christos printf(END_COMMENT);
2509 1.1 christos }
2510 1.1 christos
2511 1.5 cegger static const char *acpi_pm_profiles[] = {
2512 1.5 cegger "Unspecified", "Desktop", "Mobile", "Workstation",
2513 1.5 cegger "Enterprise Server", "SOHO Server", "Appliance PC"
2514 1.5 cegger };
2515 1.5 cegger
2516 1.5 cegger static void
2517 1.5 cegger acpi_print_fadt(ACPI_TABLE_HEADER *sdp)
2518 1.1 christos {
2519 1.5 cegger ACPI_TABLE_FADT *fadt;
2520 1.5 cegger const char *pm;
2521 1.1 christos
2522 1.5 cegger fadt = (ACPI_TABLE_FADT *)sdp;
2523 1.1 christos printf(BEGIN_COMMENT);
2524 1.5 cegger acpi_print_sdt(sdp);
2525 1.5 cegger printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs,
2526 1.5 cegger fadt->Dsdt);
2527 1.5 cegger printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC");
2528 1.5 cegger if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *))
2529 1.5 cegger pm = "Reserved";
2530 1.5 cegger else
2531 1.5 cegger pm = acpi_pm_profiles[fadt->PreferredProfile];
2532 1.5 cegger printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile);
2533 1.5 cegger printf("\tSCI_INT=%d\n", fadt->SciInterrupt);
2534 1.5 cegger printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand);
2535 1.5 cegger printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable);
2536 1.5 cegger printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable);
2537 1.5 cegger printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest);
2538 1.5 cegger printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl);
2539 1.5 cegger printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
2540 1.5 cegger fadt->Pm1aEventBlock,
2541 1.5 cegger fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1);
2542 1.5 cegger if (fadt->Pm1bEventBlock != 0)
2543 1.1 christos printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
2544 1.5 cegger fadt->Pm1bEventBlock,
2545 1.5 cegger fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1);
2546 1.5 cegger printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
2547 1.5 cegger fadt->Pm1aControlBlock,
2548 1.5 cegger fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1);
2549 1.5 cegger if (fadt->Pm1bControlBlock != 0)
2550 1.1 christos printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
2551 1.5 cegger fadt->Pm1bControlBlock,
2552 1.5 cegger fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1);
2553 1.5 cegger if (fadt->Pm2ControlBlock != 0)
2554 1.1 christos printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
2555 1.5 cegger fadt->Pm2ControlBlock,
2556 1.5 cegger fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1);
2557 1.5 cegger printf("\tPM_TMR_BLK=0x%x-0x%x\n",
2558 1.5 cegger fadt->PmTimerBlock,
2559 1.5 cegger fadt->PmTimerBlock + fadt->PmTimerLength - 1);
2560 1.5 cegger if (fadt->Gpe0Block != 0)
2561 1.5 cegger printf("\tGPE0_BLK=0x%x-0x%x\n",
2562 1.5 cegger fadt->Gpe0Block,
2563 1.5 cegger fadt->Gpe0Block + fadt->Gpe0BlockLength - 1);
2564 1.5 cegger if (fadt->Gpe1Block != 0)
2565 1.5 cegger printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
2566 1.5 cegger fadt->Gpe1Block,
2567 1.5 cegger fadt->Gpe1Block + fadt->Gpe1BlockLength - 1,
2568 1.5 cegger fadt->Gpe1Base);
2569 1.5 cegger if (fadt->CstControl != 0)
2570 1.5 cegger printf("\tCST_CNT=0x%x\n", fadt->CstControl);
2571 1.5 cegger printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
2572 1.5 cegger fadt->C2Latency, fadt->C3Latency);
2573 1.1 christos printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
2574 1.5 cegger fadt->FlushSize, fadt->FlushStride);
2575 1.1 christos printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
2576 1.5 cegger fadt->DutyOffset, fadt->DutyWidth);
2577 1.1 christos printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
2578 1.5 cegger fadt->DayAlarm, fadt->MonthAlarm, fadt->Century);
2579 1.1 christos
2580 1.16 msaitoh #define PRINTFLAG(var, flag) printflag((var), ACPI_FADT_## flag, #flag)
2581 1.1 christos
2582 1.5 cegger printf("\tIAPC_BOOT_ARCH=");
2583 1.5 cegger PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES);
2584 1.5 cegger PRINTFLAG(fadt->BootFlags, 8042);
2585 1.5 cegger PRINTFLAG(fadt->BootFlags, NO_VGA);
2586 1.5 cegger PRINTFLAG(fadt->BootFlags, NO_MSI);
2587 1.5 cegger PRINTFLAG(fadt->BootFlags, NO_ASPM);
2588 1.16 msaitoh PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC);
2589 1.16 msaitoh PRINTFLAG_END();
2590 1.5 cegger
2591 1.5 cegger printf("\tFlags=");
2592 1.5 cegger PRINTFLAG(fadt->Flags, WBINVD);
2593 1.5 cegger PRINTFLAG(fadt->Flags, WBINVD_FLUSH);
2594 1.5 cegger PRINTFLAG(fadt->Flags, C1_SUPPORTED);
2595 1.5 cegger PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED);
2596 1.5 cegger PRINTFLAG(fadt->Flags, POWER_BUTTON);
2597 1.5 cegger PRINTFLAG(fadt->Flags, SLEEP_BUTTON);
2598 1.5 cegger PRINTFLAG(fadt->Flags, FIXED_RTC);
2599 1.5 cegger PRINTFLAG(fadt->Flags, S4_RTC_WAKE);
2600 1.5 cegger PRINTFLAG(fadt->Flags, 32BIT_TIMER);
2601 1.5 cegger PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED);
2602 1.5 cegger PRINTFLAG(fadt->Flags, RESET_REGISTER);
2603 1.5 cegger PRINTFLAG(fadt->Flags, SEALED_CASE);
2604 1.5 cegger PRINTFLAG(fadt->Flags, HEADLESS);
2605 1.5 cegger PRINTFLAG(fadt->Flags, SLEEP_TYPE);
2606 1.5 cegger PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE);
2607 1.5 cegger PRINTFLAG(fadt->Flags, PLATFORM_CLOCK);
2608 1.5 cegger PRINTFLAG(fadt->Flags, S4_RTC_VALID);
2609 1.5 cegger PRINTFLAG(fadt->Flags, REMOTE_POWER_ON);
2610 1.5 cegger PRINTFLAG(fadt->Flags, APIC_CLUSTER);
2611 1.5 cegger PRINTFLAG(fadt->Flags, APIC_PHYSICAL);
2612 1.16 msaitoh PRINTFLAG(fadt->Flags, HW_REDUCED);
2613 1.16 msaitoh PRINTFLAG(fadt->Flags, LOW_POWER_S0);
2614 1.16 msaitoh PRINTFLAG_END();
2615 1.1 christos
2616 1.1 christos #undef PRINTFLAG
2617 1.1 christos
2618 1.5 cegger if (fadt->Flags & ACPI_FADT_RESET_REGISTER) {
2619 1.5 cegger printf("\tRESET_REG=");
2620 1.5 cegger acpi_print_gas(&fadt->ResetRegister);
2621 1.5 cegger printf(", RESET_VALUE=%#x\n", fadt->ResetValue);
2622 1.5 cegger }
2623 1.5 cegger if (acpi_get_fadt_revision(fadt) > 1) {
2624 1.16 msaitoh printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs);
2625 1.16 msaitoh printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt);
2626 1.5 cegger printf("\tX_PM1a_EVT_BLK=");
2627 1.5 cegger acpi_print_gas(&fadt->XPm1aEventBlock);
2628 1.5 cegger if (fadt->XPm1bEventBlock.Address != 0) {
2629 1.5 cegger printf("\n\tX_PM1b_EVT_BLK=");
2630 1.5 cegger acpi_print_gas(&fadt->XPm1bEventBlock);
2631 1.5 cegger }
2632 1.5 cegger printf("\n\tX_PM1a_CNT_BLK=");
2633 1.5 cegger acpi_print_gas(&fadt->XPm1aControlBlock);
2634 1.5 cegger if (fadt->XPm1bControlBlock.Address != 0) {
2635 1.5 cegger printf("\n\tX_PM1b_CNT_BLK=");
2636 1.5 cegger acpi_print_gas(&fadt->XPm1bControlBlock);
2637 1.5 cegger }
2638 1.5 cegger if (fadt->XPm2ControlBlock.Address != 0) {
2639 1.5 cegger printf("\n\tX_PM2_CNT_BLK=");
2640 1.5 cegger acpi_print_gas(&fadt->XPm2ControlBlock);
2641 1.5 cegger }
2642 1.5 cegger printf("\n\tX_PM_TMR_BLK=");
2643 1.5 cegger acpi_print_gas(&fadt->XPmTimerBlock);
2644 1.5 cegger if (fadt->XGpe0Block.Address != 0) {
2645 1.5 cegger printf("\n\tX_GPE0_BLK=");
2646 1.5 cegger acpi_print_gas(&fadt->XGpe0Block);
2647 1.5 cegger }
2648 1.5 cegger if (fadt->XGpe1Block.Address != 0) {
2649 1.5 cegger printf("\n\tX_GPE1_BLK=");
2650 1.5 cegger acpi_print_gas(&fadt->XGpe1Block);
2651 1.5 cegger }
2652 1.5 cegger printf("\n");
2653 1.5 cegger }
2654 1.5 cegger
2655 1.1 christos printf(END_COMMENT);
2656 1.1 christos }
2657 1.1 christos
2658 1.5 cegger static void
2659 1.5 cegger acpi_print_facs(ACPI_TABLE_FACS *facs)
2660 1.1 christos {
2661 1.5 cegger printf(BEGIN_COMMENT);
2662 1.5 cegger printf(" FACS:\tLength=%u, ", facs->Length);
2663 1.5 cegger printf("HwSig=0x%08x, ", facs->HardwareSignature);
2664 1.5 cegger printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector);
2665 1.5 cegger
2666 1.5 cegger printf("\tGlobal_Lock=");
2667 1.5 cegger if (facs->GlobalLock != 0) {
2668 1.5 cegger if (facs->GlobalLock & ACPI_GLOCK_PENDING)
2669 1.5 cegger printf("PENDING,");
2670 1.5 cegger if (facs->GlobalLock & ACPI_GLOCK_OWNED)
2671 1.5 cegger printf("OWNED");
2672 1.5 cegger }
2673 1.5 cegger printf("\n");
2674 1.5 cegger
2675 1.5 cegger printf("\tFlags=");
2676 1.5 cegger if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT)
2677 1.5 cegger printf("S4BIOS");
2678 1.5 cegger printf("\n");
2679 1.5 cegger
2680 1.16 msaitoh if (facs->XFirmwareWakingVector != 0)
2681 1.16 msaitoh printf("\tX_Firm_Wake_Vec=%016jx\n",
2682 1.16 msaitoh (uintmax_t)facs->XFirmwareWakingVector);
2683 1.5 cegger printf("\tVersion=%u\n", facs->Version);
2684 1.5 cegger
2685 1.5 cegger printf(END_COMMENT);
2686 1.5 cegger }
2687 1.1 christos
2688 1.5 cegger static void
2689 1.5 cegger acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp)
2690 1.5 cegger {
2691 1.5 cegger printf(BEGIN_COMMENT);
2692 1.1 christos acpi_print_sdt(dsdp);
2693 1.5 cegger printf(END_COMMENT);
2694 1.1 christos }
2695 1.1 christos
2696 1.1 christos int
2697 1.1 christos acpi_checksum(void *p, size_t length)
2698 1.1 christos {
2699 1.5 cegger uint8_t *bp;
2700 1.5 cegger uint8_t sum;
2701 1.1 christos
2702 1.1 christos bp = p;
2703 1.1 christos sum = 0;
2704 1.1 christos while (length--)
2705 1.1 christos sum += *bp++;
2706 1.1 christos
2707 1.1 christos return (sum);
2708 1.1 christos }
2709 1.1 christos
2710 1.5 cegger static ACPI_TABLE_HEADER *
2711 1.1 christos acpi_map_sdt(vm_offset_t pa)
2712 1.1 christos {
2713 1.5 cegger ACPI_TABLE_HEADER *sp;
2714 1.1 christos
2715 1.5 cegger sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER));
2716 1.5 cegger sp = acpi_map_physical(pa, sp->Length);
2717 1.1 christos return (sp);
2718 1.1 christos }
2719 1.1 christos
2720 1.5 cegger static void
2721 1.5 cegger acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp)
2722 1.1 christos {
2723 1.1 christos printf(BEGIN_COMMENT);
2724 1.5 cegger printf(" RSD PTR: OEM=");
2725 1.5 cegger acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE);
2726 1.5 cegger printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x",
2727 1.5 cegger rp->Revision);
2728 1.5 cegger if (rp->Revision < 2) {
2729 1.5 cegger printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress,
2730 1.5 cegger rp->Checksum);
2731 1.5 cegger } else {
2732 1.16 msaitoh printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n",
2733 1.16 msaitoh (uintmax_t)rp->XsdtPhysicalAddress, rp->Length,
2734 1.5 cegger rp->ExtendedChecksum);
2735 1.5 cegger }
2736 1.1 christos printf(END_COMMENT);
2737 1.1 christos }
2738 1.1 christos
2739 1.5 cegger static void
2740 1.5 cegger acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
2741 1.1 christos {
2742 1.5 cegger ACPI_TABLE_HEADER *sdp;
2743 1.5 cegger ACPI_TABLE_RSDT *rsdt;
2744 1.5 cegger ACPI_TABLE_XSDT *xsdt;
2745 1.15 christos vm_offset_t addr = 0;
2746 1.5 cegger int entries, i;
2747 1.1 christos
2748 1.1 christos acpi_print_rsdt(rsdp);
2749 1.5 cegger rsdt = (ACPI_TABLE_RSDT *)rsdp;
2750 1.5 cegger xsdt = (ACPI_TABLE_XSDT *)rsdp;
2751 1.5 cegger entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2752 1.1 christos for (i = 0; i < entries; i++) {
2753 1.16 msaitoh if (addr_size == 4)
2754 1.5 cegger addr = le32toh(rsdt->TableOffsetEntry[i]);
2755 1.16 msaitoh else
2756 1.5 cegger addr = le64toh(xsdt->TableOffsetEntry[i]);
2757 1.16 msaitoh if (addr == 0)
2758 1.16 msaitoh continue;
2759 1.5 cegger sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
2760 1.5 cegger if (acpi_checksum(sdp, sdp->Length)) {
2761 1.5 cegger warnx("RSDT entry %d (sig %.4s) is corrupt", i,
2762 1.5 cegger sdp->Signature);
2763 1.8 jmcneill if (sflag)
2764 1.8 jmcneill continue;
2765 1.4 drochner }
2766 1.5 cegger if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4))
2767 1.5 cegger acpi_handle_fadt(sdp);
2768 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_BERT, 4))
2769 1.5 cegger acpi_handle_bert(sdp);
2770 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_BOOT, 4))
2771 1.5 cegger acpi_handle_boot(sdp);
2772 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_CPEP, 4))
2773 1.5 cegger acpi_handle_cpep(sdp);
2774 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_DBGP, 4))
2775 1.5 cegger acpi_handle_dbgp(sdp);
2776 1.16 msaitoh else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4))
2777 1.16 msaitoh acpi_handle_dmar(sdp);
2778 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_EINJ, 4))
2779 1.5 cegger acpi_handle_einj(sdp);
2780 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_ERST, 4))
2781 1.5 cegger acpi_handle_erst(sdp);
2782 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4))
2783 1.5 cegger acpi_handle_madt(sdp);
2784 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_MSCT, 4))
2785 1.5 cegger acpi_handle_msct(sdp);
2786 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_HEST, 4))
2787 1.5 cegger acpi_handle_hest(sdp);
2788 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4))
2789 1.5 cegger acpi_handle_hpet(sdp);
2790 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4))
2791 1.5 cegger acpi_handle_ecdt(sdp);
2792 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4))
2793 1.5 cegger acpi_handle_mcfg(sdp);
2794 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_SBST, 4))
2795 1.5 cegger acpi_handle_sbst(sdp);
2796 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4))
2797 1.5 cegger acpi_handle_slit(sdp);
2798 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_SPCR, 4))
2799 1.5 cegger acpi_handle_spcr(sdp);
2800 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4))
2801 1.5 cegger acpi_handle_srat(sdp);
2802 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4))
2803 1.5 cegger acpi_handle_tcpa(sdp);
2804 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_WAET, 4))
2805 1.5 cegger acpi_handle_waet(sdp);
2806 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_WDAT, 4))
2807 1.5 cegger acpi_handle_wdat(sdp);
2808 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_WDRT, 4))
2809 1.5 cegger acpi_handle_wdrt(sdp);
2810 1.5 cegger else {
2811 1.5 cegger printf(BEGIN_COMMENT);
2812 1.1 christos acpi_print_sdt(sdp);
2813 1.7 jmcneill acpi_dump_bytes(sdp);
2814 1.5 cegger printf(END_COMMENT);
2815 1.1 christos }
2816 1.1 christos }
2817 1.1 christos }
2818 1.1 christos
2819 1.5 cegger ACPI_TABLE_HEADER *
2820 1.5 cegger sdt_load_devmem(void)
2821 1.5 cegger {
2822 1.5 cegger ACPI_TABLE_RSDP *rp;
2823 1.5 cegger ACPI_TABLE_HEADER *rsdp;
2824 1.1 christos
2825 1.5 cegger rp = acpi_find_rsd_ptr();
2826 1.5 cegger if (!rp)
2827 1.5 cegger errx(EXIT_FAILURE, "Can't find ACPI information");
2828 1.5 cegger
2829 1.5 cegger if (tflag)
2830 1.5 cegger acpi_print_rsd_ptr(rp);
2831 1.5 cegger if (rp->Revision < 2) {
2832 1.5 cegger rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress);
2833 1.5 cegger if (memcmp(rsdp->Signature, "RSDT", 4) != 0 ||
2834 1.5 cegger acpi_checksum(rsdp, rsdp->Length) != 0)
2835 1.5 cegger errx(EXIT_FAILURE, "RSDT is corrupted");
2836 1.5 cegger addr_size = sizeof(uint32_t);
2837 1.5 cegger } else {
2838 1.5 cegger rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress);
2839 1.5 cegger if (memcmp(rsdp->Signature, "XSDT", 4) != 0 ||
2840 1.5 cegger acpi_checksum(rsdp, rsdp->Length) != 0)
2841 1.5 cegger errx(EXIT_FAILURE, "XSDT is corrupted");
2842 1.5 cegger addr_size = sizeof(uint64_t);
2843 1.5 cegger }
2844 1.5 cegger return (rsdp);
2845 1.1 christos }
2846 1.1 christos
2847 1.5 cegger /* Write the DSDT to a file, concatenating any SSDTs (if present). */
2848 1.5 cegger static int
2849 1.5 cegger write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt)
2850 1.5 cegger {
2851 1.5 cegger ACPI_TABLE_HEADER sdt;
2852 1.5 cegger ACPI_TABLE_HEADER *ssdt;
2853 1.5 cegger uint8_t sum;
2854 1.5 cegger
2855 1.5 cegger /* Create a new checksum to account for the DSDT and any SSDTs. */
2856 1.5 cegger sdt = *dsdt;
2857 1.5 cegger if (rsdt != NULL) {
2858 1.5 cegger sdt.Checksum = 0;
2859 1.5 cegger sum = acpi_checksum(dsdt + 1, dsdt->Length -
2860 1.5 cegger sizeof(ACPI_TABLE_HEADER));
2861 1.5 cegger ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL);
2862 1.5 cegger while (ssdt != NULL) {
2863 1.5 cegger sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER);
2864 1.5 cegger sum += acpi_checksum(ssdt + 1,
2865 1.5 cegger ssdt->Length - sizeof(ACPI_TABLE_HEADER));
2866 1.5 cegger ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt);
2867 1.5 cegger }
2868 1.5 cegger sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER));
2869 1.5 cegger sdt.Checksum -= sum;
2870 1.5 cegger }
2871 1.5 cegger
2872 1.5 cegger /* Write out the DSDT header and body. */
2873 1.5 cegger write(fd, &sdt, sizeof(ACPI_TABLE_HEADER));
2874 1.5 cegger write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER));
2875 1.5 cegger
2876 1.5 cegger /* Write out any SSDTs (if present.) */
2877 1.5 cegger if (rsdt != NULL) {
2878 1.5 cegger ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
2879 1.5 cegger while (ssdt != NULL) {
2880 1.5 cegger write(fd, ssdt + 1, ssdt->Length -
2881 1.5 cegger sizeof(ACPI_TABLE_HEADER));
2882 1.5 cegger ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
2883 1.5 cegger }
2884 1.5 cegger }
2885 1.1 christos return (0);
2886 1.1 christos }
2887 1.1 christos
2888 1.5 cegger void
2889 1.5 cegger dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2890 1.1 christos {
2891 1.5 cegger int fd;
2892 1.5 cegger mode_t mode;
2893 1.5 cegger
2894 1.5 cegger assert(outfile != NULL);
2895 1.5 cegger mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
2896 1.5 cegger fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
2897 1.5 cegger if (fd == -1) {
2898 1.5 cegger perror("dsdt_save_file");
2899 1.5 cegger return;
2900 1.5 cegger }
2901 1.5 cegger write_dsdt(fd, rsdt, dsdp);
2902 1.5 cegger close(fd);
2903 1.1 christos }
2904 1.1 christos
2905 1.5 cegger void
2906 1.5 cegger aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2907 1.1 christos {
2908 1.16 msaitoh char buf[MAXPATHLEN], tmpstr[MAXPATHLEN], wrkdir[MAXPATHLEN];
2909 1.16 msaitoh const char *iname = "/acpdump.din";
2910 1.16 msaitoh const char *oname = "/acpdump.dsl";
2911 1.5 cegger const char *tmpdir;
2912 1.5 cegger FILE *fp;
2913 1.5 cegger size_t len;
2914 1.16 msaitoh int fd, status;
2915 1.16 msaitoh pid_t pid;
2916 1.5 cegger
2917 1.5 cegger if (rsdt == NULL)
2918 1.5 cegger errx(EXIT_FAILURE, "aml_disassemble: invalid rsdt");
2919 1.5 cegger if (dsdp == NULL)
2920 1.5 cegger errx(EXIT_FAILURE, "aml_disassemble: invalid dsdp");
2921 1.5 cegger
2922 1.5 cegger tmpdir = getenv("TMPDIR");
2923 1.5 cegger if (tmpdir == NULL)
2924 1.5 cegger tmpdir = _PATH_TMP;
2925 1.16 msaitoh if (realpath(tmpdir, buf) == NULL) {
2926 1.16 msaitoh perror("realpath tmp dir");
2927 1.5 cegger return;
2928 1.5 cegger }
2929 1.16 msaitoh len = sizeof(wrkdir) - strlen(iname);
2930 1.16 msaitoh if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) {
2931 1.16 msaitoh fprintf(stderr, "$TMPDIR too long\n");
2932 1.16 msaitoh return;
2933 1.16 msaitoh }
2934 1.16 msaitoh if (mkdtemp(wrkdir) == NULL) {
2935 1.16 msaitoh perror("mkdtemp tmp working dir");
2936 1.16 msaitoh return;
2937 1.16 msaitoh }
2938 1.16 msaitoh len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname);
2939 1.16 msaitoh assert(len <= sizeof(tmpstr) - 1);
2940 1.16 msaitoh fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
2941 1.5 cegger if (fd < 0) {
2942 1.5 cegger perror("iasl tmp file");
2943 1.5 cegger return;
2944 1.5 cegger }
2945 1.5 cegger write_dsdt(fd, rsdt, dsdp);
2946 1.5 cegger close(fd);
2947 1.5 cegger
2948 1.5 cegger /* Run iasl -d on the temp file */
2949 1.16 msaitoh if ((pid = fork()) == 0) {
2950 1.5 cegger close(STDOUT_FILENO);
2951 1.5 cegger if (vflag == 0)
2952 1.5 cegger close(STDERR_FILENO);
2953 1.5 cegger execl("/usr/bin/iasl", "iasl", "-d", tmpstr, NULL);
2954 1.5 cegger err(EXIT_FAILURE, "exec");
2955 1.5 cegger }
2956 1.16 msaitoh if (pid > 0)
2957 1.16 msaitoh wait(&status);
2958 1.16 msaitoh if (unlink(tmpstr) < 0) {
2959 1.16 msaitoh perror("unlink");
2960 1.16 msaitoh goto out;
2961 1.16 msaitoh }
2962 1.16 msaitoh if (pid < 0) {
2963 1.16 msaitoh perror("fork");
2964 1.16 msaitoh goto out;
2965 1.16 msaitoh }
2966 1.16 msaitoh if (status != 0) {
2967 1.16 msaitoh fprintf(stderr, "iast exit status = %d\n", status);
2968 1.16 msaitoh }
2969 1.1 christos
2970 1.5 cegger /* Dump iasl's output to stdout */
2971 1.16 msaitoh len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname);
2972 1.16 msaitoh assert(len <= sizeof(tmpstr) - 1);
2973 1.5 cegger fp = fopen(tmpstr, "r");
2974 1.16 msaitoh if (unlink(tmpstr) < 0) {
2975 1.16 msaitoh perror("unlink");
2976 1.16 msaitoh goto out;
2977 1.16 msaitoh }
2978 1.5 cegger if (fp == NULL) {
2979 1.5 cegger perror("iasl tmp file (read)");
2980 1.16 msaitoh goto out;
2981 1.5 cegger }
2982 1.5 cegger while ((len = fread(buf, 1, sizeof(buf), fp)) > 0)
2983 1.5 cegger fwrite(buf, 1, len, stdout);
2984 1.5 cegger fclose(fp);
2985 1.16 msaitoh
2986 1.16 msaitoh out:
2987 1.16 msaitoh if (rmdir(wrkdir) < 0)
2988 1.16 msaitoh perror("rmdir");
2989 1.1 christos }
2990 1.1 christos
2991 1.5 cegger void
2992 1.5 cegger sdt_print_all(ACPI_TABLE_HEADER *rsdp)
2993 1.1 christos {
2994 1.5 cegger acpi_handle_rsdt(rsdp);
2995 1.1 christos }
2996 1.1 christos
2997 1.5 cegger /* Fetch a table matching the given signature via the RSDT. */
2998 1.5 cegger ACPI_TABLE_HEADER *
2999 1.5 cegger sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last)
3000 1.1 christos {
3001 1.5 cegger ACPI_TABLE_HEADER *sdt;
3002 1.5 cegger ACPI_TABLE_RSDT *rsdt;
3003 1.5 cegger ACPI_TABLE_XSDT *xsdt;
3004 1.15 christos vm_offset_t addr = 0;
3005 1.5 cegger int entries, i;
3006 1.1 christos
3007 1.5 cegger rsdt = (ACPI_TABLE_RSDT *)rsdp;
3008 1.5 cegger xsdt = (ACPI_TABLE_XSDT *)rsdp;
3009 1.5 cegger entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
3010 1.5 cegger for (i = 0; i < entries; i++) {
3011 1.16 msaitoh if (addr_size == 4)
3012 1.5 cegger addr = le32toh(rsdt->TableOffsetEntry[i]);
3013 1.16 msaitoh else
3014 1.5 cegger addr = le64toh(xsdt->TableOffsetEntry[i]);
3015 1.16 msaitoh if (addr == 0)
3016 1.16 msaitoh continue;
3017 1.5 cegger sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
3018 1.5 cegger if (last != NULL) {
3019 1.5 cegger if (sdt == last)
3020 1.5 cegger last = NULL;
3021 1.5 cegger continue;
3022 1.5 cegger }
3023 1.5 cegger if (memcmp(sdt->Signature, sig, strlen(sig)))
3024 1.5 cegger continue;
3025 1.5 cegger if (acpi_checksum(sdt, sdt->Length))
3026 1.5 cegger errx(EXIT_FAILURE, "RSDT entry %d is corrupt", i);
3027 1.5 cegger return (sdt);
3028 1.5 cegger }
3029 1.1 christos
3030 1.5 cegger return (NULL);
3031 1.1 christos }
3032 1.1 christos
3033 1.5 cegger ACPI_TABLE_HEADER *
3034 1.5 cegger dsdt_from_fadt(ACPI_TABLE_FADT *fadt)
3035 1.1 christos {
3036 1.5 cegger ACPI_TABLE_HEADER *sdt;
3037 1.1 christos
3038 1.5 cegger /* Use the DSDT address if it is version 1, otherwise use XDSDT. */
3039 1.18 msaitoh sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(
3040 1.18 msaitoh acpi_select_address(fadt->Dsdt, fadt->XDsdt));
3041 1.5 cegger if (acpi_checksum(sdt, sdt->Length))
3042 1.10 christos errx(EXIT_FAILURE, "DSDT is corrupt");
3043 1.5 cegger return (sdt);
3044 1.1 christos }
3045