dtcompile.c revision 284583
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
105281396Sjkim    if (Gbl_PreprocessFlag)
106281396Sjkim    {
107281396Sjkim        /* Preprocessor */
108233250Sjkim
109281396Sjkim        Event = UtBeginEvent ("Preprocess input file");
110281396Sjkim        PrDoPreprocess ();
111281396Sjkim        UtEndEvent (Event);
112281396Sjkim
113281396Sjkim        if (Gbl_PreprocessOnly)
114281396Sjkim        {
115281396Sjkim            return (AE_OK);
116281396Sjkim        }
117233250Sjkim    }
118233250Sjkim
119208625Sjkim    /*
120208625Sjkim     * Scan the input file (file is already open) and
121208625Sjkim     * build the parse tree
122208625Sjkim     */
123208625Sjkim    Event = UtBeginEvent ("Scan and parse input file");
124208625Sjkim    FieldList = DtScanFile (Gbl_Files[ASL_FILE_INPUT].Handle);
125208625Sjkim    UtEndEvent (Event);
126208625Sjkim
127208625Sjkim    /* Did the parse tree get successfully constructed? */
128208625Sjkim
129208625Sjkim    if (!FieldList)
130208625Sjkim    {
131208625Sjkim        /* TBD: temporary error message. Msgs should come from function above */
132208625Sjkim
133208625Sjkim        DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
134209734Sjkim            "Input file does not appear to be an ASL or data table source file");
135209734Sjkim
136209734Sjkim        Status = AE_ERROR;
137209734Sjkim        goto CleanupAndExit;
138208625Sjkim    }
139208625Sjkim
140208625Sjkim    Event = UtBeginEvent ("Compile parse tree");
141208625Sjkim
142208625Sjkim    /*
143208625Sjkim     * Compile the parse tree
144208625Sjkim     */
145208625Sjkim    Status = DtCompileDataTable (&FieldList);
146208625Sjkim    UtEndEvent (Event);
147208625Sjkim
148208625Sjkim    if (ACPI_FAILURE (Status))
149208625Sjkim    {
150208625Sjkim        /* TBD: temporary error message. Msgs should come from function above */
151208625Sjkim
152208625Sjkim        DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
153208625Sjkim            "Could not compile input file");
154209734Sjkim
155208625Sjkim        goto CleanupAndExit;
156208625Sjkim    }
157208625Sjkim
158208625Sjkim    /* Create/open the binary output file */
159208625Sjkim
160208625Sjkim    Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL;
161208625Sjkim    Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
162208625Sjkim    if (ACPI_FAILURE (Status))
163208625Sjkim    {
164208625Sjkim        goto CleanupAndExit;
165208625Sjkim    }
166208625Sjkim
167208625Sjkim    /* Write the binary, then the optional hex file */
168208625Sjkim
169208625Sjkim    DtOutputBinary (Gbl_RootTable);
170245582Sjkim    HxDoHexOutput ();
171217365Sjkim    DtWriteTableToListing ();
172208625Sjkim
173208625SjkimCleanupAndExit:
174208625Sjkim
175272444Sjkim    AcpiUtDeleteCaches ();
176272444Sjkim    DtDeleteCaches ();
177208625Sjkim    CmCleanupAndExit ();
178208625Sjkim    return (Status);
179208625Sjkim}
180208625Sjkim
181208625Sjkim
182208625Sjkim/******************************************************************************
183208625Sjkim *
184208625Sjkim * FUNCTION:    DtInitialize
185208625Sjkim *
186208625Sjkim * PARAMETERS:  None
187208625Sjkim *
188212761Sjkim * RETURN:      Status
189208625Sjkim *
190208625Sjkim * DESCRIPTION: Initialize data table compiler globals. Enables multiple
191208625Sjkim *              compiles per invocation.
192208625Sjkim *
193208625Sjkim *****************************************************************************/
194208625Sjkim
195212761Sjkimstatic ACPI_STATUS
196208625SjkimDtInitialize (
197208625Sjkim    void)
198208625Sjkim{
199212761Sjkim    ACPI_STATUS             Status;
200208625Sjkim
201209734Sjkim
202212761Sjkim    Status = AcpiOsInitialize ();
203212761Sjkim    if (ACPI_FAILURE (Status))
204212761Sjkim    {
205212761Sjkim        return (Status);
206212761Sjkim    }
207212761Sjkim
208212761Sjkim    Status = AcpiUtInitGlobals ();
209212761Sjkim    if (ACPI_FAILURE (Status))
210212761Sjkim    {
211212761Sjkim        return (Status);
212212761Sjkim    }
213212761Sjkim
214208625Sjkim    Gbl_FieldList = NULL;
215208625Sjkim    Gbl_RootTable = NULL;
216208625Sjkim    Gbl_SubtableStack = NULL;
217208625Sjkim
218208625Sjkim    sprintf (VersionString, "%X", (UINT32) ACPI_CA_VERSION);
219212761Sjkim    return (AE_OK);
220208625Sjkim}
221208625Sjkim
222208625Sjkim
223208625Sjkim/******************************************************************************
224208625Sjkim *
225208625Sjkim * FUNCTION:    DtInsertCompilerIds
226208625Sjkim *
227208625Sjkim * PARAMETERS:  FieldList           - Current field list pointer
228208625Sjkim *
229208625Sjkim * RETURN:      None
230208625Sjkim *
231208625Sjkim * DESCRIPTION: Insert the IDs (Name, Version) of the current compiler into
232208625Sjkim *              the original ACPI table header.
233208625Sjkim *
234208625Sjkim *****************************************************************************/
235208625Sjkim
236208625Sjkimstatic void
237208625SjkimDtInsertCompilerIds (
238208625Sjkim    DT_FIELD                *FieldList)
239208625Sjkim{
240208625Sjkim    DT_FIELD                *Next;
241208625Sjkim    UINT32                  i;
242208625Sjkim
243208625Sjkim
244208625Sjkim    /*
245208625Sjkim     * Don't insert current compiler ID if requested. Used for compiler
246208625Sjkim     * debug/validation only.
247208625Sjkim     */
248208625Sjkim    if (Gbl_UseOriginalCompilerId)
249208625Sjkim    {
250208625Sjkim        return;
251208625Sjkim    }
252208625Sjkim
253208625Sjkim    /* Walk to the Compiler fields at the end of the header */
254208625Sjkim
255208625Sjkim    Next = FieldList;
256208625Sjkim    for (i = 0; i < 7; i++)
257208625Sjkim    {
258208625Sjkim        Next = Next->Next;
259208625Sjkim    }
260208625Sjkim
261213806Sjkim    Next->Value = ASL_CREATOR_ID;
262208625Sjkim    Next->Flags = DT_FIELD_NOT_ALLOCATED;
263208625Sjkim
264208625Sjkim    Next = Next->Next;
265208625Sjkim    Next->Value = VersionString;
266208625Sjkim    Next->Flags = DT_FIELD_NOT_ALLOCATED;
267208625Sjkim}
268208625Sjkim
269208625Sjkim
270208625Sjkim/******************************************************************************
271208625Sjkim *
272208625Sjkim * FUNCTION:    DtCompileDataTable
273208625Sjkim *
274208625Sjkim * PARAMETERS:  FieldList           - Current field list pointer
275208625Sjkim *
276208625Sjkim * RETURN:      Status
277208625Sjkim *
278208625Sjkim * DESCRIPTION: Entry point to compile one data table
279208625Sjkim *
280208625Sjkim *****************************************************************************/
281208625Sjkim
282208625Sjkimstatic ACPI_STATUS
283208625SjkimDtCompileDataTable (
284208625Sjkim    DT_FIELD                **FieldList)
285208625Sjkim{
286283092Sjkim    const ACPI_DMTABLE_DATA *TableData;
287208625Sjkim    DT_SUBTABLE             *Subtable;
288208625Sjkim    char                    *Signature;
289208625Sjkim    ACPI_TABLE_HEADER       *AcpiTableHeader;
290208625Sjkim    ACPI_STATUS             Status;
291245582Sjkim    DT_FIELD                *RootField = *FieldList;
292208625Sjkim
293208625Sjkim
294208625Sjkim    /* Verify that we at least have a table signature and save it */
295208625Sjkim
296220663Sjkim    Signature = DtGetFieldValue (*FieldList);
297208625Sjkim    if (!Signature)
298208625Sjkim    {
299209734Sjkim        sprintf (MsgBuffer, "Expected \"%s\"", "Signature");
300209734Sjkim        DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
301209734Sjkim            *FieldList, MsgBuffer);
302208625Sjkim        return (AE_ERROR);
303208625Sjkim    }
304208625Sjkim
305284583Sjkim    Gbl_Signature = UtStringCacheCalloc (strlen (Signature) + 1);
306208625Sjkim    strcpy (Gbl_Signature, Signature);
307208625Sjkim
308208625Sjkim    /*
309208625Sjkim     * Handle tables that don't use the common ACPI table header structure.
310208625Sjkim     * Currently, these are the FACS and RSDP. Also check for an OEMx table,
311208625Sjkim     * these tables have user-defined contents.
312208625Sjkim     */
313208625Sjkim    if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
314208625Sjkim    {
315208625Sjkim        Status = DtCompileFacs (FieldList);
316208625Sjkim        if (ACPI_FAILURE (Status))
317208625Sjkim        {
318208625Sjkim            return (Status);
319208625Sjkim        }
320208625Sjkim
321208625Sjkim        DtSetTableLength ();
322208625Sjkim        return (Status);
323208625Sjkim    }
324254745Sjkim    else if (ACPI_VALIDATE_RSDP_SIG (Signature))
325208625Sjkim    {
326208625Sjkim        Status = DtCompileRsdp (FieldList);
327208625Sjkim        return (Status);
328208625Sjkim    }
329228110Sjkim    else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_S3PT))
330228110Sjkim    {
331228110Sjkim        Status = DtCompileS3pt (FieldList);
332228110Sjkim        if (ACPI_FAILURE (Status))
333228110Sjkim        {
334228110Sjkim            return (Status);
335228110Sjkim        }
336208625Sjkim
337228110Sjkim        DtSetTableLength ();
338228110Sjkim        return (Status);
339228110Sjkim    }
340228110Sjkim
341208625Sjkim    /*
342208625Sjkim     * All other tables must use the common ACPI table header. Insert the
343208625Sjkim     * current iASL IDs (name, version), and compile the header now.
344208625Sjkim     */
345208625Sjkim    DtInsertCompilerIds (*FieldList);
346208625Sjkim
347208625Sjkim    Status = DtCompileTable (FieldList, AcpiDmTableInfoHeader,
348208625Sjkim                &Gbl_RootTable, TRUE);
349208625Sjkim    if (ACPI_FAILURE (Status))
350208625Sjkim    {
351208625Sjkim        return (Status);
352208625Sjkim    }
353208625Sjkim
354208625Sjkim    DtPushSubtable (Gbl_RootTable);
355208625Sjkim
356220663Sjkim    /* Validate the signature via the ACPI table list */
357220663Sjkim
358220663Sjkim    TableData = AcpiDmGetTableData (Signature);
359228110Sjkim    if (!TableData || Gbl_CompileGeneric)
360220663Sjkim    {
361284583Sjkim        /* Unknown table signature and/or force generic compile */
362284583Sjkim
363283092Sjkim        DtCompileGeneric ((void **) FieldList, NULL, NULL);
364245582Sjkim        goto FinishHeader;
365220663Sjkim    }
366220663Sjkim
367209734Sjkim    /* Dispatch to per-table compile */
368208625Sjkim
369208625Sjkim    if (TableData->CmTableHandler)
370208625Sjkim    {
371208625Sjkim        /* Complex table, has a handler */
372208625Sjkim
373208625Sjkim        Status = TableData->CmTableHandler ((void **) FieldList);
374208625Sjkim        if (ACPI_FAILURE (Status))
375208625Sjkim        {
376208625Sjkim            return (Status);
377208625Sjkim        }
378208625Sjkim    }
379208625Sjkim    else if (TableData->TableInfo)
380208625Sjkim    {
381208625Sjkim        /* Simple table, just walk the info table */
382208625Sjkim
383208625Sjkim        Subtable = NULL;
384208625Sjkim        Status = DtCompileTable (FieldList, TableData->TableInfo,
385208625Sjkim                    &Subtable, TRUE);
386208625Sjkim        if (ACPI_FAILURE (Status))
387208625Sjkim        {
388208625Sjkim            return (Status);
389208625Sjkim        }
390208625Sjkim
391208625Sjkim        DtInsertSubtable (Gbl_RootTable, Subtable);
392208625Sjkim        DtPopSubtable ();
393208625Sjkim    }
394208625Sjkim    else
395208625Sjkim    {
396208625Sjkim        DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList,
397208625Sjkim            "Missing table dispatch info");
398208625Sjkim        return (AE_ERROR);
399208625Sjkim    }
400208625Sjkim
401245582SjkimFinishHeader:
402245582Sjkim
403208625Sjkim    /* Set the final table length and then the checksum */
404208625Sjkim
405208625Sjkim    DtSetTableLength ();
406208625Sjkim    AcpiTableHeader = ACPI_CAST_PTR (
407208625Sjkim        ACPI_TABLE_HEADER, Gbl_RootTable->Buffer);
408208625Sjkim    DtSetTableChecksum (&AcpiTableHeader->Checksum);
409208625Sjkim
410245582Sjkim    DtDumpFieldList (RootField);
411245582Sjkim    DtDumpSubtableList ();
412208625Sjkim    return (AE_OK);
413208625Sjkim}
414208625Sjkim
415208625Sjkim
416208625Sjkim/******************************************************************************
417208625Sjkim *
418208625Sjkim * FUNCTION:    DtCompileTable
419208625Sjkim *
420208625Sjkim * PARAMETERS:  Field               - Current field list pointer
421208625Sjkim *              Info                - Info table for this ACPI table
422208625Sjkim *              RetSubtable         - Compile result of table
423208625Sjkim *              Required            - If this subtable must exist
424208625Sjkim *
425208625Sjkim * RETURN:      Status
426208625Sjkim *
427208625Sjkim * DESCRIPTION: Compile a subtable
428208625Sjkim *
429208625Sjkim *****************************************************************************/
430208625Sjkim
431208625SjkimACPI_STATUS
432208625SjkimDtCompileTable (
433208625Sjkim    DT_FIELD                **Field,
434208625Sjkim    ACPI_DMTABLE_INFO       *Info,
435208625Sjkim    DT_SUBTABLE             **RetSubtable,
436208625Sjkim    BOOLEAN                 Required)
437208625Sjkim{
438208625Sjkim    DT_FIELD                *LocalField;
439208625Sjkim    UINT32                  Length;
440208625Sjkim    DT_SUBTABLE             *Subtable;
441283092Sjkim    DT_SUBTABLE             *InlineSubtable = NULL;
442208625Sjkim    UINT32                  FieldLength = 0;
443208625Sjkim    UINT8                   FieldType;
444208625Sjkim    UINT8                   *Buffer;
445208625Sjkim    UINT8                   *FlagBuffer = NULL;
446272444Sjkim    char                    *String;
447228110Sjkim    UINT32                  CurrentFlagByteOffset = 0;
448283092Sjkim    ACPI_STATUS             Status = AE_OK;
449208625Sjkim
450208625Sjkim
451208625Sjkim    if (!Field || !*Field)
452208625Sjkim    {
453208625Sjkim        return (AE_BAD_PARAMETER);
454208625Sjkim    }
455208625Sjkim
456272444Sjkim    /* Ignore optional subtable if name does not match */
457272444Sjkim
458272444Sjkim    if ((Info->Flags & DT_OPTIONAL) &&
459284583Sjkim        strcmp ((*Field)->Name, Info->Name))
460272444Sjkim    {
461272444Sjkim        *RetSubtable = NULL;
462272444Sjkim        return (AE_OK);
463272444Sjkim    }
464272444Sjkim
465208625Sjkim    Length = DtGetSubtableLength (*Field, Info);
466220663Sjkim    if (Length == ASL_EOF)
467220663Sjkim    {
468220663Sjkim        return (AE_ERROR);
469220663Sjkim    }
470220663Sjkim
471272444Sjkim    Subtable = UtSubtableCacheCalloc ();
472208625Sjkim
473218590Sjkim    if (Length > 0)
474218590Sjkim    {
475272444Sjkim        String = UtStringCacheCalloc (Length);
476272444Sjkim        Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
477218590Sjkim    }
478272444Sjkim
479208625Sjkim    Subtable->Length = Length;
480208625Sjkim    Subtable->TotalLength = Length;
481208625Sjkim    Buffer = Subtable->Buffer;
482208625Sjkim
483208625Sjkim    LocalField = *Field;
484283092Sjkim    Subtable->Name = LocalField->Name;
485208625Sjkim
486208625Sjkim    /*
487208625Sjkim     * Main loop walks the info table for this ACPI table or subtable
488208625Sjkim     */
489208625Sjkim    for (; Info->Name; Info++)
490208625Sjkim    {
491228110Sjkim        if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
492228110Sjkim        {
493228110Sjkim            continue;
494228110Sjkim        }
495228110Sjkim
496208625Sjkim        if (!LocalField)
497208625Sjkim        {
498208625Sjkim            sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed",
499208625Sjkim                Info->Name);
500208625Sjkim            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
501208625Sjkim            Status = AE_BAD_DATA;
502208625Sjkim            goto Error;
503208625Sjkim        }
504208625Sjkim
505218590Sjkim        /* Maintain table offsets */
506218590Sjkim
507218590Sjkim        LocalField->TableOffset = Gbl_CurrentTableOffset;
508208625Sjkim        FieldLength = DtGetFieldLength (LocalField, Info);
509218590Sjkim        Gbl_CurrentTableOffset += FieldLength;
510218590Sjkim
511208625Sjkim        FieldType = DtGetFieldType (Info);
512208625Sjkim        Gbl_InputFieldCount++;
513208625Sjkim
514208625Sjkim        switch (FieldType)
515208625Sjkim        {
516208625Sjkim        case DT_FIELD_TYPE_FLAGS_INTEGER:
517208625Sjkim            /*
518208625Sjkim             * Start of the definition of a flags field.
519208625Sjkim             * This master flags integer starts at value zero, in preparation
520208625Sjkim             * to compile and insert the flag fields from the individual bits
521208625Sjkim             */
522208625Sjkim            LocalField = LocalField->Next;
523208625Sjkim            *Field = LocalField;
524208625Sjkim
525208625Sjkim            FlagBuffer = Buffer;
526228110Sjkim            CurrentFlagByteOffset = Info->Offset;
527208625Sjkim            break;
528208625Sjkim
529208625Sjkim        case DT_FIELD_TYPE_FLAG:
530208625Sjkim
531208625Sjkim            /* Individual Flag field, can be multiple bits */
532208625Sjkim
533208625Sjkim            if (FlagBuffer)
534208625Sjkim            {
535228110Sjkim                /*
536228110Sjkim                 * We must increment the FlagBuffer when we have crossed
537228110Sjkim                 * into the next flags byte within the flags field
538228110Sjkim                 * of type DT_FIELD_TYPE_FLAGS_INTEGER.
539228110Sjkim                 */
540228110Sjkim                FlagBuffer += (Info->Offset - CurrentFlagByteOffset);
541228110Sjkim                CurrentFlagByteOffset = Info->Offset;
542228110Sjkim
543209734Sjkim                DtCompileFlag (FlagBuffer, LocalField, Info);
544208625Sjkim            }
545208625Sjkim            else
546208625Sjkim            {
547208625Sjkim                /* TBD - this is an internal error */
548208625Sjkim            }
549208625Sjkim
550208625Sjkim            LocalField = LocalField->Next;
551208625Sjkim            *Field = LocalField;
552208625Sjkim            break;
553208625Sjkim
554208625Sjkim        case DT_FIELD_TYPE_INLINE_SUBTABLE:
555208625Sjkim            /*
556208625Sjkim             * Recursion (one level max): compile GAS (Generic Address)
557208625Sjkim             * or Notify in-line subtable
558208625Sjkim             */
559208625Sjkim            *Field = LocalField;
560208625Sjkim
561283092Sjkim            switch (Info->Opcode)
562208625Sjkim            {
563283092Sjkim            case ACPI_DMT_GAS:
564283092Sjkim
565208625Sjkim                Status = DtCompileTable (Field, AcpiDmTableInfoGas,
566208625Sjkim                    &InlineSubtable, TRUE);
567283092Sjkim                break;
568283092Sjkim
569283092Sjkim            case ACPI_DMT_HESTNTFY:
570283092Sjkim
571208625Sjkim                Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify,
572208625Sjkim                    &InlineSubtable, TRUE);
573283092Sjkim                break;
574283092Sjkim
575283092Sjkim            case ACPI_DMT_IORTMEM:
576283092Sjkim
577283092Sjkim                Status = DtCompileTable (Field, AcpiDmTableInfoIortAcc,
578283092Sjkim                    &InlineSubtable, TRUE);
579283092Sjkim                break;
580283092Sjkim
581283092Sjkim            default:
582283092Sjkim                sprintf (MsgBuffer, "Invalid DMT opcode: 0x%.2X",
583283092Sjkim                    Info->Opcode);
584283092Sjkim                DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
585283092Sjkim                Status = AE_BAD_DATA;
586283092Sjkim                break;
587208625Sjkim            }
588208625Sjkim
589208625Sjkim            if (ACPI_FAILURE (Status))
590208625Sjkim            {
591208625Sjkim                goto Error;
592208625Sjkim            }
593208625Sjkim
594209734Sjkim            DtSetSubtableLength (InlineSubtable);
595209734Sjkim
596284583Sjkim            memcpy (Buffer, InlineSubtable->Buffer, FieldLength);
597208625Sjkim            LocalField = *Field;
598208625Sjkim            break;
599208625Sjkim
600218590Sjkim        case DT_FIELD_TYPE_LABEL:
601218590Sjkim
602218590Sjkim            DtWriteFieldToListing (Buffer, LocalField, 0);
603218590Sjkim            LocalField = LocalField->Next;
604218590Sjkim            break;
605218590Sjkim
606208625Sjkim        default:
607208625Sjkim
608208625Sjkim            /* Normal case for most field types (Integer, String, etc.) */
609208625Sjkim
610208625Sjkim            DtCompileOneField (Buffer, LocalField,
611208625Sjkim                FieldLength, FieldType, Info->Flags);
612217365Sjkim
613217365Sjkim            DtWriteFieldToListing (Buffer, LocalField, FieldLength);
614208625Sjkim            LocalField = LocalField->Next;
615208625Sjkim
616208625Sjkim            if (Info->Flags & DT_LENGTH)
617208625Sjkim            {
618208625Sjkim                /* Field is an Integer that will contain a subtable length */
619208625Sjkim
620208625Sjkim                Subtable->LengthField = Buffer;
621208625Sjkim                Subtable->SizeOfLengthField = FieldLength;
622208625Sjkim            }
623208625Sjkim            break;
624208625Sjkim        }
625208625Sjkim
626208625Sjkim        Buffer += FieldLength;
627208625Sjkim    }
628208625Sjkim
629208625Sjkim    *Field = LocalField;
630208625Sjkim    *RetSubtable = Subtable;
631208625Sjkim    return (AE_OK);
632208625Sjkim
633208625SjkimError:
634208625Sjkim    ACPI_FREE (Subtable->Buffer);
635208625Sjkim    ACPI_FREE (Subtable);
636208625Sjkim    return (Status);
637208625Sjkim}
638283092Sjkim
639283092Sjkim
640283092Sjkim/******************************************************************************
641283092Sjkim *
642283092Sjkim * FUNCTION:    DtCompilePadding
643283092Sjkim *
644283092Sjkim * PARAMETERS:  Length              - Padding field size
645283092Sjkim *              RetSubtable         - Compile result of table
646283092Sjkim *
647283092Sjkim * RETURN:      Status
648283092Sjkim *
649283092Sjkim * DESCRIPTION: Compile a subtable for padding purpose
650283092Sjkim *
651283092Sjkim *****************************************************************************/
652283092Sjkim
653283092SjkimACPI_STATUS
654283092SjkimDtCompilePadding (
655283092Sjkim    UINT32                  Length,
656283092Sjkim    DT_SUBTABLE             **RetSubtable)
657283092Sjkim{
658283092Sjkim    DT_SUBTABLE             *Subtable;
659283092Sjkim    /* UINT8                   *Buffer; */
660283092Sjkim    char                    *String;
661283092Sjkim
662283092Sjkim
663283092Sjkim    Subtable = UtSubtableCacheCalloc ();
664283092Sjkim
665283092Sjkim    if (Length > 0)
666283092Sjkim    {
667283092Sjkim        String = UtStringCacheCalloc (Length);
668283092Sjkim        Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
669283092Sjkim    }
670283092Sjkim
671283092Sjkim    Subtable->Length = Length;
672283092Sjkim    Subtable->TotalLength = Length;
673283092Sjkim    /* Buffer = Subtable->Buffer; */
674283092Sjkim
675283092Sjkim    *RetSubtable = Subtable;
676283092Sjkim    return (AE_OK);
677283092Sjkim}
678