1118611Snjl/******************************************************************************
2118611Snjl *
3118611Snjl * Module Name: dswload - Dispatcher namespace load callbacks
4118611Snjl *
5118611Snjl *****************************************************************************/
6118611Snjl
7217365Sjkim/*
8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp.
9118611Snjl * All rights reserved.
10118611Snjl *
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.
25118611Snjl *
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.
29118611Snjl *
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 */
43118611Snjl
44118611Snjl#define __ASLLOAD_C__
45118611Snjl
46151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
47193529Sjkim#include <contrib/dev/acpica/include/amlcode.h>
48193529Sjkim#include <contrib/dev/acpica/include/acdispat.h>
49193529Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
50118611Snjl
51118611Snjl#include "aslcompiler.y.h"
52118611Snjl
53118611Snjl#define _COMPONENT          ACPI_COMPILER
54118611Snjl        ACPI_MODULE_NAME    ("aslload")
55118611Snjl
56151937Sjkim/* Local prototypes */
57118611Snjl
58151937Sjkimstatic ACPI_STATUS
59151937SjkimLdLoadFieldElements (
60151937Sjkim    ACPI_PARSE_OBJECT       *Op,
61151937Sjkim    ACPI_WALK_STATE         *WalkState);
62151937Sjkim
63151937Sjkimstatic ACPI_STATUS
64151937SjkimLdLoadResourceElements (
65151937Sjkim    ACPI_PARSE_OBJECT       *Op,
66151937Sjkim    ACPI_WALK_STATE         *WalkState);
67151937Sjkim
68151937Sjkimstatic ACPI_STATUS
69151937SjkimLdNamespace1Begin (
70151937Sjkim    ACPI_PARSE_OBJECT       *Op,
71151937Sjkim    UINT32                  Level,
72151937Sjkim    void                    *Context);
73151937Sjkim
74151937Sjkimstatic ACPI_STATUS
75193529SjkimLdNamespace2Begin (
76151937Sjkim    ACPI_PARSE_OBJECT       *Op,
77151937Sjkim    UINT32                  Level,
78151937Sjkim    void                    *Context);
79151937Sjkim
80193529Sjkimstatic ACPI_STATUS
81193529SjkimLdCommonNamespaceEnd (
82193529Sjkim    ACPI_PARSE_OBJECT       *Op,
83193529Sjkim    UINT32                  Level,
84193529Sjkim    void                    *Context);
85151937Sjkim
86193529Sjkim
87118611Snjl/*******************************************************************************
88118611Snjl *
89118611Snjl * FUNCTION:    LdLoadNamespace
90118611Snjl *
91151937Sjkim * PARAMETERS:  RootOp      - Root of the parse tree
92118611Snjl *
93118611Snjl * RETURN:      Status
94118611Snjl *
95118611Snjl * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the
96193529Sjkim *              named ASL/AML objects into the namespace. The namespace is
97118611Snjl *              constructed in order to resolve named references and references
98118611Snjl *              to named fields within resource templates/descriptors.
99118611Snjl *
100118611Snjl ******************************************************************************/
101118611Snjl
102118611SnjlACPI_STATUS
103118611SnjlLdLoadNamespace (
104118611Snjl    ACPI_PARSE_OBJECT       *RootOp)
105118611Snjl{
106118611Snjl    ACPI_WALK_STATE         *WalkState;
107118611Snjl
108118611Snjl
109118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nCreating namespace\n\n");
110118611Snjl
111118611Snjl    /* Create a new walk state */
112118611Snjl
113118611Snjl    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
114118611Snjl    if (!WalkState)
115118611Snjl    {
116241973Sjkim        return (AE_NO_MEMORY);
117118611Snjl    }
118118611Snjl
119193529Sjkim    /* Walk the entire parse tree, first pass */
120118611Snjl
121118611Snjl    TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin,
122193529Sjkim        LdCommonNamespaceEnd, WalkState);
123118611Snjl
124193529Sjkim    /* Second pass to handle forward references */
125193529Sjkim
126193529Sjkim    TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin,
127193529Sjkim        LdCommonNamespaceEnd, WalkState);
128193529Sjkim
129118611Snjl    /* Dump the namespace if debug is enabled */
130118611Snjl
131118611Snjl    AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX);
132241973Sjkim    return (AE_OK);
133118611Snjl}
134118611Snjl
135118611Snjl
136118611Snjl/*******************************************************************************
137118611Snjl *
138118611Snjl * FUNCTION:    LdLoadFieldElements
139118611Snjl *
140151937Sjkim * PARAMETERS:  Op              - Parent node (Field)
141118611Snjl *              WalkState       - Current walk state
142118611Snjl *
143118611Snjl * RETURN:      Status
144118611Snjl *
145118611Snjl * DESCRIPTION: Enter the named elements of the field (children of the parent)
146118611Snjl *              into the namespace.
147118611Snjl *
148118611Snjl ******************************************************************************/
149118611Snjl
150151937Sjkimstatic ACPI_STATUS
151118611SnjlLdLoadFieldElements (
152118611Snjl    ACPI_PARSE_OBJECT       *Op,
153118611Snjl    ACPI_WALK_STATE         *WalkState)
154118611Snjl{
155118611Snjl    ACPI_PARSE_OBJECT       *Child = NULL;
156118611Snjl    ACPI_NAMESPACE_NODE     *Node;
157118611Snjl    ACPI_STATUS             Status;
158118611Snjl
159118611Snjl
160118611Snjl    /* Get the first named field element */
161118611Snjl
162118611Snjl    switch (Op->Asl.AmlOpcode)
163118611Snjl    {
164118611Snjl    case AML_BANK_FIELD_OP:
165118611Snjl
166118611Snjl        Child = UtGetArg (Op, 6);
167118611Snjl        break;
168118611Snjl
169118611Snjl    case AML_INDEX_FIELD_OP:
170118611Snjl
171118611Snjl        Child = UtGetArg (Op, 5);
172118611Snjl        break;
173118611Snjl
174118611Snjl    case AML_FIELD_OP:
175118611Snjl
176118611Snjl        Child = UtGetArg (Op, 4);
177118611Snjl        break;
178118611Snjl
179118611Snjl    default:
180250838Sjkim
181118611Snjl        /* No other opcodes should arrive here */
182250838Sjkim
183118611Snjl        return (AE_BAD_PARAMETER);
184118611Snjl    }
185118611Snjl
186118611Snjl    /* Enter all elements into the namespace */
187118611Snjl
188118611Snjl    while (Child)
189118611Snjl    {
190118611Snjl        switch (Child->Asl.AmlOpcode)
191118611Snjl        {
192118611Snjl        case AML_INT_RESERVEDFIELD_OP:
193118611Snjl        case AML_INT_ACCESSFIELD_OP:
194228110Sjkim        case AML_INT_CONNECTION_OP:
195118611Snjl            break;
196118611Snjl
197118611Snjl        default:
198118611Snjl
199151937Sjkim            Status = AcpiNsLookup (WalkState->ScopeInfo,
200151937Sjkim                        Child->Asl.Value.String,
201151937Sjkim                        ACPI_TYPE_LOCAL_REGION_FIELD,
202151937Sjkim                        ACPI_IMODE_LOAD_PASS1,
203151937Sjkim                        ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
204151937Sjkim                            ACPI_NS_ERROR_IF_FOUND,
205151937Sjkim                        NULL, &Node);
206118611Snjl            if (ACPI_FAILURE (Status))
207118611Snjl            {
208118611Snjl                if (Status != AE_ALREADY_EXISTS)
209118611Snjl                {
210151937Sjkim                    AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child,
211151937Sjkim                        Child->Asl.Value.String);
212151937Sjkim                    return (Status);
213118611Snjl                }
214118611Snjl
215118611Snjl                /*
216118611Snjl                 * The name already exists in this scope
217118611Snjl                 * But continue processing the elements
218118611Snjl                 */
219151937Sjkim                AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,
220151937Sjkim                    Child->Asl.Value.String);
221118611Snjl            }
222118611Snjl            else
223118611Snjl            {
224118611Snjl                Child->Asl.Node = Node;
225151937Sjkim                Node->Op = Child;
226118611Snjl            }
227118611Snjl            break;
228118611Snjl        }
229228110Sjkim
230118611Snjl        Child = Child->Asl.Next;
231118611Snjl    }
232228110Sjkim
233118611Snjl    return (AE_OK);
234118611Snjl}
235118611Snjl
236118611Snjl
237118611Snjl/*******************************************************************************
238118611Snjl *
239118611Snjl * FUNCTION:    LdLoadResourceElements
240118611Snjl *
241151937Sjkim * PARAMETERS:  Op              - Parent node (Resource Descriptor)
242118611Snjl *              WalkState       - Current walk state
243118611Snjl *
244118611Snjl * RETURN:      Status
245118611Snjl *
246118611Snjl * DESCRIPTION: Enter the named elements of the resource descriptor (children
247118611Snjl *              of the parent) into the namespace.
248118611Snjl *
249193529Sjkim * NOTE: In the real AML namespace, these named elements never exist. But
250118611Snjl *       we simply use the namespace here as a symbol table so we can look
251118611Snjl *       them up as they are referenced.
252118611Snjl *
253118611Snjl ******************************************************************************/
254118611Snjl
255151937Sjkimstatic ACPI_STATUS
256118611SnjlLdLoadResourceElements (
257118611Snjl    ACPI_PARSE_OBJECT       *Op,
258118611Snjl    ACPI_WALK_STATE         *WalkState)
259118611Snjl{
260118611Snjl    ACPI_PARSE_OBJECT       *InitializerOp = NULL;
261118611Snjl    ACPI_NAMESPACE_NODE     *Node;
262118611Snjl    ACPI_STATUS             Status;
263118611Snjl
264118611Snjl
265118611Snjl    /*
266151937Sjkim     * Enter the resource name into the namespace. Name must not already exist.
267151937Sjkim     * This opens a scope, so later field names are guaranteed to be new/unique.
268118611Snjl     */
269118611Snjl    Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath,
270151937Sjkim                ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1,
271151937Sjkim                ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND,
272151937Sjkim                WalkState, &Node);
273118611Snjl    if (ACPI_FAILURE (Status))
274118611Snjl    {
275151937Sjkim        if (Status == AE_ALREADY_EXISTS)
276151937Sjkim        {
277151937Sjkim            /* Actual node causing the error was saved in ParentMethod */
278151937Sjkim
279151937Sjkim            AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS,
280151937Sjkim                (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath);
281151937Sjkim            return (AE_OK);
282151937Sjkim        }
283118611Snjl        return (Status);
284118611Snjl    }
285118611Snjl
286167802Sjkim    Node->Value = (UINT32) Op->Asl.Value.Integer;
287167802Sjkim    Node->Op = Op;
288197104Sjkim    Op->Asl.Node = Node;
289167802Sjkim
290118611Snjl    /*
291118611Snjl     * Now enter the predefined fields, for easy lookup when referenced
292118611Snjl     * by the source ASL
293118611Snjl     */
294118611Snjl    InitializerOp = ASL_GET_CHILD_NODE (Op);
295118611Snjl    while (InitializerOp)
296118611Snjl    {
297118611Snjl        if (InitializerOp->Asl.ExternalName)
298118611Snjl        {
299118611Snjl            Status = AcpiNsLookup (WalkState->ScopeInfo,
300151937Sjkim                        InitializerOp->Asl.ExternalName,
301151937Sjkim                        ACPI_TYPE_LOCAL_RESOURCE_FIELD,
302151937Sjkim                        ACPI_IMODE_LOAD_PASS1,
303151937Sjkim                        ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE,
304151937Sjkim                        NULL, &Node);
305118611Snjl            if (ACPI_FAILURE (Status))
306118611Snjl            {
307118611Snjl                return (Status);
308118611Snjl            }
309118611Snjl
310118611Snjl            /*
311228110Sjkim             * Store the field offset and length in the namespace node
312228110Sjkim             * so it can be used when the field is referenced
313118611Snjl             */
314228110Sjkim            Node->Value = InitializerOp->Asl.Value.Tag.BitOffset;
315228110Sjkim            Node->Length = InitializerOp->Asl.Value.Tag.BitLength;
316118611Snjl            InitializerOp->Asl.Node = Node;
317151937Sjkim            Node->Op = InitializerOp;
318228110Sjkim        }
319118611Snjl
320118611Snjl        InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
321118611Snjl    }
322118611Snjl
323118611Snjl    return (AE_OK);
324118611Snjl}
325118611Snjl
326118611Snjl
327118611Snjl/*******************************************************************************
328118611Snjl *
329118611Snjl * FUNCTION:    LdNamespace1Begin
330118611Snjl *
331118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
332118611Snjl *
333118611Snjl * RETURN:      Status
334118611Snjl *
335193529Sjkim * DESCRIPTION: Descending callback used during the parse tree walk. If this
336118611Snjl *              is a named AML opcode, enter into the namespace
337118611Snjl *
338118611Snjl ******************************************************************************/
339118611Snjl
340151937Sjkimstatic ACPI_STATUS
341118611SnjlLdNamespace1Begin (
342118611Snjl    ACPI_PARSE_OBJECT       *Op,
343118611Snjl    UINT32                  Level,
344118611Snjl    void                    *Context)
345118611Snjl{
346118611Snjl    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
347118611Snjl    ACPI_NAMESPACE_NODE     *Node;
348118611Snjl    ACPI_STATUS             Status;
349118611Snjl    ACPI_OBJECT_TYPE        ObjectType;
350118611Snjl    ACPI_OBJECT_TYPE        ActualObjectType = ACPI_TYPE_ANY;
351118611Snjl    char                    *Path;
352118611Snjl    UINT32                  Flags = ACPI_NS_NO_UPSEARCH;
353118611Snjl    ACPI_PARSE_OBJECT       *Arg;
354118611Snjl    UINT32                  i;
355167802Sjkim    BOOLEAN                 ForceNewScope = FALSE;
356118611Snjl
357118611Snjl
358167802Sjkim    ACPI_FUNCTION_NAME (LdNamespace1Begin);
359118611Snjl    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
360118611Snjl        Op, Op->Asl.ParseOpName));
361118611Snjl
362118611Snjl
363118611Snjl    /*
364118611Snjl     * We are only interested in opcodes that have an associated name
365118611Snjl     * (or multiple names)
366118611Snjl     */
367118611Snjl    switch (Op->Asl.AmlOpcode)
368118611Snjl    {
369118611Snjl    case AML_BANK_FIELD_OP:
370118611Snjl    case AML_INDEX_FIELD_OP:
371118611Snjl    case AML_FIELD_OP:
372118611Snjl
373118611Snjl        Status = LdLoadFieldElements (Op, WalkState);
374118611Snjl        return (Status);
375118611Snjl
376118611Snjl    default:
377118611Snjl
378118611Snjl        /* All other opcodes go below */
379250838Sjkim
380118611Snjl        break;
381118611Snjl    }
382118611Snjl
383118611Snjl    /* Check if this object has already been installed in the namespace */
384118611Snjl
385118611Snjl    if (Op->Asl.Node)
386118611Snjl    {
387118611Snjl        return (AE_OK);
388118611Snjl    }
389118611Snjl
390118611Snjl    Path = Op->Asl.Namepath;
391118611Snjl    if (!Path)
392118611Snjl    {
393118611Snjl        return (AE_OK);
394118611Snjl    }
395118611Snjl
396118611Snjl    /* Map the raw opcode into an internal object type */
397118611Snjl
398118611Snjl    switch (Op->Asl.ParseOpcode)
399118611Snjl    {
400118611Snjl    case PARSEOP_NAME:
401118611Snjl
402151937Sjkim        Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
403151937Sjkim        Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
404118611Snjl
405167802Sjkim        /*
406167802Sjkim         * If this name refers to a ResourceTemplate, we will need to open
407167802Sjkim         * a new scope so that the resource subfield names can be entered into
408167802Sjkim         * the namespace underneath this name
409167802Sjkim         */
410167802Sjkim        if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
411167802Sjkim        {
412167802Sjkim            ForceNewScope = TRUE;
413167802Sjkim        }
414167802Sjkim
415118611Snjl        /* Get the data type associated with the named object, not the name itself */
416118611Snjl
417118611Snjl        /* Log2 loop to convert from Btype (binary) to Etype (encoded) */
418118611Snjl
419118611Snjl        ObjectType = 1;
420118611Snjl        for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2)
421118611Snjl        {
422118611Snjl            ObjectType++;
423118611Snjl        }
424118611Snjl        break;
425118611Snjl
426118611Snjl
427118611Snjl    case PARSEOP_EXTERNAL:
428118611Snjl        /*
429118611Snjl         * "External" simply enters a name and type into the namespace.
430118611Snjl         * We must be careful to not open a new scope, however, no matter
431118611Snjl         * what type the external name refers to (e.g., a method)
432118611Snjl         *
433118611Snjl         * first child is name, next child is ObjectType
434118611Snjl         */
435118611Snjl        ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer;
436118611Snjl        ObjectType = ACPI_TYPE_ANY;
437167802Sjkim
438167802Sjkim        /*
439167802Sjkim         * We will mark every new node along the path as "External". This
440167802Sjkim         * allows some or all of the nodes to be created later in the ASL
441167802Sjkim         * code. Handles cases like this:
442167802Sjkim         *
443167802Sjkim         *   External (\_SB_.PCI0.ABCD, IntObj)
444167802Sjkim         *   Scope (_SB_)
445167802Sjkim         *   {
446167802Sjkim         *       Device (PCI0)
447167802Sjkim         *       {
448167802Sjkim         *       }
449167802Sjkim         *   }
450167802Sjkim         *   Method (X)
451167802Sjkim         *   {
452167802Sjkim         *       Store (\_SB_.PCI0.ABCD, Local0)
453167802Sjkim         *   }
454167802Sjkim         */
455167802Sjkim        Flags |= ACPI_NS_EXTERNAL;
456118611Snjl        break;
457118611Snjl
458118611Snjl    case PARSEOP_DEFAULT_ARG:
459118611Snjl
460167802Sjkim        if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)
461118611Snjl        {
462118611Snjl            Status = LdLoadResourceElements (Op, WalkState);
463202771Sjkim            return_ACPI_STATUS (Status);
464118611Snjl        }
465118611Snjl
466118611Snjl        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
467118611Snjl        break;
468118611Snjl
469118611Snjl
470118611Snjl    case PARSEOP_SCOPE:
471118611Snjl        /*
472118611Snjl         * The name referenced by Scope(Name) must already exist at this point.
473118611Snjl         * In other words, forward references for Scope() are not supported.
474118611Snjl         * The only real reason for this is that the MS interpreter cannot
475193529Sjkim         * handle this case. Perhaps someday this case can go away.
476118611Snjl         */
477118611Snjl        Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
478151937Sjkim                    ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
479151937Sjkim                    WalkState, &(Node));
480118611Snjl        if (ACPI_FAILURE (Status))
481118611Snjl        {
482118611Snjl            if (Status == AE_NOT_FOUND)
483118611Snjl            {
484118611Snjl                /* The name was not found, go ahead and create it */
485118611Snjl
486151937Sjkim                Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
487151937Sjkim                            ACPI_TYPE_LOCAL_SCOPE,
488151937Sjkim                            ACPI_IMODE_LOAD_PASS1, Flags,
489151937Sjkim                            WalkState, &(Node));
490254745Sjkim                if (ACPI_FAILURE (Status))
491254745Sjkim                {
492254745Sjkim                    return_ACPI_STATUS (Status);
493254745Sjkim                }
494118611Snjl
495118611Snjl                /*
496118611Snjl                 * However, this is an error -- primarily because the MS
497118611Snjl                 * interpreter can't handle a forward reference from the
498118611Snjl                 * Scope() operator.
499118611Snjl                 */
500151937Sjkim                AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
501151937Sjkim                    Op->Asl.ExternalName);
502151937Sjkim                AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op,
503151937Sjkim                    Op->Asl.ExternalName);
504118611Snjl                goto FinishNode;
505118611Snjl            }
506118611Snjl
507198237Sjkim            AslCoreSubsystemError (Op, Status,
508198237Sjkim                "Failure from namespace lookup", FALSE);
509198237Sjkim
510202771Sjkim            return_ACPI_STATUS (Status);
511118611Snjl        }
512118611Snjl
513118611Snjl        /* We found a node with this name, now check the type */
514118611Snjl
515118611Snjl        switch (Node->Type)
516118611Snjl        {
517118611Snjl        case ACPI_TYPE_LOCAL_SCOPE:
518118611Snjl        case ACPI_TYPE_DEVICE:
519118611Snjl        case ACPI_TYPE_POWER:
520118611Snjl        case ACPI_TYPE_PROCESSOR:
521118611Snjl        case ACPI_TYPE_THERMAL:
522118611Snjl
523118611Snjl            /* These are acceptable types - they all open a new scope */
524118611Snjl            break;
525118611Snjl
526118611Snjl        case ACPI_TYPE_INTEGER:
527118611Snjl        case ACPI_TYPE_STRING:
528118611Snjl        case ACPI_TYPE_BUFFER:
529118611Snjl            /*
530151937Sjkim             * These types we will allow, but we will change the type.
531151937Sjkim             * This enables some existing code of the form:
532118611Snjl             *
533118611Snjl             *  Name (DEB, 0)
534118611Snjl             *  Scope (DEB) { ... }
535118611Snjl             *
536118611Snjl             * Which is used to workaround the fact that the MS interpreter
537118611Snjl             * does not allow Scope() forward references.
538118611Snjl             */
539128212Snjl            sprintf (MsgBuffer, "%s [%s], changing type to [Scope]",
540118611Snjl                Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
541118611Snjl            AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
542118611Snjl
543151937Sjkim            /* Switch the type to scope, open the new scope */
544151937Sjkim
545128212Snjl            Node->Type = ACPI_TYPE_LOCAL_SCOPE;
546151937Sjkim            Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
547151937Sjkim                        WalkState);
548128212Snjl            if (ACPI_FAILURE (Status))
549128212Snjl            {
550128212Snjl                return_ACPI_STATUS (Status);
551128212Snjl            }
552118611Snjl            break;
553118611Snjl
554118611Snjl        default:
555118611Snjl
556151937Sjkim            /* All other types are an error */
557151937Sjkim
558151937Sjkim            sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName,
559151937Sjkim                AcpiUtGetTypeName (Node->Type));
560118611Snjl            AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
561118611Snjl
562118611Snjl            /*
563118611Snjl             * However, switch the type to be an actual scope so
564118611Snjl             * that compilation can continue without generating a whole
565193529Sjkim             * cascade of additional errors. Open the new scope.
566118611Snjl             */
567128212Snjl            Node->Type = ACPI_TYPE_LOCAL_SCOPE;
568151937Sjkim            Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
569151937Sjkim                        WalkState);
570128212Snjl            if (ACPI_FAILURE (Status))
571128212Snjl            {
572128212Snjl                return_ACPI_STATUS (Status);
573128212Snjl            }
574118611Snjl            break;
575118611Snjl        }
576118611Snjl
577118611Snjl        Status = AE_OK;
578118611Snjl        goto FinishNode;
579118611Snjl
580118611Snjl
581118611Snjl    default:
582118611Snjl
583118611Snjl        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
584118611Snjl        break;
585118611Snjl    }
586118611Snjl
587118611Snjl
588118611Snjl    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n",
589118611Snjl            Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType)));
590118611Snjl
591118611Snjl    /* The name must not already exist */
592118611Snjl
593118611Snjl    Flags |= ACPI_NS_ERROR_IF_FOUND;
594118611Snjl
595118611Snjl    /*
596193529Sjkim     * Enter the named type into the internal namespace. We enter the name
597193529Sjkim     * as we go downward in the parse tree. Any necessary subobjects that
598151937Sjkim     * involve arguments to the opcode must be created as we go back up the
599151937Sjkim     * parse tree later.
600118611Snjl     */
601118611Snjl    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
602167802Sjkim                    ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
603118611Snjl    if (ACPI_FAILURE (Status))
604118611Snjl    {
605118611Snjl        if (Status == AE_ALREADY_EXISTS)
606118611Snjl        {
607118611Snjl            /* The name already exists in this scope */
608118611Snjl
609118611Snjl            if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
610118611Snjl            {
611167802Sjkim                /* Allow multiple references to the same scope */
612167802Sjkim
613118611Snjl                Node->Type = (UINT8) ObjectType;
614118611Snjl                Status = AE_OK;
615118611Snjl            }
616193529Sjkim            else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
617193529Sjkim                     (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
618167802Sjkim            {
619167802Sjkim                /*
620167802Sjkim                 * Allow one create on an object or segment that was
621167802Sjkim                 * previously declared External
622167802Sjkim                 */
623167802Sjkim                Node->Flags &= ~ANOBJ_IS_EXTERNAL;
624167802Sjkim                Node->Type = (UINT8) ObjectType;
625167802Sjkim
626167802Sjkim                /* Just retyped a node, probably will need to open a scope */
627167802Sjkim
628167802Sjkim                if (AcpiNsOpensScope (ObjectType))
629167802Sjkim                {
630167802Sjkim                    Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
631167802Sjkim                    if (ACPI_FAILURE (Status))
632167802Sjkim                    {
633167802Sjkim                        return_ACPI_STATUS (Status);
634167802Sjkim                    }
635167802Sjkim                }
636167802Sjkim                Status = AE_OK;
637167802Sjkim            }
638118611Snjl            else
639118611Snjl            {
640167802Sjkim                /* Valid error, object already exists */
641167802Sjkim
642151937Sjkim                AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
643151937Sjkim                    Op->Asl.ExternalName);
644202771Sjkim                return_ACPI_STATUS (AE_OK);
645118611Snjl            }
646118611Snjl        }
647118611Snjl        else
648118611Snjl        {
649151937Sjkim            AslCoreSubsystemError (Op, Status,
650198237Sjkim                "Failure from namespace lookup", FALSE);
651202771Sjkim            return_ACPI_STATUS (Status);
652118611Snjl        }
653118611Snjl    }
654118611Snjl
655167802Sjkim    if (ForceNewScope)
656167802Sjkim    {
657167802Sjkim        Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
658167802Sjkim        if (ACPI_FAILURE (Status))
659167802Sjkim        {
660167802Sjkim            return_ACPI_STATUS (Status);
661167802Sjkim        }
662167802Sjkim    }
663118611Snjl
664118611SnjlFinishNode:
665118611Snjl    /*
666118611Snjl     * Point the parse node to the new namespace node, and point
667118611Snjl     * the Node back to the original Parse node
668118611Snjl     */
669118611Snjl    Op->Asl.Node = Node;
670151937Sjkim    Node->Op = Op;
671118611Snjl
672118611Snjl    /* Set the actual data type if appropriate (EXTERNAL term only) */
673118611Snjl
674118611Snjl    if (ActualObjectType != ACPI_TYPE_ANY)
675118611Snjl    {
676118611Snjl        Node->Type = (UINT8) ActualObjectType;
677151937Sjkim        Node->Value = ASL_EXTERNAL_METHOD;
678118611Snjl    }
679118611Snjl
680118611Snjl    if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
681118611Snjl    {
682118611Snjl        /*
683151937Sjkim         * Get the method argument count from "Extra" and save
684151937Sjkim         * it in the namespace node
685118611Snjl         */
686151937Sjkim        Node->Value = (UINT32) Op->Asl.Extra;
687118611Snjl    }
688118611Snjl
689202771Sjkim    return_ACPI_STATUS (Status);
690118611Snjl}
691118611Snjl
692118611Snjl
693118611Snjl/*******************************************************************************
694118611Snjl *
695193529Sjkim * FUNCTION:    LdNamespace2Begin
696118611Snjl *
697118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
698118611Snjl *
699118611Snjl * RETURN:      Status
700118611Snjl *
701193529Sjkim * DESCRIPTION: Descending callback used during the pass 2 parse tree walk.
702193529Sjkim *              Second pass resolves some forward references.
703193529Sjkim *
704193529Sjkim * Notes:
705193529Sjkim * Currently only needs to handle the Alias operator.
706193529Sjkim * Could be used to allow forward references from the Scope() operator, but
707193529Sjkim * the MS interpreter does not allow this, so this compiler does not either.
708193529Sjkim *
709193529Sjkim ******************************************************************************/
710193529Sjkim
711193529Sjkimstatic ACPI_STATUS
712193529SjkimLdNamespace2Begin (
713193529Sjkim    ACPI_PARSE_OBJECT       *Op,
714193529Sjkim    UINT32                  Level,
715193529Sjkim    void                    *Context)
716193529Sjkim{
717193529Sjkim    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
718193529Sjkim    ACPI_STATUS             Status;
719193529Sjkim    ACPI_NAMESPACE_NODE     *Node;
720193529Sjkim    ACPI_OBJECT_TYPE        ObjectType;
721193529Sjkim    BOOLEAN                 ForceNewScope = FALSE;
722193529Sjkim    ACPI_PARSE_OBJECT       *Arg;
723193529Sjkim    char                    *Path;
724193529Sjkim    ACPI_NAMESPACE_NODE     *TargetNode;
725193529Sjkim
726193529Sjkim
727193529Sjkim    ACPI_FUNCTION_NAME (LdNamespace2Begin);
728193529Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
729193529Sjkim        Op, Op->Asl.ParseOpName));
730193529Sjkim
731193529Sjkim
732193529Sjkim    /* Ignore Ops with no namespace node */
733193529Sjkim
734193529Sjkim    Node = Op->Asl.Node;
735193529Sjkim    if (!Node)
736193529Sjkim    {
737193529Sjkim        return (AE_OK);
738193529Sjkim    }
739193529Sjkim
740193529Sjkim    /* Get the type to determine if we should push the scope */
741193529Sjkim
742193529Sjkim    if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
743193529Sjkim        (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
744193529Sjkim    {
745193529Sjkim        ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
746193529Sjkim    }
747193529Sjkim    else
748193529Sjkim    {
749193529Sjkim        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
750193529Sjkim    }
751193529Sjkim
752193529Sjkim    /* Push scope for Resource Templates */
753193529Sjkim
754193529Sjkim    if (Op->Asl.ParseOpcode == PARSEOP_NAME)
755193529Sjkim    {
756193529Sjkim        if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
757193529Sjkim        {
758193529Sjkim            ForceNewScope = TRUE;
759193529Sjkim        }
760193529Sjkim    }
761193529Sjkim
762193529Sjkim    /* Push the scope stack */
763193529Sjkim
764193529Sjkim    if (ForceNewScope || AcpiNsOpensScope (ObjectType))
765193529Sjkim    {
766193529Sjkim        Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
767193529Sjkim        if (ACPI_FAILURE (Status))
768193529Sjkim        {
769193529Sjkim            return_ACPI_STATUS (Status);
770193529Sjkim        }
771193529Sjkim    }
772193529Sjkim
773193529Sjkim    if (Op->Asl.ParseOpcode == PARSEOP_ALIAS)
774193529Sjkim    {
775193529Sjkim        /* Complete the alias node by getting and saving the target node */
776193529Sjkim
777193529Sjkim        /* First child is the alias target */
778193529Sjkim
779193529Sjkim        Arg = Op->Asl.Child;
780193529Sjkim
781193529Sjkim        /* Get the target pathname */
782193529Sjkim
783193529Sjkim        Path = Arg->Asl.Namepath;
784193529Sjkim        if (!Path)
785193529Sjkim        {
786193529Sjkim            Status = UtInternalizeName (Arg->Asl.ExternalName, &Path);
787193529Sjkim            if (ACPI_FAILURE (Status))
788193529Sjkim            {
789193529Sjkim                return (Status);
790193529Sjkim            }
791193529Sjkim        }
792193529Sjkim
793193529Sjkim        /* Get the NS node associated with the target. It must exist. */
794193529Sjkim
795193529Sjkim        Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
796193529Sjkim                    ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
797193529Sjkim                    WalkState, &TargetNode);
798193529Sjkim        if (ACPI_FAILURE (Status))
799193529Sjkim        {
800193529Sjkim            if (Status == AE_NOT_FOUND)
801193529Sjkim            {
802193529Sjkim                AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
803193529Sjkim                    Op->Asl.ExternalName);
804193529Sjkim
805193529Sjkim                /*
806193529Sjkim                 * The name was not found, go ahead and create it.
807193529Sjkim                 * This prevents more errors later.
808193529Sjkim                 */
809193529Sjkim                Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
810193529Sjkim                            ACPI_TYPE_ANY,
811193529Sjkim                            ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH,
812193529Sjkim                            WalkState, &(Node));
813193529Sjkim                return (AE_OK);
814193529Sjkim            }
815193529Sjkim
816198237Sjkim            AslCoreSubsystemError (Op, Status,
817198237Sjkim                "Failure from namespace lookup", FALSE);
818193529Sjkim            return (AE_OK);
819193529Sjkim        }
820193529Sjkim
821193529Sjkim        /* Save the target node within the alias node */
822193529Sjkim
823193529Sjkim        Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
824193529Sjkim    }
825193529Sjkim
826193529Sjkim    return (AE_OK);
827193529Sjkim}
828193529Sjkim
829193529Sjkim
830193529Sjkim/*******************************************************************************
831193529Sjkim *
832193529Sjkim * FUNCTION:    LdCommonNamespaceEnd
833193529Sjkim *
834193529Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
835193529Sjkim *
836193529Sjkim * RETURN:      Status
837193529Sjkim *
838118611Snjl * DESCRIPTION: Ascending callback used during the loading of the namespace,
839118611Snjl *              We only need to worry about managing the scope stack here.
840118611Snjl *
841118611Snjl ******************************************************************************/
842118611Snjl
843151937Sjkimstatic ACPI_STATUS
844193529SjkimLdCommonNamespaceEnd (
845118611Snjl    ACPI_PARSE_OBJECT       *Op,
846118611Snjl    UINT32                  Level,
847118611Snjl    void                    *Context)
848118611Snjl{
849118611Snjl    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
850118611Snjl    ACPI_OBJECT_TYPE        ObjectType;
851167802Sjkim    BOOLEAN                 ForceNewScope = FALSE;
852118611Snjl
853118611Snjl
854193529Sjkim    ACPI_FUNCTION_NAME (LdCommonNamespaceEnd);
855118611Snjl
856118611Snjl
857118611Snjl    /* We are only interested in opcodes that have an associated name */
858118611Snjl
859118611Snjl    if (!Op->Asl.Namepath)
860118611Snjl    {
861118611Snjl        return (AE_OK);
862118611Snjl    }
863118611Snjl
864118611Snjl    /* Get the type to determine if we should pop the scope */
865118611Snjl
866118611Snjl    if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
867118611Snjl        (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
868118611Snjl    {
869118611Snjl        /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */
870118611Snjl
871118611Snjl        ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
872118611Snjl    }
873118611Snjl    else
874118611Snjl    {
875118611Snjl        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
876118611Snjl    }
877118611Snjl
878167802Sjkim    /* Pop scope that was pushed for Resource Templates */
879167802Sjkim
880167802Sjkim    if (Op->Asl.ParseOpcode == PARSEOP_NAME)
881167802Sjkim    {
882167802Sjkim        if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
883167802Sjkim        {
884167802Sjkim            ForceNewScope = TRUE;
885167802Sjkim        }
886167802Sjkim    }
887167802Sjkim
888118611Snjl    /* Pop the scope stack */
889118611Snjl
890167802Sjkim    if (ForceNewScope || AcpiNsOpensScope (ObjectType))
891118611Snjl    {
892118611Snjl        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
893118611Snjl            "(%s): Popping scope for Op [%s] %p\n",
894118611Snjl            AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op));
895118611Snjl
896151937Sjkim        (void) AcpiDsScopeStackPop (WalkState);
897118611Snjl    }
898118611Snjl
899118611Snjl    return (AE_OK);
900118611Snjl}
901