aslload.c revision 193529
1118611Snjl/******************************************************************************
2118611Snjl *
3118611Snjl * Module Name: dswload - Dispatcher namespace load callbacks
4118611Snjl *
5118611Snjl *****************************************************************************/
6118611Snjl
7118611Snjl/******************************************************************************
8118611Snjl *
9118611Snjl * 1. Copyright Notice
10118611Snjl *
11193529Sjkim * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
12118611Snjl * All rights reserved.
13118611Snjl *
14118611Snjl * 2. License
15118611Snjl *
16118611Snjl * 2.1. This is your license from Intel Corp. under its intellectual property
17118611Snjl * rights.  You may have additional license terms from the party that provided
18118611Snjl * you this software, covering your right to use that party's intellectual
19118611Snjl * property rights.
20118611Snjl *
21118611Snjl * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22118611Snjl * copy of the source code appearing in this file ("Covered Code") an
23118611Snjl * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24118611Snjl * base code distributed originally by Intel ("Original Intel Code") to copy,
25118611Snjl * make derivatives, distribute, use and display any portion of the Covered
26118611Snjl * Code in any form, with the right to sublicense such rights; and
27118611Snjl *
28118611Snjl * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29118611Snjl * license (with the right to sublicense), under only those claims of Intel
30118611Snjl * patents that are infringed by the Original Intel Code, to make, use, sell,
31118611Snjl * offer to sell, and import the Covered Code and derivative works thereof
32118611Snjl * solely to the minimum extent necessary to exercise the above copyright
33118611Snjl * license, and in no event shall the patent license extend to any additions
34118611Snjl * to or modifications of the Original Intel Code.  No other license or right
35118611Snjl * is granted directly or by implication, estoppel or otherwise;
36118611Snjl *
37118611Snjl * The above copyright and patent license is granted only if the following
38118611Snjl * conditions are met:
39118611Snjl *
40118611Snjl * 3. Conditions
41118611Snjl *
42118611Snjl * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43118611Snjl * Redistribution of source code of any substantial portion of the Covered
44118611Snjl * Code or modification with rights to further distribute source must include
45118611Snjl * the above Copyright Notice, the above License, this list of Conditions,
46118611Snjl * and the following Disclaimer and Export Compliance provision.  In addition,
47118611Snjl * Licensee must cause all Covered Code to which Licensee contributes to
48118611Snjl * contain a file documenting the changes Licensee made to create that Covered
49118611Snjl * Code and the date of any change.  Licensee must include in that file the
50118611Snjl * documentation of any changes made by any predecessor Licensee.  Licensee
51118611Snjl * must include a prominent statement that the modification is derived,
52118611Snjl * directly or indirectly, from Original Intel Code.
53118611Snjl *
54118611Snjl * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55118611Snjl * Redistribution of source code of any substantial portion of the Covered
56118611Snjl * Code or modification without rights to further distribute source must
57118611Snjl * include the following Disclaimer and Export Compliance provision in the
58118611Snjl * documentation and/or other materials provided with distribution.  In
59118611Snjl * addition, Licensee may not authorize further sublicense of source of any
60118611Snjl * portion of the Covered Code, and must include terms to the effect that the
61118611Snjl * license from Licensee to its licensee is limited to the intellectual
62118611Snjl * property embodied in the software Licensee provides to its licensee, and
63118611Snjl * not to intellectual property embodied in modifications its licensee may
64118611Snjl * make.
65118611Snjl *
66118611Snjl * 3.3. Redistribution of Executable. Redistribution in executable form of any
67118611Snjl * substantial portion of the Covered Code or modification must reproduce the
68118611Snjl * above Copyright Notice, and the following Disclaimer and Export Compliance
69118611Snjl * provision in the documentation and/or other materials provided with the
70118611Snjl * distribution.
71118611Snjl *
72118611Snjl * 3.4. Intel retains all right, title, and interest in and to the Original
73118611Snjl * Intel Code.
74118611Snjl *
75118611Snjl * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76118611Snjl * Intel shall be used in advertising or otherwise to promote the sale, use or
77118611Snjl * other dealings in products derived from or relating to the Covered Code
78118611Snjl * without prior written authorization from Intel.
79118611Snjl *
80118611Snjl * 4. Disclaimer and Export Compliance
81118611Snjl *
82118611Snjl * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83118611Snjl * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84118611Snjl * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85118611Snjl * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86118611Snjl * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87118611Snjl * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88118611Snjl * PARTICULAR PURPOSE.
89118611Snjl *
90118611Snjl * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91118611Snjl * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92118611Snjl * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93118611Snjl * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94118611Snjl * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95118611Snjl * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96118611Snjl * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97118611Snjl * LIMITED REMEDY.
98118611Snjl *
99118611Snjl * 4.3. Licensee shall not export, either directly or indirectly, any of this
100118611Snjl * software or system incorporating such software without first obtaining any
101118611Snjl * required license or other approval from the U. S. Department of Commerce or
102118611Snjl * any other agency or department of the United States Government.  In the
103118611Snjl * event Licensee exports any such software from the United States or
104118611Snjl * re-exports any such software from a foreign destination, Licensee shall
105118611Snjl * ensure that the distribution and export/re-export of the software is in
106118611Snjl * compliance with all laws, regulations, orders, or other restrictions of the
107118611Snjl * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108118611Snjl * any of its subsidiaries will export/re-export any technical data, process,
109118611Snjl * software, or service, directly or indirectly, to any country for which the
110118611Snjl * United States government or any agency thereof requires an export license,
111118611Snjl * other governmental approval, or letter of assurance, without first obtaining
112118611Snjl * such license, approval or letter.
113118611Snjl *
114118611Snjl *****************************************************************************/
115118611Snjl
116118611Snjl#define __ASLLOAD_C__
117118611Snjl
118151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
119193529Sjkim#include <contrib/dev/acpica/include/amlcode.h>
120193529Sjkim#include <contrib/dev/acpica/include/acdispat.h>
121193529Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
122118611Snjl
123118611Snjl#include "aslcompiler.y.h"
124118611Snjl
125118611Snjl#define _COMPONENT          ACPI_COMPILER
126118611Snjl        ACPI_MODULE_NAME    ("aslload")
127118611Snjl
128151937Sjkim/* Local prototypes */
129118611Snjl
130151937Sjkimstatic ACPI_STATUS
131151937SjkimLdLoadFieldElements (
132151937Sjkim    ACPI_PARSE_OBJECT       *Op,
133151937Sjkim    ACPI_WALK_STATE         *WalkState);
134151937Sjkim
135151937Sjkimstatic ACPI_STATUS
136151937SjkimLdLoadResourceElements (
137151937Sjkim    ACPI_PARSE_OBJECT       *Op,
138151937Sjkim    ACPI_WALK_STATE         *WalkState);
139151937Sjkim
140151937Sjkimstatic ACPI_STATUS
141151937SjkimLdNamespace1Begin (
142151937Sjkim    ACPI_PARSE_OBJECT       *Op,
143151937Sjkim    UINT32                  Level,
144151937Sjkim    void                    *Context);
145151937Sjkim
146151937Sjkimstatic ACPI_STATUS
147193529SjkimLdNamespace2Begin (
148151937Sjkim    ACPI_PARSE_OBJECT       *Op,
149151937Sjkim    UINT32                  Level,
150151937Sjkim    void                    *Context);
151151937Sjkim
152193529Sjkimstatic ACPI_STATUS
153193529SjkimLdCommonNamespaceEnd (
154193529Sjkim    ACPI_PARSE_OBJECT       *Op,
155193529Sjkim    UINT32                  Level,
156193529Sjkim    void                    *Context);
157151937Sjkim
158193529Sjkim
159118611Snjl/*******************************************************************************
160118611Snjl *
161118611Snjl * FUNCTION:    LdLoadNamespace
162118611Snjl *
163151937Sjkim * PARAMETERS:  RootOp      - Root of the parse tree
164118611Snjl *
165118611Snjl * RETURN:      Status
166118611Snjl *
167118611Snjl * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the
168193529Sjkim *              named ASL/AML objects into the namespace. The namespace is
169118611Snjl *              constructed in order to resolve named references and references
170118611Snjl *              to named fields within resource templates/descriptors.
171118611Snjl *
172118611Snjl ******************************************************************************/
173118611Snjl
174118611SnjlACPI_STATUS
175118611SnjlLdLoadNamespace (
176118611Snjl    ACPI_PARSE_OBJECT       *RootOp)
177118611Snjl{
178118611Snjl    ACPI_WALK_STATE         *WalkState;
179118611Snjl
180118611Snjl
181118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nCreating namespace\n\n");
182118611Snjl
183118611Snjl    /* Create a new walk state */
184118611Snjl
185118611Snjl    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
186118611Snjl    if (!WalkState)
187118611Snjl    {
188118611Snjl        return AE_NO_MEMORY;
189118611Snjl    }
190118611Snjl
191193529Sjkim    /* Walk the entire parse tree, first pass */
192118611Snjl
193118611Snjl    TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin,
194193529Sjkim        LdCommonNamespaceEnd, WalkState);
195118611Snjl
196193529Sjkim    /* Second pass to handle forward references */
197193529Sjkim
198193529Sjkim    TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin,
199193529Sjkim        LdCommonNamespaceEnd, WalkState);
200193529Sjkim
201118611Snjl    /* Dump the namespace if debug is enabled */
202118611Snjl
203118611Snjl    AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX);
204118611Snjl    return AE_OK;
205118611Snjl}
206118611Snjl
207118611Snjl
208118611Snjl/*******************************************************************************
209118611Snjl *
210118611Snjl * FUNCTION:    LdLoadFieldElements
211118611Snjl *
212151937Sjkim * PARAMETERS:  Op              - Parent node (Field)
213118611Snjl *              WalkState       - Current walk state
214118611Snjl *
215118611Snjl * RETURN:      Status
216118611Snjl *
217118611Snjl * DESCRIPTION: Enter the named elements of the field (children of the parent)
218118611Snjl *              into the namespace.
219118611Snjl *
220118611Snjl ******************************************************************************/
221118611Snjl
222151937Sjkimstatic ACPI_STATUS
223118611SnjlLdLoadFieldElements (
224118611Snjl    ACPI_PARSE_OBJECT       *Op,
225118611Snjl    ACPI_WALK_STATE         *WalkState)
226118611Snjl{
227118611Snjl    ACPI_PARSE_OBJECT       *Child = NULL;
228118611Snjl    ACPI_NAMESPACE_NODE     *Node;
229118611Snjl    ACPI_STATUS             Status;
230118611Snjl
231118611Snjl
232118611Snjl    /* Get the first named field element */
233118611Snjl
234118611Snjl    switch (Op->Asl.AmlOpcode)
235118611Snjl    {
236118611Snjl    case AML_BANK_FIELD_OP:
237118611Snjl
238118611Snjl        Child = UtGetArg (Op, 6);
239118611Snjl        break;
240118611Snjl
241118611Snjl    case AML_INDEX_FIELD_OP:
242118611Snjl
243118611Snjl        Child = UtGetArg (Op, 5);
244118611Snjl        break;
245118611Snjl
246118611Snjl    case AML_FIELD_OP:
247118611Snjl
248118611Snjl        Child = UtGetArg (Op, 4);
249118611Snjl        break;
250118611Snjl
251118611Snjl    default:
252118611Snjl        /* No other opcodes should arrive here */
253118611Snjl        return (AE_BAD_PARAMETER);
254118611Snjl    }
255118611Snjl
256118611Snjl    /* Enter all elements into the namespace */
257118611Snjl
258118611Snjl    while (Child)
259118611Snjl    {
260118611Snjl        switch (Child->Asl.AmlOpcode)
261118611Snjl        {
262118611Snjl        case AML_INT_RESERVEDFIELD_OP:
263118611Snjl        case AML_INT_ACCESSFIELD_OP:
264118611Snjl
265118611Snjl            break;
266118611Snjl
267118611Snjl        default:
268118611Snjl
269151937Sjkim            Status = AcpiNsLookup (WalkState->ScopeInfo,
270151937Sjkim                        Child->Asl.Value.String,
271151937Sjkim                        ACPI_TYPE_LOCAL_REGION_FIELD,
272151937Sjkim                        ACPI_IMODE_LOAD_PASS1,
273151937Sjkim                        ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
274151937Sjkim                            ACPI_NS_ERROR_IF_FOUND,
275151937Sjkim                        NULL, &Node);
276118611Snjl            if (ACPI_FAILURE (Status))
277118611Snjl            {
278118611Snjl                if (Status != AE_ALREADY_EXISTS)
279118611Snjl                {
280151937Sjkim                    AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child,
281151937Sjkim                        Child->Asl.Value.String);
282151937Sjkim                    return (Status);
283118611Snjl                }
284118611Snjl
285118611Snjl                /*
286118611Snjl                 * The name already exists in this scope
287118611Snjl                 * But continue processing the elements
288118611Snjl                 */
289151937Sjkim                AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,
290151937Sjkim                    Child->Asl.Value.String);
291118611Snjl            }
292118611Snjl            else
293118611Snjl            {
294118611Snjl                Child->Asl.Node = Node;
295151937Sjkim                Node->Op = Child;
296118611Snjl            }
297118611Snjl            break;
298118611Snjl        }
299118611Snjl        Child = Child->Asl.Next;
300118611Snjl    }
301118611Snjl    return (AE_OK);
302118611Snjl}
303118611Snjl
304118611Snjl
305118611Snjl/*******************************************************************************
306118611Snjl *
307118611Snjl * FUNCTION:    LdLoadResourceElements
308118611Snjl *
309151937Sjkim * PARAMETERS:  Op              - Parent node (Resource Descriptor)
310118611Snjl *              WalkState       - Current walk state
311118611Snjl *
312118611Snjl * RETURN:      Status
313118611Snjl *
314118611Snjl * DESCRIPTION: Enter the named elements of the resource descriptor (children
315118611Snjl *              of the parent) into the namespace.
316118611Snjl *
317193529Sjkim * NOTE: In the real AML namespace, these named elements never exist. But
318118611Snjl *       we simply use the namespace here as a symbol table so we can look
319118611Snjl *       them up as they are referenced.
320118611Snjl *
321118611Snjl ******************************************************************************/
322118611Snjl
323151937Sjkimstatic ACPI_STATUS
324118611SnjlLdLoadResourceElements (
325118611Snjl    ACPI_PARSE_OBJECT       *Op,
326118611Snjl    ACPI_WALK_STATE         *WalkState)
327118611Snjl{
328118611Snjl    ACPI_PARSE_OBJECT       *InitializerOp = NULL;
329118611Snjl    ACPI_NAMESPACE_NODE     *Node;
330118611Snjl    ACPI_STATUS             Status;
331118611Snjl
332118611Snjl
333118611Snjl    /*
334151937Sjkim     * Enter the resource name into the namespace. Name must not already exist.
335151937Sjkim     * This opens a scope, so later field names are guaranteed to be new/unique.
336118611Snjl     */
337118611Snjl    Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath,
338151937Sjkim                ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1,
339151937Sjkim                ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND,
340151937Sjkim                WalkState, &Node);
341118611Snjl    if (ACPI_FAILURE (Status))
342118611Snjl    {
343151937Sjkim        if (Status == AE_ALREADY_EXISTS)
344151937Sjkim        {
345151937Sjkim            /* Actual node causing the error was saved in ParentMethod */
346151937Sjkim
347151937Sjkim            AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS,
348151937Sjkim                (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath);
349151937Sjkim            return (AE_OK);
350151937Sjkim        }
351118611Snjl        return (Status);
352118611Snjl    }
353118611Snjl
354167802Sjkim    Node->Value = (UINT32) Op->Asl.Value.Integer;
355167802Sjkim    Node->Op = Op;
356167802Sjkim
357118611Snjl    /*
358118611Snjl     * Now enter the predefined fields, for easy lookup when referenced
359118611Snjl     * by the source ASL
360118611Snjl     */
361118611Snjl    InitializerOp = ASL_GET_CHILD_NODE (Op);
362118611Snjl    while (InitializerOp)
363118611Snjl    {
364118611Snjl
365118611Snjl        if (InitializerOp->Asl.ExternalName)
366118611Snjl        {
367118611Snjl            Status = AcpiNsLookup (WalkState->ScopeInfo,
368151937Sjkim                        InitializerOp->Asl.ExternalName,
369151937Sjkim                        ACPI_TYPE_LOCAL_RESOURCE_FIELD,
370151937Sjkim                        ACPI_IMODE_LOAD_PASS1,
371151937Sjkim                        ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE,
372151937Sjkim                        NULL, &Node);
373118611Snjl            if (ACPI_FAILURE (Status))
374118611Snjl            {
375118611Snjl                return (Status);
376118611Snjl            }
377118611Snjl
378118611Snjl            /*
379118611Snjl             * Store the field offset in the namespace node so it
380118611Snjl             * can be used when the field is referenced
381118611Snjl             */
382151937Sjkim            Node->Value = (UINT32) InitializerOp->Asl.Value.Integer;
383118611Snjl            InitializerOp->Asl.Node = Node;
384151937Sjkim            Node->Op = InitializerOp;
385118611Snjl
386118611Snjl            /* Pass thru the field type (Bitfield or Bytefield) */
387118611Snjl
388118611Snjl            if (InitializerOp->Asl.CompileFlags & NODE_IS_BIT_OFFSET)
389118611Snjl            {
390118611Snjl                Node->Flags |= ANOBJ_IS_BIT_OFFSET;
391118611Snjl            }
392118611Snjl        }
393118611Snjl        InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
394118611Snjl    }
395118611Snjl
396118611Snjl    return (AE_OK);
397118611Snjl}
398118611Snjl
399118611Snjl
400118611Snjl/*******************************************************************************
401118611Snjl *
402118611Snjl * FUNCTION:    LdNamespace1Begin
403118611Snjl *
404118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
405118611Snjl *
406118611Snjl * RETURN:      Status
407118611Snjl *
408193529Sjkim * DESCRIPTION: Descending callback used during the parse tree walk. If this
409118611Snjl *              is a named AML opcode, enter into the namespace
410118611Snjl *
411118611Snjl ******************************************************************************/
412118611Snjl
413151937Sjkimstatic ACPI_STATUS
414118611SnjlLdNamespace1Begin (
415118611Snjl    ACPI_PARSE_OBJECT       *Op,
416118611Snjl    UINT32                  Level,
417118611Snjl    void                    *Context)
418118611Snjl{
419118611Snjl    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
420118611Snjl    ACPI_NAMESPACE_NODE     *Node;
421118611Snjl    ACPI_STATUS             Status;
422118611Snjl    ACPI_OBJECT_TYPE        ObjectType;
423118611Snjl    ACPI_OBJECT_TYPE        ActualObjectType = ACPI_TYPE_ANY;
424118611Snjl    char                    *Path;
425118611Snjl    UINT32                  Flags = ACPI_NS_NO_UPSEARCH;
426118611Snjl    ACPI_PARSE_OBJECT       *Arg;
427118611Snjl    UINT32                  i;
428167802Sjkim    BOOLEAN                 ForceNewScope = FALSE;
429118611Snjl
430118611Snjl
431167802Sjkim    ACPI_FUNCTION_NAME (LdNamespace1Begin);
432118611Snjl    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
433118611Snjl        Op, Op->Asl.ParseOpName));
434118611Snjl
435118611Snjl
436118611Snjl    /*
437118611Snjl     * We are only interested in opcodes that have an associated name
438118611Snjl     * (or multiple names)
439118611Snjl     */
440118611Snjl    switch (Op->Asl.AmlOpcode)
441118611Snjl    {
442118611Snjl    case AML_BANK_FIELD_OP:
443118611Snjl    case AML_INDEX_FIELD_OP:
444118611Snjl    case AML_FIELD_OP:
445118611Snjl
446118611Snjl        Status = LdLoadFieldElements (Op, WalkState);
447118611Snjl        return (Status);
448118611Snjl
449118611Snjl    default:
450118611Snjl
451118611Snjl        /* All other opcodes go below */
452118611Snjl        break;
453118611Snjl    }
454118611Snjl
455118611Snjl    /* Check if this object has already been installed in the namespace */
456118611Snjl
457118611Snjl    if (Op->Asl.Node)
458118611Snjl    {
459118611Snjl        return (AE_OK);
460118611Snjl    }
461118611Snjl
462118611Snjl    Path = Op->Asl.Namepath;
463118611Snjl    if (!Path)
464118611Snjl    {
465118611Snjl        return (AE_OK);
466118611Snjl    }
467118611Snjl
468118611Snjl    /* Map the raw opcode into an internal object type */
469118611Snjl
470118611Snjl    switch (Op->Asl.ParseOpcode)
471118611Snjl    {
472118611Snjl    case PARSEOP_NAME:
473118611Snjl
474151937Sjkim        Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
475151937Sjkim        Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
476118611Snjl
477167802Sjkim        /*
478167802Sjkim         * If this name refers to a ResourceTemplate, we will need to open
479167802Sjkim         * a new scope so that the resource subfield names can be entered into
480167802Sjkim         * the namespace underneath this name
481167802Sjkim         */
482167802Sjkim        if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
483167802Sjkim        {
484167802Sjkim            ForceNewScope = TRUE;
485167802Sjkim        }
486167802Sjkim
487118611Snjl        /* Get the data type associated with the named object, not the name itself */
488118611Snjl
489118611Snjl        /* Log2 loop to convert from Btype (binary) to Etype (encoded) */
490118611Snjl
491118611Snjl        ObjectType = 1;
492118611Snjl        for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2)
493118611Snjl        {
494118611Snjl            ObjectType++;
495118611Snjl        }
496118611Snjl        break;
497118611Snjl
498118611Snjl
499118611Snjl    case PARSEOP_EXTERNAL:
500118611Snjl
501118611Snjl        /*
502118611Snjl         * "External" simply enters a name and type into the namespace.
503118611Snjl         * We must be careful to not open a new scope, however, no matter
504118611Snjl         * what type the external name refers to (e.g., a method)
505118611Snjl         *
506118611Snjl         * first child is name, next child is ObjectType
507118611Snjl         */
508118611Snjl        ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer;
509118611Snjl        ObjectType = ACPI_TYPE_ANY;
510167802Sjkim
511167802Sjkim        /*
512167802Sjkim         * We will mark every new node along the path as "External". This
513167802Sjkim         * allows some or all of the nodes to be created later in the ASL
514167802Sjkim         * code. Handles cases like this:
515167802Sjkim         *
516167802Sjkim         *   External (\_SB_.PCI0.ABCD, IntObj)
517167802Sjkim         *   Scope (_SB_)
518167802Sjkim         *   {
519167802Sjkim         *       Device (PCI0)
520167802Sjkim         *       {
521167802Sjkim         *       }
522167802Sjkim         *   }
523167802Sjkim         *   Method (X)
524167802Sjkim         *   {
525167802Sjkim         *       Store (\_SB_.PCI0.ABCD, Local0)
526167802Sjkim         *   }
527167802Sjkim         */
528167802Sjkim        Flags |= ACPI_NS_EXTERNAL;
529118611Snjl        break;
530118611Snjl
531118611Snjl    case PARSEOP_DEFAULT_ARG:
532118611Snjl
533167802Sjkim        if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)
534118611Snjl        {
535118611Snjl            Status = LdLoadResourceElements (Op, WalkState);
536118611Snjl            goto Exit;
537118611Snjl        }
538118611Snjl
539118611Snjl        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
540118611Snjl        break;
541118611Snjl
542118611Snjl
543118611Snjl    case PARSEOP_SCOPE:
544118611Snjl
545118611Snjl        /*
546118611Snjl         * The name referenced by Scope(Name) must already exist at this point.
547118611Snjl         * In other words, forward references for Scope() are not supported.
548118611Snjl         * The only real reason for this is that the MS interpreter cannot
549193529Sjkim         * handle this case. Perhaps someday this case can go away.
550118611Snjl         */
551118611Snjl        Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
552151937Sjkim                    ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
553151937Sjkim                    WalkState, &(Node));
554118611Snjl        if (ACPI_FAILURE (Status))
555118611Snjl        {
556118611Snjl            if (Status == AE_NOT_FOUND)
557118611Snjl            {
558118611Snjl                /* The name was not found, go ahead and create it */
559118611Snjl
560151937Sjkim                Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
561151937Sjkim                            ACPI_TYPE_LOCAL_SCOPE,
562151937Sjkim                            ACPI_IMODE_LOAD_PASS1, Flags,
563151937Sjkim                            WalkState, &(Node));
564118611Snjl
565118611Snjl                /*
566118611Snjl                 * However, this is an error -- primarily because the MS
567118611Snjl                 * interpreter can't handle a forward reference from the
568118611Snjl                 * Scope() operator.
569118611Snjl                 */
570151937Sjkim                AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
571151937Sjkim                    Op->Asl.ExternalName);
572151937Sjkim                AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op,
573151937Sjkim                    Op->Asl.ExternalName);
574118611Snjl                goto FinishNode;
575118611Snjl            }
576118611Snjl
577118611Snjl            AslCoreSubsystemError (Op, Status, "Failure from lookup\n", FALSE);
578118611Snjl            goto Exit;
579118611Snjl        }
580118611Snjl
581118611Snjl        /* We found a node with this name, now check the type */
582118611Snjl
583118611Snjl        switch (Node->Type)
584118611Snjl        {
585118611Snjl        case ACPI_TYPE_LOCAL_SCOPE:
586118611Snjl        case ACPI_TYPE_DEVICE:
587118611Snjl        case ACPI_TYPE_POWER:
588118611Snjl        case ACPI_TYPE_PROCESSOR:
589118611Snjl        case ACPI_TYPE_THERMAL:
590118611Snjl
591118611Snjl            /* These are acceptable types - they all open a new scope */
592118611Snjl            break;
593118611Snjl
594118611Snjl        case ACPI_TYPE_INTEGER:
595118611Snjl        case ACPI_TYPE_STRING:
596118611Snjl        case ACPI_TYPE_BUFFER:
597118611Snjl
598118611Snjl            /*
599151937Sjkim             * These types we will allow, but we will change the type.
600151937Sjkim             * This enables some existing code of the form:
601118611Snjl             *
602118611Snjl             *  Name (DEB, 0)
603118611Snjl             *  Scope (DEB) { ... }
604118611Snjl             *
605118611Snjl             * Which is used to workaround the fact that the MS interpreter
606118611Snjl             * does not allow Scope() forward references.
607118611Snjl             */
608128212Snjl            sprintf (MsgBuffer, "%s [%s], changing type to [Scope]",
609118611Snjl                Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
610118611Snjl            AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
611118611Snjl
612151937Sjkim            /* Switch the type to scope, open the new scope */
613151937Sjkim
614128212Snjl            Node->Type = ACPI_TYPE_LOCAL_SCOPE;
615151937Sjkim            Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
616151937Sjkim                        WalkState);
617128212Snjl            if (ACPI_FAILURE (Status))
618128212Snjl            {
619128212Snjl                return_ACPI_STATUS (Status);
620128212Snjl            }
621118611Snjl            break;
622118611Snjl
623118611Snjl        default:
624118611Snjl
625151937Sjkim            /* All other types are an error */
626151937Sjkim
627151937Sjkim            sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName,
628151937Sjkim                AcpiUtGetTypeName (Node->Type));
629118611Snjl            AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
630118611Snjl
631118611Snjl            /*
632118611Snjl             * However, switch the type to be an actual scope so
633118611Snjl             * that compilation can continue without generating a whole
634193529Sjkim             * cascade of additional errors. Open the new scope.
635118611Snjl             */
636128212Snjl            Node->Type = ACPI_TYPE_LOCAL_SCOPE;
637151937Sjkim            Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
638151937Sjkim                        WalkState);
639128212Snjl            if (ACPI_FAILURE (Status))
640128212Snjl            {
641128212Snjl                return_ACPI_STATUS (Status);
642128212Snjl            }
643118611Snjl            break;
644118611Snjl        }
645118611Snjl
646118611Snjl        Status = AE_OK;
647118611Snjl        goto FinishNode;
648118611Snjl
649118611Snjl
650118611Snjl    default:
651118611Snjl
652118611Snjl        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
653118611Snjl        break;
654118611Snjl    }
655118611Snjl
656118611Snjl
657118611Snjl    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n",
658118611Snjl            Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType)));
659118611Snjl
660118611Snjl    /* The name must not already exist */
661118611Snjl
662118611Snjl    Flags |= ACPI_NS_ERROR_IF_FOUND;
663118611Snjl
664118611Snjl    /*
665193529Sjkim     * Enter the named type into the internal namespace. We enter the name
666193529Sjkim     * as we go downward in the parse tree. Any necessary subobjects that
667151937Sjkim     * involve arguments to the opcode must be created as we go back up the
668151937Sjkim     * parse tree later.
669118611Snjl     */
670118611Snjl    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
671167802Sjkim                    ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
672118611Snjl    if (ACPI_FAILURE (Status))
673118611Snjl    {
674118611Snjl        if (Status == AE_ALREADY_EXISTS)
675118611Snjl        {
676118611Snjl            /* The name already exists in this scope */
677118611Snjl
678118611Snjl            if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
679118611Snjl            {
680167802Sjkim                /* Allow multiple references to the same scope */
681167802Sjkim
682118611Snjl                Node->Type = (UINT8) ObjectType;
683118611Snjl                Status = AE_OK;
684118611Snjl            }
685193529Sjkim            else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
686193529Sjkim                     (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
687167802Sjkim            {
688167802Sjkim                /*
689167802Sjkim                 * Allow one create on an object or segment that was
690167802Sjkim                 * previously declared External
691167802Sjkim                 */
692167802Sjkim                Node->Flags &= ~ANOBJ_IS_EXTERNAL;
693167802Sjkim                Node->Type = (UINT8) ObjectType;
694167802Sjkim
695167802Sjkim                /* Just retyped a node, probably will need to open a scope */
696167802Sjkim
697167802Sjkim                if (AcpiNsOpensScope (ObjectType))
698167802Sjkim                {
699167802Sjkim                    Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
700167802Sjkim                    if (ACPI_FAILURE (Status))
701167802Sjkim                    {
702167802Sjkim                        return_ACPI_STATUS (Status);
703167802Sjkim                    }
704167802Sjkim                }
705167802Sjkim                Status = AE_OK;
706167802Sjkim            }
707118611Snjl            else
708118611Snjl            {
709167802Sjkim                /* Valid error, object already exists */
710167802Sjkim
711151937Sjkim                AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
712151937Sjkim                    Op->Asl.ExternalName);
713118611Snjl                Status = AE_OK;
714118611Snjl                goto Exit;
715118611Snjl            }
716118611Snjl        }
717118611Snjl        else
718118611Snjl        {
719151937Sjkim            AslCoreSubsystemError (Op, Status,
720151937Sjkim                "Failure from lookup %s\n", FALSE);
721118611Snjl            goto Exit;
722118611Snjl        }
723118611Snjl    }
724118611Snjl
725167802Sjkim    if (ForceNewScope)
726167802Sjkim    {
727167802Sjkim        Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
728167802Sjkim        if (ACPI_FAILURE (Status))
729167802Sjkim        {
730167802Sjkim            return_ACPI_STATUS (Status);
731167802Sjkim        }
732167802Sjkim    }
733118611Snjl
734118611SnjlFinishNode:
735118611Snjl    /*
736118611Snjl     * Point the parse node to the new namespace node, and point
737118611Snjl     * the Node back to the original Parse node
738118611Snjl     */
739118611Snjl    Op->Asl.Node = Node;
740151937Sjkim    Node->Op = Op;
741118611Snjl
742118611Snjl    /* Set the actual data type if appropriate (EXTERNAL term only) */
743118611Snjl
744118611Snjl    if (ActualObjectType != ACPI_TYPE_ANY)
745118611Snjl    {
746118611Snjl        Node->Type = (UINT8) ActualObjectType;
747151937Sjkim        Node->Value = ASL_EXTERNAL_METHOD;
748118611Snjl    }
749118611Snjl
750118611Snjl    if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
751118611Snjl    {
752118611Snjl        /*
753151937Sjkim         * Get the method argument count from "Extra" and save
754151937Sjkim         * it in the namespace node
755118611Snjl         */
756151937Sjkim        Node->Value = (UINT32) Op->Asl.Extra;
757118611Snjl    }
758118611Snjl
759118611SnjlExit:
760118611Snjl    return (Status);
761118611Snjl}
762118611Snjl
763118611Snjl
764118611Snjl/*******************************************************************************
765118611Snjl *
766193529Sjkim * FUNCTION:    LdNamespace2Begin
767118611Snjl *
768118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
769118611Snjl *
770118611Snjl * RETURN:      Status
771118611Snjl *
772193529Sjkim * DESCRIPTION: Descending callback used during the pass 2 parse tree walk.
773193529Sjkim *              Second pass resolves some forward references.
774193529Sjkim *
775193529Sjkim * Notes:
776193529Sjkim * Currently only needs to handle the Alias operator.
777193529Sjkim * Could be used to allow forward references from the Scope() operator, but
778193529Sjkim * the MS interpreter does not allow this, so this compiler does not either.
779193529Sjkim *
780193529Sjkim ******************************************************************************/
781193529Sjkim
782193529Sjkimstatic ACPI_STATUS
783193529SjkimLdNamespace2Begin (
784193529Sjkim    ACPI_PARSE_OBJECT       *Op,
785193529Sjkim    UINT32                  Level,
786193529Sjkim    void                    *Context)
787193529Sjkim{
788193529Sjkim    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
789193529Sjkim    ACPI_STATUS             Status;
790193529Sjkim    ACPI_NAMESPACE_NODE     *Node;
791193529Sjkim    ACPI_OBJECT_TYPE        ObjectType;
792193529Sjkim    BOOLEAN                 ForceNewScope = FALSE;
793193529Sjkim    ACPI_PARSE_OBJECT       *Arg;
794193529Sjkim    char                    *Path;
795193529Sjkim    ACPI_NAMESPACE_NODE     *TargetNode;
796193529Sjkim
797193529Sjkim
798193529Sjkim    ACPI_FUNCTION_NAME (LdNamespace2Begin);
799193529Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
800193529Sjkim        Op, Op->Asl.ParseOpName));
801193529Sjkim
802193529Sjkim
803193529Sjkim    /* Ignore Ops with no namespace node */
804193529Sjkim
805193529Sjkim    Node = Op->Asl.Node;
806193529Sjkim    if (!Node)
807193529Sjkim    {
808193529Sjkim        return (AE_OK);
809193529Sjkim    }
810193529Sjkim
811193529Sjkim    /* Get the type to determine if we should push the scope */
812193529Sjkim
813193529Sjkim    if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
814193529Sjkim        (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
815193529Sjkim    {
816193529Sjkim        ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
817193529Sjkim    }
818193529Sjkim    else
819193529Sjkim    {
820193529Sjkim        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
821193529Sjkim    }
822193529Sjkim
823193529Sjkim    /* Push scope for Resource Templates */
824193529Sjkim
825193529Sjkim    if (Op->Asl.ParseOpcode == PARSEOP_NAME)
826193529Sjkim    {
827193529Sjkim        if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
828193529Sjkim        {
829193529Sjkim            ForceNewScope = TRUE;
830193529Sjkim        }
831193529Sjkim    }
832193529Sjkim
833193529Sjkim    /* Push the scope stack */
834193529Sjkim
835193529Sjkim    if (ForceNewScope || AcpiNsOpensScope (ObjectType))
836193529Sjkim    {
837193529Sjkim        Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
838193529Sjkim        if (ACPI_FAILURE (Status))
839193529Sjkim        {
840193529Sjkim            return_ACPI_STATUS (Status);
841193529Sjkim        }
842193529Sjkim    }
843193529Sjkim
844193529Sjkim    if (Op->Asl.ParseOpcode == PARSEOP_ALIAS)
845193529Sjkim    {
846193529Sjkim        /* Complete the alias node by getting and saving the target node */
847193529Sjkim
848193529Sjkim        /* First child is the alias target */
849193529Sjkim
850193529Sjkim        Arg = Op->Asl.Child;
851193529Sjkim
852193529Sjkim        /* Get the target pathname */
853193529Sjkim
854193529Sjkim        Path = Arg->Asl.Namepath;
855193529Sjkim        if (!Path)
856193529Sjkim        {
857193529Sjkim            Status = UtInternalizeName (Arg->Asl.ExternalName, &Path);
858193529Sjkim            if (ACPI_FAILURE (Status))
859193529Sjkim            {
860193529Sjkim                return (Status);
861193529Sjkim            }
862193529Sjkim        }
863193529Sjkim
864193529Sjkim        /* Get the NS node associated with the target. It must exist. */
865193529Sjkim
866193529Sjkim        Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
867193529Sjkim                    ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
868193529Sjkim                    WalkState, &TargetNode);
869193529Sjkim        if (ACPI_FAILURE (Status))
870193529Sjkim        {
871193529Sjkim            if (Status == AE_NOT_FOUND)
872193529Sjkim            {
873193529Sjkim                AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
874193529Sjkim                    Op->Asl.ExternalName);
875193529Sjkim
876193529Sjkim                /*
877193529Sjkim                 * The name was not found, go ahead and create it.
878193529Sjkim                 * This prevents more errors later.
879193529Sjkim                 */
880193529Sjkim                Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
881193529Sjkim                            ACPI_TYPE_ANY,
882193529Sjkim                            ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH,
883193529Sjkim                            WalkState, &(Node));
884193529Sjkim                return (AE_OK);
885193529Sjkim            }
886193529Sjkim
887193529Sjkim            AslCoreSubsystemError (Op, Status, "Failure from lookup\n", FALSE);
888193529Sjkim            return (AE_OK);
889193529Sjkim        }
890193529Sjkim
891193529Sjkim        /* Save the target node within the alias node */
892193529Sjkim
893193529Sjkim        Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
894193529Sjkim    }
895193529Sjkim
896193529Sjkim    return (AE_OK);
897193529Sjkim}
898193529Sjkim
899193529Sjkim
900193529Sjkim/*******************************************************************************
901193529Sjkim *
902193529Sjkim * FUNCTION:    LdCommonNamespaceEnd
903193529Sjkim *
904193529Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
905193529Sjkim *
906193529Sjkim * RETURN:      Status
907193529Sjkim *
908118611Snjl * DESCRIPTION: Ascending callback used during the loading of the namespace,
909118611Snjl *              We only need to worry about managing the scope stack here.
910118611Snjl *
911118611Snjl ******************************************************************************/
912118611Snjl
913151937Sjkimstatic ACPI_STATUS
914193529SjkimLdCommonNamespaceEnd (
915118611Snjl    ACPI_PARSE_OBJECT       *Op,
916118611Snjl    UINT32                  Level,
917118611Snjl    void                    *Context)
918118611Snjl{
919118611Snjl    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
920118611Snjl    ACPI_OBJECT_TYPE        ObjectType;
921167802Sjkim    BOOLEAN                 ForceNewScope = FALSE;
922118611Snjl
923118611Snjl
924193529Sjkim    ACPI_FUNCTION_NAME (LdCommonNamespaceEnd);
925118611Snjl
926118611Snjl
927118611Snjl    /* We are only interested in opcodes that have an associated name */
928118611Snjl
929118611Snjl    if (!Op->Asl.Namepath)
930118611Snjl    {
931118611Snjl        return (AE_OK);
932118611Snjl    }
933118611Snjl
934118611Snjl    /* Get the type to determine if we should pop the scope */
935118611Snjl
936118611Snjl    if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
937118611Snjl        (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
938118611Snjl    {
939118611Snjl        /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */
940118611Snjl
941118611Snjl        ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
942118611Snjl    }
943118611Snjl    else
944118611Snjl    {
945118611Snjl        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
946118611Snjl    }
947118611Snjl
948167802Sjkim    /* Pop scope that was pushed for Resource Templates */
949167802Sjkim
950167802Sjkim    if (Op->Asl.ParseOpcode == PARSEOP_NAME)
951167802Sjkim    {
952167802Sjkim        if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
953167802Sjkim        {
954167802Sjkim            ForceNewScope = TRUE;
955167802Sjkim        }
956167802Sjkim    }
957167802Sjkim
958118611Snjl    /* Pop the scope stack */
959118611Snjl
960167802Sjkim    if (ForceNewScope || AcpiNsOpensScope (ObjectType))
961118611Snjl    {
962118611Snjl        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
963118611Snjl            "(%s): Popping scope for Op [%s] %p\n",
964118611Snjl            AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op));
965118611Snjl
966151937Sjkim        (void) AcpiDsScopeStackPop (WalkState);
967118611Snjl    }
968118611Snjl
969118611Snjl    return (AE_OK);
970118611Snjl}
971118611Snjl
972118611Snjl
973