xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/aslload.c (revision 2c7d7e3ca2e4f0b675c6c58e614f6aede66c678e)
1 /******************************************************************************
2  *
3  * Module Name: aslload - compiler namespace load callbacks
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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 #include "acparser.h"
49 #include "aslcompiler.y.h"
50 
51 
52 #define _COMPONENT          ACPI_COMPILER
53         ACPI_MODULE_NAME    ("aslload")
54 
55 /* Local prototypes */
56 
57 static ACPI_STATUS
58 LdLoadFieldElements (
59     UINT32                  AmlType,
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 static void
87 LdCheckSpecialNames (
88     ACPI_NAMESPACE_NODE     *Node,
89     ACPI_PARSE_OBJECT       *Op);
90 
91 static ACPI_STATUS
92 LdAnalyzeExternals (
93     ACPI_NAMESPACE_NODE     *Node,
94     ACPI_PARSE_OBJECT       *Op,
95     ACPI_OBJECT_TYPE        ExternalOpType,
96     ACPI_WALK_STATE         *WalkState);
97 
98 
99 /*******************************************************************************
100  *
101  * FUNCTION:    LdLoadNamespace
102  *
103  * PARAMETERS:  RootOp      - Root of the parse tree
104  *
105  * RETURN:      Status
106  *
107  * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the
108  *              named ASL/AML objects into the namespace. The namespace is
109  *              constructed in order to resolve named references and references
110  *              to named fields within resource templates/descriptors.
111  *
112  ******************************************************************************/
113 
114 ACPI_STATUS
LdLoadNamespace(ACPI_PARSE_OBJECT * RootOp)115 LdLoadNamespace (
116     ACPI_PARSE_OBJECT       *RootOp)
117 {
118     ACPI_WALK_STATE         *WalkState;
119 
120 
121     /* Create a new walk state */
122 
123     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
124     if (!WalkState)
125     {
126         return (AE_NO_MEMORY);
127     }
128 
129     /* Walk the entire parse tree, first pass */
130 
131     TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin,
132         LdCommonNamespaceEnd, WalkState);
133 
134     /* Second pass to handle forward references */
135 
136     TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin,
137         LdCommonNamespaceEnd, WalkState);
138 
139     /* Dump the namespace if debug is enabled */
140 
141     if (AcpiDbgLevel & ACPI_LV_TABLES)
142     {
143         AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX);
144     }
145 
146     ACPI_FREE (WalkState);
147     return (AE_OK);
148 }
149 
150 
151 /*******************************************************************************
152  *
153  * FUNCTION:    LdLoadFieldElements
154  *
155  * PARAMETERS:  AmlType         - Type to search
156  *              Op              - Parent node (Field)
157  *              WalkState       - Current walk state
158  *
159  * RETURN:      Status
160  *
161  * DESCRIPTION: Enter the named elements of the field (children of the parent)
162  *              into the namespace.
163  *
164  ******************************************************************************/
165 
166 static ACPI_STATUS
LdLoadFieldElements(UINT32 AmlType,ACPI_PARSE_OBJECT * Op,ACPI_WALK_STATE * WalkState)167 LdLoadFieldElements (
168     UINT32                  AmlType,
169     ACPI_PARSE_OBJECT       *Op,
170     ACPI_WALK_STATE         *WalkState)
171 {
172     ACPI_PARSE_OBJECT       *Child = NULL;
173     ACPI_PARSE_OBJECT       *SourceRegion;
174     ACPI_NAMESPACE_NODE     *Node;
175     ACPI_STATUS             Status;
176     char                    *ExternalPath;
177 
178 
179     SourceRegion = UtGetArg (Op, 0);
180     if (SourceRegion)
181     {
182         Status = AcpiNsLookup (WalkState->ScopeInfo,
183             SourceRegion->Asl.Value.String, AmlType, ACPI_IMODE_EXECUTE,
184             ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
185         if (Status == AE_NOT_FOUND)
186         {
187             /*
188              * If the named object is not found, it means that it is either a
189              * forward reference or the named object does not exist.
190              */
191             SourceRegion->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD;
192         }
193     }
194 
195     /* Get the first named field element */
196 
197     switch (Op->Asl.AmlOpcode)
198     {
199     case AML_BANK_FIELD_OP:
200 
201         Child = UtGetArg (Op, 6);
202         break;
203 
204     case AML_INDEX_FIELD_OP:
205 
206         Child = UtGetArg (Op, 5);
207         break;
208 
209     case AML_FIELD_OP:
210 
211         Child = UtGetArg (Op, 4);
212         break;
213 
214     default:
215 
216         /* No other opcodes should arrive here */
217 
218         return (AE_BAD_PARAMETER);
219     }
220 
221     /* Enter all elements into the namespace */
222 
223     while (Child)
224     {
225         switch (Child->Asl.AmlOpcode)
226         {
227         case AML_INT_RESERVEDFIELD_OP:
228         case AML_INT_ACCESSFIELD_OP:
229         case AML_INT_CONNECTION_OP:
230             break;
231 
232         default:
233 
234             Status = AcpiNsLookup (WalkState->ScopeInfo,
235                 Child->Asl.Value.String,
236                 ACPI_TYPE_LOCAL_REGION_FIELD,
237                 ACPI_IMODE_LOAD_PASS1,
238                 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
239                     ACPI_NS_ERROR_IF_FOUND, NULL, &Node);
240             if (ACPI_FAILURE (Status))
241             {
242                 if (Status != AE_ALREADY_EXISTS)
243                 {
244                     AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child,
245                         Child->Asl.Value.String);
246                     return (Status);
247                 }
248                 else if (Status == AE_ALREADY_EXISTS &&
249                     (Node->Flags & ANOBJ_IS_EXTERNAL))
250                 {
251                     Node->Type = (UINT8) ACPI_TYPE_LOCAL_REGION_FIELD;
252                     Node->Flags &= ~ANOBJ_IS_EXTERNAL;
253                 }
254                 else
255                 {
256                     /*
257                      * The name already exists in this scope
258                      * But continue processing the elements
259                      */
260                     ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);
261 
262                     AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,
263                         ExternalPath, ASL_MSG_FOUND_HERE, Node->Op,
264                         ExternalPath);
265 
266                     if (ExternalPath)
267                     {
268                         ACPI_FREE (ExternalPath);
269                     }
270                 }
271             }
272             else
273             {
274                 Child->Asl.Node = Node;
275                 Node->Op = Child;
276             }
277             break;
278         }
279 
280         Child = Child->Asl.Next;
281     }
282 
283     return (AE_OK);
284 }
285 
286 
287 /*******************************************************************************
288  *
289  * FUNCTION:    LdLoadResourceElements
290  *
291  * PARAMETERS:  Op              - Parent node (Resource Descriptor)
292  *              WalkState       - Current walk state
293  *
294  * RETURN:      Status
295  *
296  * DESCRIPTION: Enter the named elements of the resource descriptor (children
297  *              of the parent) into the namespace.
298  *
299  * NOTE: In the real AML namespace, these named elements never exist. But
300  *       we simply use the namespace here as a symbol table so we can look
301  *       them up as they are referenced.
302  *
303  ******************************************************************************/
304 
305 static ACPI_STATUS
LdLoadResourceElements(ACPI_PARSE_OBJECT * Op,ACPI_WALK_STATE * WalkState)306 LdLoadResourceElements (
307     ACPI_PARSE_OBJECT       *Op,
308     ACPI_WALK_STATE         *WalkState)
309 {
310     ACPI_PARSE_OBJECT       *InitializerOp = NULL;
311     ACPI_NAMESPACE_NODE     *Node;
312     ACPI_STATUS             Status;
313     char                    *ExternalPath;
314 
315 
316     /*
317      * Enter the resource name into the namespace. Name must not already exist.
318      * This opens a scope, so later field names are guaranteed to be new/unique.
319      */
320     Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath,
321         ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1,
322         ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND,
323         WalkState, &Node);
324     if (ACPI_FAILURE (Status))
325     {
326         if (Status == AE_ALREADY_EXISTS)
327         {
328             /* Actual node causing the error was saved in ParentMethod */
329 
330             ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);
331 
332             AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS,
333                 (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod,
334                 ExternalPath, ASL_MSG_FOUND_HERE, Node->Op,
335                 ExternalPath);
336 
337             if (ExternalPath)
338             {
339                 ACPI_FREE (ExternalPath);
340             }
341             return (AE_OK);
342         }
343         return (Status);
344     }
345 
346     Node->Value = (UINT32) Op->Asl.Value.Integer;
347     Node->Op = Op;
348     Op->Asl.Node = Node;
349 
350     /*
351      * Now enter the predefined fields, for easy lookup when referenced
352      * by the source ASL
353      */
354     InitializerOp = ASL_GET_CHILD_NODE (Op);
355     while (InitializerOp)
356     {
357         if (InitializerOp->Asl.ExternalName)
358         {
359             Status = AcpiNsLookup (WalkState->ScopeInfo,
360                 InitializerOp->Asl.ExternalName,
361                 ACPI_TYPE_LOCAL_RESOURCE_FIELD, ACPI_IMODE_LOAD_PASS1,
362                 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
363             if (ACPI_FAILURE (Status))
364             {
365                 return (Status);
366             }
367 
368             /*
369              * Store the field offset and length in the namespace node
370              * so it can be used when the field is referenced
371              */
372             Node->Value = InitializerOp->Asl.Value.Tag.BitOffset;
373             Node->Length = InitializerOp->Asl.Value.Tag.BitLength;
374             InitializerOp->Asl.Node = Node;
375             Node->Op = InitializerOp;
376         }
377 
378         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
379     }
380 
381     return (AE_OK);
382 }
383 
384 
385 /*******************************************************************************
386  *
387  * FUNCTION:    LdNamespace1Begin
388  *
389  * PARAMETERS:  ASL_WALK_CALLBACK
390  *
391  * RETURN:      Status
392  *
393  * DESCRIPTION: Descending callback used during the parse tree walk. If this
394  *              is a named AML opcode, enter into the namespace
395  *
396  ******************************************************************************/
397 
398 static ACPI_STATUS
LdNamespace1Begin(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)399 LdNamespace1Begin (
400     ACPI_PARSE_OBJECT       *Op,
401     UINT32                  Level,
402     void                    *Context)
403 {
404     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
405     ACPI_NAMESPACE_NODE     *Node;
406     ACPI_PARSE_OBJECT       *MethodOp;
407     ACPI_STATUS             Status;
408     ACPI_OBJECT_TYPE        ObjectType;
409     char                    *Path;
410     UINT32                  Flags = ACPI_NS_NO_UPSEARCH;
411     ACPI_PARSE_OBJECT       *Arg;
412     UINT32                  i;
413     BOOLEAN                 ForceNewScope = FALSE;
414     const ACPI_OPCODE_INFO  *OpInfo;
415     ACPI_PARSE_OBJECT       *ParentOp;
416     char                    *ExternalPath;
417 
418 
419     ACPI_FUNCTION_NAME (LdNamespace1Begin);
420 
421 
422     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
423         Op, Op->Asl.ParseOpName));
424 
425     /*
426      * We are only interested in opcodes that have an associated name
427      * (or multiple names)
428      */
429     switch (Op->Asl.AmlOpcode)
430     {
431     case AML_INDEX_FIELD_OP:
432 
433         Status = LdLoadFieldElements (ACPI_TYPE_LOCAL_REGION_FIELD, Op, WalkState);
434         return (Status);
435 
436     case AML_BANK_FIELD_OP:
437     case AML_FIELD_OP:
438 
439         Status = LdLoadFieldElements (ACPI_TYPE_REGION, Op, WalkState);
440         return (Status);
441 
442     case AML_INT_CONNECTION_OP:
443 
444         if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)
445         {
446             break;
447         }
448 
449         Arg = Op->Asl.Child;
450         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName,
451             ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
452             WalkState, &Node);
453         if (ACPI_FAILURE (Status))
454         {
455             break;
456         }
457 
458         break;
459 
460     default:
461 
462         /* All other opcodes go below */
463 
464         break;
465     }
466 
467     /* Check if this object has already been installed in the namespace */
468 
469     if (Op->Asl.Node)
470     {
471         return (AE_OK);
472     }
473 
474     /* Check for a possible illegal forward reference */
475 
476     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
477         (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
478         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
479     {
480         /*
481          * Op->Asl.Namepath will be NULL for these opcodes.
482          * These opcodes are guaranteed to have a parent.
483          * Examine the parent opcode.
484          */
485         ParentOp = Op->Asl.Parent;
486         OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Asl.AmlOpcode);
487 
488         /*
489          * Exclude all operators that actually declare a new name:
490          *      Name (ABCD, 1) -> Ignore (AML_CLASS_NAMED_OBJECT)
491          * We only want references to named objects:
492          *      Store (2, WXYZ) -> Attempt to resolve the name
493          */
494         if ((Op->Asl.ParseOpcode != PARSEOP_METHODCALL) &&
495             (OpInfo->Class == AML_CLASS_NAMED_OBJECT))
496         {
497             return (AE_OK);
498         }
499 
500         /*
501          * Check if the referenced object exists at this point during
502          * the load:
503          * 1) If it exists, then this cannot be a forward reference.
504          * 2) If it does not exist, it could be a forward reference or
505          * it truly does not exist (and no external declaration).
506          */
507         Status = AcpiNsLookup (WalkState->ScopeInfo,
508             Op->Asl.Value.Name, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
509             ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
510             WalkState, &Node);
511         if (Status == AE_NOT_FOUND)
512         {
513             /*
514              * This is either a forward reference or the object truly
515              * does not exist. The two cases can only be differentiated
516              * during the cross-reference stage later. Mark the Op/Name
517              * as not-found for now to indicate the need for further
518              * processing.
519              *
520              * Special case: Allow forward references from elements of
521              * Package objects. This provides compatibility with other
522              * ACPI implementations. To correctly implement this, the
523              * ACPICA table load defers package resolution until the entire
524              * namespace has been loaded.
525              */
526             if ((ParentOp->Asl.ParseOpcode != PARSEOP_PACKAGE) &&
527                 (ParentOp->Asl.ParseOpcode != PARSEOP_VAR_PACKAGE))
528             {
529                 Op->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD;
530             }
531 
532             return (AE_OK);
533         }
534 
535         return (Status);
536     }
537 
538     Path = Op->Asl.Namepath;
539     if (!Path)
540     {
541         return (AE_OK);
542     }
543 
544     /* Map the raw opcode into an internal object type */
545 
546     switch (Op->Asl.ParseOpcode)
547     {
548     case PARSEOP_NAME:
549 
550         Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
551         Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
552 
553         /*
554          * If this name refers to a ResourceTemplate, we will need to open
555          * a new scope so that the resource subfield names can be entered into
556          * the namespace underneath this name
557          */
558         if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
559         {
560             ForceNewScope = TRUE;
561         }
562 
563         /* Get the data type associated with the named object, not the name itself */
564 
565         /* Log2 loop to convert from Btype (binary) to Etype (encoded) */
566 
567         ObjectType = 1;
568         for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2)
569         {
570             ObjectType++;
571         }
572         break;
573 
574     case PARSEOP_EXTERNAL:
575         /*
576          * "External" simply enters a name and type into the namespace.
577          * We must be careful to not open a new scope, however, no matter
578          * what type the external name refers to (e.g., a method)
579          *
580          * first child is name, next child is ObjectType
581          */
582         ObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer;
583 
584         /*
585          * We will mark every new node along the path as "External". This
586          * allows some or all of the nodes to be created later in the ASL
587          * code. Handles cases like this:
588          *
589          *   External (\_SB_.PCI0.ABCD, IntObj)
590          *   Scope (_SB_)
591          *   {
592          *       Device (PCI0)
593          *       {
594          *       }
595          *   }
596          *   Method (X)
597          *   {
598          *       Store (\_SB_.PCI0.ABCD, Local0)
599          *   }
600          */
601         Flags |= ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE;
602         break;
603 
604     case PARSEOP_DEFAULT_ARG:
605 
606         if (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC)
607         {
608             Status = LdLoadResourceElements (Op, WalkState);
609             return_ACPI_STATUS (Status);
610         }
611 
612         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
613         break;
614 
615     case PARSEOP_SCOPE:
616         /*
617          * The name referenced by Scope(Name) must already exist at this point.
618          * In other words, forward references for Scope() are not supported.
619          * The only real reason for this is that the MS interpreter cannot
620          * handle this case. Perhaps someday this case can go away.
621          */
622         Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
623             ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &Node);
624         if (ACPI_FAILURE (Status))
625         {
626             if (Status == AE_NOT_FOUND)
627             {
628                 /* The name was not found, go ahead and create it */
629 
630                 Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
631                     ACPI_TYPE_LOCAL_SCOPE, ACPI_IMODE_LOAD_PASS1,
632                     Flags, WalkState, &Node);
633                 if (ACPI_FAILURE (Status))
634                 {
635                     return_ACPI_STATUS (Status);
636                 }
637 
638                 /* However, this is an error -- operand to Scope must exist */
639 
640                 if (strlen (Op->Asl.ExternalName) == ACPI_NAMESEG_SIZE)
641                 {
642                     AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
643                         Op->Asl.ExternalName);
644                 }
645                 else
646                 {
647                     AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
648                         Op->Asl.ExternalName);
649                 }
650 
651                 goto FinishNode;
652             }
653 
654             AslCoreSubsystemError (Op, Status,
655                 "Failure from namespace lookup", FALSE);
656 
657             return_ACPI_STATUS (Status);
658         }
659         else /* Status AE_OK */
660         {
661             /*
662              * Do not allow references to external scopes from the DSDT.
663              * This is because the DSDT is always loaded first, and the
664              * external reference cannot be resolved -- causing a runtime
665              * error because Scope() must be resolved immediately.
666              * 10/2015.
667              */
668             if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
669                 (ACPI_COMPARE_NAMESEG (AslGbl_TableSignature, "DSDT")))
670             {
671                 /* However, allowed if the reference is within a method */
672 
673                 MethodOp = Op->Asl.Parent;
674                 while (MethodOp &&
675                       (MethodOp->Asl.ParseOpcode != PARSEOP_METHOD))
676                 {
677                     MethodOp = MethodOp->Asl.Parent;
678                 }
679 
680                 if (!MethodOp)
681                 {
682                     /* Not in a control method, error */
683 
684                     AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL);
685                 }
686             }
687         }
688 
689         /* We found a node with this name, now check the type */
690 
691         switch (Node->Type)
692         {
693         case ACPI_TYPE_LOCAL_SCOPE:
694         case ACPI_TYPE_DEVICE:
695         case ACPI_TYPE_POWER:
696         case ACPI_TYPE_PROCESSOR:
697         case ACPI_TYPE_THERMAL:
698 
699             /* These are acceptable types - they all open a new scope */
700             break;
701 
702         case ACPI_TYPE_INTEGER:
703         case ACPI_TYPE_STRING:
704         case ACPI_TYPE_BUFFER:
705             /*
706              * These types we will allow, but we will change the type.
707              * This enables some existing code of the form:
708              *
709              *  Name (DEB, 0)
710              *  Scope (DEB) { ... }
711              *
712              * Which is used to workaround the fact that the MS interpreter
713              * does not allow Scope() forward references.
714              */
715             snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s [%s], changing type to [Scope]",
716                 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
717             AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);
718 
719             /* Switch the type to scope, open the new scope */
720 
721             Node->Type = ACPI_TYPE_LOCAL_SCOPE;
722             Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
723                 WalkState);
724             if (ACPI_FAILURE (Status))
725             {
726                 return_ACPI_STATUS (Status);
727             }
728             break;
729 
730         default:
731 
732             /* All other types are an error */
733 
734             snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s [%s]", Op->Asl.ExternalName,
735                 AcpiUtGetTypeName (Node->Type));
736             AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);
737 
738             /*
739              * However, switch the type to be an actual scope so
740              * that compilation can continue without generating a whole
741              * cascade of additional errors. Open the new scope.
742              */
743             Node->Type = ACPI_TYPE_LOCAL_SCOPE;
744             Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
745                 WalkState);
746             if (ACPI_FAILURE (Status))
747             {
748                 return_ACPI_STATUS (Status);
749             }
750             break;
751         }
752 
753         Status = AE_OK;
754         goto FinishNode;
755 
756     default:
757 
758         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
759         break;
760     }
761 
762     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n",
763         Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType)));
764 
765     /* The name must not already exist */
766 
767     Flags |= ACPI_NS_ERROR_IF_FOUND;
768 
769     /*
770      * For opcodes that enter new names into the namespace,
771      * all prefix NameSegs must exist.
772      */
773     WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
774     if (((WalkState->OpInfo->Flags & AML_NAMED) ||
775         (WalkState->OpInfo->Flags & AML_CREATE)) &&
776         (Op->Asl.AmlOpcode != AML_EXTERNAL_OP))
777     {
778         Flags |= ACPI_NS_PREFIX_MUST_EXIST;
779     }
780 
781     /*
782      * Enter the named type into the internal namespace. We enter the name
783      * as we go downward in the parse tree. Any necessary subobjects that
784      * involve arguments to the opcode must be created as we go back up the
785      * parse tree later.
786      */
787     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
788         ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
789     if (ACPI_FAILURE (Status))
790     {
791         if (Status == AE_ALREADY_EXISTS)
792         {
793             /* The name already exists in this scope */
794 
795             if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
796             {
797                 /* Allow multiple references to the same scope */
798 
799                 Node->Type = (UINT8) ObjectType;
800                 Status = AE_OK;
801             }
802             else if ((Node->Flags & ANOBJ_IS_EXTERNAL) ||
803                      (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
804             {
805                 Status = LdAnalyzeExternals (Node, Op, ObjectType, WalkState);
806                 if (ACPI_FAILURE (Status))
807                 {
808                     if (Status == AE_ERROR)
809                     {
810                         /*
811                          * The use of AE_ERROR here indicates that there was a
812                          * compiler error emitted in LdAnalyzeExternals which
813                          * means that the caller should proceed to the next Op
814                          * for analysis of subsequent parse objects.
815                          */
816                         Status = AE_OK;
817                     }
818                     return_ACPI_STATUS (Status);
819                 }
820 
821                 if (!(Node->Flags & ANOBJ_IS_EXTERNAL) &&
822                      (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
823                 {
824                     /*
825                      * If we get to here, it means that an actual definition of
826                      * the object declared external exists. Meaning that Op
827                      * loading this this Op should have no change to the ACPI
828                      * namespace. By going to FinishNode, we skip the
829                      * assignment of Node->Op = Op.
830                      */
831                     goto FinishNode;
832                 }
833             }
834             else
835             {
836                 /* Valid error, object already exists */
837 
838                 ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);
839 
840                 AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
841                     ExternalPath, ASL_MSG_FOUND_HERE, Node->Op,
842                     ExternalPath);
843 
844                 if (ExternalPath)
845                 {
846                     ACPI_FREE (ExternalPath);
847                 }
848                 return_ACPI_STATUS (AE_OK);
849             }
850         }
851         else if (AE_NOT_FOUND)
852         {
853             /*
854              * One or more prefix NameSegs of the NamePath do not exist
855              * (all of them must exist). Attempt to continue compilation
856              * by setting the current scope to the root.
857              */
858             Node = AcpiGbl_RootNode;
859             Status = AE_OK;
860         }
861         else
862         {
863             /* Flag all other errors as coming from the ACPICA core */
864 
865             AslCoreSubsystemError (Op, Status,
866                 "Failure from namespace lookup", FALSE);
867             return_ACPI_STATUS (Status);
868         }
869     }
870 
871     /* Check special names like _WAK and _PTS */
872 
873     LdCheckSpecialNames (Node, Op);
874 
875     if (ForceNewScope)
876     {
877         Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
878         if (ACPI_FAILURE (Status))
879         {
880             return_ACPI_STATUS (Status);
881         }
882     }
883 
884     /* Point the Node back to the original Parse node */
885 
886     Node->Op = Op;
887 
888 FinishNode:
889 
890     /* Point the parse node to the new namespace node */
891 
892     Op->Asl.Node = Node;
893 
894     if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
895     {
896         /*
897          * Get the method argument count from "Extra" and save
898          * it in the namespace node
899          */
900         Node->Value = (UINT32) Op->Asl.Extra;
901     }
902     else if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL &&
903         Node->Type == ACPI_TYPE_METHOD &&
904         (Node->Flags & ANOBJ_IS_EXTERNAL))
905     {
906         Node->Value =
907             (UINT32) Op->Asl.Child->Asl.Next->Asl.Next->Asl.Value.Integer;
908     }
909 
910     return_ACPI_STATUS (Status);
911 }
912 
913 
914 /*******************************************************************************
915  *
916  * FUNCTION:    LdMatchExternType
917  *
918  * PARAMETERS:  Type1
919  *              Type2
920  *
921  * RETURN:      BOOLEAN
922  *
923  * DESCRIPTION: Match Type1 and Type2 with the assumption that one might be
924  *              using external types and another might be using local types.
925  *              This should be used to compare the types found in external
926  *              declarations with types found in other external declarations or
927  *              named object declaration. This should not be used to match two
928  *              object type declarations.
929  *
930  ******************************************************************************/
931 
932 static BOOLEAN
LdMatchExternType(ACPI_OBJECT_TYPE Type1,ACPI_OBJECT_TYPE Type2)933 LdMatchExternType (
934     ACPI_OBJECT_TYPE        Type1,
935     ACPI_OBJECT_TYPE        Type2)
936 {
937     BOOLEAN                 Type1IsLocal = Type1 > ACPI_TYPE_EXTERNAL_MAX;
938     BOOLEAN                 Type2IsLocal = Type2 > ACPI_TYPE_EXTERNAL_MAX;
939     ACPI_OBJECT_TYPE        ExternalType;
940     ACPI_OBJECT_TYPE        LocalType;
941 
942 
943     /*
944      * The inputs could represent types that are local to ACPICA or types that
945      * are known externally. Some local types, such as the OperationRegion
946      * field units, are defined with more granularity than ACPICA local types.
947      *
948      * Therefore, map the local types to the external types before matching.
949      */
950     if (Type1IsLocal && !Type2IsLocal)
951     {
952         LocalType = Type1;
953         ExternalType = Type2;
954     }
955     else if (!Type1IsLocal && Type2IsLocal)
956     {
957         LocalType = Type2;
958         ExternalType = Type1;
959     }
960     else
961     {
962         return (Type1 == Type2);
963     }
964 
965     switch (LocalType)
966     {
967         case ACPI_TYPE_LOCAL_REGION_FIELD:
968         case ACPI_TYPE_LOCAL_BANK_FIELD:
969         case ACPI_TYPE_LOCAL_INDEX_FIELD:
970 
971             LocalType = ACPI_TYPE_FIELD_UNIT;
972             break;
973 
974         default:
975             break;
976     }
977 
978     return (LocalType == ExternalType);
979 }
980 
981 
982 /*******************************************************************************
983  *
984  * FUNCTION:    LdAnalyzeExternals
985  *
986  * PARAMETERS:  Node            - Node that represents the named object
987  *              Op              - Named object declaring this named object
988  *              ExternalOpType  - Type of ExternalOp
989  *              WalkState       - Current WalkState
990  *
991  * RETURN:      Status
992  *
993  * DESCRIPTION: Node and Op represents an identically named object declaration
994  *              that is either declared by the ASL external keyword or declared
995  *              by operators that declare named objects (i.e. Name, Device,
996  *              OperationRegion, and etc.). This function ensures that the
997  *              declarations do not contradict each other.
998  *
999  ******************************************************************************/
1000 
1001 static ACPI_STATUS
LdAnalyzeExternals(ACPI_NAMESPACE_NODE * Node,ACPI_PARSE_OBJECT * Op,ACPI_OBJECT_TYPE ExternalOpType,ACPI_WALK_STATE * WalkState)1002 LdAnalyzeExternals (
1003     ACPI_NAMESPACE_NODE     *Node,
1004     ACPI_PARSE_OBJECT       *Op,
1005     ACPI_OBJECT_TYPE        ExternalOpType,
1006     ACPI_WALK_STATE         *WalkState)
1007 {
1008     ACPI_STATUS             Status = AE_OK;
1009     ACPI_OBJECT_TYPE        ActualExternalOpType;
1010     ACPI_OBJECT_TYPE        ActualOpType;
1011     ACPI_PARSE_OBJECT       *ExternalOp;
1012     ACPI_PARSE_OBJECT       *ActualOp;
1013 
1014 
1015     /*
1016      * The declaration represented by Node and Op must have the same type.
1017      * The type of the external Op is represented by ExternalOpType. However,
1018      * the type of the pre-existing declaration depends on whether if Op
1019      * is an external declaration or an actual declaration.
1020      */
1021     if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)
1022     {
1023         ActualExternalOpType = ExternalOpType;
1024         ActualOpType = Node->Type;
1025     }
1026     else
1027     {
1028         ActualExternalOpType = Node->Type;
1029         ActualOpType = ExternalOpType;
1030     }
1031 
1032     if ((ActualOpType != ACPI_TYPE_ANY) &&
1033         (ActualExternalOpType != ACPI_TYPE_ANY) &&
1034         !LdMatchExternType (ActualExternalOpType, ActualOpType))
1035     {
1036         if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL &&
1037             Node->Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)
1038         {
1039             AslDualParseOpError (ASL_WARNING,
1040                 ASL_MSG_DUPLICATE_EXTERN_MISMATCH, Op, NULL,
1041                 ASL_MSG_DUPLICATE_EXTERN_FOUND_HERE, Node->Op, NULL);
1042         }
1043         else
1044         {
1045             if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL &&
1046                 Node->Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)
1047             {
1048                 ExternalOp = Op;
1049                 ActualOp = Node->Op;
1050             }
1051             else
1052             {
1053                 ExternalOp = Node->Op;
1054                 ActualOp = Op;
1055             }
1056             AslDualParseOpError (ASL_WARNING,
1057                 ASL_MSG_DECLARATION_TYPE_MISMATCH, ExternalOp, NULL,
1058                 ASL_MSG_TYPE_MISMATCH_FOUND_HERE, ActualOp, NULL);
1059         }
1060     }
1061 
1062     /* Set the object type of the external */
1063 
1064     if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
1065         (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
1066     {
1067         /*
1068          * Allow one create on an object or segment that was
1069          * previously declared External
1070          */
1071         Node->Flags &= ~ANOBJ_IS_EXTERNAL;
1072         Node->Type = (UINT8) ActualOpType;
1073 
1074         /* Just retyped a node, probably will need to open a scope */
1075 
1076         if (AcpiNsOpensScope (ActualOpType))
1077         {
1078             Status = AcpiDsScopeStackPush (Node, ActualOpType, WalkState);
1079             if (ACPI_FAILURE (Status))
1080             {
1081                 return (Status);
1082             }
1083         }
1084 
1085         Status = AE_OK;
1086     }
1087     else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) &&
1088              (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
1089     {
1090         /*
1091          * Allow externals in same scope as the definition of the
1092          * actual object. Similar to C. Allows multiple definition
1093          * blocks that refer to each other in the same file.
1094          */
1095         Status = AE_OK;
1096     }
1097     else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
1098              (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) &&
1099              (ActualOpType == ACPI_TYPE_ANY))
1100     {
1101         /* Allow update of externals of unknown type. */
1102 
1103         Node->Type = (UINT8) ActualExternalOpType;
1104         Status = AE_OK;
1105     }
1106 
1107     return (Status);
1108 }
1109 
1110 
1111 /*******************************************************************************
1112  *
1113  * FUNCTION:    LdCheckSpecialNames
1114  *
1115  * PARAMETERS:  Node        - Node that represents the named object
1116  *              Op          - Named object declaring this named object
1117  *
1118  * RETURN:      None
1119  *
1120  * DESCRIPTION: Check if certain named objects are declared in the incorrect
1121  *              scope. Special named objects are listed in
1122  *              AslGbl_SpecialNamedObjects and can only be declared at the root
1123  *              scope. _UID inside of a processor declaration must not be a
1124  *              string.
1125  *
1126  ******************************************************************************/
1127 
1128 static void
LdCheckSpecialNames(ACPI_NAMESPACE_NODE * Node,ACPI_PARSE_OBJECT * Op)1129 LdCheckSpecialNames (
1130     ACPI_NAMESPACE_NODE     *Node,
1131     ACPI_PARSE_OBJECT       *Op)
1132 {
1133     UINT32                  i;
1134 
1135 
1136     for (i = 0; i < MAX_SPECIAL_NAMES; i++)
1137     {
1138         if (ACPI_COMPARE_NAMESEG(Node->Name.Ascii, AslGbl_SpecialNamedObjects[i]) &&
1139             Node->Parent != AcpiGbl_RootNode)
1140         {
1141             AslError (ASL_ERROR, ASL_MSG_INVALID_SPECIAL_NAME, Op, Op->Asl.ExternalName);
1142             return;
1143         }
1144     }
1145 
1146     if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, "_UID") &&
1147         Node->Parent->Type == ACPI_TYPE_PROCESSOR &&
1148         Node->Type == ACPI_TYPE_STRING)
1149     {
1150         AslError (ASL_ERROR, ASL_MSG_INVALID_PROCESSOR_UID , Op, "found a string");
1151     }
1152 }
1153 
1154 
1155 /*******************************************************************************
1156  *
1157  * FUNCTION:    LdNamespace2Begin
1158  *
1159  * PARAMETERS:  ASL_WALK_CALLBACK
1160  *
1161  * RETURN:      Status
1162  *
1163  * DESCRIPTION: Descending callback used during the pass 2 parse tree walk.
1164  *              Second pass resolves some forward references.
1165  *
1166  * Notes:
1167  * Currently only needs to handle the Alias operator.
1168  * Could be used to allow forward references from the Scope() operator, but
1169  * the MS interpreter does not allow this, so this compiler does not either.
1170  *
1171  ******************************************************************************/
1172 
1173 static ACPI_STATUS
LdNamespace2Begin(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)1174 LdNamespace2Begin (
1175     ACPI_PARSE_OBJECT       *Op,
1176     UINT32                  Level,
1177     void                    *Context)
1178 {
1179     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
1180     ACPI_STATUS             Status;
1181     ACPI_NAMESPACE_NODE     *Node;
1182     ACPI_OBJECT_TYPE        ObjectType;
1183     BOOLEAN                 ForceNewScope = FALSE;
1184     ACPI_PARSE_OBJECT       *Arg;
1185     char                    *Path;
1186     ACPI_NAMESPACE_NODE     *TargetNode;
1187 
1188 
1189     ACPI_FUNCTION_NAME (LdNamespace2Begin);
1190     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
1191         Op, Op->Asl.ParseOpName));
1192 
1193 
1194     /* Ignore Ops with no namespace node */
1195 
1196     Node = Op->Asl.Node;
1197     if (!Node)
1198     {
1199         return (AE_OK);
1200     }
1201 
1202     /* Get the type to determine if we should push the scope */
1203 
1204     if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
1205         (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC))
1206     {
1207         ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
1208     }
1209     else
1210     {
1211         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
1212     }
1213 
1214     /* Push scope for Resource Templates */
1215 
1216     if (Op->Asl.ParseOpcode == PARSEOP_NAME)
1217     {
1218         if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
1219         {
1220             ForceNewScope = TRUE;
1221         }
1222     }
1223 
1224     /* Push the scope stack */
1225 
1226     if (ForceNewScope || AcpiNsOpensScope (ObjectType))
1227     {
1228         Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
1229         if (ACPI_FAILURE (Status))
1230         {
1231             return_ACPI_STATUS (Status);
1232         }
1233     }
1234 
1235     if (Op->Asl.ParseOpcode == PARSEOP_ALIAS)
1236     {
1237         /*
1238          * Complete the alias node by getting and saving the target node.
1239          * First child is the alias target
1240          */
1241         Arg = Op->Asl.Child;
1242 
1243         /* Get the target pathname */
1244 
1245         Path = Arg->Asl.Namepath;
1246         if (!Path)
1247         {
1248             Status = UtInternalizeName (Arg->Asl.ExternalName, &Path);
1249             if (ACPI_FAILURE (Status))
1250             {
1251                 return (Status);
1252             }
1253         }
1254 
1255         /* Get the NS node associated with the target. It must exist. */
1256 
1257         Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
1258             ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
1259             WalkState, &TargetNode);
1260         if (ACPI_FAILURE (Status))
1261         {
1262             if (Status == AE_NOT_FOUND)
1263             {
1264                 /* Standalone NameSeg vs. NamePath */
1265 
1266                 if (strlen (Arg->Asl.ExternalName) == ACPI_NAMESEG_SIZE)
1267                 {
1268                     AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
1269                         Arg->Asl.ExternalName);
1270                 }
1271                 else
1272                 {
1273                     AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
1274                         Arg->Asl.ExternalName);
1275                 }
1276 
1277 #if 0
1278 /*
1279  * NOTE: Removed 10/2018 to enhance compiler error reporting. No
1280  * regressions seen.
1281  */
1282                 /*
1283                  * The name was not found, go ahead and create it.
1284                  * This prevents more errors later.
1285                  */
1286                 Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
1287                     ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
1288                     ACPI_NS_NO_UPSEARCH, WalkState, &Node);
1289 #endif
1290                 return (Status);
1291 /* Removed: return (AE_OK)*/
1292             }
1293 
1294             AslCoreSubsystemError (Op, Status,
1295                 "Failure from namespace lookup", FALSE);
1296             return (AE_OK);
1297         }
1298 
1299         /* Save the target node within the alias node as well as type information */
1300 
1301         Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
1302         Node->Type = TargetNode->Type;
1303         if (Node->Type == ACPI_TYPE_METHOD)
1304         {
1305             /* Save the parameter count for methods */
1306 
1307             Node->Value = TargetNode->Value;
1308         }
1309     }
1310 
1311     return (AE_OK);
1312 }
1313 
1314 
1315 /*******************************************************************************
1316  *
1317  * FUNCTION:    LdCommonNamespaceEnd
1318  *
1319  * PARAMETERS:  ASL_WALK_CALLBACK
1320  *
1321  * RETURN:      Status
1322  *
1323  * DESCRIPTION: Ascending callback used during the loading of the namespace,
1324  *              We only need to worry about managing the scope stack here.
1325  *
1326  ******************************************************************************/
1327 
1328 static ACPI_STATUS
LdCommonNamespaceEnd(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)1329 LdCommonNamespaceEnd (
1330     ACPI_PARSE_OBJECT       *Op,
1331     UINT32                  Level,
1332     void                    *Context)
1333 {
1334     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
1335     ACPI_OBJECT_TYPE        ObjectType;
1336     BOOLEAN                 ForceNewScope = FALSE;
1337 
1338 
1339     ACPI_FUNCTION_NAME (LdCommonNamespaceEnd);
1340 
1341 
1342     /* We are only interested in opcodes that have an associated name */
1343 
1344     if (!Op->Asl.Namepath)
1345     {
1346         return (AE_OK);
1347     }
1348 
1349     /* Get the type to determine if we should pop the scope */
1350 
1351     if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
1352         (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC))
1353     {
1354         /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */
1355 
1356         ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
1357     }
1358     else
1359     {
1360         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
1361     }
1362 
1363     /* Pop scope that was pushed for Resource Templates */
1364 
1365     if (Op->Asl.ParseOpcode == PARSEOP_NAME)
1366     {
1367         if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
1368         {
1369             ForceNewScope = TRUE;
1370         }
1371     }
1372 
1373     /* Pop the scope stack */
1374 
1375     if (ForceNewScope || AcpiNsOpensScope (ObjectType))
1376     {
1377         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1378             "(%s): Popping scope for Op [%s] %p\n",
1379             AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op));
1380 
1381         (void) AcpiDsScopeStackPop (WalkState);
1382     }
1383 
1384     return (AE_OK);
1385 }
1386