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