1208625Sjkim/******************************************************************************
2208625Sjkim *
3208625Sjkim * Module Name: dtcompile.c - Front-end for data table compiler
4208625Sjkim *
5208625Sjkim *****************************************************************************/
6208625Sjkim
7316303Sjkim/******************************************************************************
8316303Sjkim *
9316303Sjkim * 1. Copyright Notice
10316303Sjkim *
11316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
12208625Sjkim * All rights reserved.
13208625Sjkim *
14316303Sjkim * 2. License
15316303Sjkim *
16316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property
17316303Sjkim * rights. You may have additional license terms from the party that provided
18316303Sjkim * you this software, covering your right to use that party's intellectual
19316303Sjkim * property rights.
20316303Sjkim *
21316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22316303Sjkim * copy of the source code appearing in this file ("Covered Code") an
23316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy,
25316303Sjkim * make derivatives, distribute, use and display any portion of the Covered
26316303Sjkim * Code in any form, with the right to sublicense such rights; and
27316303Sjkim *
28316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29316303Sjkim * license (with the right to sublicense), under only those claims of Intel
30316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell,
31316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof
32316303Sjkim * solely to the minimum extent necessary to exercise the above copyright
33316303Sjkim * license, and in no event shall the patent license extend to any additions
34316303Sjkim * to or modifications of the Original Intel Code. No other license or right
35316303Sjkim * is granted directly or by implication, estoppel or otherwise;
36316303Sjkim *
37316303Sjkim * The above copyright and patent license is granted only if the following
38316303Sjkim * conditions are met:
39316303Sjkim *
40316303Sjkim * 3. Conditions
41316303Sjkim *
42316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43316303Sjkim * Redistribution of source code of any substantial portion of the Covered
44316303Sjkim * Code or modification with rights to further distribute source must include
45316303Sjkim * the above Copyright Notice, the above License, this list of Conditions,
46316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition,
47316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to
48316303Sjkim * contain a file documenting the changes Licensee made to create that Covered
49316303Sjkim * Code and the date of any change. Licensee must include in that file the
50316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee
51316303Sjkim * must include a prominent statement that the modification is derived,
52316303Sjkim * directly or indirectly, from Original Intel Code.
53316303Sjkim *
54316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55316303Sjkim * Redistribution of source code of any substantial portion of the Covered
56316303Sjkim * Code or modification without rights to further distribute source must
57316303Sjkim * include the following Disclaimer and Export Compliance provision in the
58316303Sjkim * documentation and/or other materials provided with distribution. In
59316303Sjkim * addition, Licensee may not authorize further sublicense of source of any
60316303Sjkim * portion of the Covered Code, and must include terms to the effect that the
61316303Sjkim * license from Licensee to its licensee is limited to the intellectual
62316303Sjkim * property embodied in the software Licensee provides to its licensee, and
63316303Sjkim * not to intellectual property embodied in modifications its licensee may
64316303Sjkim * make.
65316303Sjkim *
66316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any
67316303Sjkim * substantial portion of the Covered Code or modification must reproduce the
68316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance
69316303Sjkim * provision in the documentation and/or other materials provided with the
70316303Sjkim * distribution.
71316303Sjkim *
72316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original
73316303Sjkim * Intel Code.
74316303Sjkim *
75316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or
77316303Sjkim * other dealings in products derived from or relating to the Covered Code
78316303Sjkim * without prior written authorization from Intel.
79316303Sjkim *
80316303Sjkim * 4. Disclaimer and Export Compliance
81316303Sjkim *
82316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88316303Sjkim * PARTICULAR PURPOSE.
89316303Sjkim *
90316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97316303Sjkim * LIMITED REMEDY.
98316303Sjkim *
99316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this
100316303Sjkim * software or system incorporating such software without first obtaining any
101316303Sjkim * required license or other approval from the U. S. Department of Commerce or
102316303Sjkim * any other agency or department of the United States Government. In the
103316303Sjkim * event Licensee exports any such software from the United States or
104316303Sjkim * re-exports any such software from a foreign destination, Licensee shall
105316303Sjkim * ensure that the distribution and export/re-export of the software is in
106316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the
107316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108316303Sjkim * any of its subsidiaries will export/re-export any technical data, process,
109316303Sjkim * software, or service, directly or indirectly, to any country for which the
110316303Sjkim * United States government or any agency thereof requires an export license,
111316303Sjkim * other governmental approval, or letter of assurance, without first obtaining
112316303Sjkim * such license, approval or letter.
113316303Sjkim *
114316303Sjkim *****************************************************************************
115316303Sjkim *
116316303Sjkim * Alternatively, you may choose to be licensed under the terms of the
117316303Sjkim * following license:
118316303Sjkim *
119217365Sjkim * Redistribution and use in source and binary forms, with or without
120217365Sjkim * modification, are permitted provided that the following conditions
121217365Sjkim * are met:
122217365Sjkim * 1. Redistributions of source code must retain the above copyright
123217365Sjkim *    notice, this list of conditions, and the following disclaimer,
124217365Sjkim *    without modification.
125217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
127217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
128217365Sjkim *    including a substantially similar Disclaimer requirement for further
129217365Sjkim *    binary redistribution.
130217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
131217365Sjkim *    of any contributors may be used to endorse or promote products derived
132217365Sjkim *    from this software without specific prior written permission.
133208625Sjkim *
134316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145316303Sjkim *
146316303Sjkim * Alternatively, you may choose to be licensed under the terms of the
147217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
148217365Sjkim * Software Foundation.
149208625Sjkim *
150316303Sjkim *****************************************************************************/
151208625Sjkim
152208625Sjkim#define _DECLARE_DT_GLOBALS
153208625Sjkim
154209746Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
155208625Sjkim
156208625Sjkim#define _COMPONENT          DT_COMPILER
157208625Sjkim        ACPI_MODULE_NAME    ("dtcompile")
158208625Sjkim
159208625Sjkimstatic char                 VersionString[9];
160208625Sjkim
161208625Sjkim
162208625Sjkim/* Local prototypes */
163208625Sjkim
164212761Sjkimstatic ACPI_STATUS
165208625SjkimDtInitialize (
166208625Sjkim    void);
167208625Sjkim
168208625Sjkimstatic ACPI_STATUS
169208625SjkimDtCompileDataTable (
170208625Sjkim    DT_FIELD                **Field);
171208625Sjkim
172208625Sjkimstatic void
173208625SjkimDtInsertCompilerIds (
174208625Sjkim    DT_FIELD                *FieldList);
175208625Sjkim
176208625Sjkim
177208625Sjkim/******************************************************************************
178208625Sjkim *
179208625Sjkim * FUNCTION:    DtDoCompile
180208625Sjkim *
181208625Sjkim * PARAMETERS:  None
182208625Sjkim *
183208625Sjkim * RETURN:      Status
184208625Sjkim *
185208625Sjkim * DESCRIPTION: Main entry point for the data table compiler.
186208625Sjkim *
187208625Sjkim * Note: Assumes Gbl_Files[ASL_FILE_INPUT] is initialized and the file is
188208625Sjkim *          open at seek offset zero.
189208625Sjkim *
190208625Sjkim *****************************************************************************/
191208625Sjkim
192208625SjkimACPI_STATUS
193208625SjkimDtDoCompile (
194208625Sjkim    void)
195208625Sjkim{
196208625Sjkim    ACPI_STATUS             Status;
197208625Sjkim    UINT8                   Event;
198208625Sjkim    DT_FIELD                *FieldList;
199208625Sjkim
200208625Sjkim
201208625Sjkim    /* Initialize globals */
202208625Sjkim
203212761Sjkim    Status = DtInitialize ();
204212761Sjkim    if (ACPI_FAILURE (Status))
205212761Sjkim    {
206212761Sjkim        printf ("Error during compiler initialization, 0x%X\n", Status);
207212761Sjkim        return (Status);
208212761Sjkim    }
209208625Sjkim
210233250Sjkim    /* Preprocessor */
211233250Sjkim
212281396Sjkim    if (Gbl_PreprocessFlag)
213281396Sjkim    {
214281396Sjkim        /* Preprocessor */
215233250Sjkim
216281396Sjkim        Event = UtBeginEvent ("Preprocess input file");
217281396Sjkim        PrDoPreprocess ();
218281396Sjkim        UtEndEvent (Event);
219281396Sjkim
220281396Sjkim        if (Gbl_PreprocessOnly)
221281396Sjkim        {
222281396Sjkim            return (AE_OK);
223281396Sjkim        }
224233250Sjkim    }
225233250Sjkim
226208625Sjkim    /*
227208625Sjkim     * Scan the input file (file is already open) and
228208625Sjkim     * build the parse tree
229208625Sjkim     */
230208625Sjkim    Event = UtBeginEvent ("Scan and parse input file");
231208625Sjkim    FieldList = DtScanFile (Gbl_Files[ASL_FILE_INPUT].Handle);
232208625Sjkim    UtEndEvent (Event);
233208625Sjkim
234208625Sjkim    /* Did the parse tree get successfully constructed? */
235208625Sjkim
236208625Sjkim    if (!FieldList)
237208625Sjkim    {
238208625Sjkim        /* TBD: temporary error message. Msgs should come from function above */
239208625Sjkim
240208625Sjkim        DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
241209734Sjkim            "Input file does not appear to be an ASL or data table source file");
242209734Sjkim
243209734Sjkim        Status = AE_ERROR;
244209734Sjkim        goto CleanupAndExit;
245208625Sjkim    }
246208625Sjkim
247208625Sjkim    Event = UtBeginEvent ("Compile parse tree");
248208625Sjkim
249208625Sjkim    /*
250208625Sjkim     * Compile the parse tree
251208625Sjkim     */
252208625Sjkim    Status = DtCompileDataTable (&FieldList);
253208625Sjkim    UtEndEvent (Event);
254208625Sjkim
255208625Sjkim    if (ACPI_FAILURE (Status))
256208625Sjkim    {
257208625Sjkim        /* TBD: temporary error message. Msgs should come from function above */
258208625Sjkim
259208625Sjkim        DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
260208625Sjkim            "Could not compile input file");
261209734Sjkim
262208625Sjkim        goto CleanupAndExit;
263208625Sjkim    }
264208625Sjkim
265208625Sjkim    /* Create/open the binary output file */
266208625Sjkim
267208625Sjkim    Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL;
268208625Sjkim    Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
269208625Sjkim    if (ACPI_FAILURE (Status))
270208625Sjkim    {
271208625Sjkim        goto CleanupAndExit;
272208625Sjkim    }
273208625Sjkim
274208625Sjkim    /* Write the binary, then the optional hex file */
275208625Sjkim
276208625Sjkim    DtOutputBinary (Gbl_RootTable);
277245582Sjkim    HxDoHexOutput ();
278217365Sjkim    DtWriteTableToListing ();
279208625Sjkim
280208625SjkimCleanupAndExit:
281208625Sjkim
282272444Sjkim    AcpiUtDeleteCaches ();
283208625Sjkim    CmCleanupAndExit ();
284208625Sjkim    return (Status);
285208625Sjkim}
286208625Sjkim
287208625Sjkim
288208625Sjkim/******************************************************************************
289208625Sjkim *
290208625Sjkim * FUNCTION:    DtInitialize
291208625Sjkim *
292208625Sjkim * PARAMETERS:  None
293208625Sjkim *
294212761Sjkim * RETURN:      Status
295208625Sjkim *
296208625Sjkim * DESCRIPTION: Initialize data table compiler globals. Enables multiple
297208625Sjkim *              compiles per invocation.
298208625Sjkim *
299208625Sjkim *****************************************************************************/
300208625Sjkim
301212761Sjkimstatic ACPI_STATUS
302208625SjkimDtInitialize (
303208625Sjkim    void)
304208625Sjkim{
305212761Sjkim    ACPI_STATUS             Status;
306208625Sjkim
307209734Sjkim
308212761Sjkim    Status = AcpiOsInitialize ();
309212761Sjkim    if (ACPI_FAILURE (Status))
310212761Sjkim    {
311212761Sjkim        return (Status);
312212761Sjkim    }
313212761Sjkim
314212761Sjkim    Status = AcpiUtInitGlobals ();
315212761Sjkim    if (ACPI_FAILURE (Status))
316212761Sjkim    {
317212761Sjkim        return (Status);
318212761Sjkim    }
319212761Sjkim
320327557Sjkim    AcpiUtSetIntegerWidth (2); /* Set width to 64 bits */
321327557Sjkim
322208625Sjkim    Gbl_FieldList = NULL;
323208625Sjkim    Gbl_RootTable = NULL;
324208625Sjkim    Gbl_SubtableStack = NULL;
325208625Sjkim
326208625Sjkim    sprintf (VersionString, "%X", (UINT32) ACPI_CA_VERSION);
327212761Sjkim    return (AE_OK);
328208625Sjkim}
329208625Sjkim
330208625Sjkim
331208625Sjkim/******************************************************************************
332208625Sjkim *
333208625Sjkim * FUNCTION:    DtInsertCompilerIds
334208625Sjkim *
335208625Sjkim * PARAMETERS:  FieldList           - Current field list pointer
336208625Sjkim *
337208625Sjkim * RETURN:      None
338208625Sjkim *
339208625Sjkim * DESCRIPTION: Insert the IDs (Name, Version) of the current compiler into
340208625Sjkim *              the original ACPI table header.
341208625Sjkim *
342208625Sjkim *****************************************************************************/
343208625Sjkim
344208625Sjkimstatic void
345208625SjkimDtInsertCompilerIds (
346208625Sjkim    DT_FIELD                *FieldList)
347208625Sjkim{
348208625Sjkim    DT_FIELD                *Next;
349208625Sjkim    UINT32                  i;
350208625Sjkim
351208625Sjkim
352208625Sjkim    /*
353208625Sjkim     * Don't insert current compiler ID if requested. Used for compiler
354208625Sjkim     * debug/validation only.
355208625Sjkim     */
356208625Sjkim    if (Gbl_UseOriginalCompilerId)
357208625Sjkim    {
358208625Sjkim        return;
359208625Sjkim    }
360208625Sjkim
361208625Sjkim    /* Walk to the Compiler fields at the end of the header */
362208625Sjkim
363208625Sjkim    Next = FieldList;
364208625Sjkim    for (i = 0; i < 7; i++)
365208625Sjkim    {
366208625Sjkim        Next = Next->Next;
367208625Sjkim    }
368208625Sjkim
369213806Sjkim    Next->Value = ASL_CREATOR_ID;
370208625Sjkim    Next->Flags = DT_FIELD_NOT_ALLOCATED;
371208625Sjkim
372208625Sjkim    Next = Next->Next;
373208625Sjkim    Next->Value = VersionString;
374208625Sjkim    Next->Flags = DT_FIELD_NOT_ALLOCATED;
375208625Sjkim}
376208625Sjkim
377208625Sjkim
378208625Sjkim/******************************************************************************
379208625Sjkim *
380208625Sjkim * FUNCTION:    DtCompileDataTable
381208625Sjkim *
382208625Sjkim * PARAMETERS:  FieldList           - Current field list pointer
383208625Sjkim *
384208625Sjkim * RETURN:      Status
385208625Sjkim *
386208625Sjkim * DESCRIPTION: Entry point to compile one data table
387208625Sjkim *
388208625Sjkim *****************************************************************************/
389208625Sjkim
390208625Sjkimstatic ACPI_STATUS
391208625SjkimDtCompileDataTable (
392208625Sjkim    DT_FIELD                **FieldList)
393208625Sjkim{
394283092Sjkim    const ACPI_DMTABLE_DATA *TableData;
395208625Sjkim    DT_SUBTABLE             *Subtable;
396208625Sjkim    char                    *Signature;
397208625Sjkim    ACPI_TABLE_HEADER       *AcpiTableHeader;
398208625Sjkim    ACPI_STATUS             Status;
399245582Sjkim    DT_FIELD                *RootField = *FieldList;
400208625Sjkim
401208625Sjkim
402208625Sjkim    /* Verify that we at least have a table signature and save it */
403208625Sjkim
404220663Sjkim    Signature = DtGetFieldValue (*FieldList);
405208625Sjkim    if (!Signature)
406208625Sjkim    {
407209734Sjkim        sprintf (MsgBuffer, "Expected \"%s\"", "Signature");
408209734Sjkim        DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
409209734Sjkim            *FieldList, MsgBuffer);
410208625Sjkim        return (AE_ERROR);
411208625Sjkim    }
412208625Sjkim
413327557Sjkim    Gbl_Signature = UtLocalCacheCalloc (strlen (Signature) + 1);
414208625Sjkim    strcpy (Gbl_Signature, Signature);
415208625Sjkim
416208625Sjkim    /*
417208625Sjkim     * Handle tables that don't use the common ACPI table header structure.
418208625Sjkim     * Currently, these are the FACS and RSDP. Also check for an OEMx table,
419208625Sjkim     * these tables have user-defined contents.
420208625Sjkim     */
421208625Sjkim    if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
422208625Sjkim    {
423208625Sjkim        Status = DtCompileFacs (FieldList);
424208625Sjkim        if (ACPI_FAILURE (Status))
425208625Sjkim        {
426208625Sjkim            return (Status);
427208625Sjkim        }
428208625Sjkim
429208625Sjkim        DtSetTableLength ();
430208625Sjkim        return (Status);
431208625Sjkim    }
432254745Sjkim    else if (ACPI_VALIDATE_RSDP_SIG (Signature))
433208625Sjkim    {
434208625Sjkim        Status = DtCompileRsdp (FieldList);
435208625Sjkim        return (Status);
436208625Sjkim    }
437228110Sjkim    else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_S3PT))
438228110Sjkim    {
439228110Sjkim        Status = DtCompileS3pt (FieldList);
440228110Sjkim        if (ACPI_FAILURE (Status))
441228110Sjkim        {
442228110Sjkim            return (Status);
443228110Sjkim        }
444208625Sjkim
445228110Sjkim        DtSetTableLength ();
446228110Sjkim        return (Status);
447228110Sjkim    }
448228110Sjkim
449208625Sjkim    /*
450208625Sjkim     * All other tables must use the common ACPI table header. Insert the
451208625Sjkim     * current iASL IDs (name, version), and compile the header now.
452208625Sjkim     */
453208625Sjkim    DtInsertCompilerIds (*FieldList);
454208625Sjkim
455208625Sjkim    Status = DtCompileTable (FieldList, AcpiDmTableInfoHeader,
456298714Sjkim        &Gbl_RootTable, TRUE);
457208625Sjkim    if (ACPI_FAILURE (Status))
458208625Sjkim    {
459208625Sjkim        return (Status);
460208625Sjkim    }
461208625Sjkim
462208625Sjkim    DtPushSubtable (Gbl_RootTable);
463208625Sjkim
464220663Sjkim    /* Validate the signature via the ACPI table list */
465220663Sjkim
466220663Sjkim    TableData = AcpiDmGetTableData (Signature);
467228110Sjkim    if (!TableData || Gbl_CompileGeneric)
468220663Sjkim    {
469284583Sjkim        /* Unknown table signature and/or force generic compile */
470284583Sjkim
471283092Sjkim        DtCompileGeneric ((void **) FieldList, NULL, NULL);
472245582Sjkim        goto FinishHeader;
473220663Sjkim    }
474220663Sjkim
475209734Sjkim    /* Dispatch to per-table compile */
476208625Sjkim
477208625Sjkim    if (TableData->CmTableHandler)
478208625Sjkim    {
479208625Sjkim        /* Complex table, has a handler */
480208625Sjkim
481208625Sjkim        Status = TableData->CmTableHandler ((void **) FieldList);
482208625Sjkim        if (ACPI_FAILURE (Status))
483208625Sjkim        {
484208625Sjkim            return (Status);
485208625Sjkim        }
486208625Sjkim    }
487208625Sjkim    else if (TableData->TableInfo)
488208625Sjkim    {
489322877Sjkim        /* Simple table, just walk the info table, unless its empty */
490208625Sjkim
491322877Sjkim        if (FieldList && *FieldList)
492208625Sjkim        {
493322877Sjkim            Subtable = NULL;
494322877Sjkim            Status = DtCompileTable (FieldList, TableData->TableInfo,
495322877Sjkim                &Subtable, TRUE);
496322877Sjkim            if (ACPI_FAILURE (Status))
497322877Sjkim            {
498322877Sjkim                return (Status);
499322877Sjkim            }
500322877Sjkim
501322877Sjkim            DtInsertSubtable (Gbl_RootTable, Subtable);
502322877Sjkim            DtPopSubtable ();
503208625Sjkim        }
504208625Sjkim    }
505208625Sjkim    else
506208625Sjkim    {
507208625Sjkim        DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList,
508208625Sjkim            "Missing table dispatch info");
509208625Sjkim        return (AE_ERROR);
510208625Sjkim    }
511208625Sjkim
512245582SjkimFinishHeader:
513245582Sjkim
514208625Sjkim    /* Set the final table length and then the checksum */
515208625Sjkim
516208625Sjkim    DtSetTableLength ();
517208625Sjkim    AcpiTableHeader = ACPI_CAST_PTR (
518208625Sjkim        ACPI_TABLE_HEADER, Gbl_RootTable->Buffer);
519208625Sjkim    DtSetTableChecksum (&AcpiTableHeader->Checksum);
520208625Sjkim
521245582Sjkim    DtDumpFieldList (RootField);
522245582Sjkim    DtDumpSubtableList ();
523208625Sjkim    return (AE_OK);
524208625Sjkim}
525208625Sjkim
526208625Sjkim
527208625Sjkim/******************************************************************************
528208625Sjkim *
529208625Sjkim * FUNCTION:    DtCompileTable
530208625Sjkim *
531208625Sjkim * PARAMETERS:  Field               - Current field list pointer
532208625Sjkim *              Info                - Info table for this ACPI table
533208625Sjkim *              RetSubtable         - Compile result of table
534208625Sjkim *              Required            - If this subtable must exist
535208625Sjkim *
536208625Sjkim * RETURN:      Status
537208625Sjkim *
538208625Sjkim * DESCRIPTION: Compile a subtable
539208625Sjkim *
540208625Sjkim *****************************************************************************/
541208625Sjkim
542208625SjkimACPI_STATUS
543208625SjkimDtCompileTable (
544208625Sjkim    DT_FIELD                **Field,
545208625Sjkim    ACPI_DMTABLE_INFO       *Info,
546208625Sjkim    DT_SUBTABLE             **RetSubtable,
547208625Sjkim    BOOLEAN                 Required)
548208625Sjkim{
549208625Sjkim    DT_FIELD                *LocalField;
550208625Sjkim    UINT32                  Length;
551208625Sjkim    DT_SUBTABLE             *Subtable;
552283092Sjkim    DT_SUBTABLE             *InlineSubtable = NULL;
553208625Sjkim    UINT32                  FieldLength = 0;
554208625Sjkim    UINT8                   FieldType;
555208625Sjkim    UINT8                   *Buffer;
556208625Sjkim    UINT8                   *FlagBuffer = NULL;
557272444Sjkim    char                    *String;
558228110Sjkim    UINT32                  CurrentFlagByteOffset = 0;
559283092Sjkim    ACPI_STATUS             Status = AE_OK;
560208625Sjkim
561208625Sjkim
562327557Sjkim    if (!Field)
563208625Sjkim    {
564208625Sjkim        return (AE_BAD_PARAMETER);
565208625Sjkim    }
566327557Sjkim    if (!*Field)
567327557Sjkim    {
568327557Sjkim        /*
569327557Sjkim         * The field list is empty, this means that we are out of fields to
570327557Sjkim         * parse. In other words, we are at the end of the table.
571327557Sjkim         */
572327557Sjkim        return (AE_END_OF_TABLE);
573327557Sjkim    }
574208625Sjkim
575272444Sjkim    /* Ignore optional subtable if name does not match */
576272444Sjkim
577272444Sjkim    if ((Info->Flags & DT_OPTIONAL) &&
578284583Sjkim        strcmp ((*Field)->Name, Info->Name))
579272444Sjkim    {
580272444Sjkim        *RetSubtable = NULL;
581272444Sjkim        return (AE_OK);
582272444Sjkim    }
583272444Sjkim
584208625Sjkim    Length = DtGetSubtableLength (*Field, Info);
585220663Sjkim    if (Length == ASL_EOF)
586220663Sjkim    {
587220663Sjkim        return (AE_ERROR);
588220663Sjkim    }
589220663Sjkim
590272444Sjkim    Subtable = UtSubtableCacheCalloc ();
591208625Sjkim
592218590Sjkim    if (Length > 0)
593218590Sjkim    {
594327557Sjkim        String = UtLocalCacheCalloc (Length);
595272444Sjkim        Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
596218590Sjkim    }
597272444Sjkim
598208625Sjkim    Subtable->Length = Length;
599208625Sjkim    Subtable->TotalLength = Length;
600208625Sjkim    Buffer = Subtable->Buffer;
601208625Sjkim
602208625Sjkim    LocalField = *Field;
603283092Sjkim    Subtable->Name = LocalField->Name;
604208625Sjkim
605208625Sjkim    /*
606208625Sjkim     * Main loop walks the info table for this ACPI table or subtable
607208625Sjkim     */
608208625Sjkim    for (; Info->Name; Info++)
609208625Sjkim    {
610228110Sjkim        if (Info->Opcode == ACPI_DMT_EXTRA_TEXT)
611228110Sjkim        {
612228110Sjkim            continue;
613228110Sjkim        }
614228110Sjkim
615208625Sjkim        if (!LocalField)
616208625Sjkim        {
617208625Sjkim            sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed",
618208625Sjkim                Info->Name);
619208625Sjkim            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
620208625Sjkim            Status = AE_BAD_DATA;
621208625Sjkim            goto Error;
622208625Sjkim        }
623208625Sjkim
624218590Sjkim        /* Maintain table offsets */
625218590Sjkim
626218590Sjkim        LocalField->TableOffset = Gbl_CurrentTableOffset;
627208625Sjkim        FieldLength = DtGetFieldLength (LocalField, Info);
628218590Sjkim        Gbl_CurrentTableOffset += FieldLength;
629218590Sjkim
630208625Sjkim        FieldType = DtGetFieldType (Info);
631208625Sjkim        Gbl_InputFieldCount++;
632208625Sjkim
633208625Sjkim        switch (FieldType)
634208625Sjkim        {
635208625Sjkim        case DT_FIELD_TYPE_FLAGS_INTEGER:
636208625Sjkim            /*
637208625Sjkim             * Start of the definition of a flags field.
638208625Sjkim             * This master flags integer starts at value zero, in preparation
639208625Sjkim             * to compile and insert the flag fields from the individual bits
640208625Sjkim             */
641208625Sjkim            LocalField = LocalField->Next;
642208625Sjkim            *Field = LocalField;
643208625Sjkim
644208625Sjkim            FlagBuffer = Buffer;
645228110Sjkim            CurrentFlagByteOffset = Info->Offset;
646208625Sjkim            break;
647208625Sjkim
648208625Sjkim        case DT_FIELD_TYPE_FLAG:
649208625Sjkim
650208625Sjkim            /* Individual Flag field, can be multiple bits */
651208625Sjkim
652208625Sjkim            if (FlagBuffer)
653208625Sjkim            {
654228110Sjkim                /*
655228110Sjkim                 * We must increment the FlagBuffer when we have crossed
656228110Sjkim                 * into the next flags byte within the flags field
657228110Sjkim                 * of type DT_FIELD_TYPE_FLAGS_INTEGER.
658228110Sjkim                 */
659228110Sjkim                FlagBuffer += (Info->Offset - CurrentFlagByteOffset);
660228110Sjkim                CurrentFlagByteOffset = Info->Offset;
661228110Sjkim
662209734Sjkim                DtCompileFlag (FlagBuffer, LocalField, Info);
663208625Sjkim            }
664208625Sjkim            else
665208625Sjkim            {
666208625Sjkim                /* TBD - this is an internal error */
667208625Sjkim            }
668208625Sjkim
669208625Sjkim            LocalField = LocalField->Next;
670208625Sjkim            *Field = LocalField;
671208625Sjkim            break;
672208625Sjkim
673208625Sjkim        case DT_FIELD_TYPE_INLINE_SUBTABLE:
674208625Sjkim            /*
675208625Sjkim             * Recursion (one level max): compile GAS (Generic Address)
676208625Sjkim             * or Notify in-line subtable
677208625Sjkim             */
678208625Sjkim            *Field = LocalField;
679208625Sjkim
680283092Sjkim            switch (Info->Opcode)
681208625Sjkim            {
682283092Sjkim            case ACPI_DMT_GAS:
683283092Sjkim
684208625Sjkim                Status = DtCompileTable (Field, AcpiDmTableInfoGas,
685208625Sjkim                    &InlineSubtable, TRUE);
686283092Sjkim                break;
687283092Sjkim
688283092Sjkim            case ACPI_DMT_HESTNTFY:
689283092Sjkim
690208625Sjkim                Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify,
691208625Sjkim                    &InlineSubtable, TRUE);
692283092Sjkim                break;
693283092Sjkim
694283092Sjkim            case ACPI_DMT_IORTMEM:
695283092Sjkim
696283092Sjkim                Status = DtCompileTable (Field, AcpiDmTableInfoIortAcc,
697283092Sjkim                    &InlineSubtable, TRUE);
698283092Sjkim                break;
699283092Sjkim
700283092Sjkim            default:
701283092Sjkim                sprintf (MsgBuffer, "Invalid DMT opcode: 0x%.2X",
702283092Sjkim                    Info->Opcode);
703283092Sjkim                DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
704283092Sjkim                Status = AE_BAD_DATA;
705283092Sjkim                break;
706208625Sjkim            }
707208625Sjkim
708208625Sjkim            if (ACPI_FAILURE (Status))
709208625Sjkim            {
710208625Sjkim                goto Error;
711208625Sjkim            }
712208625Sjkim
713209734Sjkim            DtSetSubtableLength (InlineSubtable);
714209734Sjkim
715284583Sjkim            memcpy (Buffer, InlineSubtable->Buffer, FieldLength);
716208625Sjkim            LocalField = *Field;
717208625Sjkim            break;
718208625Sjkim
719218590Sjkim        case DT_FIELD_TYPE_LABEL:
720218590Sjkim
721218590Sjkim            DtWriteFieldToListing (Buffer, LocalField, 0);
722218590Sjkim            LocalField = LocalField->Next;
723218590Sjkim            break;
724218590Sjkim
725208625Sjkim        default:
726208625Sjkim
727208625Sjkim            /* Normal case for most field types (Integer, String, etc.) */
728208625Sjkim
729208625Sjkim            DtCompileOneField (Buffer, LocalField,
730208625Sjkim                FieldLength, FieldType, Info->Flags);
731217365Sjkim
732217365Sjkim            DtWriteFieldToListing (Buffer, LocalField, FieldLength);
733208625Sjkim            LocalField = LocalField->Next;
734208625Sjkim
735208625Sjkim            if (Info->Flags & DT_LENGTH)
736208625Sjkim            {
737208625Sjkim                /* Field is an Integer that will contain a subtable length */
738208625Sjkim
739208625Sjkim                Subtable->LengthField = Buffer;
740208625Sjkim                Subtable->SizeOfLengthField = FieldLength;
741208625Sjkim            }
742208625Sjkim            break;
743208625Sjkim        }
744208625Sjkim
745208625Sjkim        Buffer += FieldLength;
746208625Sjkim    }
747208625Sjkim
748208625Sjkim    *Field = LocalField;
749208625Sjkim    *RetSubtable = Subtable;
750208625Sjkim    return (AE_OK);
751208625Sjkim
752208625SjkimError:
753208625Sjkim    ACPI_FREE (Subtable->Buffer);
754208625Sjkim    ACPI_FREE (Subtable);
755208625Sjkim    return (Status);
756208625Sjkim}
757283092Sjkim
758283092Sjkim
759283092Sjkim/******************************************************************************
760283092Sjkim *
761298714Sjkim * FUNCTION:    DtCompileTwoSubtables
762298714Sjkim *
763298714Sjkim * PARAMETERS:  List                - Current field list pointer
764298714Sjkim *              TableInfo1          - Info table 1
765298714Sjkim *              TableInfo1          - Info table 2
766298714Sjkim *
767298714Sjkim * RETURN:      Status
768298714Sjkim *
769298714Sjkim * DESCRIPTION: Compile tables with a header and one or more same subtables.
770298714Sjkim *              Include CPEP, EINJ, ERST, MCFG, MSCT, WDAT
771298714Sjkim *
772298714Sjkim *****************************************************************************/
773298714Sjkim
774298714SjkimACPI_STATUS
775298714SjkimDtCompileTwoSubtables (
776298714Sjkim    void                    **List,
777298714Sjkim    ACPI_DMTABLE_INFO       *TableInfo1,
778298714Sjkim    ACPI_DMTABLE_INFO       *TableInfo2)
779298714Sjkim{
780298714Sjkim    ACPI_STATUS             Status;
781298714Sjkim    DT_SUBTABLE             *Subtable;
782298714Sjkim    DT_SUBTABLE             *ParentTable;
783298714Sjkim    DT_FIELD                **PFieldList = (DT_FIELD **) List;
784298714Sjkim
785298714Sjkim
786298714Sjkim    Status = DtCompileTable (PFieldList, TableInfo1, &Subtable, TRUE);
787298714Sjkim    if (ACPI_FAILURE (Status))
788298714Sjkim    {
789298714Sjkim        return (Status);
790298714Sjkim    }
791298714Sjkim
792298714Sjkim    ParentTable = DtPeekSubtable ();
793298714Sjkim    DtInsertSubtable (ParentTable, Subtable);
794298714Sjkim
795298714Sjkim    while (*PFieldList)
796298714Sjkim    {
797298714Sjkim        Status = DtCompileTable (PFieldList, TableInfo2, &Subtable, FALSE);
798298714Sjkim        if (ACPI_FAILURE (Status))
799298714Sjkim        {
800298714Sjkim            return (Status);
801298714Sjkim        }
802298714Sjkim
803298714Sjkim        DtInsertSubtable (ParentTable, Subtable);
804298714Sjkim    }
805298714Sjkim
806298714Sjkim    return (AE_OK);
807298714Sjkim}
808298714Sjkim
809298714Sjkim
810298714Sjkim/******************************************************************************
811298714Sjkim *
812283092Sjkim * FUNCTION:    DtCompilePadding
813283092Sjkim *
814283092Sjkim * PARAMETERS:  Length              - Padding field size
815283092Sjkim *              RetSubtable         - Compile result of table
816283092Sjkim *
817283092Sjkim * RETURN:      Status
818283092Sjkim *
819283092Sjkim * DESCRIPTION: Compile a subtable for padding purpose
820283092Sjkim *
821283092Sjkim *****************************************************************************/
822283092Sjkim
823283092SjkimACPI_STATUS
824283092SjkimDtCompilePadding (
825283092Sjkim    UINT32                  Length,
826283092Sjkim    DT_SUBTABLE             **RetSubtable)
827283092Sjkim{
828283092Sjkim    DT_SUBTABLE             *Subtable;
829283092Sjkim    /* UINT8                   *Buffer; */
830283092Sjkim    char                    *String;
831283092Sjkim
832283092Sjkim
833283092Sjkim    Subtable = UtSubtableCacheCalloc ();
834283092Sjkim
835283092Sjkim    if (Length > 0)
836283092Sjkim    {
837327557Sjkim        String = UtLocalCacheCalloc (Length);
838283092Sjkim        Subtable->Buffer = ACPI_CAST_PTR (UINT8, String);
839283092Sjkim    }
840283092Sjkim
841283092Sjkim    Subtable->Length = Length;
842283092Sjkim    Subtable->TotalLength = Length;
843283092Sjkim    /* Buffer = Subtable->Buffer; */
844283092Sjkim
845283092Sjkim    *RetSubtable = Subtable;
846283092Sjkim    return (AE_OK);
847283092Sjkim}
848