]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/contrib/dev/acpica/compiler/aslload.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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 - 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                 if (ACPI_FAILURE (Status))
491                 {
492                     return_ACPI_STATUS (Status);
493                 }
494
495                 /*
496                  * However, this is an error -- primarily because the MS
497                  * interpreter can't handle a forward reference from the
498                  * Scope() operator.
499                  */
500                 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
501                     Op->Asl.ExternalName);
502                 AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op,
503                     Op->Asl.ExternalName);
504                 goto FinishNode;
505             }
506
507             AslCoreSubsystemError (Op, Status,
508                 "Failure from namespace lookup", FALSE);
509
510             return_ACPI_STATUS (Status);
511         }
512
513         /* We found a node with this name, now check the type */
514
515         switch (Node->Type)
516         {
517         case ACPI_TYPE_LOCAL_SCOPE:
518         case ACPI_TYPE_DEVICE:
519         case ACPI_TYPE_POWER:
520         case ACPI_TYPE_PROCESSOR:
521         case ACPI_TYPE_THERMAL:
522
523             /* These are acceptable types - they all open a new scope */
524             break;
525
526         case ACPI_TYPE_INTEGER:
527         case ACPI_TYPE_STRING:
528         case ACPI_TYPE_BUFFER:
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 }