dtcompile.c revision 278970
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
105233250Sjkim    Event = UtBeginEvent ("Preprocess input file");
106233250Sjkim    PrDoPreprocess ();
107233250Sjkim    UtEndEvent (Event);
108233250Sjkim
109233250Sjkim    if (Gbl_PreprocessOnly)
110233250Sjkim    {
111241973Sjkim        return (AE_OK);
112233250Sjkim    }
113233250Sjkim
114208625Sjkim    /*
115208625Sjkim     * Scan the input file (file is already open) and
116208625Sjkim     * build the parse tree
117208625Sjkim     */
118208625Sjkim    Event = UtBeginEvent ("Scan and parse input file");
119208625Sjkim    FieldList = DtScanFile (Gbl_Files[ASL_FILE_INPUT].Handle);
120208625Sjkim    UtEndEvent (Event);
121208625Sjkim
122208625Sjkim    /* Did the parse tree get successfully constructed? */
123208625Sjkim
124208625Sjkim    if (!FieldList)
125208625Sjkim    {
126208625Sjkim        /* TBD: temporary error message. Msgs should come from function above */
127208625Sjkim
128208625Sjkim        DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
129209734Sjkim            "Input file does not appear to be an ASL or data table source file");
130209734Sjkim
131209734Sjkim        Status = AE_ERROR;
132209734Sjkim        goto CleanupAndExit;
133208625Sjkim    }
134208625Sjkim
135208625Sjkim    Event = UtBeginEvent ("Compile parse tree");
136208625Sjkim
137208625Sjkim    /*
138208625Sjkim     * Compile the parse tree
139208625Sjkim     */
140208625Sjkim    Status = DtCompileDataTable (&FieldList);
141208625Sjkim    UtEndEvent (Event);
142208625Sjkim
143208625Sjkim    if (ACPI_FAILURE (Status))
144208625Sjkim    {
145208625Sjkim        /* TBD: temporary error message. Msgs should come from function above */
146208625Sjkim
147208625Sjkim        DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
148208625Sjkim            "Could not compile input file");
149209734Sjkim
150208625Sjkim        goto CleanupAndExit;
151208625Sjkim    }
152208625Sjkim
153208625Sjkim    /* Create/open the binary output file */
154208625Sjkim
155208625Sjkim    Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL;
156208625Sjkim    Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
157208625Sjkim    if (ACPI_FAILURE (Status))
158208625Sjkim    {
159208625Sjkim        goto CleanupAndExit;
160208625Sjkim    }
161208625Sjkim
162208625Sjkim    /* Write the binary, then the optional hex file */
163208625Sjkim
164208625Sjkim    DtOutputBinary (Gbl_RootTable);
165245582Sjkim    HxDoHexOutput ();
166217365Sjkim    DtWriteTableToListing ();
167208625Sjkim
168208625SjkimCleanupAndExit:
169208625Sjkim
170272444Sjkim    AcpiUtDeleteCaches ();
171272444Sjkim    DtDeleteCaches ();
172208625Sjkim    CmCleanupAndExit ();
173208625Sjkim    return (Status);
174208625Sjkim}
175208625Sjkim
176208625Sjkim
177208625Sjkim/******************************************************************************
178208625Sjkim *
179208625Sjkim * FUNCTION:    DtInitialize
180208625Sjkim *
181208625Sjkim * PARAMETERS:  None
182208625Sjkim *
183212761Sjkim * RETURN:      Status
184208625Sjkim *
185208625Sjkim * DESCRIPTION: Initialize data table compiler globals. Enables multiple
186208625Sjkim *              compiles per invocation.
187208625Sjkim *
188208625Sjkim *****************************************************************************/
189208625Sjkim
190212761Sjkimstatic ACPI_STATUS
191208625SjkimDtInitialize (
192208625Sjkim    void)
193208625Sjkim{
194212761Sjkim    ACPI_STATUS             Status;
195208625Sjkim
196209734Sjkim
197212761Sjkim    Status = AcpiOsInitialize ();
198212761Sjkim    if (ACPI_FAILURE (Status))
199212761Sjkim    {
200212761Sjkim        return (Status);
201212761Sjkim    }
202212761Sjkim
203212761Sjkim    Status = AcpiUtInitGlobals ();
204212761Sjkim    if (ACPI_FAILURE (Status))
205212761Sjkim    {
206212761Sjkim        return (Status);
207212761Sjkim    }
208212761Sjkim
209208625Sjkim    Gbl_FieldList = NULL;
210208625Sjkim    Gbl_RootTable = NULL;
211208625Sjkim    Gbl_SubtableStack = NULL;
212208625Sjkim
213208625Sjkim    sprintf (VersionString, "%X", (UINT32) ACPI_CA_VERSION);
214212761Sjkim    return (AE_OK);
215208625Sjkim}
216208625Sjkim
217208625Sjkim
218208625Sjkim/******************************************************************************
219208625Sjkim *
220208625Sjkim * FUNCTION:    DtInsertCompilerIds
221208625Sjkim *
222208625Sjkim * PARAMETERS:  FieldList           - Current field list pointer
223208625Sjkim *
224208625Sjkim * RETURN:      None
225208625Sjkim *
226208625Sjkim * DESCRIPTION: Insert the IDs (Name, Version) of the current compiler into
227208625Sjkim *              the original ACPI table header.
228208625Sjkim *
229208625Sjkim *****************************************************************************/
230208625Sjkim
231208625Sjkimstatic void
232208625SjkimDtInsertCompilerIds (
233208625Sjkim    DT_FIELD                *FieldList)
234208625Sjkim{
235208625Sjkim    DT_FIELD                *Next;
236208625Sjkim    UINT32                  i;
237208625Sjkim
238208625Sjkim
239208625Sjkim    /*
240208625Sjkim     * Don't insert current compiler ID if requested. Used for compiler
241208625Sjkim     * debug/validation only.
242208625Sjkim     */
243208625Sjkim    if (Gbl_UseOriginalCompilerId)
244208625Sjkim    {
245208625Sjkim        return;
246208625Sjkim    }
247208625Sjkim
248208625Sjkim    /* Walk to the Compiler fields at the end of the header */
249208625Sjkim
250208625Sjkim    Next = FieldList;
251208625Sjkim    for (i = 0; i < 7; i++)
252208625Sjkim    {
253208625Sjkim        Next = Next->Next;
254208625Sjkim    }
255208625Sjkim
256213806Sjkim    Next->Value = ASL_CREATOR_ID;
257208625Sjkim    Next->Flags = DT_FIELD_NOT_ALLOCATED;
258208625Sjkim
259208625Sjkim    Next = Next->Next;
260208625Sjkim    Next->Value = VersionString;
261208625Sjkim    Next->Flags = DT_FIELD_NOT_ALLOCATED;
262208625Sjkim}
263208625Sjkim
264208625Sjkim
265208625Sjkim/******************************************************************************
266208625Sjkim *
267208625Sjkim * FUNCTION:    DtCompileDataTable
268208625Sjkim *
269208625Sjkim * PARAMETERS:  FieldList           - Current field list pointer
270208625Sjkim *
271208625Sjkim * RETURN:      Status
272208625Sjkim *
273208625Sjkim * DESCRIPTION: Entry point to compile one data table
274208625Sjkim *
275208625Sjkim *****************************************************************************/
276208625Sjkim
277208625Sjkimstatic ACPI_STATUS
278208625SjkimDtCompileDataTable (
279208625Sjkim    DT_FIELD                **FieldList)
280208625Sjkim{
281208625Sjkim    ACPI_DMTABLE_DATA       *TableData;
282208625Sjkim    DT_SUBTABLE             *Subtable;
283208625Sjkim    char                    *Signature;
284208625Sjkim    ACPI_TABLE_HEADER       *AcpiTableHeader;
285208625Sjkim    ACPI_STATUS             Status;
286245582Sjkim    DT_FIELD                *RootField = *FieldList;
287208625Sjkim
288208625Sjkim
289208625Sjkim    /* Verify that we at least have a table signature and save it */
290208625Sjkim
291220663Sjkim    Signature = DtGetFieldValue (*FieldList);
292208625Sjkim    if (!Signature)
293208625Sjkim    {
294209734Sjkim        sprintf (MsgBuffer, "Expected \"%s\"", "Signature");
295209734Sjkim        DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
296209734Sjkim            *FieldList, MsgBuffer);
297208625Sjkim        return (AE_ERROR);
298208625Sjkim    }
299208625Sjkim
300272444Sjkim    Gbl_Signature = UtStringCacheCalloc (ACPI_STRLEN (Signature) + 1);
301208625Sjkim    strcpy (Gbl_Signature, Signature);
302208625Sjkim
303208625Sjkim    /*
304208625Sjkim     * Handle tables that don't use the common ACPI table header structure.
305208625Sjkim     * Currently, these are the FACS and RSDP. Also check for an OEMx table,
306208625Sjkim     * these tables have user-defined contents.
307208625Sjkim     */
308208625Sjkim    if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
309208625Sjkim    {
310208625Sjkim        Status = DtCompileFacs (FieldList);
311208625Sjkim        if (ACPI_FAILURE (Status))
312208625Sjkim        {
313208625Sjkim            return (Status);
314208625Sjkim        }
315208625Sjkim
316208625Sjkim        DtSetTableLength ();
317208625Sjkim        return (Status);
318208625Sjkim    }
319254745Sjkim    else if (ACPI_VALIDATE_RSDP_SIG (Signature))
320208625Sjkim    {
321208625Sjkim        Status = DtCompileRsdp (FieldList);
322208625Sjkim        return (Status);
323208625Sjkim    }
324228110Sjkim    else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_S3PT))
325228110Sjkim    {
326228110Sjkim        Status = DtCompileS3pt (FieldList);
327228110Sjkim        if (ACPI_FAILURE (Status))
328228110Sjkim        {
329228110Sjkim            return (Status);
330228110Sjkim        }
331208625Sjkim
332228110Sjkim        DtSetTableLength ();
333228110Sjkim        return (Status);
334228110Sjkim    }
335228110Sjkim
336208625Sjkim    /*
337208625Sjkim     * All other tables must use the common ACPI table header. Insert the
338208625Sjkim     * current iASL IDs (name, version), and compile the header now.
339208625Sjkim     */
340208625Sjkim    DtInsertCompilerIds (*FieldList);
341208625Sjkim
342208625Sjkim    Status = DtCompileTable (FieldList, AcpiDmTableInfoHeader,
343208625Sjkim                &Gbl_RootTable, TRUE);
344208625Sjkim    if (ACPI_FAILURE (Status))
345208625Sjkim    {
346208625Sjkim        return (Status);
347208625Sjkim    }
348208625Sjkim
349208625Sjkim    DtPushSubtable (Gbl_RootTable);
350208625Sjkim
351220663Sjkim    /* Validate the signature via the ACPI table list */
352220663Sjkim
353220663Sjkim    TableData = AcpiDmGetTableData (Signature);
354228110Sjkim    if (!TableData || Gbl_CompileGeneric)
355220663Sjkim    {
356220663Sjkim        DtCompileGeneric ((void **) FieldList);
357245582Sjkim        goto FinishHeader;
358220663Sjkim    }
359220663Sjkim
360209734Sjkim    /* Dispatch to per-table compile */
361208625Sjkim
362208625Sjkim    if (TableData->CmTableHandler)
363208625Sjkim    {
364208625Sjkim        /* Complex table, has a handler */
365208625Sjkim
366208625Sjkim        Status = TableData->CmTableHandler ((void **) FieldList);
367208625Sjkim        if (ACPI_FAILURE (Status))
368208625Sjkim        {
369208625Sjkim            return (Status);
370208625Sjkim        }
371208625Sjkim    }
372208625Sjkim    else if (TableData->TableInfo)
373208625Sjkim    {
374208625Sjkim        /* Simple table, just walk the info table */
375208625Sjkim
376208625Sjkim        Subtable = NULL;
377208625Sjkim        Status = DtCompileTable (FieldList, TableData->TableInfo,
378208625Sjkim                    &Subtable, TRUE);
379208625Sjkim        if (ACPI_FAILURE (Status))
380208625Sjkim        {
381208625Sjkim            return (Status);
382208625Sjkim        }
383208625Sjkim
384208625Sjkim        DtInsertSubtable (Gbl_RootTable, Subtable);
385208625Sjkim        DtPopSubtable ();
386208625Sjkim    }
387208625Sjkim    else
388208625Sjkim    {
389208625Sjkim        DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList,
390208625Sjkim            "Missing table dispatch info");
391208625Sjkim        return (AE_ERROR);
392208625Sjkim    }
393208625Sjkim
394245582SjkimFinishHeader:
395245582Sjkim
396208625Sjkim    /* Set the final table length and then the checksum */
397208625Sjkim
398208625Sjkim    DtSetTableLength ();
399208625Sjkim    AcpiTableHeader = ACPI_CAST_PTR (
400208625Sjkim        ACPI_TABLE_HEADER, Gbl_RootTable->Buffer);
401208625Sjkim    DtSetTableChecksum (&AcpiTableHeader->Checksum);
402208625Sjkim
403245582Sjkim    DtDumpFieldList (RootField);
404245582Sjkim    DtDumpSubtableList ();
405208625Sjkim    return (AE_OK);
406208625Sjkim}
407208625Sjkim
408208625Sjkim
409208625Sjkim/******************************************************************************
410208625Sjkim *
411208625Sjkim * FUNCTION:    DtCompileTable
412208625Sjkim *
413208625Sjkim * PARAMETERS:  Field               - Current field list pointer
414208625Sjkim *              Info                - Info table for this ACPI table
415208625Sjkim *              RetSubtable         - Compile result of table
416208625Sjkim *              Required            - If this subtable must exist
417208625Sjkim *
418208625Sjkim * RETURN:      Status
419208625Sjkim *
420208625Sjkim * DESCRIPTION: Compile a subtable
421208625Sjkim *
422208625Sjkim *****************************************************************************/
423208625Sjkim
424208625SjkimACPI_STATUS
425208625SjkimDtCompileTable (
426208625Sjkim    DT_FIELD                **Field,
427208625Sjkim    ACPI_DMTABLE_INFO       *Info,
428208625Sjkim    DT_SUBTABLE             **RetSubtable,
429208625Sjkim    BOOLEAN                 Required)
430208625Sjkim{
431208625Sjkim    DT_FIELD                *LocalField;
432208625Sjkim    UINT32                  Length;
433208625Sjkim    DT_SUBTABLE             *Subtable;
434208625Sjkim    DT_SUBTABLE             *InlineSubtable;
435208625Sjkim    UINT32                  FieldLength = 0;
436208625Sjkim    UINT8                   FieldType;
437208625Sjkim    UINT8                   *Buffer;
438208625Sjkim    UINT8                   *FlagBuffer = NULL;
439272444Sjkim    char                    *String;
440228110Sjkim    UINT32                  CurrentFlagByteOffset = 0;
441208625Sjkim    ACPI_STATUS             Status;
442208625Sjkim
443208625Sjkim
444208625Sjkim    if (!Field || !*Field)
445208625Sjkim    {
446208625Sjkim        return (AE_BAD_PARAMETER);
447208625Sjkim    }
448208625Sjkim
449272444Sjkim    /* Ignore optional subtable if name does not match */
450272444Sjkim
451272444Sjkim    if ((Info->Flags & DT_OPTIONAL) &&
452272444Sjkim        ACPI_STRCMP ((*Field)->Name, Info->Name))
453272444Sjkim    {
454272444Sjkim        *RetSubtable = NULL;
455272444Sjkim        return (AE_OK);
456272444Sjkim    }
457272444Sjkim
458208625Sjkim    Length = DtGetSubtableLength (*Field, Info);
459220663Sjkim    if (Length == ASL_EOF)
460220663Sjkim    {
461220663Sjkim        return (AE_ERROR);
462220663Sjkim    }
463220663Sjkim
464272444Sjkim    Subtable = UtSubtableCacheCalloc ();
465208625Sjkim
466218590Sjkim    if (Length > 0)
467218590Sjkim    {
468272444Sjkim        String = UtStringCacheCalloc (Length);
469272444Sjkim        Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
470218590Sjkim    }
471272444Sjkim
472208625Sjkim    Subtable->Length = Length;
473208625Sjkim    Subtable->TotalLength = Length;
474208625Sjkim    Buffer = Subtable->Buffer;
475208625Sjkim
476208625Sjkim    LocalField = *Field;
477208625Sjkim
478208625Sjkim    /*
479208625Sjkim     * Main loop walks the info table for this ACPI table or subtable
480208625Sjkim     */
481208625Sjkim    for (; Info->Name; Info++)
482208625Sjkim    {
483228110Sjkim        if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
484228110Sjkim        {
485228110Sjkim            continue;
486228110Sjkim        }
487228110Sjkim
488208625Sjkim        if (!LocalField)
489208625Sjkim        {
490208625Sjkim            sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed",
491208625Sjkim                Info->Name);
492208625Sjkim            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
493208625Sjkim            Status = AE_BAD_DATA;
494208625Sjkim            goto Error;
495208625Sjkim        }
496208625Sjkim
497218590Sjkim        /* Maintain table offsets */
498218590Sjkim
499218590Sjkim        LocalField->TableOffset = Gbl_CurrentTableOffset;
500208625Sjkim        FieldLength = DtGetFieldLength (LocalField, Info);
501218590Sjkim        Gbl_CurrentTableOffset += FieldLength;
502218590Sjkim
503208625Sjkim        FieldType = DtGetFieldType (Info);
504208625Sjkim        Gbl_InputFieldCount++;
505208625Sjkim
506208625Sjkim        switch (FieldType)
507208625Sjkim        {
508208625Sjkim        case DT_FIELD_TYPE_FLAGS_INTEGER:
509208625Sjkim            /*
510208625Sjkim             * Start of the definition of a flags field.
511208625Sjkim             * This master flags integer starts at value zero, in preparation
512208625Sjkim             * to compile and insert the flag fields from the individual bits
513208625Sjkim             */
514208625Sjkim            LocalField = LocalField->Next;
515208625Sjkim            *Field = LocalField;
516208625Sjkim
517208625Sjkim            FlagBuffer = Buffer;
518228110Sjkim            CurrentFlagByteOffset = Info->Offset;
519208625Sjkim            break;
520208625Sjkim
521208625Sjkim        case DT_FIELD_TYPE_FLAG:
522208625Sjkim
523208625Sjkim            /* Individual Flag field, can be multiple bits */
524208625Sjkim
525208625Sjkim            if (FlagBuffer)
526208625Sjkim            {
527228110Sjkim                /*
528228110Sjkim                 * We must increment the FlagBuffer when we have crossed
529228110Sjkim                 * into the next flags byte within the flags field
530228110Sjkim                 * of type DT_FIELD_TYPE_FLAGS_INTEGER.
531228110Sjkim                 */
532228110Sjkim                FlagBuffer += (Info->Offset - CurrentFlagByteOffset);
533228110Sjkim                CurrentFlagByteOffset = Info->Offset;
534228110Sjkim
535209734Sjkim                DtCompileFlag (FlagBuffer, LocalField, Info);
536208625Sjkim            }
537208625Sjkim            else
538208625Sjkim            {
539208625Sjkim                /* TBD - this is an internal error */
540208625Sjkim            }
541208625Sjkim
542208625Sjkim            LocalField = LocalField->Next;
543208625Sjkim            *Field = LocalField;
544208625Sjkim            break;
545208625Sjkim
546208625Sjkim        case DT_FIELD_TYPE_INLINE_SUBTABLE:
547208625Sjkim            /*
548208625Sjkim             * Recursion (one level max): compile GAS (Generic Address)
549208625Sjkim             * or Notify in-line subtable
550208625Sjkim             */
551208625Sjkim            *Field = LocalField;
552208625Sjkim
553208625Sjkim            if (Info->Opcode == ACPI_DMT_GAS)
554208625Sjkim            {
555208625Sjkim                Status = DtCompileTable (Field, AcpiDmTableInfoGas,
556208625Sjkim                    &InlineSubtable, TRUE);
557208625Sjkim            }
558208625Sjkim            else
559208625Sjkim            {
560208625Sjkim                Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify,
561208625Sjkim                    &InlineSubtable, TRUE);
562208625Sjkim            }
563208625Sjkim
564208625Sjkim            if (ACPI_FAILURE (Status))
565208625Sjkim            {
566208625Sjkim                goto Error;
567208625Sjkim            }
568208625Sjkim
569209734Sjkim            DtSetSubtableLength (InlineSubtable);
570209734Sjkim
571208625Sjkim            ACPI_MEMCPY (Buffer, InlineSubtable->Buffer, FieldLength);
572208625Sjkim            LocalField = *Field;
573208625Sjkim            break;
574208625Sjkim
575218590Sjkim        case DT_FIELD_TYPE_LABEL:
576218590Sjkim
577218590Sjkim            DtWriteFieldToListing (Buffer, LocalField, 0);
578218590Sjkim            LocalField = LocalField->Next;
579218590Sjkim            break;
580218590Sjkim
581208625Sjkim        default:
582208625Sjkim
583208625Sjkim            /* Normal case for most field types (Integer, String, etc.) */
584208625Sjkim
585208625Sjkim            DtCompileOneField (Buffer, LocalField,
586208625Sjkim                FieldLength, FieldType, Info->Flags);
587217365Sjkim
588217365Sjkim            DtWriteFieldToListing (Buffer, LocalField, FieldLength);
589208625Sjkim            LocalField = LocalField->Next;
590208625Sjkim
591208625Sjkim            if (Info->Flags & DT_LENGTH)
592208625Sjkim            {
593208625Sjkim                /* Field is an Integer that will contain a subtable length */
594208625Sjkim
595208625Sjkim                Subtable->LengthField = Buffer;
596208625Sjkim                Subtable->SizeOfLengthField = FieldLength;
597208625Sjkim            }
598217365Sjkim
599208625Sjkim            break;
600208625Sjkim        }
601208625Sjkim
602208625Sjkim        Buffer += FieldLength;
603208625Sjkim    }
604208625Sjkim
605208625Sjkim    *Field = LocalField;
606208625Sjkim    *RetSubtable = Subtable;
607208625Sjkim    return (AE_OK);
608208625Sjkim
609208625SjkimError:
610208625Sjkim    ACPI_FREE (Subtable->Buffer);
611208625Sjkim    ACPI_FREE (Subtable);
612208625Sjkim    return (Status);
613208625Sjkim}
614