1167802Sjkim/******************************************************************************
2167802Sjkim *
3167802Sjkim * Module Name: adwalk - Application-level disassembler parse tree walk routines
4167802Sjkim *
5167802Sjkim *****************************************************************************/
6167802Sjkim
7217365Sjkim/*
8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp.
9167802Sjkim * All rights reserved.
10167802Sjkim *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25167802Sjkim *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29167802Sjkim *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43167802Sjkim
44167802Sjkim
45193529Sjkim#include <contrib/dev/acpica/include/acpi.h>
46193529Sjkim#include <contrib/dev/acpica/include/accommon.h>
47193529Sjkim#include <contrib/dev/acpica/include/acparser.h>
48193529Sjkim#include <contrib/dev/acpica/include/amlcode.h>
49193529Sjkim#include <contrib/dev/acpica/include/acdisasm.h>
50193529Sjkim#include <contrib/dev/acpica/include/acdispat.h>
51193529Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
52193529Sjkim#include <contrib/dev/acpica/include/acapps.h>
53167802Sjkim
54167802Sjkim
55167802Sjkim#define _COMPONENT          ACPI_TOOLS
56167802Sjkim        ACPI_MODULE_NAME    ("adwalk")
57167802Sjkim
58167802Sjkim/*
59167802Sjkim * aslmap - opcode mappings and reserved method names
60167802Sjkim */
61167802SjkimACPI_OBJECT_TYPE
62167802SjkimAslMapNamedOpcodeToDataType (
63167802Sjkim    UINT16                  Opcode);
64167802Sjkim
65167802Sjkim/* Local prototypes */
66167802Sjkim
67167802Sjkimstatic ACPI_STATUS
68167802SjkimAcpiDmFindOrphanDescending (
69167802Sjkim    ACPI_PARSE_OBJECT       *Op,
70167802Sjkim    UINT32                  Level,
71167802Sjkim    void                    *Context);
72167802Sjkim
73167802Sjkimstatic ACPI_STATUS
74167802SjkimAcpiDmDumpDescending (
75167802Sjkim    ACPI_PARSE_OBJECT       *Op,
76167802Sjkim    UINT32                  Level,
77167802Sjkim    void                    *Context);
78167802Sjkim
79167802Sjkimstatic ACPI_STATUS
80167802SjkimAcpiDmXrefDescendingOp (
81167802Sjkim    ACPI_PARSE_OBJECT       *Op,
82167802Sjkim    UINT32                  Level,
83167802Sjkim    void                    *Context);
84167802Sjkim
85167802Sjkimstatic ACPI_STATUS
86167802SjkimAcpiDmCommonAscendingOp (
87167802Sjkim    ACPI_PARSE_OBJECT       *Op,
88167802Sjkim    UINT32                  Level,
89167802Sjkim    void                    *Context);
90167802Sjkim
91167802Sjkimstatic ACPI_STATUS
92167802SjkimAcpiDmLoadDescendingOp (
93167802Sjkim    ACPI_PARSE_OBJECT       *Op,
94167802Sjkim    UINT32                  Level,
95167802Sjkim    void                    *Context);
96167802Sjkim
97167802Sjkimstatic UINT32
98167802SjkimAcpiDmInspectPossibleArgs (
99167802Sjkim    UINT32                  CurrentOpArgCount,
100167802Sjkim    UINT32                  TargetCount,
101167802Sjkim    ACPI_PARSE_OBJECT       *Op);
102167802Sjkim
103167802Sjkimstatic ACPI_STATUS
104167802SjkimAcpiDmResourceDescendingOp (
105167802Sjkim    ACPI_PARSE_OBJECT       *Op,
106167802Sjkim    UINT32                  Level,
107167802Sjkim    void                    *Context);
108167802Sjkim
109167802Sjkim
110167802Sjkim/*******************************************************************************
111167802Sjkim *
112167802Sjkim * FUNCTION:    AcpiDmDumpTree
113167802Sjkim *
114198237Sjkim * PARAMETERS:  Origin              - Starting object
115167802Sjkim *
116167802Sjkim * RETURN:      None
117167802Sjkim *
118167802Sjkim * DESCRIPTION: Parse tree walk to format and output the nodes
119167802Sjkim *
120167802Sjkim ******************************************************************************/
121167802Sjkim
122167802Sjkimvoid
123167802SjkimAcpiDmDumpTree (
124167802Sjkim    ACPI_PARSE_OBJECT       *Origin)
125167802Sjkim{
126167802Sjkim    ACPI_OP_WALK_INFO       Info;
127167802Sjkim
128167802Sjkim
129167802Sjkim    if (!Origin)
130167802Sjkim    {
131167802Sjkim        return;
132167802Sjkim    }
133167802Sjkim
134167802Sjkim    AcpiOsPrintf ("/*\nAML Parse Tree\n\n");
135167802Sjkim    Info.Flags = 0;
136167802Sjkim    Info.Count = 0;
137167802Sjkim    Info.Level = 0;
138167802Sjkim    Info.WalkState = NULL;
139167802Sjkim    AcpiDmWalkParseTree (Origin, AcpiDmDumpDescending, NULL, &Info);
140167802Sjkim    AcpiOsPrintf ("*/\n\n");
141167802Sjkim}
142167802Sjkim
143167802Sjkim
144167802Sjkim/*******************************************************************************
145167802Sjkim *
146167802Sjkim * FUNCTION:    AcpiDmFindOrphanMethods
147167802Sjkim *
148198237Sjkim * PARAMETERS:  Origin              - Starting object
149167802Sjkim *
150167802Sjkim * RETURN:      None
151167802Sjkim *
152167802Sjkim * DESCRIPTION: Parse tree walk to find "orphaned" method invocations -- methods
153167802Sjkim *              that are not resolved in the namespace
154167802Sjkim *
155167802Sjkim ******************************************************************************/
156167802Sjkim
157167802Sjkimvoid
158167802SjkimAcpiDmFindOrphanMethods (
159167802Sjkim    ACPI_PARSE_OBJECT       *Origin)
160167802Sjkim{
161167802Sjkim    ACPI_OP_WALK_INFO       Info;
162167802Sjkim
163167802Sjkim
164167802Sjkim    if (!Origin)
165167802Sjkim    {
166167802Sjkim        return;
167167802Sjkim    }
168167802Sjkim
169167802Sjkim    Info.Flags = 0;
170167802Sjkim    Info.Level = 0;
171167802Sjkim    Info.WalkState = NULL;
172167802Sjkim    AcpiDmWalkParseTree (Origin, AcpiDmFindOrphanDescending, NULL, &Info);
173167802Sjkim}
174167802Sjkim
175167802Sjkim
176167802Sjkim/*******************************************************************************
177167802Sjkim *
178167802Sjkim * FUNCTION:    AcpiDmFinishNamespaceLoad
179167802Sjkim *
180167802Sjkim * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
181167802Sjkim *              NamespaceRoot       - Root of the internal namespace
182193529Sjkim *              OwnerId             - OwnerId of the table to be disassembled
183167802Sjkim *
184167802Sjkim * RETURN:      None
185167802Sjkim *
186167802Sjkim * DESCRIPTION: Load all namespace items that are created within control
187167802Sjkim *              methods. Used before namespace cross reference
188167802Sjkim *
189167802Sjkim ******************************************************************************/
190167802Sjkim
191167802Sjkimvoid
192167802SjkimAcpiDmFinishNamespaceLoad (
193167802Sjkim    ACPI_PARSE_OBJECT       *ParseTreeRoot,
194193529Sjkim    ACPI_NAMESPACE_NODE     *NamespaceRoot,
195193529Sjkim    ACPI_OWNER_ID           OwnerId)
196167802Sjkim{
197167802Sjkim    ACPI_STATUS             Status;
198167802Sjkim    ACPI_OP_WALK_INFO       Info;
199167802Sjkim    ACPI_WALK_STATE         *WalkState;
200167802Sjkim
201167802Sjkim
202167802Sjkim    if (!ParseTreeRoot)
203167802Sjkim    {
204167802Sjkim        return;
205167802Sjkim    }
206167802Sjkim
207167802Sjkim    /* Create and initialize a new walk state */
208167802Sjkim
209193529Sjkim    WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
210167802Sjkim    if (!WalkState)
211167802Sjkim    {
212167802Sjkim        return;
213167802Sjkim    }
214167802Sjkim
215167802Sjkim    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState);
216167802Sjkim    if (ACPI_FAILURE (Status))
217167802Sjkim    {
218167802Sjkim        return;
219167802Sjkim    }
220167802Sjkim
221167802Sjkim    Info.Flags = 0;
222167802Sjkim    Info.Level = 0;
223167802Sjkim    Info.WalkState = WalkState;
224167802Sjkim    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmLoadDescendingOp,
225167802Sjkim        AcpiDmCommonAscendingOp, &Info);
226167802Sjkim    ACPI_FREE (WalkState);
227167802Sjkim}
228167802Sjkim
229167802Sjkim
230167802Sjkim/*******************************************************************************
231167802Sjkim *
232167802Sjkim * FUNCTION:    AcpiDmCrossReferenceNamespace
233167802Sjkim *
234167802Sjkim * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
235167802Sjkim *              NamespaceRoot       - Root of the internal namespace
236193529Sjkim *              OwnerId             - OwnerId of the table to be disassembled
237167802Sjkim *
238167802Sjkim * RETURN:      None
239167802Sjkim *
240167802Sjkim * DESCRIPTION: Cross reference the namespace to create externals
241167802Sjkim *
242167802Sjkim ******************************************************************************/
243167802Sjkim
244167802Sjkimvoid
245167802SjkimAcpiDmCrossReferenceNamespace (
246167802Sjkim    ACPI_PARSE_OBJECT       *ParseTreeRoot,
247193529Sjkim    ACPI_NAMESPACE_NODE     *NamespaceRoot,
248193529Sjkim    ACPI_OWNER_ID           OwnerId)
249167802Sjkim{
250167802Sjkim    ACPI_STATUS             Status;
251167802Sjkim    ACPI_OP_WALK_INFO       Info;
252167802Sjkim    ACPI_WALK_STATE         *WalkState;
253167802Sjkim
254167802Sjkim
255167802Sjkim    if (!ParseTreeRoot)
256167802Sjkim    {
257167802Sjkim        return;
258167802Sjkim    }
259167802Sjkim
260167802Sjkim    /* Create and initialize a new walk state */
261167802Sjkim
262193529Sjkim    WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
263167802Sjkim    if (!WalkState)
264167802Sjkim    {
265167802Sjkim        return;
266167802Sjkim    }
267167802Sjkim
268167802Sjkim    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState);
269167802Sjkim    if (ACPI_FAILURE (Status))
270167802Sjkim    {
271167802Sjkim        return;
272167802Sjkim    }
273167802Sjkim
274167802Sjkim    Info.Flags = 0;
275167802Sjkim    Info.Level = 0;
276167802Sjkim    Info.WalkState = WalkState;
277167802Sjkim    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmXrefDescendingOp,
278167802Sjkim        AcpiDmCommonAscendingOp, &Info);
279167802Sjkim    ACPI_FREE (WalkState);
280167802Sjkim}
281167802Sjkim
282167802Sjkim
283167802Sjkim/*******************************************************************************
284167802Sjkim *
285167802Sjkim * FUNCTION:    AcpiDmConvertResourceIndexes
286167802Sjkim *
287167802Sjkim * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
288167802Sjkim *              NamespaceRoot       - Root of the internal namespace
289167802Sjkim *
290167802Sjkim * RETURN:      None
291167802Sjkim *
292167802Sjkim * DESCRIPTION: Convert fixed-offset references to resource descriptors to
293167802Sjkim *              symbolic references. Should only be called after namespace has
294167802Sjkim *              been cross referenced.
295167802Sjkim *
296167802Sjkim ******************************************************************************/
297167802Sjkim
298167802Sjkimvoid
299167802SjkimAcpiDmConvertResourceIndexes (
300167802Sjkim    ACPI_PARSE_OBJECT       *ParseTreeRoot,
301167802Sjkim    ACPI_NAMESPACE_NODE     *NamespaceRoot)
302167802Sjkim{
303167802Sjkim    ACPI_STATUS             Status;
304167802Sjkim    ACPI_OP_WALK_INFO       Info;
305167802Sjkim    ACPI_WALK_STATE         *WalkState;
306167802Sjkim
307167802Sjkim
308167802Sjkim    if (!ParseTreeRoot)
309167802Sjkim    {
310167802Sjkim        return;
311167802Sjkim    }
312167802Sjkim
313167802Sjkim    /* Create and initialize a new walk state */
314167802Sjkim
315167802Sjkim    WalkState = AcpiDsCreateWalkState (0, ParseTreeRoot, NULL, NULL);
316167802Sjkim    if (!WalkState)
317167802Sjkim    {
318167802Sjkim        return;
319167802Sjkim    }
320167802Sjkim
321167802Sjkim    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState);
322167802Sjkim    if (ACPI_FAILURE (Status))
323167802Sjkim    {
324167802Sjkim        return;
325167802Sjkim    }
326167802Sjkim
327167802Sjkim    Info.Flags = 0;
328167802Sjkim    Info.Level = 0;
329167802Sjkim    Info.WalkState = WalkState;
330167802Sjkim    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmResourceDescendingOp,
331167802Sjkim        AcpiDmCommonAscendingOp, &Info);
332167802Sjkim    ACPI_FREE (WalkState);
333167802Sjkim    return;
334167802Sjkim}
335167802Sjkim
336167802Sjkim
337167802Sjkim/*******************************************************************************
338167802Sjkim *
339167802Sjkim * FUNCTION:    AcpiDmDumpDescending
340167802Sjkim *
341167802Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
342167802Sjkim *
343167802Sjkim * RETURN:      Status
344167802Sjkim *
345167802Sjkim * DESCRIPTION: Format and print contents of one parse Op.
346167802Sjkim *
347167802Sjkim ******************************************************************************/
348167802Sjkim
349167802Sjkimstatic ACPI_STATUS
350167802SjkimAcpiDmDumpDescending (
351167802Sjkim    ACPI_PARSE_OBJECT       *Op,
352167802Sjkim    UINT32                  Level,
353167802Sjkim    void                    *Context)
354167802Sjkim{
355167802Sjkim    ACPI_OP_WALK_INFO       *Info = Context;
356167802Sjkim    char                    *Path;
357167802Sjkim
358167802Sjkim
359167802Sjkim    if (!Op)
360167802Sjkim    {
361167802Sjkim        return (AE_OK);
362167802Sjkim    }
363167802Sjkim
364167802Sjkim    /* Most of the information (count, level, name) here */
365167802Sjkim
366198237Sjkim    Info->Count++;
367167802Sjkim    AcpiOsPrintf ("% 5d [%2.2d] ", Info->Count, Level);
368167802Sjkim    AcpiDmIndent (Level);
369167802Sjkim    AcpiOsPrintf ("%-28s", AcpiPsGetOpcodeName (Op->Common.AmlOpcode));
370167802Sjkim
371167802Sjkim    /* Extra info is helpful */
372167802Sjkim
373167802Sjkim    switch (Op->Common.AmlOpcode)
374167802Sjkim    {
375167802Sjkim    case AML_BYTE_OP:
376254745Sjkim
377254745Sjkim        AcpiOsPrintf ("%2.2X", (UINT32) Op->Common.Value.Integer);
378254745Sjkim        break;
379254745Sjkim
380167802Sjkim    case AML_WORD_OP:
381254745Sjkim
382254745Sjkim        AcpiOsPrintf ("%4.4X", (UINT32) Op->Common.Value.Integer);
383254745Sjkim        break;
384254745Sjkim
385167802Sjkim    case AML_DWORD_OP:
386250838Sjkim
387254745Sjkim        AcpiOsPrintf ("%8.8X", (UINT32) Op->Common.Value.Integer);
388167802Sjkim        break;
389167802Sjkim
390228110Sjkim    case AML_QWORD_OP:
391250838Sjkim
392228110Sjkim        AcpiOsPrintf ("%8.8X%8.8X", ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
393228110Sjkim        break;
394228110Sjkim
395167802Sjkim    case AML_INT_NAMEPATH_OP:
396250838Sjkim
397167802Sjkim        if (Op->Common.Value.String)
398167802Sjkim        {
399167802Sjkim            AcpiNsExternalizeName (ACPI_UINT32_MAX, Op->Common.Value.String,
400167802Sjkim                            NULL, &Path);
401167802Sjkim            AcpiOsPrintf ("%s %p", Path, Op->Common.Node);
402167802Sjkim            ACPI_FREE (Path);
403167802Sjkim        }
404167802Sjkim        else
405167802Sjkim        {
406167802Sjkim            AcpiOsPrintf ("[NULL]");
407167802Sjkim        }
408167802Sjkim        break;
409167802Sjkim
410167802Sjkim    case AML_NAME_OP:
411167802Sjkim    case AML_METHOD_OP:
412167802Sjkim    case AML_DEVICE_OP:
413167802Sjkim    case AML_INT_NAMEDFIELD_OP:
414250838Sjkim
415198237Sjkim        AcpiOsPrintf ("%4.4s", ACPI_CAST_PTR (char, &Op->Named.Name));
416167802Sjkim        break;
417193529Sjkim
418193529Sjkim    default:
419250838Sjkim
420193529Sjkim        break;
421167802Sjkim    }
422167802Sjkim
423167802Sjkim    AcpiOsPrintf ("\n");
424167802Sjkim    return (AE_OK);
425167802Sjkim}
426167802Sjkim
427167802Sjkim
428167802Sjkim/*******************************************************************************
429167802Sjkim *
430167802Sjkim * FUNCTION:    AcpiDmFindOrphanDescending
431167802Sjkim *
432167802Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
433167802Sjkim *
434167802Sjkim * RETURN:      Status
435167802Sjkim *
436167802Sjkim * DESCRIPTION: Check namepath Ops for orphaned method invocations
437167802Sjkim *
438167802Sjkim * Note: Experimental.
439167802Sjkim *
440167802Sjkim ******************************************************************************/
441167802Sjkim
442167802Sjkimstatic ACPI_STATUS
443167802SjkimAcpiDmFindOrphanDescending (
444167802Sjkim    ACPI_PARSE_OBJECT       *Op,
445167802Sjkim    UINT32                  Level,
446167802Sjkim    void                    *Context)
447167802Sjkim{
448167802Sjkim    const ACPI_OPCODE_INFO  *OpInfo;
449167802Sjkim    ACPI_PARSE_OBJECT       *ChildOp;
450167802Sjkim    ACPI_PARSE_OBJECT       *NextOp;
451167802Sjkim    ACPI_PARSE_OBJECT       *ParentOp;
452167802Sjkim    UINT32                  ArgCount;
453167802Sjkim
454167802Sjkim
455167802Sjkim    if (!Op)
456167802Sjkim    {
457167802Sjkim        return (AE_OK);
458167802Sjkim    }
459167802Sjkim
460167802Sjkim    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
461167802Sjkim
462167802Sjkim    switch (Op->Common.AmlOpcode)
463167802Sjkim    {
464167802Sjkim#ifdef ACPI_UNDER_DEVELOPMENT
465167802Sjkim    case AML_ADD_OP:
466250838Sjkim
467167802Sjkim        ChildOp = Op->Common.Value.Arg;
468167802Sjkim        if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
469167802Sjkim            !ChildOp->Common.Node)
470167802Sjkim        {
471167802Sjkim            AcpiNsExternalizeName (ACPI_UINT32_MAX, ChildOp->Common.Value.String,
472167802Sjkim                            NULL, &Path);
473167802Sjkim            AcpiOsPrintf ("/* %-16s A-NAMEPATH: %s  */\n", Op->Common.AmlOpName, Path);
474167802Sjkim            ACPI_FREE (Path);
475167802Sjkim
476167802Sjkim            NextOp = Op->Common.Next;
477167802Sjkim            if (!NextOp)
478167802Sjkim            {
479167802Sjkim                /* This NamePath has no args, assume it is an integer */
480167802Sjkim
481198237Sjkim                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
482167802Sjkim                return (AE_OK);
483167802Sjkim            }
484167802Sjkim
485167802Sjkim            ArgCount = AcpiDmInspectPossibleArgs (3, 1, NextOp);
486209746Sjkim            AcpiOsPrintf ("/* A-CHILDREN: %u Actual %u */\n", ArgCount, AcpiDmCountChildren (Op));
487167802Sjkim
488167802Sjkim            if (ArgCount < 1)
489167802Sjkim            {
490167802Sjkim                /* One Arg means this is just a Store(Name,Target) */
491167802Sjkim
492198237Sjkim                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
493167802Sjkim                return (AE_OK);
494167802Sjkim            }
495167802Sjkim
496198237Sjkim            AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount);
497167802Sjkim        }
498167802Sjkim        break;
499167802Sjkim#endif
500167802Sjkim
501167802Sjkim    case AML_STORE_OP:
502167802Sjkim
503167802Sjkim        ChildOp = Op->Common.Value.Arg;
504167802Sjkim        if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
505167802Sjkim            !ChildOp->Common.Node)
506167802Sjkim        {
507167802Sjkim            NextOp = Op->Common.Next;
508167802Sjkim            if (!NextOp)
509167802Sjkim            {
510167802Sjkim                /* This NamePath has no args, assume it is an integer */
511167802Sjkim
512198237Sjkim                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
513167802Sjkim                return (AE_OK);
514167802Sjkim            }
515167802Sjkim
516167802Sjkim            ArgCount = AcpiDmInspectPossibleArgs (2, 1, NextOp);
517167802Sjkim            if (ArgCount <= 1)
518167802Sjkim            {
519167802Sjkim                /* One Arg means this is just a Store(Name,Target) */
520167802Sjkim
521198237Sjkim                AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0);
522167802Sjkim                return (AE_OK);
523167802Sjkim            }
524167802Sjkim
525198237Sjkim            AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount);
526167802Sjkim        }
527167802Sjkim        break;
528167802Sjkim
529167802Sjkim    case AML_INT_NAMEPATH_OP:
530167802Sjkim
531167802Sjkim        /* Must examine parent to see if this namepath is an argument */
532167802Sjkim
533167802Sjkim        ParentOp = Op->Common.Parent;
534167802Sjkim        OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
535167802Sjkim
536167802Sjkim        if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
537167802Sjkim            (OpInfo->Class != AML_CLASS_CREATE) &&
538235945Sjkim            (OpInfo->ObjectType != ACPI_TYPE_LOCAL_ALIAS) &&
539167802Sjkim            (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
540167802Sjkim            !Op->Common.Node)
541167802Sjkim        {
542167802Sjkim            ArgCount = AcpiDmInspectPossibleArgs (0, 0, Op->Common.Next);
543167802Sjkim
544167802Sjkim            /*
545167802Sjkim             * Check if namepath is a predicate for if/while or lone parameter to
546167802Sjkim             * a return.
547167802Sjkim             */
548167802Sjkim            if (ArgCount == 0)
549167802Sjkim            {
550167802Sjkim                if (((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
551167802Sjkim                     (ParentOp->Common.AmlOpcode == AML_WHILE_OP) ||
552167802Sjkim                     (ParentOp->Common.AmlOpcode == AML_RETURN_OP)) &&
553167802Sjkim
554167802Sjkim                     /* And namepath is the first argument */
555167802Sjkim                     (ParentOp->Common.Value.Arg == Op))
556167802Sjkim                {
557198237Sjkim                    AcpiDmAddToExternalList (Op, Op->Common.Value.String, ACPI_TYPE_INTEGER, 0);
558167802Sjkim                    break;
559167802Sjkim                }
560167802Sjkim            }
561167802Sjkim
562167802Sjkim            /*
563167802Sjkim             * This is a standalone namestring (not a parameter to another
564167802Sjkim             * operator) - it *must* be a method invocation, nothing else is
565167802Sjkim             * grammatically possible.
566167802Sjkim             */
567198237Sjkim            AcpiDmAddToExternalList (Op, Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount);
568167802Sjkim
569167802Sjkim        }
570167802Sjkim        break;
571193529Sjkim
572193529Sjkim    default:
573250838Sjkim
574193529Sjkim        break;
575167802Sjkim    }
576167802Sjkim
577167802Sjkim    return (AE_OK);
578167802Sjkim}
579167802Sjkim
580167802Sjkim
581167802Sjkim/*******************************************************************************
582167802Sjkim *
583167802Sjkim * FUNCTION:    AcpiDmLoadDescendingOp
584167802Sjkim *
585167802Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
586167802Sjkim *
587167802Sjkim * RETURN:      Status
588167802Sjkim *
589167802Sjkim * DESCRIPTION: Descending handler for namespace control method object load
590167802Sjkim *
591167802Sjkim ******************************************************************************/
592167802Sjkim
593167802Sjkimstatic ACPI_STATUS
594167802SjkimAcpiDmLoadDescendingOp (
595167802Sjkim    ACPI_PARSE_OBJECT       *Op,
596167802Sjkim    UINT32                  Level,
597167802Sjkim    void                    *Context)
598167802Sjkim{
599167802Sjkim    ACPI_OP_WALK_INFO       *Info = Context;
600167802Sjkim    const ACPI_OPCODE_INFO  *OpInfo;
601167802Sjkim    ACPI_WALK_STATE         *WalkState;
602167802Sjkim    ACPI_OBJECT_TYPE        ObjectType;
603167802Sjkim    ACPI_STATUS             Status;
604167802Sjkim    char                    *Path = NULL;
605167802Sjkim    ACPI_PARSE_OBJECT       *NextOp;
606167802Sjkim    ACPI_NAMESPACE_NODE     *Node;
607193529Sjkim    char                    FieldPath[5];
608193529Sjkim    BOOLEAN                 PreDefined = FALSE;
609193529Sjkim    UINT8                   PreDefineIndex = 0;
610167802Sjkim
611167802Sjkim
612167802Sjkim    WalkState = Info->WalkState;
613167802Sjkim    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
614167802Sjkim    ObjectType = OpInfo->ObjectType;
615167802Sjkim    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
616167802Sjkim
617167802Sjkim    /* Only interested in operators that create new names */
618167802Sjkim
619167802Sjkim    if (!(OpInfo->Flags & AML_NAMED) &&
620167802Sjkim        !(OpInfo->Flags & AML_CREATE))
621167802Sjkim    {
622167802Sjkim        goto Exit;
623167802Sjkim    }
624167802Sjkim
625167802Sjkim    /* Get the NamePath from the appropriate place */
626167802Sjkim
627167802Sjkim    if (OpInfo->Flags & AML_NAMED)
628167802Sjkim    {
629167802Sjkim        /* For all named operators, get the new name */
630167802Sjkim
631167802Sjkim        Path = (char *) Op->Named.Path;
632193529Sjkim
633193529Sjkim        if (!Path && Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
634193529Sjkim        {
635193529Sjkim            *ACPI_CAST_PTR (UINT32, &FieldPath[0]) = Op->Named.Name;
636193529Sjkim            FieldPath[4] = 0;
637193529Sjkim            Path = FieldPath;
638193529Sjkim        }
639167802Sjkim    }
640167802Sjkim    else if (OpInfo->Flags & AML_CREATE)
641167802Sjkim    {
642167802Sjkim        /* New name is the last child */
643167802Sjkim
644167802Sjkim        NextOp = Op->Common.Value.Arg;
645167802Sjkim
646167802Sjkim        while (NextOp->Common.Next)
647167802Sjkim        {
648167802Sjkim            NextOp = NextOp->Common.Next;
649167802Sjkim        }
650167802Sjkim        Path = NextOp->Common.Value.String;
651167802Sjkim    }
652167802Sjkim
653167802Sjkim    if (!Path)
654167802Sjkim    {
655167802Sjkim        goto Exit;
656167802Sjkim    }
657167802Sjkim
658167802Sjkim    /* Insert the name into the namespace */
659167802Sjkim
660167802Sjkim    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
661167802Sjkim                ACPI_IMODE_LOAD_PASS2, ACPI_NS_DONT_OPEN_SCOPE,
662167802Sjkim                WalkState, &Node);
663167802Sjkim
664167802Sjkim    Op->Common.Node = Node;
665167802Sjkim
666193529Sjkim    if (ACPI_SUCCESS (Status))
667193529Sjkim    {
668193529Sjkim        /* Check if it's a predefined node */
669167802Sjkim
670193529Sjkim        while (AcpiGbl_PreDefinedNames[PreDefineIndex].Name)
671193529Sjkim        {
672241973Sjkim            if (ACPI_COMPARE_NAME (Node->Name.Ascii,
673241973Sjkim                AcpiGbl_PreDefinedNames[PreDefineIndex].Name))
674193529Sjkim            {
675193529Sjkim                PreDefined = TRUE;
676193529Sjkim                break;
677193529Sjkim            }
678193529Sjkim
679193529Sjkim            PreDefineIndex++;
680193529Sjkim        }
681193529Sjkim
682193529Sjkim        /*
683193529Sjkim         * Set node owner id if it satisfies all the following conditions:
684193529Sjkim         * 1) Not a predefined node, _SB_ etc
685193529Sjkim         * 2) Not the root node
686193529Sjkim         * 3) Not a node created by Scope
687193529Sjkim         */
688193529Sjkim
689193529Sjkim        if (!PreDefined && Node != AcpiGbl_RootNode &&
690193529Sjkim            Op->Common.AmlOpcode != AML_SCOPE_OP)
691193529Sjkim        {
692193529Sjkim            Node->OwnerId = WalkState->OwnerId;
693193529Sjkim        }
694193529Sjkim    }
695193529Sjkim
696193529Sjkim
697167802SjkimExit:
698167802Sjkim
699167802Sjkim    if (AcpiNsOpensScope (ObjectType))
700167802Sjkim    {
701167802Sjkim        if (Op->Common.Node)
702167802Sjkim        {
703167802Sjkim            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
704167802Sjkim            if (ACPI_FAILURE (Status))
705167802Sjkim            {
706167802Sjkim                return (Status);
707167802Sjkim            }
708167802Sjkim        }
709167802Sjkim    }
710167802Sjkim
711167802Sjkim    return (AE_OK);
712167802Sjkim}
713167802Sjkim
714167802Sjkim
715167802Sjkim/*******************************************************************************
716167802Sjkim *
717167802Sjkim * FUNCTION:    AcpiDmXrefDescendingOp
718167802Sjkim *
719167802Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
720167802Sjkim *
721167802Sjkim * RETURN:      Status
722167802Sjkim *
723167802Sjkim * DESCRIPTION: Descending handler for namespace cross reference
724167802Sjkim *
725167802Sjkim ******************************************************************************/
726167802Sjkim
727167802Sjkimstatic ACPI_STATUS
728167802SjkimAcpiDmXrefDescendingOp (
729167802Sjkim    ACPI_PARSE_OBJECT       *Op,
730167802Sjkim    UINT32                  Level,
731167802Sjkim    void                    *Context)
732167802Sjkim{
733167802Sjkim    ACPI_OP_WALK_INFO       *Info = Context;
734167802Sjkim    const ACPI_OPCODE_INFO  *OpInfo;
735167802Sjkim    ACPI_WALK_STATE         *WalkState;
736167802Sjkim    ACPI_OBJECT_TYPE        ObjectType;
737193529Sjkim    ACPI_OBJECT_TYPE        ObjectType2;
738167802Sjkim    ACPI_STATUS             Status;
739167802Sjkim    char                    *Path = NULL;
740167802Sjkim    ACPI_PARSE_OBJECT       *NextOp;
741167802Sjkim    ACPI_NAMESPACE_NODE     *Node;
742193529Sjkim    ACPI_OPERAND_OBJECT     *Object;
743212761Sjkim    UINT32                  ParamCount = 0;
744167802Sjkim
745167802Sjkim
746167802Sjkim    WalkState = Info->WalkState;
747167802Sjkim    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
748167802Sjkim    ObjectType = OpInfo->ObjectType;
749167802Sjkim    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
750167802Sjkim
751167802Sjkim    if ((!(OpInfo->Flags & AML_NAMED)) &&
752167802Sjkim        (!(OpInfo->Flags & AML_CREATE)) &&
753167802Sjkim        (Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
754167802Sjkim    {
755167802Sjkim        goto Exit;
756167802Sjkim    }
757167802Sjkim
758167802Sjkim    /* Get the NamePath from the appropriate place */
759167802Sjkim
760167802Sjkim    if (OpInfo->Flags & AML_NAMED)
761167802Sjkim    {
762235945Sjkim        /*
763235945Sjkim         * Only these two operators (Alias, Scope) refer to an existing
764235945Sjkim         * name, it is the first argument
765235945Sjkim         */
766235945Sjkim        if (Op->Common.AmlOpcode == AML_ALIAS_OP)
767167802Sjkim        {
768235945Sjkim            ObjectType = ACPI_TYPE_ANY;
769235945Sjkim
770235945Sjkim            NextOp = Op->Common.Value.Arg;
771235945Sjkim            NextOp = NextOp->Common.Value.Arg;
772235945Sjkim            if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
773235945Sjkim            {
774235945Sjkim                Path = NextOp->Common.Value.String;
775235945Sjkim            }
776235945Sjkim        }
777235945Sjkim        else if (Op->Common.AmlOpcode == AML_SCOPE_OP)
778235945Sjkim        {
779167802Sjkim            Path = (char *) Op->Named.Path;
780167802Sjkim        }
781167802Sjkim    }
782167802Sjkim    else if (OpInfo->Flags & AML_CREATE)
783167802Sjkim    {
784167802Sjkim        /* Referenced Buffer Name is the first child */
785167802Sjkim
786235945Sjkim        ObjectType = ACPI_TYPE_BUFFER; /* Change from TYPE_BUFFER_FIELD */
787235945Sjkim
788167802Sjkim        NextOp = Op->Common.Value.Arg;
789167802Sjkim        if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
790167802Sjkim        {
791167802Sjkim            Path = NextOp->Common.Value.String;
792167802Sjkim        }
793167802Sjkim    }
794167802Sjkim    else
795167802Sjkim    {
796167802Sjkim        Path = Op->Common.Value.String;
797167802Sjkim    }
798167802Sjkim
799167802Sjkim    if (!Path)
800167802Sjkim    {
801167802Sjkim        goto Exit;
802167802Sjkim    }
803167802Sjkim
804167802Sjkim    /*
805241973Sjkim     * Lookup the name in the namespace. Name must exist at this point, or it
806167802Sjkim     * is an invalid reference.
807167802Sjkim     *
808167802Sjkim     * The namespace is also used as a lookup table for references to resource
809167802Sjkim     * descriptors and the fields within them.
810167802Sjkim     */
811167802Sjkim    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
812167802Sjkim                ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
813167802Sjkim                WalkState, &Node);
814235945Sjkim    if (ACPI_SUCCESS (Status) && (Node->Flags & ANOBJ_IS_EXTERNAL))
815235945Sjkim    {
816235945Sjkim        Status = AE_NOT_FOUND;
817235945Sjkim    }
818235945Sjkim
819167802Sjkim    if (ACPI_FAILURE (Status))
820167802Sjkim    {
821167802Sjkim        if (Status == AE_NOT_FOUND)
822167802Sjkim        {
823198237Sjkim            AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType, 0);
824167802Sjkim
825167802Sjkim            /*
826167802Sjkim             * We could install this into the namespace, but we catch duplicate
827167802Sjkim             * externals when they are added to the list.
828167802Sjkim             */
829167802Sjkim#if 0
830167802Sjkim            Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
831167802Sjkim                       ACPI_IMODE_LOAD_PASS1, ACPI_NS_DONT_OPEN_SCOPE,
832167802Sjkim                       WalkState, &Node);
833167802Sjkim#endif
834167802Sjkim        }
835167802Sjkim    }
836193529Sjkim
837193529Sjkim    /*
838193529Sjkim     * Found the node in external table, add it to external list
839193529Sjkim     * Node->OwnerId == 0 indicates built-in ACPI Names, _OS_ etc
840193529Sjkim     */
841193529Sjkim    else if (Node->OwnerId && WalkState->OwnerId != Node->OwnerId)
842193529Sjkim    {
843193529Sjkim        ObjectType2 = ObjectType;
844193529Sjkim
845193529Sjkim        Object = AcpiNsGetAttachedObject (Node);
846193529Sjkim        if (Object)
847193529Sjkim        {
848193529Sjkim            ObjectType2 = Object->Common.Type;
849212761Sjkim            if (ObjectType2 == ACPI_TYPE_METHOD)
850212761Sjkim            {
851212761Sjkim                ParamCount = Object->Method.ParamCount;
852212761Sjkim            }
853193529Sjkim        }
854193529Sjkim
855246849Sjkim        AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType2, ParamCount | 0x80);
856193529Sjkim        Op->Common.Node = Node;
857193529Sjkim    }
858167802Sjkim    else
859167802Sjkim    {
860167802Sjkim        Op->Common.Node = Node;
861167802Sjkim    }
862167802Sjkim
863167802Sjkim
864167802SjkimExit:
865167802Sjkim    /* Open new scope if necessary */
866167802Sjkim
867167802Sjkim    if (AcpiNsOpensScope (ObjectType))
868167802Sjkim    {
869167802Sjkim        if (Op->Common.Node)
870167802Sjkim        {
871167802Sjkim            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
872167802Sjkim            if (ACPI_FAILURE (Status))
873167802Sjkim            {
874167802Sjkim                return (Status);
875167802Sjkim            }
876167802Sjkim        }
877167802Sjkim    }
878167802Sjkim
879167802Sjkim    return (AE_OK);
880167802Sjkim}
881167802Sjkim
882167802Sjkim
883167802Sjkim/*******************************************************************************
884167802Sjkim *
885167802Sjkim * FUNCTION:    AcpiDmResourceDescendingOp
886167802Sjkim *
887167802Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
888167802Sjkim *
889167802Sjkim * RETURN:      None
890167802Sjkim *
891167802Sjkim * DESCRIPTION: Process one parse op during symbolic resource index conversion.
892167802Sjkim *
893167802Sjkim ******************************************************************************/
894167802Sjkim
895167802Sjkimstatic ACPI_STATUS
896167802SjkimAcpiDmResourceDescendingOp (
897167802Sjkim    ACPI_PARSE_OBJECT       *Op,
898167802Sjkim    UINT32                  Level,
899167802Sjkim    void                    *Context)
900167802Sjkim{
901167802Sjkim    ACPI_OP_WALK_INFO       *Info = Context;
902167802Sjkim    const ACPI_OPCODE_INFO  *OpInfo;
903167802Sjkim    ACPI_WALK_STATE         *WalkState;
904167802Sjkim    ACPI_OBJECT_TYPE        ObjectType;
905167802Sjkim    ACPI_STATUS             Status;
906167802Sjkim
907167802Sjkim
908167802Sjkim    WalkState = Info->WalkState;
909167802Sjkim    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
910167802Sjkim
911167802Sjkim    /* Open new scope if necessary */
912167802Sjkim
913167802Sjkim    ObjectType = OpInfo->ObjectType;
914167802Sjkim    if (AcpiNsOpensScope (ObjectType))
915167802Sjkim    {
916167802Sjkim        if (Op->Common.Node)
917167802Sjkim        {
918167802Sjkim
919167802Sjkim            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState);
920167802Sjkim            if (ACPI_FAILURE (Status))
921167802Sjkim            {
922167802Sjkim                return (Status);
923167802Sjkim            }
924167802Sjkim        }
925167802Sjkim    }
926167802Sjkim
927167802Sjkim    /*
928167802Sjkim     * Check if this operator contains a reference to a resource descriptor.
929167802Sjkim     * If so, convert the reference into a symbolic reference.
930167802Sjkim     */
931167802Sjkim    AcpiDmCheckResourceReference (Op, WalkState);
932167802Sjkim    return (AE_OK);
933167802Sjkim}
934167802Sjkim
935167802Sjkim
936167802Sjkim/*******************************************************************************
937167802Sjkim *
938167802Sjkim * FUNCTION:    AcpiDmCommonAscendingOp
939167802Sjkim *
940167802Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
941167802Sjkim *
942167802Sjkim * RETURN:      None
943167802Sjkim *
944167802Sjkim * DESCRIPTION: Ascending handler for combined parse/namespace walks. Closes
945167802Sjkim *              scope if necessary.
946167802Sjkim *
947167802Sjkim ******************************************************************************/
948167802Sjkim
949167802Sjkimstatic ACPI_STATUS
950167802SjkimAcpiDmCommonAscendingOp (
951167802Sjkim    ACPI_PARSE_OBJECT       *Op,
952167802Sjkim    UINT32                  Level,
953167802Sjkim    void                    *Context)
954167802Sjkim{
955167802Sjkim    ACPI_OP_WALK_INFO       *Info = Context;
956167802Sjkim    const ACPI_OPCODE_INFO  *OpInfo;
957167802Sjkim    ACPI_OBJECT_TYPE        ObjectType;
958167802Sjkim
959167802Sjkim
960167802Sjkim    /* Close scope if necessary */
961167802Sjkim
962167802Sjkim    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
963167802Sjkim    ObjectType = OpInfo->ObjectType;
964167802Sjkim    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
965167802Sjkim
966167802Sjkim    if (AcpiNsOpensScope (ObjectType))
967167802Sjkim    {
968167802Sjkim        (void) AcpiDsScopeStackPop (Info->WalkState);
969167802Sjkim    }
970167802Sjkim
971167802Sjkim    return (AE_OK);
972167802Sjkim}
973167802Sjkim
974167802Sjkim
975167802Sjkim/*******************************************************************************
976167802Sjkim *
977167802Sjkim * FUNCTION:    AcpiDmInspectPossibleArgs
978167802Sjkim *
979167802Sjkim * PARAMETERS:  CurrentOpArgCount   - Which arg of the current op was the
980167802Sjkim *                                    possible method invocation found
981167802Sjkim *              TargetCount         - Number of targets (0,1,2) for this op
982167802Sjkim *              Op                  - Parse op
983167802Sjkim *
984167802Sjkim * RETURN:      Status
985167802Sjkim *
986167802Sjkim * DESCRIPTION: Examine following args and next ops for possible arguments
987167802Sjkim *              for an unrecognized method invocation.
988167802Sjkim *
989167802Sjkim ******************************************************************************/
990167802Sjkim
991167802Sjkimstatic UINT32
992167802SjkimAcpiDmInspectPossibleArgs (
993167802Sjkim    UINT32                  CurrentOpArgCount,
994167802Sjkim    UINT32                  TargetCount,
995167802Sjkim    ACPI_PARSE_OBJECT       *Op)
996167802Sjkim{
997167802Sjkim    const ACPI_OPCODE_INFO  *OpInfo;
998167802Sjkim    UINT32                  i;
999167802Sjkim    UINT32                  Last = 0;
1000167802Sjkim    UINT32                  Lookahead;
1001167802Sjkim
1002167802Sjkim
1003167802Sjkim    Lookahead = (ACPI_METHOD_NUM_ARGS + TargetCount) - CurrentOpArgCount;
1004167802Sjkim
1005167802Sjkim    /* Lookahead for the maximum number of possible arguments */
1006167802Sjkim
1007167802Sjkim    for (i = 0; i < Lookahead; i++)
1008167802Sjkim    {
1009167802Sjkim        if (!Op)
1010167802Sjkim        {
1011167802Sjkim            break;
1012167802Sjkim        }
1013167802Sjkim
1014167802Sjkim        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1015167802Sjkim
1016167802Sjkim        /*
1017167802Sjkim         * Any one of these operators is "very probably" not a method arg
1018167802Sjkim         */
1019167802Sjkim        if ((Op->Common.AmlOpcode == AML_STORE_OP) ||
1020167802Sjkim            (Op->Common.AmlOpcode == AML_NOTIFY_OP))
1021167802Sjkim        {
1022167802Sjkim            break;
1023167802Sjkim        }
1024167802Sjkim
1025167802Sjkim        if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
1026167802Sjkim            (OpInfo->Class != AML_CLASS_CONTROL))
1027167802Sjkim        {
1028167802Sjkim            Last = i+1;
1029167802Sjkim        }
1030167802Sjkim
1031167802Sjkim        Op = Op->Common.Next;
1032167802Sjkim    }
1033167802Sjkim
1034167802Sjkim    return (Last);
1035167802Sjkim}
1036