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