1/******************************************************************************
2 *
3 * Module Name: adwalk - Application-level disassembler parse tree walk routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45#include <contrib/dev/acpica/include/acpi.h>
46#include <contrib/dev/acpica/include/accommon.h>
47#include <contrib/dev/acpica/include/acparser.h>
48#include <contrib/dev/acpica/include/amlcode.h>
49#include <contrib/dev/acpica/include/acdisasm.h>
50#include <contrib/dev/acpica/include/acdispat.h>
51#include <contrib/dev/acpica/include/acnamesp.h>
52#include <contrib/dev/acpica/include/acapps.h>
53
54
55#define _COMPONENT          ACPI_TOOLS
56        ACPI_MODULE_NAME    ("adwalk")
57
58/*
59 * aslmap - opcode mappings and reserved method names
60 */
61ACPI_OBJECT_TYPE
62AslMapNamedOpcodeToDataType (
63    UINT16                  Opcode);
64
65/* Local prototypes */
66
67static ACPI_STATUS
68AcpiDmFindOrphanDescending (
69    ACPI_PARSE_OBJECT       *Op,
70    UINT32                  Level,
71    void                    *Context);
72
73static ACPI_STATUS
74AcpiDmDumpDescending (
75    ACPI_PARSE_OBJECT       *Op,
76    UINT32                  Level,
77    void                    *Context);
78
79static ACPI_STATUS
80AcpiDmXrefDescendingOp (
81    ACPI_PARSE_OBJECT       *Op,
82    UINT32                  Level,
83    void                    *Context);
84
85static ACPI_STATUS
86AcpiDmCommonAscendingOp (
87    ACPI_PARSE_OBJECT       *Op,
88    UINT32                  Level,
89    void                    *Context);
90
91static ACPI_STATUS
92AcpiDmLoadDescendingOp (
93    ACPI_PARSE_OBJECT       *Op,
94    UINT32                  Level,
95    void                    *Context);
96
97static UINT32
98AcpiDmInspectPossibleArgs (
99    UINT32                  CurrentOpArgCount,
100    UINT32                  TargetCount,
101    ACPI_PARSE_OBJECT       *Op);
102
103static ACPI_STATUS
104AcpiDmResourceDescendingOp (
105    ACPI_PARSE_OBJECT       *Op,
106    UINT32                  Level,
107    void                    *Context);
108
109
110/*******************************************************************************
111 *
112 * FUNCTION:    AcpiDmDumpTree
113 *
114 * PARAMETERS:  Origin              - Starting object
115 *
116 * RETURN:      None
117 *
118 * DESCRIPTION: Parse tree walk to format and output the nodes
119 *
120 ******************************************************************************/
121
122void
123AcpiDmDumpTree (
124    ACPI_PARSE_OBJECT       *Origin)
125{
126    ACPI_OP_WALK_INFO       Info;
127
128
129    if (!Origin)
130    {
131        return;
132    }
133
134    AcpiOsPrintf ("/*\nAML Parse Tree\n\n");
135    Info.Flags = 0;
136    Info.Count = 0;
137    Info.Level = 0;
138    Info.WalkState = NULL;
139    AcpiDmWalkParseTree (Origin, AcpiDmDumpDescending, NULL, &Info);
140    AcpiOsPrintf ("*/\n\n");
141}
142
143
144/*******************************************************************************
145 *
146 * FUNCTION:    AcpiDmFindOrphanMethods
147 *
148 * PARAMETERS:  Origin              - Starting object
149 *
150 * RETURN:      None
151 *
152 * DESCRIPTION: Parse tree walk to find "orphaned" method invocations -- methods
153 *              that are not resolved in the namespace
154 *
155 ******************************************************************************/
156
157void
158AcpiDmFindOrphanMethods (
159    ACPI_PARSE_OBJECT       *Origin)
160{
161    ACPI_OP_WALK_INFO       Info;
162
163
164    if (!Origin)
165    {
166        return;
167    }
168
169    Info.Flags = 0;
170    Info.Level = 0;
171    Info.WalkState = NULL;
172    AcpiDmWalkParseTree (Origin, AcpiDmFindOrphanDescending, NULL, &Info);
173}
174
175
176/*******************************************************************************
177 *
178 * FUNCTION:    AcpiDmFinishNamespaceLoad
179 *
180 * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
181 *              NamespaceRoot       - Root of the internal namespace
182 *              OwnerId             - OwnerId of the table to be disassembled
183 *
184 * RETURN:      None
185 *
186 * DESCRIPTION: Load all namespace items that are created within control
187 *              methods. Used before namespace cross reference
188 *
189 ******************************************************************************/
190
191void
192AcpiDmFinishNamespaceLoad (
193    ACPI_PARSE_OBJECT       *ParseTreeRoot,
194    ACPI_NAMESPACE_NODE     *NamespaceRoot,
195    ACPI_OWNER_ID           OwnerId)
196{
197    ACPI_STATUS             Status;
198    ACPI_OP_WALK_INFO       Info;
199    ACPI_WALK_STATE         *WalkState;
200
201
202    if (!ParseTreeRoot)
203    {
204        return;
205    }
206
207    /* Create and initialize a new walk state */
208
209    WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
210    if (!WalkState)
211    {
212        return;
213    }
214
215    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState);
216    if (ACPI_FAILURE (Status))
217    {
218        return;
219    }
220
221    Info.Flags = 0;
222    Info.Level = 0;
223    Info.WalkState = WalkState;
224    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmLoadDescendingOp,
225        AcpiDmCommonAscendingOp, &Info);
226    ACPI_FREE (WalkState);
227}
228
229
230/*******************************************************************************
231 *
232 * FUNCTION:    AcpiDmCrossReferenceNamespace
233 *
234 * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
235 *              NamespaceRoot       - Root of the internal namespace
236 *              OwnerId             - OwnerId of the table to be disassembled
237 *
238 * RETURN:      None
239 *
240 * DESCRIPTION: Cross reference the namespace to create externals
241 *
242 ******************************************************************************/
243
244void
245AcpiDmCrossReferenceNamespace (
246    ACPI_PARSE_OBJECT       *ParseTreeRoot,
247    ACPI_NAMESPACE_NODE     *NamespaceRoot,
248    ACPI_OWNER_ID           OwnerId)
249{
250    ACPI_STATUS             Status;
251    ACPI_OP_WALK_INFO       Info;
252    ACPI_WALK_STATE         *WalkState;
253
254
255    if (!ParseTreeRoot)
256    {
257        return;
258    }
259
260    /* Create and initialize a new walk state */
261
262    WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
263    if (!WalkState)
264    {
265        return;
266    }
267
268    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState);
269    if (ACPI_FAILURE (Status))
270    {
271        return;
272    }
273
274    Info.Flags = 0;
275    Info.Level = 0;
276    Info.WalkState = WalkState;
277    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmXrefDescendingOp,
278        AcpiDmCommonAscendingOp, &Info);
279    ACPI_FREE (WalkState);
280}
281
282
283/*******************************************************************************
284 *
285 * FUNCTION:    AcpiDmConvertResourceIndexes
286 *
287 * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
288 *              NamespaceRoot       - Root of the internal namespace
289 *
290 * RETURN:      None
291 *
292 * DESCRIPTION: Convert fixed-offset references to resource descriptors to
293 *              symbolic references. Should only be called after namespace has
294 *              been cross referenced.
295 *
296 ******************************************************************************/
297
298void
299AcpiDmConvertResourceIndexes (
300    ACPI_PARSE_OBJECT       *ParseTreeRoot,
301    ACPI_NAMESPACE_NODE     *NamespaceRoot)
302{
303    ACPI_STATUS             Status;
304    ACPI_OP_WALK_INFO       Info;
305    ACPI_WALK_STATE         *WalkState;
306
307
308    if (!ParseTreeRoot)
309    {
310        return;
311    }
312
313    /* Create and initialize a new walk state */
314
315    WalkState = AcpiDsCreateWalkState (0, ParseTreeRoot, NULL, NULL);
316    if (!WalkState)
317    {
318        return;
319    }
320
321    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState);
322    if (ACPI_FAILURE (Status))
323    {
324        return;
325    }
326
327    Info.Flags = 0;
328    Info.Level = 0;
329    Info.WalkState = WalkState;
330    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmResourceDescendingOp,
331        AcpiDmCommonAscendingOp, &Info);
332    ACPI_FREE (WalkState);
333    return;
334}
335
336
337/*******************************************************************************
338 *
339 * FUNCTION:    AcpiDmDumpDescending
340 *
341 * PARAMETERS:  ASL_WALK_CALLBACK
342 *
343 * RETURN:      Status
344 *
345 * DESCRIPTION: Format and print contents of one parse Op.
346 *
347 ******************************************************************************/
348
349static ACPI_STATUS
350AcpiDmDumpDescending (
351    ACPI_PARSE_OBJECT       *Op,
352    UINT32                  Level,
353    void                    *Context)
354{
355    ACPI_OP_WALK_INFO       *Info = Context;
356    char                    *Path;
357
358
359    if (!Op)
360    {
361        return (AE_OK);
362    }
363
364    /* Most of the information (count, level, name) here */
365
366    Info->Count++;
367    AcpiOsPrintf ("% 5d [%2.2d] ", Info->Count, Level);
368    AcpiDmIndent (Level);
369    AcpiOsPrintf ("%-28s", AcpiPsGetOpcodeName (Op->Common.AmlOpcode));
370
371    /* Extra info is helpful */
372
373    switch (Op->Common.AmlOpcode)
374    {
375    case AML_BYTE_OP:
376    case AML_WORD_OP:
377    case AML_DWORD_OP:
378        AcpiOsPrintf ("%X", (UINT32) Op->Common.Value.Integer);
379        break;
380
381    case AML_INT_NAMEPATH_OP:
382        if (Op->Common.Value.String)
383        {
384            AcpiNsExternalizeName (ACPI_UINT32_MAX, Op->Common.Value.String,
385                            NULL, &Path);
386            AcpiOsPrintf ("%s %p", Path, Op->Common.Node);
387            ACPI_FREE (Path);
388        }
389        else
390        {
391            AcpiOsPrintf ("[NULL]");
392        }
393        break;
394
395    case AML_NAME_OP:
396    case AML_METHOD_OP:
397    case AML_DEVICE_OP:
398    case AML_INT_NAMEDFIELD_OP:
399        AcpiOsPrintf ("%4.4s", ACPI_CAST_PTR (char, &Op->Named.Name));
400        break;
401
402    default:
403        break;
404    }
405
406    AcpiOsPrintf ("\n");
407    return (AE_OK);
408}
409
410
411/*******************************************************************************
412 *
413 * FUNCTION:    AcpiDmFindOrphanDescending
414 *
415 * PARAMETERS:  ASL_WALK_CALLBACK
416 *
417 * RETURN:      Status
418 *
419 * DESCRIPTION: Check namepath Ops for orphaned method invocations
420 *
421 * Note: Experimental.
422 *
423 ******************************************************************************/
424
425static ACPI_STATUS
426AcpiDmFindOrphanDescending (
427    ACPI_PARSE_OBJECT       *Op,
428    UINT32                  Level,
429    void                    *Context)
430{
431    const ACPI_OPCODE_INFO  *OpInfo;
432    ACPI_PARSE_OBJECT       *ChildOp;
433    ACPI_PARSE_OBJECT       *NextOp;
434    ACPI_PARSE_OBJECT       *ParentOp;
435    UINT32                  ArgCount;
436
437
438    if (!Op)
439    {
440        return (AE_OK);
441    }
442
443    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
444
445    switch (Op->Common.AmlOpcode)
446    {
447#ifdef ACPI_UNDER_DEVELOPMENT
448    case AML_ADD_OP:
449        ChildOp = Op->Common.Value.Arg;
450        if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
451            !ChildOp->Common.Node)
452        {
453            AcpiNsExternalizeName (ACPI_UINT32_MAX, ChildOp->Common.Value.String,
454                            NULL, &Path);
455            AcpiOsPrintf ("/* %-16s A-NAMEPATH: %s  */\n", Op->Common.AmlOpName, Path);
456            ACPI_FREE (Path);
457
458            NextOp = Op->Common.Next;
459            if (!NextOp)
460            {
461                /* This NamePath has no args, assume it is an integer */
462
463                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
464                return (AE_OK);
465            }
466
467            ArgCount = AcpiDmInspectPossibleArgs (3, 1, NextOp);
468            AcpiOsPrintf ("/* A-CHILDREN: %u Actual %u */\n", ArgCount, AcpiDmCountChildren (Op));
469
470            if (ArgCount < 1)
471            {
472                /* One Arg means this is just a Store(Name,Target) */
473
474                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
475                return (AE_OK);
476            }
477
478            AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount);
479        }
480        break;
481#endif
482
483    case AML_STORE_OP:
484
485        ChildOp = Op->Common.Value.Arg;
486        if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
487            !ChildOp->Common.Node)
488        {
489            NextOp = Op->Common.Next;
490            if (!NextOp)
491            {
492                /* This NamePath has no args, assume it is an integer */
493
494                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
495                return (AE_OK);
496            }
497
498            ArgCount = AcpiDmInspectPossibleArgs (2, 1, NextOp);
499            if (ArgCount <= 1)
500            {
501                /* One Arg means this is just a Store(Name,Target) */
502
503                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
504                return (AE_OK);
505            }
506
507            AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount);
508        }
509        break;
510
511    case AML_INT_NAMEPATH_OP:
512
513        /* Must examine parent to see if this namepath is an argument */
514
515        ParentOp = Op->Common.Parent;
516        OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
517
518        if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
519            (OpInfo->Class != AML_CLASS_CREATE) &&
520            (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
521            !Op->Common.Node)
522        {
523            ArgCount = AcpiDmInspectPossibleArgs (0, 0, Op->Common.Next);
524
525            /*
526             * Check if namepath is a predicate for if/while or lone parameter to
527             * a return.
528             */
529            if (ArgCount == 0)
530            {
531                if (((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
532                     (ParentOp->Common.AmlOpcode == AML_WHILE_OP) ||
533                     (ParentOp->Common.AmlOpcode == AML_RETURN_OP)) &&
534
535                     /* And namepath is the first argument */
536                     (ParentOp->Common.Value.Arg == Op))
537                {
538                    AcpiDmAddToExternalList (Op, Op->Common.Value.String, ACPI_TYPE_INTEGER, 0);
539                    break;
540                }
541            }
542
543            /*
544             * This is a standalone namestring (not a parameter to another
545             * operator) - it *must* be a method invocation, nothing else is
546             * grammatically possible.
547             */
548            AcpiDmAddToExternalList (Op, Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount);
549
550        }
551        break;
552
553    default:
554        break;
555    }
556
557    return (AE_OK);
558}
559
560
561/*******************************************************************************
562 *
563 * FUNCTION:    AcpiDmLoadDescendingOp
564 *
565 * PARAMETERS:  ASL_WALK_CALLBACK
566 *
567 * RETURN:      Status
568 *
569 * DESCRIPTION: Descending handler for namespace control method object load
570 *
571 ******************************************************************************/
572
573static ACPI_STATUS
574AcpiDmLoadDescendingOp (
575    ACPI_PARSE_OBJECT       *Op,
576    UINT32                  Level,
577    void                    *Context)
578{
579    ACPI_OP_WALK_INFO       *Info = Context;
580    const ACPI_OPCODE_INFO  *OpInfo;
581    ACPI_WALK_STATE         *WalkState;
582    ACPI_OBJECT_TYPE        ObjectType;
583    ACPI_STATUS             Status;
584    char                    *Path = NULL;
585    ACPI_PARSE_OBJECT       *NextOp;
586    ACPI_NAMESPACE_NODE     *Node;
587    char                    FieldPath[5];
588    BOOLEAN                 PreDefined = FALSE;
589    UINT8                   PreDefineIndex = 0;
590
591
592    WalkState = Info->WalkState;
593    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
594    ObjectType = OpInfo->ObjectType;
595    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
596
597    /* Only interested in operators that create new names */
598
599    if (!(OpInfo->Flags & AML_NAMED) &&
600        !(OpInfo->Flags & AML_CREATE))
601    {
602        goto Exit;
603    }
604
605    /* Get the NamePath from the appropriate place */
606
607    if (OpInfo->Flags & AML_NAMED)
608    {
609        /* For all named operators, get the new name */
610
611        Path = (char *) Op->Named.Path;
612
613        if (!Path && Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
614        {
615            *ACPI_CAST_PTR (UINT32, &FieldPath[0]) = Op->Named.Name;
616            FieldPath[4] = 0;
617            Path = FieldPath;
618        }
619    }
620    else if (OpInfo->Flags & AML_CREATE)
621    {
622        /* New name is the last child */
623
624        NextOp = Op->Common.Value.Arg;
625
626        while (NextOp->Common.Next)
627        {
628            NextOp = NextOp->Common.Next;
629        }
630        Path = NextOp->Common.Value.String;
631    }
632
633    if (!Path)
634    {
635        goto Exit;
636    }
637
638    /* Insert the name into the namespace */
639
640    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
641                ACPI_IMODE_LOAD_PASS2, ACPI_NS_DONT_OPEN_SCOPE,
642                WalkState, &Node);
643
644    Op->Common.Node = Node;
645
646    if (ACPI_SUCCESS (Status))
647    {
648        /* Check if it's a predefined node */
649
650        while (AcpiGbl_PreDefinedNames[PreDefineIndex].Name)
651        {
652            if (!ACPI_STRNCMP (Node->Name.Ascii,
653                AcpiGbl_PreDefinedNames[PreDefineIndex].Name, 4))
654            {
655                PreDefined = TRUE;
656                break;
657            }
658
659            PreDefineIndex++;
660        }
661
662        /*
663         * Set node owner id if it satisfies all the following conditions:
664         * 1) Not a predefined node, _SB_ etc
665         * 2) Not the root node
666         * 3) Not a node created by Scope
667         */
668
669        if (!PreDefined && Node != AcpiGbl_RootNode &&
670            Op->Common.AmlOpcode != AML_SCOPE_OP)
671        {
672            Node->OwnerId = WalkState->OwnerId;
673        }
674    }
675
676
677Exit:
678
679    if (AcpiNsOpensScope (ObjectType))
680    {
681        if (Op->Common.Node)
682        {
683            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
684            if (ACPI_FAILURE (Status))
685            {
686                return (Status);
687            }
688        }
689    }
690
691    return (AE_OK);
692}
693
694
695/*******************************************************************************
696 *
697 * FUNCTION:    AcpiDmXrefDescendingOp
698 *
699 * PARAMETERS:  ASL_WALK_CALLBACK
700 *
701 * RETURN:      Status
702 *
703 * DESCRIPTION: Descending handler for namespace cross reference
704 *
705 ******************************************************************************/
706
707static ACPI_STATUS
708AcpiDmXrefDescendingOp (
709    ACPI_PARSE_OBJECT       *Op,
710    UINT32                  Level,
711    void                    *Context)
712{
713    ACPI_OP_WALK_INFO       *Info = Context;
714    const ACPI_OPCODE_INFO  *OpInfo;
715    ACPI_WALK_STATE         *WalkState;
716    ACPI_OBJECT_TYPE        ObjectType;
717    ACPI_OBJECT_TYPE        ObjectType2;
718    ACPI_STATUS             Status;
719    char                    *Path = NULL;
720    ACPI_PARSE_OBJECT       *NextOp;
721    ACPI_NAMESPACE_NODE     *Node;
722    ACPI_OPERAND_OBJECT     *Object;
723    UINT32                  ParamCount = 0;
724
725
726    WalkState = Info->WalkState;
727    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
728    ObjectType = OpInfo->ObjectType;
729    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
730
731    if ((!(OpInfo->Flags & AML_NAMED)) &&
732        (!(OpInfo->Flags & AML_CREATE)) &&
733        (Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
734    {
735        goto Exit;
736    }
737
738    /* Get the NamePath from the appropriate place */
739
740    if (OpInfo->Flags & AML_NAMED)
741    {
742        if ((Op->Common.AmlOpcode == AML_ALIAS_OP) ||
743            (Op->Common.AmlOpcode == AML_SCOPE_OP))
744        {
745            /*
746             * Only these two operators refer to an existing name,
747             * first argument
748             */
749            Path = (char *) Op->Named.Path;
750        }
751    }
752    else if (OpInfo->Flags & AML_CREATE)
753    {
754        /* Referenced Buffer Name is the first child */
755
756        NextOp = Op->Common.Value.Arg;
757        if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
758        {
759            Path = NextOp->Common.Value.String;
760        }
761    }
762    else
763    {
764        Path = Op->Common.Value.String;
765    }
766
767    if (!Path)
768    {
769        goto Exit;
770    }
771
772    /*
773     * Lookup the name in the namespace.  Name must exist at this point, or it
774     * is an invalid reference.
775     *
776     * The namespace is also used as a lookup table for references to resource
777     * descriptors and the fields within them.
778     */
779    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
780                ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
781                WalkState, &Node);
782    if (ACPI_FAILURE (Status))
783    {
784        if (Status == AE_NOT_FOUND)
785        {
786            AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType, 0);
787
788            /*
789             * We could install this into the namespace, but we catch duplicate
790             * externals when they are added to the list.
791             */
792#if 0
793            Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
794                       ACPI_IMODE_LOAD_PASS1, ACPI_NS_DONT_OPEN_SCOPE,
795                       WalkState, &Node);
796#endif
797        }
798    }
799
800    /*
801     * Found the node in external table, add it to external list
802     * Node->OwnerId == 0 indicates built-in ACPI Names, _OS_ etc
803     */
804    else if (Node->OwnerId && WalkState->OwnerId != Node->OwnerId)
805    {
806        ObjectType2 = ObjectType;
807
808        Object = AcpiNsGetAttachedObject (Node);
809        if (Object)
810        {
811            ObjectType2 = Object->Common.Type;
812            if (ObjectType2 == ACPI_TYPE_METHOD)
813            {
814                ParamCount = Object->Method.ParamCount;
815            }
816        }
817
818        AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType2, ParamCount);
819        Op->Common.Node = Node;
820    }
821    else
822    {
823        Op->Common.Node = Node;
824    }
825
826
827Exit:
828    /* Open new scope if necessary */
829
830    if (AcpiNsOpensScope (ObjectType))
831    {
832        if (Op->Common.Node)
833        {
834            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
835            if (ACPI_FAILURE (Status))
836            {
837                return (Status);
838            }
839        }
840    }
841
842    return (AE_OK);
843}
844
845
846/*******************************************************************************
847 *
848 * FUNCTION:    AcpiDmResourceDescendingOp
849 *
850 * PARAMETERS:  ASL_WALK_CALLBACK
851 *
852 * RETURN:      None
853 *
854 * DESCRIPTION: Process one parse op during symbolic resource index conversion.
855 *
856 ******************************************************************************/
857
858static ACPI_STATUS
859AcpiDmResourceDescendingOp (
860    ACPI_PARSE_OBJECT       *Op,
861    UINT32                  Level,
862    void                    *Context)
863{
864    ACPI_OP_WALK_INFO       *Info = Context;
865    const ACPI_OPCODE_INFO  *OpInfo;
866    ACPI_WALK_STATE         *WalkState;
867    ACPI_OBJECT_TYPE        ObjectType;
868    ACPI_STATUS             Status;
869
870
871    WalkState = Info->WalkState;
872    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
873
874    /* Open new scope if necessary */
875
876    ObjectType = OpInfo->ObjectType;
877    if (AcpiNsOpensScope (ObjectType))
878    {
879        if (Op->Common.Node)
880        {
881
882            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
883            if (ACPI_FAILURE (Status))
884            {
885                return (Status);
886            }
887        }
888    }
889
890    /*
891     * Check if this operator contains a reference to a resource descriptor.
892     * If so, convert the reference into a symbolic reference.
893     */
894    AcpiDmCheckResourceReference (Op, WalkState);
895    return (AE_OK);
896}
897
898
899/*******************************************************************************
900 *
901 * FUNCTION:    AcpiDmCommonAscendingOp
902 *
903 * PARAMETERS:  ASL_WALK_CALLBACK
904 *
905 * RETURN:      None
906 *
907 * DESCRIPTION: Ascending handler for combined parse/namespace walks. Closes
908 *              scope if necessary.
909 *
910 ******************************************************************************/
911
912static ACPI_STATUS
913AcpiDmCommonAscendingOp (
914    ACPI_PARSE_OBJECT       *Op,
915    UINT32                  Level,
916    void                    *Context)
917{
918    ACPI_OP_WALK_INFO       *Info = Context;
919    const ACPI_OPCODE_INFO  *OpInfo;
920    ACPI_OBJECT_TYPE        ObjectType;
921
922
923    /* Close scope if necessary */
924
925    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
926    ObjectType = OpInfo->ObjectType;
927    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
928
929    if (AcpiNsOpensScope (ObjectType))
930    {
931        (void) AcpiDsScopeStackPop (Info->WalkState);
932    }
933
934    return (AE_OK);
935}
936
937
938/*******************************************************************************
939 *
940 * FUNCTION:    AcpiDmInspectPossibleArgs
941 *
942 * PARAMETERS:  CurrentOpArgCount   - Which arg of the current op was the
943 *                                    possible method invocation found
944 *              TargetCount         - Number of targets (0,1,2) for this op
945 *              Op                  - Parse op
946 *
947 * RETURN:      Status
948 *
949 * DESCRIPTION: Examine following args and next ops for possible arguments
950 *              for an unrecognized method invocation.
951 *
952 ******************************************************************************/
953
954static UINT32
955AcpiDmInspectPossibleArgs (
956    UINT32                  CurrentOpArgCount,
957    UINT32                  TargetCount,
958    ACPI_PARSE_OBJECT       *Op)
959{
960    const ACPI_OPCODE_INFO  *OpInfo;
961    UINT32                  i;
962    UINT32                  Last = 0;
963    UINT32                  Lookahead;
964
965
966    Lookahead = (ACPI_METHOD_NUM_ARGS + TargetCount) - CurrentOpArgCount;
967
968    /* Lookahead for the maximum number of possible arguments */
969
970    for (i = 0; i < Lookahead; i++)
971    {
972        if (!Op)
973        {
974            break;
975        }
976
977        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
978
979        /*
980         * Any one of these operators is "very probably" not a method arg
981         */
982        if ((Op->Common.AmlOpcode == AML_STORE_OP) ||
983            (Op->Common.AmlOpcode == AML_NOTIFY_OP))
984        {
985            break;
986        }
987
988        if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
989            (OpInfo->Class != AML_CLASS_CONTROL))
990        {
991            Last = i+1;
992        }
993
994        Op = Op->Common.Next;
995    }
996
997    return (Last);
998}
999
1000
1001