xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/aslload.c (revision 76c7fc5f6b13ed0b1508e6b313e88e59977ed78e)
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_WARNING, 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 
422         if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)
423         {
424             break;
425         }
426         Arg = Op->Asl.Child;
427 
428         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName,
429             ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
430             WalkState, &Node);
431         if (ACPI_FAILURE (Status))
432         {
433             break;
434         }
435 
436         if (Node->Type == ACPI_TYPE_BUFFER)
437         {
438             Arg->Asl.Node = Node;
439 
440             Arg = Node->Op->Asl.Child;  /* Get namepath */
441             Arg = Arg->Asl.Next;        /* Get actual buffer */
442             Arg = Arg->Asl.Child;       /* Buffer length */
443             Arg = Arg->Asl.Next;        /* RAW_DATA buffer */
444         }
445         break;
446 
447     default:
448 
449         /* All other opcodes go below */
450 
451         break;
452     }
453 
454     /* Check if this object has already been installed in the namespace */
455 
456     if (Op->Asl.Node)
457     {
458         return (AE_OK);
459     }
460 
461     /* Check for a possible illegal forward reference */
462 
463     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
464         (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
465     {
466         /*
467          * Op->Asl.Namepath will be NULL for these opcodes.
468          * These opcodes are guaranteed to have a parent.
469          * Examine the parent opcode.
470          */
471         Status = AE_OK;
472         ParentOp = Op->Asl.Parent;
473         OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Asl.AmlOpcode);
474 
475         /*
476          * Exclude all operators that actually declare a new name:
477          *      Name (ABCD, 1) -> Ignore (AML_CLASS_NAMED_OBJECT)
478          * We only want references to named objects:
479          *      Store (2, WXYZ) -> Attempt to resolve the name
480          */
481         if (OpInfo->Class == AML_CLASS_NAMED_OBJECT)
482         {
483             return (AE_OK);
484         }
485 
486         /*
487          * Check if the referenced object exists at this point during
488          * the load:
489          * 1) If it exists, then this cannot be a forward reference.
490          * 2) If it does not exist, it could be a forward reference or
491          * it truly does not exist (and no external declaration).
492          */
493         Status = AcpiNsLookup (WalkState->ScopeInfo,
494             Op->Asl.Value.Name, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
495             ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
496             WalkState, &Node);
497         if (Status == AE_NOT_FOUND)
498         {
499             /*
500              * This is either a forward reference or the object truly
501              * does not exist. The two cases can only be differentiated
502              * during the cross-reference stage later. Mark the Op/Name
503              * as not-found for now to indicate the need for further
504              * processing.
505              *
506              * Special case: Allow forward references from elements of
507              * Package objects. This provides compatibility with other
508              * ACPI implementations. To correctly implement this, the
509              * ACPICA table load defers package resolution until the entire
510              * namespace has been loaded.
511              */
512             if ((ParentOp->Asl.ParseOpcode != PARSEOP_PACKAGE) &&
513                 (ParentOp->Asl.ParseOpcode != PARSEOP_VAR_PACKAGE))
514             {
515                 Op->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD;
516             }
517 
518             return (AE_OK);
519         }
520 
521         return (Status);
522     }
523 
524     Path = Op->Asl.Namepath;
525     if (!Path)
526     {
527         return (AE_OK);
528     }
529 
530     /* Map the raw opcode into an internal object type */
531 
532     switch (Op->Asl.ParseOpcode)
533     {
534     case PARSEOP_NAME:
535 
536         Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
537         Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
538 
539         /*
540          * If this name refers to a ResourceTemplate, we will need to open
541          * a new scope so that the resource subfield names can be entered into
542          * the namespace underneath this name
543          */
544         if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
545         {
546             ForceNewScope = TRUE;
547         }
548 
549         /* Get the data type associated with the named object, not the name itself */
550 
551         /* Log2 loop to convert from Btype (binary) to Etype (encoded) */
552 
553         ObjectType = 1;
554         for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2)
555         {
556             ObjectType++;
557         }
558         break;
559 
560     case PARSEOP_EXTERNAL:
561         /*
562          * "External" simply enters a name and type into the namespace.
563          * We must be careful to not open a new scope, however, no matter
564          * what type the external name refers to (e.g., a method)
565          *
566          * first child is name, next child is ObjectType
567          */
568         ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer;
569         ObjectType = ACPI_TYPE_ANY;
570 
571         /*
572          * We will mark every new node along the path as "External". This
573          * allows some or all of the nodes to be created later in the ASL
574          * code. Handles cases like this:
575          *
576          *   External (\_SB_.PCI0.ABCD, IntObj)
577          *   Scope (_SB_)
578          *   {
579          *       Device (PCI0)
580          *       {
581          *       }
582          *   }
583          *   Method (X)
584          *   {
585          *       Store (\_SB_.PCI0.ABCD, Local0)
586          *   }
587          */
588         Flags |= ACPI_NS_EXTERNAL;
589         break;
590 
591     case PARSEOP_DEFAULT_ARG:
592 
593         if (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC)
594         {
595             Status = LdLoadResourceElements (Op, WalkState);
596             return_ACPI_STATUS (Status);
597         }
598 
599         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
600         break;
601 
602     case PARSEOP_SCOPE:
603         /*
604          * The name referenced by Scope(Name) must already exist at this point.
605          * In other words, forward references for Scope() are not supported.
606          * The only real reason for this is that the MS interpreter cannot
607          * handle this case. Perhaps someday this case can go away.
608          */
609         Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
610             ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &Node);
611         if (ACPI_FAILURE (Status))
612         {
613             if (Status == AE_NOT_FOUND)
614             {
615                 /* The name was not found, go ahead and create it */
616 
617                 Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
618                     ACPI_TYPE_LOCAL_SCOPE, ACPI_IMODE_LOAD_PASS1,
619                     Flags, WalkState, &Node);
620                 if (ACPI_FAILURE (Status))
621                 {
622                     return_ACPI_STATUS (Status);
623                 }
624 
625                 /* However, this is an error -- operand to Scope must exist */
626 
627                 if (strlen (Op->Asl.ExternalName) == ACPI_NAMESEG_SIZE)
628                 {
629                     AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
630                         Op->Asl.ExternalName);
631                 }
632                 else
633                 {
634                     AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
635                         Op->Asl.ExternalName);
636                 }
637 
638                 goto FinishNode;
639             }
640 
641             AslCoreSubsystemError (Op, Status,
642                 "Failure from namespace lookup", FALSE);
643 
644             return_ACPI_STATUS (Status);
645         }
646         else /* Status AE_OK */
647         {
648             /*
649              * Do not allow references to external scopes from the DSDT.
650              * This is because the DSDT is always loaded first, and the
651              * external reference cannot be resolved -- causing a runtime
652              * error because Scope() must be resolved immediately.
653              * 10/2015.
654              */
655             if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
656                 (ACPI_COMPARE_NAMESEG (AslGbl_TableSignature, "DSDT")))
657             {
658                 /* However, allowed if the reference is within a method */
659 
660                 MethodOp = Op->Asl.Parent;
661                 while (MethodOp &&
662                       (MethodOp->Asl.ParseOpcode != PARSEOP_METHOD))
663                 {
664                     MethodOp = MethodOp->Asl.Parent;
665                 }
666 
667                 if (!MethodOp)
668                 {
669                     /* Not in a control method, error */
670 
671                     AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL);
672                 }
673             }
674         }
675 
676         /* We found a node with this name, now check the type */
677 
678         switch (Node->Type)
679         {
680         case ACPI_TYPE_LOCAL_SCOPE:
681         case ACPI_TYPE_DEVICE:
682         case ACPI_TYPE_POWER:
683         case ACPI_TYPE_PROCESSOR:
684         case ACPI_TYPE_THERMAL:
685 
686             /* These are acceptable types - they all open a new scope */
687             break;
688 
689         case ACPI_TYPE_INTEGER:
690         case ACPI_TYPE_STRING:
691         case ACPI_TYPE_BUFFER:
692             /*
693              * These types we will allow, but we will change the type.
694              * This enables some existing code of the form:
695              *
696              *  Name (DEB, 0)
697              *  Scope (DEB) { ... }
698              *
699              * Which is used to workaround the fact that the MS interpreter
700              * does not allow Scope() forward references.
701              */
702             snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s [%s], changing type to [Scope]",
703                 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
704             AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);
705 
706             /* Switch the type to scope, open the new scope */
707 
708             Node->Type = ACPI_TYPE_LOCAL_SCOPE;
709             Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
710                 WalkState);
711             if (ACPI_FAILURE (Status))
712             {
713                 return_ACPI_STATUS (Status);
714             }
715             break;
716 
717         default:
718 
719             /* All other types are an error */
720 
721             snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s [%s]", Op->Asl.ExternalName,
722                 AcpiUtGetTypeName (Node->Type));
723             AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);
724 
725             /*
726              * However, switch the type to be an actual scope so
727              * that compilation can continue without generating a whole
728              * cascade of additional errors. Open the new scope.
729              */
730             Node->Type = ACPI_TYPE_LOCAL_SCOPE;
731             Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
732                 WalkState);
733             if (ACPI_FAILURE (Status))
734             {
735                 return_ACPI_STATUS (Status);
736             }
737             break;
738         }
739 
740         Status = AE_OK;
741         goto FinishNode;
742 
743     default:
744 
745         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
746         break;
747     }
748 
749     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n",
750         Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType)));
751 
752     /* The name must not already exist */
753 
754     Flags |= ACPI_NS_ERROR_IF_FOUND;
755 
756     /*
757      * For opcodes that enter new names into the namespace,
758      * all prefix NameSegs must exist.
759      */
760     WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
761     if (((WalkState->OpInfo->Flags & AML_NAMED) ||
762         (WalkState->OpInfo->Flags & AML_CREATE)) &&
763         (Op->Asl.AmlOpcode != AML_EXTERNAL_OP))
764     {
765         Flags |= ACPI_NS_PREFIX_MUST_EXIST;
766     }
767 
768     /*
769      * Enter the named type into the internal namespace. We enter the name
770      * as we go downward in the parse tree. Any necessary subobjects that
771      * involve arguments to the opcode must be created as we go back up the
772      * parse tree later.
773      */
774     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
775         ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
776     if (ACPI_FAILURE (Status))
777     {
778         if (Status == AE_ALREADY_EXISTS)
779         {
780             /* The name already exists in this scope */
781 
782             if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
783             {
784                 /* Allow multiple references to the same scope */
785 
786                 Node->Type = (UINT8) ObjectType;
787                 Status = AE_OK;
788             }
789             else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
790                      (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
791             {
792                 /*
793                  * Allow one create on an object or segment that was
794                  * previously declared External
795                  */
796                 Node->Flags &= ~ANOBJ_IS_EXTERNAL;
797                 Node->Type = (UINT8) ObjectType;
798 
799                 /* Just retyped a node, probably will need to open a scope */
800 
801                 if (AcpiNsOpensScope (ObjectType))
802                 {
803                     Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
804                     if (ACPI_FAILURE (Status))
805                     {
806                         return_ACPI_STATUS (Status);
807                     }
808                 }
809 
810                 Status = AE_OK;
811             }
812             else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) &&
813                      (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))
814             {
815                 /*
816                  * Allow externals in same scope as the definition of the
817                  * actual object. Similar to C. Allows multiple definition
818                  * blocks that refer to each other in the same file.
819                  */
820                 Status = AE_OK;
821             }
822             else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
823                      (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) &&
824                      (ObjectType == ACPI_TYPE_ANY))
825             {
826                 /* Allow update of externals of unknown type. */
827 
828                 if (AcpiNsOpensScope (ActualObjectType))
829                 {
830                     Node->Type = (UINT8) ActualObjectType;
831                     Status = AE_OK;
832                 }
833                 else
834                 {
835                     sprintf (AslGbl_MsgBuffer, "%s [%s]", Op->Asl.ExternalName,
836                         AcpiUtGetTypeName (Node->Type));
837                     AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);
838                     return_ACPI_STATUS (AE_OK);
839                 }
840             }
841             else
842             {
843                 /* Valid error, object already exists */
844 
845                 AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
846                     Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op,
847                     Node->Op->Asl.ExternalName);
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 FinishNode:
885     /*
886      * Point the parse node to the new namespace node, and point
887      * the Node back to the original Parse node
888      */
889     Op->Asl.Node = Node;
890     Node->Op = Op;
891 
892     /* Set the actual data type if appropriate (EXTERNAL term only) */
893 
894     if (ActualObjectType != ACPI_TYPE_ANY)
895     {
896         Node->Type = (UINT8) ActualObjectType;
897         Node->Value = ASL_EXTERNAL_METHOD;
898     }
899 
900     if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
901     {
902         /*
903          * Get the method argument count from "Extra" and save
904          * it in the namespace node
905          */
906         Node->Value = (UINT32) Op->Asl.Extra;
907     }
908 
909     return_ACPI_STATUS (Status);
910 }
911 
912 
913 /*******************************************************************************
914  *
915  * FUNCTION:    LdCheckSpecialNames
916  *
917  * PARAMETERS:  Node        - Node that represents the named object
918  *              Op          - Named object declaring this named object
919  *
920  * RETURN:      None
921  *
922  * DESCRIPTION: Check if certain named objects are declared in the incorrect
923  *              scope. Special named objects are listed in
924  *              AslGbl_SpecialNamedObjects and can only be declared at the root
925  *              scope. _UID inside of a processor declaration must not be a
926  *              string.
927  *
928  ******************************************************************************/
929 
930 static void
931 LdCheckSpecialNames (
932     ACPI_NAMESPACE_NODE     *Node,
933     ACPI_PARSE_OBJECT       *Op)
934 {
935     UINT32                  i;
936 
937 
938     for (i = 0; i < MAX_SPECIAL_NAMES; i++)
939     {
940         if (ACPI_COMPARE_NAMESEG(Node->Name.Ascii, AslGbl_SpecialNamedObjects[i]) &&
941             Node->Parent != AcpiGbl_RootNode)
942         {
943             AslError (ASL_ERROR, ASL_MSG_INVALID_SPECIAL_NAME, Op, Op->Asl.ExternalName);
944             return;
945         }
946     }
947 
948     if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, "_UID") &&
949         Node->Parent->Type == ACPI_TYPE_PROCESSOR &&
950         Node->Type == ACPI_TYPE_STRING)
951     {
952         AslError (ASL_ERROR, ASL_MSG_INVALID_PROCESSOR_UID , Op, "found a string");
953     }
954 }
955 
956 
957 /*******************************************************************************
958  *
959  * FUNCTION:    LdNamespace2Begin
960  *
961  * PARAMETERS:  ASL_WALK_CALLBACK
962  *
963  * RETURN:      Status
964  *
965  * DESCRIPTION: Descending callback used during the pass 2 parse tree walk.
966  *              Second pass resolves some forward references.
967  *
968  * Notes:
969  * Currently only needs to handle the Alias operator.
970  * Could be used to allow forward references from the Scope() operator, but
971  * the MS interpreter does not allow this, so this compiler does not either.
972  *
973  ******************************************************************************/
974 
975 static ACPI_STATUS
976 LdNamespace2Begin (
977     ACPI_PARSE_OBJECT       *Op,
978     UINT32                  Level,
979     void                    *Context)
980 {
981     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
982     ACPI_STATUS             Status;
983     ACPI_NAMESPACE_NODE     *Node;
984     ACPI_OBJECT_TYPE        ObjectType;
985     BOOLEAN                 ForceNewScope = FALSE;
986     ACPI_PARSE_OBJECT       *Arg;
987     char                    *Path;
988     ACPI_NAMESPACE_NODE     *TargetNode;
989 
990 
991     ACPI_FUNCTION_NAME (LdNamespace2Begin);
992     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
993         Op, Op->Asl.ParseOpName));
994 
995 
996     /* Ignore Ops with no namespace node */
997 
998     Node = Op->Asl.Node;
999     if (!Node)
1000     {
1001         return (AE_OK);
1002     }
1003 
1004     /* Get the type to determine if we should push the scope */
1005 
1006     if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
1007         (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC))
1008     {
1009         ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
1010     }
1011     else
1012     {
1013         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
1014     }
1015 
1016     /* Push scope for Resource Templates */
1017 
1018     if (Op->Asl.ParseOpcode == PARSEOP_NAME)
1019     {
1020         if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
1021         {
1022             ForceNewScope = TRUE;
1023         }
1024     }
1025 
1026     /* Push the scope stack */
1027 
1028     if (ForceNewScope || AcpiNsOpensScope (ObjectType))
1029     {
1030         Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
1031         if (ACPI_FAILURE (Status))
1032         {
1033             return_ACPI_STATUS (Status);
1034         }
1035     }
1036 
1037     if (Op->Asl.ParseOpcode == PARSEOP_ALIAS)
1038     {
1039         /*
1040          * Complete the alias node by getting and saving the target node.
1041          * First child is the alias target
1042          */
1043         Arg = Op->Asl.Child;
1044 
1045         /* Get the target pathname */
1046 
1047         Path = Arg->Asl.Namepath;
1048         if (!Path)
1049         {
1050             Status = UtInternalizeName (Arg->Asl.ExternalName, &Path);
1051             if (ACPI_FAILURE (Status))
1052             {
1053                 return (Status);
1054             }
1055         }
1056 
1057         /* Get the NS node associated with the target. It must exist. */
1058 
1059         Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
1060             ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
1061             WalkState, &TargetNode);
1062         if (ACPI_FAILURE (Status))
1063         {
1064             if (Status == AE_NOT_FOUND)
1065             {
1066                 /* Standalone NameSeg vs. NamePath */
1067 
1068                 if (strlen (Arg->Asl.ExternalName) == ACPI_NAMESEG_SIZE)
1069                 {
1070                     AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
1071                         Arg->Asl.ExternalName);
1072                 }
1073                 else
1074                 {
1075                     AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,
1076                         Arg->Asl.ExternalName);
1077                 }
1078 
1079 #if 0
1080 /*
1081  * NOTE: Removed 10/2018 to enhance compiler error reporting. No
1082  * regressions seen.
1083  */
1084                 /*
1085                  * The name was not found, go ahead and create it.
1086                  * This prevents more errors later.
1087                  */
1088                 Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
1089                     ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
1090                     ACPI_NS_NO_UPSEARCH, WalkState, &Node);
1091 #endif
1092                 return (Status);
1093 /* Removed: return (AE_OK)*/
1094             }
1095 
1096             AslCoreSubsystemError (Op, Status,
1097                 "Failure from namespace lookup", FALSE);
1098             return (AE_OK);
1099         }
1100 
1101         /* Save the target node within the alias node */
1102 
1103         Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
1104     }
1105 
1106     return (AE_OK);
1107 }
1108 
1109 
1110 /*******************************************************************************
1111  *
1112  * FUNCTION:    LdCommonNamespaceEnd
1113  *
1114  * PARAMETERS:  ASL_WALK_CALLBACK
1115  *
1116  * RETURN:      Status
1117  *
1118  * DESCRIPTION: Ascending callback used during the loading of the namespace,
1119  *              We only need to worry about managing the scope stack here.
1120  *
1121  ******************************************************************************/
1122 
1123 static ACPI_STATUS
1124 LdCommonNamespaceEnd (
1125     ACPI_PARSE_OBJECT       *Op,
1126     UINT32                  Level,
1127     void                    *Context)
1128 {
1129     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
1130     ACPI_OBJECT_TYPE        ObjectType;
1131     BOOLEAN                 ForceNewScope = FALSE;
1132 
1133 
1134     ACPI_FUNCTION_NAME (LdCommonNamespaceEnd);
1135 
1136 
1137     /* We are only interested in opcodes that have an associated name */
1138 
1139     if (!Op->Asl.Namepath)
1140     {
1141         return (AE_OK);
1142     }
1143 
1144     /* Get the type to determine if we should pop the scope */
1145 
1146     if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
1147         (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC))
1148     {
1149         /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */
1150 
1151         ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
1152     }
1153     else
1154     {
1155         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
1156     }
1157 
1158     /* Pop scope that was pushed for Resource Templates */
1159 
1160     if (Op->Asl.ParseOpcode == PARSEOP_NAME)
1161     {
1162         if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)
1163         {
1164             ForceNewScope = TRUE;
1165         }
1166     }
1167 
1168     /* Pop the scope stack */
1169 
1170     if (ForceNewScope || AcpiNsOpensScope (ObjectType))
1171     {
1172         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1173             "(%s): Popping scope for Op [%s] %p\n",
1174             AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op));
1175 
1176         (void) AcpiDsScopeStackPop (WalkState);
1177     }
1178 
1179     return (AE_OK);
1180 }
1181