dtcompile.c revision 281396
1208625Sjkim/****************************************************************************** 2208625Sjkim * 3208625Sjkim * Module Name: dtcompile.c - Front-end for data table compiler 4208625Sjkim * 5208625Sjkim *****************************************************************************/ 6208625Sjkim 7217365Sjkim/* 8278970Sjkim * Copyright (C) 2000 - 2015, 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 105281396Sjkim if (Gbl_PreprocessFlag) 106281396Sjkim { 107281396Sjkim /* Preprocessor */ 108233250Sjkim 109281396Sjkim Event = UtBeginEvent ("Preprocess input file"); 110281396Sjkim PrDoPreprocess (); 111281396Sjkim UtEndEvent (Event); 112281396Sjkim 113281396Sjkim if (Gbl_PreprocessOnly) 114281396Sjkim { 115281396Sjkim return (AE_OK); 116281396Sjkim } 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 175272444Sjkim AcpiUtDeleteCaches (); 176272444Sjkim 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{ 286208625Sjkim 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 305272444Sjkim Gbl_Signature = UtStringCacheCalloc (ACPI_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, 348208625Sjkim &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 { 361220663Sjkim DtCompileGeneric ((void **) FieldList); 362245582Sjkim goto FinishHeader; 363220663Sjkim } 364220663Sjkim 365209734Sjkim /* Dispatch to per-table compile */ 366208625Sjkim 367208625Sjkim if (TableData->CmTableHandler) 368208625Sjkim { 369208625Sjkim /* Complex table, has a handler */ 370208625Sjkim 371208625Sjkim Status = TableData->CmTableHandler ((void **) FieldList); 372208625Sjkim if (ACPI_FAILURE (Status)) 373208625Sjkim { 374208625Sjkim return (Status); 375208625Sjkim } 376208625Sjkim } 377208625Sjkim else if (TableData->TableInfo) 378208625Sjkim { 379208625Sjkim /* Simple table, just walk the info table */ 380208625Sjkim 381208625Sjkim Subtable = NULL; 382208625Sjkim Status = DtCompileTable (FieldList, TableData->TableInfo, 383208625Sjkim &Subtable, TRUE); 384208625Sjkim if (ACPI_FAILURE (Status)) 385208625Sjkim { 386208625Sjkim return (Status); 387208625Sjkim } 388208625Sjkim 389208625Sjkim DtInsertSubtable (Gbl_RootTable, Subtable); 390208625Sjkim DtPopSubtable (); 391208625Sjkim } 392208625Sjkim else 393208625Sjkim { 394208625Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList, 395208625Sjkim "Missing table dispatch info"); 396208625Sjkim return (AE_ERROR); 397208625Sjkim } 398208625Sjkim 399245582SjkimFinishHeader: 400245582Sjkim 401208625Sjkim /* Set the final table length and then the checksum */ 402208625Sjkim 403208625Sjkim DtSetTableLength (); 404208625Sjkim AcpiTableHeader = ACPI_CAST_PTR ( 405208625Sjkim ACPI_TABLE_HEADER, Gbl_RootTable->Buffer); 406208625Sjkim DtSetTableChecksum (&AcpiTableHeader->Checksum); 407208625Sjkim 408245582Sjkim DtDumpFieldList (RootField); 409245582Sjkim DtDumpSubtableList (); 410208625Sjkim return (AE_OK); 411208625Sjkim} 412208625Sjkim 413208625Sjkim 414208625Sjkim/****************************************************************************** 415208625Sjkim * 416208625Sjkim * FUNCTION: DtCompileTable 417208625Sjkim * 418208625Sjkim * PARAMETERS: Field - Current field list pointer 419208625Sjkim * Info - Info table for this ACPI table 420208625Sjkim * RetSubtable - Compile result of table 421208625Sjkim * Required - If this subtable must exist 422208625Sjkim * 423208625Sjkim * RETURN: Status 424208625Sjkim * 425208625Sjkim * DESCRIPTION: Compile a subtable 426208625Sjkim * 427208625Sjkim *****************************************************************************/ 428208625Sjkim 429208625SjkimACPI_STATUS 430208625SjkimDtCompileTable ( 431208625Sjkim DT_FIELD **Field, 432208625Sjkim ACPI_DMTABLE_INFO *Info, 433208625Sjkim DT_SUBTABLE **RetSubtable, 434208625Sjkim BOOLEAN Required) 435208625Sjkim{ 436208625Sjkim DT_FIELD *LocalField; 437208625Sjkim UINT32 Length; 438208625Sjkim DT_SUBTABLE *Subtable; 439208625Sjkim DT_SUBTABLE *InlineSubtable; 440208625Sjkim UINT32 FieldLength = 0; 441208625Sjkim UINT8 FieldType; 442208625Sjkim UINT8 *Buffer; 443208625Sjkim UINT8 *FlagBuffer = NULL; 444272444Sjkim char *String; 445228110Sjkim UINT32 CurrentFlagByteOffset = 0; 446208625Sjkim ACPI_STATUS Status; 447208625Sjkim 448208625Sjkim 449208625Sjkim if (!Field || !*Field) 450208625Sjkim { 451208625Sjkim return (AE_BAD_PARAMETER); 452208625Sjkim } 453208625Sjkim 454272444Sjkim /* Ignore optional subtable if name does not match */ 455272444Sjkim 456272444Sjkim if ((Info->Flags & DT_OPTIONAL) && 457272444Sjkim ACPI_STRCMP ((*Field)->Name, Info->Name)) 458272444Sjkim { 459272444Sjkim *RetSubtable = NULL; 460272444Sjkim return (AE_OK); 461272444Sjkim } 462272444Sjkim 463208625Sjkim Length = DtGetSubtableLength (*Field, Info); 464220663Sjkim if (Length == ASL_EOF) 465220663Sjkim { 466220663Sjkim return (AE_ERROR); 467220663Sjkim } 468220663Sjkim 469272444Sjkim Subtable = UtSubtableCacheCalloc (); 470208625Sjkim 471218590Sjkim if (Length > 0) 472218590Sjkim { 473272444Sjkim String = UtStringCacheCalloc (Length); 474272444Sjkim Subtable->Buffer = ACPI_CAST_PTR (UINT8, String); 475218590Sjkim } 476272444Sjkim 477208625Sjkim Subtable->Length = Length; 478208625Sjkim Subtable->TotalLength = Length; 479208625Sjkim Buffer = Subtable->Buffer; 480208625Sjkim 481208625Sjkim LocalField = *Field; 482208625Sjkim 483208625Sjkim /* 484208625Sjkim * Main loop walks the info table for this ACPI table or subtable 485208625Sjkim */ 486208625Sjkim for (; Info->Name; Info++) 487208625Sjkim { 488228110Sjkim if (Info->Opcode == ACPI_DMT_EXTRA_TEXT) 489228110Sjkim { 490228110Sjkim continue; 491228110Sjkim } 492228110Sjkim 493208625Sjkim if (!LocalField) 494208625Sjkim { 495208625Sjkim sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed", 496208625Sjkim Info->Name); 497208625Sjkim DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 498208625Sjkim Status = AE_BAD_DATA; 499208625Sjkim goto Error; 500208625Sjkim } 501208625Sjkim 502218590Sjkim /* Maintain table offsets */ 503218590Sjkim 504218590Sjkim LocalField->TableOffset = Gbl_CurrentTableOffset; 505208625Sjkim FieldLength = DtGetFieldLength (LocalField, Info); 506218590Sjkim Gbl_CurrentTableOffset += FieldLength; 507218590Sjkim 508208625Sjkim FieldType = DtGetFieldType (Info); 509208625Sjkim Gbl_InputFieldCount++; 510208625Sjkim 511208625Sjkim switch (FieldType) 512208625Sjkim { 513208625Sjkim case DT_FIELD_TYPE_FLAGS_INTEGER: 514208625Sjkim /* 515208625Sjkim * Start of the definition of a flags field. 516208625Sjkim * This master flags integer starts at value zero, in preparation 517208625Sjkim * to compile and insert the flag fields from the individual bits 518208625Sjkim */ 519208625Sjkim LocalField = LocalField->Next; 520208625Sjkim *Field = LocalField; 521208625Sjkim 522208625Sjkim FlagBuffer = Buffer; 523228110Sjkim CurrentFlagByteOffset = Info->Offset; 524208625Sjkim break; 525208625Sjkim 526208625Sjkim case DT_FIELD_TYPE_FLAG: 527208625Sjkim 528208625Sjkim /* Individual Flag field, can be multiple bits */ 529208625Sjkim 530208625Sjkim if (FlagBuffer) 531208625Sjkim { 532228110Sjkim /* 533228110Sjkim * We must increment the FlagBuffer when we have crossed 534228110Sjkim * into the next flags byte within the flags field 535228110Sjkim * of type DT_FIELD_TYPE_FLAGS_INTEGER. 536228110Sjkim */ 537228110Sjkim FlagBuffer += (Info->Offset - CurrentFlagByteOffset); 538228110Sjkim CurrentFlagByteOffset = Info->Offset; 539228110Sjkim 540209734Sjkim DtCompileFlag (FlagBuffer, LocalField, Info); 541208625Sjkim } 542208625Sjkim else 543208625Sjkim { 544208625Sjkim /* TBD - this is an internal error */ 545208625Sjkim } 546208625Sjkim 547208625Sjkim LocalField = LocalField->Next; 548208625Sjkim *Field = LocalField; 549208625Sjkim break; 550208625Sjkim 551208625Sjkim case DT_FIELD_TYPE_INLINE_SUBTABLE: 552208625Sjkim /* 553208625Sjkim * Recursion (one level max): compile GAS (Generic Address) 554208625Sjkim * or Notify in-line subtable 555208625Sjkim */ 556208625Sjkim *Field = LocalField; 557208625Sjkim 558208625Sjkim if (Info->Opcode == ACPI_DMT_GAS) 559208625Sjkim { 560208625Sjkim Status = DtCompileTable (Field, AcpiDmTableInfoGas, 561208625Sjkim &InlineSubtable, TRUE); 562208625Sjkim } 563208625Sjkim else 564208625Sjkim { 565208625Sjkim Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify, 566208625Sjkim &InlineSubtable, TRUE); 567208625Sjkim } 568208625Sjkim 569208625Sjkim if (ACPI_FAILURE (Status)) 570208625Sjkim { 571208625Sjkim goto Error; 572208625Sjkim } 573208625Sjkim 574209734Sjkim DtSetSubtableLength (InlineSubtable); 575209734Sjkim 576208625Sjkim ACPI_MEMCPY (Buffer, InlineSubtable->Buffer, FieldLength); 577208625Sjkim LocalField = *Field; 578208625Sjkim break; 579208625Sjkim 580218590Sjkim case DT_FIELD_TYPE_LABEL: 581218590Sjkim 582218590Sjkim DtWriteFieldToListing (Buffer, LocalField, 0); 583218590Sjkim LocalField = LocalField->Next; 584218590Sjkim break; 585218590Sjkim 586208625Sjkim default: 587208625Sjkim 588208625Sjkim /* Normal case for most field types (Integer, String, etc.) */ 589208625Sjkim 590208625Sjkim DtCompileOneField (Buffer, LocalField, 591208625Sjkim FieldLength, FieldType, Info->Flags); 592217365Sjkim 593217365Sjkim DtWriteFieldToListing (Buffer, LocalField, FieldLength); 594208625Sjkim LocalField = LocalField->Next; 595208625Sjkim 596208625Sjkim if (Info->Flags & DT_LENGTH) 597208625Sjkim { 598208625Sjkim /* Field is an Integer that will contain a subtable length */ 599208625Sjkim 600208625Sjkim Subtable->LengthField = Buffer; 601208625Sjkim Subtable->SizeOfLengthField = FieldLength; 602208625Sjkim } 603217365Sjkim 604208625Sjkim break; 605208625Sjkim } 606208625Sjkim 607208625Sjkim Buffer += FieldLength; 608208625Sjkim } 609208625Sjkim 610208625Sjkim *Field = LocalField; 611208625Sjkim *RetSubtable = Subtable; 612208625Sjkim return (AE_OK); 613208625Sjkim 614208625SjkimError: 615208625Sjkim ACPI_FREE (Subtable->Buffer); 616208625Sjkim ACPI_FREE (Subtable); 617208625Sjkim return (Status); 618208625Sjkim} 619