1208625Sjkim/****************************************************************************** 2208625Sjkim * 3208625Sjkim * Module Name: dtcompile.c - Front-end for data table compiler 4208625Sjkim * 5208625Sjkim *****************************************************************************/ 6208625Sjkim 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 9208625Sjkim * All rights reserved. 10208625Sjkim * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 25208625Sjkim * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 29208625Sjkim * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 43208625Sjkim 44208625Sjkim#define _DECLARE_DT_GLOBALS 45208625Sjkim 46209746Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 47209746Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h> 48208625Sjkim 49208625Sjkim#define _COMPONENT DT_COMPILER 50208625Sjkim ACPI_MODULE_NAME ("dtcompile") 51208625Sjkim 52208625Sjkimstatic char VersionString[9]; 53208625Sjkim 54208625Sjkim 55208625Sjkim/* Local prototypes */ 56208625Sjkim 57212761Sjkimstatic ACPI_STATUS 58208625SjkimDtInitialize ( 59208625Sjkim void); 60208625Sjkim 61208625Sjkimstatic ACPI_STATUS 62208625SjkimDtCompileDataTable ( 63208625Sjkim DT_FIELD **Field); 64208625Sjkim 65208625Sjkimstatic void 66208625SjkimDtInsertCompilerIds ( 67208625Sjkim DT_FIELD *FieldList); 68208625Sjkim 69208625Sjkim 70208625Sjkim/****************************************************************************** 71208625Sjkim * 72208625Sjkim * FUNCTION: DtDoCompile 73208625Sjkim * 74208625Sjkim * PARAMETERS: None 75208625Sjkim * 76208625Sjkim * RETURN: Status 77208625Sjkim * 78208625Sjkim * DESCRIPTION: Main entry point for the data table compiler. 79208625Sjkim * 80208625Sjkim * Note: Assumes Gbl_Files[ASL_FILE_INPUT] is initialized and the file is 81208625Sjkim * open at seek offset zero. 82208625Sjkim * 83208625Sjkim *****************************************************************************/ 84208625Sjkim 85208625SjkimACPI_STATUS 86208625SjkimDtDoCompile ( 87208625Sjkim void) 88208625Sjkim{ 89208625Sjkim ACPI_STATUS Status; 90208625Sjkim UINT8 Event; 91208625Sjkim DT_FIELD *FieldList; 92208625Sjkim 93208625Sjkim 94208625Sjkim /* Initialize globals */ 95208625Sjkim 96212761Sjkim Status = DtInitialize (); 97212761Sjkim if (ACPI_FAILURE (Status)) 98212761Sjkim { 99212761Sjkim printf ("Error during compiler initialization, 0x%X\n", Status); 100212761Sjkim return (Status); 101212761Sjkim } 102208625Sjkim 103233250Sjkim /* Preprocessor */ 104233250Sjkim 105281687Sjkim if (Gbl_PreprocessFlag) 106281687Sjkim { 107281687Sjkim /* Preprocessor */ 108233250Sjkim 109281687Sjkim Event = UtBeginEvent ("Preprocess input file"); 110281687Sjkim PrDoPreprocess (); 111281687Sjkim UtEndEvent (Event); 112281687Sjkim 113281687Sjkim if (Gbl_PreprocessOnly) 114281687Sjkim { 115281687Sjkim return (AE_OK); 116281687Sjkim } 117233250Sjkim } 118233250Sjkim 119208625Sjkim /* 120208625Sjkim * Scan the input file (file is already open) and 121208625Sjkim * build the parse tree 122208625Sjkim */ 123208625Sjkim Event = UtBeginEvent ("Scan and parse input file"); 124208625Sjkim FieldList = DtScanFile (Gbl_Files[ASL_FILE_INPUT].Handle); 125208625Sjkim UtEndEvent (Event); 126208625Sjkim 127208625Sjkim /* Did the parse tree get successfully constructed? */ 128208625Sjkim 129208625Sjkim if (!FieldList) 130208625Sjkim { 131208625Sjkim /* TBD: temporary error message. Msgs should come from function above */ 132208625Sjkim 133208625Sjkim DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL, 134209734Sjkim "Input file does not appear to be an ASL or data table source file"); 135209734Sjkim 136209734Sjkim Status = AE_ERROR; 137209734Sjkim goto CleanupAndExit; 138208625Sjkim } 139208625Sjkim 140208625Sjkim Event = UtBeginEvent ("Compile parse tree"); 141208625Sjkim 142208625Sjkim /* 143208625Sjkim * Compile the parse tree 144208625Sjkim */ 145208625Sjkim Status = DtCompileDataTable (&FieldList); 146208625Sjkim UtEndEvent (Event); 147208625Sjkim 148208625Sjkim if (ACPI_FAILURE (Status)) 149208625Sjkim { 150208625Sjkim /* TBD: temporary error message. Msgs should come from function above */ 151208625Sjkim 152208625Sjkim DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL, 153208625Sjkim "Could not compile input file"); 154209734Sjkim 155208625Sjkim goto CleanupAndExit; 156208625Sjkim } 157208625Sjkim 158208625Sjkim /* Create/open the binary output file */ 159208625Sjkim 160208625Sjkim Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL; 161208625Sjkim Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix); 162208625Sjkim if (ACPI_FAILURE (Status)) 163208625Sjkim { 164208625Sjkim goto CleanupAndExit; 165208625Sjkim } 166208625Sjkim 167208625Sjkim /* Write the binary, then the optional hex file */ 168208625Sjkim 169208625Sjkim DtOutputBinary (Gbl_RootTable); 170245582Sjkim HxDoHexOutput (); 171217365Sjkim DtWriteTableToListing (); 172208625Sjkim 173208625SjkimCleanupAndExit: 174208625Sjkim 175281075Sdim AcpiUtDeleteCaches (); 176281075Sdim DtDeleteCaches (); 177208625Sjkim CmCleanupAndExit (); 178208625Sjkim return (Status); 179208625Sjkim} 180208625Sjkim 181208625Sjkim 182208625Sjkim/****************************************************************************** 183208625Sjkim * 184208625Sjkim * FUNCTION: DtInitialize 185208625Sjkim * 186208625Sjkim * PARAMETERS: None 187208625Sjkim * 188212761Sjkim * RETURN: Status 189208625Sjkim * 190208625Sjkim * DESCRIPTION: Initialize data table compiler globals. Enables multiple 191208625Sjkim * compiles per invocation. 192208625Sjkim * 193208625Sjkim *****************************************************************************/ 194208625Sjkim 195212761Sjkimstatic ACPI_STATUS 196208625SjkimDtInitialize ( 197208625Sjkim void) 198208625Sjkim{ 199212761Sjkim ACPI_STATUS Status; 200208625Sjkim 201209734Sjkim 202212761Sjkim Status = AcpiOsInitialize (); 203212761Sjkim if (ACPI_FAILURE (Status)) 204212761Sjkim { 205212761Sjkim return (Status); 206212761Sjkim } 207212761Sjkim 208212761Sjkim Status = AcpiUtInitGlobals (); 209212761Sjkim if (ACPI_FAILURE (Status)) 210212761Sjkim { 211212761Sjkim return (Status); 212212761Sjkim } 213212761Sjkim 214208625Sjkim Gbl_FieldList = NULL; 215208625Sjkim Gbl_RootTable = NULL; 216208625Sjkim Gbl_SubtableStack = NULL; 217208625Sjkim 218208625Sjkim sprintf (VersionString, "%X", (UINT32) ACPI_CA_VERSION); 219212761Sjkim return (AE_OK); 220208625Sjkim} 221208625Sjkim 222208625Sjkim 223208625Sjkim/****************************************************************************** 224208625Sjkim * 225208625Sjkim * FUNCTION: DtInsertCompilerIds 226208625Sjkim * 227208625Sjkim * PARAMETERS: FieldList - Current field list pointer 228208625Sjkim * 229208625Sjkim * RETURN: None 230208625Sjkim * 231208625Sjkim * DESCRIPTION: Insert the IDs (Name, Version) of the current compiler into 232208625Sjkim * the original ACPI table header. 233208625Sjkim * 234208625Sjkim *****************************************************************************/ 235208625Sjkim 236208625Sjkimstatic void 237208625SjkimDtInsertCompilerIds ( 238208625Sjkim DT_FIELD *FieldList) 239208625Sjkim{ 240208625Sjkim DT_FIELD *Next; 241208625Sjkim UINT32 i; 242208625Sjkim 243208625Sjkim 244208625Sjkim /* 245208625Sjkim * Don't insert current compiler ID if requested. Used for compiler 246208625Sjkim * debug/validation only. 247208625Sjkim */ 248208625Sjkim if (Gbl_UseOriginalCompilerId) 249208625Sjkim { 250208625Sjkim return; 251208625Sjkim } 252208625Sjkim 253208625Sjkim /* Walk to the Compiler fields at the end of the header */ 254208625Sjkim 255208625Sjkim Next = FieldList; 256208625Sjkim for (i = 0; i < 7; i++) 257208625Sjkim { 258208625Sjkim Next = Next->Next; 259208625Sjkim } 260208625Sjkim 261213806Sjkim Next->Value = ASL_CREATOR_ID; 262208625Sjkim Next->Flags = DT_FIELD_NOT_ALLOCATED; 263208625Sjkim 264208625Sjkim Next = Next->Next; 265208625Sjkim Next->Value = VersionString; 266208625Sjkim Next->Flags = DT_FIELD_NOT_ALLOCATED; 267208625Sjkim} 268208625Sjkim 269208625Sjkim 270208625Sjkim/****************************************************************************** 271208625Sjkim * 272208625Sjkim * FUNCTION: DtCompileDataTable 273208625Sjkim * 274208625Sjkim * PARAMETERS: FieldList - Current field list pointer 275208625Sjkim * 276208625Sjkim * RETURN: Status 277208625Sjkim * 278208625Sjkim * DESCRIPTION: Entry point to compile one data table 279208625Sjkim * 280208625Sjkim *****************************************************************************/ 281208625Sjkim 282208625Sjkimstatic ACPI_STATUS 283208625SjkimDtCompileDataTable ( 284208625Sjkim DT_FIELD **FieldList) 285208625Sjkim{ 286284460Sjkim const ACPI_DMTABLE_DATA *TableData; 287208625Sjkim DT_SUBTABLE *Subtable; 288208625Sjkim char *Signature; 289208625Sjkim ACPI_TABLE_HEADER *AcpiTableHeader; 290208625Sjkim ACPI_STATUS Status; 291245582Sjkim DT_FIELD *RootField = *FieldList; 292208625Sjkim 293208625Sjkim 294208625Sjkim /* Verify that we at least have a table signature and save it */ 295208625Sjkim 296220663Sjkim Signature = DtGetFieldValue (*FieldList); 297208625Sjkim if (!Signature) 298208625Sjkim { 299209734Sjkim sprintf (MsgBuffer, "Expected \"%s\"", "Signature"); 300209734Sjkim DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 301209734Sjkim *FieldList, MsgBuffer); 302208625Sjkim return (AE_ERROR); 303208625Sjkim } 304208625Sjkim 305306536Sjkim Gbl_Signature = UtStringCacheCalloc (strlen (Signature) + 1); 306208625Sjkim strcpy (Gbl_Signature, Signature); 307208625Sjkim 308208625Sjkim /* 309208625Sjkim * Handle tables that don't use the common ACPI table header structure. 310208625Sjkim * Currently, these are the FACS and RSDP. Also check for an OEMx table, 311208625Sjkim * these tables have user-defined contents. 312208625Sjkim */ 313208625Sjkim if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) 314208625Sjkim { 315208625Sjkim Status = DtCompileFacs (FieldList); 316208625Sjkim if (ACPI_FAILURE (Status)) 317208625Sjkim { 318208625Sjkim return (Status); 319208625Sjkim } 320208625Sjkim 321208625Sjkim DtSetTableLength (); 322208625Sjkim return (Status); 323208625Sjkim } 324254745Sjkim else if (ACPI_VALIDATE_RSDP_SIG (Signature)) 325208625Sjkim { 326208625Sjkim Status = DtCompileRsdp (FieldList); 327208625Sjkim return (Status); 328208625Sjkim } 329228110Sjkim else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_S3PT)) 330228110Sjkim { 331228110Sjkim Status = DtCompileS3pt (FieldList); 332228110Sjkim if (ACPI_FAILURE (Status)) 333228110Sjkim { 334228110Sjkim return (Status); 335228110Sjkim } 336208625Sjkim 337228110Sjkim DtSetTableLength (); 338228110Sjkim return (Status); 339228110Sjkim } 340228110Sjkim 341208625Sjkim /* 342208625Sjkim * All other tables must use the common ACPI table header. Insert the 343208625Sjkim * current iASL IDs (name, version), and compile the header now. 344208625Sjkim */ 345208625Sjkim DtInsertCompilerIds (*FieldList); 346208625Sjkim 347208625Sjkim Status = DtCompileTable (FieldList, AcpiDmTableInfoHeader, 348306536Sjkim &Gbl_RootTable, TRUE); 349208625Sjkim if (ACPI_FAILURE (Status)) 350208625Sjkim { 351208625Sjkim return (Status); 352208625Sjkim } 353208625Sjkim 354208625Sjkim DtPushSubtable (Gbl_RootTable); 355208625Sjkim 356220663Sjkim /* Validate the signature via the ACPI table list */ 357220663Sjkim 358220663Sjkim TableData = AcpiDmGetTableData (Signature); 359228110Sjkim if (!TableData || Gbl_CompileGeneric) 360220663Sjkim { 361306536Sjkim /* Unknown table signature and/or force generic compile */ 362306536Sjkim 363284460Sjkim DtCompileGeneric ((void **) FieldList, NULL, NULL); 364245582Sjkim goto FinishHeader; 365220663Sjkim } 366220663Sjkim 367209734Sjkim /* Dispatch to per-table compile */ 368208625Sjkim 369208625Sjkim if (TableData->CmTableHandler) 370208625Sjkim { 371208625Sjkim /* Complex table, has a handler */ 372208625Sjkim 373208625Sjkim Status = TableData->CmTableHandler ((void **) FieldList); 374208625Sjkim if (ACPI_FAILURE (Status)) 375208625Sjkim { 376208625Sjkim return (Status); 377208625Sjkim } 378208625Sjkim } 379208625Sjkim else if (TableData->TableInfo) 380208625Sjkim { 381208625Sjkim /* Simple table, just walk the info table */ 382208625Sjkim 383208625Sjkim Subtable = NULL; 384208625Sjkim Status = DtCompileTable (FieldList, TableData->TableInfo, 385306536Sjkim &Subtable, TRUE); 386208625Sjkim if (ACPI_FAILURE (Status)) 387208625Sjkim { 388208625Sjkim return (Status); 389208625Sjkim } 390208625Sjkim 391208625Sjkim DtInsertSubtable (Gbl_RootTable, Subtable); 392208625Sjkim DtPopSubtable (); 393208625Sjkim } 394208625Sjkim else 395208625Sjkim { 396208625Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList, 397208625Sjkim "Missing table dispatch info"); 398208625Sjkim return (AE_ERROR); 399208625Sjkim } 400208625Sjkim 401245582SjkimFinishHeader: 402245582Sjkim 403208625Sjkim /* Set the final table length and then the checksum */ 404208625Sjkim 405208625Sjkim DtSetTableLength (); 406208625Sjkim AcpiTableHeader = ACPI_CAST_PTR ( 407208625Sjkim ACPI_TABLE_HEADER, Gbl_RootTable->Buffer); 408208625Sjkim DtSetTableChecksum (&AcpiTableHeader->Checksum); 409208625Sjkim 410245582Sjkim DtDumpFieldList (RootField); 411245582Sjkim DtDumpSubtableList (); 412208625Sjkim return (AE_OK); 413208625Sjkim} 414208625Sjkim 415208625Sjkim 416208625Sjkim/****************************************************************************** 417208625Sjkim * 418208625Sjkim * FUNCTION: DtCompileTable 419208625Sjkim * 420208625Sjkim * PARAMETERS: Field - Current field list pointer 421208625Sjkim * Info - Info table for this ACPI table 422208625Sjkim * RetSubtable - Compile result of table 423208625Sjkim * Required - If this subtable must exist 424208625Sjkim * 425208625Sjkim * RETURN: Status 426208625Sjkim * 427208625Sjkim * DESCRIPTION: Compile a subtable 428208625Sjkim * 429208625Sjkim *****************************************************************************/ 430208625Sjkim 431208625SjkimACPI_STATUS 432208625SjkimDtCompileTable ( 433208625Sjkim DT_FIELD **Field, 434208625Sjkim ACPI_DMTABLE_INFO *Info, 435208625Sjkim DT_SUBTABLE **RetSubtable, 436208625Sjkim BOOLEAN Required) 437208625Sjkim{ 438208625Sjkim DT_FIELD *LocalField; 439208625Sjkim UINT32 Length; 440208625Sjkim DT_SUBTABLE *Subtable; 441284460Sjkim DT_SUBTABLE *InlineSubtable = NULL; 442208625Sjkim UINT32 FieldLength = 0; 443208625Sjkim UINT8 FieldType; 444208625Sjkim UINT8 *Buffer; 445208625Sjkim UINT8 *FlagBuffer = NULL; 446281075Sdim char *String; 447228110Sjkim UINT32 CurrentFlagByteOffset = 0; 448284460Sjkim ACPI_STATUS Status = AE_OK; 449208625Sjkim 450208625Sjkim 451208625Sjkim if (!Field || !*Field) 452208625Sjkim { 453208625Sjkim return (AE_BAD_PARAMETER); 454208625Sjkim } 455208625Sjkim 456281075Sdim /* Ignore optional subtable if name does not match */ 457281075Sdim 458281075Sdim if ((Info->Flags & DT_OPTIONAL) && 459306536Sjkim strcmp ((*Field)->Name, Info->Name)) 460281075Sdim { 461281075Sdim *RetSubtable = NULL; 462281075Sdim return (AE_OK); 463281075Sdim } 464281075Sdim 465208625Sjkim Length = DtGetSubtableLength (*Field, Info); 466220663Sjkim if (Length == ASL_EOF) 467220663Sjkim { 468220663Sjkim return (AE_ERROR); 469220663Sjkim } 470220663Sjkim 471281075Sdim Subtable = UtSubtableCacheCalloc (); 472208625Sjkim 473218590Sjkim if (Length > 0) 474218590Sjkim { 475281075Sdim String = UtStringCacheCalloc (Length); 476281075Sdim Subtable->Buffer = ACPI_CAST_PTR (UINT8, String); 477218590Sjkim } 478281075Sdim 479208625Sjkim Subtable->Length = Length; 480208625Sjkim Subtable->TotalLength = Length; 481208625Sjkim Buffer = Subtable->Buffer; 482208625Sjkim 483208625Sjkim LocalField = *Field; 484284460Sjkim Subtable->Name = LocalField->Name; 485208625Sjkim 486208625Sjkim /* 487208625Sjkim * Main loop walks the info table for this ACPI table or subtable 488208625Sjkim */ 489208625Sjkim for (; Info->Name; Info++) 490208625Sjkim { 491228110Sjkim if (Info->Opcode == ACPI_DMT_EXTRA_TEXT) 492228110Sjkim { 493228110Sjkim continue; 494228110Sjkim } 495228110Sjkim 496208625Sjkim if (!LocalField) 497208625Sjkim { 498208625Sjkim sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed", 499208625Sjkim Info->Name); 500208625Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 501208625Sjkim Status = AE_BAD_DATA; 502208625Sjkim goto Error; 503208625Sjkim } 504208625Sjkim 505218590Sjkim /* Maintain table offsets */ 506218590Sjkim 507218590Sjkim LocalField->TableOffset = Gbl_CurrentTableOffset; 508208625Sjkim FieldLength = DtGetFieldLength (LocalField, Info); 509218590Sjkim Gbl_CurrentTableOffset += FieldLength; 510218590Sjkim 511208625Sjkim FieldType = DtGetFieldType (Info); 512208625Sjkim Gbl_InputFieldCount++; 513208625Sjkim 514208625Sjkim switch (FieldType) 515208625Sjkim { 516208625Sjkim case DT_FIELD_TYPE_FLAGS_INTEGER: 517208625Sjkim /* 518208625Sjkim * Start of the definition of a flags field. 519208625Sjkim * This master flags integer starts at value zero, in preparation 520208625Sjkim * to compile and insert the flag fields from the individual bits 521208625Sjkim */ 522208625Sjkim LocalField = LocalField->Next; 523208625Sjkim *Field = LocalField; 524208625Sjkim 525208625Sjkim FlagBuffer = Buffer; 526228110Sjkim CurrentFlagByteOffset = Info->Offset; 527208625Sjkim break; 528208625Sjkim 529208625Sjkim case DT_FIELD_TYPE_FLAG: 530208625Sjkim 531208625Sjkim /* Individual Flag field, can be multiple bits */ 532208625Sjkim 533208625Sjkim if (FlagBuffer) 534208625Sjkim { 535228110Sjkim /* 536228110Sjkim * We must increment the FlagBuffer when we have crossed 537228110Sjkim * into the next flags byte within the flags field 538228110Sjkim * of type DT_FIELD_TYPE_FLAGS_INTEGER. 539228110Sjkim */ 540228110Sjkim FlagBuffer += (Info->Offset - CurrentFlagByteOffset); 541228110Sjkim CurrentFlagByteOffset = Info->Offset; 542228110Sjkim 543209734Sjkim DtCompileFlag (FlagBuffer, LocalField, Info); 544208625Sjkim } 545208625Sjkim else 546208625Sjkim { 547208625Sjkim /* TBD - this is an internal error */ 548208625Sjkim } 549208625Sjkim 550208625Sjkim LocalField = LocalField->Next; 551208625Sjkim *Field = LocalField; 552208625Sjkim break; 553208625Sjkim 554208625Sjkim case DT_FIELD_TYPE_INLINE_SUBTABLE: 555208625Sjkim /* 556208625Sjkim * Recursion (one level max): compile GAS (Generic Address) 557208625Sjkim * or Notify in-line subtable 558208625Sjkim */ 559208625Sjkim *Field = LocalField; 560208625Sjkim 561284460Sjkim switch (Info->Opcode) 562208625Sjkim { 563284460Sjkim case ACPI_DMT_GAS: 564284460Sjkim 565208625Sjkim Status = DtCompileTable (Field, AcpiDmTableInfoGas, 566208625Sjkim &InlineSubtable, TRUE); 567284460Sjkim break; 568284460Sjkim 569284460Sjkim case ACPI_DMT_HESTNTFY: 570284460Sjkim 571208625Sjkim Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify, 572208625Sjkim &InlineSubtable, TRUE); 573284460Sjkim break; 574284460Sjkim 575284460Sjkim case ACPI_DMT_IORTMEM: 576284460Sjkim 577284460Sjkim Status = DtCompileTable (Field, AcpiDmTableInfoIortAcc, 578284460Sjkim &InlineSubtable, TRUE); 579284460Sjkim break; 580284460Sjkim 581284460Sjkim default: 582284460Sjkim sprintf (MsgBuffer, "Invalid DMT opcode: 0x%.2X", 583284460Sjkim Info->Opcode); 584284460Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 585284460Sjkim Status = AE_BAD_DATA; 586284460Sjkim break; 587208625Sjkim } 588208625Sjkim 589208625Sjkim if (ACPI_FAILURE (Status)) 590208625Sjkim { 591208625Sjkim goto Error; 592208625Sjkim } 593208625Sjkim 594209734Sjkim DtSetSubtableLength (InlineSubtable); 595209734Sjkim 596306536Sjkim memcpy (Buffer, InlineSubtable->Buffer, FieldLength); 597208625Sjkim LocalField = *Field; 598208625Sjkim break; 599208625Sjkim 600218590Sjkim case DT_FIELD_TYPE_LABEL: 601218590Sjkim 602218590Sjkim DtWriteFieldToListing (Buffer, LocalField, 0); 603218590Sjkim LocalField = LocalField->Next; 604218590Sjkim break; 605218590Sjkim 606208625Sjkim default: 607208625Sjkim 608208625Sjkim /* Normal case for most field types (Integer, String, etc.) */ 609208625Sjkim 610208625Sjkim DtCompileOneField (Buffer, LocalField, 611208625Sjkim FieldLength, FieldType, Info->Flags); 612217365Sjkim 613217365Sjkim DtWriteFieldToListing (Buffer, LocalField, FieldLength); 614208625Sjkim LocalField = LocalField->Next; 615208625Sjkim 616208625Sjkim if (Info->Flags & DT_LENGTH) 617208625Sjkim { 618208625Sjkim /* Field is an Integer that will contain a subtable length */ 619208625Sjkim 620208625Sjkim Subtable->LengthField = Buffer; 621208625Sjkim Subtable->SizeOfLengthField = FieldLength; 622208625Sjkim } 623208625Sjkim break; 624208625Sjkim } 625208625Sjkim 626208625Sjkim Buffer += FieldLength; 627208625Sjkim } 628208625Sjkim 629208625Sjkim *Field = LocalField; 630208625Sjkim *RetSubtable = Subtable; 631208625Sjkim return (AE_OK); 632208625Sjkim 633208625SjkimError: 634208625Sjkim ACPI_FREE (Subtable->Buffer); 635208625Sjkim ACPI_FREE (Subtable); 636208625Sjkim return (Status); 637208625Sjkim} 638284460Sjkim 639284460Sjkim 640284460Sjkim/****************************************************************************** 641284460Sjkim * 642306536Sjkim * FUNCTION: DtCompileTwoSubtables 643306536Sjkim * 644306536Sjkim * PARAMETERS: List - Current field list pointer 645306536Sjkim * TableInfo1 - Info table 1 646306536Sjkim * TableInfo1 - Info table 2 647306536Sjkim * 648306536Sjkim * RETURN: Status 649306536Sjkim * 650306536Sjkim * DESCRIPTION: Compile tables with a header and one or more same subtables. 651306536Sjkim * Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT 652306536Sjkim * 653306536Sjkim *****************************************************************************/ 654306536Sjkim 655306536SjkimACPI_STATUS 656306536SjkimDtCompileTwoSubtables ( 657306536Sjkim void **List, 658306536Sjkim ACPI_DMTABLE_INFO *TableInfo1, 659306536Sjkim ACPI_DMTABLE_INFO *TableInfo2) 660306536Sjkim{ 661306536Sjkim ACPI_STATUS Status; 662306536Sjkim DT_SUBTABLE *Subtable; 663306536Sjkim DT_SUBTABLE *ParentTable; 664306536Sjkim DT_FIELD **PFieldList = (DT_FIELD **) List; 665306536Sjkim 666306536Sjkim 667306536Sjkim Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE); 668306536Sjkim if (ACPI_FAILURE (Status)) 669306536Sjkim { 670306536Sjkim return (Status); 671306536Sjkim } 672306536Sjkim 673306536Sjkim ParentTable = DtPeekSubtable (); 674306536Sjkim DtInsertSubtable (ParentTable, Subtable); 675306536Sjkim 676306536Sjkim while (*PFieldList) 677306536Sjkim { 678306536Sjkim Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE); 679306536Sjkim if (ACPI_FAILURE (Status)) 680306536Sjkim { 681306536Sjkim return (Status); 682306536Sjkim } 683306536Sjkim 684306536Sjkim DtInsertSubtable (ParentTable, Subtable); 685306536Sjkim } 686306536Sjkim 687306536Sjkim return (AE_OK); 688306536Sjkim} 689306536Sjkim 690306536Sjkim 691306536Sjkim/****************************************************************************** 692306536Sjkim * 693284460Sjkim * FUNCTION: DtCompilePadding 694284460Sjkim * 695284460Sjkim * PARAMETERS: Length - Padding field size 696284460Sjkim * RetSubtable - Compile result of table 697284460Sjkim * 698284460Sjkim * RETURN: Status 699284460Sjkim * 700284460Sjkim * DESCRIPTION: Compile a subtable for padding purpose 701284460Sjkim * 702284460Sjkim *****************************************************************************/ 703284460Sjkim 704284460SjkimACPI_STATUS 705284460SjkimDtCompilePadding ( 706284460Sjkim UINT32 Length, 707284460Sjkim DT_SUBTABLE **RetSubtable) 708284460Sjkim{ 709284460Sjkim DT_SUBTABLE *Subtable; 710284460Sjkim /* UINT8 *Buffer; */ 711284460Sjkim char *String; 712284460Sjkim 713284460Sjkim 714284460Sjkim Subtable = UtSubtableCacheCalloc (); 715284460Sjkim 716284460Sjkim if (Length > 0) 717284460Sjkim { 718284460Sjkim String = UtStringCacheCalloc (Length); 719284460Sjkim Subtable->Buffer = ACPI_CAST_PTR (UINT8, String); 720284460Sjkim } 721284460Sjkim 722284460Sjkim Subtable->Length = Length; 723284460Sjkim Subtable->TotalLength = Length; 724284460Sjkim /* Buffer = Subtable->Buffer; */ 725284460Sjkim 726284460Sjkim *RetSubtable = Subtable; 727284460Sjkim return (AE_OK); 728284460Sjkim} 729