1208625Sjkim/******************************************************************************
2208625Sjkim *
3208625Sjkim * Module Name: dtcompile.c - Front-end for data table compiler
4208625Sjkim *
5208625Sjkim *****************************************************************************/
6208625Sjkim
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, 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
105281687Sjkim    if (Gbl_PreprocessFlag)
106281687Sjkim    {
107281687Sjkim        /* Preprocessor */
108233250Sjkim
109281687Sjkim        Event = UtBeginEvent ("Preprocess input file");
110281687Sjkim        PrDoPreprocess ();
111281687Sjkim        UtEndEvent (Event);
112281687Sjkim
113281687Sjkim        if (Gbl_PreprocessOnly)
114281687Sjkim        {
115281687Sjkim            return (AE_OK);
116281687Sjkim        }
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
175281075Sdim    AcpiUtDeleteCaches ();
176281075Sdim    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{
286284460Sjkim    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
305306536Sjkim    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,
348306536Sjkim        &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    {
361306536Sjkim        /* Unknown table signature and/or force generic compile */
362306536Sjkim
363284460Sjkim        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,
385306536Sjkim            &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;
441284460Sjkim    DT_SUBTABLE             *InlineSubtable = NULL;
442208625Sjkim    UINT32                  FieldLength = 0;
443208625Sjkim    UINT8                   FieldType;
444208625Sjkim    UINT8                   *Buffer;
445208625Sjkim    UINT8                   *FlagBuffer = NULL;
446281075Sdim    char                    *String;
447228110Sjkim    UINT32                  CurrentFlagByteOffset = 0;
448284460Sjkim    ACPI_STATUS             Status = AE_OK;
449208625Sjkim
450208625Sjkim
451208625Sjkim    if (!Field || !*Field)
452208625Sjkim    {
453208625Sjkim        return (AE_BAD_PARAMETER);
454208625Sjkim    }
455208625Sjkim
456281075Sdim    /* Ignore optional subtable if name does not match */
457281075Sdim
458281075Sdim    if ((Info->Flags & DT_OPTIONAL) &&
459306536Sjkim        strcmp ((*Field)->Name, Info->Name))
460281075Sdim    {
461281075Sdim        *RetSubtable = NULL;
462281075Sdim        return (AE_OK);
463281075Sdim    }
464281075Sdim
465208625Sjkim    Length = DtGetSubtableLength (*Field, Info);
466220663Sjkim    if (Length == ASL_EOF)
467220663Sjkim    {
468220663Sjkim        return (AE_ERROR);
469220663Sjkim    }
470220663Sjkim
471281075Sdim    Subtable = UtSubtableCacheCalloc ();
472208625Sjkim
473218590Sjkim    if (Length > 0)
474218590Sjkim    {
475281075Sdim        String = UtStringCacheCalloc (Length);
476281075Sdim        Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
477218590Sjkim    }
478281075Sdim
479208625Sjkim    Subtable->Length = Length;
480208625Sjkim    Subtable->TotalLength = Length;
481208625Sjkim    Buffer = Subtable->Buffer;
482208625Sjkim
483208625Sjkim    LocalField = *Field;
484284460Sjkim    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
561284460Sjkim            switch (Info->Opcode)
562208625Sjkim            {
563284460Sjkim            case ACPI_DMT_GAS:
564284460Sjkim
565208625Sjkim                Status = DtCompileTable (Field, AcpiDmTableInfoGas,
566208625Sjkim                    &InlineSubtable, TRUE);
567284460Sjkim                break;
568284460Sjkim
569284460Sjkim            case ACPI_DMT_HESTNTFY:
570284460Sjkim
571208625Sjkim                Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify,
572208625Sjkim                    &InlineSubtable, TRUE);
573284460Sjkim                break;
574284460Sjkim
575284460Sjkim            case ACPI_DMT_IORTMEM:
576284460Sjkim
577284460Sjkim                Status = DtCompileTable (Field, AcpiDmTableInfoIortAcc,
578284460Sjkim                    &InlineSubtable, TRUE);
579284460Sjkim                break;
580284460Sjkim
581284460Sjkim            default:
582284460Sjkim                sprintf (MsgBuffer, "Invalid DMT opcode: 0x%.2X",
583284460Sjkim                    Info->Opcode);
584284460Sjkim                DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
585284460Sjkim                Status = AE_BAD_DATA;
586284460Sjkim                break;
587208625Sjkim            }
588208625Sjkim
589208625Sjkim            if (ACPI_FAILURE (Status))
590208625Sjkim            {
591208625Sjkim                goto Error;
592208625Sjkim            }
593208625Sjkim
594209734Sjkim            DtSetSubtableLength (InlineSubtable);
595209734Sjkim
596306536Sjkim            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}
638284460Sjkim
639284460Sjkim
640284460Sjkim/******************************************************************************
641284460Sjkim *
642306536Sjkim * FUNCTION:    DtCompileTwoSubtables
643306536Sjkim *
644306536Sjkim * PARAMETERS:  List                - Current field list pointer
645306536Sjkim *              TableInfo1          - Info table 1
646306536Sjkim *              TableInfo1          - Info table 2
647306536Sjkim *
648306536Sjkim * RETURN:      Status
649306536Sjkim *
650306536Sjkim * DESCRIPTION: Compile tables with a header and one or more same subtables.
651306536Sjkim *              Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT
652306536Sjkim *
653306536Sjkim *****************************************************************************/
654306536Sjkim
655306536SjkimACPI_STATUS
656306536SjkimDtCompileTwoSubtables (
657306536Sjkim    void                    **List,
658306536Sjkim    ACPI_DMTABLE_INFO       *TableInfo1,
659306536Sjkim    ACPI_DMTABLE_INFO       *TableInfo2)
660306536Sjkim{
661306536Sjkim    ACPI_STATUS             Status;
662306536Sjkim    DT_SUBTABLE             *Subtable;
663306536Sjkim    DT_SUBTABLE             *ParentTable;
664306536Sjkim    DT_FIELD                **PFieldList = (DT_FIELD **) List;
665306536Sjkim
666306536Sjkim
667306536Sjkim    Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE);
668306536Sjkim    if (ACPI_FAILURE (Status))
669306536Sjkim    {
670306536Sjkim        return (Status);
671306536Sjkim    }
672306536Sjkim
673306536Sjkim    ParentTable = DtPeekSubtable ();
674306536Sjkim    DtInsertSubtable (ParentTable, Subtable);
675306536Sjkim
676306536Sjkim    while (*PFieldList)
677306536Sjkim    {
678306536Sjkim        Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE);
679306536Sjkim        if (ACPI_FAILURE (Status))
680306536Sjkim        {
681306536Sjkim            return (Status);
682306536Sjkim        }
683306536Sjkim
684306536Sjkim        DtInsertSubtable (ParentTable, Subtable);
685306536Sjkim    }
686306536Sjkim
687306536Sjkim    return (AE_OK);
688306536Sjkim}
689306536Sjkim
690306536Sjkim
691306536Sjkim/******************************************************************************
692306536Sjkim *
693284460Sjkim * FUNCTION:    DtCompilePadding
694284460Sjkim *
695284460Sjkim * PARAMETERS:  Length              - Padding field size
696284460Sjkim *              RetSubtable         - Compile result of table
697284460Sjkim *
698284460Sjkim * RETURN:      Status
699284460Sjkim *
700284460Sjkim * DESCRIPTION: Compile a subtable for padding purpose
701284460Sjkim *
702284460Sjkim *****************************************************************************/
703284460Sjkim
704284460SjkimACPI_STATUS
705284460SjkimDtCompilePadding (
706284460Sjkim    UINT32                  Length,
707284460Sjkim    DT_SUBTABLE             **RetSubtable)
708284460Sjkim{
709284460Sjkim    DT_SUBTABLE             *Subtable;
710284460Sjkim    /* UINT8                   *Buffer; */
711284460Sjkim    char                    *String;
712284460Sjkim
713284460Sjkim
714284460Sjkim    Subtable = UtSubtableCacheCalloc ();
715284460Sjkim
716284460Sjkim    if (Length > 0)
717284460Sjkim    {
718284460Sjkim        String = UtStringCacheCalloc (Length);
719284460Sjkim        Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
720284460Sjkim    }
721284460Sjkim
722284460Sjkim    Subtable->Length = Length;
723284460Sjkim    Subtable->TotalLength = Length;
724284460Sjkim    /* Buffer = Subtable->Buffer; */
725284460Sjkim
726284460Sjkim    *RetSubtable = Subtable;
727284460Sjkim    return (AE_OK);
728284460Sjkim}
729