dtcompile.c revision 281396
125184Sjkh/******************************************************************************
2113674Smtm *
3113674Smtm * Module Name: dtcompile.c - Front-end for data table compiler
4113674Smtm *
5113674Smtm *****************************************************************************/
6113674Smtm
7113674Smtm/*
8113674Smtm * Copyright (C) 2000 - 2015, Intel Corp.
9113674Smtm * All rights reserved.
10113674Smtm *
11113674Smtm * Redistribution and use in source and binary forms, with or without
12113674Smtm * modification, are permitted provided that the following conditions
13113674Smtm * are met:
14113674Smtm * 1. Redistributions of source code must retain the above copyright
15113674Smtm *    notice, this list of conditions, and the following disclaimer,
16113674Smtm *    without modification.
17113674Smtm * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18113674Smtm *    substantially similar to the "NO WARRANTY" disclaimer below
19113674Smtm *    ("Disclaimer") and any redistribution must be conditioned upon
20113674Smtm *    including a substantially similar Disclaimer requirement for further
21113674Smtm *    binary redistribution.
22113674Smtm * 3. Neither the names of the above-listed copyright holders nor the names
23113674Smtm *    of any contributors may be used to endorse or promote products derived
24113674Smtm *    from this software without specific prior written permission.
2550472Speter *
2666830Sobrien * Alternatively, this software may be distributed under the terms of the
2725184Sjkh * GNU General Public License ("GPL") version 2 as published by the Free
28113674Smtm * Software Foundation.
29113674Smtm *
30113674Smtm * NO WARRANTY
31113674Smtm * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3225184Sjkh * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33113674Smtm * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34113674Smtm * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35113674Smtm * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36113674Smtm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37147088Sbrooks * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38147088Sbrooks * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39113674Smtm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40113674Smtm * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41113674Smtm * POSSIBILITY OF SUCH DAMAGES.
42147088Sbrooks */
43147088Sbrooks
44147088Sbrooks#define _DECLARE_DT_GLOBALS
45113674Smtm
46149726Sbrooks#include <contrib/dev/acpica/compiler/aslcompiler.h>
47157706Sbrooks#include <contrib/dev/acpica/compiler/dtcompiler.h>
48147088Sbrooks
49113674Smtm#define _COMPONENT          DT_COMPILER
50147088Sbrooks        ACPI_MODULE_NAME    ("dtcompile")
51147088Sbrooks
52149726Sbrooksstatic char                 VersionString[9];
53149726Sbrooks
54149726Sbrooks
55147682Sbrooks/* Local prototypes */
56147088Sbrooks
57147088Sbrooksstatic ACPI_STATUS
58147088SbrooksDtInitialize (
59147088Sbrooks    void);
60149726Sbrooks
61149726Sbrooksstatic ACPI_STATUS
62149726SbrooksDtCompileDataTable (
63157706Sbrooks    DT_FIELD                **Field);
64157706Sbrooks
65157706Sbrooksstatic void
66147088SbrooksDtInsertCompilerIds (
67147088Sbrooks    DT_FIELD                *FieldList);
68147088Sbrooks
69147121Sbrooks
70113674Smtm/******************************************************************************
7125184Sjkh *
72116029Smtm * FUNCTION:    DtDoCompile
73161386Sbrooks *
74161386Sbrooks * PARAMETERS:  None
75116029Smtm *
76116029Smtm * RETURN:      Status
77116029Smtm *
78116029Smtm * DESCRIPTION: Main entry point for the data table compiler.
79147121Sbrooks *
80116029Smtm * Note: Assumes Gbl_Files[ASL_FILE_INPUT] is initialized and the file is
81147088Sbrooks *          open at seek offset zero.
82147682Sbrooks *
83147121Sbrooks *****************************************************************************/
84147088Sbrooks
85147088SbrooksACPI_STATUS
86147088SbrooksDtDoCompile (
87147088Sbrooks    void)
88147088Sbrooks{
89147088Sbrooks    ACPI_STATUS             Status;
90147088Sbrooks    UINT8                   Event;
91161386Sbrooks    DT_FIELD                *FieldList;
92161386Sbrooks
93161386Sbrooks
94161386Sbrooks    /* Initialize globals */
95157706Sbrooks
96147121Sbrooks    Status = DtInitialize ();
97116029Smtm    if (ACPI_FAILURE (Status))
98116029Smtm    {
99157706Sbrooks        printf ("Error during compiler initialization, 0x%X\n", Status);
100157706Sbrooks        return (Status);
101157706Sbrooks    }
102157706Sbrooks
103157706Sbrooks    /* Preprocessor */
104157706Sbrooks
105157706Sbrooks    if (Gbl_PreprocessFlag)
106157706Sbrooks    {
107157706Sbrooks        /* Preprocessor */
108157706Sbrooks
109157706Sbrooks        Event = UtBeginEvent ("Preprocess input file");
110157706Sbrooks        PrDoPreprocess ();
111157706Sbrooks        UtEndEvent (Event);
112157706Sbrooks
113157736Sbrooks        if (Gbl_PreprocessOnly)
114157706Sbrooks        {
115157706Sbrooks            return (AE_OK);
116157706Sbrooks        }
117157706Sbrooks    }
118157706Sbrooks
119157706Sbrooks    /*
120157706Sbrooks     * Scan the input file (file is already open) and
121157706Sbrooks     * build the parse tree
122157706Sbrooks     */
123157706Sbrooks    Event = UtBeginEvent ("Scan and parse input file");
124147088Sbrooks    FieldList = DtScanFile (Gbl_Files[ASL_FILE_INPUT].Handle);
125147088Sbrooks    UtEndEvent (Event);
126147088Sbrooks
127147088Sbrooks    /* Did the parse tree get successfully constructed? */
128147088Sbrooks
129147088Sbrooks    if (!FieldList)
130147088Sbrooks    {
131147088Sbrooks        /* TBD: temporary error message. Msgs should come from function above */
132147088Sbrooks
133147088Sbrooks        DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
134147088Sbrooks            "Input file does not appear to be an ASL or data table source file");
135157706Sbrooks
136147088Sbrooks        Status = AE_ERROR;
137147088Sbrooks        goto CleanupAndExit;
138147088Sbrooks    }
139147088Sbrooks
140147088Sbrooks    Event = UtBeginEvent ("Compile parse tree");
141147088Sbrooks
142147088Sbrooks    /*
143147088Sbrooks     * Compile the parse tree
144147088Sbrooks     */
145147088Sbrooks    Status = DtCompileDataTable (&FieldList);
146147088Sbrooks    UtEndEvent (Event);
147147088Sbrooks
148147088Sbrooks    if (ACPI_FAILURE (Status))
149147088Sbrooks    {
150147088Sbrooks        /* TBD: temporary error message. Msgs should come from function above */
151157706Sbrooks
152157706Sbrooks        DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
153157706Sbrooks            "Could not compile input file");
154157706Sbrooks
155157706Sbrooks        goto CleanupAndExit;
156147088Sbrooks    }
157147088Sbrooks
158147088Sbrooks    /* Create/open the binary output file */
159147088Sbrooks
160147088Sbrooks    Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL;
161147088Sbrooks    Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
162147088Sbrooks    if (ACPI_FAILURE (Status))
163147088Sbrooks    {
164147088Sbrooks        goto CleanupAndExit;
165149401Sbrooks    }
166149401Sbrooks
167149401Sbrooks    /* Write the binary, then the optional hex file */
168149401Sbrooks
169149401Sbrooks    DtOutputBinary (Gbl_RootTable);
170149401Sbrooks    HxDoHexOutput ();
171149401Sbrooks    DtWriteTableToListing ();
172149401Sbrooks
173149401SbrooksCleanupAndExit:
174149401Sbrooks
175149401Sbrooks    AcpiUtDeleteCaches ();
176149401Sbrooks    DtDeleteCaches ();
177149401Sbrooks    CmCleanupAndExit ();
178149401Sbrooks    return (Status);
179149401Sbrooks}
180149401Sbrooks
181147088Sbrooks
182147088Sbrooks/******************************************************************************
183147088Sbrooks *
184147088Sbrooks * FUNCTION:    DtInitialize
185147088Sbrooks *
186147088Sbrooks * PARAMETERS:  None
187147088Sbrooks *
188147088Sbrooks * RETURN:      Status
189147088Sbrooks *
190147088Sbrooks * DESCRIPTION: Initialize data table compiler globals. Enables multiple
191157706Sbrooks *              compiles per invocation.
192157706Sbrooks *
193157706Sbrooks *****************************************************************************/
194157706Sbrooks
195157706Sbrooksstatic ACPI_STATUS
196157706SbrooksDtInitialize (
197147088Sbrooks    void)
198147088Sbrooks{
199147088Sbrooks    ACPI_STATUS             Status;
200147088Sbrooks
201147088Sbrooks
202157706Sbrooks    Status = AcpiOsInitialize ();
203157706Sbrooks    if (ACPI_FAILURE (Status))
204157706Sbrooks    {
205157706Sbrooks        return (Status);
206157706Sbrooks    }
207157706Sbrooks
208157706Sbrooks    Status = AcpiUtInitGlobals ();
209157706Sbrooks    if (ACPI_FAILURE (Status))
210157706Sbrooks    {
211157706Sbrooks        return (Status);
212157706Sbrooks    }
213157706Sbrooks
214157706Sbrooks    Gbl_FieldList = NULL;
215157706Sbrooks    Gbl_RootTable = NULL;
216157706Sbrooks    Gbl_SubtableStack = NULL;
217157706Sbrooks
218157737Sbrooks    sprintf (VersionString, "%X", (UINT32) ACPI_CA_VERSION);
219157706Sbrooks    return (AE_OK);
220157706Sbrooks}
221157706Sbrooks
222157706Sbrooks
223157706Sbrooks/******************************************************************************
224157706Sbrooks *
225147088Sbrooks * FUNCTION:    DtInsertCompilerIds
226147088Sbrooks *
227147088Sbrooks * PARAMETERS:  FieldList           - Current field list pointer
228147088Sbrooks *
229147088Sbrooks * RETURN:      None
230147088Sbrooks *
231147088Sbrooks * DESCRIPTION: Insert the IDs (Name, Version) of the current compiler into
232147088Sbrooks *              the original ACPI table header.
233147088Sbrooks *
234147088Sbrooks *****************************************************************************/
235147088Sbrooks
236147088Sbrooksstatic void
237147088SbrooksDtInsertCompilerIds (
238147088Sbrooks    DT_FIELD                *FieldList)
239147088Sbrooks{
240162490Sbrooks    DT_FIELD                *Next;
241162490Sbrooks    UINT32                  i;
242162490Sbrooks
243162490Sbrooks
244162490Sbrooks    /*
245162490Sbrooks     * Don't insert current compiler ID if requested. Used for compiler
246162490Sbrooks     * debug/validation only.
247162490Sbrooks     */
248162490Sbrooks    if (Gbl_UseOriginalCompilerId)
249162490Sbrooks    {
250162490Sbrooks        return;
251162490Sbrooks    }
252162490Sbrooks
253162490Sbrooks    /* Walk to the Compiler fields at the end of the header */
254162490Sbrooks
255162490Sbrooks    Next = FieldList;
256162490Sbrooks    for (i = 0; i < 7; i++)
257162490Sbrooks    {
258162490Sbrooks        Next = Next->Next;
259162490Sbrooks    }
260162490Sbrooks
261162490Sbrooks    Next->Value = ASL_CREATOR_ID;
262162490Sbrooks    Next->Flags = DT_FIELD_NOT_ALLOCATED;
263162490Sbrooks
264161386Sbrooks    Next = Next->Next;
265161386Sbrooks    Next->Value = VersionString;
266161386Sbrooks    Next->Flags = DT_FIELD_NOT_ALLOCATED;
267161386Sbrooks}
268161386Sbrooks
269161386Sbrooks
270161386Sbrooks/******************************************************************************
271152441Sbrooks *
272152441Sbrooks * FUNCTION:    DtCompileDataTable
273152441Sbrooks *
274152441Sbrooks * PARAMETERS:  FieldList           - Current field list pointer
275152441Sbrooks *
276152441Sbrooks * RETURN:      Status
277152441Sbrooks *
278152441Sbrooks * DESCRIPTION: Entry point to compile one data table
279152441Sbrooks *
280152441Sbrooks *****************************************************************************/
281152441Sbrooks
282152441Sbrooksstatic ACPI_STATUS
283152441SbrooksDtCompileDataTable (
284152441Sbrooks    DT_FIELD                **FieldList)
285161386Sbrooks{
286161386Sbrooks    ACPI_DMTABLE_DATA       *TableData;
287161386Sbrooks    DT_SUBTABLE             *Subtable;
288161386Sbrooks    char                    *Signature;
289161386Sbrooks    ACPI_TABLE_HEADER       *AcpiTableHeader;
290161386Sbrooks    ACPI_STATUS             Status;
291161386Sbrooks    DT_FIELD                *RootField = *FieldList;
292161386Sbrooks
293161386Sbrooks
294161386Sbrooks    /* Verify that we at least have a table signature and save it */
295161386Sbrooks
296161386Sbrooks    Signature = DtGetFieldValue (*FieldList);
297161386Sbrooks    if (!Signature)
298161386Sbrooks    {
299161386Sbrooks        sprintf (MsgBuffer, "Expected \"%s\"", "Signature");
300161386Sbrooks        DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
301161386Sbrooks            *FieldList, MsgBuffer);
302161386Sbrooks        return (AE_ERROR);
303161386Sbrooks    }
304161386Sbrooks
305161386Sbrooks    Gbl_Signature = UtStringCacheCalloc (ACPI_STRLEN (Signature) + 1);
306161386Sbrooks    strcpy (Gbl_Signature, Signature);
307161386Sbrooks
308161386Sbrooks    /*
309161386Sbrooks     * Handle tables that don't use the common ACPI table header structure.
310161386Sbrooks     * Currently, these are the FACS and RSDP. Also check for an OEMx table,
311152441Sbrooks     * these tables have user-defined contents.
312152441Sbrooks     */
313152441Sbrooks    if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
314152441Sbrooks    {
315152441Sbrooks        Status = DtCompileFacs (FieldList);
316152441Sbrooks        if (ACPI_FAILURE (Status))
317152441Sbrooks        {
318152441Sbrooks            return (Status);
319152441Sbrooks        }
320152441Sbrooks
321152441Sbrooks        DtSetTableLength ();
322152441Sbrooks        return (Status);
323157706Sbrooks    }
324152441Sbrooks    else if (ACPI_VALIDATE_RSDP_SIG (Signature))
325152441Sbrooks    {
326152441Sbrooks        Status = DtCompileRsdp (FieldList);
327152441Sbrooks        return (Status);
328152441Sbrooks    }
329152441Sbrooks    else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_S3PT))
330152441Sbrooks    {
331152441Sbrooks        Status = DtCompileS3pt (FieldList);
332152441Sbrooks        if (ACPI_FAILURE (Status))
333152441Sbrooks        {
334152441Sbrooks            return (Status);
335152441Sbrooks        }
336152441Sbrooks
337152441Sbrooks        DtSetTableLength ();
338152441Sbrooks        return (Status);
339152441Sbrooks    }
340152441Sbrooks
341152441Sbrooks    /*
342152441Sbrooks     * All other tables must use the common ACPI table header. Insert the
343152441Sbrooks     * current iASL IDs (name, version), and compile the header now.
344152441Sbrooks     */
345152441Sbrooks    DtInsertCompilerIds (*FieldList);
346152441Sbrooks
347152441Sbrooks    Status = DtCompileTable (FieldList, AcpiDmTableInfoHeader,
348152441Sbrooks                &Gbl_RootTable, TRUE);
349152441Sbrooks    if (ACPI_FAILURE (Status))
350152441Sbrooks    {
351152441Sbrooks        return (Status);
352152441Sbrooks    }
353113674Smtm
354113674Smtm    DtPushSubtable (Gbl_RootTable);
355113674Smtm
356113674Smtm    /* Validate the signature via the ACPI table list */
357113674Smtm
358113674Smtm    TableData = AcpiDmGetTableData (Signature);
359113674Smtm    if (!TableData || Gbl_CompileGeneric)
360113674Smtm    {
361113674Smtm        DtCompileGeneric ((void **) FieldList);
362113674Smtm        goto FinishHeader;
363157706Sbrooks    }
364113674Smtm
365113674Smtm    /* Dispatch to per-table compile */
366113674Smtm
367113674Smtm    if (TableData->CmTableHandler)
368113674Smtm    {
369113674Smtm        /* Complex table, has a handler */
370113674Smtm
371113674Smtm        Status = TableData->CmTableHandler ((void **) FieldList);
372113674Smtm        if (ACPI_FAILURE (Status))
373113674Smtm        {
374100280Sgordon            return (Status);
375116029Smtm        }
376116029Smtm    }
377116029Smtm    else if (TableData->TableInfo)
378116029Smtm    {
379116029Smtm        /* Simple table, just walk the info table */
380116029Smtm
381116029Smtm        Subtable = NULL;
382116029Smtm        Status = DtCompileTable (FieldList, TableData->TableInfo,
383116029Smtm                    &Subtable, TRUE);
384116029Smtm        if (ACPI_FAILURE (Status))
385157706Sbrooks        {
386116029Smtm            return (Status);
387116029Smtm        }
388116029Smtm
389116029Smtm        DtInsertSubtable (Gbl_RootTable, Subtable);
390116029Smtm        DtPopSubtable ();
391116029Smtm    }
392116029Smtm    else
393116029Smtm    {
394116029Smtm        DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList,
395116029Smtm            "Missing table dispatch info");
396116029Smtm        return (AE_ERROR);
397113674Smtm    }
398113674Smtm
399113674SmtmFinishHeader:
400113674Smtm
401113674Smtm    /* Set the final table length and then the checksum */
402113674Smtm
403100280Sgordon    DtSetTableLength ();
404113674Smtm    AcpiTableHeader = ACPI_CAST_PTR (
405113674Smtm        ACPI_TABLE_HEADER, Gbl_RootTable->Buffer);
406113674Smtm    DtSetTableChecksum (&AcpiTableHeader->Checksum);
407113674Smtm
408113674Smtm    DtDumpFieldList (RootField);
409100280Sgordon    DtDumpSubtableList ();
410100280Sgordon    return (AE_OK);
411116029Smtm}
412116029Smtm
413116029Smtm
414116029Smtm/******************************************************************************
415116029Smtm *
416116029Smtm * FUNCTION:    DtCompileTable
417116029Smtm *
418116029Smtm * PARAMETERS:  Field               - Current field list pointer
419116029Smtm *              Info                - Info table for this ACPI table
420116029Smtm *              RetSubtable         - Compile result of table
421116029Smtm *              Required            - If this subtable must exist
422116029Smtm *
423116029Smtm * RETURN:      Status
424116029Smtm *
425113674Smtm * DESCRIPTION: Compile a subtable
426113674Smtm *
427113674Smtm *****************************************************************************/
428100280Sgordon
429113674SmtmACPI_STATUS
430113674SmtmDtCompileTable (
431113674Smtm    DT_FIELD                **Field,
432113674Smtm    ACPI_DMTABLE_INFO       *Info,
433116774Skuriyama    DT_SUBTABLE             **RetSubtable,
434113674Smtm    BOOLEAN                 Required)
435113674Smtm{
436113674Smtm    DT_FIELD                *LocalField;
437113674Smtm    UINT32                  Length;
438113674Smtm    DT_SUBTABLE             *Subtable;
439113674Smtm    DT_SUBTABLE             *InlineSubtable;
440100280Sgordon    UINT32                  FieldLength = 0;
441113674Smtm    UINT8                   FieldType;
442113674Smtm    UINT8                   *Buffer;
443113674Smtm    UINT8                   *FlagBuffer = NULL;
444113674Smtm    char                    *String;
445113674Smtm    UINT32                  CurrentFlagByteOffset = 0;
446113674Smtm    ACPI_STATUS             Status;
447113674Smtm
448113674Smtm
449113674Smtm    if (!Field || !*Field)
450116774Skuriyama    {
451113674Smtm        return (AE_BAD_PARAMETER);
452113674Smtm    }
453113674Smtm
454113674Smtm    /* Ignore optional subtable if name does not match */
455113674Smtm
456100280Sgordon    if ((Info->Flags & DT_OPTIONAL) &&
457100280Sgordon        ACPI_STRCMP ((*Field)->Name, Info->Name))
458113674Smtm    {
459100282Sdougb        *RetSubtable = NULL;
460100282Sdougb        return (AE_OK);
461100282Sdougb    }
462100282Sdougb
463100282Sdougb    Length = DtGetSubtableLength (*Field, Info);
464157706Sbrooks    if (Length == ASL_EOF)
465100282Sdougb    {
466100282Sdougb        return (AE_ERROR);
467100282Sdougb    }
468100282Sdougb
469100282Sdougb    Subtable = UtSubtableCacheCalloc ();
470100282Sdougb
471100282Sdougb    if (Length > 0)
472103710Sume    {
473100282Sdougb        String = UtStringCacheCalloc (Length);
474100282Sdougb        Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
475100282Sdougb    }
476100282Sdougb
477100282Sdougb    Subtable->Length = Length;
478100282Sdougb    Subtable->TotalLength = Length;
479100282Sdougb    Buffer = Subtable->Buffer;
480113674Smtm
481113674Smtm    LocalField = *Field;
482113674Smtm
483113674Smtm    /*
484113674Smtm     * Main loop walks the info table for this ACPI table or subtable
485113674Smtm     */
486100280Sgordon    for (; Info->Name; Info++)
487113674Smtm    {
488157706Sbrooks        if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
489113674Smtm        {
490113674Smtm            continue;
491113674Smtm        }
49285831Sdes
493113674Smtm        if (!LocalField)
494113674Smtm        {
49585831Sdes            sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed",
496116029Smtm                Info->Name);
497116029Smtm            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
498116029Smtm            Status = AE_BAD_DATA;
499113674Smtm            goto Error;
500116029Smtm        }
501116029Smtm
502116100Smtm        /* Maintain table offsets */
503116100Smtm
504116100Smtm        LocalField->TableOffset = Gbl_CurrentTableOffset;
505116100Smtm        FieldLength = DtGetFieldLength (LocalField, Info);
506161386Sbrooks        Gbl_CurrentTableOffset += FieldLength;
507161386Sbrooks
508116100Smtm        FieldType = DtGetFieldType (Info);
509116100Smtm        Gbl_InputFieldCount++;
510116100Smtm
511116100Smtm        switch (FieldType)
512116100Smtm        {
513116100Smtm        case DT_FIELD_TYPE_FLAGS_INTEGER:
514116100Smtm            /*
515116100Smtm             * Start of the definition of a flags field.
516116100Smtm             * This master flags integer starts at value zero, in preparation
517116100Smtm             * to compile and insert the flag fields from the individual bits
518116100Smtm             */
519116100Smtm            LocalField = LocalField->Next;
520116100Smtm            *Field = LocalField;
521116100Smtm
522116100Smtm            FlagBuffer = Buffer;
523116100Smtm            CurrentFlagByteOffset = Info->Offset;
524116100Smtm            break;
525116100Smtm
526116029Smtm        case DT_FIELD_TYPE_FLAG:
527116029Smtm
528137070Spjd            /* Individual Flag field, can be multiple bits */
529137070Spjd
530116029Smtm            if (FlagBuffer)
531137070Spjd            {
532137070Spjd                /*
533137070Spjd                 * We must increment the FlagBuffer when we have crossed
534138386Srse                 * into the next flags byte within the flags field
535137070Spjd                 * of type DT_FIELD_TYPE_FLAGS_INTEGER.
536137070Spjd                 */
537157706Sbrooks                FlagBuffer += (Info->Offset - CurrentFlagByteOffset);
538137070Spjd                CurrentFlagByteOffset = Info->Offset;
539137070Spjd
540137070Spjd                DtCompileFlag (FlagBuffer, LocalField, Info);
541137070Spjd            }
542137070Spjd            else
543137070Spjd            {
544137070Spjd                /* TBD - this is an internal error */
545137070Spjd            }
546113674Smtm
547113674Smtm            LocalField = LocalField->Next;
548113674Smtm            *Field = LocalField;
549113674Smtm            break;
550113674Smtm
551113674Smtm        case DT_FIELD_TYPE_INLINE_SUBTABLE:
552113674Smtm            /*
553134429Syar             * Recursion (one level max): compile GAS (Generic Address)
554134429Syar             * or Notify in-line subtable
555134429Syar             */
556113674Smtm            *Field = LocalField;
557113674Smtm
558113674Smtm            if (Info->Opcode == ACPI_DMT_GAS)
559113674Smtm            {
56065532Snectar                Status = DtCompileTable (Field, AcpiDmTableInfoGas,
561149726Sbrooks                    &InlineSubtable, TRUE);
56251231Ssheldonh            }
56351231Ssheldonh            else
56451231Ssheldonh            {
565149401Sbrooks                Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify,
566149401Sbrooks                    &InlineSubtable, TRUE);
567149726Sbrooks            }
568149401Sbrooks
569149401Sbrooks            if (ACPI_FAILURE (Status))
570149726Sbrooks            {
571149726Sbrooks                goto Error;
572149726Sbrooks            }
573149726Sbrooks
574149726Sbrooks            DtSetSubtableLength (InlineSubtable);
575149726Sbrooks
576149401Sbrooks            ACPI_MEMCPY (Buffer, InlineSubtable->Buffer, FieldLength);
577149401Sbrooks            LocalField = *Field;
578149726Sbrooks            break;
57951231Ssheldonh
58083677Sbrooks        case DT_FIELD_TYPE_LABEL:
581149401Sbrooks
58283677Sbrooks            DtWriteFieldToListing (Buffer, LocalField, 0);
58351231Ssheldonh            LocalField = LocalField->Next;
58449122Sbrian            break;
585113674Smtm
586113674Smtm        default:
587113674Smtm
588113674Smtm            /* Normal case for most field types (Integer, String, etc.) */
58949122Sbrian
590138385Srse            DtCompileOneField (Buffer, LocalField,
591113674Smtm                FieldLength, FieldType, Info->Flags);
592113674Smtm
593134376Syar            DtWriteFieldToListing (Buffer, LocalField, FieldLength);
594113674Smtm            LocalField = LocalField->Next;
595147684Sbrooks
596113674Smtm            if (Info->Flags & DT_LENGTH)
597113674Smtm            {
598157706Sbrooks                /* Field is an Integer that will contain a subtable length */
599113674Smtm
600113674Smtm                Subtable->LengthField = Buffer;
601147684Sbrooks                Subtable->SizeOfLengthField = FieldLength;
60254458Sobrien            }
60351231Ssheldonh
604113674Smtm            break;
605113674Smtm        }
606113674Smtm
607113674Smtm        Buffer += FieldLength;
608113674Smtm    }
609113674Smtm
610113674Smtm    *Field = LocalField;
611113674Smtm    *RetSubtable = Subtable;
612130151Sschweikh    return (AE_OK);
61325184Sjkh
614114942SumeError:
615114942Sume    ACPI_FREE (Subtable->Buffer);
616114942Sume    ACPI_FREE (Subtable);
617114942Sume    return (Status);
618114942Sume}
619114942Sume