aslload.c revision 217365
1281SN/A/******************************************************************************
2281SN/A *
3281SN/A * Module Name: dswload - Dispatcher namespace load callbacks
4281SN/A *
5281SN/A *****************************************************************************/
6281SN/A
7281SN/A/*
8281SN/A * Copyright (C) 2000 - 2011, Intel Corp.
9281SN/A * All rights reserved.
10281SN/A *
11281SN/A * Redistribution and use in source and binary forms, with or without
12281SN/A * modification, are permitted provided that the following conditions
13281SN/A * are met:
14281SN/A * 1. Redistributions of source code must retain the above copyright
15281SN/A *    notice, this list of conditions, and the following disclaimer,
16281SN/A *    without modification.
17281SN/A * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18281SN/A *    substantially similar to the "NO WARRANTY" disclaimer below
19281SN/A *    ("Disclaimer") and any redistribution must be conditioned upon
20281SN/A *    including a substantially similar Disclaimer requirement for further
21281SN/A *    binary redistribution.
22281SN/A * 3. Neither the names of the above-listed copyright holders nor the names
23281SN/A *    of any contributors may be used to endorse or promote products derived
24281SN/A *    from this software without specific prior written permission.
25281SN/A *
26281SN/A * Alternatively, this software may be distributed under the terms of the
27281SN/A * GNU General Public License ("GPL") version 2 as published by the Free
28281SN/A * Software Foundation.
29281SN/A *
30281SN/A * NO WARRANTY
31281SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32281SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33281SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34281SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35281SN/A * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36281SN/A * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37281SN/A * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38281SN/A * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39281SN/A * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40281SN/A * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41281SN/A * POSSIBILITY OF SUCH DAMAGES.
42281SN/A */
43281SN/A
44281SN/A#define __ASLLOAD_C__
45281SN/A
46281SN/A#include <contrib/dev/acpica/compiler/aslcompiler.h>
47281SN/A#include <contrib/dev/acpica/include/amlcode.h>
48281SN/A#include <contrib/dev/acpica/include/acdispat.h>
49281SN/A#include <contrib/dev/acpica/include/acnamesp.h>
50281SN/A
51281SN/A#include "aslcompiler.y.h"
52605SN/A
53281SN/A#define _COMPONENT          ACPI_COMPILER
54281SN/A        ACPI_MODULE_NAME    ("aslload")
55281SN/A
56281SN/A/* Local prototypes */
57281SN/A
58281SN/Astatic ACPI_STATUS
59281SN/ALdLoadFieldElements (
60281SN/A    ACPI_PARSE_OBJECT       *Op,
61281SN/A    ACPI_WALK_STATE         *WalkState);
62281SN/A
63281SN/Astatic ACPI_STATUS
64281SN/ALdLoadResourceElements (
65281SN/A    ACPI_PARSE_OBJECT       *Op,
66281SN/A    ACPI_WALK_STATE         *WalkState);
67281SN/A
68281SN/Astatic ACPI_STATUS
69281SN/ALdNamespace1Begin (
70281SN/A    ACPI_PARSE_OBJECT       *Op,
71281SN/A    UINT32                  Level,
72281SN/A    void                    *Context);
73281SN/A
74281SN/Astatic ACPI_STATUS
75281SN/ALdNamespace2Begin (
76281SN/A    ACPI_PARSE_OBJECT       *Op,
77281SN/A    UINT32                  Level,
78281SN/A    void                    *Context);
79281SN/A
80281SN/Astatic ACPI_STATUS
81281SN/ALdCommonNamespaceEnd (
82281SN/A    ACPI_PARSE_OBJECT       *Op,
83281SN/A    UINT32                  Level,
84281SN/A    void                    *Context);
85281SN/A
86281SN/A
87281SN/A/*******************************************************************************
88281SN/A *
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
102ACPI_STATUS
103LdLoadNamespace (
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
150static ACPI_STATUS
151LdLoadFieldElements (
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
251static ACPI_STATUS
252LdLoadResourceElements (
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
342static ACPI_STATUS
343LdNamespace1Begin (
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
664FinishNode:
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
711static ACPI_STATUS
712LdNamespace2Begin (
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
843static ACPI_STATUS
844LdCommonNamespaceEnd (
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
903