dtcompile.c revision 209746
1208625Sjkim/******************************************************************************
2208625Sjkim *
3208625Sjkim * Module Name: dtcompile.c - Front-end for data table compiler
4208625Sjkim *
5208625Sjkim *****************************************************************************/
6208625Sjkim
7208625Sjkim/******************************************************************************
8208625Sjkim *
9208625Sjkim * 1. Copyright Notice
10208625Sjkim *
11208625Sjkim * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
12208625Sjkim * All rights reserved.
13208625Sjkim *
14208625Sjkim * 2. License
15208625Sjkim *
16208625Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property
17208625Sjkim * rights.  You may have additional license terms from the party that provided
18208625Sjkim * you this software, covering your right to use that party's intellectual
19208625Sjkim * property rights.
20208625Sjkim *
21208625Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22208625Sjkim * copy of the source code appearing in this file ("Covered Code") an
23208625Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24208625Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy,
25208625Sjkim * make derivatives, distribute, use and display any portion of the Covered
26208625Sjkim * Code in any form, with the right to sublicense such rights; and
27208625Sjkim *
28208625Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29208625Sjkim * license (with the right to sublicense), under only those claims of Intel
30208625Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell,
31208625Sjkim * offer to sell, and import the Covered Code and derivative works thereof
32208625Sjkim * solely to the minimum extent necessary to exercise the above copyright
33208625Sjkim * license, and in no event shall the patent license extend to any additions
34208625Sjkim * to or modifications of the Original Intel Code.  No other license or right
35208625Sjkim * is granted directly or by implication, estoppel or otherwise;
36208625Sjkim *
37208625Sjkim * The above copyright and patent license is granted only if the following
38208625Sjkim * conditions are met:
39208625Sjkim *
40208625Sjkim * 3. Conditions
41208625Sjkim *
42208625Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43208625Sjkim * Redistribution of source code of any substantial portion of the Covered
44208625Sjkim * Code or modification with rights to further distribute source must include
45208625Sjkim * the above Copyright Notice, the above License, this list of Conditions,
46208625Sjkim * and the following Disclaimer and Export Compliance provision.  In addition,
47208625Sjkim * Licensee must cause all Covered Code to which Licensee contributes to
48208625Sjkim * contain a file documenting the changes Licensee made to create that Covered
49208625Sjkim * Code and the date of any change.  Licensee must include in that file the
50208625Sjkim * documentation of any changes made by any predecessor Licensee.  Licensee
51208625Sjkim * must include a prominent statement that the modification is derived,
52208625Sjkim * directly or indirectly, from Original Intel Code.
53208625Sjkim *
54208625Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55208625Sjkim * Redistribution of source code of any substantial portion of the Covered
56208625Sjkim * Code or modification without rights to further distribute source must
57208625Sjkim * include the following Disclaimer and Export Compliance provision in the
58208625Sjkim * documentation and/or other materials provided with distribution.  In
59208625Sjkim * addition, Licensee may not authorize further sublicense of source of any
60208625Sjkim * portion of the Covered Code, and must include terms to the effect that the
61208625Sjkim * license from Licensee to its licensee is limited to the intellectual
62208625Sjkim * property embodied in the software Licensee provides to its licensee, and
63208625Sjkim * not to intellectual property embodied in modifications its licensee may
64208625Sjkim * make.
65208625Sjkim *
66208625Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any
67208625Sjkim * substantial portion of the Covered Code or modification must reproduce the
68208625Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance
69208625Sjkim * provision in the documentation and/or other materials provided with the
70208625Sjkim * distribution.
71208625Sjkim *
72208625Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original
73208625Sjkim * Intel Code.
74208625Sjkim *
75208625Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76208625Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or
77208625Sjkim * other dealings in products derived from or relating to the Covered Code
78208625Sjkim * without prior written authorization from Intel.
79208625Sjkim *
80208625Sjkim * 4. Disclaimer and Export Compliance
81208625Sjkim *
82208625Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83208625Sjkim * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84208625Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85208625Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86208625Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87208625Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88208625Sjkim * PARTICULAR PURPOSE.
89208625Sjkim *
90208625Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91208625Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92208625Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93208625Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94208625Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95208625Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96208625Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97208625Sjkim * LIMITED REMEDY.
98208625Sjkim *
99208625Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this
100208625Sjkim * software or system incorporating such software without first obtaining any
101208625Sjkim * required license or other approval from the U. S. Department of Commerce or
102208625Sjkim * any other agency or department of the United States Government.  In the
103208625Sjkim * event Licensee exports any such software from the United States or
104208625Sjkim * re-exports any such software from a foreign destination, Licensee shall
105208625Sjkim * ensure that the distribution and export/re-export of the software is in
106208625Sjkim * compliance with all laws, regulations, orders, or other restrictions of the
107208625Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108208625Sjkim * any of its subsidiaries will export/re-export any technical data, process,
109208625Sjkim * software, or service, directly or indirectly, to any country for which the
110208625Sjkim * United States government or any agency thereof requires an export license,
111208625Sjkim * other governmental approval, or letter of assurance, without first obtaining
112208625Sjkim * such license, approval or letter.
113208625Sjkim *
114208625Sjkim *****************************************************************************/
115208625Sjkim
116208625Sjkim#define __DTCOMPILE_C__
117208625Sjkim#define _DECLARE_DT_GLOBALS
118208625Sjkim
119209746Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
120209746Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h>
121208625Sjkim
122208625Sjkim#define _COMPONENT          DT_COMPILER
123208625Sjkim        ACPI_MODULE_NAME    ("dtcompile")
124208625Sjkim
125208625Sjkimstatic char                 VersionString[9];
126208625Sjkim
127208625Sjkim
128208625Sjkim/* Local prototypes */
129208625Sjkim
130208625Sjkimstatic void
131208625SjkimDtInitialize (
132208625Sjkim    void);
133208625Sjkim
134208625Sjkimstatic ACPI_STATUS
135208625SjkimDtCompileDataTable (
136208625Sjkim    DT_FIELD                **Field);
137208625Sjkim
138208625Sjkimstatic void
139208625SjkimDtInsertCompilerIds (
140208625Sjkim    DT_FIELD                *FieldList);
141208625Sjkim
142208625Sjkim
143208625Sjkim/******************************************************************************
144208625Sjkim *
145208625Sjkim * FUNCTION:    DtDoCompile
146208625Sjkim *
147208625Sjkim * PARAMETERS:  None
148208625Sjkim *
149208625Sjkim * RETURN:      Status
150208625Sjkim *
151208625Sjkim * DESCRIPTION: Main entry point for the data table compiler.
152208625Sjkim *
153208625Sjkim * Note: Assumes Gbl_Files[ASL_FILE_INPUT] is initialized and the file is
154208625Sjkim *          open at seek offset zero.
155208625Sjkim *
156208625Sjkim *****************************************************************************/
157208625Sjkim
158208625SjkimACPI_STATUS
159208625SjkimDtDoCompile (
160208625Sjkim    void)
161208625Sjkim{
162208625Sjkim    ACPI_STATUS             Status;
163208625Sjkim    UINT8                   Event;
164208625Sjkim    DT_FIELD                *FieldList;
165208625Sjkim
166208625Sjkim
167208625Sjkim    /* Initialize globals */
168208625Sjkim
169208625Sjkim    DtInitialize ();
170208625Sjkim
171208625Sjkim    /*
172208625Sjkim     * Scan the input file (file is already open) and
173208625Sjkim     * build the parse tree
174208625Sjkim     */
175208625Sjkim    Event = UtBeginEvent ("Scan and parse input file");
176208625Sjkim    FieldList = DtScanFile (Gbl_Files[ASL_FILE_INPUT].Handle);
177208625Sjkim    UtEndEvent (Event);
178208625Sjkim
179208625Sjkim    /* Did the parse tree get successfully constructed? */
180208625Sjkim
181208625Sjkim    if (!FieldList)
182208625Sjkim    {
183208625Sjkim        /* TBD: temporary error message. Msgs should come from function above */
184208625Sjkim
185208625Sjkim        DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
186209734Sjkim            "Input file does not appear to be an ASL or data table source file");
187209734Sjkim
188209734Sjkim        Status = AE_ERROR;
189209734Sjkim        goto CleanupAndExit;
190208625Sjkim    }
191208625Sjkim
192208625Sjkim    Event = UtBeginEvent ("Compile parse tree");
193208625Sjkim
194208625Sjkim    /*
195208625Sjkim     * Compile the parse tree
196208625Sjkim     */
197208625Sjkim    Status = DtCompileDataTable (&FieldList);
198208625Sjkim    UtEndEvent (Event);
199208625Sjkim
200208625Sjkim    DtFreeFieldList ();
201208625Sjkim
202208625Sjkim    if (ACPI_FAILURE (Status))
203208625Sjkim    {
204208625Sjkim        /* TBD: temporary error message. Msgs should come from function above */
205208625Sjkim
206208625Sjkim        DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
207208625Sjkim            "Could not compile input file");
208209734Sjkim
209208625Sjkim        goto CleanupAndExit;
210208625Sjkim    }
211208625Sjkim
212208625Sjkim    /* Create/open the binary output file */
213208625Sjkim
214208625Sjkim    Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL;
215208625Sjkim    Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
216208625Sjkim    if (ACPI_FAILURE (Status))
217208625Sjkim    {
218208625Sjkim        goto CleanupAndExit;
219208625Sjkim    }
220208625Sjkim
221208625Sjkim    /* Write the binary, then the optional hex file */
222208625Sjkim
223208625Sjkim    DtOutputBinary (Gbl_RootTable);
224208625Sjkim    LsDoHexOutput ();
225208625Sjkim
226208625SjkimCleanupAndExit:
227208625Sjkim
228208625Sjkim    CmCleanupAndExit ();
229208625Sjkim    return (Status);
230208625Sjkim}
231208625Sjkim
232208625Sjkim
233208625Sjkim/******************************************************************************
234208625Sjkim *
235208625Sjkim * FUNCTION:    DtInitialize
236208625Sjkim *
237208625Sjkim * PARAMETERS:  None
238208625Sjkim *
239208625Sjkim * RETURN:      None
240208625Sjkim *
241208625Sjkim * DESCRIPTION: Initialize data table compiler globals. Enables multiple
242208625Sjkim *              compiles per invocation.
243208625Sjkim *
244208625Sjkim *****************************************************************************/
245208625Sjkim
246208625Sjkimstatic void
247208625SjkimDtInitialize (
248208625Sjkim    void)
249208625Sjkim{
250208625Sjkim
251209734Sjkim    AcpiOsInitialize ();
252209734Sjkim    AcpiUtInitGlobals ();
253209734Sjkim
254208625Sjkim    Gbl_FieldList = NULL;
255208625Sjkim    Gbl_RootTable = NULL;
256208625Sjkim    Gbl_SubtableStack = NULL;
257208625Sjkim
258208625Sjkim    sprintf (VersionString, "%X", (UINT32) ACPI_CA_VERSION);
259208625Sjkim}
260208625Sjkim
261208625Sjkim
262208625Sjkim/******************************************************************************
263208625Sjkim *
264208625Sjkim * FUNCTION:    DtInsertCompilerIds
265208625Sjkim *
266208625Sjkim * PARAMETERS:  FieldList           - Current field list pointer
267208625Sjkim *
268208625Sjkim * RETURN:      None
269208625Sjkim *
270208625Sjkim * DESCRIPTION: Insert the IDs (Name, Version) of the current compiler into
271208625Sjkim *              the original ACPI table header.
272208625Sjkim *
273208625Sjkim *****************************************************************************/
274208625Sjkim
275208625Sjkimstatic void
276208625SjkimDtInsertCompilerIds (
277208625Sjkim    DT_FIELD                *FieldList)
278208625Sjkim{
279208625Sjkim    DT_FIELD                *Next;
280208625Sjkim    UINT32                  i;
281208625Sjkim
282208625Sjkim
283208625Sjkim    /*
284208625Sjkim     * Don't insert current compiler ID if requested. Used for compiler
285208625Sjkim     * debug/validation only.
286208625Sjkim     */
287208625Sjkim    if (Gbl_UseOriginalCompilerId)
288208625Sjkim    {
289208625Sjkim        return;
290208625Sjkim    }
291208625Sjkim
292208625Sjkim    /* Walk to the Compiler fields at the end of the header */
293208625Sjkim
294208625Sjkim    Next = FieldList;
295208625Sjkim    for (i = 0; i < 7; i++)
296208625Sjkim    {
297208625Sjkim        Next = Next->Next;
298208625Sjkim    }
299208625Sjkim
300208625Sjkim    Next->Value = CompilerCreatorId;
301208625Sjkim    Next->Flags = DT_FIELD_NOT_ALLOCATED;
302208625Sjkim
303208625Sjkim    Next = Next->Next;
304208625Sjkim    Next->Value = VersionString;
305208625Sjkim    Next->Flags = DT_FIELD_NOT_ALLOCATED;
306208625Sjkim}
307208625Sjkim
308208625Sjkim
309208625Sjkim/******************************************************************************
310208625Sjkim *
311208625Sjkim * FUNCTION:    DtCompileDataTable
312208625Sjkim *
313208625Sjkim * PARAMETERS:  FieldList           - Current field list pointer
314208625Sjkim *
315208625Sjkim * RETURN:      Status
316208625Sjkim *
317208625Sjkim * DESCRIPTION: Entry point to compile one data table
318208625Sjkim *
319208625Sjkim *****************************************************************************/
320208625Sjkim
321208625Sjkimstatic ACPI_STATUS
322208625SjkimDtCompileDataTable (
323208625Sjkim    DT_FIELD                **FieldList)
324208625Sjkim{
325208625Sjkim    ACPI_DMTABLE_DATA       *TableData;
326208625Sjkim    DT_SUBTABLE             *Subtable;
327208625Sjkim    char                    *Signature;
328208625Sjkim    ACPI_TABLE_HEADER       *AcpiTableHeader;
329208625Sjkim    ACPI_STATUS             Status;
330208625Sjkim
331208625Sjkim
332208625Sjkim    /* Verify that we at least have a table signature and save it */
333208625Sjkim
334208625Sjkim    Signature = DtGetFieldValue (*FieldList, "Signature");
335208625Sjkim    if (!Signature)
336208625Sjkim    {
337209734Sjkim        sprintf (MsgBuffer, "Expected \"%s\"", "Signature");
338209734Sjkim        DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
339209734Sjkim            *FieldList, MsgBuffer);
340208625Sjkim        return (AE_ERROR);
341208625Sjkim    }
342208625Sjkim
343208625Sjkim    Gbl_Signature = UtLocalCalloc (ACPI_STRLEN (Signature) + 1);
344208625Sjkim    strcpy (Gbl_Signature, Signature);
345208625Sjkim
346208625Sjkim    /*
347208625Sjkim     * Handle tables that don't use the common ACPI table header structure.
348208625Sjkim     * Currently, these are the FACS and RSDP. Also check for an OEMx table,
349208625Sjkim     * these tables have user-defined contents.
350208625Sjkim     */
351208625Sjkim    if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
352208625Sjkim    {
353208625Sjkim        Status = DtCompileFacs (FieldList);
354208625Sjkim        if (ACPI_FAILURE (Status))
355208625Sjkim        {
356208625Sjkim            return (Status);
357208625Sjkim        }
358208625Sjkim
359208625Sjkim        DtSetTableLength ();
360208625Sjkim        return (Status);
361208625Sjkim    }
362208625Sjkim    else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDP))
363208625Sjkim    {
364208625Sjkim        Status = DtCompileRsdp (FieldList);
365208625Sjkim        return (Status);
366208625Sjkim    }
367208625Sjkim    else if (!ACPI_STRNCMP (Signature, "OEM", 3))
368208625Sjkim    {
369208625Sjkim        DtFatal (ASL_MSG_OEM_TABLE, *FieldList, Signature);
370208625Sjkim        return (AE_ERROR);
371208625Sjkim    }
372208625Sjkim
373209734Sjkim    /* Validate the signature via the ACPI table list */
374209734Sjkim
375209734Sjkim    TableData = AcpiDmGetTableData (Signature);
376209734Sjkim    if (!TableData)
377209734Sjkim    {
378209734Sjkim        DtFatal (ASL_MSG_UNKNOWN_TABLE, *FieldList, Signature);
379209734Sjkim        return (AE_ERROR);
380209734Sjkim    }
381209734Sjkim
382208625Sjkim    /*
383208625Sjkim     * All other tables must use the common ACPI table header. Insert the
384208625Sjkim     * current iASL IDs (name, version), and compile the header now.
385208625Sjkim     */
386208625Sjkim    DtInsertCompilerIds (*FieldList);
387208625Sjkim
388208625Sjkim    Status = DtCompileTable (FieldList, AcpiDmTableInfoHeader,
389208625Sjkim                &Gbl_RootTable, TRUE);
390208625Sjkim    if (ACPI_FAILURE (Status))
391208625Sjkim    {
392208625Sjkim        return (Status);
393208625Sjkim    }
394208625Sjkim
395208625Sjkim    DtPushSubtable (Gbl_RootTable);
396208625Sjkim
397209734Sjkim    /* Dispatch to per-table compile */
398208625Sjkim
399208625Sjkim    if (TableData->CmTableHandler)
400208625Sjkim    {
401208625Sjkim        /* Complex table, has a handler */
402208625Sjkim
403208625Sjkim        Status = TableData->CmTableHandler ((void **) FieldList);
404208625Sjkim        if (ACPI_FAILURE (Status))
405208625Sjkim        {
406208625Sjkim            return (Status);
407208625Sjkim        }
408208625Sjkim    }
409208625Sjkim    else if (TableData->TableInfo)
410208625Sjkim    {
411208625Sjkim        /* Simple table, just walk the info table */
412208625Sjkim
413208625Sjkim        Subtable = NULL;
414208625Sjkim        Status = DtCompileTable (FieldList, TableData->TableInfo,
415208625Sjkim                    &Subtable, TRUE);
416208625Sjkim        if (ACPI_FAILURE (Status))
417208625Sjkim        {
418208625Sjkim            return (Status);
419208625Sjkim        }
420208625Sjkim
421208625Sjkim        DtInsertSubtable (Gbl_RootTable, Subtable);
422208625Sjkim        DtPopSubtable ();
423208625Sjkim    }
424208625Sjkim    else
425208625Sjkim    {
426208625Sjkim        DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList,
427208625Sjkim            "Missing table dispatch info");
428208625Sjkim        return (AE_ERROR);
429208625Sjkim    }
430208625Sjkim
431208625Sjkim    /* Set the final table length and then the checksum */
432208625Sjkim
433208625Sjkim    DtSetTableLength ();
434208625Sjkim    AcpiTableHeader = ACPI_CAST_PTR (
435208625Sjkim        ACPI_TABLE_HEADER, Gbl_RootTable->Buffer);
436208625Sjkim    DtSetTableChecksum (&AcpiTableHeader->Checksum);
437208625Sjkim
438208625Sjkim    return (AE_OK);
439208625Sjkim}
440208625Sjkim
441208625Sjkim
442208625Sjkim/******************************************************************************
443208625Sjkim *
444208625Sjkim * FUNCTION:    DtCompileTable
445208625Sjkim *
446208625Sjkim * PARAMETERS:  Field               - Current field list pointer
447208625Sjkim *              Info                - Info table for this ACPI table
448208625Sjkim *              RetSubtable         - Compile result of table
449208625Sjkim *              Required            - If this subtable must exist
450208625Sjkim *
451208625Sjkim * RETURN:      Status
452208625Sjkim *
453208625Sjkim * DESCRIPTION: Compile a subtable
454208625Sjkim *
455208625Sjkim *****************************************************************************/
456208625Sjkim
457208625SjkimACPI_STATUS
458208625SjkimDtCompileTable (
459208625Sjkim    DT_FIELD                **Field,
460208625Sjkim    ACPI_DMTABLE_INFO       *Info,
461208625Sjkim    DT_SUBTABLE             **RetSubtable,
462208625Sjkim    BOOLEAN                 Required)
463208625Sjkim{
464208625Sjkim    DT_FIELD                *LocalField;
465208625Sjkim    UINT32                  Length;
466208625Sjkim    DT_SUBTABLE             *Subtable;
467208625Sjkim    DT_SUBTABLE             *InlineSubtable;
468208625Sjkim    UINT32                  FieldLength = 0;
469208625Sjkim    UINT8                   FieldType;
470208625Sjkim    UINT8                   *Buffer;
471208625Sjkim    UINT8                   *FlagBuffer = NULL;
472208625Sjkim    ACPI_STATUS             Status;
473208625Sjkim
474208625Sjkim
475208625Sjkim    if (!Field || !*Field)
476208625Sjkim    {
477208625Sjkim        return (AE_BAD_PARAMETER);
478208625Sjkim    }
479208625Sjkim
480208625Sjkim    Length = DtGetSubtableLength (*Field, Info);
481208625Sjkim    Subtable = UtLocalCalloc (sizeof (DT_SUBTABLE));
482208625Sjkim
483208625Sjkim    Subtable->Buffer = UtLocalCalloc (Length);
484208625Sjkim    Subtable->Length = Length;
485208625Sjkim    Subtable->TotalLength = Length;
486208625Sjkim    Buffer = Subtable->Buffer;
487208625Sjkim
488208625Sjkim    LocalField = *Field;
489208625Sjkim
490208625Sjkim    /*
491208625Sjkim     * Main loop walks the info table for this ACPI table or subtable
492208625Sjkim     */
493208625Sjkim    for (; Info->Name; Info++)
494208625Sjkim    {
495208625Sjkim        if (!LocalField)
496208625Sjkim        {
497208625Sjkim            sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed",
498208625Sjkim                Info->Name);
499208625Sjkim            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
500208625Sjkim            Status = AE_BAD_DATA;
501208625Sjkim            goto Error;
502208625Sjkim        }
503208625Sjkim
504208625Sjkim        /* Does input field name match what is expected? */
505208625Sjkim
506208625Sjkim        if (ACPI_STRCMP (LocalField->Name, Info->Name))
507208625Sjkim        {
508208625Sjkim            /*
509208625Sjkim             * If Required = TRUE, the subtable must exist.
510208625Sjkim             * If Required = FALSE, the subtable is optional
511208625Sjkim             * (For example, AcpiDmTableInfoDmarScope in DMAR table is
512208625Sjkim             * optional)
513208625Sjkim             */
514208625Sjkim            if (Required)
515208625Sjkim            {
516208625Sjkim                sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
517208625Sjkim                DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
518208625Sjkim                    LocalField, MsgBuffer);
519208625Sjkim            }
520208625Sjkim            else
521208625Sjkim            {
522208625Sjkim                Status = AE_NOT_FOUND;
523208625Sjkim                goto Error;
524208625Sjkim            }
525208625Sjkim        }
526208625Sjkim
527208625Sjkim        FieldLength = DtGetFieldLength (LocalField, Info);
528208625Sjkim        FieldType = DtGetFieldType (Info);
529208625Sjkim        Gbl_InputFieldCount++;
530208625Sjkim
531208625Sjkim        switch (FieldType)
532208625Sjkim        {
533208625Sjkim        case DT_FIELD_TYPE_FLAGS_INTEGER:
534208625Sjkim            /*
535208625Sjkim             * Start of the definition of a flags field.
536208625Sjkim             * This master flags integer starts at value zero, in preparation
537208625Sjkim             * to compile and insert the flag fields from the individual bits
538208625Sjkim             */
539208625Sjkim            LocalField = LocalField->Next;
540208625Sjkim            *Field = LocalField;
541208625Sjkim
542208625Sjkim            FlagBuffer = Buffer;
543208625Sjkim            break;
544208625Sjkim
545208625Sjkim        case DT_FIELD_TYPE_FLAG:
546208625Sjkim
547208625Sjkim            /* Individual Flag field, can be multiple bits */
548208625Sjkim
549208625Sjkim            if (FlagBuffer)
550208625Sjkim            {
551209734Sjkim                DtCompileFlag (FlagBuffer, LocalField, Info);
552208625Sjkim            }
553208625Sjkim            else
554208625Sjkim            {
555208625Sjkim                /* TBD - this is an internal error */
556208625Sjkim            }
557208625Sjkim
558208625Sjkim            LocalField = LocalField->Next;
559208625Sjkim            *Field = LocalField;
560208625Sjkim            break;
561208625Sjkim
562208625Sjkim        case DT_FIELD_TYPE_INLINE_SUBTABLE:
563208625Sjkim            /*
564208625Sjkim             * Recursion (one level max): compile GAS (Generic Address)
565208625Sjkim             * or Notify in-line subtable
566208625Sjkim             */
567208625Sjkim            LocalField = LocalField->Next;
568208625Sjkim            *Field = LocalField;
569208625Sjkim
570208625Sjkim            if (Info->Opcode == ACPI_DMT_GAS)
571208625Sjkim            {
572208625Sjkim                Status = DtCompileTable (Field, AcpiDmTableInfoGas,
573208625Sjkim                    &InlineSubtable, TRUE);
574208625Sjkim            }
575208625Sjkim            else
576208625Sjkim            {
577208625Sjkim                Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify,
578208625Sjkim                    &InlineSubtable, TRUE);
579208625Sjkim            }
580208625Sjkim
581208625Sjkim            if (ACPI_FAILURE (Status))
582208625Sjkim            {
583208625Sjkim                goto Error;
584208625Sjkim            }
585208625Sjkim
586209734Sjkim            DtSetSubtableLength (InlineSubtable);
587209734Sjkim
588208625Sjkim            ACPI_MEMCPY (Buffer, InlineSubtable->Buffer, FieldLength);
589208625Sjkim            ACPI_FREE (InlineSubtable->Buffer);
590208625Sjkim            ACPI_FREE (InlineSubtable);
591208625Sjkim            LocalField = *Field;
592208625Sjkim            break;
593208625Sjkim
594208625Sjkim        default:
595208625Sjkim
596208625Sjkim            /* Normal case for most field types (Integer, String, etc.) */
597208625Sjkim
598208625Sjkim            DtCompileOneField (Buffer, LocalField,
599208625Sjkim                FieldLength, FieldType, Info->Flags);
600208625Sjkim            LocalField = LocalField->Next;
601208625Sjkim
602208625Sjkim            if (Info->Flags & DT_LENGTH)
603208625Sjkim            {
604208625Sjkim                /* Field is an Integer that will contain a subtable length */
605208625Sjkim
606208625Sjkim                Subtable->LengthField = Buffer;
607208625Sjkim                Subtable->SizeOfLengthField = FieldLength;
608208625Sjkim            }
609208625Sjkim            break;
610208625Sjkim        }
611208625Sjkim
612208625Sjkim        Buffer += FieldLength;
613208625Sjkim    }
614208625Sjkim
615208625Sjkim    *Field = LocalField;
616208625Sjkim    *RetSubtable = Subtable;
617208625Sjkim    return (AE_OK);
618208625Sjkim
619208625SjkimError:
620208625Sjkim    ACPI_FREE (Subtable->Buffer);
621208625Sjkim    ACPI_FREE (Subtable);
622208625Sjkim    return (Status);
623208625Sjkim}
624