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