aslload.c revision 254745
1/******************************************************************************
2 *
3 * Module Name: dswload - Dispatcher namespace load callbacks
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2013, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#define __ASLLOAD_C__
45
46#include <contrib/dev/acpica/compiler/aslcompiler.h>
47#include <contrib/dev/acpica/include/amlcode.h>
48#include <contrib/dev/acpica/include/acdispat.h>
49#include <contrib/dev/acpica/include/acnamesp.h>
50
51#include "aslcompiler.y.h"
52
53#define _COMPONENT          ACPI_COMPILER
54        ACPI_MODULE_NAME    ("aslload")
55
56/* Local prototypes */
57
58static ACPI_STATUS
59LdLoadFieldElements (
60    ACPI_PARSE_OBJECT       *Op,
61    ACPI_WALK_STATE         *WalkState);
62
63static ACPI_STATUS
64LdLoadResourceElements (
65    ACPI_PARSE_OBJECT       *Op,
66    ACPI_WALK_STATE         *WalkState);
67
68static ACPI_STATUS
69LdNamespace1Begin (
70    ACPI_PARSE_OBJECT       *Op,
71    UINT32                  Level,
72    void                    *Context);
73
74static ACPI_STATUS
75LdNamespace2Begin (
76    ACPI_PARSE_OBJECT       *Op,
77    UINT32                  Level,
78    void                    *Context);
79
80static ACPI_STATUS
81LdCommonNamespaceEnd (
82    ACPI_PARSE_OBJECT       *Op,
83    UINT32                  Level,
84    void                    *Context);
85
86
87/*******************************************************************************
88 *
89 * FUNCTION:    LdLoadNamespace
90 *
91 * PARAMETERS:  RootOp      - Root of the parse tree
92 *
93 * RETURN:      Status
94 *
95 * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the
96 *              named ASL/AML objects into the namespace. The namespace is
97 *              constructed in order to resolve named references and references
98 *              to named fields within resource templates/descriptors.
99 *
100 ******************************************************************************/
101
102ACPI_STATUS
103LdLoadNamespace (
104    ACPI_PARSE_OBJECT       *RootOp)
105{
106    ACPI_WALK_STATE         *WalkState;
107
108
109    DbgPrint (ASL_DEBUG_OUTPUT, "\nCreating namespace\n\n");
110
111    /* Create a new walk state */
112
113    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
114    if (!WalkState)
115    {
116        return (AE_NO_MEMORY);
117    }
118
119    /* Walk the entire parse tree, first pass */
120
121    TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin,
122        LdCommonNamespaceEnd, WalkState);
123
124    /* Second pass to handle forward references */
125
126    TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin,
127        LdCommonNamespaceEnd, WalkState);
128
129    /* Dump the namespace if debug is enabled */
130
131    AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX);
132    return (AE_OK);
133}
134
135
136/*******************************************************************************
137 *
138 * FUNCTION:    LdLoadFieldElements
139 *
140 * PARAMETERS:  Op              - Parent node (Field)
141 *              WalkState       - Current walk state
142 *
143 * RETURN:      Status
144 *
145 * DESCRIPTION: Enter the named elements of the field (children of the parent)
146 *              into the namespace.
147 *
148 ******************************************************************************/
149
150static ACPI_STATUS
151LdLoadFieldElements (
152    ACPI_PARSE_OBJECT       *Op,
153    ACPI_WALK_STATE         *WalkState)
154{
155    ACPI_PARSE_OBJECT       *Child = NULL;
156    ACPI_NAMESPACE_NODE     *Node;
157    ACPI_STATUS             Status;
158
159
160    /* Get the first named field element */
161
162    switch (Op->Asl.AmlOpcode)
163    {
164    case AML_BANK_FIELD_OP:
165
166        Child = UtGetArg (Op, 6);
167        break;
168
169    case AML_INDEX_FIELD_OP:
170
171        Child = UtGetArg (Op, 5);
172        break;
173
174    case AML_FIELD_OP:
175
176        Child = UtGetArg (Op, 4);
177        break;
178
179    default:
180
181        /* No other opcodes should arrive here */
182
183        return (AE_BAD_PARAMETER);
184    }
185
186    /* Enter all elements into the namespace */
187
188    while (Child)
189    {
190        switch (Child->Asl.AmlOpcode)
191        {
192        case AML_INT_RESERVEDFIELD_OP:
193        case AML_INT_ACCESSFIELD_OP:
194        case AML_INT_CONNECTION_OP:
195            break;
196
197        default:
198
199            Status = AcpiNsLookup (WalkState->ScopeInfo,
200                        Child->Asl.Value.String,
201                        ACPI_TYPE_LOCAL_REGION_FIELD,
202                        ACPI_IMODE_LOAD_PASS1,
203                        ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
204                            ACPI_NS_ERROR_IF_FOUND,
205                        NULL, &Node);
206            if (ACPI_FAILURE (Status))
207            {
208                if (Status != AE_ALREADY_EXISTS)
209                {
210                    AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child,
211                        Child->Asl.Value.String);
212                    return (Status);
213                }
214
215                /*
216                 * The name already exists in this scope
217                 * But continue processing the elements
218                 */
219                AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,
220                    Child->Asl.Value.String);
221            }
222            else
223            {
224                Child->Asl.Node = Node;
225                Node->Op = Child;
226            }
227            break;
228        }
229
230        Child = Child->Asl.Next;
231    }
232
233    return (AE_OK);
234}
235
236
237/*******************************************************************************
238 *
239 * FUNCTION:    LdLoadResourceElements
240 *
241 * PARAMETERS:  Op              - Parent node (Resource Descriptor)
242 *              WalkState       - Current walk state
243 *
244 * RETURN:      Status
245 *
246 * DESCRIPTION: Enter the named elements of the resource descriptor (children
247 *              of the parent) into the namespace.
248 *
249 * NOTE: In the real AML namespace, these named elements never exist. But
250 *       we simply use the namespace here as a symbol table so we can look
251 *       them up as they are referenced.
252 *
253 ******************************************************************************/
254
255static ACPI_STATUS
256LdLoadResourceElements (
257    ACPI_PARSE_OBJECT       *Op,
258    ACPI_WALK_STATE         *WalkState)
259{
260    ACPI_PARSE_OBJECT       *InitializerOp = NULL;
261    ACPI_NAMESPACE_NODE     *Node;
262    ACPI_STATUS             Status;
263
264
265    /*
266     * Enter the resource name into the namespace. Name must not already exist.
267     * This opens a scope, so later field names are guaranteed to be new/unique.
268     */
269    Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath,
270                ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1,
271                ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND,
272                WalkState, &Node);
273    if (ACPI_FAILURE (Status))
274    {
275        if (Status == AE_ALREADY_EXISTS)
276        {
277            /* Actual node causing the error was saved in ParentMethod */
278
279            AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS,
280                (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath);
281            return (AE_OK);
282        }
283        return (Status);
284    }
285
286    Node->Value = (UINT32) Op->Asl.Value.Integer;
287    Node->Op = Op;
288    Op->Asl.Node = Node;
289
290    /*
291     * Now enter the predefined fields, for easy lookup when referenced
292     * by the source ASL
293     */
294    InitializerOp = ASL_GET_CHILD_NODE (Op);
295    while (InitializerOp)
296    {
297        if (InitializerOp->Asl.ExternalName)
298        {
299            Status = AcpiNsLookup (WalkState->ScopeInfo,
300                        InitializerOp->Asl.ExternalName,
301                        ACPI_TYPE_LOCAL_RESOURCE_FIELD,
302                        ACPI_IMODE_LOAD_PASS1,
303                        ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE,
304                        NULL, &Node);
305            if (ACPI_FAILURE (Status))
306            {
307                return (Status);
308            }
309
310            /*
311             * Store the field offset and length in the namespace node
312             * so it can be used when the field is referenced
313             */
314            Node->Value = InitializerOp->Asl.Value.Tag.BitOffset;
315            Node->Length = InitializerOp->Asl.Value.Tag.BitLength;
316            InitializerOp->Asl.Node = Node;
317            Node->Op = InitializerOp;
318        }
319
320        InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
321    }
322
323    return (AE_OK);
324}
325
326
327/*******************************************************************************
328 *
329 * FUNCTION:    LdNamespace1Begin
330 *
331 * PARAMETERS:  ASL_WALK_CALLBACK
332 *
333 * RETURN:      Status
334 *
335 * DESCRIPTION: Descending callback used during the parse tree walk. If this
336 *              is a named AML opcode, enter into the namespace
337 *
338 ******************************************************************************/
339
340static ACPI_STATUS
341LdNamespace1Begin (
342    ACPI_PARSE_OBJECT       *Op,
343    UINT32                  Level,
344    void                    *Context)
345{
346    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
347    ACPI_NAMESPACE_NODE     *Node;
348    ACPI_STATUS             Status;
349    ACPI_OBJECT_TYPE        ObjectType;
350    ACPI_OBJECT_TYPE        ActualObjectType = ACPI_TYPE_ANY;
351    char                    *Path;
352    UINT32                  Flags = ACPI_NS_NO_UPSEARCH;
353    ACPI_PARSE_OBJECT       *Arg;
354    UINT32                  i;
355    BOOLEAN                 ForceNewScope = FALSE;
356
357
358    ACPI_FUNCTION_NAME (LdNamespace1Begin);
359    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
360        Op, Op->Asl.ParseOpName));
361
362
363    /*
364     * We are only interested in opcodes that have an associated name
365     * (or multiple names)
366     */
367    switch (Op->Asl.AmlOpcode)
368    {
369    case AML_BANK_FIELD_OP:
370    case AML_INDEX_FIELD_OP:
371    case AML_FIELD_OP:
372
373        Status = LdLoadFieldElements (Op, WalkState);
374        return (Status);
375
376    default:
377
378        /* All other opcodes go below */
379
380        break;
381    }
382
383    /* Check if this object has already been installed in the namespace */
384
385    if (Op->Asl.Node)
386    {
387        return (AE_OK);
388    }
389
390    Path = Op->Asl.Namepath;
391    if (!Path)
392    {
393        return (AE_OK);
394    }
395
396    /* Map the raw opcode into an internal object type */
397
398    switch (Op->Asl.ParseOpcode)
399    {
400    case PARSEOP_NAME:
401
402        Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
403        Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
404
405        /*
406         * If this name refers to a ResourceTemplate, we will need to open
407         * a new scope so that the resource subfield names can be entered into
408         * the namespace underneath this name
409         */
410        if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
411        {
412            ForceNewScope = TRUE;
413        }
414
415        /* Get the data type associated with the named object, not the name itself */
416
417        /* Log2 loop to convert from Btype (binary) to Etype (encoded) */
418
419        ObjectType = 1;
420        for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2)
421        {
422            ObjectType++;
423        }
424        break;
425
426
427    case PARSEOP_EXTERNAL:
428        /*
429         * "External" simply enters a name and type into the namespace.
430         * We must be careful to not open a new scope, however, no matter
431         * what type the external name refers to (e.g., a method)
432         *
433         * first child is name, next child is ObjectType
434         */
435        ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer;
436        ObjectType = ACPI_TYPE_ANY;
437
438        /*
439         * We will mark every new node along the path as "External". This
440         * allows some or all of the nodes to be created later in the ASL
441         * code. Handles cases like this:
442         *
443         *   External (\_SB_.PCI0.ABCD, IntObj)
444         *   Scope (_SB_)
445         *   {
446         *       Device (PCI0)
447         *       {
448         *       }
449         *   }
450         *   Method (X)
451         *   {
452         *       Store (\_SB_.PCI0.ABCD, Local0)
453         *   }
454         */
455        Flags |= ACPI_NS_EXTERNAL;
456        break;
457
458    case PARSEOP_DEFAULT_ARG:
459
460        if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)
461        {
462            Status = LdLoadResourceElements (Op, WalkState);
463            return_ACPI_STATUS (Status);
464        }
465
466        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
467        break;
468
469
470    case PARSEOP_SCOPE:
471        /*
472         * The name referenced by Scope(Name) must already exist at this point.
473         * In other words, forward references for Scope() are not supported.
474         * The only real reason for this is that the MS interpreter cannot
475         * handle this case. Perhaps someday this case can go away.
476         */
477        Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
478                    ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
479                    WalkState, &(Node));
480        if (ACPI_FAILURE (Status))
481        {
482            if (Status == AE_NOT_FOUND)
483            {
484                /* The name was not found, go ahead and create it */
485
486                Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
487                            ACPI_TYPE_LOCAL_SCOPE,
488                            ACPI_IMODE_LOAD_PASS1, Flags,
489                            WalkState, &(Node));
490                if (ACPI_FAILURE (Status))
491                {
492                    return_ACPI_STATUS (Status);
493                }
494
495                /*
496                 * However, this is an error -- primarily because the MS
497                 * interpreter can't handle a forward reference from the
498                 * Scope() operator.
499                 */
500                AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
501                    Op->Asl.ExternalName);
502                AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op,
503                    Op->Asl.ExternalName);
504                goto FinishNode;
505            }
506
507            AslCoreSubsystemError (Op, Status,
508                "Failure from namespace lookup", FALSE);
509
510            return_ACPI_STATUS (Status);
511        }
512
513        /* We found a node with this name, now check the type */
514
515        switch (Node->Type)
516        {
517        case ACPI_TYPE_LOCAL_SCOPE:
518        case ACPI_TYPE_DEVICE:
519        case ACPI_TYPE_POWER:
520        case ACPI_TYPE_PROCESSOR:
521        case ACPI_TYPE_THERMAL:
522
523            /* These are acceptable types - they all open a new scope */
524            break;
525
526        case ACPI_TYPE_INTEGER:
527        case ACPI_TYPE_STRING:
528        case ACPI_TYPE_BUFFER:
529            /*
530             * These types we will allow, but we will change the type.
531             * This enables some existing code of the form:
532             *
533             *  Name (DEB, 0)
534             *  Scope (DEB) { ... }
535             *
536             * Which is used to workaround the fact that the MS interpreter
537             * does not allow Scope() forward references.
538             */
539            sprintf (MsgBuffer, "%s [%s], changing type to [Scope]",
540                Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
541            AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
542
543            /* Switch the type to scope, open the new scope */
544
545            Node->Type = ACPI_TYPE_LOCAL_SCOPE;
546            Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
547                        WalkState);
548            if (ACPI_FAILURE (Status))
549            {
550                return_ACPI_STATUS (Status);
551            }
552            break;
553
554        default:
555
556            /* All other types are an error */
557
558            sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName,
559                AcpiUtGetTypeName (Node->Type));
560            AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
561
562            /*
563             * However, switch the type to be an actual scope so
564             * that compilation can continue without generating a whole
565             * cascade of additional errors. Open the new scope.
566             */
567            Node->Type = ACPI_TYPE_LOCAL_SCOPE;
568            Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
569                        WalkState);
570            if (ACPI_FAILURE (Status))
571            {
572                return_ACPI_STATUS (Status);
573            }
574            break;
575        }
576
577        Status = AE_OK;
578        goto FinishNode;
579
580
581    default:
582
583        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
584        break;
585    }
586
587
588    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n",
589            Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType)));
590
591    /* The name must not already exist */
592
593    Flags |= ACPI_NS_ERROR_IF_FOUND;
594
595    /*
596     * Enter the named type into the internal namespace. We enter the name
597     * as we go downward in the parse tree. Any necessary subobjects that
598     * involve arguments to the opcode must be created as we go back up the
599     * parse tree later.
600     */
601    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
602                    ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
603    if (ACPI_FAILURE (Status))
604    {
605        if (Status == AE_ALREADY_EXISTS)
606        {
607            /* The name already exists in this scope */
608
609            if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
610            {
611                /* Allow multiple references to the same scope */
612
613                Node->Type = (UINT8) ObjectType;
614                Status = AE_OK;
615            }
616            else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
617                     (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
618            {
619                /*
620                 * Allow one create on an object or segment that was
621                 * previously declared External
622                 */
623                Node->Flags &= ~ANOBJ_IS_EXTERNAL;
624                Node->Type = (UINT8) ObjectType;
625
626                /* Just retyped a node, probably will need to open a scope */
627
628                if (AcpiNsOpensScope (ObjectType))
629                {
630                    Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
631                    if (ACPI_FAILURE (Status))
632                    {
633                        return_ACPI_STATUS (Status);
634                    }
635                }
636                Status = AE_OK;
637            }
638            else
639            {
640                /* Valid error, object already exists */
641
642                AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
643                    Op->Asl.ExternalName);
644                return_ACPI_STATUS (AE_OK);
645            }
646        }
647        else
648        {
649            AslCoreSubsystemError (Op, Status,
650                "Failure from namespace lookup", FALSE);
651            return_ACPI_STATUS (Status);
652        }
653    }
654
655    if (ForceNewScope)
656    {
657        Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
658        if (ACPI_FAILURE (Status))
659        {
660            return_ACPI_STATUS (Status);
661        }
662    }
663
664FinishNode:
665    /*
666     * Point the parse node to the new namespace node, and point
667     * the Node back to the original Parse node
668     */
669    Op->Asl.Node = Node;
670    Node->Op = Op;
671
672    /* Set the actual data type if appropriate (EXTERNAL term only) */
673
674    if (ActualObjectType != ACPI_TYPE_ANY)
675    {
676        Node->Type = (UINT8) ActualObjectType;
677        Node->Value = ASL_EXTERNAL_METHOD;
678    }
679
680    if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
681    {
682        /*
683         * Get the method argument count from "Extra" and save
684         * it in the namespace node
685         */
686        Node->Value = (UINT32) Op->Asl.Extra;
687    }
688
689    return_ACPI_STATUS (Status);
690}
691
692
693/*******************************************************************************
694 *
695 * FUNCTION:    LdNamespace2Begin
696 *
697 * PARAMETERS:  ASL_WALK_CALLBACK
698 *
699 * RETURN:      Status
700 *
701 * DESCRIPTION: Descending callback used during the pass 2 parse tree walk.
702 *              Second pass resolves some forward references.
703 *
704 * Notes:
705 * Currently only needs to handle the Alias operator.
706 * Could be used to allow forward references from the Scope() operator, but
707 * the MS interpreter does not allow this, so this compiler does not either.
708 *
709 ******************************************************************************/
710
711static ACPI_STATUS
712LdNamespace2Begin (
713    ACPI_PARSE_OBJECT       *Op,
714    UINT32                  Level,
715    void                    *Context)
716{
717    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
718    ACPI_STATUS             Status;
719    ACPI_NAMESPACE_NODE     *Node;
720    ACPI_OBJECT_TYPE        ObjectType;
721    BOOLEAN                 ForceNewScope = FALSE;
722    ACPI_PARSE_OBJECT       *Arg;
723    char                    *Path;
724    ACPI_NAMESPACE_NODE     *TargetNode;
725
726
727    ACPI_FUNCTION_NAME (LdNamespace2Begin);
728    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
729        Op, Op->Asl.ParseOpName));
730
731
732    /* Ignore Ops with no namespace node */
733
734    Node = Op->Asl.Node;
735    if (!Node)
736    {
737        return (AE_OK);
738    }
739
740    /* Get the type to determine if we should push the scope */
741
742    if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
743        (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
744    {
745        ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
746    }
747    else
748    {
749        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
750    }
751
752    /* Push scope for Resource Templates */
753
754    if (Op->Asl.ParseOpcode == PARSEOP_NAME)
755    {
756        if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
757        {
758            ForceNewScope = TRUE;
759        }
760    }
761
762    /* Push the scope stack */
763
764    if (ForceNewScope || AcpiNsOpensScope (ObjectType))
765    {
766        Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
767        if (ACPI_FAILURE (Status))
768        {
769            return_ACPI_STATUS (Status);
770        }
771    }
772
773    if (Op->Asl.ParseOpcode == PARSEOP_ALIAS)
774    {
775        /* Complete the alias node by getting and saving the target node */
776
777        /* First child is the alias target */
778
779        Arg = Op->Asl.Child;
780
781        /* Get the target pathname */
782
783        Path = Arg->Asl.Namepath;
784        if (!Path)
785        {
786            Status = UtInternalizeName (Arg->Asl.ExternalName, &Path);
787            if (ACPI_FAILURE (Status))
788            {
789                return (Status);
790            }
791        }
792
793        /* Get the NS node associated with the target. It must exist. */
794
795        Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
796                    ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
797                    WalkState, &TargetNode);
798        if (ACPI_FAILURE (Status))
799        {
800            if (Status == AE_NOT_FOUND)
801            {
802                AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
803                    Op->Asl.ExternalName);
804
805                /*
806                 * The name was not found, go ahead and create it.
807                 * This prevents more errors later.
808                 */
809                Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
810                            ACPI_TYPE_ANY,
811                            ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH,
812                            WalkState, &(Node));
813                return (AE_OK);
814            }
815
816            AslCoreSubsystemError (Op, Status,
817                "Failure from namespace lookup", FALSE);
818            return (AE_OK);
819        }
820
821        /* Save the target node within the alias node */
822
823        Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
824    }
825
826    return (AE_OK);
827}
828
829
830/*******************************************************************************
831 *
832 * FUNCTION:    LdCommonNamespaceEnd
833 *
834 * PARAMETERS:  ASL_WALK_CALLBACK
835 *
836 * RETURN:      Status
837 *
838 * DESCRIPTION: Ascending callback used during the loading of the namespace,
839 *              We only need to worry about managing the scope stack here.
840 *
841 ******************************************************************************/
842
843static ACPI_STATUS
844LdCommonNamespaceEnd (
845    ACPI_PARSE_OBJECT       *Op,
846    UINT32                  Level,
847    void                    *Context)
848{
849    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
850    ACPI_OBJECT_TYPE        ObjectType;
851    BOOLEAN                 ForceNewScope = FALSE;
852
853
854    ACPI_FUNCTION_NAME (LdCommonNamespaceEnd);
855
856
857    /* We are only interested in opcodes that have an associated name */
858
859    if (!Op->Asl.Namepath)
860    {
861        return (AE_OK);
862    }
863
864    /* Get the type to determine if we should pop the scope */
865
866    if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
867        (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
868    {
869        /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */
870
871        ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
872    }
873    else
874    {
875        ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
876    }
877
878    /* Pop scope that was pushed for Resource Templates */
879
880    if (Op->Asl.ParseOpcode == PARSEOP_NAME)
881    {
882        if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
883        {
884            ForceNewScope = TRUE;
885        }
886    }
887
888    /* Pop the scope stack */
889
890    if (ForceNewScope || AcpiNsOpensScope (ObjectType))
891    {
892        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
893            "(%s): Popping scope for Op [%s] %p\n",
894            AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op));
895
896        (void) AcpiDsScopeStackPop (WalkState);
897    }
898
899    return (AE_OK);
900}
901