1/******************************************************************************
2 *
3 * Module Name: dswload - Dispatcher first pass namespace load callbacks
4 *
5 *****************************************************************************/
6
7/******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2012, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************/
115
116#define __DSWLOAD_C__
117
118#include "acpi.h"
119#include "accommon.h"
120#include "acparser.h"
121#include "amlcode.h"
122#include "acdispat.h"
123#include "acinterp.h"
124#include "acnamesp.h"
125
126#ifdef ACPI_ASL_COMPILER
127#include "acdisasm.h"
128#endif
129
130#define _COMPONENT          ACPI_DISPATCHER
131        ACPI_MODULE_NAME    ("dswload")
132
133
134/*******************************************************************************
135 *
136 * FUNCTION:    AcpiDsInitCallbacks
137 *
138 * PARAMETERS:  WalkState       - Current state of the parse tree walk
139 *              PassNumber      - 1, 2, or 3
140 *
141 * RETURN:      Status
142 *
143 * DESCRIPTION: Init walk state callbacks
144 *
145 ******************************************************************************/
146
147ACPI_STATUS
148AcpiDsInitCallbacks (
149    ACPI_WALK_STATE         *WalkState,
150    UINT32                  PassNumber)
151{
152
153    switch (PassNumber)
154    {
155    case 1:
156        WalkState->ParseFlags         = ACPI_PARSE_LOAD_PASS1 |
157                                        ACPI_PARSE_DELETE_TREE;
158        WalkState->DescendingCallback = AcpiDsLoad1BeginOp;
159        WalkState->AscendingCallback  = AcpiDsLoad1EndOp;
160        break;
161
162    case 2:
163        WalkState->ParseFlags         = ACPI_PARSE_LOAD_PASS1 |
164                                        ACPI_PARSE_DELETE_TREE;
165        WalkState->DescendingCallback = AcpiDsLoad2BeginOp;
166        WalkState->AscendingCallback  = AcpiDsLoad2EndOp;
167        break;
168
169    case 3:
170#ifndef ACPI_NO_METHOD_EXECUTION
171        WalkState->ParseFlags        |= ACPI_PARSE_EXECUTE  |
172                                        ACPI_PARSE_DELETE_TREE;
173        WalkState->DescendingCallback = AcpiDsExecBeginOp;
174        WalkState->AscendingCallback  = AcpiDsExecEndOp;
175#endif
176        break;
177
178    default:
179        return (AE_BAD_PARAMETER);
180    }
181
182    return (AE_OK);
183}
184
185
186/*******************************************************************************
187 *
188 * FUNCTION:    AcpiDsLoad1BeginOp
189 *
190 * PARAMETERS:  WalkState       - Current state of the parse tree walk
191 *              OutOp           - Where to return op if a new one is created
192 *
193 * RETURN:      Status
194 *
195 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
196 *
197 ******************************************************************************/
198
199ACPI_STATUS
200AcpiDsLoad1BeginOp (
201    ACPI_WALK_STATE         *WalkState,
202    ACPI_PARSE_OBJECT       **OutOp)
203{
204    ACPI_PARSE_OBJECT       *Op;
205    ACPI_NAMESPACE_NODE     *Node;
206    ACPI_STATUS             Status;
207    ACPI_OBJECT_TYPE        ObjectType;
208    char                    *Path;
209    UINT32                  Flags;
210
211
212    ACPI_FUNCTION_TRACE (DsLoad1BeginOp);
213
214
215    Op = WalkState->Op;
216    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", Op, WalkState));
217
218    /* We are only interested in opcodes that have an associated name */
219
220    if (Op)
221    {
222        if (!(WalkState->OpInfo->Flags & AML_NAMED))
223        {
224            *OutOp = Op;
225            return_ACPI_STATUS (AE_OK);
226        }
227
228        /* Check if this object has already been installed in the namespace */
229
230        if (Op->Common.Node)
231        {
232            *OutOp = Op;
233            return_ACPI_STATUS (AE_OK);
234        }
235    }
236
237    Path = AcpiPsGetNextNamestring (&WalkState->ParserState);
238
239    /* Map the raw opcode into an internal object type */
240
241    ObjectType = WalkState->OpInfo->ObjectType;
242
243    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
244        "State=%p Op=%p [%s]\n", WalkState, Op, AcpiUtGetTypeName (ObjectType)));
245
246    switch (WalkState->Opcode)
247    {
248    case AML_SCOPE_OP:
249
250        /*
251         * The target name of the Scope() operator must exist at this point so
252         * that we can actually open the scope to enter new names underneath it.
253         * Allow search-to-root for single namesegs.
254         */
255        Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
256                        ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &(Node));
257#ifdef ACPI_ASL_COMPILER
258        if (Status == AE_NOT_FOUND)
259        {
260            /*
261             * Table disassembly:
262             * Target of Scope() not found. Generate an External for it, and
263             * insert the name into the namespace.
264             */
265            AcpiDmAddToExternalList (Op, Path, ACPI_TYPE_DEVICE, 0);
266            Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
267                       ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
268                       WalkState, &Node);
269        }
270#endif
271        if (ACPI_FAILURE (Status))
272        {
273            ACPI_ERROR_NAMESPACE (Path, Status);
274            return_ACPI_STATUS (Status);
275        }
276
277        /*
278         * Check to make sure that the target is
279         * one of the opcodes that actually opens a scope
280         */
281        switch (Node->Type)
282        {
283        case ACPI_TYPE_ANY:
284        case ACPI_TYPE_LOCAL_SCOPE:         /* Scope  */
285        case ACPI_TYPE_DEVICE:
286        case ACPI_TYPE_POWER:
287        case ACPI_TYPE_PROCESSOR:
288        case ACPI_TYPE_THERMAL:
289
290            /* These are acceptable types */
291            break;
292
293        case ACPI_TYPE_INTEGER:
294        case ACPI_TYPE_STRING:
295        case ACPI_TYPE_BUFFER:
296
297            /*
298             * These types we will allow, but we will change the type.
299             * This enables some existing code of the form:
300             *
301             *  Name (DEB, 0)
302             *  Scope (DEB) { ... }
303             *
304             * Note: silently change the type here. On the second pass,
305             * we will report a warning
306             */
307            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
308                "Type override - [%4.4s] had invalid type (%s) "
309                "for Scope operator, changed to type ANY\n",
310                AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type)));
311
312            Node->Type = ACPI_TYPE_ANY;
313            WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY;
314            break;
315
316        case ACPI_TYPE_METHOD:
317
318            /*
319             * Allow scope change to root during execution of module-level
320             * code. Root is typed METHOD during this time.
321             */
322            if ((Node == AcpiGbl_RootNode) &&
323                (WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
324            {
325                break;
326            }
327
328            /*lint -fallthrough */
329
330        default:
331
332            /* All other types are an error */
333
334            ACPI_ERROR ((AE_INFO,
335                "Invalid type (%s) for target of "
336                "Scope operator [%4.4s] (Cannot override)",
337                AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node)));
338
339            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
340        }
341        break;
342
343
344    default:
345        /*
346         * For all other named opcodes, we will enter the name into
347         * the namespace.
348         *
349         * Setup the search flags.
350         * Since we are entering a name into the namespace, we do not want to
351         * enable the search-to-root upsearch.
352         *
353         * There are only two conditions where it is acceptable that the name
354         * already exists:
355         *    1) the Scope() operator can reopen a scoping object that was
356         *       previously defined (Scope, Method, Device, etc.)
357         *    2) Whenever we are parsing a deferred opcode (OpRegion, Buffer,
358         *       BufferField, or Package), the name of the object is already
359         *       in the namespace.
360         */
361        if (WalkState->DeferredNode)
362        {
363            /* This name is already in the namespace, get the node */
364
365            Node = WalkState->DeferredNode;
366            Status = AE_OK;
367            break;
368        }
369
370        /*
371         * If we are executing a method, do not create any namespace objects
372         * during the load phase, only during execution.
373         */
374        if (WalkState->MethodNode)
375        {
376            Node = NULL;
377            Status = AE_OK;
378            break;
379        }
380
381        Flags = ACPI_NS_NO_UPSEARCH;
382        if ((WalkState->Opcode != AML_SCOPE_OP) &&
383            (!(WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP)))
384        {
385            Flags |= ACPI_NS_ERROR_IF_FOUND;
386            ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n",
387                    AcpiUtGetTypeName (ObjectType)));
388        }
389        else
390        {
391            ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
392                "[%s] Both Find or Create allowed\n",
393                    AcpiUtGetTypeName (ObjectType)));
394        }
395
396        /*
397         * Enter the named type into the internal namespace. We enter the name
398         * as we go downward in the parse tree. Any necessary subobjects that
399         * involve arguments to the opcode must be created as we go back up the
400         * parse tree later.
401         */
402        Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
403                        ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
404        if (ACPI_FAILURE (Status))
405        {
406            if (Status == AE_ALREADY_EXISTS)
407            {
408                /* The name already exists in this scope */
409
410                if (Node->Flags & ANOBJ_IS_EXTERNAL)
411                {
412                    /*
413                     * Allow one create on an object or segment that was
414                     * previously declared External
415                     */
416                    Node->Flags &= ~ANOBJ_IS_EXTERNAL;
417                    Node->Type = (UINT8) ObjectType;
418
419                    /* Just retyped a node, probably will need to open a scope */
420
421                    if (AcpiNsOpensScope (ObjectType))
422                    {
423                        Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
424                        if (ACPI_FAILURE (Status))
425                        {
426                            return_ACPI_STATUS (Status);
427                        }
428                    }
429
430                    Status = AE_OK;
431                }
432            }
433
434            if (ACPI_FAILURE (Status))
435            {
436                ACPI_ERROR_NAMESPACE (Path, Status);
437                return_ACPI_STATUS (Status);
438            }
439        }
440        break;
441    }
442
443    /* Common exit */
444
445    if (!Op)
446    {
447        /* Create a new op */
448
449        Op = AcpiPsAllocOp (WalkState->Opcode);
450        if (!Op)
451        {
452            return_ACPI_STATUS (AE_NO_MEMORY);
453        }
454    }
455
456    /* Initialize the op */
457
458#if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY))
459    Op->Named.Path = ACPI_CAST_PTR (UINT8, Path);
460#endif
461
462    if (Node)
463    {
464        /*
465         * Put the Node in the "op" object that the parser uses, so we
466         * can get it again quickly when this scope is closed
467         */
468        Op->Common.Node = Node;
469        Op->Named.Name = Node->Name.Integer;
470    }
471
472    AcpiPsAppendArg (AcpiPsGetParentScope (&WalkState->ParserState), Op);
473    *OutOp = Op;
474    return_ACPI_STATUS (Status);
475}
476
477
478/*******************************************************************************
479 *
480 * FUNCTION:    AcpiDsLoad1EndOp
481 *
482 * PARAMETERS:  WalkState       - Current state of the parse tree walk
483 *
484 * RETURN:      Status
485 *
486 * DESCRIPTION: Ascending callback used during the loading of the namespace,
487 *              both control methods and everything else.
488 *
489 ******************************************************************************/
490
491ACPI_STATUS
492AcpiDsLoad1EndOp (
493    ACPI_WALK_STATE         *WalkState)
494{
495    ACPI_PARSE_OBJECT       *Op;
496    ACPI_OBJECT_TYPE        ObjectType;
497    ACPI_STATUS             Status = AE_OK;
498
499
500    ACPI_FUNCTION_TRACE (DsLoad1EndOp);
501
502
503    Op = WalkState->Op;
504    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", Op, WalkState));
505
506    /* We are only interested in opcodes that have an associated name */
507
508    if (!(WalkState->OpInfo->Flags & (AML_NAMED | AML_FIELD)))
509    {
510        return_ACPI_STATUS (AE_OK);
511    }
512
513    /* Get the object type to determine if we should pop the scope */
514
515    ObjectType = WalkState->OpInfo->ObjectType;
516
517#ifndef ACPI_NO_METHOD_EXECUTION
518    if (WalkState->OpInfo->Flags & AML_FIELD)
519    {
520        /*
521         * If we are executing a method, do not create any namespace objects
522         * during the load phase, only during execution.
523         */
524        if (!WalkState->MethodNode)
525        {
526            if (WalkState->Opcode == AML_FIELD_OP          ||
527                WalkState->Opcode == AML_BANK_FIELD_OP     ||
528                WalkState->Opcode == AML_INDEX_FIELD_OP)
529            {
530                Status = AcpiDsInitFieldObjects (Op, WalkState);
531            }
532        }
533        return_ACPI_STATUS (Status);
534    }
535
536    /*
537     * If we are executing a method, do not create any namespace objects
538     * during the load phase, only during execution.
539     */
540    if (!WalkState->MethodNode)
541    {
542        if (Op->Common.AmlOpcode == AML_REGION_OP)
543        {
544            Status = AcpiExCreateRegion (Op->Named.Data, Op->Named.Length,
545                        (ACPI_ADR_SPACE_TYPE) ((Op->Common.Value.Arg)->Common.Value.Integer),
546                        WalkState);
547            if (ACPI_FAILURE (Status))
548            {
549                return_ACPI_STATUS (Status);
550            }
551        }
552        else if (Op->Common.AmlOpcode == AML_DATA_REGION_OP)
553        {
554            Status = AcpiExCreateRegion (Op->Named.Data, Op->Named.Length,
555                        ACPI_ADR_SPACE_DATA_TABLE, WalkState);
556            if (ACPI_FAILURE (Status))
557            {
558                return_ACPI_STATUS (Status);
559            }
560        }
561    }
562#endif
563
564    if (Op->Common.AmlOpcode == AML_NAME_OP)
565    {
566        /* For Name opcode, get the object type from the argument */
567
568        if (Op->Common.Value.Arg)
569        {
570            ObjectType = (AcpiPsGetOpcodeInfo (
571                (Op->Common.Value.Arg)->Common.AmlOpcode))->ObjectType;
572
573            /* Set node type if we have a namespace node */
574
575            if (Op->Common.Node)
576            {
577                Op->Common.Node->Type = (UINT8) ObjectType;
578            }
579        }
580    }
581
582    /*
583     * If we are executing a method, do not create any namespace objects
584     * during the load phase, only during execution.
585     */
586    if (!WalkState->MethodNode)
587    {
588        if (Op->Common.AmlOpcode == AML_METHOD_OP)
589        {
590            /*
591             * MethodOp PkgLength NameString MethodFlags TermList
592             *
593             * Note: We must create the method node/object pair as soon as we
594             * see the method declaration. This allows later pass1 parsing
595             * of invocations of the method (need to know the number of
596             * arguments.)
597             */
598            ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
599                "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
600                WalkState, Op, Op->Named.Node));
601
602            if (!AcpiNsGetAttachedObject (Op->Named.Node))
603            {
604                WalkState->Operands[0] = ACPI_CAST_PTR (void, Op->Named.Node);
605                WalkState->NumOperands = 1;
606
607                Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
608                if (ACPI_SUCCESS (Status))
609                {
610                    Status = AcpiExCreateMethod (Op->Named.Data,
611                                        Op->Named.Length, WalkState);
612                }
613
614                WalkState->Operands[0] = NULL;
615                WalkState->NumOperands = 0;
616
617                if (ACPI_FAILURE (Status))
618                {
619                    return_ACPI_STATUS (Status);
620                }
621            }
622        }
623    }
624
625    /* Pop the scope stack (only if loading a table) */
626
627    if (!WalkState->MethodNode &&
628        AcpiNsOpensScope (ObjectType))
629    {
630        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s): Popping scope for Op %p\n",
631            AcpiUtGetTypeName (ObjectType), Op));
632
633        Status = AcpiDsScopeStackPop (WalkState);
634    }
635
636    return_ACPI_STATUS (Status);
637}
638