1 /****************************************************************************** 2 * 3 * Module Name: dmtbdump - Dump ACPI data tables that contain no AML code 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, 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 "acpi.h" 45 #include "accommon.h" 46 #include "acdisasm.h" 47 #include "actables.h" 48 49 /* This module used for application-level code only */ 50 51 #define _COMPONENT ACPI_CA_DISASSEMBLER 52 ACPI_MODULE_NAME ("dmtbdump") 53 54 55 /* Local prototypes */ 56 57 static void 58 AcpiDmValidateFadtLength ( 59 UINT32 Revision, 60 UINT32 Length); 61 62 63 /******************************************************************************* 64 * 65 * FUNCTION: AcpiDmDumpBuffer 66 * 67 * PARAMETERS: Table - ACPI Table or subtable 68 * BufferOffset - Offset of buffer from Table above 69 * Length - Length of the buffer 70 * AbsoluteOffset - Offset of buffer in the main ACPI table 71 * Header - Name of the buffer field (printed on the 72 * first line only.) 73 * 74 * RETURN: None 75 * 76 * DESCRIPTION: Format the contents of an arbitrary length data buffer (in the 77 * disassembler output format.) 78 * 79 ******************************************************************************/ 80 81 void 82 AcpiDmDumpBuffer ( 83 void *Table, 84 UINT32 BufferOffset, 85 UINT32 Length, 86 UINT32 AbsoluteOffset, 87 char *Header) 88 { 89 UINT8 *Buffer; 90 UINT32 i; 91 92 93 if (!Length) 94 { 95 return; 96 } 97 98 Buffer = ACPI_CAST_PTR (UINT8, Table) + BufferOffset; 99 i = 0; 100 101 while (i < Length) 102 { 103 if (!(i % 16)) 104 { 105 /* Insert a backslash - line continuation character */ 106 107 if (Length > 16) 108 { 109 AcpiOsPrintf ("\\\n "); 110 } 111 } 112 113 AcpiOsPrintf ("%.02X ", *Buffer); 114 i++; 115 Buffer++; 116 AbsoluteOffset++; 117 } 118 119 AcpiOsPrintf ("\n"); 120 } 121 122 123 /******************************************************************************* 124 * 125 * FUNCTION: AcpiDmDumpUnicode 126 * 127 * PARAMETERS: Table - ACPI Table or subtable 128 * BufferOffset - Offset of buffer from Table above 129 * ByteLength - Length of the buffer 130 * 131 * RETURN: None 132 * 133 * DESCRIPTION: Validate and dump the contents of a buffer that contains 134 * unicode data. The output is a standard ASCII string. If it 135 * appears that the data is not unicode, the buffer is dumped 136 * as hex characters. 137 * 138 ******************************************************************************/ 139 140 void 141 AcpiDmDumpUnicode ( 142 void *Table, 143 UINT32 BufferOffset, 144 UINT32 ByteLength) 145 { 146 UINT8 *Buffer; 147 UINT32 Length; 148 UINT32 i; 149 150 151 Buffer = ((UINT8 *) Table) + BufferOffset; 152 Length = ByteLength - 2; /* Last two bytes are the null terminator */ 153 154 /* Ensure all low bytes are entirely printable ASCII */ 155 156 for (i = 0; i < Length; i += 2) 157 { 158 if (!isprint (Buffer[i])) 159 { 160 goto DumpRawBuffer; 161 } 162 } 163 164 /* Ensure all high bytes are zero */ 165 166 for (i = 1; i < Length; i += 2) 167 { 168 if (Buffer[i]) 169 { 170 goto DumpRawBuffer; 171 } 172 } 173 174 /* Dump the buffer as a normal string */ 175 176 AcpiOsPrintf ("\""); 177 for (i = 0; i < Length; i += 2) 178 { 179 AcpiOsPrintf ("%c", Buffer[i]); 180 } 181 182 AcpiOsPrintf ("\"\n"); 183 return; 184 185 DumpRawBuffer: 186 AcpiDmDumpBuffer (Table, BufferOffset, ByteLength, 187 BufferOffset, NULL); 188 AcpiOsPrintf ("\n"); 189 } 190 191 192 /******************************************************************************* 193 * 194 * FUNCTION: AcpiDmDumpRsdp 195 * 196 * PARAMETERS: Table - A RSDP 197 * 198 * RETURN: Length of the table (there is not always a length field, 199 * use revision or length if available (ACPI 2.0+)) 200 * 201 * DESCRIPTION: Format the contents of a RSDP 202 * 203 ******************************************************************************/ 204 205 UINT32 206 AcpiDmDumpRsdp ( 207 ACPI_TABLE_HEADER *Table) 208 { 209 ACPI_TABLE_RSDP *Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table); 210 UINT32 Length = sizeof (ACPI_RSDP_COMMON); 211 UINT8 Checksum; 212 ACPI_STATUS Status; 213 214 215 /* Dump the common ACPI 1.0 portion */ 216 217 Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoRsdp1); 218 if (ACPI_FAILURE (Status)) 219 { 220 return (Length); 221 } 222 223 /* Validate the first checksum */ 224 225 Checksum = AcpiDmGenerateChecksum (Rsdp, sizeof (ACPI_RSDP_COMMON), 226 Rsdp->Checksum); 227 if (Checksum != Rsdp->Checksum) 228 { 229 AcpiOsPrintf ("/* Incorrect Checksum above, should be 0x%2.2X */\n", 230 Checksum); 231 } 232 233 /* The RSDP for ACPI 2.0+ contains more data and has a Length field */ 234 235 if (Rsdp->Revision > 0) 236 { 237 Length = Rsdp->Length; 238 Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoRsdp2); 239 if (ACPI_FAILURE (Status)) 240 { 241 return (Length); 242 } 243 244 /* Validate the extended checksum over entire RSDP */ 245 246 Checksum = AcpiDmGenerateChecksum (Rsdp, sizeof (ACPI_TABLE_RSDP), 247 Rsdp->ExtendedChecksum); 248 if (Checksum != Rsdp->ExtendedChecksum) 249 { 250 AcpiOsPrintf ( 251 "/* Incorrect Extended Checksum above, should be 0x%2.2X */\n", 252 Checksum); 253 } 254 } 255 256 return (Length); 257 } 258 259 260 /******************************************************************************* 261 * 262 * FUNCTION: AcpiDmDumpRsdt 263 * 264 * PARAMETERS: Table - A RSDT 265 * 266 * RETURN: None 267 * 268 * DESCRIPTION: Format the contents of a RSDT 269 * 270 ******************************************************************************/ 271 272 void 273 AcpiDmDumpRsdt ( 274 ACPI_TABLE_HEADER *Table) 275 { 276 UINT32 *Array; 277 UINT32 Entries; 278 UINT32 Offset; 279 UINT32 i; 280 281 282 /* Point to start of table pointer array */ 283 284 Array = ACPI_CAST_PTR (ACPI_TABLE_RSDT, Table)->TableOffsetEntry; 285 Offset = sizeof (ACPI_TABLE_HEADER); 286 287 /* RSDT uses 32-bit pointers */ 288 289 Entries = (Table->Length - sizeof (ACPI_TABLE_HEADER)) / sizeof (UINT32); 290 291 for (i = 0; i < Entries; i++) 292 { 293 AcpiDmLineHeader2 (Offset, sizeof (UINT32), "ACPI Table Address", i); 294 AcpiOsPrintf ("%8.8X\n", Array[i]); 295 Offset += sizeof (UINT32); 296 } 297 } 298 299 300 /******************************************************************************* 301 * 302 * FUNCTION: AcpiDmDumpXsdt 303 * 304 * PARAMETERS: Table - A XSDT 305 * 306 * RETURN: None 307 * 308 * DESCRIPTION: Format the contents of a XSDT 309 * 310 ******************************************************************************/ 311 312 void 313 AcpiDmDumpXsdt ( 314 ACPI_TABLE_HEADER *Table) 315 { 316 UINT64 *Array; 317 UINT32 Entries; 318 UINT32 Offset; 319 UINT32 i; 320 321 322 /* Point to start of table pointer array */ 323 324 Array = ACPI_CAST_PTR (ACPI_TABLE_XSDT, Table)->TableOffsetEntry; 325 Offset = sizeof (ACPI_TABLE_HEADER); 326 327 /* XSDT uses 64-bit pointers */ 328 329 Entries = (Table->Length - sizeof (ACPI_TABLE_HEADER)) / sizeof (UINT64); 330 331 for (i = 0; i < Entries; i++) 332 { 333 AcpiDmLineHeader2 (Offset, sizeof (UINT64), "ACPI Table Address", i); 334 AcpiOsPrintf ("%8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Array[i])); 335 Offset += sizeof (UINT64); 336 } 337 } 338 339 340 /******************************************************************************* 341 * 342 * FUNCTION: AcpiDmDumpFadt 343 * 344 * PARAMETERS: Table - A FADT 345 * 346 * RETURN: None 347 * 348 * DESCRIPTION: Format the contents of a FADT 349 * 350 * NOTE: We cannot depend on the FADT version to indicate the actual 351 * contents of the FADT because of BIOS bugs. The table length 352 * is the only reliable indicator. 353 * 354 ******************************************************************************/ 355 356 void 357 AcpiDmDumpFadt ( 358 ACPI_TABLE_HEADER *Table) 359 { 360 ACPI_STATUS Status; 361 362 363 /* Always dump the minimum FADT revision 1 fields (ACPI 1.0) */ 364 365 Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, 366 AcpiDmTableInfoFadt1); 367 if (ACPI_FAILURE (Status)) 368 { 369 return; 370 } 371 372 /* Check for FADT revision 2 fields (ACPI 1.0B MS extensions) */ 373 374 if ((Table->Length > ACPI_FADT_V1_SIZE) && 375 (Table->Length <= ACPI_FADT_V2_SIZE)) 376 { 377 Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, 378 AcpiDmTableInfoFadt2); 379 if (ACPI_FAILURE (Status)) 380 { 381 return; 382 } 383 } 384 385 /* Check for FADT revision 3/4 fields and up (ACPI 2.0+ extended data) */ 386 387 else if (Table->Length > ACPI_FADT_V2_SIZE) 388 { 389 Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, 390 AcpiDmTableInfoFadt3); 391 if (ACPI_FAILURE (Status)) 392 { 393 return; 394 } 395 396 /* Check for FADT revision 5 fields and up (ACPI 5.0+) */ 397 398 if (Table->Length > ACPI_FADT_V3_SIZE) 399 { 400 Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, 401 AcpiDmTableInfoFadt5); 402 if (ACPI_FAILURE (Status)) 403 { 404 return; 405 } 406 } 407 408 /* Check for FADT revision 6 fields and up (ACPI 6.0+) */ 409 410 if (Table->Length > ACPI_FADT_V3_SIZE) 411 { 412 Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, 413 AcpiDmTableInfoFadt6); 414 if (ACPI_FAILURE (Status)) 415 { 416 return; 417 } 418 } 419 } 420 421 /* Validate various fields in the FADT, including length */ 422 423 AcpiTbCreateLocalFadt (Table, Table->Length); 424 425 /* Validate FADT length against the revision */ 426 427 AcpiDmValidateFadtLength (Table->Revision, Table->Length); 428 } 429 430 431 /******************************************************************************* 432 * 433 * FUNCTION: AcpiDmValidateFadtLength 434 * 435 * PARAMETERS: Revision - FADT revision (Header->Revision) 436 * Length - FADT length (Header->Length 437 * 438 * RETURN: None 439 * 440 * DESCRIPTION: Check the FADT revision against the expected table length for 441 * that revision. Issue a warning if the length is not what was 442 * expected. This seems to be such a common BIOS bug that the 443 * FADT revision has been rendered virtually meaningless. 444 * 445 ******************************************************************************/ 446 447 static void 448 AcpiDmValidateFadtLength ( 449 UINT32 Revision, 450 UINT32 Length) 451 { 452 UINT32 ExpectedLength; 453 454 455 switch (Revision) 456 { 457 case 0: 458 459 AcpiOsPrintf ("// ACPI Warning: Invalid FADT revision: 0\n"); 460 return; 461 462 case 1: 463 464 ExpectedLength = ACPI_FADT_V1_SIZE; 465 break; 466 467 case 2: 468 469 ExpectedLength = ACPI_FADT_V2_SIZE; 470 break; 471 472 case 3: 473 case 4: 474 475 ExpectedLength = ACPI_FADT_V3_SIZE; 476 break; 477 478 case 5: 479 480 ExpectedLength = ACPI_FADT_V5_SIZE; 481 break; 482 483 default: 484 485 return; 486 } 487 488 if (Length == ExpectedLength) 489 { 490 return; 491 } 492 493 AcpiOsPrintf ( 494 "\n// ACPI Warning: FADT revision %X does not match length: " 495 "found %X expected %X\n", 496 Revision, Length, ExpectedLength); 497 } 498