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