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