adwalk.c revision 235945
1275970Scy/******************************************************************************
2275970Scy *
3275970Scy * Module Name: adwalk - Application-level disassembler parse tree walk routines
4275970Scy *
5275970Scy *****************************************************************************/
6275970Scy
7275970Scy/*
8275970Scy * Copyright (C) 2000 - 2012, Intel Corp.
9275970Scy * All rights reserved.
10275970Scy *
11275970Scy * Redistribution and use in source and binary forms, with or without
12275970Scy * modification, are permitted provided that the following conditions
13275970Scy * are met:
14275970Scy * 1. Redistributions of source code must retain the above copyright
15275970Scy *    notice, this list of conditions, and the following disclaimer,
16275970Scy *    without modification.
17275970Scy * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18275970Scy *    substantially similar to the "NO WARRANTY" disclaimer below
19275970Scy *    ("Disclaimer") and any redistribution must be conditioned upon
20275970Scy *    including a substantially similar Disclaimer requirement for further
21275970Scy *    binary redistribution.
22275970Scy * 3. Neither the names of the above-listed copyright holders nor the names
23275970Scy *    of any contributors may be used to endorse or promote products derived
24275970Scy *    from this software without specific prior written permission.
25275970Scy *
26275970Scy * Alternatively, this software may be distributed under the terms of the
27275970Scy * GNU General Public License ("GPL") version 2 as published by the Free
28275970Scy * Software Foundation.
29275970Scy *
30275970Scy * NO WARRANTY
31275970Scy * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32275970Scy * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33275970Scy * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34275970Scy * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35275970Scy * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36275970Scy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37275970Scy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38275970Scy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39275970Scy * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40275970Scy * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41275970Scy * POSSIBILITY OF SUCH DAMAGES.
42275970Scy */
43275970Scy
44275970Scy
45275970Scy#include <contrib/dev/acpica/include/acpi.h>
46275970Scy#include <contrib/dev/acpica/include/accommon.h>
47275970Scy#include <contrib/dev/acpica/include/acparser.h>
48275970Scy#include <contrib/dev/acpica/include/amlcode.h>
49275970Scy#include <contrib/dev/acpica/include/acdisasm.h>
50275970Scy#include <contrib/dev/acpica/include/acdispat.h>
51275970Scy#include <contrib/dev/acpica/include/acnamesp.h>
52275970Scy#include <contrib/dev/acpica/include/acapps.h>
53275970Scy
54275970Scy
55275970Scy#define _COMPONENT          ACPI_TOOLS
56275970Scy        ACPI_MODULE_NAME    ("adwalk")
57275970Scy
58275970Scy/*
59275970Scy * aslmap - opcode mappings and reserved method names
60275970Scy */
61275970ScyACPI_OBJECT_TYPE
62275970ScyAslMapNamedOpcodeToDataType (
63275970Scy    UINT16                  Opcode);
64275970Scy
65275970Scy/* Local prototypes */
66275970Scy
67275970Scystatic ACPI_STATUS
68275970ScyAcpiDmFindOrphanDescending (
69275970Scy    ACPI_PARSE_OBJECT       *Op,
70275970Scy    UINT32                  Level,
71275970Scy    void                    *Context);
72275970Scy
73275970Scystatic ACPI_STATUS
74275970ScyAcpiDmDumpDescending (
75275970Scy    ACPI_PARSE_OBJECT       *Op,
76275970Scy    UINT32                  Level,
77275970Scy    void                    *Context);
78275970Scy
79275970Scystatic ACPI_STATUS
80275970ScyAcpiDmXrefDescendingOp (
81275970Scy    ACPI_PARSE_OBJECT       *Op,
82275970Scy    UINT32                  Level,
83275970Scy    void                    *Context);
84275970Scy
85275970Scystatic ACPI_STATUS
86275970ScyAcpiDmCommonAscendingOp (
87275970Scy    ACPI_PARSE_OBJECT       *Op,
88275970Scy    UINT32                  Level,
89275970Scy    void                    *Context);
90275970Scy
91275970Scystatic ACPI_STATUS
92275970ScyAcpiDmLoadDescendingOp (
93275970Scy    ACPI_PARSE_OBJECT       *Op,
94275970Scy    UINT32                  Level,
95275970Scy    void                    *Context);
96275970Scy
97275970Scystatic UINT32
98275970ScyAcpiDmInspectPossibleArgs (
99275970Scy    UINT32                  CurrentOpArgCount,
100275970Scy    UINT32                  TargetCount,
101275970Scy    ACPI_PARSE_OBJECT       *Op);
102275970Scy
103275970Scystatic ACPI_STATUS
104275970ScyAcpiDmResourceDescendingOp (
105275970Scy    ACPI_PARSE_OBJECT       *Op,
106275970Scy    UINT32                  Level,
107275970Scy    void                    *Context);
108275970Scy
109275970Scy
110275970Scy/*******************************************************************************
111275970Scy *
112275970Scy * FUNCTION:    AcpiDmDumpTree
113275970Scy *
114275970Scy * PARAMETERS:  Origin              - Starting object
115275970Scy *
116275970Scy * RETURN:      None
117275970Scy *
118275970Scy * DESCRIPTION: Parse tree walk to format and output the nodes
119275970Scy *
120275970Scy ******************************************************************************/
121275970Scy
122275970Scyvoid
123275970ScyAcpiDmDumpTree (
124275970Scy    ACPI_PARSE_OBJECT       *Origin)
125275970Scy{
126275970Scy    ACPI_OP_WALK_INFO       Info;
127275970Scy
128275970Scy
129275970Scy    if (!Origin)
130275970Scy    {
131275970Scy        return;
132275970Scy    }
133275970Scy
134275970Scy    AcpiOsPrintf ("/*\nAML Parse Tree\n\n");
135275970Scy    Info.Flags = 0;
136275970Scy    Info.Count = 0;
137275970Scy    Info.Level = 0;
138275970Scy    Info.WalkState = NULL;
139275970Scy    AcpiDmWalkParseTree (Origin, AcpiDmDumpDescending, NULL, &Info);
140275970Scy    AcpiOsPrintf ("*/\n\n");
141275970Scy}
142275970Scy
143275970Scy
144275970Scy/*******************************************************************************
145275970Scy *
146275970Scy * FUNCTION:    AcpiDmFindOrphanMethods
147275970Scy *
148275970Scy * PARAMETERS:  Origin              - Starting object
149275970Scy *
150275970Scy * RETURN:      None
151275970Scy *
152275970Scy * DESCRIPTION: Parse tree walk to find "orphaned" method invocations -- methods
153275970Scy *              that are not resolved in the namespace
154275970Scy *
155275970Scy ******************************************************************************/
156275970Scy
157275970Scyvoid
158275970ScyAcpiDmFindOrphanMethods (
159275970Scy    ACPI_PARSE_OBJECT       *Origin)
160275970Scy{
161275970Scy    ACPI_OP_WALK_INFO       Info;
162275970Scy
163275970Scy
164275970Scy    if (!Origin)
165275970Scy    {
166275970Scy        return;
167275970Scy    }
168275970Scy
169275970Scy    Info.Flags = 0;
170275970Scy    Info.Level = 0;
171275970Scy    Info.WalkState = NULL;
172275970Scy    AcpiDmWalkParseTree (Origin, AcpiDmFindOrphanDescending, NULL, &Info);
173275970Scy}
174275970Scy
175275970Scy
176275970Scy/*******************************************************************************
177275970Scy *
178275970Scy * FUNCTION:    AcpiDmFinishNamespaceLoad
179275970Scy *
180275970Scy * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
181275970Scy *              NamespaceRoot       - Root of the internal namespace
182275970Scy *              OwnerId             - OwnerId of the table to be disassembled
183275970Scy *
184275970Scy * RETURN:      None
185275970Scy *
186275970Scy * DESCRIPTION: Load all namespace items that are created within control
187275970Scy *              methods. Used before namespace cross reference
188275970Scy *
189275970Scy ******************************************************************************/
190275970Scy
191275970Scyvoid
192275970ScyAcpiDmFinishNamespaceLoad (
193275970Scy    ACPI_PARSE_OBJECT       *ParseTreeRoot,
194275970Scy    ACPI_NAMESPACE_NODE     *NamespaceRoot,
195275970Scy    ACPI_OWNER_ID           OwnerId)
196275970Scy{
197275970Scy    ACPI_STATUS             Status;
198275970Scy    ACPI_OP_WALK_INFO       Info;
199275970Scy    ACPI_WALK_STATE         *WalkState;
200275970Scy
201275970Scy
202275970Scy    if (!ParseTreeRoot)
203275970Scy    {
204275970Scy        return;
205275970Scy    }
206275970Scy
207275970Scy    /* Create and initialize a new walk state */
208275970Scy
209275970Scy    WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
210275970Scy    if (!WalkState)
211275970Scy    {
212275970Scy        return;
213275970Scy    }
214275970Scy
215275970Scy    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState);
216275970Scy    if (ACPI_FAILURE (Status))
217275970Scy    {
218275970Scy        return;
219275970Scy    }
220275970Scy
221275970Scy    Info.Flags = 0;
222275970Scy    Info.Level = 0;
223275970Scy    Info.WalkState = WalkState;
224275970Scy    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmLoadDescendingOp,
225275970Scy        AcpiDmCommonAscendingOp, &Info);
226275970Scy    ACPI_FREE (WalkState);
227275970Scy}
228275970Scy
229275970Scy
230275970Scy/*******************************************************************************
231275970Scy *
232275970Scy * FUNCTION:    AcpiDmCrossReferenceNamespace
233275970Scy *
234275970Scy * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
235275970Scy *              NamespaceRoot       - Root of the internal namespace
236275970Scy *              OwnerId             - OwnerId of the table to be disassembled
237275970Scy *
238275970Scy * RETURN:      None
239275970Scy *
240275970Scy * DESCRIPTION: Cross reference the namespace to create externals
241275970Scy *
242275970Scy ******************************************************************************/
243275970Scy
244275970Scyvoid
245275970ScyAcpiDmCrossReferenceNamespace (
246275970Scy    ACPI_PARSE_OBJECT       *ParseTreeRoot,
247275970Scy    ACPI_NAMESPACE_NODE     *NamespaceRoot,
248275970Scy    ACPI_OWNER_ID           OwnerId)
249275970Scy{
250275970Scy    ACPI_STATUS             Status;
251275970Scy    ACPI_OP_WALK_INFO       Info;
252275970Scy    ACPI_WALK_STATE         *WalkState;
253275970Scy
254275970Scy
255275970Scy    if (!ParseTreeRoot)
256275970Scy    {
257275970Scy        return;
258275970Scy    }
259275970Scy
260275970Scy    /* Create and initialize a new walk state */
261275970Scy
262275970Scy    WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
263275970Scy    if (!WalkState)
264275970Scy    {
265275970Scy        return;
266275970Scy    }
267275970Scy
268275970Scy    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState);
269275970Scy    if (ACPI_FAILURE (Status))
270275970Scy    {
271275970Scy        return;
272275970Scy    }
273275970Scy
274275970Scy    Info.Flags = 0;
275275970Scy    Info.Level = 0;
276275970Scy    Info.WalkState = WalkState;
277275970Scy    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmXrefDescendingOp,
278275970Scy        AcpiDmCommonAscendingOp, &Info);
279275970Scy    ACPI_FREE (WalkState);
280275970Scy}
281275970Scy
282275970Scy
283275970Scy/*******************************************************************************
284275970Scy *
285275970Scy * FUNCTION:    AcpiDmConvertResourceIndexes
286275970Scy *
287275970Scy * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
288275970Scy *              NamespaceRoot       - Root of the internal namespace
289275970Scy *
290275970Scy * RETURN:      None
291275970Scy *
292275970Scy * DESCRIPTION: Convert fixed-offset references to resource descriptors to
293275970Scy *              symbolic references. Should only be called after namespace has
294275970Scy *              been cross referenced.
295275970Scy *
296275970Scy ******************************************************************************/
297275970Scy
298275970Scyvoid
299275970ScyAcpiDmConvertResourceIndexes (
300275970Scy    ACPI_PARSE_OBJECT       *ParseTreeRoot,
301275970Scy    ACPI_NAMESPACE_NODE     *NamespaceRoot)
302275970Scy{
303275970Scy    ACPI_STATUS             Status;
304275970Scy    ACPI_OP_WALK_INFO       Info;
305275970Scy    ACPI_WALK_STATE         *WalkState;
306275970Scy
307275970Scy
308275970Scy    if (!ParseTreeRoot)
309275970Scy    {
310275970Scy        return;
311275970Scy    }
312275970Scy
313275970Scy    /* Create and initialize a new walk state */
314275970Scy
315275970Scy    WalkState = AcpiDsCreateWalkState (0, ParseTreeRoot, NULL, NULL);
316275970Scy    if (!WalkState)
317275970Scy    {
318275970Scy        return;
319275970Scy    }
320275970Scy
321275970Scy    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState);
322275970Scy    if (ACPI_FAILURE (Status))
323275970Scy    {
324275970Scy        return;
325275970Scy    }
326275970Scy
327275970Scy    Info.Flags = 0;
328275970Scy    Info.Level = 0;
329275970Scy    Info.WalkState = WalkState;
330275970Scy    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmResourceDescendingOp,
331275970Scy        AcpiDmCommonAscendingOp, &Info);
332275970Scy    ACPI_FREE (WalkState);
333275970Scy    return;
334275970Scy}
335275970Scy
336275970Scy
337275970Scy/*******************************************************************************
338275970Scy *
339275970Scy * FUNCTION:    AcpiDmDumpDescending
340275970Scy *
341275970Scy * PARAMETERS:  ASL_WALK_CALLBACK
342275970Scy *
343275970Scy * RETURN:      Status
344275970Scy *
345275970Scy * DESCRIPTION: Format and print contents of one parse Op.
346275970Scy *
347275970Scy ******************************************************************************/
348275970Scy
349275970Scystatic ACPI_STATUS
350275970ScyAcpiDmDumpDescending (
351275970Scy    ACPI_PARSE_OBJECT       *Op,
352275970Scy    UINT32                  Level,
353275970Scy    void                    *Context)
354275970Scy{
355275970Scy    ACPI_OP_WALK_INFO       *Info = Context;
356275970Scy    char                    *Path;
357275970Scy
358275970Scy
359275970Scy    if (!Op)
360275970Scy    {
361275970Scy        return (AE_OK);
362275970Scy    }
363275970Scy
364275970Scy    /* Most of the information (count, level, name) here */
365275970Scy
366275970Scy    Info->Count++;
367275970Scy    AcpiOsPrintf ("% 5d [%2.2d] ", Info->Count, Level);
368275970Scy    AcpiDmIndent (Level);
369275970Scy    AcpiOsPrintf ("%-28s", AcpiPsGetOpcodeName (Op->Common.AmlOpcode));
370275970Scy
371275970Scy    /* Extra info is helpful */
372275970Scy
373275970Scy    switch (Op->Common.AmlOpcode)
374275970Scy    {
375275970Scy    case AML_BYTE_OP:
376275970Scy    case AML_WORD_OP:
377275970Scy    case AML_DWORD_OP:
378275970Scy        AcpiOsPrintf ("%X", (UINT32) Op->Common.Value.Integer);
379275970Scy        break;
380275970Scy
381275970Scy    case AML_QWORD_OP:
382275970Scy        AcpiOsPrintf ("%8.8X%8.8X", ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
383275970Scy        break;
384275970Scy
385275970Scy    case AML_INT_NAMEPATH_OP:
386275970Scy        if (Op->Common.Value.String)
387275970Scy        {
388275970Scy            AcpiNsExternalizeName (ACPI_UINT32_MAX, Op->Common.Value.String,
389275970Scy                            NULL, &Path);
390275970Scy            AcpiOsPrintf ("%s %p", Path, Op->Common.Node);
391275970Scy            ACPI_FREE (Path);
392275970Scy        }
393275970Scy        else
394275970Scy        {
395275970Scy            AcpiOsPrintf ("[NULL]");
396275970Scy        }
397275970Scy        break;
398275970Scy
399275970Scy    case AML_NAME_OP:
400275970Scy    case AML_METHOD_OP:
401275970Scy    case AML_DEVICE_OP:
402275970Scy    case AML_INT_NAMEDFIELD_OP:
403275970Scy        AcpiOsPrintf ("%4.4s", ACPI_CAST_PTR (char, &Op->Named.Name));
404275970Scy        break;
405275970Scy
406275970Scy    default:
407275970Scy        break;
408275970Scy    }
409275970Scy
410275970Scy    AcpiOsPrintf ("\n");
411275970Scy    return (AE_OK);
412275970Scy}
413275970Scy
414275970Scy
415275970Scy/*******************************************************************************
416275970Scy *
417275970Scy * FUNCTION:    AcpiDmFindOrphanDescending
418275970Scy *
419275970Scy * PARAMETERS:  ASL_WALK_CALLBACK
420275970Scy *
421275970Scy * RETURN:      Status
422275970Scy *
423275970Scy * DESCRIPTION: Check namepath Ops for orphaned method invocations
424275970Scy *
425275970Scy * Note: Experimental.
426275970Scy *
427275970Scy ******************************************************************************/
428275970Scy
429275970Scystatic ACPI_STATUS
430275970ScyAcpiDmFindOrphanDescending (
431275970Scy    ACPI_PARSE_OBJECT       *Op,
432275970Scy    UINT32                  Level,
433275970Scy    void                    *Context)
434275970Scy{
435275970Scy    const ACPI_OPCODE_INFO  *OpInfo;
436275970Scy    ACPI_PARSE_OBJECT       *ChildOp;
437275970Scy    ACPI_PARSE_OBJECT       *NextOp;
438275970Scy    ACPI_PARSE_OBJECT       *ParentOp;
439275970Scy    UINT32                  ArgCount;
440275970Scy
441275970Scy
442275970Scy    if (!Op)
443275970Scy    {
444275970Scy        return (AE_OK);
445275970Scy    }
446275970Scy
447275970Scy    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
448275970Scy
449275970Scy    switch (Op->Common.AmlOpcode)
450275970Scy    {
451275970Scy#ifdef ACPI_UNDER_DEVELOPMENT
452275970Scy    case AML_ADD_OP:
453275970Scy        ChildOp = Op->Common.Value.Arg;
454275970Scy        if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
455275970Scy            !ChildOp->Common.Node)
456275970Scy        {
457275970Scy            AcpiNsExternalizeName (ACPI_UINT32_MAX, ChildOp->Common.Value.String,
458275970Scy                            NULL, &Path);
459275970Scy            AcpiOsPrintf ("/* %-16s A-NAMEPATH: %s  */\n", Op->Common.AmlOpName, Path);
460275970Scy            ACPI_FREE (Path);
461275970Scy
462275970Scy            NextOp = Op->Common.Next;
463275970Scy            if (!NextOp)
464275970Scy            {
465275970Scy                /* This NamePath has no args, assume it is an integer */
466275970Scy
467275970Scy                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
468275970Scy                return (AE_OK);
469275970Scy            }
470275970Scy
471275970Scy            ArgCount = AcpiDmInspectPossibleArgs (3, 1, NextOp);
472275970Scy            AcpiOsPrintf ("/* A-CHILDREN: %u Actual %u */\n", ArgCount, AcpiDmCountChildren (Op));
473275970Scy
474275970Scy            if (ArgCount < 1)
475275970Scy            {
476275970Scy                /* One Arg means this is just a Store(Name,Target) */
477275970Scy
478275970Scy                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
479275970Scy                return (AE_OK);
480275970Scy            }
481275970Scy
482275970Scy            AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount);
483275970Scy        }
484275970Scy        break;
485275970Scy#endif
486275970Scy
487275970Scy    case AML_STORE_OP:
488275970Scy
489275970Scy        ChildOp = Op->Common.Value.Arg;
490275970Scy        if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
491275970Scy            !ChildOp->Common.Node)
492275970Scy        {
493275970Scy            NextOp = Op->Common.Next;
494275970Scy            if (!NextOp)
495275970Scy            {
496275970Scy                /* This NamePath has no args, assume it is an integer */
497275970Scy
498275970Scy                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
499275970Scy                return (AE_OK);
500275970Scy            }
501275970Scy
502275970Scy            ArgCount = AcpiDmInspectPossibleArgs (2, 1, NextOp);
503275970Scy            if (ArgCount <= 1)
504275970Scy            {
505275970Scy                /* One Arg means this is just a Store(Name,Target) */
506275970Scy
507275970Scy                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
508275970Scy                return (AE_OK);
509275970Scy            }
510275970Scy
511275970Scy            AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount);
512275970Scy        }
513275970Scy        break;
514275970Scy
515275970Scy    case AML_INT_NAMEPATH_OP:
516275970Scy
517275970Scy        /* Must examine parent to see if this namepath is an argument */
518275970Scy
519275970Scy        ParentOp = Op->Common.Parent;
520275970Scy        OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
521275970Scy
522275970Scy        if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
523275970Scy            (OpInfo->Class != AML_CLASS_CREATE) &&
524275970Scy            (OpInfo->ObjectType != ACPI_TYPE_LOCAL_ALIAS) &&
525275970Scy            (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
526275970Scy            !Op->Common.Node)
527275970Scy        {
528275970Scy            ArgCount = AcpiDmInspectPossibleArgs (0, 0, Op->Common.Next);
529275970Scy
530275970Scy            /*
531275970Scy             * Check if namepath is a predicate for if/while or lone parameter to
532275970Scy             * a return.
533275970Scy             */
534275970Scy            if (ArgCount == 0)
535275970Scy            {
536275970Scy                if (((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
537275970Scy                     (ParentOp->Common.AmlOpcode == AML_WHILE_OP) ||
538275970Scy                     (ParentOp->Common.AmlOpcode == AML_RETURN_OP)) &&
539275970Scy
540275970Scy                     /* And namepath is the first argument */
541275970Scy                     (ParentOp->Common.Value.Arg == Op))
542275970Scy                {
543275970Scy                    AcpiDmAddToExternalList (Op, Op->Common.Value.String, ACPI_TYPE_INTEGER, 0);
544275970Scy                    break;
545275970Scy                }
546275970Scy            }
547275970Scy
548275970Scy            /*
549275970Scy             * This is a standalone namestring (not a parameter to another
550275970Scy             * operator) - it *must* be a method invocation, nothing else is
551275970Scy             * grammatically possible.
552275970Scy             */
553275970Scy            AcpiDmAddToExternalList (Op, Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount);
554275970Scy
555275970Scy        }
556275970Scy        break;
557275970Scy
558275970Scy    default:
559275970Scy        break;
560275970Scy    }
561275970Scy
562275970Scy    return (AE_OK);
563275970Scy}
564275970Scy
565275970Scy
566275970Scy/*******************************************************************************
567275970Scy *
568275970Scy * FUNCTION:    AcpiDmLoadDescendingOp
569275970Scy *
570275970Scy * PARAMETERS:  ASL_WALK_CALLBACK
571275970Scy *
572275970Scy * RETURN:      Status
573275970Scy *
574275970Scy * DESCRIPTION: Descending handler for namespace control method object load
575275970Scy *
576275970Scy ******************************************************************************/
577275970Scy
578275970Scystatic ACPI_STATUS
579275970ScyAcpiDmLoadDescendingOp (
580275970Scy    ACPI_PARSE_OBJECT       *Op,
581275970Scy    UINT32                  Level,
582275970Scy    void                    *Context)
583275970Scy{
584275970Scy    ACPI_OP_WALK_INFO       *Info = Context;
585275970Scy    const ACPI_OPCODE_INFO  *OpInfo;
586275970Scy    ACPI_WALK_STATE         *WalkState;
587275970Scy    ACPI_OBJECT_TYPE        ObjectType;
588275970Scy    ACPI_STATUS             Status;
589275970Scy    char                    *Path = NULL;
590275970Scy    ACPI_PARSE_OBJECT       *NextOp;
591275970Scy    ACPI_NAMESPACE_NODE     *Node;
592275970Scy    char                    FieldPath[5];
593275970Scy    BOOLEAN                 PreDefined = FALSE;
594275970Scy    UINT8                   PreDefineIndex = 0;
595275970Scy
596275970Scy
597275970Scy    WalkState = Info->WalkState;
598275970Scy    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
599275970Scy    ObjectType = OpInfo->ObjectType;
600275970Scy    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
601275970Scy
602275970Scy    /* Only interested in operators that create new names */
603275970Scy
604275970Scy    if (!(OpInfo->Flags & AML_NAMED) &&
605275970Scy        !(OpInfo->Flags & AML_CREATE))
606275970Scy    {
607275970Scy        goto Exit;
608275970Scy    }
609275970Scy
610275970Scy    /* Get the NamePath from the appropriate place */
611275970Scy
612275970Scy    if (OpInfo->Flags & AML_NAMED)
613275970Scy    {
614275970Scy        /* For all named operators, get the new name */
615275970Scy
616275970Scy        Path = (char *) Op->Named.Path;
617275970Scy
618275970Scy        if (!Path && Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
619275970Scy        {
620275970Scy            *ACPI_CAST_PTR (UINT32, &FieldPath[0]) = Op->Named.Name;
621275970Scy            FieldPath[4] = 0;
622275970Scy            Path = FieldPath;
623275970Scy        }
624275970Scy    }
625275970Scy    else if (OpInfo->Flags & AML_CREATE)
626275970Scy    {
627275970Scy        /* New name is the last child */
628275970Scy
629275970Scy        NextOp = Op->Common.Value.Arg;
630275970Scy
631275970Scy        while (NextOp->Common.Next)
632275970Scy        {
633275970Scy            NextOp = NextOp->Common.Next;
634275970Scy        }
635275970Scy        Path = NextOp->Common.Value.String;
636275970Scy    }
637275970Scy
638275970Scy    if (!Path)
639275970Scy    {
640275970Scy        goto Exit;
641275970Scy    }
642275970Scy
643275970Scy    /* Insert the name into the namespace */
644275970Scy
645275970Scy    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
646275970Scy                ACPI_IMODE_LOAD_PASS2, ACPI_NS_DONT_OPEN_SCOPE,
647275970Scy                WalkState, &Node);
648275970Scy
649275970Scy    Op->Common.Node = Node;
650275970Scy
651275970Scy    if (ACPI_SUCCESS (Status))
652275970Scy    {
653275970Scy        /* Check if it's a predefined node */
654275970Scy
655275970Scy        while (AcpiGbl_PreDefinedNames[PreDefineIndex].Name)
656275970Scy        {
657275970Scy            if (!ACPI_STRNCMP (Node->Name.Ascii,
658275970Scy                AcpiGbl_PreDefinedNames[PreDefineIndex].Name, 4))
659275970Scy            {
660275970Scy                PreDefined = TRUE;
661275970Scy                break;
662275970Scy            }
663275970Scy
664275970Scy            PreDefineIndex++;
665275970Scy        }
666275970Scy
667275970Scy        /*
668275970Scy         * Set node owner id if it satisfies all the following conditions:
669275970Scy         * 1) Not a predefined node, _SB_ etc
670275970Scy         * 2) Not the root node
671275970Scy         * 3) Not a node created by Scope
672275970Scy         */
673275970Scy
674275970Scy        if (!PreDefined && Node != AcpiGbl_RootNode &&
675275970Scy            Op->Common.AmlOpcode != AML_SCOPE_OP)
676275970Scy        {
677275970Scy            Node->OwnerId = WalkState->OwnerId;
678275970Scy        }
679275970Scy    }
680275970Scy
681275970Scy
682275970ScyExit:
683275970Scy
684275970Scy    if (AcpiNsOpensScope (ObjectType))
685275970Scy    {
686275970Scy        if (Op->Common.Node)
687275970Scy        {
688275970Scy            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
689275970Scy            if (ACPI_FAILURE (Status))
690275970Scy            {
691275970Scy                return (Status);
692275970Scy            }
693275970Scy        }
694275970Scy    }
695275970Scy
696275970Scy    return (AE_OK);
697275970Scy}
698275970Scy
699275970Scy
700275970Scy/*******************************************************************************
701275970Scy *
702275970Scy * FUNCTION:    AcpiDmXrefDescendingOp
703275970Scy *
704275970Scy * PARAMETERS:  ASL_WALK_CALLBACK
705275970Scy *
706275970Scy * RETURN:      Status
707275970Scy *
708275970Scy * DESCRIPTION: Descending handler for namespace cross reference
709275970Scy *
710275970Scy ******************************************************************************/
711275970Scy
712275970Scystatic ACPI_STATUS
713275970ScyAcpiDmXrefDescendingOp (
714275970Scy    ACPI_PARSE_OBJECT       *Op,
715275970Scy    UINT32                  Level,
716275970Scy    void                    *Context)
717275970Scy{
718275970Scy    ACPI_OP_WALK_INFO       *Info = Context;
719275970Scy    const ACPI_OPCODE_INFO  *OpInfo;
720275970Scy    ACPI_WALK_STATE         *WalkState;
721275970Scy    ACPI_OBJECT_TYPE        ObjectType;
722275970Scy    ACPI_OBJECT_TYPE        ObjectType2;
723275970Scy    ACPI_STATUS             Status;
724275970Scy    char                    *Path = NULL;
725275970Scy    ACPI_PARSE_OBJECT       *NextOp;
726275970Scy    ACPI_NAMESPACE_NODE     *Node;
727275970Scy    ACPI_OPERAND_OBJECT     *Object;
728275970Scy    UINT32                  ParamCount = 0;
729275970Scy
730275970Scy
731275970Scy    WalkState = Info->WalkState;
732275970Scy    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
733275970Scy    ObjectType = OpInfo->ObjectType;
734275970Scy    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
735275970Scy
736275970Scy    if ((!(OpInfo->Flags & AML_NAMED)) &&
737275970Scy        (!(OpInfo->Flags & AML_CREATE)) &&
738275970Scy        (Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
739275970Scy    {
740275970Scy        goto Exit;
741275970Scy    }
742275970Scy
743275970Scy    /* Get the NamePath from the appropriate place */
744275970Scy
745275970Scy    if (OpInfo->Flags & AML_NAMED)
746275970Scy    {
747275970Scy        /*
748275970Scy         * Only these two operators (Alias, Scope) refer to an existing
749275970Scy         * name, it is the first argument
750275970Scy         */
751275970Scy        if (Op->Common.AmlOpcode == AML_ALIAS_OP)
752275970Scy        {
753275970Scy            ObjectType = ACPI_TYPE_ANY;
754275970Scy
755275970Scy            NextOp = Op->Common.Value.Arg;
756275970Scy            NextOp = NextOp->Common.Value.Arg;
757275970Scy            if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
758275970Scy            {
759275970Scy                Path = NextOp->Common.Value.String;
760275970Scy            }
761275970Scy        }
762275970Scy        else if (Op->Common.AmlOpcode == AML_SCOPE_OP)
763275970Scy        {
764275970Scy            Path = (char *) Op->Named.Path;
765275970Scy        }
766275970Scy    }
767275970Scy    else if (OpInfo->Flags & AML_CREATE)
768275970Scy    {
769275970Scy        /* Referenced Buffer Name is the first child */
770275970Scy
771275970Scy        ObjectType = ACPI_TYPE_BUFFER; /* Change from TYPE_BUFFER_FIELD */
772275970Scy
773275970Scy        NextOp = Op->Common.Value.Arg;
774275970Scy        if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
775275970Scy        {
776275970Scy            Path = NextOp->Common.Value.String;
777275970Scy        }
778275970Scy    }
779275970Scy    else
780275970Scy    {
781275970Scy        Path = Op->Common.Value.String;
782275970Scy    }
783275970Scy
784275970Scy    if (!Path)
785275970Scy    {
786275970Scy        goto Exit;
787275970Scy    }
788275970Scy
789275970Scy    /*
790275970Scy     * Lookup the name in the namespace.  Name must exist at this point, or it
791275970Scy     * is an invalid reference.
792275970Scy     *
793275970Scy     * The namespace is also used as a lookup table for references to resource
794275970Scy     * descriptors and the fields within them.
795275970Scy     */
796275970Scy    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
797275970Scy                ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
798275970Scy                WalkState, &Node);
799275970Scy    if (ACPI_SUCCESS (Status) && (Node->Flags & ANOBJ_IS_EXTERNAL))
800275970Scy    {
801275970Scy        Status = AE_NOT_FOUND;
802275970Scy    }
803275970Scy
804275970Scy    if (ACPI_FAILURE (Status))
805275970Scy    {
806275970Scy        if (Status == AE_NOT_FOUND)
807275970Scy        {
808275970Scy            AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType, 0);
809275970Scy
810275970Scy            /*
811275970Scy             * We could install this into the namespace, but we catch duplicate
812275970Scy             * externals when they are added to the list.
813275970Scy             */
814275970Scy#if 0
815275970Scy            Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
816275970Scy                       ACPI_IMODE_LOAD_PASS1, ACPI_NS_DONT_OPEN_SCOPE,
817275970Scy                       WalkState, &Node);
818275970Scy#endif
819275970Scy        }
820275970Scy    }
821275970Scy
822275970Scy    /*
823275970Scy     * Found the node in external table, add it to external list
824275970Scy     * Node->OwnerId == 0 indicates built-in ACPI Names, _OS_ etc
825275970Scy     */
826275970Scy    else if (Node->OwnerId && WalkState->OwnerId != Node->OwnerId)
827275970Scy    {
828275970Scy        ObjectType2 = ObjectType;
829275970Scy
830275970Scy        Object = AcpiNsGetAttachedObject (Node);
831275970Scy        if (Object)
832275970Scy        {
833275970Scy            ObjectType2 = Object->Common.Type;
834275970Scy            if (ObjectType2 == ACPI_TYPE_METHOD)
835275970Scy            {
836275970Scy                ParamCount = Object->Method.ParamCount;
837275970Scy            }
838275970Scy        }
839275970Scy
840275970Scy        AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType2, ParamCount);
841275970Scy        Op->Common.Node = Node;
842275970Scy    }
843275970Scy    else
844275970Scy    {
845275970Scy        Op->Common.Node = Node;
846275970Scy    }
847275970Scy
848275970Scy
849275970ScyExit:
850275970Scy    /* Open new scope if necessary */
851275970Scy
852275970Scy    if (AcpiNsOpensScope (ObjectType))
853275970Scy    {
854275970Scy        if (Op->Common.Node)
855275970Scy        {
856275970Scy            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
857275970Scy            if (ACPI_FAILURE (Status))
858275970Scy            {
859275970Scy                return (Status);
860275970Scy            }
861275970Scy        }
862275970Scy    }
863275970Scy
864275970Scy    return (AE_OK);
865275970Scy}
866275970Scy
867275970Scy
868275970Scy/*******************************************************************************
869275970Scy *
870275970Scy * FUNCTION:    AcpiDmResourceDescendingOp
871275970Scy *
872275970Scy * PARAMETERS:  ASL_WALK_CALLBACK
873275970Scy *
874275970Scy * RETURN:      None
875275970Scy *
876275970Scy * DESCRIPTION: Process one parse op during symbolic resource index conversion.
877275970Scy *
878275970Scy ******************************************************************************/
879275970Scy
880275970Scystatic ACPI_STATUS
881275970ScyAcpiDmResourceDescendingOp (
882275970Scy    ACPI_PARSE_OBJECT       *Op,
883275970Scy    UINT32                  Level,
884275970Scy    void                    *Context)
885275970Scy{
886275970Scy    ACPI_OP_WALK_INFO       *Info = Context;
887275970Scy    const ACPI_OPCODE_INFO  *OpInfo;
888275970Scy    ACPI_WALK_STATE         *WalkState;
889275970Scy    ACPI_OBJECT_TYPE        ObjectType;
890275970Scy    ACPI_STATUS             Status;
891275970Scy
892275970Scy
893275970Scy    WalkState = Info->WalkState;
894275970Scy    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
895275970Scy
896275970Scy    /* Open new scope if necessary */
897275970Scy
898275970Scy    ObjectType = OpInfo->ObjectType;
899275970Scy    if (AcpiNsOpensScope (ObjectType))
900275970Scy    {
901275970Scy        if (Op->Common.Node)
902275970Scy        {
903275970Scy
904275970Scy            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
905275970Scy            if (ACPI_FAILURE (Status))
906275970Scy            {
907275970Scy                return (Status);
908275970Scy            }
909275970Scy        }
910275970Scy    }
911275970Scy
912275970Scy    /*
913275970Scy     * Check if this operator contains a reference to a resource descriptor.
914275970Scy     * If so, convert the reference into a symbolic reference.
915275970Scy     */
916275970Scy    AcpiDmCheckResourceReference (Op, WalkState);
917275970Scy    return (AE_OK);
918275970Scy}
919275970Scy
920275970Scy
921275970Scy/*******************************************************************************
922275970Scy *
923275970Scy * FUNCTION:    AcpiDmCommonAscendingOp
924275970Scy *
925275970Scy * PARAMETERS:  ASL_WALK_CALLBACK
926275970Scy *
927275970Scy * RETURN:      None
928275970Scy *
929275970Scy * DESCRIPTION: Ascending handler for combined parse/namespace walks. Closes
930275970Scy *              scope if necessary.
931275970Scy *
932275970Scy ******************************************************************************/
933275970Scy
934275970Scystatic ACPI_STATUS
935275970ScyAcpiDmCommonAscendingOp (
936275970Scy    ACPI_PARSE_OBJECT       *Op,
937275970Scy    UINT32                  Level,
938275970Scy    void                    *Context)
939275970Scy{
940275970Scy    ACPI_OP_WALK_INFO       *Info = Context;
941275970Scy    const ACPI_OPCODE_INFO  *OpInfo;
942275970Scy    ACPI_OBJECT_TYPE        ObjectType;
943275970Scy
944275970Scy
945275970Scy    /* Close scope if necessary */
946275970Scy
947275970Scy    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
948275970Scy    ObjectType = OpInfo->ObjectType;
949275970Scy    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
950275970Scy
951275970Scy    if (AcpiNsOpensScope (ObjectType))
952275970Scy    {
953275970Scy        (void) AcpiDsScopeStackPop (Info->WalkState);
954275970Scy    }
955275970Scy
956275970Scy    return (AE_OK);
957275970Scy}
958275970Scy
959275970Scy
960275970Scy/*******************************************************************************
961275970Scy *
962275970Scy * FUNCTION:    AcpiDmInspectPossibleArgs
963275970Scy *
964275970Scy * PARAMETERS:  CurrentOpArgCount   - Which arg of the current op was the
965275970Scy *                                    possible method invocation found
966275970Scy *              TargetCount         - Number of targets (0,1,2) for this op
967275970Scy *              Op                  - Parse op
968275970Scy *
969275970Scy * RETURN:      Status
970275970Scy *
971275970Scy * DESCRIPTION: Examine following args and next ops for possible arguments
972275970Scy *              for an unrecognized method invocation.
973275970Scy *
974275970Scy ******************************************************************************/
975275970Scy
976275970Scystatic UINT32
977275970ScyAcpiDmInspectPossibleArgs (
978275970Scy    UINT32                  CurrentOpArgCount,
979275970Scy    UINT32                  TargetCount,
980275970Scy    ACPI_PARSE_OBJECT       *Op)
981275970Scy{
982275970Scy    const ACPI_OPCODE_INFO  *OpInfo;
983275970Scy    UINT32                  i;
984275970Scy    UINT32                  Last = 0;
985275970Scy    UINT32                  Lookahead;
986275970Scy
987275970Scy
988275970Scy    Lookahead = (ACPI_METHOD_NUM_ARGS + TargetCount) - CurrentOpArgCount;
989275970Scy
990275970Scy    /* Lookahead for the maximum number of possible arguments */
991275970Scy
992275970Scy    for (i = 0; i < Lookahead; i++)
993275970Scy    {
994275970Scy        if (!Op)
995275970Scy        {
996275970Scy            break;
997275970Scy        }
998275970Scy
999275970Scy        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1000275970Scy
1001275970Scy        /*
1002275970Scy         * Any one of these operators is "very probably" not a method arg
1003275970Scy         */
1004275970Scy        if ((Op->Common.AmlOpcode == AML_STORE_OP) ||
1005275970Scy            (Op->Common.AmlOpcode == AML_NOTIFY_OP))
1006275970Scy        {
1007275970Scy            break;
1008275970Scy        }
1009275970Scy
1010        if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
1011            (OpInfo->Class != AML_CLASS_CONTROL))
1012        {
1013            Last = i+1;
1014        }
1015
1016        Op = Op->Common.Next;
1017    }
1018
1019    return (Last);
1020}
1021
1022
1023