dtcompile.c revision 229989
1178825Sdfr/******************************************************************************
2233294Sstas *
3233294Sstas * Module Name: dtcompile.c - Front-end for data table compiler
4233294Sstas *
5178825Sdfr *****************************************************************************/
6233294Sstas
7233294Sstas/*
8233294Sstas * Copyright (C) 2000 - 2012, Intel Corp.
9178825Sdfr * All rights reserved.
10233294Sstas *
11233294Sstas * Redistribution and use in source and binary forms, with or without
12178825Sdfr * modification, are permitted provided that the following conditions
13233294Sstas * are met:
14233294Sstas * 1. Redistributions of source code must retain the above copyright
15233294Sstas *    notice, this list of conditions, and the following disclaimer,
16178825Sdfr *    without modification.
17233294Sstas * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18233294Sstas *    substantially similar to the "NO WARRANTY" disclaimer below
19233294Sstas *    ("Disclaimer") and any redistribution must be conditioned upon
20178825Sdfr *    including a substantially similar Disclaimer requirement for further
21233294Sstas *    binary redistribution.
22233294Sstas * 3. Neither the names of the above-listed copyright holders nor the names
23233294Sstas *    of any contributors may be used to endorse or promote products derived
24233294Sstas *    from this software without specific prior written permission.
25233294Sstas *
26233294Sstas * Alternatively, this software may be distributed under the terms of the
27233294Sstas * GNU General Public License ("GPL") version 2 as published by the Free
28233294Sstas * Software Foundation.
29233294Sstas *
30233294Sstas * NO WARRANTY
31233294Sstas * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32178825Sdfr * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33178825Sdfr * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34178825Sdfr * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35178825Sdfr * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36178825Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37178825Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38178825Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39178825Sdfr * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40233294Sstas * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41178825Sdfr * POSSIBILITY OF SUCH DAMAGES.
42178825Sdfr */
43178825Sdfr
44178825Sdfr#define __DTCOMPILE_C__
45178825Sdfr#define _DECLARE_DT_GLOBALS
46178825Sdfr
47178825Sdfr#include <contrib/dev/acpica/compiler/aslcompiler.h>
48178825Sdfr#include <contrib/dev/acpica/compiler/dtcompiler.h>
49178825Sdfr
50178825Sdfr#define _COMPONENT          DT_COMPILER
51178825Sdfr        ACPI_MODULE_NAME    ("dtcompile")
52178825Sdfr
53178825Sdfrstatic char                 VersionString[9];
54178825Sdfr
55178825Sdfr
56178825Sdfr/* Local prototypes */
57178825Sdfr
58178825Sdfrstatic ACPI_STATUS
59178825SdfrDtInitialize (
60178825Sdfr    void);
61178825Sdfr
62178825Sdfrstatic ACPI_STATUS
63178825SdfrDtCompileDataTable (
64178825Sdfr    DT_FIELD                **Field);
65178825Sdfr
66178825Sdfrstatic void
67233294SstasDtInsertCompilerIds (
68178825Sdfr    DT_FIELD                *FieldList);
69178825Sdfr
70178825Sdfr
71178825Sdfr/******************************************************************************
72178825Sdfr *
73178825Sdfr * FUNCTION:    DtDoCompile
74178825Sdfr *
75178825Sdfr * PARAMETERS:  None
76178825Sdfr *
77178825Sdfr * RETURN:      Status
78178825Sdfr *
79178825Sdfr * DESCRIPTION: Main entry point for the data table compiler.
80178825Sdfr *
81233294Sstas * Note: Assumes Gbl_Files[ASL_FILE_INPUT] is initialized and the file is
82233294Sstas *          open at seek offset zero.
83178825Sdfr *
84178825Sdfr *****************************************************************************/
85178825Sdfr
86178825SdfrACPI_STATUS
87178825SdfrDtDoCompile (
88178825Sdfr    void)
89178825Sdfr{
90178825Sdfr    ACPI_STATUS             Status;
91178825Sdfr    UINT8                   Event;
92178825Sdfr    DT_FIELD                *FieldList;
93178825Sdfr
94178825Sdfr
95178825Sdfr    /* Initialize globals */
96178825Sdfr
97178825Sdfr    Status = DtInitialize ();
98178825Sdfr    if (ACPI_FAILURE (Status))
99178825Sdfr    {
100178825Sdfr        printf ("Error during compiler initialization, 0x%X\n", Status);
101178825Sdfr        return (Status);
102178825Sdfr    }
103178825Sdfr
104178825Sdfr    /*
105178825Sdfr     * Scan the input file (file is already open) and
106178825Sdfr     * build the parse tree
107233294Sstas     */
108178825Sdfr    Event = UtBeginEvent ("Scan and parse input file");
109233294Sstas    FieldList = DtScanFile (Gbl_Files[ASL_FILE_INPUT].Handle);
110178825Sdfr    UtEndEvent (Event);
111178825Sdfr
112178825Sdfr    /* Did the parse tree get successfully constructed? */
113178825Sdfr
114178825Sdfr    if (!FieldList)
115178825Sdfr    {
116233294Sstas        /* TBD: temporary error message. Msgs should come from function above */
117178825Sdfr
118178825Sdfr        DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
119233294Sstas            "Input file does not appear to be an ASL or data table source file");
120178825Sdfr
121178825Sdfr        Status = AE_ERROR;
122178825Sdfr        goto CleanupAndExit;
123178825Sdfr    }
124178825Sdfr
125178825Sdfr    Event = UtBeginEvent ("Compile parse tree");
126233294Sstas
127233294Sstas    /*
128233294Sstas     * Compile the parse tree
129178825Sdfr     */
130233294Sstas    Status = DtCompileDataTable (&FieldList);
131233294Sstas    UtEndEvent (Event);
132178825Sdfr
133178825Sdfr    DtFreeFieldList ();
134178825Sdfr
135178825Sdfr    if (ACPI_FAILURE (Status))
136178825Sdfr    {
137178825Sdfr        /* TBD: temporary error message. Msgs should come from function above */
138178825Sdfr
139178825Sdfr        DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
140178825Sdfr            "Could not compile input file");
141178825Sdfr
142178825Sdfr        goto CleanupAndExit;
143178825Sdfr    }
144178825Sdfr
145178825Sdfr    /* Create/open the binary output file */
146178825Sdfr
147178825Sdfr    Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL;
148178825Sdfr    Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
149178825Sdfr    if (ACPI_FAILURE (Status))
150178825Sdfr    {
151178825Sdfr        goto CleanupAndExit;
152178825Sdfr    }
153178825Sdfr
154178825Sdfr    /* Write the binary, then the optional hex file */
155178825Sdfr
156178825Sdfr    DtOutputBinary (Gbl_RootTable);
157233294Sstas    LsDoHexOutput ();
158178825Sdfr    DtWriteTableToListing ();
159178825Sdfr
160178825SdfrCleanupAndExit:
161178825Sdfr
162178825Sdfr    CmCleanupAndExit ();
163178825Sdfr    return (Status);
164178825Sdfr}
165178825Sdfr
166178825Sdfr
167178825Sdfr/******************************************************************************
168178825Sdfr *
169178825Sdfr * FUNCTION:    DtInitialize
170178825Sdfr *
171178825Sdfr * PARAMETERS:  None
172178825Sdfr *
173233294Sstas * RETURN:      Status
174178825Sdfr *
175178825Sdfr * DESCRIPTION: Initialize data table compiler globals. Enables multiple
176178825Sdfr *              compiles per invocation.
177178825Sdfr *
178178825Sdfr *****************************************************************************/
179178825Sdfr
180178825Sdfrstatic ACPI_STATUS
181178825SdfrDtInitialize (
182178825Sdfr    void)
183178825Sdfr{
184178825Sdfr    ACPI_STATUS             Status;
185178825Sdfr
186178825Sdfr
187178825Sdfr    Status = AcpiOsInitialize ();
188178825Sdfr    if (ACPI_FAILURE (Status))
189178825Sdfr    {
190233294Sstas        return (Status);
191178825Sdfr    }
192233294Sstas
193233294Sstas    Status = AcpiUtInitGlobals ();
194178825Sdfr    if (ACPI_FAILURE (Status))
195178825Sdfr    {
196178825Sdfr        return (Status);
197178825Sdfr    }
198178825Sdfr
199233294Sstas    Gbl_FieldList = NULL;
200233294Sstas    Gbl_RootTable = NULL;
201178825Sdfr    Gbl_SubtableStack = NULL;
202178825Sdfr
203178825Sdfr    sprintf (VersionString, "%X", (UINT32) ACPI_CA_VERSION);
204178825Sdfr    return (AE_OK);
205178825Sdfr}
206233294Sstas
207178825Sdfr
208178825Sdfr/******************************************************************************
209178825Sdfr *
210178825Sdfr * FUNCTION:    DtInsertCompilerIds
211178825Sdfr *
212178825Sdfr * PARAMETERS:  FieldList           - Current field list pointer
213233294Sstas *
214233294Sstas * RETURN:      None
215178825Sdfr *
216233294Sstas * DESCRIPTION: Insert the IDs (Name, Version) of the current compiler into
217178825Sdfr *              the original ACPI table header.
218178825Sdfr *
219178825Sdfr *****************************************************************************/
220178825Sdfr
221178825Sdfrstatic void
222178825SdfrDtInsertCompilerIds (
223178825Sdfr    DT_FIELD                *FieldList)
224178825Sdfr{
225178825Sdfr    DT_FIELD                *Next;
226178825Sdfr    UINT32                  i;
227178825Sdfr
228178825Sdfr
229178825Sdfr    /*
230178825Sdfr     * Don't insert current compiler ID if requested. Used for compiler
231178825Sdfr     * debug/validation only.
232178825Sdfr     */
233178825Sdfr    if (Gbl_UseOriginalCompilerId)
234178825Sdfr    {
235178825Sdfr        return;
236178825Sdfr    }
237178825Sdfr
238233294Sstas    /* Walk to the Compiler fields at the end of the header */
239233294Sstas
240178825Sdfr    Next = FieldList;
241178825Sdfr    for (i = 0; i < 7; i++)
242178825Sdfr    {
243178825Sdfr        Next = Next->Next;
244178825Sdfr    }
245233294Sstas
246233294Sstas    Next->Value = ASL_CREATOR_ID;
247233294Sstas    Next->Flags = DT_FIELD_NOT_ALLOCATED;
248178825Sdfr
249178825Sdfr    Next = Next->Next;
250233294Sstas    Next->Value = VersionString;
251178825Sdfr    Next->Flags = DT_FIELD_NOT_ALLOCATED;
252178825Sdfr}
253178825Sdfr
254178825Sdfr
255178825Sdfr/******************************************************************************
256178825Sdfr *
257178825Sdfr * FUNCTION:    DtCompileDataTable
258233294Sstas *
259178825Sdfr * PARAMETERS:  FieldList           - Current field list pointer
260178825Sdfr *
261178825Sdfr * RETURN:      Status
262178825Sdfr *
263178825Sdfr * DESCRIPTION: Entry point to compile one data table
264178825Sdfr *
265178825Sdfr *****************************************************************************/
266178825Sdfr
267233294Sstasstatic ACPI_STATUS
268233294SstasDtCompileDataTable (
269178825Sdfr    DT_FIELD                **FieldList)
270178825Sdfr{
271178825Sdfr    ACPI_DMTABLE_DATA       *TableData;
272178825Sdfr    DT_SUBTABLE             *Subtable;
273178825Sdfr    char                    *Signature;
274178825Sdfr    ACPI_TABLE_HEADER       *AcpiTableHeader;
275178825Sdfr    ACPI_STATUS             Status;
276178825Sdfr
277178825Sdfr
278178825Sdfr    /* Verify that we at least have a table signature and save it */
279178825Sdfr
280178825Sdfr    Signature = DtGetFieldValue (*FieldList);
281178825Sdfr    if (!Signature)
282233294Sstas    {
283178825Sdfr        sprintf (MsgBuffer, "Expected \"%s\"", "Signature");
284178825Sdfr        DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
285233294Sstas            *FieldList, MsgBuffer);
286233294Sstas        return (AE_ERROR);
287233294Sstas    }
288233294Sstas
289233294Sstas    Gbl_Signature = UtLocalCalloc (ACPI_STRLEN (Signature) + 1);
290178825Sdfr    strcpy (Gbl_Signature, Signature);
291178825Sdfr
292233294Sstas    /*
293178825Sdfr     * Handle tables that don't use the common ACPI table header structure.
294178825Sdfr     * Currently, these are the FACS and RSDP. Also check for an OEMx table,
295178825Sdfr     * these tables have user-defined contents.
296178825Sdfr     */
297178825Sdfr    if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
298178825Sdfr    {
299178825Sdfr        Status = DtCompileFacs (FieldList);
300178825Sdfr        if (ACPI_FAILURE (Status))
301178825Sdfr        {
302178825Sdfr            return (Status);
303178825Sdfr        }
304178825Sdfr
305178825Sdfr        DtSetTableLength ();
306178825Sdfr        return (Status);
307178825Sdfr    }
308178825Sdfr    else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDP))
309178825Sdfr    {
310178825Sdfr        Status = DtCompileRsdp (FieldList);
311178825Sdfr        return (Status);
312233294Sstas    }
313233294Sstas    else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_S3PT))
314178825Sdfr    {
315178825Sdfr        Status = DtCompileS3pt (FieldList);
316178825Sdfr        if (ACPI_FAILURE (Status))
317178825Sdfr        {
318178825Sdfr            return (Status);
319233294Sstas        }
320178825Sdfr
321178825Sdfr        DtSetTableLength ();
322178825Sdfr        return (Status);
323178825Sdfr    }
324178825Sdfr
325178825Sdfr    /*
326178825Sdfr     * All other tables must use the common ACPI table header. Insert the
327178825Sdfr     * current iASL IDs (name, version), and compile the header now.
328178825Sdfr     */
329178825Sdfr    DtInsertCompilerIds (*FieldList);
330178825Sdfr
331233294Sstas    Status = DtCompileTable (FieldList, AcpiDmTableInfoHeader,
332178825Sdfr                &Gbl_RootTable, TRUE);
333233294Sstas    if (ACPI_FAILURE (Status))
334178825Sdfr    {
335178825Sdfr        return (Status);
336178825Sdfr    }
337178825Sdfr
338178825Sdfr    DtPushSubtable (Gbl_RootTable);
339233294Sstas
340233294Sstas    /* Validate the signature via the ACPI table list */
341233294Sstas
342178825Sdfr    TableData = AcpiDmGetTableData (Signature);
343178825Sdfr    if (!TableData || Gbl_CompileGeneric)
344178825Sdfr    {
345178825Sdfr        DtCompileGeneric ((void **) FieldList);
346178825Sdfr        goto Out;
347233294Sstas    }
348233294Sstas
349233294Sstas    /* Dispatch to per-table compile */
350233294Sstas
351233294Sstas    if (TableData->CmTableHandler)
352233294Sstas    {
353233294Sstas        /* Complex table, has a handler */
354233294Sstas
355233294Sstas        Status = TableData->CmTableHandler ((void **) FieldList);
356233294Sstas        if (ACPI_FAILURE (Status))
357233294Sstas        {
358233294Sstas            return (Status);
359178825Sdfr        }
360178825Sdfr    }
361178825Sdfr    else if (TableData->TableInfo)
362178825Sdfr    {
363178825Sdfr        /* Simple table, just walk the info table */
364178825Sdfr
365178825Sdfr        Subtable = NULL;
366178825Sdfr        Status = DtCompileTable (FieldList, TableData->TableInfo,
367178825Sdfr                    &Subtable, TRUE);
368178825Sdfr        if (ACPI_FAILURE (Status))
369178825Sdfr        {
370178825Sdfr            return (Status);
371178825Sdfr        }
372178825Sdfr
373178825Sdfr        DtInsertSubtable (Gbl_RootTable, Subtable);
374233294Sstas        DtPopSubtable ();
375178825Sdfr    }
376178825Sdfr    else
377178825Sdfr    {
378178825Sdfr        DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList,
379233294Sstas            "Missing table dispatch info");
380178825Sdfr        return (AE_ERROR);
381178825Sdfr    }
382178825Sdfr
383178825SdfrOut:
384178825Sdfr    /* Set the final table length and then the checksum */
385178825Sdfr
386178825Sdfr    DtSetTableLength ();
387178825Sdfr    AcpiTableHeader = ACPI_CAST_PTR (
388178825Sdfr        ACPI_TABLE_HEADER, Gbl_RootTable->Buffer);
389178825Sdfr    DtSetTableChecksum (&AcpiTableHeader->Checksum);
390178825Sdfr
391178825Sdfr    return (AE_OK);
392178825Sdfr}
393178825Sdfr
394233294Sstas
395178825Sdfr/******************************************************************************
396178825Sdfr *
397178825Sdfr * FUNCTION:    DtCompileTable
398178825Sdfr *
399178825Sdfr * PARAMETERS:  Field               - Current field list pointer
400178825Sdfr *              Info                - Info table for this ACPI table
401178825Sdfr *              RetSubtable         - Compile result of table
402178825Sdfr *              Required            - If this subtable must exist
403178825Sdfr *
404178825Sdfr * RETURN:      Status
405178825Sdfr *
406178825Sdfr * DESCRIPTION: Compile a subtable
407178825Sdfr *
408178825Sdfr *****************************************************************************/
409178825Sdfr
410178825SdfrACPI_STATUS
411178825SdfrDtCompileTable (
412178825Sdfr    DT_FIELD                **Field,
413178825Sdfr    ACPI_DMTABLE_INFO       *Info,
414178825Sdfr    DT_SUBTABLE             **RetSubtable,
415178825Sdfr    BOOLEAN                 Required)
416178825Sdfr{
417178825Sdfr    DT_FIELD                *LocalField;
418233294Sstas    UINT32                  Length;
419178825Sdfr    DT_SUBTABLE             *Subtable;
420178825Sdfr    DT_SUBTABLE             *InlineSubtable;
421178825Sdfr    UINT32                  FieldLength = 0;
422178825Sdfr    UINT8                   FieldType;
423178825Sdfr    UINT8                   *Buffer;
424178825Sdfr    UINT8                   *FlagBuffer = NULL;
425178825Sdfr    UINT32                  CurrentFlagByteOffset = 0;
426178825Sdfr    ACPI_STATUS             Status;
427178825Sdfr
428178825Sdfr
429178825Sdfr    if (!Field || !*Field)
430178825Sdfr    {
431178825Sdfr        return (AE_BAD_PARAMETER);
432178825Sdfr    }
433178825Sdfr
434178825Sdfr    Length = DtGetSubtableLength (*Field, Info);
435178825Sdfr    if (Length == ASL_EOF)
436178825Sdfr    {
437178825Sdfr        return (AE_ERROR);
438178825Sdfr    }
439178825Sdfr
440178825Sdfr    Subtable = UtLocalCalloc (sizeof (DT_SUBTABLE));
441178825Sdfr
442178825Sdfr    if (Length > 0)
443178825Sdfr    {
444178825Sdfr        Subtable->Buffer = UtLocalCalloc (Length);
445178825Sdfr    }
446178825Sdfr    Subtable->Length = Length;
447178825Sdfr    Subtable->TotalLength = Length;
448178825Sdfr    Buffer = Subtable->Buffer;
449178825Sdfr
450178825Sdfr    LocalField = *Field;
451178825Sdfr
452178825Sdfr    /*
453178825Sdfr     * Main loop walks the info table for this ACPI table or subtable
454178825Sdfr     */
455178825Sdfr    for (; Info->Name; Info++)
456178825Sdfr    {
457178825Sdfr        if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
458178825Sdfr        {
459178825Sdfr            continue;
460178825Sdfr        }
461178825Sdfr
462178825Sdfr        if (!LocalField)
463233294Sstas        {
464178825Sdfr            sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed",
465178825Sdfr                Info->Name);
466178825Sdfr            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
467178825Sdfr            Status = AE_BAD_DATA;
468178825Sdfr            goto Error;
469178825Sdfr        }
470178825Sdfr
471178825Sdfr        /* Maintain table offsets */
472178825Sdfr
473178825Sdfr        LocalField->TableOffset = Gbl_CurrentTableOffset;
474178825Sdfr        FieldLength = DtGetFieldLength (LocalField, Info);
475178825Sdfr        Gbl_CurrentTableOffset += FieldLength;
476178825Sdfr
477178825Sdfr        FieldType = DtGetFieldType (Info);
478178825Sdfr        Gbl_InputFieldCount++;
479178825Sdfr
480178825Sdfr        switch (FieldType)
481178825Sdfr        {
482178825Sdfr        case DT_FIELD_TYPE_FLAGS_INTEGER:
483178825Sdfr            /*
484178825Sdfr             * Start of the definition of a flags field.
485178825Sdfr             * This master flags integer starts at value zero, in preparation
486178825Sdfr             * to compile and insert the flag fields from the individual bits
487178825Sdfr             */
488233294Sstas            LocalField = LocalField->Next;
489233294Sstas            *Field = LocalField;
490178825Sdfr
491178825Sdfr            FlagBuffer = Buffer;
492178825Sdfr            CurrentFlagByteOffset = Info->Offset;
493178825Sdfr            break;
494178825Sdfr
495178825Sdfr        case DT_FIELD_TYPE_FLAG:
496178825Sdfr
497178825Sdfr            /* Individual Flag field, can be multiple bits */
498178825Sdfr
499178825Sdfr            if (FlagBuffer)
500178825Sdfr            {
501178825Sdfr                /*
502233294Sstas                 * We must increment the FlagBuffer when we have crossed
503178825Sdfr                 * into the next flags byte within the flags field
504178825Sdfr                 * of type DT_FIELD_TYPE_FLAGS_INTEGER.
505178825Sdfr                 */
506233294Sstas                FlagBuffer += (Info->Offset - CurrentFlagByteOffset);
507178825Sdfr                CurrentFlagByteOffset = Info->Offset;
508233294Sstas
509178825Sdfr                DtCompileFlag (FlagBuffer, LocalField, Info);
510233294Sstas            }
511233294Sstas            else
512178825Sdfr            {
513178825Sdfr                /* TBD - this is an internal error */
514178825Sdfr            }
515233294Sstas
516178825Sdfr            LocalField = LocalField->Next;
517233294Sstas            *Field = LocalField;
518233294Sstas            break;
519233294Sstas
520233294Sstas        case DT_FIELD_TYPE_INLINE_SUBTABLE:
521233294Sstas            /*
522233294Sstas             * Recursion (one level max): compile GAS (Generic Address)
523233294Sstas             * or Notify in-line subtable
524233294Sstas             */
525233294Sstas            *Field = LocalField;
526233294Sstas
527178825Sdfr            if (Info->Opcode == ACPI_DMT_GAS)
528178825Sdfr            {
529178825Sdfr                Status = DtCompileTable (Field, AcpiDmTableInfoGas,
530233294Sstas                    &InlineSubtable, TRUE);
531233294Sstas            }
532233294Sstas            else
533233294Sstas            {
534233294Sstas                Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify,
535233294Sstas                    &InlineSubtable, TRUE);
536233294Sstas            }
537233294Sstas
538233294Sstas            if (ACPI_FAILURE (Status))
539233294Sstas            {
540233294Sstas                goto Error;
541233294Sstas            }
542233294Sstas
543178825Sdfr            DtSetSubtableLength (InlineSubtable);
544233294Sstas
545233294Sstas            ACPI_MEMCPY (Buffer, InlineSubtable->Buffer, FieldLength);
546233294Sstas            ACPI_FREE (InlineSubtable->Buffer);
547233294Sstas            ACPI_FREE (InlineSubtable);
548233294Sstas            LocalField = *Field;
549233294Sstas            break;
550233294Sstas
551233294Sstas        case DT_FIELD_TYPE_LABEL:
552178825Sdfr
553178825Sdfr            DtWriteFieldToListing (Buffer, LocalField, 0);
554178825Sdfr            LocalField = LocalField->Next;
555233294Sstas            break;
556178825Sdfr
557178825Sdfr        default:
558178825Sdfr
559233294Sstas            /* Normal case for most field types (Integer, String, etc.) */
560178825Sdfr
561233294Sstas            DtCompileOneField (Buffer, LocalField,
562233294Sstas                FieldLength, FieldType, Info->Flags);
563178825Sdfr
564178825Sdfr            DtWriteFieldToListing (Buffer, LocalField, FieldLength);
565178825Sdfr            LocalField = LocalField->Next;
566233294Sstas
567233294Sstas            if (Info->Flags & DT_LENGTH)
568233294Sstas            {
569233294Sstas                /* Field is an Integer that will contain a subtable length */
570233294Sstas
571233294Sstas                Subtable->LengthField = Buffer;
572233294Sstas                Subtable->SizeOfLengthField = FieldLength;
573233294Sstas            }
574233294Sstas
575233294Sstas            break;
576233294Sstas        }
577233294Sstas
578233294Sstas        Buffer += FieldLength;
579233294Sstas    }
580233294Sstas
581233294Sstas    *Field = LocalField;
582233294Sstas    *RetSubtable = Subtable;
583233294Sstas    return (AE_OK);
584233294Sstas
585233294SstasError:
586233294Sstas    ACPI_FREE (Subtable->Buffer);
587233294Sstas    ACPI_FREE (Subtable);
588233294Sstas    return (Status);
589233294Sstas}
590233294Sstas