1208625Sjkim/****************************************************************************** 2208625Sjkim * 3208625Sjkim * Module Name: dtcompile.c - Front-end for data table compiler 4208625Sjkim * 5208625Sjkim *****************************************************************************/ 6208625Sjkim 7316303Sjkim/****************************************************************************** 8316303Sjkim * 9316303Sjkim * 1. Copyright Notice 10316303Sjkim * 11316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. 12208625Sjkim * All rights reserved. 13208625Sjkim * 14316303Sjkim * 2. License 15316303Sjkim * 16316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property 17316303Sjkim * rights. You may have additional license terms from the party that provided 18316303Sjkim * you this software, covering your right to use that party's intellectual 19316303Sjkim * property rights. 20316303Sjkim * 21316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22316303Sjkim * copy of the source code appearing in this file ("Covered Code") an 23316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy, 25316303Sjkim * make derivatives, distribute, use and display any portion of the Covered 26316303Sjkim * Code in any form, with the right to sublicense such rights; and 27316303Sjkim * 28316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29316303Sjkim * license (with the right to sublicense), under only those claims of Intel 30316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell, 31316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof 32316303Sjkim * solely to the minimum extent necessary to exercise the above copyright 33316303Sjkim * license, and in no event shall the patent license extend to any additions 34316303Sjkim * to or modifications of the Original Intel Code. No other license or right 35316303Sjkim * is granted directly or by implication, estoppel or otherwise; 36316303Sjkim * 37316303Sjkim * The above copyright and patent license is granted only if the following 38316303Sjkim * conditions are met: 39316303Sjkim * 40316303Sjkim * 3. Conditions 41316303Sjkim * 42316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43316303Sjkim * Redistribution of source code of any substantial portion of the Covered 44316303Sjkim * Code or modification with rights to further distribute source must include 45316303Sjkim * the above Copyright Notice, the above License, this list of Conditions, 46316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition, 47316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to 48316303Sjkim * contain a file documenting the changes Licensee made to create that Covered 49316303Sjkim * Code and the date of any change. Licensee must include in that file the 50316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee 51316303Sjkim * must include a prominent statement that the modification is derived, 52316303Sjkim * directly or indirectly, from Original Intel Code. 53316303Sjkim * 54316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55316303Sjkim * Redistribution of source code of any substantial portion of the Covered 56316303Sjkim * Code or modification without rights to further distribute source must 57316303Sjkim * include the following Disclaimer and Export Compliance provision in the 58316303Sjkim * documentation and/or other materials provided with distribution. In 59316303Sjkim * addition, Licensee may not authorize further sublicense of source of any 60316303Sjkim * portion of the Covered Code, and must include terms to the effect that the 61316303Sjkim * license from Licensee to its licensee is limited to the intellectual 62316303Sjkim * property embodied in the software Licensee provides to its licensee, and 63316303Sjkim * not to intellectual property embodied in modifications its licensee may 64316303Sjkim * make. 65316303Sjkim * 66316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any 67316303Sjkim * substantial portion of the Covered Code or modification must reproduce the 68316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance 69316303Sjkim * provision in the documentation and/or other materials provided with the 70316303Sjkim * distribution. 71316303Sjkim * 72316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original 73316303Sjkim * Intel Code. 74316303Sjkim * 75316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or 77316303Sjkim * other dealings in products derived from or relating to the Covered Code 78316303Sjkim * without prior written authorization from Intel. 79316303Sjkim * 80316303Sjkim * 4. Disclaimer and Export Compliance 81316303Sjkim * 82316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88316303Sjkim * PARTICULAR PURPOSE. 89316303Sjkim * 90316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97316303Sjkim * LIMITED REMEDY. 98316303Sjkim * 99316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this 100316303Sjkim * software or system incorporating such software without first obtaining any 101316303Sjkim * required license or other approval from the U. S. Department of Commerce or 102316303Sjkim * any other agency or department of the United States Government. In the 103316303Sjkim * event Licensee exports any such software from the United States or 104316303Sjkim * re-exports any such software from a foreign destination, Licensee shall 105316303Sjkim * ensure that the distribution and export/re-export of the software is in 106316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the 107316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108316303Sjkim * any of its subsidiaries will export/re-export any technical data, process, 109316303Sjkim * software, or service, directly or indirectly, to any country for which the 110316303Sjkim * United States government or any agency thereof requires an export license, 111316303Sjkim * other governmental approval, or letter of assurance, without first obtaining 112316303Sjkim * such license, approval or letter. 113316303Sjkim * 114316303Sjkim ***************************************************************************** 115316303Sjkim * 116316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 117316303Sjkim * following license: 118316303Sjkim * 119217365Sjkim * Redistribution and use in source and binary forms, with or without 120217365Sjkim * modification, are permitted provided that the following conditions 121217365Sjkim * are met: 122217365Sjkim * 1. Redistributions of source code must retain the above copyright 123217365Sjkim * notice, this list of conditions, and the following disclaimer, 124217365Sjkim * without modification. 125217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 127217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 128217365Sjkim * including a substantially similar Disclaimer requirement for further 129217365Sjkim * binary redistribution. 130217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 131217365Sjkim * of any contributors may be used to endorse or promote products derived 132217365Sjkim * from this software without specific prior written permission. 133208625Sjkim * 134316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145316303Sjkim * 146316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 147217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 148217365Sjkim * Software Foundation. 149208625Sjkim * 150316303Sjkim *****************************************************************************/ 151208625Sjkim 152208625Sjkim#define _DECLARE_DT_GLOBALS 153208625Sjkim 154209746Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 155208625Sjkim 156208625Sjkim#define _COMPONENT DT_COMPILER 157208625Sjkim ACPI_MODULE_NAME ("dtcompile") 158208625Sjkim 159208625Sjkimstatic char VersionString[9]; 160208625Sjkim 161208625Sjkim 162208625Sjkim/* Local prototypes */ 163208625Sjkim 164212761Sjkimstatic ACPI_STATUS 165208625SjkimDtInitialize ( 166208625Sjkim void); 167208625Sjkim 168208625Sjkimstatic ACPI_STATUS 169208625SjkimDtCompileDataTable ( 170208625Sjkim DT_FIELD **Field); 171208625Sjkim 172208625Sjkimstatic void 173208625SjkimDtInsertCompilerIds ( 174208625Sjkim DT_FIELD *FieldList); 175208625Sjkim 176208625Sjkim 177208625Sjkim/****************************************************************************** 178208625Sjkim * 179208625Sjkim * FUNCTION: DtDoCompile 180208625Sjkim * 181208625Sjkim * PARAMETERS: None 182208625Sjkim * 183208625Sjkim * RETURN: Status 184208625Sjkim * 185208625Sjkim * DESCRIPTION: Main entry point for the data table compiler. 186208625Sjkim * 187208625Sjkim * Note: Assumes Gbl_Files[ASL_FILE_INPUT] is initialized and the file is 188208625Sjkim * open at seek offset zero. 189208625Sjkim * 190208625Sjkim *****************************************************************************/ 191208625Sjkim 192208625SjkimACPI_STATUS 193208625SjkimDtDoCompile ( 194208625Sjkim void) 195208625Sjkim{ 196208625Sjkim ACPI_STATUS Status; 197208625Sjkim UINT8 Event; 198208625Sjkim DT_FIELD *FieldList; 199208625Sjkim 200208625Sjkim 201208625Sjkim /* Initialize globals */ 202208625Sjkim 203212761Sjkim Status = DtInitialize (); 204212761Sjkim if (ACPI_FAILURE (Status)) 205212761Sjkim { 206212761Sjkim printf ("Error during compiler initialization, 0x%X\n", Status); 207212761Sjkim return (Status); 208212761Sjkim } 209208625Sjkim 210233250Sjkim /* Preprocessor */ 211233250Sjkim 212281396Sjkim if (Gbl_PreprocessFlag) 213281396Sjkim { 214281396Sjkim /* Preprocessor */ 215233250Sjkim 216281396Sjkim Event = UtBeginEvent ("Preprocess input file"); 217281396Sjkim PrDoPreprocess (); 218281396Sjkim UtEndEvent (Event); 219281396Sjkim 220281396Sjkim if (Gbl_PreprocessOnly) 221281396Sjkim { 222281396Sjkim return (AE_OK); 223281396Sjkim } 224233250Sjkim } 225233250Sjkim 226208625Sjkim /* 227208625Sjkim * Scan the input file (file is already open) and 228208625Sjkim * build the parse tree 229208625Sjkim */ 230208625Sjkim Event = UtBeginEvent ("Scan and parse input file"); 231208625Sjkim FieldList = DtScanFile (Gbl_Files[ASL_FILE_INPUT].Handle); 232208625Sjkim UtEndEvent (Event); 233208625Sjkim 234208625Sjkim /* Did the parse tree get successfully constructed? */ 235208625Sjkim 236208625Sjkim if (!FieldList) 237208625Sjkim { 238208625Sjkim /* TBD: temporary error message. Msgs should come from function above */ 239208625Sjkim 240208625Sjkim DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL, 241209734Sjkim "Input file does not appear to be an ASL or data table source file"); 242209734Sjkim 243209734Sjkim Status = AE_ERROR; 244209734Sjkim goto CleanupAndExit; 245208625Sjkim } 246208625Sjkim 247208625Sjkim Event = UtBeginEvent ("Compile parse tree"); 248208625Sjkim 249208625Sjkim /* 250208625Sjkim * Compile the parse tree 251208625Sjkim */ 252208625Sjkim Status = DtCompileDataTable (&FieldList); 253208625Sjkim UtEndEvent (Event); 254208625Sjkim 255208625Sjkim if (ACPI_FAILURE (Status)) 256208625Sjkim { 257208625Sjkim /* TBD: temporary error message. Msgs should come from function above */ 258208625Sjkim 259208625Sjkim DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL, 260208625Sjkim "Could not compile input file"); 261209734Sjkim 262208625Sjkim goto CleanupAndExit; 263208625Sjkim } 264208625Sjkim 265208625Sjkim /* Create/open the binary output file */ 266208625Sjkim 267208625Sjkim Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL; 268208625Sjkim Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix); 269208625Sjkim if (ACPI_FAILURE (Status)) 270208625Sjkim { 271208625Sjkim goto CleanupAndExit; 272208625Sjkim } 273208625Sjkim 274208625Sjkim /* Write the binary, then the optional hex file */ 275208625Sjkim 276208625Sjkim DtOutputBinary (Gbl_RootTable); 277245582Sjkim HxDoHexOutput (); 278217365Sjkim DtWriteTableToListing (); 279208625Sjkim 280208625SjkimCleanupAndExit: 281208625Sjkim 282272444Sjkim AcpiUtDeleteCaches (); 283208625Sjkim CmCleanupAndExit (); 284208625Sjkim return (Status); 285208625Sjkim} 286208625Sjkim 287208625Sjkim 288208625Sjkim/****************************************************************************** 289208625Sjkim * 290208625Sjkim * FUNCTION: DtInitialize 291208625Sjkim * 292208625Sjkim * PARAMETERS: None 293208625Sjkim * 294212761Sjkim * RETURN: Status 295208625Sjkim * 296208625Sjkim * DESCRIPTION: Initialize data table compiler globals. Enables multiple 297208625Sjkim * compiles per invocation. 298208625Sjkim * 299208625Sjkim *****************************************************************************/ 300208625Sjkim 301212761Sjkimstatic ACPI_STATUS 302208625SjkimDtInitialize ( 303208625Sjkim void) 304208625Sjkim{ 305212761Sjkim ACPI_STATUS Status; 306208625Sjkim 307209734Sjkim 308212761Sjkim Status = AcpiOsInitialize (); 309212761Sjkim if (ACPI_FAILURE (Status)) 310212761Sjkim { 311212761Sjkim return (Status); 312212761Sjkim } 313212761Sjkim 314212761Sjkim Status = AcpiUtInitGlobals (); 315212761Sjkim if (ACPI_FAILURE (Status)) 316212761Sjkim { 317212761Sjkim return (Status); 318212761Sjkim } 319212761Sjkim 320327557Sjkim AcpiUtSetIntegerWidth (2); /* Set width to 64 bits */ 321327557Sjkim 322208625Sjkim Gbl_FieldList = NULL; 323208625Sjkim Gbl_RootTable = NULL; 324208625Sjkim Gbl_SubtableStack = NULL; 325208625Sjkim 326208625Sjkim sprintf (VersionString, "%X", (UINT32) ACPI_CA_VERSION); 327212761Sjkim return (AE_OK); 328208625Sjkim} 329208625Sjkim 330208625Sjkim 331208625Sjkim/****************************************************************************** 332208625Sjkim * 333208625Sjkim * FUNCTION: DtInsertCompilerIds 334208625Sjkim * 335208625Sjkim * PARAMETERS: FieldList - Current field list pointer 336208625Sjkim * 337208625Sjkim * RETURN: None 338208625Sjkim * 339208625Sjkim * DESCRIPTION: Insert the IDs (Name, Version) of the current compiler into 340208625Sjkim * the original ACPI table header. 341208625Sjkim * 342208625Sjkim *****************************************************************************/ 343208625Sjkim 344208625Sjkimstatic void 345208625SjkimDtInsertCompilerIds ( 346208625Sjkim DT_FIELD *FieldList) 347208625Sjkim{ 348208625Sjkim DT_FIELD *Next; 349208625Sjkim UINT32 i; 350208625Sjkim 351208625Sjkim 352208625Sjkim /* 353208625Sjkim * Don't insert current compiler ID if requested. Used for compiler 354208625Sjkim * debug/validation only. 355208625Sjkim */ 356208625Sjkim if (Gbl_UseOriginalCompilerId) 357208625Sjkim { 358208625Sjkim return; 359208625Sjkim } 360208625Sjkim 361208625Sjkim /* Walk to the Compiler fields at the end of the header */ 362208625Sjkim 363208625Sjkim Next = FieldList; 364208625Sjkim for (i = 0; i < 7; i++) 365208625Sjkim { 366208625Sjkim Next = Next->Next; 367208625Sjkim } 368208625Sjkim 369213806Sjkim Next->Value = ASL_CREATOR_ID; 370208625Sjkim Next->Flags = DT_FIELD_NOT_ALLOCATED; 371208625Sjkim 372208625Sjkim Next = Next->Next; 373208625Sjkim Next->Value = VersionString; 374208625Sjkim Next->Flags = DT_FIELD_NOT_ALLOCATED; 375208625Sjkim} 376208625Sjkim 377208625Sjkim 378208625Sjkim/****************************************************************************** 379208625Sjkim * 380208625Sjkim * FUNCTION: DtCompileDataTable 381208625Sjkim * 382208625Sjkim * PARAMETERS: FieldList - Current field list pointer 383208625Sjkim * 384208625Sjkim * RETURN: Status 385208625Sjkim * 386208625Sjkim * DESCRIPTION: Entry point to compile one data table 387208625Sjkim * 388208625Sjkim *****************************************************************************/ 389208625Sjkim 390208625Sjkimstatic ACPI_STATUS 391208625SjkimDtCompileDataTable ( 392208625Sjkim DT_FIELD **FieldList) 393208625Sjkim{ 394283092Sjkim const ACPI_DMTABLE_DATA *TableData; 395208625Sjkim DT_SUBTABLE *Subtable; 396208625Sjkim char *Signature; 397208625Sjkim ACPI_TABLE_HEADER *AcpiTableHeader; 398208625Sjkim ACPI_STATUS Status; 399245582Sjkim DT_FIELD *RootField = *FieldList; 400208625Sjkim 401208625Sjkim 402208625Sjkim /* Verify that we at least have a table signature and save it */ 403208625Sjkim 404220663Sjkim Signature = DtGetFieldValue (*FieldList); 405208625Sjkim if (!Signature) 406208625Sjkim { 407209734Sjkim sprintf (MsgBuffer, "Expected \"%s\"", "Signature"); 408209734Sjkim DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 409209734Sjkim *FieldList, MsgBuffer); 410208625Sjkim return (AE_ERROR); 411208625Sjkim } 412208625Sjkim 413327557Sjkim Gbl_Signature = UtLocalCacheCalloc (strlen (Signature) + 1); 414208625Sjkim strcpy (Gbl_Signature, Signature); 415208625Sjkim 416208625Sjkim /* 417208625Sjkim * Handle tables that don't use the common ACPI table header structure. 418208625Sjkim * Currently, these are the FACS and RSDP. Also check for an OEMx table, 419208625Sjkim * these tables have user-defined contents. 420208625Sjkim */ 421208625Sjkim if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) 422208625Sjkim { 423208625Sjkim Status = DtCompileFacs (FieldList); 424208625Sjkim if (ACPI_FAILURE (Status)) 425208625Sjkim { 426208625Sjkim return (Status); 427208625Sjkim } 428208625Sjkim 429208625Sjkim DtSetTableLength (); 430208625Sjkim return (Status); 431208625Sjkim } 432254745Sjkim else if (ACPI_VALIDATE_RSDP_SIG (Signature)) 433208625Sjkim { 434208625Sjkim Status = DtCompileRsdp (FieldList); 435208625Sjkim return (Status); 436208625Sjkim } 437228110Sjkim else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_S3PT)) 438228110Sjkim { 439228110Sjkim Status = DtCompileS3pt (FieldList); 440228110Sjkim if (ACPI_FAILURE (Status)) 441228110Sjkim { 442228110Sjkim return (Status); 443228110Sjkim } 444208625Sjkim 445228110Sjkim DtSetTableLength (); 446228110Sjkim return (Status); 447228110Sjkim } 448228110Sjkim 449208625Sjkim /* 450208625Sjkim * All other tables must use the common ACPI table header. Insert the 451208625Sjkim * current iASL IDs (name, version), and compile the header now. 452208625Sjkim */ 453208625Sjkim DtInsertCompilerIds (*FieldList); 454208625Sjkim 455208625Sjkim Status = DtCompileTable (FieldList, AcpiDmTableInfoHeader, 456298714Sjkim &Gbl_RootTable, TRUE); 457208625Sjkim if (ACPI_FAILURE (Status)) 458208625Sjkim { 459208625Sjkim return (Status); 460208625Sjkim } 461208625Sjkim 462208625Sjkim DtPushSubtable (Gbl_RootTable); 463208625Sjkim 464220663Sjkim /* Validate the signature via the ACPI table list */ 465220663Sjkim 466220663Sjkim TableData = AcpiDmGetTableData (Signature); 467228110Sjkim if (!TableData || Gbl_CompileGeneric) 468220663Sjkim { 469284583Sjkim /* Unknown table signature and/or force generic compile */ 470284583Sjkim 471283092Sjkim DtCompileGeneric ((void **) FieldList, NULL, NULL); 472245582Sjkim goto FinishHeader; 473220663Sjkim } 474220663Sjkim 475209734Sjkim /* Dispatch to per-table compile */ 476208625Sjkim 477208625Sjkim if (TableData->CmTableHandler) 478208625Sjkim { 479208625Sjkim /* Complex table, has a handler */ 480208625Sjkim 481208625Sjkim Status = TableData->CmTableHandler ((void **) FieldList); 482208625Sjkim if (ACPI_FAILURE (Status)) 483208625Sjkim { 484208625Sjkim return (Status); 485208625Sjkim } 486208625Sjkim } 487208625Sjkim else if (TableData->TableInfo) 488208625Sjkim { 489322877Sjkim /* Simple table, just walk the info table, unless its empty */ 490208625Sjkim 491322877Sjkim if (FieldList && *FieldList) 492208625Sjkim { 493322877Sjkim Subtable = NULL; 494322877Sjkim Status = DtCompileTable (FieldList, TableData->TableInfo, 495322877Sjkim &Subtable, TRUE); 496322877Sjkim if (ACPI_FAILURE (Status)) 497322877Sjkim { 498322877Sjkim return (Status); 499322877Sjkim } 500322877Sjkim 501322877Sjkim DtInsertSubtable (Gbl_RootTable, Subtable); 502322877Sjkim DtPopSubtable (); 503208625Sjkim } 504208625Sjkim } 505208625Sjkim else 506208625Sjkim { 507208625Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList, 508208625Sjkim "Missing table dispatch info"); 509208625Sjkim return (AE_ERROR); 510208625Sjkim } 511208625Sjkim 512245582SjkimFinishHeader: 513245582Sjkim 514208625Sjkim /* Set the final table length and then the checksum */ 515208625Sjkim 516208625Sjkim DtSetTableLength (); 517208625Sjkim AcpiTableHeader = ACPI_CAST_PTR ( 518208625Sjkim ACPI_TABLE_HEADER, Gbl_RootTable->Buffer); 519208625Sjkim DtSetTableChecksum (&AcpiTableHeader->Checksum); 520208625Sjkim 521245582Sjkim DtDumpFieldList (RootField); 522245582Sjkim DtDumpSubtableList (); 523208625Sjkim return (AE_OK); 524208625Sjkim} 525208625Sjkim 526208625Sjkim 527208625Sjkim/****************************************************************************** 528208625Sjkim * 529208625Sjkim * FUNCTION: DtCompileTable 530208625Sjkim * 531208625Sjkim * PARAMETERS: Field - Current field list pointer 532208625Sjkim * Info - Info table for this ACPI table 533208625Sjkim * RetSubtable - Compile result of table 534208625Sjkim * Required - If this subtable must exist 535208625Sjkim * 536208625Sjkim * RETURN: Status 537208625Sjkim * 538208625Sjkim * DESCRIPTION: Compile a subtable 539208625Sjkim * 540208625Sjkim *****************************************************************************/ 541208625Sjkim 542208625SjkimACPI_STATUS 543208625SjkimDtCompileTable ( 544208625Sjkim DT_FIELD **Field, 545208625Sjkim ACPI_DMTABLE_INFO *Info, 546208625Sjkim DT_SUBTABLE **RetSubtable, 547208625Sjkim BOOLEAN Required) 548208625Sjkim{ 549208625Sjkim DT_FIELD *LocalField; 550208625Sjkim UINT32 Length; 551208625Sjkim DT_SUBTABLE *Subtable; 552283092Sjkim DT_SUBTABLE *InlineSubtable = NULL; 553208625Sjkim UINT32 FieldLength = 0; 554208625Sjkim UINT8 FieldType; 555208625Sjkim UINT8 *Buffer; 556208625Sjkim UINT8 *FlagBuffer = NULL; 557272444Sjkim char *String; 558228110Sjkim UINT32 CurrentFlagByteOffset = 0; 559283092Sjkim ACPI_STATUS Status = AE_OK; 560208625Sjkim 561208625Sjkim 562327557Sjkim if (!Field) 563208625Sjkim { 564208625Sjkim return (AE_BAD_PARAMETER); 565208625Sjkim } 566327557Sjkim if (!*Field) 567327557Sjkim { 568327557Sjkim /* 569327557Sjkim * The field list is empty, this means that we are out of fields to 570327557Sjkim * parse. In other words, we are at the end of the table. 571327557Sjkim */ 572327557Sjkim return (AE_END_OF_TABLE); 573327557Sjkim } 574208625Sjkim 575272444Sjkim /* Ignore optional subtable if name does not match */ 576272444Sjkim 577272444Sjkim if ((Info->Flags & DT_OPTIONAL) && 578284583Sjkim strcmp ((*Field)->Name, Info->Name)) 579272444Sjkim { 580272444Sjkim *RetSubtable = NULL; 581272444Sjkim return (AE_OK); 582272444Sjkim } 583272444Sjkim 584208625Sjkim Length = DtGetSubtableLength (*Field, Info); 585220663Sjkim if (Length == ASL_EOF) 586220663Sjkim { 587220663Sjkim return (AE_ERROR); 588220663Sjkim } 589220663Sjkim 590272444Sjkim Subtable = UtSubtableCacheCalloc (); 591208625Sjkim 592218590Sjkim if (Length > 0) 593218590Sjkim { 594327557Sjkim String = UtLocalCacheCalloc (Length); 595272444Sjkim Subtable->Buffer = ACPI_CAST_PTR (UINT8, String); 596218590Sjkim } 597272444Sjkim 598208625Sjkim Subtable->Length = Length; 599208625Sjkim Subtable->TotalLength = Length; 600208625Sjkim Buffer = Subtable->Buffer; 601208625Sjkim 602208625Sjkim LocalField = *Field; 603283092Sjkim Subtable->Name = LocalField->Name; 604208625Sjkim 605208625Sjkim /* 606208625Sjkim * Main loop walks the info table for this ACPI table or subtable 607208625Sjkim */ 608208625Sjkim for (; Info->Name; Info++) 609208625Sjkim { 610228110Sjkim if (Info->Opcode == ACPI_DMT_EXTRA_TEXT) 611228110Sjkim { 612228110Sjkim continue; 613228110Sjkim } 614228110Sjkim 615208625Sjkim if (!LocalField) 616208625Sjkim { 617208625Sjkim sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed", 618208625Sjkim Info->Name); 619208625Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 620208625Sjkim Status = AE_BAD_DATA; 621208625Sjkim goto Error; 622208625Sjkim } 623208625Sjkim 624218590Sjkim /* Maintain table offsets */ 625218590Sjkim 626218590Sjkim LocalField->TableOffset = Gbl_CurrentTableOffset; 627208625Sjkim FieldLength = DtGetFieldLength (LocalField, Info); 628218590Sjkim Gbl_CurrentTableOffset += FieldLength; 629218590Sjkim 630208625Sjkim FieldType = DtGetFieldType (Info); 631208625Sjkim Gbl_InputFieldCount++; 632208625Sjkim 633208625Sjkim switch (FieldType) 634208625Sjkim { 635208625Sjkim case DT_FIELD_TYPE_FLAGS_INTEGER: 636208625Sjkim /* 637208625Sjkim * Start of the definition of a flags field. 638208625Sjkim * This master flags integer starts at value zero, in preparation 639208625Sjkim * to compile and insert the flag fields from the individual bits 640208625Sjkim */ 641208625Sjkim LocalField = LocalField->Next; 642208625Sjkim *Field = LocalField; 643208625Sjkim 644208625Sjkim FlagBuffer = Buffer; 645228110Sjkim CurrentFlagByteOffset = Info->Offset; 646208625Sjkim break; 647208625Sjkim 648208625Sjkim case DT_FIELD_TYPE_FLAG: 649208625Sjkim 650208625Sjkim /* Individual Flag field, can be multiple bits */ 651208625Sjkim 652208625Sjkim if (FlagBuffer) 653208625Sjkim { 654228110Sjkim /* 655228110Sjkim * We must increment the FlagBuffer when we have crossed 656228110Sjkim * into the next flags byte within the flags field 657228110Sjkim * of type DT_FIELD_TYPE_FLAGS_INTEGER. 658228110Sjkim */ 659228110Sjkim FlagBuffer += (Info->Offset - CurrentFlagByteOffset); 660228110Sjkim CurrentFlagByteOffset = Info->Offset; 661228110Sjkim 662209734Sjkim DtCompileFlag (FlagBuffer, LocalField, Info); 663208625Sjkim } 664208625Sjkim else 665208625Sjkim { 666208625Sjkim /* TBD - this is an internal error */ 667208625Sjkim } 668208625Sjkim 669208625Sjkim LocalField = LocalField->Next; 670208625Sjkim *Field = LocalField; 671208625Sjkim break; 672208625Sjkim 673208625Sjkim case DT_FIELD_TYPE_INLINE_SUBTABLE: 674208625Sjkim /* 675208625Sjkim * Recursion (one level max): compile GAS (Generic Address) 676208625Sjkim * or Notify in-line subtable 677208625Sjkim */ 678208625Sjkim *Field = LocalField; 679208625Sjkim 680283092Sjkim switch (Info->Opcode) 681208625Sjkim { 682283092Sjkim case ACPI_DMT_GAS: 683283092Sjkim 684208625Sjkim Status = DtCompileTable (Field, AcpiDmTableInfoGas, 685208625Sjkim &InlineSubtable, TRUE); 686283092Sjkim break; 687283092Sjkim 688283092Sjkim case ACPI_DMT_HESTNTFY: 689283092Sjkim 690208625Sjkim Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify, 691208625Sjkim &InlineSubtable, TRUE); 692283092Sjkim break; 693283092Sjkim 694283092Sjkim case ACPI_DMT_IORTMEM: 695283092Sjkim 696283092Sjkim Status = DtCompileTable (Field, AcpiDmTableInfoIortAcc, 697283092Sjkim &InlineSubtable, TRUE); 698283092Sjkim break; 699283092Sjkim 700283092Sjkim default: 701283092Sjkim sprintf (MsgBuffer, "Invalid DMT opcode: 0x%.2X", 702283092Sjkim Info->Opcode); 703283092Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 704283092Sjkim Status = AE_BAD_DATA; 705283092Sjkim break; 706208625Sjkim } 707208625Sjkim 708208625Sjkim if (ACPI_FAILURE (Status)) 709208625Sjkim { 710208625Sjkim goto Error; 711208625Sjkim } 712208625Sjkim 713209734Sjkim DtSetSubtableLength (InlineSubtable); 714209734Sjkim 715284583Sjkim memcpy (Buffer, InlineSubtable->Buffer, FieldLength); 716208625Sjkim LocalField = *Field; 717208625Sjkim break; 718208625Sjkim 719218590Sjkim case DT_FIELD_TYPE_LABEL: 720218590Sjkim 721218590Sjkim DtWriteFieldToListing (Buffer, LocalField, 0); 722218590Sjkim LocalField = LocalField->Next; 723218590Sjkim break; 724218590Sjkim 725208625Sjkim default: 726208625Sjkim 727208625Sjkim /* Normal case for most field types (Integer, String, etc.) */ 728208625Sjkim 729208625Sjkim DtCompileOneField (Buffer, LocalField, 730208625Sjkim FieldLength, FieldType, Info->Flags); 731217365Sjkim 732217365Sjkim DtWriteFieldToListing (Buffer, LocalField, FieldLength); 733208625Sjkim LocalField = LocalField->Next; 734208625Sjkim 735208625Sjkim if (Info->Flags & DT_LENGTH) 736208625Sjkim { 737208625Sjkim /* Field is an Integer that will contain a subtable length */ 738208625Sjkim 739208625Sjkim Subtable->LengthField = Buffer; 740208625Sjkim Subtable->SizeOfLengthField = FieldLength; 741208625Sjkim } 742208625Sjkim break; 743208625Sjkim } 744208625Sjkim 745208625Sjkim Buffer += FieldLength; 746208625Sjkim } 747208625Sjkim 748208625Sjkim *Field = LocalField; 749208625Sjkim *RetSubtable = Subtable; 750208625Sjkim return (AE_OK); 751208625Sjkim 752208625SjkimError: 753208625Sjkim ACPI_FREE (Subtable->Buffer); 754208625Sjkim ACPI_FREE (Subtable); 755208625Sjkim return (Status); 756208625Sjkim} 757283092Sjkim 758283092Sjkim 759283092Sjkim/****************************************************************************** 760283092Sjkim * 761298714Sjkim * FUNCTION: DtCompileTwoSubtables 762298714Sjkim * 763298714Sjkim * PARAMETERS: List - Current field list pointer 764298714Sjkim * TableInfo1 - Info table 1 765298714Sjkim * TableInfo1 - Info table 2 766298714Sjkim * 767298714Sjkim * RETURN: Status 768298714Sjkim * 769298714Sjkim * DESCRIPTION: Compile tables with a header and one or more same subtables. 770298714Sjkim * Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT 771298714Sjkim * 772298714Sjkim *****************************************************************************/ 773298714Sjkim 774298714SjkimACPI_STATUS 775298714SjkimDtCompileTwoSubtables ( 776298714Sjkim void **List, 777298714Sjkim ACPI_DMTABLE_INFO *TableInfo1, 778298714Sjkim ACPI_DMTABLE_INFO *TableInfo2) 779298714Sjkim{ 780298714Sjkim ACPI_STATUS Status; 781298714Sjkim DT_SUBTABLE *Subtable; 782298714Sjkim DT_SUBTABLE *ParentTable; 783298714Sjkim DT_FIELD **PFieldList = (DT_FIELD **) List; 784298714Sjkim 785298714Sjkim 786298714Sjkim Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE); 787298714Sjkim if (ACPI_FAILURE (Status)) 788298714Sjkim { 789298714Sjkim return (Status); 790298714Sjkim } 791298714Sjkim 792298714Sjkim ParentTable = DtPeekSubtable (); 793298714Sjkim DtInsertSubtable (ParentTable, Subtable); 794298714Sjkim 795298714Sjkim while (*PFieldList) 796298714Sjkim { 797298714Sjkim Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE); 798298714Sjkim if (ACPI_FAILURE (Status)) 799298714Sjkim { 800298714Sjkim return (Status); 801298714Sjkim } 802298714Sjkim 803298714Sjkim DtInsertSubtable (ParentTable, Subtable); 804298714Sjkim } 805298714Sjkim 806298714Sjkim return (AE_OK); 807298714Sjkim} 808298714Sjkim 809298714Sjkim 810298714Sjkim/****************************************************************************** 811298714Sjkim * 812283092Sjkim * FUNCTION: DtCompilePadding 813283092Sjkim * 814283092Sjkim * PARAMETERS: Length - Padding field size 815283092Sjkim * RetSubtable - Compile result of table 816283092Sjkim * 817283092Sjkim * RETURN: Status 818283092Sjkim * 819283092Sjkim * DESCRIPTION: Compile a subtable for padding purpose 820283092Sjkim * 821283092Sjkim *****************************************************************************/ 822283092Sjkim 823283092SjkimACPI_STATUS 824283092SjkimDtCompilePadding ( 825283092Sjkim UINT32 Length, 826283092Sjkim DT_SUBTABLE **RetSubtable) 827283092Sjkim{ 828283092Sjkim DT_SUBTABLE *Subtable; 829283092Sjkim /* UINT8 *Buffer; */ 830283092Sjkim char *String; 831283092Sjkim 832283092Sjkim 833283092Sjkim Subtable = UtSubtableCacheCalloc (); 834283092Sjkim 835283092Sjkim if (Length > 0) 836283092Sjkim { 837327557Sjkim String = UtLocalCacheCalloc (Length); 838283092Sjkim Subtable->Buffer = ACPI_CAST_PTR (UINT8, String); 839283092Sjkim } 840283092Sjkim 841283092Sjkim Subtable->Length = Length; 842283092Sjkim Subtable->TotalLength = Length; 843283092Sjkim /* Buffer = Subtable->Buffer; */ 844283092Sjkim 845283092Sjkim *RetSubtable = Subtable; 846283092Sjkim return (AE_OK); 847283092Sjkim} 848