1 /****************************************************************************** 2 * 3 * Module Name: apdump - Dump routines for ACPI tables (acpidump) 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "acpidump.h" 45 46 47 /* Local prototypes */ 48 49 static int 50 ApDumpTableBuffer ( 51 ACPI_TABLE_HEADER *Table, 52 UINT32 Instance, 53 ACPI_PHYSICAL_ADDRESS Address); 54 55 56 /****************************************************************************** 57 * 58 * FUNCTION: ApIsValidHeader 59 * 60 * PARAMETERS: Table - Pointer to table to be validated 61 * 62 * RETURN: TRUE if the header appears to be valid. FALSE otherwise 63 * 64 * DESCRIPTION: Check for a valid ACPI table header 65 * 66 ******************************************************************************/ 67 68 BOOLEAN 69 ApIsValidHeader ( 70 ACPI_TABLE_HEADER *Table) 71 { 72 if (!ACPI_VALIDATE_RSDP_SIG (Table->Signature)) 73 { 74 /* Make sure signature is all ASCII and a valid ACPI name */ 75 76 if (!AcpiUtValidAcpiName (Table->Signature)) 77 { 78 fprintf (stderr, "Table signature (0x%8.8X) is invalid\n", 79 *(UINT32 *) Table->Signature); 80 return (FALSE); 81 } 82 83 /* Check for minimum table length */ 84 85 if (Table->Length < sizeof (ACPI_TABLE_HEADER)) 86 { 87 fprintf (stderr, "Table length (0x%8.8X) is invalid\n", 88 Table->Length); 89 return (FALSE); 90 } 91 } 92 93 return (TRUE); 94 } 95 96 97 /****************************************************************************** 98 * 99 * FUNCTION: ApIsValidChecksum 100 * 101 * PARAMETERS: Table - Pointer to table to be validated 102 * 103 * RETURN: TRUE if the checksum appears to be valid. FALSE otherwise 104 * 105 * DESCRIPTION: Check for a valid ACPI table checksum 106 * 107 ******************************************************************************/ 108 109 BOOLEAN 110 ApIsValidChecksum ( 111 ACPI_TABLE_HEADER *Table) 112 { 113 ACPI_STATUS Status; 114 ACPI_TABLE_RSDP *Rsdp; 115 116 117 if (ACPI_VALIDATE_RSDP_SIG (Table->Signature)) 118 { 119 /* 120 * Checksum for RSDP. 121 * Note: Other checksums are computed during the table dump. 122 */ 123 124 Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table); 125 Status = AcpiTbValidateRsdp (Rsdp); 126 } 127 else 128 { 129 Status = AcpiTbVerifyChecksum (Table, Table->Length); 130 } 131 132 if (ACPI_FAILURE (Status)) 133 { 134 fprintf (stderr, "%4.4s: Warning: wrong checksum\n", 135 Table->Signature); 136 } 137 138 return (AE_OK); 139 } 140 141 142 /****************************************************************************** 143 * 144 * FUNCTION: ApGetTableLength 145 * 146 * PARAMETERS: Table - Pointer to the table 147 * 148 * RETURN: Table length 149 * 150 * DESCRIPTION: Obtain table length according to table signature 151 * 152 ******************************************************************************/ 153 154 UINT32 155 ApGetTableLength ( 156 ACPI_TABLE_HEADER *Table) 157 { 158 ACPI_TABLE_RSDP *Rsdp; 159 160 161 /* Check if table is valid */ 162 163 if (!ApIsValidHeader (Table)) 164 { 165 return (0); 166 } 167 168 if (ACPI_VALIDATE_RSDP_SIG (Table->Signature)) 169 { 170 Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table); 171 return (Rsdp->Length); 172 } 173 else 174 { 175 return (Table->Length); 176 } 177 } 178 179 180 /****************************************************************************** 181 * 182 * FUNCTION: ApDumpTableBuffer 183 * 184 * PARAMETERS: Table - ACPI table to be dumped 185 * Instance - ACPI table instance no. to be dumped 186 * Address - Physical address of the table 187 * 188 * RETURN: None 189 * 190 * DESCRIPTION: Dump an ACPI table in standard ASCII hex format, with a 191 * header that is compatible with the AcpiXtract utility. 192 * 193 ******************************************************************************/ 194 195 static int 196 ApDumpTableBuffer ( 197 ACPI_TABLE_HEADER *Table, 198 UINT32 Instance, 199 ACPI_PHYSICAL_ADDRESS Address) 200 { 201 UINT32 TableLength; 202 203 204 TableLength = ApGetTableLength (Table); 205 206 /* Print only the header if requested */ 207 208 if (Gbl_SummaryMode) 209 { 210 AcpiTbPrintTableHeader (Address, Table); 211 return (0); 212 } 213 214 /* Dump to binary file if requested */ 215 216 if (Gbl_BinaryMode) 217 { 218 return (ApWriteToBinaryFile (Table, Instance)); 219 } 220 221 /* 222 * Dump the table with header for use with acpixtract utility 223 * Note: simplest to just always emit a 64-bit address. AcpiXtract 224 * utility can handle this. 225 */ 226 printf ("%4.4s @ 0x%8.8X%8.8X\n", Table->Signature, 227 ACPI_FORMAT_UINT64 (Address)); 228 229 AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, Table), TableLength, 230 DB_BYTE_DISPLAY, 0); 231 printf ("\n"); 232 return (0); 233 } 234 235 236 /****************************************************************************** 237 * 238 * FUNCTION: ApDumpAllTables 239 * 240 * PARAMETERS: None 241 * 242 * RETURN: Status 243 * 244 * DESCRIPTION: Get all tables from the RSDT/XSDT (or at least all of the 245 * tables that we can possibly get). 246 * 247 ******************************************************************************/ 248 249 int 250 ApDumpAllTables ( 251 void) 252 { 253 ACPI_TABLE_HEADER *Table; 254 UINT32 Instance = 0; 255 ACPI_PHYSICAL_ADDRESS Address; 256 ACPI_STATUS Status; 257 UINT32 i; 258 259 260 /* Get and dump all available ACPI tables */ 261 262 for (i = 0; i < AP_MAX_ACPI_FILES; i++) 263 { 264 Status = AcpiOsGetTableByIndex (i, &Table, &Instance, &Address); 265 if (ACPI_FAILURE (Status)) 266 { 267 /* AE_LIMIT means that no more tables are available */ 268 269 if (Status == AE_LIMIT) 270 { 271 return (0); 272 } 273 else if (i == 0) 274 { 275 fprintf (stderr, "Could not get ACPI tables, %s\n", 276 AcpiFormatException (Status)); 277 return (-1); 278 } 279 else 280 { 281 fprintf (stderr, "Could not get ACPI table at index %u, %s\n", 282 i, AcpiFormatException (Status)); 283 continue; 284 } 285 } 286 287 if (ApDumpTableBuffer (Table, Instance, Address)) 288 { 289 return (-1); 290 } 291 free (Table); 292 } 293 294 /* Something seriously bad happened if the loop terminates here */ 295 296 return (-1); 297 } 298 299 300 /****************************************************************************** 301 * 302 * FUNCTION: ApDumpTableByAddress 303 * 304 * PARAMETERS: AsciiAddress - Address for requested ACPI table 305 * 306 * RETURN: Status 307 * 308 * DESCRIPTION: Get an ACPI table via a physical address and dump it. 309 * 310 ******************************************************************************/ 311 312 int 313 ApDumpTableByAddress ( 314 char *AsciiAddress) 315 { 316 ACPI_PHYSICAL_ADDRESS Address; 317 ACPI_TABLE_HEADER *Table; 318 ACPI_STATUS Status; 319 int TableStatus; 320 UINT64 LongAddress; 321 322 323 /* Convert argument to an integer physical address */ 324 325 Status = AcpiUtStrtoul64 (AsciiAddress, 0, &LongAddress); 326 if (ACPI_FAILURE (Status)) 327 { 328 fprintf (stderr, "%s: Could not convert to a physical address\n", 329 AsciiAddress); 330 return (-1); 331 } 332 333 Address = (ACPI_PHYSICAL_ADDRESS) LongAddress; 334 Status = AcpiOsGetTableByAddress (Address, &Table); 335 if (ACPI_FAILURE (Status)) 336 { 337 fprintf (stderr, "Could not get table at 0x%8.8X%8.8X, %s\n", 338 ACPI_FORMAT_UINT64 (Address), 339 AcpiFormatException (Status)); 340 return (-1); 341 } 342 343 TableStatus = ApDumpTableBuffer (Table, 0, Address); 344 free (Table); 345 return (TableStatus); 346 } 347 348 349 /****************************************************************************** 350 * 351 * FUNCTION: ApDumpTableByName 352 * 353 * PARAMETERS: Signature - Requested ACPI table signature 354 * 355 * RETURN: Status 356 * 357 * DESCRIPTION: Get an ACPI table via a signature and dump it. Handles 358 * multiple tables with the same signature (SSDTs). 359 * 360 ******************************************************************************/ 361 362 int 363 ApDumpTableByName ( 364 char *Signature) 365 { 366 char LocalSignature [ACPI_NAME_SIZE + 1]; 367 UINT32 Instance; 368 ACPI_TABLE_HEADER *Table; 369 ACPI_PHYSICAL_ADDRESS Address; 370 ACPI_STATUS Status; 371 372 373 if (strlen (Signature) != ACPI_NAME_SIZE) 374 { 375 fprintf (stderr, 376 "Invalid table signature [%s]: must be exactly 4 characters\n", 377 Signature); 378 return (-1); 379 } 380 381 /* Table signatures are expected to be uppercase */ 382 383 strcpy (LocalSignature, Signature); 384 AcpiUtStrupr (LocalSignature); 385 386 /* To be friendly, handle tables whose signatures do not match the name */ 387 388 if (ACPI_COMPARE_NAME (LocalSignature, AP_DUMP_SIG_RSDP)) 389 { 390 strcpy (LocalSignature, AP_DUMP_SIG_RSDP); 391 } 392 else if (ACPI_COMPARE_NAME (LocalSignature, "FADT")) 393 { 394 strcpy (LocalSignature, ACPI_SIG_FADT); 395 } 396 else if (ACPI_COMPARE_NAME (LocalSignature, "MADT")) 397 { 398 strcpy (LocalSignature, ACPI_SIG_MADT); 399 } 400 401 /* Dump all instances of this signature (to handle multiple SSDTs) */ 402 403 for (Instance = 0; Instance < AP_MAX_ACPI_FILES; Instance++) 404 { 405 Status = AcpiOsGetTableByName (LocalSignature, Instance, 406 &Table, &Address); 407 if (ACPI_FAILURE (Status)) 408 { 409 /* AE_LIMIT means that no more tables are available */ 410 411 if (Status == AE_LIMIT) 412 { 413 return (0); 414 } 415 416 fprintf (stderr, 417 "Could not get ACPI table with signature [%s], %s\n", 418 LocalSignature, AcpiFormatException (Status)); 419 return (-1); 420 } 421 422 if (ApDumpTableBuffer (Table, Instance, Address)) 423 { 424 return (-1); 425 } 426 free (Table); 427 } 428 429 /* Something seriously bad happened if the loop terminates here */ 430 431 return (-1); 432 } 433 434 435 /****************************************************************************** 436 * 437 * FUNCTION: ApDumpTableFromFile 438 * 439 * PARAMETERS: Pathname - File containing the binary ACPI table 440 * 441 * RETURN: Status 442 * 443 * DESCRIPTION: Dump an ACPI table from a binary file 444 * 445 ******************************************************************************/ 446 447 int 448 ApDumpTableFromFile ( 449 char *Pathname) 450 { 451 ACPI_TABLE_HEADER *Table; 452 UINT32 FileSize = 0; 453 int TableStatus; 454 455 456 /* Get the entire ACPI table from the file */ 457 458 Table = ApGetTableFromFile (Pathname, &FileSize); 459 if (!Table) 460 { 461 return (-1); 462 } 463 464 /* File must be at least as long as the table length */ 465 466 if (Table->Length > FileSize) 467 { 468 fprintf (stderr, 469 "Table length (0x%X) is too large for input file (0x%X) %s\n", 470 Table->Length, FileSize, Pathname); 471 return (-1); 472 } 473 474 if (Gbl_VerboseMode) 475 { 476 fprintf (stderr, 477 "Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n", 478 Pathname, Table->Signature, FileSize, FileSize); 479 } 480 481 TableStatus = ApDumpTableBuffer (Table, 0, 0); 482 free (Table); 483 return (TableStatus); 484 } 485 486 487 /****************************************************************************** 488 * 489 * FUNCTION: AcpiOs* print functions 490 * 491 * DESCRIPTION: Used for linkage with ACPICA modules 492 * 493 ******************************************************************************/ 494 495 void ACPI_INTERNAL_VAR_XFACE 496 AcpiOsPrintf ( 497 const char *Fmt, 498 ...) 499 { 500 va_list Args; 501 502 va_start (Args, Fmt); 503 vfprintf (stdout, Fmt, Args); 504 va_end (Args); 505 } 506 507 void 508 AcpiOsVprintf ( 509 const char *Fmt, 510 va_list Args) 511 { 512 vfprintf (stdout, Fmt, Args); 513 }