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