dtcompile.c revision 213806
1/****************************************************************************** 2 * 3 * Module Name: dtcompile.c - Front-end for data table compiler 4 * 5 *****************************************************************************/ 6 7/****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116#define __DTCOMPILE_C__ 117#define _DECLARE_DT_GLOBALS 118 119#include <contrib/dev/acpica/compiler/aslcompiler.h> 120#include <contrib/dev/acpica/compiler/dtcompiler.h> 121 122#define _COMPONENT DT_COMPILER 123 ACPI_MODULE_NAME ("dtcompile") 124 125static char VersionString[9]; 126 127 128/* Local prototypes */ 129 130static ACPI_STATUS 131DtInitialize ( 132 void); 133 134static ACPI_STATUS 135DtCompileDataTable ( 136 DT_FIELD **Field); 137 138static void 139DtInsertCompilerIds ( 140 DT_FIELD *FieldList); 141 142 143/****************************************************************************** 144 * 145 * FUNCTION: DtDoCompile 146 * 147 * PARAMETERS: None 148 * 149 * RETURN: Status 150 * 151 * DESCRIPTION: Main entry point for the data table compiler. 152 * 153 * Note: Assumes Gbl_Files[ASL_FILE_INPUT] is initialized and the file is 154 * open at seek offset zero. 155 * 156 *****************************************************************************/ 157 158ACPI_STATUS 159DtDoCompile ( 160 void) 161{ 162 ACPI_STATUS Status; 163 UINT8 Event; 164 DT_FIELD *FieldList; 165 166 167 /* Initialize globals */ 168 169 Status = DtInitialize (); 170 if (ACPI_FAILURE (Status)) 171 { 172 printf ("Error during compiler initialization, 0x%X\n", Status); 173 return (Status); 174 } 175 176 /* 177 * Scan the input file (file is already open) and 178 * build the parse tree 179 */ 180 Event = UtBeginEvent ("Scan and parse input file"); 181 FieldList = DtScanFile (Gbl_Files[ASL_FILE_INPUT].Handle); 182 UtEndEvent (Event); 183 184 /* Did the parse tree get successfully constructed? */ 185 186 if (!FieldList) 187 { 188 /* TBD: temporary error message. Msgs should come from function above */ 189 190 DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL, 191 "Input file does not appear to be an ASL or data table source file"); 192 193 Status = AE_ERROR; 194 goto CleanupAndExit; 195 } 196 197 Event = UtBeginEvent ("Compile parse tree"); 198 199 /* 200 * Compile the parse tree 201 */ 202 Status = DtCompileDataTable (&FieldList); 203 UtEndEvent (Event); 204 205 DtFreeFieldList (); 206 207 if (ACPI_FAILURE (Status)) 208 { 209 /* TBD: temporary error message. Msgs should come from function above */ 210 211 DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL, 212 "Could not compile input file"); 213 214 goto CleanupAndExit; 215 } 216 217 /* Create/open the binary output file */ 218 219 Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL; 220 Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix); 221 if (ACPI_FAILURE (Status)) 222 { 223 goto CleanupAndExit; 224 } 225 226 /* Write the binary, then the optional hex file */ 227 228 DtOutputBinary (Gbl_RootTable); 229 LsDoHexOutput (); 230 231CleanupAndExit: 232 233 CmCleanupAndExit (); 234 return (Status); 235} 236 237 238/****************************************************************************** 239 * 240 * FUNCTION: DtInitialize 241 * 242 * PARAMETERS: None 243 * 244 * RETURN: Status 245 * 246 * DESCRIPTION: Initialize data table compiler globals. Enables multiple 247 * compiles per invocation. 248 * 249 *****************************************************************************/ 250 251static ACPI_STATUS 252DtInitialize ( 253 void) 254{ 255 ACPI_STATUS Status; 256 257 258 Status = AcpiOsInitialize (); 259 if (ACPI_FAILURE (Status)) 260 { 261 return (Status); 262 } 263 264 Status = AcpiUtInitGlobals (); 265 if (ACPI_FAILURE (Status)) 266 { 267 return (Status); 268 } 269 270 Gbl_FieldList = NULL; 271 Gbl_RootTable = NULL; 272 Gbl_SubtableStack = NULL; 273 274 sprintf (VersionString, "%X", (UINT32) ACPI_CA_VERSION); 275 return (AE_OK); 276} 277 278 279/****************************************************************************** 280 * 281 * FUNCTION: DtInsertCompilerIds 282 * 283 * PARAMETERS: FieldList - Current field list pointer 284 * 285 * RETURN: None 286 * 287 * DESCRIPTION: Insert the IDs (Name, Version) of the current compiler into 288 * the original ACPI table header. 289 * 290 *****************************************************************************/ 291 292static void 293DtInsertCompilerIds ( 294 DT_FIELD *FieldList) 295{ 296 DT_FIELD *Next; 297 UINT32 i; 298 299 300 /* 301 * Don't insert current compiler ID if requested. Used for compiler 302 * debug/validation only. 303 */ 304 if (Gbl_UseOriginalCompilerId) 305 { 306 return; 307 } 308 309 /* Walk to the Compiler fields at the end of the header */ 310 311 Next = FieldList; 312 for (i = 0; i < 7; i++) 313 { 314 Next = Next->Next; 315 } 316 317 Next->Value = ASL_CREATOR_ID; 318 Next->Flags = DT_FIELD_NOT_ALLOCATED; 319 320 Next = Next->Next; 321 Next->Value = VersionString; 322 Next->Flags = DT_FIELD_NOT_ALLOCATED; 323} 324 325 326/****************************************************************************** 327 * 328 * FUNCTION: DtCompileDataTable 329 * 330 * PARAMETERS: FieldList - Current field list pointer 331 * 332 * RETURN: Status 333 * 334 * DESCRIPTION: Entry point to compile one data table 335 * 336 *****************************************************************************/ 337 338static ACPI_STATUS 339DtCompileDataTable ( 340 DT_FIELD **FieldList) 341{ 342 ACPI_DMTABLE_DATA *TableData; 343 DT_SUBTABLE *Subtable; 344 char *Signature; 345 ACPI_TABLE_HEADER *AcpiTableHeader; 346 ACPI_STATUS Status; 347 348 349 /* Verify that we at least have a table signature and save it */ 350 351 Signature = DtGetFieldValue (*FieldList, "Signature"); 352 if (!Signature) 353 { 354 sprintf (MsgBuffer, "Expected \"%s\"", "Signature"); 355 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 356 *FieldList, MsgBuffer); 357 return (AE_ERROR); 358 } 359 360 Gbl_Signature = UtLocalCalloc (ACPI_STRLEN (Signature) + 1); 361 strcpy (Gbl_Signature, Signature); 362 363 /* 364 * Handle tables that don't use the common ACPI table header structure. 365 * Currently, these are the FACS and RSDP. Also check for an OEMx table, 366 * these tables have user-defined contents. 367 */ 368 if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) 369 { 370 Status = DtCompileFacs (FieldList); 371 if (ACPI_FAILURE (Status)) 372 { 373 return (Status); 374 } 375 376 DtSetTableLength (); 377 return (Status); 378 } 379 else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDP)) 380 { 381 Status = DtCompileRsdp (FieldList); 382 return (Status); 383 } 384 else if (!ACPI_STRNCMP (Signature, "OEM", 3)) 385 { 386 DtFatal (ASL_MSG_OEM_TABLE, *FieldList, Signature); 387 return (AE_ERROR); 388 } 389 390 /* Validate the signature via the ACPI table list */ 391 392 TableData = AcpiDmGetTableData (Signature); 393 if (!TableData) 394 { 395 DtFatal (ASL_MSG_UNKNOWN_TABLE, *FieldList, Signature); 396 return (AE_ERROR); 397 } 398 399 /* 400 * All other tables must use the common ACPI table header. Insert the 401 * current iASL IDs (name, version), and compile the header now. 402 */ 403 DtInsertCompilerIds (*FieldList); 404 405 Status = DtCompileTable (FieldList, AcpiDmTableInfoHeader, 406 &Gbl_RootTable, TRUE); 407 if (ACPI_FAILURE (Status)) 408 { 409 return (Status); 410 } 411 412 DtPushSubtable (Gbl_RootTable); 413 414 /* Dispatch to per-table compile */ 415 416 if (TableData->CmTableHandler) 417 { 418 /* Complex table, has a handler */ 419 420 Status = TableData->CmTableHandler ((void **) FieldList); 421 if (ACPI_FAILURE (Status)) 422 { 423 return (Status); 424 } 425 } 426 else if (TableData->TableInfo) 427 { 428 /* Simple table, just walk the info table */ 429 430 Subtable = NULL; 431 Status = DtCompileTable (FieldList, TableData->TableInfo, 432 &Subtable, TRUE); 433 if (ACPI_FAILURE (Status)) 434 { 435 return (Status); 436 } 437 438 DtInsertSubtable (Gbl_RootTable, Subtable); 439 DtPopSubtable (); 440 } 441 else 442 { 443 DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList, 444 "Missing table dispatch info"); 445 return (AE_ERROR); 446 } 447 448 /* Set the final table length and then the checksum */ 449 450 DtSetTableLength (); 451 AcpiTableHeader = ACPI_CAST_PTR ( 452 ACPI_TABLE_HEADER, Gbl_RootTable->Buffer); 453 DtSetTableChecksum (&AcpiTableHeader->Checksum); 454 455 return (AE_OK); 456} 457 458 459/****************************************************************************** 460 * 461 * FUNCTION: DtCompileTable 462 * 463 * PARAMETERS: Field - Current field list pointer 464 * Info - Info table for this ACPI table 465 * RetSubtable - Compile result of table 466 * Required - If this subtable must exist 467 * 468 * RETURN: Status 469 * 470 * DESCRIPTION: Compile a subtable 471 * 472 *****************************************************************************/ 473 474ACPI_STATUS 475DtCompileTable ( 476 DT_FIELD **Field, 477 ACPI_DMTABLE_INFO *Info, 478 DT_SUBTABLE **RetSubtable, 479 BOOLEAN Required) 480{ 481 DT_FIELD *LocalField; 482 UINT32 Length; 483 DT_SUBTABLE *Subtable; 484 DT_SUBTABLE *InlineSubtable; 485 UINT32 FieldLength = 0; 486 UINT8 FieldType; 487 UINT8 *Buffer; 488 UINT8 *FlagBuffer = NULL; 489 ACPI_STATUS Status; 490 491 492 if (!Field || !*Field) 493 { 494 return (AE_BAD_PARAMETER); 495 } 496 497 Length = DtGetSubtableLength (*Field, Info); 498 Subtable = UtLocalCalloc (sizeof (DT_SUBTABLE)); 499 500 Subtable->Buffer = UtLocalCalloc (Length); 501 Subtable->Length = Length; 502 Subtable->TotalLength = Length; 503 Buffer = Subtable->Buffer; 504 505 LocalField = *Field; 506 507 /* 508 * Main loop walks the info table for this ACPI table or subtable 509 */ 510 for (; Info->Name; Info++) 511 { 512 if (!LocalField) 513 { 514 sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed", 515 Info->Name); 516 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 517 Status = AE_BAD_DATA; 518 goto Error; 519 } 520 521 /* Does input field name match what is expected? */ 522 523 if (ACPI_STRCMP (LocalField->Name, Info->Name)) 524 { 525 /* 526 * If Required = TRUE, the subtable must exist. 527 * If Required = FALSE, the subtable is optional 528 * (For example, AcpiDmTableInfoDmarScope in DMAR table is 529 * optional) 530 */ 531 if (Required) 532 { 533 sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 534 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 535 LocalField, MsgBuffer); 536 } 537 else 538 { 539 Status = AE_NOT_FOUND; 540 goto Error; 541 } 542 } 543 544 FieldLength = DtGetFieldLength (LocalField, Info); 545 FieldType = DtGetFieldType (Info); 546 Gbl_InputFieldCount++; 547 548 switch (FieldType) 549 { 550 case DT_FIELD_TYPE_FLAGS_INTEGER: 551 /* 552 * Start of the definition of a flags field. 553 * This master flags integer starts at value zero, in preparation 554 * to compile and insert the flag fields from the individual bits 555 */ 556 LocalField = LocalField->Next; 557 *Field = LocalField; 558 559 FlagBuffer = Buffer; 560 break; 561 562 case DT_FIELD_TYPE_FLAG: 563 564 /* Individual Flag field, can be multiple bits */ 565 566 if (FlagBuffer) 567 { 568 DtCompileFlag (FlagBuffer, LocalField, Info); 569 } 570 else 571 { 572 /* TBD - this is an internal error */ 573 } 574 575 LocalField = LocalField->Next; 576 *Field = LocalField; 577 break; 578 579 case DT_FIELD_TYPE_INLINE_SUBTABLE: 580 /* 581 * Recursion (one level max): compile GAS (Generic Address) 582 * or Notify in-line subtable 583 */ 584 LocalField = LocalField->Next; 585 *Field = LocalField; 586 587 if (Info->Opcode == ACPI_DMT_GAS) 588 { 589 Status = DtCompileTable (Field, AcpiDmTableInfoGas, 590 &InlineSubtable, TRUE); 591 } 592 else 593 { 594 Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify, 595 &InlineSubtable, TRUE); 596 } 597 598 if (ACPI_FAILURE (Status)) 599 { 600 goto Error; 601 } 602 603 DtSetSubtableLength (InlineSubtable); 604 605 ACPI_MEMCPY (Buffer, InlineSubtable->Buffer, FieldLength); 606 ACPI_FREE (InlineSubtable->Buffer); 607 ACPI_FREE (InlineSubtable); 608 LocalField = *Field; 609 break; 610 611 default: 612 613 /* Normal case for most field types (Integer, String, etc.) */ 614 615 DtCompileOneField (Buffer, LocalField, 616 FieldLength, FieldType, Info->Flags); 617 LocalField = LocalField->Next; 618 619 if (Info->Flags & DT_LENGTH) 620 { 621 /* Field is an Integer that will contain a subtable length */ 622 623 Subtable->LengthField = Buffer; 624 Subtable->SizeOfLengthField = FieldLength; 625 } 626 break; 627 } 628 629 Buffer += FieldLength; 630 } 631 632 *Field = LocalField; 633 *RetSubtable = Subtable; 634 return (AE_OK); 635 636Error: 637 ACPI_FREE (Subtable->Buffer); 638 ACPI_FREE (Subtable); 639 return (Status); 640} 641