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