1118611Snjl/******************************************************************************
2118611Snjl *
3118611Snjl * Module Name: dswload - Dispatcher namespace load callbacks
4118611Snjl *
5118611Snjl *****************************************************************************/
6118611Snjl
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, 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
44151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
45193529Sjkim#include <contrib/dev/acpica/include/amlcode.h>
46193529Sjkim#include <contrib/dev/acpica/include/acdispat.h>
47193529Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
48118611Snjl
49118611Snjl#include "aslcompiler.y.h"
50118611Snjl
51118611Snjl#define _COMPONENT          ACPI_COMPILER
52118611Snjl        ACPI_MODULE_NAME    ("aslload")
53118611Snjl
54151937Sjkim/* Local prototypes */
55118611Snjl
56151937Sjkimstatic ACPI_STATUS
57151937SjkimLdLoadFieldElements (
58151937Sjkim    ACPI_PARSE_OBJECT       *Op,
59151937Sjkim    ACPI_WALK_STATE         *WalkState);
60151937Sjkim
61151937Sjkimstatic ACPI_STATUS
62151937SjkimLdLoadResourceElements (
63151937Sjkim    ACPI_PARSE_OBJECT       *Op,
64151937Sjkim    ACPI_WALK_STATE         *WalkState);
65151937Sjkim
66151937Sjkimstatic ACPI_STATUS
67151937SjkimLdNamespace1Begin (
68151937Sjkim    ACPI_PARSE_OBJECT       *Op,
69151937Sjkim    UINT32                  Level,
70151937Sjkim    void                    *Context);
71151937Sjkim
72151937Sjkimstatic ACPI_STATUS
73193529SjkimLdNamespace2Begin (
74151937Sjkim    ACPI_PARSE_OBJECT       *Op,
75151937Sjkim    UINT32                  Level,
76151937Sjkim    void                    *Context);
77151937Sjkim
78193529Sjkimstatic ACPI_STATUS
79193529SjkimLdCommonNamespaceEnd (
80193529Sjkim    ACPI_PARSE_OBJECT       *Op,
81193529Sjkim    UINT32                  Level,
82193529Sjkim    void                    *Context);
83151937Sjkim
84193529Sjkim
85118611Snjl/*******************************************************************************
86118611Snjl *
87118611Snjl * FUNCTION:    LdLoadNamespace
88118611Snjl *
89151937Sjkim * PARAMETERS:  RootOp      - Root of the parse tree
90118611Snjl *
91118611Snjl * RETURN:      Status
92118611Snjl *
93118611Snjl * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the
94193529Sjkim *              named ASL/AML objects into the namespace. The namespace is
95118611Snjl *              constructed in order to resolve named references and references
96118611Snjl *              to named fields within resource templates/descriptors.
97118611Snjl *
98118611Snjl ******************************************************************************/
99118611Snjl
100118611SnjlACPI_STATUS
101118611SnjlLdLoadNamespace (
102118611Snjl    ACPI_PARSE_OBJECT       *RootOp)
103118611Snjl{
104118611Snjl    ACPI_WALK_STATE         *WalkState;
105118611Snjl
106118611Snjl
107118611Snjl    /* Create a new walk state */
108118611Snjl
109118611Snjl    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
110118611Snjl    if (!WalkState)
111118611Snjl    {
112241973Sjkim        return (AE_NO_MEMORY);
113118611Snjl    }
114118611Snjl
115193529Sjkim    /* Walk the entire parse tree, first pass */
116118611Snjl
117118611Snjl    TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin,
118193529Sjkim        LdCommonNamespaceEnd, WalkState);
119118611Snjl
120193529Sjkim    /* Second pass to handle forward references */
121193529Sjkim
122193529Sjkim    TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin,
123193529Sjkim        LdCommonNamespaceEnd, WalkState);
124193529Sjkim
125118611Snjl    /* Dump the namespace if debug is enabled */
126118611Snjl
127118611Snjl    AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX);
128281075Sdim    ACPI_FREE (WalkState);
129241973Sjkim    return (AE_OK);
130118611Snjl}
131118611Snjl
132118611Snjl
133118611Snjl/*******************************************************************************
134118611Snjl *
135118611Snjl * FUNCTION:    LdLoadFieldElements
136118611Snjl *
137151937Sjkim * PARAMETERS:  Op              - Parent node (Field)
138118611Snjl *              WalkState       - Current walk state
139118611Snjl *
140118611Snjl * RETURN:      Status
141118611Snjl *
142118611Snjl * DESCRIPTION: Enter the named elements of the field (children of the parent)
143118611Snjl *              into the namespace.
144118611Snjl *
145118611Snjl ******************************************************************************/
146118611Snjl
147151937Sjkimstatic ACPI_STATUS
148118611SnjlLdLoadFieldElements (
149118611Snjl    ACPI_PARSE_OBJECT       *Op,
150118611Snjl    ACPI_WALK_STATE         *WalkState)
151118611Snjl{
152118611Snjl    ACPI_PARSE_OBJECT       *Child = NULL;
153118611Snjl    ACPI_NAMESPACE_NODE     *Node;
154118611Snjl    ACPI_STATUS             Status;
155118611Snjl
156118611Snjl
157118611Snjl    /* Get the first named field element */
158118611Snjl
159118611Snjl    switch (Op->Asl.AmlOpcode)
160118611Snjl    {
161118611Snjl    case AML_BANK_FIELD_OP:
162118611Snjl
163118611Snjl        Child = UtGetArg (Op, 6);
164118611Snjl        break;
165118611Snjl
166118611Snjl    case AML_INDEX_FIELD_OP:
167118611Snjl
168118611Snjl        Child = UtGetArg (Op, 5);
169118611Snjl        break;
170118611Snjl
171118611Snjl    case AML_FIELD_OP:
172118611Snjl
173118611Snjl        Child = UtGetArg (Op, 4);
174118611Snjl        break;
175118611Snjl
176118611Snjl    default:
177250838Sjkim
178118611Snjl        /* No other opcodes should arrive here */
179250838Sjkim
180118611Snjl        return (AE_BAD_PARAMETER);
181118611Snjl    }
182118611Snjl
183118611Snjl    /* Enter all elements into the namespace */
184118611Snjl
185118611Snjl    while (Child)
186118611Snjl    {
187118611Snjl        switch (Child->Asl.AmlOpcode)
188118611Snjl        {
189118611Snjl        case AML_INT_RESERVEDFIELD_OP:
190118611Snjl        case AML_INT_ACCESSFIELD_OP:
191228110Sjkim        case AML_INT_CONNECTION_OP:
192118611Snjl            break;
193118611Snjl
194118611Snjl        default:
195118611Snjl
196151937Sjkim            Status = AcpiNsLookup (WalkState->ScopeInfo,
197306536Sjkim                Child->Asl.Value.String,
198306536Sjkim                ACPI_TYPE_LOCAL_REGION_FIELD,
199306536Sjkim                ACPI_IMODE_LOAD_PASS1,
200306536Sjkim                ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
201306536Sjkim                    ACPI_NS_ERROR_IF_FOUND, NULL, &Node);
202118611Snjl            if (ACPI_FAILURE (Status))
203118611Snjl            {
204118611Snjl                if (Status != AE_ALREADY_EXISTS)
205118611Snjl                {
206151937Sjkim                    AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child,
207151937Sjkim                        Child->Asl.Value.String);
208151937Sjkim                    return (Status);
209118611Snjl                }
210118611Snjl
211118611Snjl                /*
212118611Snjl                 * The name already exists in this scope
213118611Snjl                 * But continue processing the elements
214118611Snjl                 */
215151937Sjkim                AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,
216151937Sjkim                    Child->Asl.Value.String);
217118611Snjl            }
218118611Snjl            else
219118611Snjl            {
220118611Snjl                Child->Asl.Node = Node;
221151937Sjkim                Node->Op = Child;
222118611Snjl            }
223118611Snjl            break;
224118611Snjl        }
225228110Sjkim
226118611Snjl        Child = Child->Asl.Next;
227118611Snjl    }
228228110Sjkim
229118611Snjl    return (AE_OK);
230118611Snjl}
231118611Snjl
232118611Snjl
233118611Snjl/*******************************************************************************
234118611Snjl *
235118611Snjl * FUNCTION:    LdLoadResourceElements
236118611Snjl *
237151937Sjkim * PARAMETERS:  Op              - Parent node (Resource Descriptor)
238118611Snjl *              WalkState       - Current walk state
239118611Snjl *
240118611Snjl * RETURN:      Status
241118611Snjl *
242118611Snjl * DESCRIPTION: Enter the named elements of the resource descriptor (children
243118611Snjl *              of the parent) into the namespace.
244118611Snjl *
245193529Sjkim * NOTE: In the real AML namespace, these named elements never exist. But
246118611Snjl *       we simply use the namespace here as a symbol table so we can look
247118611Snjl *       them up as they are referenced.
248118611Snjl *
249118611Snjl ******************************************************************************/
250118611Snjl
251151937Sjkimstatic ACPI_STATUS
252118611SnjlLdLoadResourceElements (
253118611Snjl    ACPI_PARSE_OBJECT       *Op,
254118611Snjl    ACPI_WALK_STATE         *WalkState)
255118611Snjl{
256118611Snjl    ACPI_PARSE_OBJECT       *InitializerOp = NULL;
257118611Snjl    ACPI_NAMESPACE_NODE     *Node;
258118611Snjl    ACPI_STATUS             Status;
259118611Snjl
260118611Snjl
261118611Snjl    /*
262151937Sjkim     * Enter the resource name into the namespace. Name must not already exist.
263151937Sjkim     * This opens a scope, so later field names are guaranteed to be new/unique.
264118611Snjl     */
265118611Snjl    Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath,
266306536Sjkim        ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1,
267306536Sjkim        ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND,
268306536Sjkim        WalkState, &Node);
269118611Snjl    if (ACPI_FAILURE (Status))
270118611Snjl    {
271151937Sjkim        if (Status == AE_ALREADY_EXISTS)
272151937Sjkim        {
273151937Sjkim            /* Actual node causing the error was saved in ParentMethod */
274151937Sjkim
275151937Sjkim            AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS,
276151937Sjkim                (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath);
277151937Sjkim            return (AE_OK);
278151937Sjkim        }
279118611Snjl        return (Status);
280118611Snjl    }
281118611Snjl
282167802Sjkim    Node->Value = (UINT32) Op->Asl.Value.Integer;
283167802Sjkim    Node->Op = Op;
284197104Sjkim    Op->Asl.Node = Node;
285167802Sjkim
286118611Snjl    /*
287118611Snjl     * Now enter the predefined fields, for easy lookup when referenced
288118611Snjl     * by the source ASL
289118611Snjl     */
290118611Snjl    InitializerOp = ASL_GET_CHILD_NODE (Op);
291118611Snjl    while (InitializerOp)
292118611Snjl    {
293118611Snjl        if (InitializerOp->Asl.ExternalName)
294118611Snjl        {
295118611Snjl            Status = AcpiNsLookup (WalkState->ScopeInfo,
296306536Sjkim                InitializerOp->Asl.ExternalName,
297306536Sjkim                ACPI_TYPE_LOCAL_RESOURCE_FIELD,
298306536Sjkim                ACPI_IMODE_LOAD_PASS1,
299306536Sjkim                ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE,
300306536Sjkim                NULL, &Node);
301118611Snjl            if (ACPI_FAILURE (Status))
302118611Snjl            {
303118611Snjl                return (Status);
304118611Snjl            }
305118611Snjl
306118611Snjl            /*
307228110Sjkim             * Store the field offset and length in the namespace node
308228110Sjkim             * so it can be used when the field is referenced
309118611Snjl             */
310228110Sjkim            Node->Value = InitializerOp->Asl.Value.Tag.BitOffset;
311228110Sjkim            Node->Length = InitializerOp->Asl.Value.Tag.BitLength;
312118611Snjl            InitializerOp->Asl.Node = Node;
313151937Sjkim            Node->Op = InitializerOp;
314228110Sjkim        }
315118611Snjl
316118611Snjl        InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
317118611Snjl    }
318118611Snjl
319118611Snjl    return (AE_OK);
320118611Snjl}
321118611Snjl
322118611Snjl
323118611Snjl/*******************************************************************************
324118611Snjl *
325118611Snjl * FUNCTION:    LdNamespace1Begin
326118611Snjl *
327118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
328118611Snjl *
329118611Snjl * RETURN:      Status
330118611Snjl *
331193529Sjkim * DESCRIPTION: Descending callback used during the parse tree walk. If this
332118611Snjl *              is a named AML opcode, enter into the namespace
333118611Snjl *
334118611Snjl ******************************************************************************/
335118611Snjl
336151937Sjkimstatic ACPI_STATUS
337118611SnjlLdNamespace1Begin (
338118611Snjl    ACPI_PARSE_OBJECT       *Op,
339118611Snjl    UINT32                  Level,
340118611Snjl    void                    *Context)
341118611Snjl{
342118611Snjl    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
343118611Snjl    ACPI_NAMESPACE_NODE     *Node;
344306536Sjkim    ACPI_PARSE_OBJECT       *MethodOp;
345118611Snjl    ACPI_STATUS             Status;
346118611Snjl    ACPI_OBJECT_TYPE        ObjectType;
347118611Snjl    ACPI_OBJECT_TYPE        ActualObjectType = ACPI_TYPE_ANY;
348118611Snjl    char                    *Path;
349118611Snjl    UINT32                  Flags = ACPI_NS_NO_UPSEARCH;
350118611Snjl    ACPI_PARSE_OBJECT       *Arg;
351118611Snjl    UINT32                  i;
352167802Sjkim    BOOLEAN                 ForceNewScope = FALSE;
353118611Snjl
354118611Snjl
355167802Sjkim    ACPI_FUNCTION_NAME (LdNamespace1Begin);
356118611Snjl    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
357118611Snjl        Op, Op->Asl.ParseOpName));
358118611Snjl
359118611Snjl    /*
360118611Snjl     * We are only interested in opcodes that have an associated name
361118611Snjl     * (or multiple names)
362118611Snjl     */
363118611Snjl    switch (Op->Asl.AmlOpcode)
364118611Snjl    {
365118611Snjl    case AML_BANK_FIELD_OP:
366118611Snjl    case AML_INDEX_FIELD_OP:
367118611Snjl    case AML_FIELD_OP:
368118611Snjl
369118611Snjl        Status = LdLoadFieldElements (Op, WalkState);
370118611Snjl        return (Status);
371118611Snjl
372281075Sdim    case AML_INT_CONNECTION_OP:
373281075Sdim
374281075Sdim
375281075Sdim        if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)
376281075Sdim        {
377281075Sdim            break;
378281075Sdim        }
379281075Sdim        Arg = Op->Asl.Child;
380281075Sdim
381281075Sdim        Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName,
382281075Sdim            ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
383281075Sdim            WalkState, &Node);
384281075Sdim        if (ACPI_FAILURE (Status))
385281075Sdim        {
386281075Sdim            break;
387281075Sdim        }
388281075Sdim
389281075Sdim        if (Node->Type == ACPI_TYPE_BUFFER)
390281075Sdim        {
391281075Sdim            Arg->Asl.Node = Node;
392281075Sdim
393281075Sdim            Arg = Node->Op->Asl.Child;  /* Get namepath */
394281075Sdim            Arg = Arg->Asl.Next;        /* Get actual buffer */
395281075Sdim            Arg = Arg->Asl.Child;       /* Buffer length */
396281075Sdim            Arg = Arg->Asl.Next;        /* RAW_DATA buffer */
397281075Sdim        }
398281075Sdim        break;
399281075Sdim
400118611Snjl    default:
401118611Snjl
402118611Snjl        /* All other opcodes go below */
403250838Sjkim
404118611Snjl        break;
405118611Snjl    }
406118611Snjl
407118611Snjl    /* Check if this object has already been installed in the namespace */
408118611Snjl
409118611Snjl    if (Op->Asl.Node)
410118611Snjl    {
411118611Snjl        return (AE_OK);
412118611Snjl    }
413118611Snjl
414118611Snjl    Path = Op->Asl.Namepath;
415118611Snjl    if (!Path)
416118611Snjl    {
417118611Snjl        return (AE_OK);
418118611Snjl    }
419118611Snjl
420118611Snjl    /* Map the raw opcode into an internal object type */
421118611Snjl
422118611Snjl    switch (Op->Asl.ParseOpcode)
423118611Snjl    {
424118611Snjl    case PARSEOP_NAME:
425118611Snjl
426151937Sjkim        Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
427151937Sjkim        Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
428118611Snjl
429167802Sjkim        /*
430167802Sjkim         * If this name refers to a ResourceTemplate, we will need to open
431167802Sjkim         * a new scope so that the resource subfield names can be entered into
432167802Sjkim         * the namespace underneath this name
433167802Sjkim         */
434167802Sjkim        if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
435167802Sjkim        {
436167802Sjkim            ForceNewScope = TRUE;
437167802Sjkim        }
438167802Sjkim
439118611Snjl        /* Get the data type associated with the named object, not the name itself */
440118611Snjl
441118611Snjl        /* Log2 loop to convert from Btype (binary) to Etype (encoded) */
442118611Snjl
443118611Snjl        ObjectType = 1;
444118611Snjl        for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2)
445118611Snjl        {
446118611Snjl            ObjectType++;
447118611Snjl        }
448118611Snjl        break;
449118611Snjl
450118611Snjl
451118611Snjl    case PARSEOP_EXTERNAL:
452118611Snjl        /*
453118611Snjl         * "External" simply enters a name and type into the namespace.
454118611Snjl         * We must be careful to not open a new scope, however, no matter
455118611Snjl         * what type the external name refers to (e.g., a method)
456118611Snjl         *
457118611Snjl         * first child is name, next child is ObjectType
458118611Snjl         */
459118611Snjl        ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer;
460118611Snjl        ObjectType = ACPI_TYPE_ANY;
461167802Sjkim
462167802Sjkim        /*
463167802Sjkim         * We will mark every new node along the path as "External". This
464167802Sjkim         * allows some or all of the nodes to be created later in the ASL
465167802Sjkim         * code. Handles cases like this:
466167802Sjkim         *
467167802Sjkim         *   External (\_SB_.PCI0.ABCD, IntObj)
468167802Sjkim         *   Scope (_SB_)
469167802Sjkim         *   {
470167802Sjkim         *       Device (PCI0)
471167802Sjkim         *       {
472167802Sjkim         *       }
473167802Sjkim         *   }
474167802Sjkim         *   Method (X)
475167802Sjkim         *   {
476167802Sjkim         *       Store (\_SB_.PCI0.ABCD, Local0)
477167802Sjkim         *   }
478167802Sjkim         */
479167802Sjkim        Flags |= ACPI_NS_EXTERNAL;
480118611Snjl        break;
481118611Snjl
482118611Snjl    case PARSEOP_DEFAULT_ARG:
483118611Snjl
484167802Sjkim        if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)
485118611Snjl        {
486118611Snjl            Status = LdLoadResourceElements (Op, WalkState);
487202771Sjkim            return_ACPI_STATUS (Status);
488118611Snjl        }
489118611Snjl
490118611Snjl        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
491118611Snjl        break;
492118611Snjl
493118611Snjl    case PARSEOP_SCOPE:
494118611Snjl        /*
495118611Snjl         * The name referenced by Scope(Name) must already exist at this point.
496118611Snjl         * In other words, forward references for Scope() are not supported.
497118611Snjl         * The only real reason for this is that the MS interpreter cannot
498193529Sjkim         * handle this case. Perhaps someday this case can go away.
499118611Snjl         */
500118611Snjl        Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
501306536Sjkim            ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
502306536Sjkim            WalkState, &(Node));
503118611Snjl        if (ACPI_FAILURE (Status))
504118611Snjl        {
505118611Snjl            if (Status == AE_NOT_FOUND)
506118611Snjl            {
507118611Snjl                /* The name was not found, go ahead and create it */
508118611Snjl
509151937Sjkim                Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
510306536Sjkim                    ACPI_TYPE_LOCAL_SCOPE,
511306536Sjkim                    ACPI_IMODE_LOAD_PASS1, Flags,
512306536Sjkim                    WalkState, &(Node));
513254745Sjkim                if (ACPI_FAILURE (Status))
514254745Sjkim                {
515254745Sjkim                    return_ACPI_STATUS (Status);
516254745Sjkim                }
517118611Snjl
518118611Snjl                /*
519118611Snjl                 * However, this is an error -- primarily because the MS
520118611Snjl                 * interpreter can't handle a forward reference from the
521118611Snjl                 * Scope() operator.
522118611Snjl                 */
523151937Sjkim                AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
524151937Sjkim                    Op->Asl.ExternalName);
525151937Sjkim                AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op,
526151937Sjkim                    Op->Asl.ExternalName);
527118611Snjl                goto FinishNode;
528118611Snjl            }
529118611Snjl
530198237Sjkim            AslCoreSubsystemError (Op, Status,
531198237Sjkim                "Failure from namespace lookup", FALSE);
532198237Sjkim
533202771Sjkim            return_ACPI_STATUS (Status);
534118611Snjl        }
535306536Sjkim        else /* Status AE_OK */
536306536Sjkim        {
537306536Sjkim            /*
538306536Sjkim             * Do not allow references to external scopes from the DSDT.
539306536Sjkim             * This is because the DSDT is always loaded first, and the
540306536Sjkim             * external reference cannot be resolved -- causing a runtime
541306536Sjkim             * error because Scope() must be resolved immediately.
542306536Sjkim             * 10/2015.
543306536Sjkim             */
544306536Sjkim            if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
545306536Sjkim                (ACPI_COMPARE_NAME (Gbl_TableSignature, "DSDT")))
546306536Sjkim            {
547306536Sjkim                /* However, allowed if the reference is within a method */
548118611Snjl
549306536Sjkim                MethodOp = Op->Asl.Parent;
550306536Sjkim                while (MethodOp &&
551306536Sjkim                      (MethodOp->Asl.ParseOpcode != PARSEOP_METHOD))
552306536Sjkim                {
553306536Sjkim                    MethodOp = MethodOp->Asl.Parent;
554306536Sjkim                }
555306536Sjkim
556306536Sjkim                if (!MethodOp)
557306536Sjkim                {
558306536Sjkim                    /* Not in a control method, error */
559306536Sjkim
560306536Sjkim                    AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL);
561306536Sjkim                }
562306536Sjkim            }
563306536Sjkim        }
564306536Sjkim
565118611Snjl        /* We found a node with this name, now check the type */
566118611Snjl
567118611Snjl        switch (Node->Type)
568118611Snjl        {
569118611Snjl        case ACPI_TYPE_LOCAL_SCOPE:
570118611Snjl        case ACPI_TYPE_DEVICE:
571118611Snjl        case ACPI_TYPE_POWER:
572118611Snjl        case ACPI_TYPE_PROCESSOR:
573118611Snjl        case ACPI_TYPE_THERMAL:
574118611Snjl
575118611Snjl            /* These are acceptable types - they all open a new scope */
576118611Snjl            break;
577118611Snjl
578118611Snjl        case ACPI_TYPE_INTEGER:
579118611Snjl        case ACPI_TYPE_STRING:
580118611Snjl        case ACPI_TYPE_BUFFER:
581118611Snjl            /*
582151937Sjkim             * These types we will allow, but we will change the type.
583151937Sjkim             * This enables some existing code of the form:
584118611Snjl             *
585118611Snjl             *  Name (DEB, 0)
586118611Snjl             *  Scope (DEB) { ... }
587118611Snjl             *
588118611Snjl             * Which is used to workaround the fact that the MS interpreter
589118611Snjl             * does not allow Scope() forward references.
590118611Snjl             */
591128212Snjl            sprintf (MsgBuffer, "%s [%s], changing type to [Scope]",
592118611Snjl                Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
593118611Snjl            AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
594118611Snjl
595151937Sjkim            /* Switch the type to scope, open the new scope */
596151937Sjkim
597128212Snjl            Node->Type = ACPI_TYPE_LOCAL_SCOPE;
598151937Sjkim            Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
599306536Sjkim                WalkState);
600128212Snjl            if (ACPI_FAILURE (Status))
601128212Snjl            {
602128212Snjl                return_ACPI_STATUS (Status);
603128212Snjl            }
604118611Snjl            break;
605118611Snjl
606118611Snjl        default:
607118611Snjl
608151937Sjkim            /* All other types are an error */
609151937Sjkim
610151937Sjkim            sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName,
611151937Sjkim                AcpiUtGetTypeName (Node->Type));
612118611Snjl            AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
613118611Snjl
614118611Snjl            /*
615118611Snjl             * However, switch the type to be an actual scope so
616118611Snjl             * that compilation can continue without generating a whole
617193529Sjkim             * cascade of additional errors. Open the new scope.
618118611Snjl             */
619128212Snjl            Node->Type = ACPI_TYPE_LOCAL_SCOPE;
620151937Sjkim            Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
621306536Sjkim                WalkState);
622128212Snjl            if (ACPI_FAILURE (Status))
623128212Snjl            {
624128212Snjl                return_ACPI_STATUS (Status);
625128212Snjl            }
626118611Snjl            break;
627118611Snjl        }
628118611Snjl
629118611Snjl        Status = AE_OK;
630118611Snjl        goto FinishNode;
631118611Snjl
632118611Snjl
633118611Snjl    default:
634118611Snjl
635118611Snjl        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
636118611Snjl        break;
637118611Snjl    }
638118611Snjl
639118611Snjl
640118611Snjl    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n",
641306536Sjkim        Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType)));
642118611Snjl
643118611Snjl    /* The name must not already exist */
644118611Snjl
645118611Snjl    Flags |= ACPI_NS_ERROR_IF_FOUND;
646118611Snjl
647118611Snjl    /*
648193529Sjkim     * Enter the named type into the internal namespace. We enter the name
649193529Sjkim     * as we go downward in the parse tree. Any necessary subobjects that
650151937Sjkim     * involve arguments to the opcode must be created as we go back up the
651151937Sjkim     * parse tree later.
652118611Snjl     */
653118611Snjl    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
654306536Sjkim        ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
655118611Snjl    if (ACPI_FAILURE (Status))
656118611Snjl    {
657118611Snjl        if (Status == AE_ALREADY_EXISTS)
658118611Snjl        {
659118611Snjl            /* The name already exists in this scope */
660118611Snjl
661118611Snjl            if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
662118611Snjl            {
663167802Sjkim                /* Allow multiple references to the same scope */
664167802Sjkim
665118611Snjl                Node->Type = (UINT8) ObjectType;
666118611Snjl                Status = AE_OK;
667118611Snjl            }
668193529Sjkim            else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
669193529Sjkim                     (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
670167802Sjkim            {
671167802Sjkim                /*
672167802Sjkim                 * Allow one create on an object or segment that was
673167802Sjkim                 * previously declared External
674167802Sjkim                 */
675167802Sjkim                Node->Flags &= ~ANOBJ_IS_EXTERNAL;
676167802Sjkim                Node->Type = (UINT8) ObjectType;
677167802Sjkim
678167802Sjkim                /* Just retyped a node, probably will need to open a scope */
679167802Sjkim
680167802Sjkim                if (AcpiNsOpensScope (ObjectType))
681167802Sjkim                {
682167802Sjkim                    Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
683167802Sjkim                    if (ACPI_FAILURE (Status))
684167802Sjkim                    {
685167802Sjkim                        return_ACPI_STATUS (Status);
686167802Sjkim                    }
687167802Sjkim                }
688306536Sjkim
689167802Sjkim                Status = AE_OK;
690167802Sjkim            }
691306536Sjkim            else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) &&
692306536Sjkim                     (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
693306536Sjkim            {
694306536Sjkim                /*
695306536Sjkim                 * Allow externals in same scope as the definition of the
696306536Sjkim                 * actual object. Similar to C. Allows multiple definition
697306536Sjkim                 * blocks that refer to each other in the same file.
698306536Sjkim                 */
699306536Sjkim                Status = AE_OK;
700306536Sjkim            }
701306536Sjkim            else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
702306536Sjkim                     (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) &&
703306536Sjkim                     (ObjectType == ACPI_TYPE_ANY))
704306536Sjkim            {
705306536Sjkim                /* Allow update of externals of unknown type. */
706306536Sjkim
707306536Sjkim                if (AcpiNsOpensScope (ActualObjectType))
708306536Sjkim                {
709306536Sjkim                    Node->Type = (UINT8) ActualObjectType;
710306536Sjkim                    Status = AE_OK;
711306536Sjkim                }
712306536Sjkim                else
713306536Sjkim                {
714306536Sjkim                    sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName,
715306536Sjkim                        AcpiUtGetTypeName (Node->Type));
716306536Sjkim                    AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
717306536Sjkim                    return_ACPI_STATUS (AE_OK);
718306536Sjkim                }
719306536Sjkim            }
720118611Snjl            else
721118611Snjl            {
722167802Sjkim                /* Valid error, object already exists */
723167802Sjkim
724151937Sjkim                AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
725151937Sjkim                    Op->Asl.ExternalName);
726202771Sjkim                return_ACPI_STATUS (AE_OK);
727118611Snjl            }
728118611Snjl        }
729118611Snjl        else
730118611Snjl        {
731151937Sjkim            AslCoreSubsystemError (Op, Status,
732198237Sjkim                "Failure from namespace lookup", FALSE);
733202771Sjkim            return_ACPI_STATUS (Status);
734118611Snjl        }
735118611Snjl    }
736118611Snjl
737167802Sjkim    if (ForceNewScope)
738167802Sjkim    {
739167802Sjkim        Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
740167802Sjkim        if (ACPI_FAILURE (Status))
741167802Sjkim        {
742167802Sjkim            return_ACPI_STATUS (Status);
743167802Sjkim        }
744167802Sjkim    }
745118611Snjl
746118611SnjlFinishNode:
747118611Snjl    /*
748118611Snjl     * Point the parse node to the new namespace node, and point
749118611Snjl     * the Node back to the original Parse node
750118611Snjl     */
751118611Snjl    Op->Asl.Node = Node;
752151937Sjkim    Node->Op = Op;
753118611Snjl
754118611Snjl    /* Set the actual data type if appropriate (EXTERNAL term only) */
755118611Snjl
756118611Snjl    if (ActualObjectType != ACPI_TYPE_ANY)
757118611Snjl    {
758118611Snjl        Node->Type = (UINT8) ActualObjectType;
759151937Sjkim        Node->Value = ASL_EXTERNAL_METHOD;
760118611Snjl    }
761118611Snjl
762118611Snjl    if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
763118611Snjl    {
764118611Snjl        /*
765151937Sjkim         * Get the method argument count from "Extra" and save
766151937Sjkim         * it in the namespace node
767118611Snjl         */
768151937Sjkim        Node->Value = (UINT32) Op->Asl.Extra;
769118611Snjl    }
770118611Snjl
771202771Sjkim    return_ACPI_STATUS (Status);
772118611Snjl}
773118611Snjl
774118611Snjl
775118611Snjl/*******************************************************************************
776118611Snjl *
777193529Sjkim * FUNCTION:    LdNamespace2Begin
778118611Snjl *
779118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
780118611Snjl *
781118611Snjl * RETURN:      Status
782118611Snjl *
783193529Sjkim * DESCRIPTION: Descending callback used during the pass 2 parse tree walk.
784193529Sjkim *              Second pass resolves some forward references.
785193529Sjkim *
786193529Sjkim * Notes:
787193529Sjkim * Currently only needs to handle the Alias operator.
788193529Sjkim * Could be used to allow forward references from the Scope() operator, but
789193529Sjkim * the MS interpreter does not allow this, so this compiler does not either.
790193529Sjkim *
791193529Sjkim ******************************************************************************/
792193529Sjkim
793193529Sjkimstatic ACPI_STATUS
794193529SjkimLdNamespace2Begin (
795193529Sjkim    ACPI_PARSE_OBJECT       *Op,
796193529Sjkim    UINT32                  Level,
797193529Sjkim    void                    *Context)
798193529Sjkim{
799193529Sjkim    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
800193529Sjkim    ACPI_STATUS             Status;
801193529Sjkim    ACPI_NAMESPACE_NODE     *Node;
802193529Sjkim    ACPI_OBJECT_TYPE        ObjectType;
803193529Sjkim    BOOLEAN                 ForceNewScope = FALSE;
804193529Sjkim    ACPI_PARSE_OBJECT       *Arg;
805193529Sjkim    char                    *Path;
806193529Sjkim    ACPI_NAMESPACE_NODE     *TargetNode;
807193529Sjkim
808193529Sjkim
809193529Sjkim    ACPI_FUNCTION_NAME (LdNamespace2Begin);
810193529Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
811193529Sjkim        Op, Op->Asl.ParseOpName));
812193529Sjkim
813193529Sjkim
814193529Sjkim    /* Ignore Ops with no namespace node */
815193529Sjkim
816193529Sjkim    Node = Op->Asl.Node;
817193529Sjkim    if (!Node)
818193529Sjkim    {
819193529Sjkim        return (AE_OK);
820193529Sjkim    }
821193529Sjkim
822193529Sjkim    /* Get the type to determine if we should push the scope */
823193529Sjkim
824193529Sjkim    if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
825193529Sjkim        (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
826193529Sjkim    {
827193529Sjkim        ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
828193529Sjkim    }
829193529Sjkim    else
830193529Sjkim    {
831193529Sjkim        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
832193529Sjkim    }
833193529Sjkim
834193529Sjkim    /* Push scope for Resource Templates */
835193529Sjkim
836193529Sjkim    if (Op->Asl.ParseOpcode == PARSEOP_NAME)
837193529Sjkim    {
838193529Sjkim        if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
839193529Sjkim        {
840193529Sjkim            ForceNewScope = TRUE;
841193529Sjkim        }
842193529Sjkim    }
843193529Sjkim
844193529Sjkim    /* Push the scope stack */
845193529Sjkim
846193529Sjkim    if (ForceNewScope || AcpiNsOpensScope (ObjectType))
847193529Sjkim    {
848193529Sjkim        Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
849193529Sjkim        if (ACPI_FAILURE (Status))
850193529Sjkim        {
851193529Sjkim            return_ACPI_STATUS (Status);
852193529Sjkim        }
853193529Sjkim    }
854193529Sjkim
855193529Sjkim    if (Op->Asl.ParseOpcode == PARSEOP_ALIAS)
856193529Sjkim    {
857193529Sjkim        /* Complete the alias node by getting and saving the target node */
858193529Sjkim
859193529Sjkim        /* First child is the alias target */
860193529Sjkim
861193529Sjkim        Arg = Op->Asl.Child;
862193529Sjkim
863193529Sjkim        /* Get the target pathname */
864193529Sjkim
865193529Sjkim        Path = Arg->Asl.Namepath;
866193529Sjkim        if (!Path)
867193529Sjkim        {
868193529Sjkim            Status = UtInternalizeName (Arg->Asl.ExternalName, &Path);
869193529Sjkim            if (ACPI_FAILURE (Status))
870193529Sjkim            {
871193529Sjkim                return (Status);
872193529Sjkim            }
873193529Sjkim        }
874193529Sjkim
875193529Sjkim        /* Get the NS node associated with the target. It must exist. */
876193529Sjkim
877193529Sjkim        Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
878306536Sjkim            ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
879306536Sjkim            WalkState, &TargetNode);
880193529Sjkim        if (ACPI_FAILURE (Status))
881193529Sjkim        {
882193529Sjkim            if (Status == AE_NOT_FOUND)
883193529Sjkim            {
884193529Sjkim                AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
885193529Sjkim                    Op->Asl.ExternalName);
886193529Sjkim
887193529Sjkim                /*
888193529Sjkim                 * The name was not found, go ahead and create it.
889193529Sjkim                 * This prevents more errors later.
890193529Sjkim                 */
891193529Sjkim                Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
892306536Sjkim                    ACPI_TYPE_ANY,
893306536Sjkim                    ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH,
894306536Sjkim                    WalkState, &(Node));
895193529Sjkim                return (AE_OK);
896193529Sjkim            }
897193529Sjkim
898198237Sjkim            AslCoreSubsystemError (Op, Status,
899198237Sjkim                "Failure from namespace lookup", FALSE);
900193529Sjkim            return (AE_OK);
901193529Sjkim        }
902193529Sjkim
903193529Sjkim        /* Save the target node within the alias node */
904193529Sjkim
905193529Sjkim        Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
906193529Sjkim    }
907193529Sjkim
908193529Sjkim    return (AE_OK);
909193529Sjkim}
910193529Sjkim
911193529Sjkim
912193529Sjkim/*******************************************************************************
913193529Sjkim *
914193529Sjkim * FUNCTION:    LdCommonNamespaceEnd
915193529Sjkim *
916193529Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
917193529Sjkim *
918193529Sjkim * RETURN:      Status
919193529Sjkim *
920118611Snjl * DESCRIPTION: Ascending callback used during the loading of the namespace,
921118611Snjl *              We only need to worry about managing the scope stack here.
922118611Snjl *
923118611Snjl ******************************************************************************/
924118611Snjl
925151937Sjkimstatic ACPI_STATUS
926193529SjkimLdCommonNamespaceEnd (
927118611Snjl    ACPI_PARSE_OBJECT       *Op,
928118611Snjl    UINT32                  Level,
929118611Snjl    void                    *Context)
930118611Snjl{
931118611Snjl    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
932118611Snjl    ACPI_OBJECT_TYPE        ObjectType;
933167802Sjkim    BOOLEAN                 ForceNewScope = FALSE;
934118611Snjl
935118611Snjl
936193529Sjkim    ACPI_FUNCTION_NAME (LdCommonNamespaceEnd);
937118611Snjl
938118611Snjl
939118611Snjl    /* We are only interested in opcodes that have an associated name */
940118611Snjl
941118611Snjl    if (!Op->Asl.Namepath)
942118611Snjl    {
943118611Snjl        return (AE_OK);
944118611Snjl    }
945118611Snjl
946118611Snjl    /* Get the type to determine if we should pop the scope */
947118611Snjl
948118611Snjl    if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
949118611Snjl        (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
950118611Snjl    {
951118611Snjl        /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */
952118611Snjl
953118611Snjl        ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
954118611Snjl    }
955118611Snjl    else
956118611Snjl    {
957118611Snjl        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
958118611Snjl    }
959118611Snjl
960167802Sjkim    /* Pop scope that was pushed for Resource Templates */
961167802Sjkim
962167802Sjkim    if (Op->Asl.ParseOpcode == PARSEOP_NAME)
963167802Sjkim    {
964167802Sjkim        if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
965167802Sjkim        {
966167802Sjkim            ForceNewScope = TRUE;
967167802Sjkim        }
968167802Sjkim    }
969167802Sjkim
970118611Snjl    /* Pop the scope stack */
971118611Snjl
972167802Sjkim    if (ForceNewScope || AcpiNsOpensScope (ObjectType))
973118611Snjl    {
974118611Snjl        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
975118611Snjl            "(%s): Popping scope for Op [%s] %p\n",
976118611Snjl            AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op));
977118611Snjl
978151937Sjkim        (void) AcpiDsScopeStackPop (WalkState);
979118611Snjl    }
980118611Snjl
981118611Snjl    return (AE_OK);
982118611Snjl}
983