adwalk.c revision 306536
1219181Snwhitehorn/******************************************************************************
2219181Snwhitehorn *
3219181Snwhitehorn * Module Name: adwalk - Application-level disassembler parse tree walk routines
4219181Snwhitehorn *
5219181Snwhitehorn *****************************************************************************/
6219181Snwhitehorn
7219181Snwhitehorn/*
8219181Snwhitehorn * Copyright (C) 2000 - 2016, Intel Corp.
9219181Snwhitehorn * All rights reserved.
10219181Snwhitehorn *
11225637Snwhitehorn * Redistribution and use in source and binary forms, with or without
12225637Snwhitehorn * modification, are permitted provided that the following conditions
13230482Snwhitehorn * are met:
14225637Snwhitehorn * 1. Redistributions of source code must retain the above copyright
15230482Snwhitehorn *    notice, this list of conditions, and the following disclaimer,
16230482Snwhitehorn *    without modification.
17230482Snwhitehorn * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18230482Snwhitehorn *    substantially similar to the "NO WARRANTY" disclaimer below
19230482Snwhitehorn *    ("Disclaimer") and any redistribution must be conditioned upon
20230482Snwhitehorn *    including a substantially similar Disclaimer requirement for further
21230482Snwhitehorn *    binary redistribution.
22230482Snwhitehorn * 3. Neither the names of the above-listed copyright holders nor the names
23230482Snwhitehorn *    of any contributors may be used to endorse or promote products derived
24230482Snwhitehorn *    from this software without specific prior written permission.
25230482Snwhitehorn *
26225637Snwhitehorn * Alternatively, this software may be distributed under the terms of the
27225637Snwhitehorn * GNU General Public License ("GPL") version 2 as published by the Free
28225637Snwhitehorn * Software Foundation.
29225637Snwhitehorn *
30225637Snwhitehorn * NO WARRANTY
31225637Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32225637Snwhitehorn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33225637Snwhitehorn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34225637Snwhitehorn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35225637Snwhitehorn * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36225637Snwhitehorn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37225637Snwhitehorn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38225637Snwhitehorn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39225637Snwhitehorn * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40225637Snwhitehorn * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41225637Snwhitehorn * POSSIBILITY OF SUCH DAMAGES.
42219181Snwhitehorn */
43219181Snwhitehorn
44219181Snwhitehorn#include <contrib/dev/acpica/include/acpi.h>
45219181Snwhitehorn#include <contrib/dev/acpica/include/accommon.h>
46219181Snwhitehorn#include <contrib/dev/acpica/include/acparser.h>
47225637Snwhitehorn#include <contrib/dev/acpica/include/amlcode.h>
48225637Snwhitehorn#include <contrib/dev/acpica/include/acdisasm.h>
49225637Snwhitehorn#include <contrib/dev/acpica/include/acdispat.h>
50225637Snwhitehorn#include <contrib/dev/acpica/include/acnamesp.h>
51225637Snwhitehorn#include <contrib/dev/acpica/include/acapps.h>
52225637Snwhitehorn
53219181Snwhitehorn
54219181Snwhitehorn#define _COMPONENT          ACPI_TOOLS
55220500Snwhitehorn        ACPI_MODULE_NAME    ("adwalk")
56220500Snwhitehorn
57220500Snwhitehorn/*
58220500Snwhitehorn * aslmap - opcode mappings and reserved method names
59220500Snwhitehorn */
60219181SnwhitehornACPI_OBJECT_TYPE
61219181SnwhitehornAslMapNamedOpcodeToDataType (
62219181Snwhitehorn    UINT16                  Opcode);
63219181Snwhitehorn
64219181Snwhitehorn/* Local prototypes */
65219181Snwhitehorn
66219181Snwhitehornstatic ACPI_STATUS
67219181SnwhitehornAcpiDmFindOrphanDescending (
68219181Snwhitehorn    ACPI_PARSE_OBJECT       *Op,
69219181Snwhitehorn    UINT32                  Level,
70219181Snwhitehorn    void                    *Context);
71219181Snwhitehorn
72static ACPI_STATUS
73AcpiDmDumpDescending (
74    ACPI_PARSE_OBJECT       *Op,
75    UINT32                  Level,
76    void                    *Context);
77
78static ACPI_STATUS
79AcpiDmXrefDescendingOp (
80    ACPI_PARSE_OBJECT       *Op,
81    UINT32                  Level,
82    void                    *Context);
83
84static ACPI_STATUS
85AcpiDmCommonAscendingOp (
86    ACPI_PARSE_OBJECT       *Op,
87    UINT32                  Level,
88    void                    *Context);
89
90static ACPI_STATUS
91AcpiDmLoadDescendingOp (
92    ACPI_PARSE_OBJECT       *Op,
93    UINT32                  Level,
94    void                    *Context);
95
96static UINT32
97AcpiDmInspectPossibleArgs (
98    UINT32                  CurrentOpArgCount,
99    UINT32                  TargetCount,
100    ACPI_PARSE_OBJECT       *Op);
101
102static ACPI_STATUS
103AcpiDmResourceDescendingOp (
104    ACPI_PARSE_OBJECT       *Op,
105    UINT32                  Level,
106    void                    *Context);
107
108
109/*******************************************************************************
110 *
111 * FUNCTION:    AcpiDmDumpTree
112 *
113 * PARAMETERS:  Origin              - Starting object
114 *
115 * RETURN:      None
116 *
117 * DESCRIPTION: Parse tree walk to format and output the nodes
118 *
119 ******************************************************************************/
120
121void
122AcpiDmDumpTree (
123    ACPI_PARSE_OBJECT       *Origin)
124{
125    ACPI_OP_WALK_INFO       Info;
126
127
128    if (!Origin)
129    {
130        return;
131    }
132
133    AcpiOsPrintf ("/*\nAML Parse Tree\n\n");
134    Info.Flags = 0;
135    Info.Count = 0;
136    Info.Level = 0;
137    Info.WalkState = NULL;
138
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
173    AcpiDmWalkParseTree (Origin, AcpiDmFindOrphanDescending, NULL, &Info);
174}
175
176
177/*******************************************************************************
178 *
179 * FUNCTION:    AcpiDmFinishNamespaceLoad
180 *
181 * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
182 *              NamespaceRoot       - Root of the internal namespace
183 *              OwnerId             - OwnerId of the table to be disassembled
184 *
185 * RETURN:      None
186 *
187 * DESCRIPTION: Load all namespace items that are created within control
188 *              methods. Used before namespace cross reference
189 *
190 ******************************************************************************/
191
192void
193AcpiDmFinishNamespaceLoad (
194    ACPI_PARSE_OBJECT       *ParseTreeRoot,
195    ACPI_NAMESPACE_NODE     *NamespaceRoot,
196    ACPI_OWNER_ID           OwnerId)
197{
198    ACPI_STATUS             Status;
199    ACPI_OP_WALK_INFO       Info;
200    ACPI_WALK_STATE         *WalkState;
201
202
203    if (!ParseTreeRoot)
204    {
205        return;
206    }
207
208    /* Create and initialize a new walk state */
209
210    WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
211    if (!WalkState)
212    {
213        return;
214    }
215
216    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type,
217        WalkState);
218    if (ACPI_FAILURE (Status))
219    {
220        return;
221    }
222
223    Info.Flags = 0;
224    Info.Level = 0;
225    Info.WalkState = WalkState;
226
227    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmLoadDescendingOp,
228        AcpiDmCommonAscendingOp, &Info);
229    ACPI_FREE (WalkState);
230}
231
232
233/*******************************************************************************
234 *
235 * FUNCTION:    AcpiDmCrossReferenceNamespace
236 *
237 * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
238 *              NamespaceRoot       - Root of the internal namespace
239 *              OwnerId             - OwnerId of the table to be disassembled
240 *
241 * RETURN:      None
242 *
243 * DESCRIPTION: Cross reference the namespace to create externals
244 *
245 ******************************************************************************/
246
247void
248AcpiDmCrossReferenceNamespace (
249    ACPI_PARSE_OBJECT       *ParseTreeRoot,
250    ACPI_NAMESPACE_NODE     *NamespaceRoot,
251    ACPI_OWNER_ID           OwnerId)
252{
253    ACPI_STATUS             Status;
254    ACPI_OP_WALK_INFO       Info;
255    ACPI_WALK_STATE         *WalkState;
256
257
258    if (!ParseTreeRoot)
259    {
260        return;
261    }
262
263    /* Create and initialize a new walk state */
264
265    WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
266    if (!WalkState)
267    {
268        return;
269    }
270
271    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type,
272        WalkState);
273    if (ACPI_FAILURE (Status))
274    {
275        return;
276    }
277
278    Info.Flags = 0;
279    Info.Level = 0;
280    Info.WalkState = WalkState;
281
282    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmXrefDescendingOp,
283        AcpiDmCommonAscendingOp, &Info);
284    ACPI_FREE (WalkState);
285}
286
287
288/*******************************************************************************
289 *
290 * FUNCTION:    AcpiDmConvertResourceIndexes
291 *
292 * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
293 *              NamespaceRoot       - Root of the internal namespace
294 *
295 * RETURN:      None
296 *
297 * DESCRIPTION: Convert fixed-offset references to resource descriptors to
298 *              symbolic references. Should only be called after namespace has
299 *              been cross referenced.
300 *
301 ******************************************************************************/
302
303void
304AcpiDmConvertResourceIndexes (
305    ACPI_PARSE_OBJECT       *ParseTreeRoot,
306    ACPI_NAMESPACE_NODE     *NamespaceRoot)
307{
308    ACPI_STATUS             Status;
309    ACPI_OP_WALK_INFO       Info;
310    ACPI_WALK_STATE         *WalkState;
311
312
313    if (!ParseTreeRoot)
314    {
315        return;
316    }
317
318    /* Create and initialize a new walk state */
319
320    WalkState = AcpiDsCreateWalkState (0, ParseTreeRoot, NULL, NULL);
321    if (!WalkState)
322    {
323        return;
324    }
325
326    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type,
327        WalkState);
328    if (ACPI_FAILURE (Status))
329    {
330        ACPI_FREE (WalkState);
331        return;
332    }
333
334    Info.Flags = 0;
335    Info.Level = 0;
336    Info.WalkState = WalkState;
337
338    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmResourceDescendingOp,
339        AcpiDmCommonAscendingOp, &Info);
340    ACPI_FREE (WalkState);
341    return;
342}
343
344
345/*******************************************************************************
346 *
347 * FUNCTION:    AcpiDmDumpDescending
348 *
349 * PARAMETERS:  ASL_WALK_CALLBACK
350 *
351 * RETURN:      Status
352 *
353 * DESCRIPTION: Format and print contents of one parse Op.
354 *
355 ******************************************************************************/
356
357static ACPI_STATUS
358AcpiDmDumpDescending (
359    ACPI_PARSE_OBJECT       *Op,
360    UINT32                  Level,
361    void                    *Context)
362{
363    ACPI_OP_WALK_INFO       *Info = Context;
364    char                    *Path;
365
366
367    if (!Op)
368    {
369        return (AE_OK);
370    }
371
372    /* Most of the information (count, level, name) here */
373
374    Info->Count++;
375    AcpiOsPrintf ("% 5d [%2.2d] ", Info->Count, Level);
376    AcpiDmIndent (Level);
377    AcpiOsPrintf ("%-28s", AcpiPsGetOpcodeName (Op->Common.AmlOpcode));
378
379    /* Extra info is helpful */
380
381    switch (Op->Common.AmlOpcode)
382    {
383    case AML_BYTE_OP:
384
385        AcpiOsPrintf ("%2.2X", (UINT32) Op->Common.Value.Integer);
386        break;
387
388    case AML_WORD_OP:
389
390        AcpiOsPrintf ("%4.4X", (UINT32) Op->Common.Value.Integer);
391        break;
392
393    case AML_DWORD_OP:
394
395        AcpiOsPrintf ("%8.8X", (UINT32) Op->Common.Value.Integer);
396        break;
397
398    case AML_QWORD_OP:
399
400        AcpiOsPrintf ("%8.8X%8.8X", ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
401        break;
402
403    case AML_INT_NAMEPATH_OP:
404
405        if (Op->Common.Value.String)
406        {
407            AcpiNsExternalizeName (ACPI_UINT32_MAX, Op->Common.Value.String,
408                NULL, &Path);
409            AcpiOsPrintf ("%s %p", Path, Op->Common.Node);
410            ACPI_FREE (Path);
411        }
412        else
413        {
414            AcpiOsPrintf ("[NULL]");
415        }
416        break;
417
418    case AML_NAME_OP:
419    case AML_METHOD_OP:
420    case AML_DEVICE_OP:
421    case AML_INT_NAMEDFIELD_OP:
422
423        AcpiOsPrintf ("%4.4s", ACPI_CAST_PTR (char, &Op->Named.Name));
424        break;
425
426    default:
427
428        break;
429    }
430
431    AcpiOsPrintf ("\n");
432    return (AE_OK);
433}
434
435
436/*******************************************************************************
437 *
438 * FUNCTION:    AcpiDmFindOrphanDescending
439 *
440 * PARAMETERS:  ASL_WALK_CALLBACK
441 *
442 * RETURN:      Status
443 *
444 * DESCRIPTION: Check namepath Ops for orphaned method invocations
445 *
446 * Note: Parts of this are experimental, under possible further development.
447 *
448 ******************************************************************************/
449
450static ACPI_STATUS
451AcpiDmFindOrphanDescending (
452    ACPI_PARSE_OBJECT       *Op,
453    UINT32                  Level,
454    void                    *Context)
455{
456    const ACPI_OPCODE_INFO  *OpInfo;
457    ACPI_PARSE_OBJECT       *ChildOp;
458    ACPI_PARSE_OBJECT       *NextOp;
459    ACPI_PARSE_OBJECT       *ParentOp;
460    UINT32                  ArgCount;
461
462
463    if (!Op)
464    {
465        return (AE_OK);
466    }
467
468    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
469
470    switch (Op->Common.AmlOpcode)
471    {
472#ifdef ACPI_UNDER_DEVELOPMENT
473    case AML_ADD_OP:
474
475        ChildOp = Op->Common.Value.Arg;
476        if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
477            !ChildOp->Common.Node)
478        {
479            AcpiNsExternalizeName (ACPI_UINT32_MAX, ChildOp->Common.Value.String,
480                NULL, &Path);
481            AcpiOsPrintf ("/* %-16s A-NAMEPATH: %s  */\n",
482                Op->Common.AmlOpName, Path);
483            ACPI_FREE (Path);
484
485            NextOp = Op->Common.Next;
486            if (!NextOp)
487            {
488                /* This NamePath has no args, assume it is an integer */
489
490                AcpiDmAddOpToExternalList (ChildOp,
491                    ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
492                return (AE_OK);
493            }
494
495            ArgCount = AcpiDmInspectPossibleArgs (3, 1, NextOp);
496            AcpiOsPrintf ("/* A-CHILDREN: %u Actual %u */\n",
497                ArgCount, AcpiDmCountChildren (Op));
498
499            if (ArgCount < 1)
500            {
501                /* One Arg means this is just a Store(Name,Target) */
502
503                AcpiDmAddOpToExternalList (ChildOp,
504                    ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
505                return (AE_OK);
506            }
507
508            AcpiDmAddOpToExternalList (ChildOp,
509                ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
510        }
511        break;
512
513#endif
514
515    case AML_STORE_OP:
516
517        ChildOp = Op->Common.Value.Arg;
518        if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
519            !ChildOp->Common.Node)
520        {
521            NextOp = Op->Common.Next;
522            if (!NextOp)
523            {
524                /* This NamePath has no args, assume it is an integer */
525
526                AcpiDmAddOpToExternalList (ChildOp,
527                    ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
528                return (AE_OK);
529            }
530
531            ArgCount = AcpiDmInspectPossibleArgs (2, 1, NextOp);
532            if (ArgCount <= 1)
533            {
534                /* One Arg means this is just a Store(Name,Target) */
535
536                AcpiDmAddOpToExternalList (ChildOp,
537                    ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, ArgCount, 0);
538                return (AE_OK);
539            }
540
541            AcpiDmAddOpToExternalList (ChildOp,
542                ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
543        }
544        break;
545
546    case AML_INT_NAMEPATH_OP:
547
548        /* Must examine parent to see if this namepath is an argument */
549
550        ParentOp = Op->Common.Parent;
551        OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
552
553        if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
554            (OpInfo->Class != AML_CLASS_CREATE) &&
555            (OpInfo->ObjectType != ACPI_TYPE_LOCAL_ALIAS) &&
556            (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
557            !Op->Common.Node)
558        {
559            ArgCount = AcpiDmInspectPossibleArgs (0, 0, Op);
560
561            /*
562             * Check if namepath is a predicate for if/while or lone parameter to
563             * a return.
564             */
565            if (ArgCount == 0)
566            {
567                if (((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
568                     (ParentOp->Common.AmlOpcode == AML_WHILE_OP) ||
569                     (ParentOp->Common.AmlOpcode == AML_RETURN_OP)) &&
570
571                     /* And namepath is the first argument */
572                     (ParentOp->Common.Value.Arg == Op))
573                {
574                    AcpiDmAddOpToExternalList (Op,
575                        Op->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
576                    break;
577                }
578            }
579
580            /*
581             * This is a standalone namestring (not a parameter to another
582             * operator) - it *must* be a method invocation, nothing else is
583             * grammatically possible.
584             */
585            AcpiDmAddOpToExternalList (Op,
586                Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
587        }
588        break;
589
590    default:
591
592        break;
593    }
594
595    return (AE_OK);
596}
597
598
599/*******************************************************************************
600 *
601 * FUNCTION:    AcpiDmLoadDescendingOp
602 *
603 * PARAMETERS:  ASL_WALK_CALLBACK
604 *
605 * RETURN:      Status
606 *
607 * DESCRIPTION: Descending handler for namespace control method object load
608 *
609 ******************************************************************************/
610
611static ACPI_STATUS
612AcpiDmLoadDescendingOp (
613    ACPI_PARSE_OBJECT       *Op,
614    UINT32                  Level,
615    void                    *Context)
616{
617    ACPI_OP_WALK_INFO       *Info = Context;
618    const ACPI_OPCODE_INFO  *OpInfo;
619    ACPI_WALK_STATE         *WalkState;
620    ACPI_OBJECT_TYPE        ObjectType;
621    ACPI_STATUS             Status;
622    char                    *Path = NULL;
623    ACPI_PARSE_OBJECT       *NextOp;
624    ACPI_NAMESPACE_NODE     *Node;
625    char                    FieldPath[5];
626    BOOLEAN                 PreDefined = FALSE;
627    UINT8                   PreDefineIndex = 0;
628
629
630    WalkState = Info->WalkState;
631    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
632    ObjectType = OpInfo->ObjectType;
633    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
634
635    /* Only interested in operators that create new names */
636
637    if (!(OpInfo->Flags & AML_NAMED) &&
638        !(OpInfo->Flags & AML_CREATE))
639    {
640        goto Exit;
641    }
642
643    /* Get the NamePath from the appropriate place */
644
645    if (OpInfo->Flags & AML_NAMED)
646    {
647        /* For all named operators, get the new name */
648
649        Path = (char *) Op->Named.Path;
650
651        if (!Path && Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
652        {
653            *ACPI_CAST_PTR (UINT32, &FieldPath[0]) = Op->Named.Name;
654            FieldPath[4] = 0;
655            Path = FieldPath;
656        }
657    }
658    else if (OpInfo->Flags & AML_CREATE)
659    {
660        /* New name is the last child */
661
662        NextOp = Op->Common.Value.Arg;
663
664        while (NextOp->Common.Next)
665        {
666            NextOp = NextOp->Common.Next;
667        }
668
669        Path = NextOp->Common.Value.String;
670    }
671
672    if (!Path)
673    {
674        goto Exit;
675    }
676
677    /* Insert the name into the namespace */
678
679    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
680        ACPI_IMODE_LOAD_PASS2, ACPI_NS_DONT_OPEN_SCOPE,
681        WalkState, &Node);
682
683    Op->Common.Node = Node;
684
685    if (ACPI_SUCCESS (Status))
686    {
687        /* Check if it's a predefined node */
688
689        while (AcpiGbl_PreDefinedNames[PreDefineIndex].Name)
690        {
691            if (ACPI_COMPARE_NAME (Node->Name.Ascii,
692                AcpiGbl_PreDefinedNames[PreDefineIndex].Name))
693            {
694                PreDefined = TRUE;
695                break;
696            }
697
698            PreDefineIndex++;
699        }
700
701        /*
702         * Set node owner id if it satisfies all the following conditions:
703         * 1) Not a predefined node, _SB_ etc
704         * 2) Not the root node
705         * 3) Not a node created by Scope
706         */
707
708        if (!PreDefined && Node != AcpiGbl_RootNode &&
709            Op->Common.AmlOpcode != AML_SCOPE_OP)
710        {
711            Node->OwnerId = WalkState->OwnerId;
712        }
713    }
714
715
716Exit:
717
718    if (AcpiNsOpensScope (ObjectType))
719    {
720        if (Op->Common.Node)
721        {
722            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
723                WalkState);
724            if (ACPI_FAILURE (Status))
725            {
726                return (Status);
727            }
728        }
729    }
730
731    return (AE_OK);
732}
733
734
735/*******************************************************************************
736 *
737 * FUNCTION:    AcpiDmXrefDescendingOp
738 *
739 * PARAMETERS:  ASL_WALK_CALLBACK
740 *
741 * RETURN:      Status
742 *
743 * DESCRIPTION: Descending handler for namespace cross reference
744 *
745 ******************************************************************************/
746
747static ACPI_STATUS
748AcpiDmXrefDescendingOp (
749    ACPI_PARSE_OBJECT       *Op,
750    UINT32                  Level,
751    void                    *Context)
752{
753    ACPI_OP_WALK_INFO       *Info = Context;
754    const ACPI_OPCODE_INFO  *OpInfo;
755    ACPI_WALK_STATE         *WalkState;
756    ACPI_OBJECT_TYPE        ObjectType;
757    ACPI_OBJECT_TYPE        ObjectType2;
758    ACPI_STATUS             Status;
759    char                    *Path = NULL;
760    ACPI_PARSE_OBJECT       *NextOp;
761    ACPI_NAMESPACE_NODE     *Node;
762    ACPI_OPERAND_OBJECT     *Object;
763    UINT32                  ParamCount = 0;
764    char                    *Pathname;
765    UINT16                  Flags = 0;
766
767
768    WalkState = Info->WalkState;
769    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
770    ObjectType = OpInfo->ObjectType;
771    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
772
773    if ((!(OpInfo->Flags & AML_NAMED)) &&
774        (!(OpInfo->Flags & AML_CREATE)) &&
775        (Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP) &&
776        (Op->Common.AmlOpcode != AML_NOTIFY_OP))
777    {
778        goto Exit;
779    }
780    else if (Op->Common.Parent &&
781             Op->Common.Parent->Common.AmlOpcode == AML_EXTERNAL_OP)
782    {
783        /* External() NamePath */
784
785        Path = Op->Common.Value.String;
786        ObjectType = (ACPI_OBJECT_TYPE) Op->Common.Next->Common.Value.Integer;
787        if (ObjectType == ACPI_TYPE_METHOD)
788        {
789            ParamCount = (UINT32)
790                Op->Common.Next->Common.Next->Common.Value.Integer;
791        }
792
793        Flags |= ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_OPCODE;
794        AcpiDmAddOpToExternalList (Op, Path,
795            (UINT8) ObjectType, ParamCount, Flags);
796
797        goto Exit;
798    }
799
800    /* Get the NamePath from the appropriate place */
801
802    if (OpInfo->Flags & AML_NAMED)
803    {
804        /*
805         * Only these two operators (Alias, Scope) refer to an existing
806         * name, it is the first argument
807         */
808        if (Op->Common.AmlOpcode == AML_ALIAS_OP)
809        {
810            ObjectType = ACPI_TYPE_ANY;
811
812            NextOp = Op->Common.Value.Arg;
813            NextOp = NextOp->Common.Value.Arg;
814            if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
815            {
816                Path = NextOp->Common.Value.String;
817            }
818        }
819        else if (Op->Common.AmlOpcode == AML_SCOPE_OP)
820        {
821            Path = (char *) Op->Named.Path;
822        }
823    }
824    else if (OpInfo->Flags & AML_CREATE)
825    {
826        /* Referenced Buffer Name is the first child */
827
828        ObjectType = ACPI_TYPE_BUFFER; /* Change from TYPE_BUFFER_FIELD */
829
830        NextOp = Op->Common.Value.Arg;
831        if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
832        {
833            Path = NextOp->Common.Value.String;
834        }
835    }
836    else if (Op->Common.AmlOpcode == AML_NOTIFY_OP)
837    {
838        Path = Op->Common.Value.Arg->Asl.Value.String;
839    }
840    else
841    {
842        Path = Op->Common.Value.String;
843    }
844
845    if (!Path)
846    {
847        goto Exit;
848    }
849
850    /*
851     * Lookup the name in the namespace. Name must exist at this point, or it
852     * is an invalid reference.
853     *
854     * The namespace is also used as a lookup table for references to resource
855     * descriptors and the fields within them.
856     */
857    Node = NULL;
858    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
859        ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
860        WalkState, &Node);
861
862    if (ACPI_SUCCESS (Status) && (Node->Flags & ANOBJ_IS_EXTERNAL))
863    {
864        /* Node was created by an External() statement */
865
866        Status = AE_NOT_FOUND;
867    }
868
869    if (ACPI_FAILURE (Status))
870    {
871        if (Status == AE_NOT_FOUND)
872        {
873            /*
874             * Add this symbol as an external declaration, except if the
875             * parent is a CondRefOf operator. For this operator, we do not
876             * need an external, nor do we want one, since this can cause
877             * disassembly problems if the symbol is actually a control
878             * method.
879             */
880            if (!(Op->Asl.Parent &&
881                (Op->Asl.Parent->Asl.AmlOpcode == AML_COND_REF_OF_OP)))
882            {
883                if (Node)
884                {
885                    AcpiDmAddNodeToExternalList (Node,
886                        (UINT8) ObjectType, 7, Flags);
887                }
888                else
889                {
890                    AcpiDmAddOpToExternalList (Op, Path,
891                        (UINT8) ObjectType, 7, Flags);
892                }
893            }
894        }
895    }
896
897    /*
898     * Found the node, but check if it came from an external table.
899     * Add it to external list. Note: Node->OwnerId == 0 indicates
900     * one of the built-in ACPI Names (_OS_ etc.) which can safely
901     * be ignored.
902     */
903    else if (Node->OwnerId &&
904            (WalkState->OwnerId != Node->OwnerId))
905    {
906        ObjectType2 = ObjectType;
907
908        Object = AcpiNsGetAttachedObject (Node);
909        if (Object)
910        {
911            ObjectType2 = Object->Common.Type;
912            if (ObjectType2 == ACPI_TYPE_METHOD)
913            {
914                ParamCount = Object->Method.ParamCount;
915            }
916        }
917
918        Pathname = AcpiNsGetExternalPathname (Node);
919        if (!Pathname)
920        {
921            return (AE_NO_MEMORY);
922        }
923
924        AcpiDmAddNodeToExternalList (Node, (UINT8) ObjectType2,
925            ParamCount, ACPI_EXT_RESOLVED_REFERENCE);
926
927        ACPI_FREE (Pathname);
928        Op->Common.Node = Node;
929    }
930    else
931    {
932        Op->Common.Node = Node;
933    }
934
935
936Exit:
937    /* Open new scope if necessary */
938
939    if (AcpiNsOpensScope (ObjectType))
940    {
941        if (Op->Common.Node)
942        {
943            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
944                WalkState);
945            if (ACPI_FAILURE (Status))
946            {
947                return (Status);
948            }
949        }
950    }
951
952    return (AE_OK);
953}
954
955
956/*******************************************************************************
957 *
958 * FUNCTION:    AcpiDmResourceDescendingOp
959 *
960 * PARAMETERS:  ASL_WALK_CALLBACK
961 *
962 * RETURN:      None
963 *
964 * DESCRIPTION: Process one parse op during symbolic resource index conversion.
965 *
966 ******************************************************************************/
967
968static ACPI_STATUS
969AcpiDmResourceDescendingOp (
970    ACPI_PARSE_OBJECT       *Op,
971    UINT32                  Level,
972    void                    *Context)
973{
974    ACPI_OP_WALK_INFO       *Info = Context;
975    const ACPI_OPCODE_INFO  *OpInfo;
976    ACPI_WALK_STATE         *WalkState;
977    ACPI_OBJECT_TYPE        ObjectType;
978    ACPI_STATUS             Status;
979
980
981    WalkState = Info->WalkState;
982    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
983
984    /* Open new scope if necessary */
985
986    ObjectType = OpInfo->ObjectType;
987    if (AcpiNsOpensScope (ObjectType))
988    {
989        if (Op->Common.Node)
990        {
991
992            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
993                WalkState);
994            if (ACPI_FAILURE (Status))
995            {
996                return (Status);
997            }
998        }
999    }
1000
1001    /*
1002     * Check if this operator contains a reference to a resource descriptor.
1003     * If so, convert the reference into a symbolic reference.
1004     */
1005    AcpiDmCheckResourceReference (Op, WalkState);
1006    return (AE_OK);
1007}
1008
1009
1010/*******************************************************************************
1011 *
1012 * FUNCTION:    AcpiDmCommonAscendingOp
1013 *
1014 * PARAMETERS:  ASL_WALK_CALLBACK
1015 *
1016 * RETURN:      None
1017 *
1018 * DESCRIPTION: Ascending handler for combined parse/namespace walks. Closes
1019 *              scope if necessary.
1020 *
1021 ******************************************************************************/
1022
1023static ACPI_STATUS
1024AcpiDmCommonAscendingOp (
1025    ACPI_PARSE_OBJECT       *Op,
1026    UINT32                  Level,
1027    void                    *Context)
1028{
1029    ACPI_OP_WALK_INFO       *Info = Context;
1030    const ACPI_OPCODE_INFO  *OpInfo;
1031    ACPI_OBJECT_TYPE        ObjectType;
1032
1033
1034    /* Close scope if necessary */
1035
1036    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1037    ObjectType = OpInfo->ObjectType;
1038    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
1039
1040    if (AcpiNsOpensScope (ObjectType))
1041    {
1042        (void) AcpiDsScopeStackPop (Info->WalkState);
1043    }
1044
1045    return (AE_OK);
1046}
1047
1048
1049/*******************************************************************************
1050 *
1051 * FUNCTION:    AcpiDmInspectPossibleArgs
1052 *
1053 * PARAMETERS:  CurrentOpArgCount   - Which arg of the current op was the
1054 *                                    possible method invocation found
1055 *              TargetCount         - Number of targets (0,1,2) for this op
1056 *              Op                  - Parse op
1057 *
1058 * RETURN:      Status
1059 *
1060 * DESCRIPTION: Examine following args and next ops for possible arguments
1061 *              for an unrecognized method invocation.
1062 *
1063 ******************************************************************************/
1064
1065static UINT32
1066AcpiDmInspectPossibleArgs (
1067    UINT32                  CurrentOpArgCount,
1068    UINT32                  TargetCount,
1069    ACPI_PARSE_OBJECT       *Op)
1070{
1071    const ACPI_OPCODE_INFO  *OpInfo;
1072    UINT32                  i;
1073    UINT32                  ArgumentCount = 0;
1074    ACPI_PARSE_OBJECT       *NextOp;
1075    ACPI_PARSE_OBJECT       *ExecuteOp;
1076
1077
1078    if (!Op)
1079    {
1080        return (0);
1081    }
1082
1083    /* Lookahead for the maximum number of possible arguments */
1084
1085    NextOp = Op->Common.Next;
1086
1087    for (i = 0; (i < ACPI_METHOD_NUM_ARGS) && NextOp; i++)
1088    {
1089        OpInfo = AcpiPsGetOpcodeInfo (NextOp->Common.AmlOpcode);
1090
1091        /* Any one of these operators is "very probably" not a method arg */
1092
1093        if ((NextOp->Common.AmlOpcode == AML_STORE_OP) ||
1094            (NextOp->Common.AmlOpcode == AML_NOTIFY_OP) ||
1095            (OpInfo->Class == AML_CLASS_CONTROL) ||
1096            (OpInfo->Class == AML_CLASS_CREATE) ||
1097            (OpInfo->Class == AML_CLASS_NAMED_OBJECT))
1098        {
1099            break;
1100        }
1101
1102        if (OpInfo->Class == AML_CLASS_EXECUTE)
1103        {
1104            /* Probable that this is method arg if there is no target */
1105
1106            ExecuteOp = NextOp->Common.Value.Arg;
1107            while (ExecuteOp)
1108            {
1109                if ((ExecuteOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
1110                    (ExecuteOp->Common.Value.Arg == NULL))
1111                {
1112                    /* No target, could be a method arg */
1113
1114                    break;
1115                }
1116
1117                if (NextOp->Common.AmlOpcode == AML_REF_OF_OP)
1118                {
1119                    break;
1120                }
1121
1122                ExecuteOp = ExecuteOp->Common.Next;
1123            }
1124
1125            if (!ExecuteOp)
1126            {
1127                /* Has a target, not method arg */
1128
1129                return (ArgumentCount);
1130            }
1131        }
1132
1133        ArgumentCount++;
1134        NextOp = NextOp->Common.Next;
1135    }
1136
1137    return (ArgumentCount);
1138}
1139