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