dtcompile.c revision 254745
1208625Sjkim/******************************************************************************
2208625Sjkim *
3208625Sjkim * Module Name: dtcompile.c - Front-end for data table compiler
4208625Sjkim *
5208625Sjkim *****************************************************************************/
6208625Sjkim
7217365Sjkim/*
8245582Sjkim * Copyright (C) 2000 - 2013, 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 __DTCOMPILE_C__
45208625Sjkim#define _DECLARE_DT_GLOBALS
46208625Sjkim
47209746Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
48209746Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h>
49208625Sjkim
50208625Sjkim#define _COMPONENT          DT_COMPILER
51208625Sjkim        ACPI_MODULE_NAME    ("dtcompile")
52208625Sjkim
53208625Sjkimstatic char                 VersionString[9];
54208625Sjkim
55208625Sjkim
56208625Sjkim/* Local prototypes */
57208625Sjkim
58212761Sjkimstatic ACPI_STATUS
59208625SjkimDtInitialize (
60208625Sjkim    void);
61208625Sjkim
62208625Sjkimstatic ACPI_STATUS
63208625SjkimDtCompileDataTable (
64208625Sjkim    DT_FIELD                **Field);
65208625Sjkim
66208625Sjkimstatic void
67208625SjkimDtInsertCompilerIds (
68208625Sjkim    DT_FIELD                *FieldList);
69208625Sjkim
70208625Sjkim
71208625Sjkim/******************************************************************************
72208625Sjkim *
73208625Sjkim * FUNCTION:    DtDoCompile
74208625Sjkim *
75208625Sjkim * PARAMETERS:  None
76208625Sjkim *
77208625Sjkim * RETURN:      Status
78208625Sjkim *
79208625Sjkim * DESCRIPTION: Main entry point for the data table compiler.
80208625Sjkim *
81208625Sjkim * Note: Assumes Gbl_Files[ASL_FILE_INPUT] is initialized and the file is
82208625Sjkim *          open at seek offset zero.
83208625Sjkim *
84208625Sjkim *****************************************************************************/
85208625Sjkim
86208625SjkimACPI_STATUS
87208625SjkimDtDoCompile (
88208625Sjkim    void)
89208625Sjkim{
90208625Sjkim    ACPI_STATUS             Status;
91208625Sjkim    UINT8                   Event;
92208625Sjkim    DT_FIELD                *FieldList;
93208625Sjkim
94208625Sjkim
95208625Sjkim    /* Initialize globals */
96208625Sjkim
97212761Sjkim    Status = DtInitialize ();
98212761Sjkim    if (ACPI_FAILURE (Status))
99212761Sjkim    {
100212761Sjkim        printf ("Error during compiler initialization, 0x%X\n", Status);
101212761Sjkim        return (Status);
102212761Sjkim    }
103208625Sjkim
104233250Sjkim    /* Preprocessor */
105233250Sjkim
106233250Sjkim    Event = UtBeginEvent ("Preprocess input file");
107233250Sjkim    PrDoPreprocess ();
108233250Sjkim    UtEndEvent (Event);
109233250Sjkim
110233250Sjkim    if (Gbl_PreprocessOnly)
111233250Sjkim    {
112241973Sjkim        return (AE_OK);
113233250Sjkim    }
114233250Sjkim
115208625Sjkim    /*
116208625Sjkim     * Scan the input file (file is already open) and
117208625Sjkim     * build the parse tree
118208625Sjkim     */
119208625Sjkim    Event = UtBeginEvent ("Scan and parse input file");
120208625Sjkim    FieldList = DtScanFile (Gbl_Files[ASL_FILE_INPUT].Handle);
121208625Sjkim    UtEndEvent (Event);
122208625Sjkim
123208625Sjkim    /* Did the parse tree get successfully constructed? */
124208625Sjkim
125208625Sjkim    if (!FieldList)
126208625Sjkim    {
127208625Sjkim        /* TBD: temporary error message. Msgs should come from function above */
128208625Sjkim
129208625Sjkim        DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
130209734Sjkim            "Input file does not appear to be an ASL or data table source file");
131209734Sjkim
132209734Sjkim        Status = AE_ERROR;
133209734Sjkim        goto CleanupAndExit;
134208625Sjkim    }
135208625Sjkim
136208625Sjkim    Event = UtBeginEvent ("Compile parse tree");
137208625Sjkim
138208625Sjkim    /*
139208625Sjkim     * Compile the parse tree
140208625Sjkim     */
141208625Sjkim    Status = DtCompileDataTable (&FieldList);
142208625Sjkim    UtEndEvent (Event);
143208625Sjkim
144208625Sjkim    DtFreeFieldList ();
145208625Sjkim
146208625Sjkim    if (ACPI_FAILURE (Status))
147208625Sjkim    {
148208625Sjkim        /* TBD: temporary error message. Msgs should come from function above */
149208625Sjkim
150208625Sjkim        DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
151208625Sjkim            "Could not compile input file");
152209734Sjkim
153208625Sjkim        goto CleanupAndExit;
154208625Sjkim    }
155208625Sjkim
156208625Sjkim    /* Create/open the binary output file */
157208625Sjkim
158208625Sjkim    Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL;
159208625Sjkim    Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
160208625Sjkim    if (ACPI_FAILURE (Status))
161208625Sjkim    {
162208625Sjkim        goto CleanupAndExit;
163208625Sjkim    }
164208625Sjkim
165208625Sjkim    /* Write the binary, then the optional hex file */
166208625Sjkim
167208625Sjkim    DtOutputBinary (Gbl_RootTable);
168245582Sjkim    HxDoHexOutput ();
169217365Sjkim    DtWriteTableToListing ();
170208625Sjkim
171208625SjkimCleanupAndExit:
172208625Sjkim
173208625Sjkim    CmCleanupAndExit ();
174208625Sjkim    return (Status);
175208625Sjkim}
176208625Sjkim
177208625Sjkim
178208625Sjkim/******************************************************************************
179208625Sjkim *
180208625Sjkim * FUNCTION:    DtInitialize
181208625Sjkim *
182208625Sjkim * PARAMETERS:  None
183208625Sjkim *
184212761Sjkim * RETURN:      Status
185208625Sjkim *
186208625Sjkim * DESCRIPTION: Initialize data table compiler globals. Enables multiple
187208625Sjkim *              compiles per invocation.
188208625Sjkim *
189208625Sjkim *****************************************************************************/
190208625Sjkim
191212761Sjkimstatic ACPI_STATUS
192208625SjkimDtInitialize (
193208625Sjkim    void)
194208625Sjkim{
195212761Sjkim    ACPI_STATUS             Status;
196208625Sjkim
197209734Sjkim
198212761Sjkim    Status = AcpiOsInitialize ();
199212761Sjkim    if (ACPI_FAILURE (Status))
200212761Sjkim    {
201212761Sjkim        return (Status);
202212761Sjkim    }
203212761Sjkim
204212761Sjkim    Status = AcpiUtInitGlobals ();
205212761Sjkim    if (ACPI_FAILURE (Status))
206212761Sjkim    {
207212761Sjkim        return (Status);
208212761Sjkim    }
209212761Sjkim
210208625Sjkim    Gbl_FieldList = NULL;
211208625Sjkim    Gbl_RootTable = NULL;
212208625Sjkim    Gbl_SubtableStack = NULL;
213208625Sjkim
214208625Sjkim    sprintf (VersionString, "%X", (UINT32) ACPI_CA_VERSION);
215212761Sjkim    return (AE_OK);
216208625Sjkim}
217208625Sjkim
218208625Sjkim
219208625Sjkim/******************************************************************************
220208625Sjkim *
221208625Sjkim * FUNCTION:    DtInsertCompilerIds
222208625Sjkim *
223208625Sjkim * PARAMETERS:  FieldList           - Current field list pointer
224208625Sjkim *
225208625Sjkim * RETURN:      None
226208625Sjkim *
227208625Sjkim * DESCRIPTION: Insert the IDs (Name, Version) of the current compiler into
228208625Sjkim *              the original ACPI table header.
229208625Sjkim *
230208625Sjkim *****************************************************************************/
231208625Sjkim
232208625Sjkimstatic void
233208625SjkimDtInsertCompilerIds (
234208625Sjkim    DT_FIELD                *FieldList)
235208625Sjkim{
236208625Sjkim    DT_FIELD                *Next;
237208625Sjkim    UINT32                  i;
238208625Sjkim
239208625Sjkim
240208625Sjkim    /*
241208625Sjkim     * Don't insert current compiler ID if requested. Used for compiler
242208625Sjkim     * debug/validation only.
243208625Sjkim     */
244208625Sjkim    if (Gbl_UseOriginalCompilerId)
245208625Sjkim    {
246208625Sjkim        return;
247208625Sjkim    }
248208625Sjkim
249208625Sjkim    /* Walk to the Compiler fields at the end of the header */
250208625Sjkim
251208625Sjkim    Next = FieldList;
252208625Sjkim    for (i = 0; i < 7; i++)
253208625Sjkim    {
254208625Sjkim        Next = Next->Next;
255208625Sjkim    }
256208625Sjkim
257213806Sjkim    Next->Value = ASL_CREATOR_ID;
258208625Sjkim    Next->Flags = DT_FIELD_NOT_ALLOCATED;
259208625Sjkim
260208625Sjkim    Next = Next->Next;
261208625Sjkim    Next->Value = VersionString;
262208625Sjkim    Next->Flags = DT_FIELD_NOT_ALLOCATED;
263208625Sjkim}
264208625Sjkim
265208625Sjkim
266208625Sjkim/******************************************************************************
267208625Sjkim *
268208625Sjkim * FUNCTION:    DtCompileDataTable
269208625Sjkim *
270208625Sjkim * PARAMETERS:  FieldList           - Current field list pointer
271208625Sjkim *
272208625Sjkim * RETURN:      Status
273208625Sjkim *
274208625Sjkim * DESCRIPTION: Entry point to compile one data table
275208625Sjkim *
276208625Sjkim *****************************************************************************/
277208625Sjkim
278208625Sjkimstatic ACPI_STATUS
279208625SjkimDtCompileDataTable (
280208625Sjkim    DT_FIELD                **FieldList)
281208625Sjkim{
282208625Sjkim    ACPI_DMTABLE_DATA       *TableData;
283208625Sjkim    DT_SUBTABLE             *Subtable;
284208625Sjkim    char                    *Signature;
285208625Sjkim    ACPI_TABLE_HEADER       *AcpiTableHeader;
286208625Sjkim    ACPI_STATUS             Status;
287245582Sjkim    DT_FIELD                *RootField = *FieldList;
288208625Sjkim
289208625Sjkim
290208625Sjkim    /* Verify that we at least have a table signature and save it */
291208625Sjkim
292220663Sjkim    Signature = DtGetFieldValue (*FieldList);
293208625Sjkim    if (!Signature)
294208625Sjkim    {
295209734Sjkim        sprintf (MsgBuffer, "Expected \"%s\"", "Signature");
296209734Sjkim        DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
297209734Sjkim            *FieldList, MsgBuffer);
298208625Sjkim        return (AE_ERROR);
299208625Sjkim    }
300208625Sjkim
301208625Sjkim    Gbl_Signature = UtLocalCalloc (ACPI_STRLEN (Signature) + 1);
302208625Sjkim    strcpy (Gbl_Signature, Signature);
303208625Sjkim
304208625Sjkim    /*
305208625Sjkim     * Handle tables that don't use the common ACPI table header structure.
306208625Sjkim     * Currently, these are the FACS and RSDP. Also check for an OEMx table,
307208625Sjkim     * these tables have user-defined contents.
308208625Sjkim     */
309208625Sjkim    if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
310208625Sjkim    {
311208625Sjkim        Status = DtCompileFacs (FieldList);
312208625Sjkim        if (ACPI_FAILURE (Status))
313208625Sjkim        {
314208625Sjkim            return (Status);
315208625Sjkim        }
316208625Sjkim
317208625Sjkim        DtSetTableLength ();
318208625Sjkim        return (Status);
319208625Sjkim    }
320254745Sjkim    else if (ACPI_VALIDATE_RSDP_SIG (Signature))
321208625Sjkim    {
322208625Sjkim        Status = DtCompileRsdp (FieldList);
323208625Sjkim        return (Status);
324208625Sjkim    }
325228110Sjkim    else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_S3PT))
326228110Sjkim    {
327228110Sjkim        Status = DtCompileS3pt (FieldList);
328228110Sjkim        if (ACPI_FAILURE (Status))
329228110Sjkim        {
330228110Sjkim            return (Status);
331228110Sjkim        }
332208625Sjkim
333228110Sjkim        DtSetTableLength ();
334228110Sjkim        return (Status);
335228110Sjkim    }
336228110Sjkim
337208625Sjkim    /*
338208625Sjkim     * All other tables must use the common ACPI table header. Insert the
339208625Sjkim     * current iASL IDs (name, version), and compile the header now.
340208625Sjkim     */
341208625Sjkim    DtInsertCompilerIds (*FieldList);
342208625Sjkim
343208625Sjkim    Status = DtCompileTable (FieldList, AcpiDmTableInfoHeader,
344208625Sjkim                &Gbl_RootTable, TRUE);
345208625Sjkim    if (ACPI_FAILURE (Status))
346208625Sjkim    {
347208625Sjkim        return (Status);
348208625Sjkim    }
349208625Sjkim
350208625Sjkim    DtPushSubtable (Gbl_RootTable);
351208625Sjkim
352220663Sjkim    /* Validate the signature via the ACPI table list */
353220663Sjkim
354220663Sjkim    TableData = AcpiDmGetTableData (Signature);
355228110Sjkim    if (!TableData || Gbl_CompileGeneric)
356220663Sjkim    {
357220663Sjkim        DtCompileGeneric ((void **) FieldList);
358245582Sjkim        goto FinishHeader;
359220663Sjkim    }
360220663Sjkim
361209734Sjkim    /* Dispatch to per-table compile */
362208625Sjkim
363208625Sjkim    if (TableData->CmTableHandler)
364208625Sjkim    {
365208625Sjkim        /* Complex table, has a handler */
366208625Sjkim
367208625Sjkim        Status = TableData->CmTableHandler ((void **) FieldList);
368208625Sjkim        if (ACPI_FAILURE (Status))
369208625Sjkim        {
370208625Sjkim            return (Status);
371208625Sjkim        }
372208625Sjkim    }
373208625Sjkim    else if (TableData->TableInfo)
374208625Sjkim    {
375208625Sjkim        /* Simple table, just walk the info table */
376208625Sjkim
377208625Sjkim        Subtable = NULL;
378208625Sjkim        Status = DtCompileTable (FieldList, TableData->TableInfo,
379208625Sjkim                    &Subtable, TRUE);
380208625Sjkim        if (ACPI_FAILURE (Status))
381208625Sjkim        {
382208625Sjkim            return (Status);
383208625Sjkim        }
384208625Sjkim
385208625Sjkim        DtInsertSubtable (Gbl_RootTable, Subtable);
386208625Sjkim        DtPopSubtable ();
387208625Sjkim    }
388208625Sjkim    else
389208625Sjkim    {
390208625Sjkim        DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList,
391208625Sjkim            "Missing table dispatch info");
392208625Sjkim        return (AE_ERROR);
393208625Sjkim    }
394208625Sjkim
395245582SjkimFinishHeader:
396245582Sjkim
397208625Sjkim    /* Set the final table length and then the checksum */
398208625Sjkim
399208625Sjkim    DtSetTableLength ();
400208625Sjkim    AcpiTableHeader = ACPI_CAST_PTR (
401208625Sjkim        ACPI_TABLE_HEADER, Gbl_RootTable->Buffer);
402208625Sjkim    DtSetTableChecksum (&AcpiTableHeader->Checksum);
403208625Sjkim
404245582Sjkim    DtDumpFieldList (RootField);
405245582Sjkim    DtDumpSubtableList ();
406208625Sjkim    return (AE_OK);
407208625Sjkim}
408208625Sjkim
409208625Sjkim
410208625Sjkim/******************************************************************************
411208625Sjkim *
412208625Sjkim * FUNCTION:    DtCompileTable
413208625Sjkim *
414208625Sjkim * PARAMETERS:  Field               - Current field list pointer
415208625Sjkim *              Info                - Info table for this ACPI table
416208625Sjkim *              RetSubtable         - Compile result of table
417208625Sjkim *              Required            - If this subtable must exist
418208625Sjkim *
419208625Sjkim * RETURN:      Status
420208625Sjkim *
421208625Sjkim * DESCRIPTION: Compile a subtable
422208625Sjkim *
423208625Sjkim *****************************************************************************/
424208625Sjkim
425208625SjkimACPI_STATUS
426208625SjkimDtCompileTable (
427208625Sjkim    DT_FIELD                **Field,
428208625Sjkim    ACPI_DMTABLE_INFO       *Info,
429208625Sjkim    DT_SUBTABLE             **RetSubtable,
430208625Sjkim    BOOLEAN                 Required)
431208625Sjkim{
432208625Sjkim    DT_FIELD                *LocalField;
433208625Sjkim    UINT32                  Length;
434208625Sjkim    DT_SUBTABLE             *Subtable;
435208625Sjkim    DT_SUBTABLE             *InlineSubtable;
436208625Sjkim    UINT32                  FieldLength = 0;
437208625Sjkim    UINT8                   FieldType;
438208625Sjkim    UINT8                   *Buffer;
439208625Sjkim    UINT8                   *FlagBuffer = NULL;
440228110Sjkim    UINT32                  CurrentFlagByteOffset = 0;
441208625Sjkim    ACPI_STATUS             Status;
442208625Sjkim
443208625Sjkim
444208625Sjkim    if (!Field || !*Field)
445208625Sjkim    {
446208625Sjkim        return (AE_BAD_PARAMETER);
447208625Sjkim    }
448208625Sjkim
449208625Sjkim    Length = DtGetSubtableLength (*Field, Info);
450220663Sjkim    if (Length == ASL_EOF)
451220663Sjkim    {
452220663Sjkim        return (AE_ERROR);
453220663Sjkim    }
454220663Sjkim
455208625Sjkim    Subtable = UtLocalCalloc (sizeof (DT_SUBTABLE));
456208625Sjkim
457218590Sjkim    if (Length > 0)
458218590Sjkim    {
459218590Sjkim        Subtable->Buffer = UtLocalCalloc (Length);
460218590Sjkim    }
461208625Sjkim    Subtable->Length = Length;
462208625Sjkim    Subtable->TotalLength = Length;
463208625Sjkim    Buffer = Subtable->Buffer;
464208625Sjkim
465208625Sjkim    LocalField = *Field;
466208625Sjkim
467208625Sjkim    /*
468208625Sjkim     * Main loop walks the info table for this ACPI table or subtable
469208625Sjkim     */
470208625Sjkim    for (; Info->Name; Info++)
471208625Sjkim    {
472228110Sjkim        if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
473228110Sjkim        {
474228110Sjkim            continue;
475228110Sjkim        }
476228110Sjkim
477208625Sjkim        if (!LocalField)
478208625Sjkim        {
479208625Sjkim            sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed",
480208625Sjkim                Info->Name);
481208625Sjkim            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
482208625Sjkim            Status = AE_BAD_DATA;
483208625Sjkim            goto Error;
484208625Sjkim        }
485208625Sjkim
486218590Sjkim        /* Maintain table offsets */
487218590Sjkim
488218590Sjkim        LocalField->TableOffset = Gbl_CurrentTableOffset;
489208625Sjkim        FieldLength = DtGetFieldLength (LocalField, Info);
490218590Sjkim        Gbl_CurrentTableOffset += FieldLength;
491218590Sjkim
492208625Sjkim        FieldType = DtGetFieldType (Info);
493208625Sjkim        Gbl_InputFieldCount++;
494208625Sjkim
495208625Sjkim        switch (FieldType)
496208625Sjkim        {
497208625Sjkim        case DT_FIELD_TYPE_FLAGS_INTEGER:
498208625Sjkim            /*
499208625Sjkim             * Start of the definition of a flags field.
500208625Sjkim             * This master flags integer starts at value zero, in preparation
501208625Sjkim             * to compile and insert the flag fields from the individual bits
502208625Sjkim             */
503208625Sjkim            LocalField = LocalField->Next;
504208625Sjkim            *Field = LocalField;
505208625Sjkim
506208625Sjkim            FlagBuffer = Buffer;
507228110Sjkim            CurrentFlagByteOffset = Info->Offset;
508208625Sjkim            break;
509208625Sjkim
510208625Sjkim        case DT_FIELD_TYPE_FLAG:
511208625Sjkim
512208625Sjkim            /* Individual Flag field, can be multiple bits */
513208625Sjkim
514208625Sjkim            if (FlagBuffer)
515208625Sjkim            {
516228110Sjkim                /*
517228110Sjkim                 * We must increment the FlagBuffer when we have crossed
518228110Sjkim                 * into the next flags byte within the flags field
519228110Sjkim                 * of type DT_FIELD_TYPE_FLAGS_INTEGER.
520228110Sjkim                 */
521228110Sjkim                FlagBuffer += (Info->Offset - CurrentFlagByteOffset);
522228110Sjkim                CurrentFlagByteOffset = Info->Offset;
523228110Sjkim
524209734Sjkim                DtCompileFlag (FlagBuffer, LocalField, Info);
525208625Sjkim            }
526208625Sjkim            else
527208625Sjkim            {
528208625Sjkim                /* TBD - this is an internal error */
529208625Sjkim            }
530208625Sjkim
531208625Sjkim            LocalField = LocalField->Next;
532208625Sjkim            *Field = LocalField;
533208625Sjkim            break;
534208625Sjkim
535208625Sjkim        case DT_FIELD_TYPE_INLINE_SUBTABLE:
536208625Sjkim            /*
537208625Sjkim             * Recursion (one level max): compile GAS (Generic Address)
538208625Sjkim             * or Notify in-line subtable
539208625Sjkim             */
540208625Sjkim            *Field = LocalField;
541208625Sjkim
542208625Sjkim            if (Info->Opcode == ACPI_DMT_GAS)
543208625Sjkim            {
544208625Sjkim                Status = DtCompileTable (Field, AcpiDmTableInfoGas,
545208625Sjkim                    &InlineSubtable, TRUE);
546208625Sjkim            }
547208625Sjkim            else
548208625Sjkim            {
549208625Sjkim                Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify,
550208625Sjkim                    &InlineSubtable, TRUE);
551208625Sjkim            }
552208625Sjkim
553208625Sjkim            if (ACPI_FAILURE (Status))
554208625Sjkim            {
555208625Sjkim                goto Error;
556208625Sjkim            }
557208625Sjkim
558209734Sjkim            DtSetSubtableLength (InlineSubtable);
559209734Sjkim
560208625Sjkim            ACPI_MEMCPY (Buffer, InlineSubtable->Buffer, FieldLength);
561208625Sjkim            ACPI_FREE (InlineSubtable->Buffer);
562208625Sjkim            ACPI_FREE (InlineSubtable);
563208625Sjkim            LocalField = *Field;
564208625Sjkim            break;
565208625Sjkim
566218590Sjkim        case DT_FIELD_TYPE_LABEL:
567218590Sjkim
568218590Sjkim            DtWriteFieldToListing (Buffer, LocalField, 0);
569218590Sjkim            LocalField = LocalField->Next;
570218590Sjkim            break;
571218590Sjkim
572208625Sjkim        default:
573208625Sjkim
574208625Sjkim            /* Normal case for most field types (Integer, String, etc.) */
575208625Sjkim
576208625Sjkim            DtCompileOneField (Buffer, LocalField,
577208625Sjkim                FieldLength, FieldType, Info->Flags);
578217365Sjkim
579217365Sjkim            DtWriteFieldToListing (Buffer, LocalField, FieldLength);
580208625Sjkim            LocalField = LocalField->Next;
581208625Sjkim
582208625Sjkim            if (Info->Flags & DT_LENGTH)
583208625Sjkim            {
584208625Sjkim                /* Field is an Integer that will contain a subtable length */
585208625Sjkim
586208625Sjkim                Subtable->LengthField = Buffer;
587208625Sjkim                Subtable->SizeOfLengthField = FieldLength;
588208625Sjkim            }
589217365Sjkim
590208625Sjkim            break;
591208625Sjkim        }
592208625Sjkim
593208625Sjkim        Buffer += FieldLength;
594208625Sjkim    }
595208625Sjkim
596208625Sjkim    *Field = LocalField;
597208625Sjkim    *RetSubtable = Subtable;
598208625Sjkim    return (AE_OK);
599208625Sjkim
600208625SjkimError:
601208625Sjkim    ACPI_FREE (Subtable->Buffer);
602208625Sjkim    ACPI_FREE (Subtable);
603208625Sjkim    return (Status);
604208625Sjkim}
605