xref: /freebsd/sys/contrib/dev/acpica/compiler/aslload.c (revision 595e514d0df2bac5b813d35f83e32875dbf16a83)
1 /******************************************************************************
2  *
3  * Module Name: dswload - Dispatcher namespace load callbacks
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2013, 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 #define __ASLLOAD_C__
45 
46 #include <contrib/dev/acpica/compiler/aslcompiler.h>
47 #include <contrib/dev/acpica/include/amlcode.h>
48 #include <contrib/dev/acpica/include/acdispat.h>
49 #include <contrib/dev/acpica/include/acnamesp.h>
50 
51 #include "aslcompiler.y.h"
52 
53 #define _COMPONENT          ACPI_COMPILER
54         ACPI_MODULE_NAME    ("aslload")
55 
56 /* Local prototypes */
57 
58 static ACPI_STATUS
59 LdLoadFieldElements (
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 
87 /*******************************************************************************
88  *
89  * FUNCTION:    LdLoadNamespace
90  *
91  * PARAMETERS:  RootOp      - Root of the parse tree
92  *
93  * RETURN:      Status
94  *
95  * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the
96  *              named ASL/AML objects into the namespace. The namespace is
97  *              constructed in order to resolve named references and references
98  *              to named fields within resource templates/descriptors.
99  *
100  ******************************************************************************/
101 
102 ACPI_STATUS
103 LdLoadNamespace (
104     ACPI_PARSE_OBJECT       *RootOp)
105 {
106     ACPI_WALK_STATE         *WalkState;
107 
108 
109     DbgPrint (ASL_DEBUG_OUTPUT, "\nCreating namespace\n\n");
110 
111     /* Create a new walk state */
112 
113     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
114     if (!WalkState)
115     {
116         return (AE_NO_MEMORY);
117     }
118 
119     /* Walk the entire parse tree, first pass */
120 
121     TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin,
122         LdCommonNamespaceEnd, WalkState);
123 
124     /* Second pass to handle forward references */
125 
126     TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin,
127         LdCommonNamespaceEnd, WalkState);
128 
129     /* Dump the namespace if debug is enabled */
130 
131     AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX);
132     return (AE_OK);
133 }
134 
135 
136 /*******************************************************************************
137  *
138  * FUNCTION:    LdLoadFieldElements
139  *
140  * PARAMETERS:  Op              - Parent node (Field)
141  *              WalkState       - Current walk state
142  *
143  * RETURN:      Status
144  *
145  * DESCRIPTION: Enter the named elements of the field (children of the parent)
146  *              into the namespace.
147  *
148  ******************************************************************************/
149 
150 static ACPI_STATUS
151 LdLoadFieldElements (
152     ACPI_PARSE_OBJECT       *Op,
153     ACPI_WALK_STATE         *WalkState)
154 {
155     ACPI_PARSE_OBJECT       *Child = NULL;
156     ACPI_NAMESPACE_NODE     *Node;
157     ACPI_STATUS             Status;
158 
159 
160     /* Get the first named field element */
161 
162     switch (Op->Asl.AmlOpcode)
163     {
164     case AML_BANK_FIELD_OP:
165 
166         Child = UtGetArg (Op, 6);
167         break;
168 
169     case AML_INDEX_FIELD_OP:
170 
171         Child = UtGetArg (Op, 5);
172         break;
173 
174     case AML_FIELD_OP:
175 
176         Child = UtGetArg (Op, 4);
177         break;
178 
179     default:
180 
181         /* No other opcodes should arrive here */
182 
183         return (AE_BAD_PARAMETER);
184     }
185 
186     /* Enter all elements into the namespace */
187 
188     while (Child)
189     {
190         switch (Child->Asl.AmlOpcode)
191         {
192         case AML_INT_RESERVEDFIELD_OP:
193         case AML_INT_ACCESSFIELD_OP:
194         case AML_INT_CONNECTION_OP:
195             break;
196 
197         default:
198 
199             Status = AcpiNsLookup (WalkState->ScopeInfo,
200                         Child->Asl.Value.String,
201                         ACPI_TYPE_LOCAL_REGION_FIELD,
202                         ACPI_IMODE_LOAD_PASS1,
203                         ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
204                             ACPI_NS_ERROR_IF_FOUND,
205                         NULL, &Node);
206             if (ACPI_FAILURE (Status))
207             {
208                 if (Status != AE_ALREADY_EXISTS)
209                 {
210                     AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child,
211                         Child->Asl.Value.String);
212                     return (Status);
213                 }
214 
215                 /*
216                  * The name already exists in this scope
217                  * But continue processing the elements
218                  */
219                 AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,
220                     Child->Asl.Value.String);
221             }
222             else
223             {
224                 Child->Asl.Node = Node;
225                 Node->Op = Child;
226             }
227             break;
228         }
229 
230         Child = Child->Asl.Next;
231     }
232 
233     return (AE_OK);
234 }
235 
236 
237 /*******************************************************************************
238  *
239  * FUNCTION:    LdLoadResourceElements
240  *
241  * PARAMETERS:  Op              - Parent node (Resource Descriptor)
242  *              WalkState       - Current walk state
243  *
244  * RETURN:      Status
245  *
246  * DESCRIPTION: Enter the named elements of the resource descriptor (children
247  *              of the parent) into the namespace.
248  *
249  * NOTE: In the real AML namespace, these named elements never exist. But
250  *       we simply use the namespace here as a symbol table so we can look
251  *       them up as they are referenced.
252  *
253  ******************************************************************************/
254 
255 static ACPI_STATUS
256 LdLoadResourceElements (
257     ACPI_PARSE_OBJECT       *Op,
258     ACPI_WALK_STATE         *WalkState)
259 {
260     ACPI_PARSE_OBJECT       *InitializerOp = NULL;
261     ACPI_NAMESPACE_NODE     *Node;
262     ACPI_STATUS             Status;
263 
264 
265     /*
266      * Enter the resource name into the namespace. Name must not already exist.
267      * This opens a scope, so later field names are guaranteed to be new/unique.
268      */
269     Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath,
270                 ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1,
271                 ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND,
272                 WalkState, &Node);
273     if (ACPI_FAILURE (Status))
274     {
275         if (Status == AE_ALREADY_EXISTS)
276         {
277             /* Actual node causing the error was saved in ParentMethod */
278 
279             AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS,
280                 (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath);
281             return (AE_OK);
282         }
283         return (Status);
284     }
285 
286     Node->Value = (UINT32) Op->Asl.Value.Integer;
287     Node->Op = Op;
288     Op->Asl.Node = Node;
289 
290     /*
291      * Now enter the predefined fields, for easy lookup when referenced
292      * by the source ASL
293      */
294     InitializerOp = ASL_GET_CHILD_NODE (Op);
295     while (InitializerOp)
296     {
297         if (InitializerOp->Asl.ExternalName)
298         {
299             Status = AcpiNsLookup (WalkState->ScopeInfo,
300                         InitializerOp->Asl.ExternalName,
301                         ACPI_TYPE_LOCAL_RESOURCE_FIELD,
302                         ACPI_IMODE_LOAD_PASS1,
303                         ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE,
304                         NULL, &Node);
305             if (ACPI_FAILURE (Status))
306             {
307                 return (Status);
308             }
309 
310             /*
311              * Store the field offset and length in the namespace node
312              * so it can be used when the field is referenced
313              */
314             Node->Value = InitializerOp->Asl.Value.Tag.BitOffset;
315             Node->Length = InitializerOp->Asl.Value.Tag.BitLength;
316             InitializerOp->Asl.Node = Node;
317             Node->Op = InitializerOp;
318         }
319 
320         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
321     }
322 
323     return (AE_OK);
324 }
325 
326 
327 /*******************************************************************************
328  *
329  * FUNCTION:    LdNamespace1Begin
330  *
331  * PARAMETERS:  ASL_WALK_CALLBACK
332  *
333  * RETURN:      Status
334  *
335  * DESCRIPTION: Descending callback used during the parse tree walk. If this
336  *              is a named AML opcode, enter into the namespace
337  *
338  ******************************************************************************/
339 
340 static ACPI_STATUS
341 LdNamespace1Begin (
342     ACPI_PARSE_OBJECT       *Op,
343     UINT32                  Level,
344     void                    *Context)
345 {
346     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
347     ACPI_NAMESPACE_NODE     *Node;
348     ACPI_STATUS             Status;
349     ACPI_OBJECT_TYPE        ObjectType;
350     ACPI_OBJECT_TYPE        ActualObjectType = ACPI_TYPE_ANY;
351     char                    *Path;
352     UINT32                  Flags = ACPI_NS_NO_UPSEARCH;
353     ACPI_PARSE_OBJECT       *Arg;
354     UINT32                  i;
355     BOOLEAN                 ForceNewScope = FALSE;
356 
357 
358     ACPI_FUNCTION_NAME (LdNamespace1Begin);
359     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
360         Op, Op->Asl.ParseOpName));
361 
362 
363     /*
364      * We are only interested in opcodes that have an associated name
365      * (or multiple names)
366      */
367     switch (Op->Asl.AmlOpcode)
368     {
369     case AML_BANK_FIELD_OP:
370     case AML_INDEX_FIELD_OP:
371     case AML_FIELD_OP:
372 
373         Status = LdLoadFieldElements (Op, WalkState);
374         return (Status);
375 
376     default:
377 
378         /* All other opcodes go below */
379 
380         break;
381     }
382 
383     /* Check if this object has already been installed in the namespace */
384 
385     if (Op->Asl.Node)
386     {
387         return (AE_OK);
388     }
389 
390     Path = Op->Asl.Namepath;
391     if (!Path)
392     {
393         return (AE_OK);
394     }
395 
396     /* Map the raw opcode into an internal object type */
397 
398     switch (Op->Asl.ParseOpcode)
399     {
400     case PARSEOP_NAME:
401 
402         Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
403         Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
404 
405         /*
406          * If this name refers to a ResourceTemplate, we will need to open
407          * a new scope so that the resource subfield names can be entered into
408          * the namespace underneath this name
409          */
410         if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
411         {
412             ForceNewScope = TRUE;
413         }
414 
415         /* Get the data type associated with the named object, not the name itself */
416 
417         /* Log2 loop to convert from Btype (binary) to Etype (encoded) */
418 
419         ObjectType = 1;
420         for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2)
421         {
422             ObjectType++;
423         }
424         break;
425 
426 
427     case PARSEOP_EXTERNAL:
428         /*
429          * "External" simply enters a name and type into the namespace.
430          * We must be careful to not open a new scope, however, no matter
431          * what type the external name refers to (e.g., a method)
432          *
433          * first child is name, next child is ObjectType
434          */
435         ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer;
436         ObjectType = ACPI_TYPE_ANY;
437 
438         /*
439          * We will mark every new node along the path as "External". This
440          * allows some or all of the nodes to be created later in the ASL
441          * code. Handles cases like this:
442          *
443          *   External (\_SB_.PCI0.ABCD, IntObj)
444          *   Scope (_SB_)
445          *   {
446          *       Device (PCI0)
447          *       {
448          *       }
449          *   }
450          *   Method (X)
451          *   {
452          *       Store (\_SB_.PCI0.ABCD, Local0)
453          *   }
454          */
455         Flags |= ACPI_NS_EXTERNAL;
456         break;
457 
458     case PARSEOP_DEFAULT_ARG:
459 
460         if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)
461         {
462             Status = LdLoadResourceElements (Op, WalkState);
463             return_ACPI_STATUS (Status);
464         }
465 
466         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
467         break;
468 
469 
470     case PARSEOP_SCOPE:
471         /*
472          * The name referenced by Scope(Name) must already exist at this point.
473          * In other words, forward references for Scope() are not supported.
474          * The only real reason for this is that the MS interpreter cannot
475          * handle this case. Perhaps someday this case can go away.
476          */
477         Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
478                     ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
479                     WalkState, &(Node));
480         if (ACPI_FAILURE (Status))
481         {
482             if (Status == AE_NOT_FOUND)
483             {
484                 /* The name was not found, go ahead and create it */
485 
486                 Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
487                             ACPI_TYPE_LOCAL_SCOPE,
488                             ACPI_IMODE_LOAD_PASS1, Flags,
489                             WalkState, &(Node));
490 
491                 /*
492                  * However, this is an error -- primarily because the MS
493                  * interpreter can't handle a forward reference from the
494                  * Scope() operator.
495                  */
496                 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
497                     Op->Asl.ExternalName);
498                 AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op,
499                     Op->Asl.ExternalName);
500                 goto FinishNode;
501             }
502 
503             AslCoreSubsystemError (Op, Status,
504                 "Failure from namespace lookup", FALSE);
505 
506             return_ACPI_STATUS (Status);
507         }
508 
509         /* We found a node with this name, now check the type */
510 
511         switch (Node->Type)
512         {
513         case ACPI_TYPE_LOCAL_SCOPE:
514         case ACPI_TYPE_DEVICE:
515         case ACPI_TYPE_POWER:
516         case ACPI_TYPE_PROCESSOR:
517         case ACPI_TYPE_THERMAL:
518 
519             /* These are acceptable types - they all open a new scope */
520             break;
521 
522         case ACPI_TYPE_INTEGER:
523         case ACPI_TYPE_STRING:
524         case ACPI_TYPE_BUFFER:
525             /*
526              * These types we will allow, but we will change the type.
527              * This enables some existing code of the form:
528              *
529              *  Name (DEB, 0)
530              *  Scope (DEB) { ... }
531              *
532              * Which is used to workaround the fact that the MS interpreter
533              * does not allow Scope() forward references.
534              */
535             sprintf (MsgBuffer, "%s [%s], changing type to [Scope]",
536                 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
537             AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
538 
539             /* Switch the type to scope, open the new scope */
540 
541             Node->Type = ACPI_TYPE_LOCAL_SCOPE;
542             Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
543                         WalkState);
544             if (ACPI_FAILURE (Status))
545             {
546                 return_ACPI_STATUS (Status);
547             }
548             break;
549 
550         default:
551 
552             /* All other types are an error */
553 
554             sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName,
555                 AcpiUtGetTypeName (Node->Type));
556             AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
557 
558             /*
559              * However, switch the type to be an actual scope so
560              * that compilation can continue without generating a whole
561              * cascade of additional errors. Open the new scope.
562              */
563             Node->Type = ACPI_TYPE_LOCAL_SCOPE;
564             Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
565                         WalkState);
566             if (ACPI_FAILURE (Status))
567             {
568                 return_ACPI_STATUS (Status);
569             }
570             break;
571         }
572 
573         Status = AE_OK;
574         goto FinishNode;
575 
576 
577     default:
578 
579         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
580         break;
581     }
582 
583 
584     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n",
585             Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType)));
586 
587     /* The name must not already exist */
588 
589     Flags |= ACPI_NS_ERROR_IF_FOUND;
590 
591     /*
592      * Enter the named type into the internal namespace. We enter the name
593      * as we go downward in the parse tree. Any necessary subobjects that
594      * involve arguments to the opcode must be created as we go back up the
595      * parse tree later.
596      */
597     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
598                     ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
599     if (ACPI_FAILURE (Status))
600     {
601         if (Status == AE_ALREADY_EXISTS)
602         {
603             /* The name already exists in this scope */
604 
605             if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
606             {
607                 /* Allow multiple references to the same scope */
608 
609                 Node->Type = (UINT8) ObjectType;
610                 Status = AE_OK;
611             }
612             else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
613                      (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
614             {
615                 /*
616                  * Allow one create on an object or segment that was
617                  * previously declared External
618                  */
619                 Node->Flags &= ~ANOBJ_IS_EXTERNAL;
620                 Node->Type = (UINT8) ObjectType;
621 
622                 /* Just retyped a node, probably will need to open a scope */
623 
624                 if (AcpiNsOpensScope (ObjectType))
625                 {
626                     Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
627                     if (ACPI_FAILURE (Status))
628                     {
629                         return_ACPI_STATUS (Status);
630                     }
631                 }
632                 Status = AE_OK;
633             }
634             else
635             {
636                 /* Valid error, object already exists */
637 
638                 AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
639                     Op->Asl.ExternalName);
640                 return_ACPI_STATUS (AE_OK);
641             }
642         }
643         else
644         {
645             AslCoreSubsystemError (Op, Status,
646                 "Failure from namespace lookup", FALSE);
647             return_ACPI_STATUS (Status);
648         }
649     }
650 
651     if (ForceNewScope)
652     {
653         Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
654         if (ACPI_FAILURE (Status))
655         {
656             return_ACPI_STATUS (Status);
657         }
658     }
659 
660 FinishNode:
661     /*
662      * Point the parse node to the new namespace node, and point
663      * the Node back to the original Parse node
664      */
665     Op->Asl.Node = Node;
666     Node->Op = Op;
667 
668     /* Set the actual data type if appropriate (EXTERNAL term only) */
669 
670     if (ActualObjectType != ACPI_TYPE_ANY)
671     {
672         Node->Type = (UINT8) ActualObjectType;
673         Node->Value = ASL_EXTERNAL_METHOD;
674     }
675 
676     if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
677     {
678         /*
679          * Get the method argument count from "Extra" and save
680          * it in the namespace node
681          */
682         Node->Value = (UINT32) Op->Asl.Extra;
683     }
684 
685     return_ACPI_STATUS (Status);
686 }
687 
688 
689 /*******************************************************************************
690  *
691  * FUNCTION:    LdNamespace2Begin
692  *
693  * PARAMETERS:  ASL_WALK_CALLBACK
694  *
695  * RETURN:      Status
696  *
697  * DESCRIPTION: Descending callback used during the pass 2 parse tree walk.
698  *              Second pass resolves some forward references.
699  *
700  * Notes:
701  * Currently only needs to handle the Alias operator.
702  * Could be used to allow forward references from the Scope() operator, but
703  * the MS interpreter does not allow this, so this compiler does not either.
704  *
705  ******************************************************************************/
706 
707 static ACPI_STATUS
708 LdNamespace2Begin (
709     ACPI_PARSE_OBJECT       *Op,
710     UINT32                  Level,
711     void                    *Context)
712 {
713     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
714     ACPI_STATUS             Status;
715     ACPI_NAMESPACE_NODE     *Node;
716     ACPI_OBJECT_TYPE        ObjectType;
717     BOOLEAN                 ForceNewScope = FALSE;
718     ACPI_PARSE_OBJECT       *Arg;
719     char                    *Path;
720     ACPI_NAMESPACE_NODE     *TargetNode;
721 
722 
723     ACPI_FUNCTION_NAME (LdNamespace2Begin);
724     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
725         Op, Op->Asl.ParseOpName));
726 
727 
728     /* Ignore Ops with no namespace node */
729 
730     Node = Op->Asl.Node;
731     if (!Node)
732     {
733         return (AE_OK);
734     }
735 
736     /* Get the type to determine if we should push the scope */
737 
738     if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
739         (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
740     {
741         ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
742     }
743     else
744     {
745         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
746     }
747 
748     /* Push scope for Resource Templates */
749 
750     if (Op->Asl.ParseOpcode == PARSEOP_NAME)
751     {
752         if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
753         {
754             ForceNewScope = TRUE;
755         }
756     }
757 
758     /* Push the scope stack */
759 
760     if (ForceNewScope || AcpiNsOpensScope (ObjectType))
761     {
762         Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
763         if (ACPI_FAILURE (Status))
764         {
765             return_ACPI_STATUS (Status);
766         }
767     }
768 
769     if (Op->Asl.ParseOpcode == PARSEOP_ALIAS)
770     {
771         /* Complete the alias node by getting and saving the target node */
772 
773         /* First child is the alias target */
774 
775         Arg = Op->Asl.Child;
776 
777         /* Get the target pathname */
778 
779         Path = Arg->Asl.Namepath;
780         if (!Path)
781         {
782             Status = UtInternalizeName (Arg->Asl.ExternalName, &Path);
783             if (ACPI_FAILURE (Status))
784             {
785                 return (Status);
786             }
787         }
788 
789         /* Get the NS node associated with the target. It must exist. */
790 
791         Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
792                     ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
793                     WalkState, &TargetNode);
794         if (ACPI_FAILURE (Status))
795         {
796             if (Status == AE_NOT_FOUND)
797             {
798                 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
799                     Op->Asl.ExternalName);
800 
801                 /*
802                  * The name was not found, go ahead and create it.
803                  * This prevents more errors later.
804                  */
805                 Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
806                             ACPI_TYPE_ANY,
807                             ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH,
808                             WalkState, &(Node));
809                 return (AE_OK);
810             }
811 
812             AslCoreSubsystemError (Op, Status,
813                 "Failure from namespace lookup", FALSE);
814             return (AE_OK);
815         }
816 
817         /* Save the target node within the alias node */
818 
819         Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
820     }
821 
822     return (AE_OK);
823 }
824 
825 
826 /*******************************************************************************
827  *
828  * FUNCTION:    LdCommonNamespaceEnd
829  *
830  * PARAMETERS:  ASL_WALK_CALLBACK
831  *
832  * RETURN:      Status
833  *
834  * DESCRIPTION: Ascending callback used during the loading of the namespace,
835  *              We only need to worry about managing the scope stack here.
836  *
837  ******************************************************************************/
838 
839 static ACPI_STATUS
840 LdCommonNamespaceEnd (
841     ACPI_PARSE_OBJECT       *Op,
842     UINT32                  Level,
843     void                    *Context)
844 {
845     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
846     ACPI_OBJECT_TYPE        ObjectType;
847     BOOLEAN                 ForceNewScope = FALSE;
848 
849 
850     ACPI_FUNCTION_NAME (LdCommonNamespaceEnd);
851 
852 
853     /* We are only interested in opcodes that have an associated name */
854 
855     if (!Op->Asl.Namepath)
856     {
857         return (AE_OK);
858     }
859 
860     /* Get the type to determine if we should pop the scope */
861 
862     if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
863         (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
864     {
865         /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */
866 
867         ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
868     }
869     else
870     {
871         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
872     }
873 
874     /* Pop scope that was pushed for Resource Templates */
875 
876     if (Op->Asl.ParseOpcode == PARSEOP_NAME)
877     {
878         if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
879         {
880             ForceNewScope = TRUE;
881         }
882     }
883 
884     /* Pop the scope stack */
885 
886     if (ForceNewScope || AcpiNsOpensScope (ObjectType))
887     {
888         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
889             "(%s): Popping scope for Op [%s] %p\n",
890             AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op));
891 
892         (void) AcpiDsScopeStackPop (WalkState);
893     }
894 
895     return (AE_OK);
896 }
897