1/******************************************************************************
2 *
3 * Module Name: adwalk - Application-level disassembler parse tree walk routines
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
117#include "acpi.h"
118#include "accommon.h"
119#include "acparser.h"
120#include "amlcode.h"
121#include "acdisasm.h"
122#include "acdispat.h"
123#include "acnamesp.h"
124#include "acapps.h"
125
126
127#define _COMPONENT          ACPI_TOOLS
128        ACPI_MODULE_NAME    ("adwalk")
129
130/*
131 * aslmap - opcode mappings and reserved method names
132 */
133ACPI_OBJECT_TYPE
134AslMapNamedOpcodeToDataType (
135    UINT16                  Opcode);
136
137/* Local prototypes */
138
139static ACPI_STATUS
140AcpiDmFindOrphanDescending (
141    ACPI_PARSE_OBJECT       *Op,
142    UINT32                  Level,
143    void                    *Context);
144
145static ACPI_STATUS
146AcpiDmDumpDescending (
147    ACPI_PARSE_OBJECT       *Op,
148    UINT32                  Level,
149    void                    *Context);
150
151static ACPI_STATUS
152AcpiDmXrefDescendingOp (
153    ACPI_PARSE_OBJECT       *Op,
154    UINT32                  Level,
155    void                    *Context);
156
157static ACPI_STATUS
158AcpiDmCommonAscendingOp (
159    ACPI_PARSE_OBJECT       *Op,
160    UINT32                  Level,
161    void                    *Context);
162
163static ACPI_STATUS
164AcpiDmLoadDescendingOp (
165    ACPI_PARSE_OBJECT       *Op,
166    UINT32                  Level,
167    void                    *Context);
168
169static UINT32
170AcpiDmInspectPossibleArgs (
171    UINT32                  CurrentOpArgCount,
172    UINT32                  TargetCount,
173    ACPI_PARSE_OBJECT       *Op);
174
175static ACPI_STATUS
176AcpiDmResourceDescendingOp (
177    ACPI_PARSE_OBJECT       *Op,
178    UINT32                  Level,
179    void                    *Context);
180
181
182/*******************************************************************************
183 *
184 * FUNCTION:    AcpiDmDumpTree
185 *
186 * PARAMETERS:  Origin              - Starting object
187 *
188 * RETURN:      None
189 *
190 * DESCRIPTION: Parse tree walk to format and output the nodes
191 *
192 ******************************************************************************/
193
194void
195AcpiDmDumpTree (
196    ACPI_PARSE_OBJECT       *Origin)
197{
198    ACPI_OP_WALK_INFO       Info;
199
200
201    if (!Origin)
202    {
203        return;
204    }
205
206    AcpiOsPrintf ("/*\nAML Parse Tree\n\n");
207    Info.Flags = 0;
208    Info.Count = 0;
209    Info.Level = 0;
210    Info.WalkState = NULL;
211    AcpiDmWalkParseTree (Origin, AcpiDmDumpDescending, NULL, &Info);
212    AcpiOsPrintf ("*/\n\n");
213}
214
215
216/*******************************************************************************
217 *
218 * FUNCTION:    AcpiDmFindOrphanMethods
219 *
220 * PARAMETERS:  Origin              - Starting object
221 *
222 * RETURN:      None
223 *
224 * DESCRIPTION: Parse tree walk to find "orphaned" method invocations -- methods
225 *              that are not resolved in the namespace
226 *
227 ******************************************************************************/
228
229void
230AcpiDmFindOrphanMethods (
231    ACPI_PARSE_OBJECT       *Origin)
232{
233    ACPI_OP_WALK_INFO       Info;
234
235
236    if (!Origin)
237    {
238        return;
239    }
240
241    Info.Flags = 0;
242    Info.Level = 0;
243    Info.WalkState = NULL;
244    AcpiDmWalkParseTree (Origin, AcpiDmFindOrphanDescending, NULL, &Info);
245}
246
247
248/*******************************************************************************
249 *
250 * FUNCTION:    AcpiDmFinishNamespaceLoad
251 *
252 * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
253 *              NamespaceRoot       - Root of the internal namespace
254 *              OwnerId             - OwnerId of the table to be disassembled
255 *
256 * RETURN:      None
257 *
258 * DESCRIPTION: Load all namespace items that are created within control
259 *              methods. Used before namespace cross reference
260 *
261 ******************************************************************************/
262
263void
264AcpiDmFinishNamespaceLoad (
265    ACPI_PARSE_OBJECT       *ParseTreeRoot,
266    ACPI_NAMESPACE_NODE     *NamespaceRoot,
267    ACPI_OWNER_ID           OwnerId)
268{
269    ACPI_STATUS             Status;
270    ACPI_OP_WALK_INFO       Info;
271    ACPI_WALK_STATE         *WalkState;
272
273
274    if (!ParseTreeRoot)
275    {
276        return;
277    }
278
279    /* Create and initialize a new walk state */
280
281    WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
282    if (!WalkState)
283    {
284        return;
285    }
286
287    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState);
288    if (ACPI_FAILURE (Status))
289    {
290        return;
291    }
292
293    Info.Flags = 0;
294    Info.Level = 0;
295    Info.WalkState = WalkState;
296    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmLoadDescendingOp,
297        AcpiDmCommonAscendingOp, &Info);
298    ACPI_FREE (WalkState);
299}
300
301
302/*******************************************************************************
303 *
304 * FUNCTION:    AcpiDmCrossReferenceNamespace
305 *
306 * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
307 *              NamespaceRoot       - Root of the internal namespace
308 *              OwnerId             - OwnerId of the table to be disassembled
309 *
310 * RETURN:      None
311 *
312 * DESCRIPTION: Cross reference the namespace to create externals
313 *
314 ******************************************************************************/
315
316void
317AcpiDmCrossReferenceNamespace (
318    ACPI_PARSE_OBJECT       *ParseTreeRoot,
319    ACPI_NAMESPACE_NODE     *NamespaceRoot,
320    ACPI_OWNER_ID           OwnerId)
321{
322    ACPI_STATUS             Status;
323    ACPI_OP_WALK_INFO       Info;
324    ACPI_WALK_STATE         *WalkState;
325
326
327    if (!ParseTreeRoot)
328    {
329        return;
330    }
331
332    /* Create and initialize a new walk state */
333
334    WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
335    if (!WalkState)
336    {
337        return;
338    }
339
340    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState);
341    if (ACPI_FAILURE (Status))
342    {
343        return;
344    }
345
346    Info.Flags = 0;
347    Info.Level = 0;
348    Info.WalkState = WalkState;
349    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmXrefDescendingOp,
350        AcpiDmCommonAscendingOp, &Info);
351    ACPI_FREE (WalkState);
352}
353
354
355/*******************************************************************************
356 *
357 * FUNCTION:    AcpiDmConvertResourceIndexes
358 *
359 * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
360 *              NamespaceRoot       - Root of the internal namespace
361 *
362 * RETURN:      None
363 *
364 * DESCRIPTION: Convert fixed-offset references to resource descriptors to
365 *              symbolic references. Should only be called after namespace has
366 *              been cross referenced.
367 *
368 ******************************************************************************/
369
370void
371AcpiDmConvertResourceIndexes (
372    ACPI_PARSE_OBJECT       *ParseTreeRoot,
373    ACPI_NAMESPACE_NODE     *NamespaceRoot)
374{
375    ACPI_STATUS             Status;
376    ACPI_OP_WALK_INFO       Info;
377    ACPI_WALK_STATE         *WalkState;
378
379
380    if (!ParseTreeRoot)
381    {
382        return;
383    }
384
385    /* Create and initialize a new walk state */
386
387    WalkState = AcpiDsCreateWalkState (0, ParseTreeRoot, NULL, NULL);
388    if (!WalkState)
389    {
390        return;
391    }
392
393    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState);
394    if (ACPI_FAILURE (Status))
395    {
396        return;
397    }
398
399    Info.Flags = 0;
400    Info.Level = 0;
401    Info.WalkState = WalkState;
402    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmResourceDescendingOp,
403        AcpiDmCommonAscendingOp, &Info);
404    ACPI_FREE (WalkState);
405    return;
406}
407
408
409/*******************************************************************************
410 *
411 * FUNCTION:    AcpiDmDumpDescending
412 *
413 * PARAMETERS:  ASL_WALK_CALLBACK
414 *
415 * RETURN:      Status
416 *
417 * DESCRIPTION: Format and print contents of one parse Op.
418 *
419 ******************************************************************************/
420
421static ACPI_STATUS
422AcpiDmDumpDescending (
423    ACPI_PARSE_OBJECT       *Op,
424    UINT32                  Level,
425    void                    *Context)
426{
427    ACPI_OP_WALK_INFO       *Info = Context;
428    char                    *Path;
429
430
431    if (!Op)
432    {
433        return (AE_OK);
434    }
435
436    /* Most of the information (count, level, name) here */
437
438    Info->Count++;
439    AcpiOsPrintf ("% 5d [%2.2d] ", Info->Count, Level);
440    AcpiDmIndent (Level);
441    AcpiOsPrintf ("%-28s", AcpiPsGetOpcodeName (Op->Common.AmlOpcode));
442
443    /* Extra info is helpful */
444
445    switch (Op->Common.AmlOpcode)
446    {
447    case AML_BYTE_OP:
448    case AML_WORD_OP:
449    case AML_DWORD_OP:
450        AcpiOsPrintf ("%X", (UINT32) Op->Common.Value.Integer);
451        break;
452
453    case AML_QWORD_OP:
454        AcpiOsPrintf ("%8.8X%8.8X", ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
455        break;
456
457    case AML_INT_NAMEPATH_OP:
458        if (Op->Common.Value.String)
459        {
460            AcpiNsExternalizeName (ACPI_UINT32_MAX, Op->Common.Value.String,
461                            NULL, &Path);
462            AcpiOsPrintf ("%s %p", Path, Op->Common.Node);
463            ACPI_FREE (Path);
464        }
465        else
466        {
467            AcpiOsPrintf ("[NULL]");
468        }
469        break;
470
471    case AML_NAME_OP:
472    case AML_METHOD_OP:
473    case AML_DEVICE_OP:
474    case AML_INT_NAMEDFIELD_OP:
475        AcpiOsPrintf ("%4.4s", ACPI_CAST_PTR (char, &Op->Named.Name));
476        break;
477
478    default:
479        break;
480    }
481
482    AcpiOsPrintf ("\n");
483    return (AE_OK);
484}
485
486
487/*******************************************************************************
488 *
489 * FUNCTION:    AcpiDmFindOrphanDescending
490 *
491 * PARAMETERS:  ASL_WALK_CALLBACK
492 *
493 * RETURN:      Status
494 *
495 * DESCRIPTION: Check namepath Ops for orphaned method invocations
496 *
497 * Note: Experimental.
498 *
499 ******************************************************************************/
500
501static ACPI_STATUS
502AcpiDmFindOrphanDescending (
503    ACPI_PARSE_OBJECT       *Op,
504    UINT32                  Level,
505    void                    *Context)
506{
507    const ACPI_OPCODE_INFO  *OpInfo;
508    ACPI_PARSE_OBJECT       *ChildOp;
509    ACPI_PARSE_OBJECT       *NextOp;
510    ACPI_PARSE_OBJECT       *ParentOp;
511    UINT32                  ArgCount;
512
513
514    if (!Op)
515    {
516        return (AE_OK);
517    }
518
519    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
520
521    switch (Op->Common.AmlOpcode)
522    {
523#ifdef ACPI_UNDER_DEVELOPMENT
524    case AML_ADD_OP:
525        ChildOp = Op->Common.Value.Arg;
526        if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
527            !ChildOp->Common.Node)
528        {
529            AcpiNsExternalizeName (ACPI_UINT32_MAX, ChildOp->Common.Value.String,
530                            NULL, &Path);
531            AcpiOsPrintf ("/* %-16s A-NAMEPATH: %s  */\n", Op->Common.AmlOpName, Path);
532            ACPI_FREE (Path);
533
534            NextOp = Op->Common.Next;
535            if (!NextOp)
536            {
537                /* This NamePath has no args, assume it is an integer */
538
539                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
540                return (AE_OK);
541            }
542
543            ArgCount = AcpiDmInspectPossibleArgs (3, 1, NextOp);
544            AcpiOsPrintf ("/* A-CHILDREN: %u Actual %u */\n", ArgCount, AcpiDmCountChildren (Op));
545
546            if (ArgCount < 1)
547            {
548                /* One Arg means this is just a Store(Name,Target) */
549
550                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
551                return (AE_OK);
552            }
553
554            AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount);
555        }
556        break;
557#endif
558
559    case AML_STORE_OP:
560
561        ChildOp = Op->Common.Value.Arg;
562        if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
563            !ChildOp->Common.Node)
564        {
565            NextOp = Op->Common.Next;
566            if (!NextOp)
567            {
568                /* This NamePath has no args, assume it is an integer */
569
570                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
571                return (AE_OK);
572            }
573
574            ArgCount = AcpiDmInspectPossibleArgs (2, 1, NextOp);
575            if (ArgCount <= 1)
576            {
577                /* One Arg means this is just a Store(Name,Target) */
578
579                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
580                return (AE_OK);
581            }
582
583            AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount);
584        }
585        break;
586
587    case AML_INT_NAMEPATH_OP:
588
589        /* Must examine parent to see if this namepath is an argument */
590
591        ParentOp = Op->Common.Parent;
592        OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
593
594        if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
595            (OpInfo->Class != AML_CLASS_CREATE) &&
596            (OpInfo->ObjectType != ACPI_TYPE_LOCAL_ALIAS) &&
597            (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
598            !Op->Common.Node)
599        {
600            ArgCount = AcpiDmInspectPossibleArgs (0, 0, Op->Common.Next);
601
602            /*
603             * Check if namepath is a predicate for if/while or lone parameter to
604             * a return.
605             */
606            if (ArgCount == 0)
607            {
608                if (((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
609                     (ParentOp->Common.AmlOpcode == AML_WHILE_OP) ||
610                     (ParentOp->Common.AmlOpcode == AML_RETURN_OP)) &&
611
612                     /* And namepath is the first argument */
613                     (ParentOp->Common.Value.Arg == Op))
614                {
615                    AcpiDmAddToExternalList (Op, Op->Common.Value.String, ACPI_TYPE_INTEGER, 0);
616                    break;
617                }
618            }
619
620            /*
621             * This is a standalone namestring (not a parameter to another
622             * operator) - it *must* be a method invocation, nothing else is
623             * grammatically possible.
624             */
625            AcpiDmAddToExternalList (Op, Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount);
626
627        }
628        break;
629
630    default:
631        break;
632    }
633
634    return (AE_OK);
635}
636
637
638/*******************************************************************************
639 *
640 * FUNCTION:    AcpiDmLoadDescendingOp
641 *
642 * PARAMETERS:  ASL_WALK_CALLBACK
643 *
644 * RETURN:      Status
645 *
646 * DESCRIPTION: Descending handler for namespace control method object load
647 *
648 ******************************************************************************/
649
650static ACPI_STATUS
651AcpiDmLoadDescendingOp (
652    ACPI_PARSE_OBJECT       *Op,
653    UINT32                  Level,
654    void                    *Context)
655{
656    ACPI_OP_WALK_INFO       *Info = Context;
657    const ACPI_OPCODE_INFO  *OpInfo;
658    ACPI_WALK_STATE         *WalkState;
659    ACPI_OBJECT_TYPE        ObjectType;
660    ACPI_STATUS             Status;
661    char                    *Path = NULL;
662    ACPI_PARSE_OBJECT       *NextOp;
663    ACPI_NAMESPACE_NODE     *Node;
664    char                    FieldPath[5];
665    BOOLEAN                 PreDefined = FALSE;
666    UINT8                   PreDefineIndex = 0;
667
668
669    WalkState = Info->WalkState;
670    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
671    ObjectType = OpInfo->ObjectType;
672    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
673
674    /* Only interested in operators that create new names */
675
676    if (!(OpInfo->Flags & AML_NAMED) &&
677        !(OpInfo->Flags & AML_CREATE))
678    {
679        goto Exit;
680    }
681
682    /* Get the NamePath from the appropriate place */
683
684    if (OpInfo->Flags & AML_NAMED)
685    {
686        /* For all named operators, get the new name */
687
688        Path = (char *) Op->Named.Path;
689
690        if (!Path && Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
691        {
692            *ACPI_CAST_PTR (UINT32, &FieldPath[0]) = Op->Named.Name;
693            FieldPath[4] = 0;
694            Path = FieldPath;
695        }
696    }
697    else if (OpInfo->Flags & AML_CREATE)
698    {
699        /* New name is the last child */
700
701        NextOp = Op->Common.Value.Arg;
702
703        while (NextOp->Common.Next)
704        {
705            NextOp = NextOp->Common.Next;
706        }
707        Path = NextOp->Common.Value.String;
708    }
709
710    if (!Path)
711    {
712        goto Exit;
713    }
714
715    /* Insert the name into the namespace */
716
717    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
718                ACPI_IMODE_LOAD_PASS2, ACPI_NS_DONT_OPEN_SCOPE,
719                WalkState, &Node);
720
721    Op->Common.Node = Node;
722
723    if (ACPI_SUCCESS (Status))
724    {
725        /* Check if it's a predefined node */
726
727        while (AcpiGbl_PreDefinedNames[PreDefineIndex].Name)
728        {
729            if (ACPI_COMPARE_NAME (Node->Name.Ascii,
730                AcpiGbl_PreDefinedNames[PreDefineIndex].Name))
731            {
732                PreDefined = TRUE;
733                break;
734            }
735
736            PreDefineIndex++;
737        }
738
739        /*
740         * Set node owner id if it satisfies all the following conditions:
741         * 1) Not a predefined node, _SB_ etc
742         * 2) Not the root node
743         * 3) Not a node created by Scope
744         */
745
746        if (!PreDefined && Node != AcpiGbl_RootNode &&
747            Op->Common.AmlOpcode != AML_SCOPE_OP)
748        {
749            Node->OwnerId = WalkState->OwnerId;
750        }
751    }
752
753
754Exit:
755
756    if (AcpiNsOpensScope (ObjectType))
757    {
758        if (Op->Common.Node)
759        {
760            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
761            if (ACPI_FAILURE (Status))
762            {
763                return (Status);
764            }
765        }
766    }
767
768    return (AE_OK);
769}
770
771
772/*******************************************************************************
773 *
774 * FUNCTION:    AcpiDmXrefDescendingOp
775 *
776 * PARAMETERS:  ASL_WALK_CALLBACK
777 *
778 * RETURN:      Status
779 *
780 * DESCRIPTION: Descending handler for namespace cross reference
781 *
782 ******************************************************************************/
783
784static ACPI_STATUS
785AcpiDmXrefDescendingOp (
786    ACPI_PARSE_OBJECT       *Op,
787    UINT32                  Level,
788    void                    *Context)
789{
790    ACPI_OP_WALK_INFO       *Info = Context;
791    const ACPI_OPCODE_INFO  *OpInfo;
792    ACPI_WALK_STATE         *WalkState;
793    ACPI_OBJECT_TYPE        ObjectType;
794    ACPI_OBJECT_TYPE        ObjectType2;
795    ACPI_STATUS             Status;
796    char                    *Path = NULL;
797    ACPI_PARSE_OBJECT       *NextOp;
798    ACPI_NAMESPACE_NODE     *Node;
799    ACPI_OPERAND_OBJECT     *Object;
800    UINT32                  ParamCount = 0;
801
802
803    WalkState = Info->WalkState;
804    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
805    ObjectType = OpInfo->ObjectType;
806    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
807
808    if ((!(OpInfo->Flags & AML_NAMED)) &&
809        (!(OpInfo->Flags & AML_CREATE)) &&
810        (Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
811    {
812        goto Exit;
813    }
814
815    /* Get the NamePath from the appropriate place */
816
817    if (OpInfo->Flags & AML_NAMED)
818    {
819        /*
820         * Only these two operators (Alias, Scope) refer to an existing
821         * name, it is the first argument
822         */
823        if (Op->Common.AmlOpcode == AML_ALIAS_OP)
824        {
825            ObjectType = ACPI_TYPE_ANY;
826
827            NextOp = Op->Common.Value.Arg;
828            NextOp = NextOp->Common.Value.Arg;
829            if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
830            {
831                Path = NextOp->Common.Value.String;
832            }
833        }
834        else if (Op->Common.AmlOpcode == AML_SCOPE_OP)
835        {
836            Path = (char *) Op->Named.Path;
837        }
838    }
839    else if (OpInfo->Flags & AML_CREATE)
840    {
841        /* Referenced Buffer Name is the first child */
842
843        ObjectType = ACPI_TYPE_BUFFER; /* Change from TYPE_BUFFER_FIELD */
844
845        NextOp = Op->Common.Value.Arg;
846        if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
847        {
848            Path = NextOp->Common.Value.String;
849        }
850    }
851    else
852    {
853        Path = Op->Common.Value.String;
854    }
855
856    if (!Path)
857    {
858        goto Exit;
859    }
860
861    /*
862     * Lookup the name in the namespace. Name must exist at this point, or it
863     * is an invalid reference.
864     *
865     * The namespace is also used as a lookup table for references to resource
866     * descriptors and the fields within them.
867     */
868    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
869                ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
870                WalkState, &Node);
871    if (ACPI_SUCCESS (Status) && (Node->Flags & ANOBJ_IS_EXTERNAL))
872    {
873        Status = AE_NOT_FOUND;
874    }
875
876    if (ACPI_FAILURE (Status))
877    {
878        if (Status == AE_NOT_FOUND)
879        {
880            AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType, 0);
881
882            /*
883             * We could install this into the namespace, but we catch duplicate
884             * externals when they are added to the list.
885             */
886#if 0
887            Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
888                       ACPI_IMODE_LOAD_PASS1, ACPI_NS_DONT_OPEN_SCOPE,
889                       WalkState, &Node);
890#endif
891        }
892    }
893
894    /*
895     * Found the node in external table, add it to external list
896     * Node->OwnerId == 0 indicates built-in ACPI Names, _OS_ etc
897     */
898    else if (Node->OwnerId && WalkState->OwnerId != Node->OwnerId)
899    {
900        ObjectType2 = ObjectType;
901
902        Object = AcpiNsGetAttachedObject (Node);
903        if (Object)
904        {
905            ObjectType2 = Object->Common.Type;
906            if (ObjectType2 == ACPI_TYPE_METHOD)
907            {
908                ParamCount = Object->Method.ParamCount;
909            }
910        }
911
912        AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType2, ParamCount);
913        Op->Common.Node = Node;
914    }
915    else
916    {
917        Op->Common.Node = Node;
918    }
919
920
921Exit:
922    /* Open new scope if necessary */
923
924    if (AcpiNsOpensScope (ObjectType))
925    {
926        if (Op->Common.Node)
927        {
928            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
929            if (ACPI_FAILURE (Status))
930            {
931                return (Status);
932            }
933        }
934    }
935
936    return (AE_OK);
937}
938
939
940/*******************************************************************************
941 *
942 * FUNCTION:    AcpiDmResourceDescendingOp
943 *
944 * PARAMETERS:  ASL_WALK_CALLBACK
945 *
946 * RETURN:      None
947 *
948 * DESCRIPTION: Process one parse op during symbolic resource index conversion.
949 *
950 ******************************************************************************/
951
952static ACPI_STATUS
953AcpiDmResourceDescendingOp (
954    ACPI_PARSE_OBJECT       *Op,
955    UINT32                  Level,
956    void                    *Context)
957{
958    ACPI_OP_WALK_INFO       *Info = Context;
959    const ACPI_OPCODE_INFO  *OpInfo;
960    ACPI_WALK_STATE         *WalkState;
961    ACPI_OBJECT_TYPE        ObjectType;
962    ACPI_STATUS             Status;
963
964
965    WalkState = Info->WalkState;
966    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
967
968    /* Open new scope if necessary */
969
970    ObjectType = OpInfo->ObjectType;
971    if (AcpiNsOpensScope (ObjectType))
972    {
973        if (Op->Common.Node)
974        {
975
976            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
977            if (ACPI_FAILURE (Status))
978            {
979                return (Status);
980            }
981        }
982    }
983
984    /*
985     * Check if this operator contains a reference to a resource descriptor.
986     * If so, convert the reference into a symbolic reference.
987     */
988    AcpiDmCheckResourceReference (Op, WalkState);
989    return (AE_OK);
990}
991
992
993/*******************************************************************************
994 *
995 * FUNCTION:    AcpiDmCommonAscendingOp
996 *
997 * PARAMETERS:  ASL_WALK_CALLBACK
998 *
999 * RETURN:      None
1000 *
1001 * DESCRIPTION: Ascending handler for combined parse/namespace walks. Closes
1002 *              scope if necessary.
1003 *
1004 ******************************************************************************/
1005
1006static ACPI_STATUS
1007AcpiDmCommonAscendingOp (
1008    ACPI_PARSE_OBJECT       *Op,
1009    UINT32                  Level,
1010    void                    *Context)
1011{
1012    ACPI_OP_WALK_INFO       *Info = Context;
1013    const ACPI_OPCODE_INFO  *OpInfo;
1014    ACPI_OBJECT_TYPE        ObjectType;
1015
1016
1017    /* Close scope if necessary */
1018
1019    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1020    ObjectType = OpInfo->ObjectType;
1021    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
1022
1023    if (AcpiNsOpensScope (ObjectType))
1024    {
1025        (void) AcpiDsScopeStackPop (Info->WalkState);
1026    }
1027
1028    return (AE_OK);
1029}
1030
1031
1032/*******************************************************************************
1033 *
1034 * FUNCTION:    AcpiDmInspectPossibleArgs
1035 *
1036 * PARAMETERS:  CurrentOpArgCount   - Which arg of the current op was the
1037 *                                    possible method invocation found
1038 *              TargetCount         - Number of targets (0,1,2) for this op
1039 *              Op                  - Parse op
1040 *
1041 * RETURN:      Status
1042 *
1043 * DESCRIPTION: Examine following args and next ops for possible arguments
1044 *              for an unrecognized method invocation.
1045 *
1046 ******************************************************************************/
1047
1048static UINT32
1049AcpiDmInspectPossibleArgs (
1050    UINT32                  CurrentOpArgCount,
1051    UINT32                  TargetCount,
1052    ACPI_PARSE_OBJECT       *Op)
1053{
1054    const ACPI_OPCODE_INFO  *OpInfo;
1055    UINT32                  i;
1056    UINT32                  Last = 0;
1057    UINT32                  Lookahead;
1058
1059
1060    Lookahead = (ACPI_METHOD_NUM_ARGS + TargetCount) - CurrentOpArgCount;
1061
1062    /* Lookahead for the maximum number of possible arguments */
1063
1064    for (i = 0; i < Lookahead; i++)
1065    {
1066        if (!Op)
1067        {
1068            break;
1069        }
1070
1071        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1072
1073        /*
1074         * Any one of these operators is "very probably" not a method arg
1075         */
1076        if ((Op->Common.AmlOpcode == AML_STORE_OP) ||
1077            (Op->Common.AmlOpcode == AML_NOTIFY_OP))
1078        {
1079            break;
1080        }
1081
1082        if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
1083            (OpInfo->Class != AML_CLASS_CONTROL))
1084        {
1085            Last = i+1;
1086        }
1087
1088        Op = Op->Common.Next;
1089    }
1090
1091    return (Last);
1092}
1093