1114239Snjl/******************************************************************************
2114239Snjl *
3114239Snjl * Module Name: nsparse - namespace interface to AML parser
4114239Snjl *
5114239Snjl *****************************************************************************/
6114239Snjl
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
9114239Snjl * All rights reserved.
10114239Snjl *
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.
25114239Snjl *
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.
29114239Snjl *
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 */
43114239Snjl
44193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
45193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
46193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
47193341Sjkim#include <contrib/dev/acpica/include/acparser.h>
48193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
49193341Sjkim#include <contrib/dev/acpica/include/actables.h>
50114239Snjl
51114239Snjl
52114239Snjl#define _COMPONENT          ACPI_NAMESPACE
53114239Snjl        ACPI_MODULE_NAME    ("nsparse")
54114239Snjl
55114239Snjl
56114239Snjl/*******************************************************************************
57114239Snjl *
58114239Snjl * FUNCTION:    NsOneCompleteParse
59114239Snjl *
60114239Snjl * PARAMETERS:  PassNumber              - 1 or 2
61114239Snjl *              TableDesc               - The table to be parsed.
62114239Snjl *
63114239Snjl * RETURN:      Status
64114239Snjl *
65114239Snjl * DESCRIPTION: Perform one complete parse of an ACPI/AML table.
66114239Snjl *
67114239Snjl ******************************************************************************/
68114239Snjl
69114239SnjlACPI_STATUS
70114239SnjlAcpiNsOneCompleteParse (
71193267Sjkim    UINT32                  PassNumber,
72193267Sjkim    UINT32                  TableIndex,
73193267Sjkim    ACPI_NAMESPACE_NODE     *StartNode)
74114239Snjl{
75114239Snjl    ACPI_PARSE_OBJECT       *ParseRoot;
76114239Snjl    ACPI_STATUS             Status;
77193267Sjkim    UINT32                  AmlLength;
78167802Sjkim    UINT8                   *AmlStart;
79114239Snjl    ACPI_WALK_STATE         *WalkState;
80167802Sjkim    ACPI_TABLE_HEADER       *Table;
81167802Sjkim    ACPI_OWNER_ID           OwnerId;
82114239Snjl
83114239Snjl
84167802Sjkim    ACPI_FUNCTION_TRACE (NsOneCompleteParse);
85114239Snjl
86114239Snjl
87306536Sjkim    Status = AcpiGetTableByIndex (TableIndex, &Table);
88306536Sjkim    if (ACPI_FAILURE (Status))
89306536Sjkim    {
90306536Sjkim        return_ACPI_STATUS (Status);
91306536Sjkim    }
92306536Sjkim
93306536Sjkim    /* Table must consist of at least a complete header */
94306536Sjkim
95306536Sjkim    if (Table->Length < sizeof (ACPI_TABLE_HEADER))
96306536Sjkim    {
97306536Sjkim        return_ACPI_STATUS (AE_BAD_HEADER);
98306536Sjkim    }
99306536Sjkim
100306536Sjkim    AmlStart = (UINT8 *) Table + sizeof (ACPI_TABLE_HEADER);
101306536Sjkim    AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
102306536Sjkim
103167802Sjkim    Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
104167802Sjkim    if (ACPI_FAILURE (Status))
105167802Sjkim    {
106167802Sjkim        return_ACPI_STATUS (Status);
107167802Sjkim    }
108167802Sjkim
109114239Snjl    /* Create and init a Root Node */
110114239Snjl
111306536Sjkim    ParseRoot = AcpiPsCreateScopeOp (AmlStart);
112114239Snjl    if (!ParseRoot)
113114239Snjl    {
114114239Snjl        return_ACPI_STATUS (AE_NO_MEMORY);
115114239Snjl    }
116114239Snjl
117114239Snjl    /* Create and initialize a new walk state */
118114239Snjl
119167802Sjkim    WalkState = AcpiDsCreateWalkState (OwnerId, NULL, NULL, NULL);
120114239Snjl    if (!WalkState)
121114239Snjl    {
122114239Snjl        AcpiPsFreeOp (ParseRoot);
123114239Snjl        return_ACPI_STATUS (AE_NO_MEMORY);
124114239Snjl    }
125114239Snjl
126306536Sjkim    Status = AcpiDsInitAmlWalk (WalkState, ParseRoot, NULL,
127306536Sjkim        AmlStart, AmlLength, NULL, (UINT8) PassNumber);
128114239Snjl    if (ACPI_FAILURE (Status))
129114239Snjl    {
130114239Snjl        AcpiDsDeleteWalkState (WalkState);
131306536Sjkim        goto Cleanup;
132114239Snjl    }
133114239Snjl
134306536Sjkim    /* Found OSDT table, enable the namespace override feature */
135167802Sjkim
136306536Sjkim    if (ACPI_COMPARE_NAME(Table->Signature, ACPI_SIG_OSDT) &&
137306536Sjkim        PassNumber == ACPI_IMODE_LOAD_PASS1)
138167802Sjkim    {
139306536Sjkim        WalkState->NamespaceOverride = TRUE;
140167802Sjkim    }
141167802Sjkim
142193267Sjkim    /* StartNode is the default location to load the table  */
143193267Sjkim
144193267Sjkim    if (StartNode && StartNode != AcpiGbl_RootNode)
145193267Sjkim    {
146306536Sjkim        Status = AcpiDsScopeStackPush (
147306536Sjkim            StartNode, ACPI_TYPE_METHOD, WalkState);
148193267Sjkim        if (ACPI_FAILURE (Status))
149193267Sjkim        {
150193267Sjkim            AcpiDsDeleteWalkState (WalkState);
151193267Sjkim            goto Cleanup;
152193267Sjkim        }
153193267Sjkim    }
154193267Sjkim
155114239Snjl    /* Parse the AML */
156114239Snjl
157306536Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
158306536Sjkim        "*PARSE* pass %u parse\n", PassNumber));
159114239Snjl    Status = AcpiPsParseAml (WalkState);
160114239Snjl
161193267SjkimCleanup:
162114239Snjl    AcpiPsDeleteParseTree (ParseRoot);
163114239Snjl    return_ACPI_STATUS (Status);
164114239Snjl}
165114239Snjl
166114239Snjl
167114239Snjl/*******************************************************************************
168114239Snjl *
169114239Snjl * FUNCTION:    AcpiNsParseTable
170114239Snjl *
171114239Snjl * PARAMETERS:  TableDesc       - An ACPI table descriptor for table to parse
172114239Snjl *              StartNode       - Where to enter the table into the namespace
173114239Snjl *
174114239Snjl * RETURN:      Status
175114239Snjl *
176114239Snjl * DESCRIPTION: Parse AML within an ACPI table and return a tree of ops
177114239Snjl *
178114239Snjl ******************************************************************************/
179114239Snjl
180114239SnjlACPI_STATUS
181114239SnjlAcpiNsParseTable (
182193267Sjkim    UINT32                  TableIndex,
183114239Snjl    ACPI_NAMESPACE_NODE     *StartNode)
184114239Snjl{
185114239Snjl    ACPI_STATUS             Status;
186114239Snjl
187114239Snjl
188167802Sjkim    ACPI_FUNCTION_TRACE (NsParseTable);
189114239Snjl
190114239Snjl
191114239Snjl    /*
192114239Snjl     * AML Parse, pass 1
193114239Snjl     *
194241973Sjkim     * In this pass, we load most of the namespace. Control methods
195241973Sjkim     * are not parsed until later. A parse tree is not created. Instead,
196241973Sjkim     * each Parser Op subtree is deleted when it is finished. This saves
197114239Snjl     * a great deal of memory, and allows a small cache of parse objects
198241973Sjkim     * to service the entire parse. The second pass of the parse then
199167802Sjkim     * performs another complete parse of the AML.
200114239Snjl     */
201151937Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 1\n"));
202306536Sjkim
203193267Sjkim    Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS1,
204306536Sjkim        TableIndex, StartNode);
205114239Snjl    if (ACPI_FAILURE (Status))
206114239Snjl    {
207114239Snjl        return_ACPI_STATUS (Status);
208114239Snjl    }
209114239Snjl
210114239Snjl    /*
211114239Snjl     * AML Parse, pass 2
212114239Snjl     *
213114239Snjl     * In this pass, we resolve forward references and other things
214114239Snjl     * that could not be completed during the first pass.
215114239Snjl     * Another complete parse of the AML is performed, but the
216114239Snjl     * overhead of this is compensated for by the fact that the
217114239Snjl     * parse objects are all cached.
218114239Snjl     */
219151937Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 2\n"));
220193267Sjkim    Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2,
221306536Sjkim        TableIndex, StartNode);
222114239Snjl    if (ACPI_FAILURE (Status))
223114239Snjl    {
224114239Snjl        return_ACPI_STATUS (Status);
225114239Snjl    }
226114239Snjl
227114239Snjl    return_ACPI_STATUS (Status);
228114239Snjl}
229