1/****************************************************************************** 2 * 3 * Module Name: dmtables - disassembler ACPI table support 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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 "aslcompiler.h" 45#include "acdispat.h" 46#include "acnamesp.h" 47#include "actables.h" 48#include "acparser.h" 49#include "acapps.h" 50#include "acmacros.h" 51#include "acconvert.h" 52 53 54#define _COMPONENT ACPI_TOOLS 55 ACPI_MODULE_NAME ("dmtables") 56 57 58/* Local prototypes */ 59 60static void 61AdCreateTableHeader ( 62 char *Filename, 63 ACPI_TABLE_HEADER *Table); 64 65static ACPI_STATUS 66AdStoreTable ( 67 ACPI_TABLE_HEADER *Table, 68 UINT32 *TableIndex); 69 70 71extern ACPI_TABLE_DESC LocalTables[1]; 72extern ACPI_PARSE_OBJECT *AcpiGbl_ParseOpRoot; 73 74 75/****************************************************************************** 76 * 77 * FUNCTION: AdDisassemblerHeader 78 * 79 * PARAMETERS: Filename - Input file for the table 80 * TableType - Either AML or DataTable 81 * 82 * RETURN: None 83 * 84 * DESCRIPTION: Create the disassembler header, including ACPICA signon with 85 * current time and date. 86 * 87 *****************************************************************************/ 88 89void 90AdDisassemblerHeader ( 91 char *Filename, 92 UINT8 TableType) 93{ 94 time_t Timer; 95 96 97 time (&Timer); 98 99 /* Header and input table info */ 100 101 AcpiOsPrintf ("/*\n"); 102 AcpiOsPrintf (ACPI_COMMON_HEADER (AML_DISASSEMBLER_NAME, " * ")); 103 104 if (TableType == ACPI_IS_AML_TABLE) 105 { 106 if (AcpiGbl_CstyleDisassembly) 107 { 108 AcpiOsPrintf ( 109 " * Disassembling to symbolic ASL+ operators\n" 110 " *\n"); 111 } 112 else 113 { 114 AcpiOsPrintf ( 115 " * Disassembling to non-symbolic legacy ASL operators\n" 116 " *\n"); 117 } 118 } 119 120 AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer)); 121 AcpiOsPrintf (" *\n"); 122} 123 124 125/****************************************************************************** 126 * 127 * FUNCTION: AdCreateTableHeader 128 * 129 * PARAMETERS: Filename - Input file for the table 130 * Table - Pointer to the raw table 131 * 132 * RETURN: None 133 * 134 * DESCRIPTION: Create the ASL table header, including ACPICA signon with 135 * current time and date. 136 * 137 *****************************************************************************/ 138 139static void 140AdCreateTableHeader ( 141 char *Filename, 142 ACPI_TABLE_HEADER *Table) 143{ 144 UINT8 Checksum; 145 146 147 /* Reset globals for External statements */ 148 149 AcpiGbl_NumExternalMethods = 0; 150 AcpiGbl_ResolvedExternalMethods = 0; 151 152 /* 153 * Print file header and dump original table header 154 */ 155 AdDisassemblerHeader (Filename, ACPI_IS_AML_TABLE); 156 157 AcpiOsPrintf (" * Original Table Header:\n"); 158 AcpiOsPrintf (" * Signature \"%4.4s\"\n", Table->Signature); 159 AcpiOsPrintf (" * Length 0x%8.8X (%u)\n", Table->Length, Table->Length); 160 161 /* Print and validate the revision */ 162 163 AcpiOsPrintf (" * Revision 0x%2.2X", Table->Revision); 164 165 switch (Table->Revision) 166 { 167 case 0: 168 169 AcpiOsPrintf (" **** Invalid Revision"); 170 break; 171 172 case 1: 173 174 /* Revision of DSDT controls the ACPI integer width */ 175 176 if (ACPI_COMPARE_NAMESEG (Table->Signature, ACPI_SIG_DSDT)) 177 { 178 AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support"); 179 } 180 break; 181 182 default: 183 184 break; 185 } 186 187 /* Print and validate the table checksum */ 188 189 AcpiOsPrintf ("\n * Checksum 0x%2.2X", Table->Checksum); 190 191 Checksum = AcpiUtChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length); 192 if (Checksum) 193 { 194 AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X", 195 (UINT8) (Table->Checksum - Checksum)); 196 } 197 198 AcpiOsPrintf ("\n"); 199 AcpiOsPrintf (" * OEM ID \"%.6s\"\n", Table->OemId); 200 AcpiOsPrintf (" * OEM Table ID \"%.8s\"\n", Table->OemTableId); 201 AcpiOsPrintf (" * OEM Revision 0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision); 202 AcpiOsPrintf (" * Compiler ID \"%.4s\"\n", Table->AslCompilerId); 203 AcpiOsPrintf (" * Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision); 204 AcpiOsPrintf (" */\n"); 205 206 /* 207 * Print comments that come before this definition block. 208 */ 209 if (AcpiGbl_CaptureComments) 210 { 211 ASL_CV_PRINT_ONE_COMMENT(AcpiGbl_ParseOpRoot,AML_COMMENT_STANDARD, NULL, 0); 212 } 213 214 /* 215 * Open the ASL definition block. 216 * 217 * Note: the AMLFilename string is left zero-length in order to just let 218 * the compiler create it when the disassembled file is compiled. This 219 * makes it easier to rename the disassembled ASL file if needed. 220 */ 221 AcpiOsPrintf ( 222 "DefinitionBlock (\"\", \"%4.4s\", %u, \"%.6s\", \"%.8s\", 0x%8.8X)\n", 223 Table->Signature, Table->Revision, 224 Table->OemId, Table->OemTableId, Table->OemRevision); 225} 226 227 228/****************************************************************************** 229 * 230 * FUNCTION: AdDisplayTables 231 * 232 * PARAMETERS: Filename - Input file for the table 233 * Table - Pointer to the raw table 234 * 235 * RETURN: Status 236 * 237 * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables 238 * 239 *****************************************************************************/ 240 241ACPI_STATUS 242AdDisplayTables ( 243 char *Filename, 244 ACPI_TABLE_HEADER *Table) 245{ 246 247 248 if (!AcpiGbl_ParseOpRoot) 249 { 250 return (AE_NOT_EXIST); 251 } 252 253 if (!AcpiGbl_DmOpt_Listing) 254 { 255 AdCreateTableHeader (Filename, Table); 256 } 257 258 AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX); 259 MpEmitMappingInfo (); 260 261 if (AcpiGbl_DmOpt_Listing) 262 { 263 AcpiOsPrintf ("\n\nTable Header:\n"); 264 AcpiUtDebugDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER), 265 DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 266 267 AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length); 268 AcpiUtDebugDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)), 269 Table->Length, DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 270 } 271 272 return (AE_OK); 273} 274 275 276/******************************************************************************* 277 * 278 * FUNCTION: AdStoreTable 279 * 280 * PARAMETERS: Table - Table header 281 * TableIndex - Where the table index is returned 282 * 283 * RETURN: Status and table index. 284 * 285 * DESCRIPTION: Add an ACPI table to the global table list 286 * 287 ******************************************************************************/ 288 289static ACPI_STATUS 290AdStoreTable ( 291 ACPI_TABLE_HEADER *Table, 292 UINT32 *TableIndex) 293{ 294 ACPI_STATUS Status; 295 ACPI_TABLE_DESC *TableDesc; 296 297 298 Status = AcpiTbGetNextTableDescriptor (TableIndex, &TableDesc); 299 if (ACPI_FAILURE (Status)) 300 { 301 return (Status); 302 } 303 304 /* Initialize added table */ 305 306 AcpiTbInitTableDescriptor (TableDesc, ACPI_PTR_TO_PHYSADDR (Table), 307 ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, Table); 308 Status = AcpiTbValidateTable (TableDesc); 309 return (Status); 310} 311 312 313/****************************************************************************** 314 * 315 * FUNCTION: AdGetLocalTables 316 * 317 * PARAMETERS: None 318 * 319 * RETURN: Status 320 * 321 * DESCRIPTION: Get the ACPI tables from either memory or a file 322 * 323 *****************************************************************************/ 324 325ACPI_STATUS 326AdGetLocalTables ( 327 void) 328{ 329 ACPI_STATUS Status; 330 ACPI_TABLE_HEADER TableHeader; 331 ACPI_TABLE_HEADER *NewTable; 332 UINT32 TableIndex; 333 334 335 /* Get the DSDT via table override */ 336 337 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT); 338 Status = AcpiOsTableOverride (&TableHeader, &NewTable); 339 if (ACPI_FAILURE (Status) || !NewTable) 340 { 341 fprintf (stderr, "Could not obtain DSDT\n"); 342 return (AE_NO_ACPI_TABLES); 343 } 344 345 AdWriteTable (NewTable, NewTable->Length, 346 ACPI_SIG_DSDT, NewTable->OemTableId); 347 348 /* Store DSDT in the Table Manager */ 349 350 Status = AdStoreTable (NewTable, &TableIndex); 351 if (ACPI_FAILURE (Status)) 352 { 353 fprintf (stderr, "Could not store DSDT\n"); 354 return (AE_NO_ACPI_TABLES); 355 } 356 357 return (AE_OK); 358} 359 360 361/****************************************************************************** 362 * 363 * FUNCTION: AdParseTable 364 * 365 * PARAMETERS: Table - Pointer to the raw table 366 * OwnerId - Returned OwnerId of the table 367 * LoadTable - If add table to the global table list 368 * External - If this is an external table 369 * 370 * RETURN: Status 371 * 372 * DESCRIPTION: Parse an ACPI AML table 373 * 374 *****************************************************************************/ 375 376ACPI_STATUS 377AdParseTable ( 378 ACPI_TABLE_HEADER *Table, 379 ACPI_OWNER_ID *OwnerId, 380 BOOLEAN LoadTable, 381 BOOLEAN External) 382{ 383 ACPI_STATUS Status = AE_OK; 384 ACPI_WALK_STATE *WalkState; 385 UINT8 *AmlStart; 386 UINT32 AmlLength; 387 UINT32 TableIndex; 388 389 390 if (!Table) 391 { 392 return (AE_NOT_EXIST); 393 } 394 395 /* Pass 1: Parse everything except control method bodies */ 396 397 fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature); 398 399 AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER); 400 AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)); 401 402 AcpiUtSetIntegerWidth (Table->Revision); 403 404 /* Create the root object */ 405 406 AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp (AmlStart); 407 if (!AcpiGbl_ParseOpRoot) 408 { 409 return (AE_NO_MEMORY); 410 } 411 412#ifdef ACPI_ASL_COMPILER 413 if (AcpiGbl_CaptureComments) 414 { 415 AcpiGbl_ParseOpRoot->Common.CvFilename = AcpiGbl_FileTreeRoot->Filename; 416 } 417 else 418 { 419 AcpiGbl_ParseOpRoot->Common.CvFilename = NULL; 420 } 421#endif 422 423 /* Create and initialize a new walk state */ 424 425 WalkState = AcpiDsCreateWalkState (0, AcpiGbl_ParseOpRoot, NULL, NULL); 426 if (!WalkState) 427 { 428 return (AE_NO_MEMORY); 429 } 430 431 Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot, 432 NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 433 if (ACPI_FAILURE (Status)) 434 { 435 return (Status); 436 } 437 438 WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 439 440 Status = AcpiPsParseAml (WalkState); 441 if (ACPI_FAILURE (Status)) 442 { 443 return (Status); 444 } 445 446 /* If LoadTable is FALSE, we are parsing the last loaded table */ 447 448 TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1; 449 450 /* Pass 2 */ 451 452 if (LoadTable) 453 { 454 Status = AdStoreTable (Table, &TableIndex); 455 if (ACPI_FAILURE (Status)) 456 { 457 return (Status); 458 } 459 Status = AcpiTbAllocateOwnerId (TableIndex); 460 if (ACPI_FAILURE (Status)) 461 { 462 return (Status); 463 } 464 if (OwnerId) 465 { 466 Status = AcpiTbGetOwnerId (TableIndex, OwnerId); 467 if (ACPI_FAILURE (Status)) 468 { 469 return (Status); 470 } 471 } 472 } 473 474 fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature); 475 476 Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL); 477 if (ACPI_FAILURE (Status)) 478 { 479 return (Status); 480 } 481 482 /* No need to parse control methods of external table */ 483 484 if (External) 485 { 486 return (AE_OK); 487 } 488 489 /* 490 * Pass 3: Parse control methods and link their parse trees 491 * into the main parse tree 492 */ 493 fprintf (stderr, 494 "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n"); 495 496 (void) AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot); 497 fprintf (stderr, "\n"); 498 499 /* Process Resource Templates */ 500 501 AcpiDmFindResources (AcpiGbl_ParseOpRoot); 502 503 fprintf (stderr, "Parsing completed\n"); 504 return (AE_OK); 505} 506