1114239Snjl/******************************************************************************
2114239Snjl *
3114239Snjl * Module Name: nsparse - namespace interface to AML parser
4114239Snjl *
5114239Snjl *****************************************************************************/
6114239Snjl
7217365Sjkim/*
8217365Sjkim * Copyright (C) 2000 - 2011, 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
44114239Snjl#define __NSPARSE_C__
45114239Snjl
46193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
47193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
48193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
49193341Sjkim#include <contrib/dev/acpica/include/acparser.h>
50193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
51193341Sjkim#include <contrib/dev/acpica/include/actables.h>
52114239Snjl
53114239Snjl
54114239Snjl#define _COMPONENT          ACPI_NAMESPACE
55114239Snjl        ACPI_MODULE_NAME    ("nsparse")
56114239Snjl
57114239Snjl
58114239Snjl/*******************************************************************************
59114239Snjl *
60114239Snjl * FUNCTION:    NsOneCompleteParse
61114239Snjl *
62114239Snjl * PARAMETERS:  PassNumber              - 1 or 2
63114239Snjl *              TableDesc               - The table to be parsed.
64114239Snjl *
65114239Snjl * RETURN:      Status
66114239Snjl *
67114239Snjl * DESCRIPTION: Perform one complete parse of an ACPI/AML table.
68114239Snjl *
69114239Snjl ******************************************************************************/
70114239Snjl
71114239SnjlACPI_STATUS
72114239SnjlAcpiNsOneCompleteParse (
73193267Sjkim    UINT32                  PassNumber,
74193267Sjkim    UINT32                  TableIndex,
75193267Sjkim    ACPI_NAMESPACE_NODE     *StartNode)
76114239Snjl{
77114239Snjl    ACPI_PARSE_OBJECT       *ParseRoot;
78114239Snjl    ACPI_STATUS             Status;
79193267Sjkim    UINT32                  AmlLength;
80167802Sjkim    UINT8                   *AmlStart;
81114239Snjl    ACPI_WALK_STATE         *WalkState;
82167802Sjkim    ACPI_TABLE_HEADER       *Table;
83167802Sjkim    ACPI_OWNER_ID           OwnerId;
84114239Snjl
85114239Snjl
86167802Sjkim    ACPI_FUNCTION_TRACE (NsOneCompleteParse);
87114239Snjl
88114239Snjl
89167802Sjkim    Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
90167802Sjkim    if (ACPI_FAILURE (Status))
91167802Sjkim    {
92167802Sjkim        return_ACPI_STATUS (Status);
93167802Sjkim    }
94167802Sjkim
95114239Snjl    /* Create and init a Root Node */
96114239Snjl
97114239Snjl    ParseRoot = AcpiPsCreateScopeOp ();
98114239Snjl    if (!ParseRoot)
99114239Snjl    {
100114239Snjl        return_ACPI_STATUS (AE_NO_MEMORY);
101114239Snjl    }
102114239Snjl
103114239Snjl    /* Create and initialize a new walk state */
104114239Snjl
105167802Sjkim    WalkState = AcpiDsCreateWalkState (OwnerId, NULL, NULL, NULL);
106114239Snjl    if (!WalkState)
107114239Snjl    {
108114239Snjl        AcpiPsFreeOp (ParseRoot);
109114239Snjl        return_ACPI_STATUS (AE_NO_MEMORY);
110114239Snjl    }
111114239Snjl
112167802Sjkim    Status = AcpiGetTableByIndex (TableIndex, &Table);
113114239Snjl    if (ACPI_FAILURE (Status))
114114239Snjl    {
115114239Snjl        AcpiDsDeleteWalkState (WalkState);
116167802Sjkim        AcpiPsFreeOp (ParseRoot);
117114239Snjl        return_ACPI_STATUS (Status);
118114239Snjl    }
119114239Snjl
120167802Sjkim    /* Table must consist of at least a complete header */
121167802Sjkim
122167802Sjkim    if (Table->Length < sizeof (ACPI_TABLE_HEADER))
123167802Sjkim    {
124167802Sjkim        Status = AE_BAD_HEADER;
125167802Sjkim    }
126167802Sjkim    else
127167802Sjkim    {
128167802Sjkim        AmlStart = (UINT8 *) Table + sizeof (ACPI_TABLE_HEADER);
129167802Sjkim        AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
130167802Sjkim        Status = AcpiDsInitAmlWalk (WalkState, ParseRoot, NULL,
131167802Sjkim                    AmlStart, AmlLength, NULL, (UINT8) PassNumber);
132167802Sjkim    }
133167802Sjkim
134167802Sjkim    if (ACPI_FAILURE (Status))
135167802Sjkim    {
136167802Sjkim        AcpiDsDeleteWalkState (WalkState);
137193267Sjkim        goto Cleanup;
138167802Sjkim    }
139167802Sjkim
140193267Sjkim    /* StartNode is the default location to load the table  */
141193267Sjkim
142193267Sjkim    if (StartNode && StartNode != AcpiGbl_RootNode)
143193267Sjkim    {
144193267Sjkim        Status = AcpiDsScopeStackPush (StartNode, ACPI_TYPE_METHOD, WalkState);
145193267Sjkim        if (ACPI_FAILURE (Status))
146193267Sjkim        {
147193267Sjkim            AcpiDsDeleteWalkState (WalkState);
148193267Sjkim            goto Cleanup;
149193267Sjkim        }
150193267Sjkim    }
151193267Sjkim
152114239Snjl    /* Parse the AML */
153114239Snjl
154209746Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "*PARSE* pass %u parse\n", PassNumber));
155114239Snjl    Status = AcpiPsParseAml (WalkState);
156114239Snjl
157193267SjkimCleanup:
158114239Snjl    AcpiPsDeleteParseTree (ParseRoot);
159114239Snjl    return_ACPI_STATUS (Status);
160114239Snjl}
161114239Snjl
162114239Snjl
163114239Snjl/*******************************************************************************
164114239Snjl *
165114239Snjl * FUNCTION:    AcpiNsParseTable
166114239Snjl *
167114239Snjl * PARAMETERS:  TableDesc       - An ACPI table descriptor for table to parse
168114239Snjl *              StartNode       - Where to enter the table into the namespace
169114239Snjl *
170114239Snjl * RETURN:      Status
171114239Snjl *
172114239Snjl * DESCRIPTION: Parse AML within an ACPI table and return a tree of ops
173114239Snjl *
174114239Snjl ******************************************************************************/
175114239Snjl
176114239SnjlACPI_STATUS
177114239SnjlAcpiNsParseTable (
178193267Sjkim    UINT32                  TableIndex,
179114239Snjl    ACPI_NAMESPACE_NODE     *StartNode)
180114239Snjl{
181114239Snjl    ACPI_STATUS             Status;
182114239Snjl
183114239Snjl
184167802Sjkim    ACPI_FUNCTION_TRACE (NsParseTable);
185114239Snjl
186114239Snjl
187114239Snjl    /*
188114239Snjl     * AML Parse, pass 1
189114239Snjl     *
190114239Snjl     * In this pass, we load most of the namespace.  Control methods
191114239Snjl     * are not parsed until later.  A parse tree is not created.  Instead,
192114239Snjl     * each Parser Op subtree is deleted when it is finished.  This saves
193114239Snjl     * a great deal of memory, and allows a small cache of parse objects
194114239Snjl     * to service the entire parse.  The second pass of the parse then
195167802Sjkim     * performs another complete parse of the AML.
196114239Snjl     */
197151937Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 1\n"));
198193267Sjkim    Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS1,
199193267Sjkim                TableIndex, StartNode);
200114239Snjl    if (ACPI_FAILURE (Status))
201114239Snjl    {
202114239Snjl        return_ACPI_STATUS (Status);
203114239Snjl    }
204114239Snjl
205114239Snjl    /*
206114239Snjl     * AML Parse, pass 2
207114239Snjl     *
208114239Snjl     * In this pass, we resolve forward references and other things
209114239Snjl     * that could not be completed during the first pass.
210114239Snjl     * Another complete parse of the AML is performed, but the
211114239Snjl     * overhead of this is compensated for by the fact that the
212114239Snjl     * parse objects are all cached.
213114239Snjl     */
214151937Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 2\n"));
215193267Sjkim    Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2,
216193267Sjkim                TableIndex, StartNode);
217114239Snjl    if (ACPI_FAILURE (Status))
218114239Snjl    {
219114239Snjl        return_ACPI_STATUS (Status);
220114239Snjl    }
221114239Snjl
222114239Snjl    return_ACPI_STATUS (Status);
223114239Snjl}
224114239Snjl
225114239Snjl
226