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