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