1167802Sjkim/******************************************************************************
2167802Sjkim *
3167802Sjkim * Module Name: adwalk - Application-level disassembler parse tree walk routines
4167802Sjkim *
5167802Sjkim *****************************************************************************/
6167802Sjkim
7316303Sjkim/******************************************************************************
8316303Sjkim *
9316303Sjkim * 1. Copyright Notice
10316303Sjkim *
11316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
12167802Sjkim * All rights reserved.
13167802Sjkim *
14316303Sjkim * 2. License
15316303Sjkim *
16316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property
17316303Sjkim * rights. You may have additional license terms from the party that provided
18316303Sjkim * you this software, covering your right to use that party's intellectual
19316303Sjkim * property rights.
20316303Sjkim *
21316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22316303Sjkim * copy of the source code appearing in this file ("Covered Code") an
23316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy,
25316303Sjkim * make derivatives, distribute, use and display any portion of the Covered
26316303Sjkim * Code in any form, with the right to sublicense such rights; and
27316303Sjkim *
28316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29316303Sjkim * license (with the right to sublicense), under only those claims of Intel
30316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell,
31316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof
32316303Sjkim * solely to the minimum extent necessary to exercise the above copyright
33316303Sjkim * license, and in no event shall the patent license extend to any additions
34316303Sjkim * to or modifications of the Original Intel Code. No other license or right
35316303Sjkim * is granted directly or by implication, estoppel or otherwise;
36316303Sjkim *
37316303Sjkim * The above copyright and patent license is granted only if the following
38316303Sjkim * conditions are met:
39316303Sjkim *
40316303Sjkim * 3. Conditions
41316303Sjkim *
42316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43316303Sjkim * Redistribution of source code of any substantial portion of the Covered
44316303Sjkim * Code or modification with rights to further distribute source must include
45316303Sjkim * the above Copyright Notice, the above License, this list of Conditions,
46316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition,
47316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to
48316303Sjkim * contain a file documenting the changes Licensee made to create that Covered
49316303Sjkim * Code and the date of any change. Licensee must include in that file the
50316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee
51316303Sjkim * must include a prominent statement that the modification is derived,
52316303Sjkim * directly or indirectly, from Original Intel Code.
53316303Sjkim *
54316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55316303Sjkim * Redistribution of source code of any substantial portion of the Covered
56316303Sjkim * Code or modification without rights to further distribute source must
57316303Sjkim * include the following Disclaimer and Export Compliance provision in the
58316303Sjkim * documentation and/or other materials provided with distribution. In
59316303Sjkim * addition, Licensee may not authorize further sublicense of source of any
60316303Sjkim * portion of the Covered Code, and must include terms to the effect that the
61316303Sjkim * license from Licensee to its licensee is limited to the intellectual
62316303Sjkim * property embodied in the software Licensee provides to its licensee, and
63316303Sjkim * not to intellectual property embodied in modifications its licensee may
64316303Sjkim * make.
65316303Sjkim *
66316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any
67316303Sjkim * substantial portion of the Covered Code or modification must reproduce the
68316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance
69316303Sjkim * provision in the documentation and/or other materials provided with the
70316303Sjkim * distribution.
71316303Sjkim *
72316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original
73316303Sjkim * Intel Code.
74316303Sjkim *
75316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or
77316303Sjkim * other dealings in products derived from or relating to the Covered Code
78316303Sjkim * without prior written authorization from Intel.
79316303Sjkim *
80316303Sjkim * 4. Disclaimer and Export Compliance
81316303Sjkim *
82316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88316303Sjkim * PARTICULAR PURPOSE.
89316303Sjkim *
90316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97316303Sjkim * LIMITED REMEDY.
98316303Sjkim *
99316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this
100316303Sjkim * software or system incorporating such software without first obtaining any
101316303Sjkim * required license or other approval from the U. S. Department of Commerce or
102316303Sjkim * any other agency or department of the United States Government. In the
103316303Sjkim * event Licensee exports any such software from the United States or
104316303Sjkim * re-exports any such software from a foreign destination, Licensee shall
105316303Sjkim * ensure that the distribution and export/re-export of the software is in
106316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the
107316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108316303Sjkim * any of its subsidiaries will export/re-export any technical data, process,
109316303Sjkim * software, or service, directly or indirectly, to any country for which the
110316303Sjkim * United States government or any agency thereof requires an export license,
111316303Sjkim * other governmental approval, or letter of assurance, without first obtaining
112316303Sjkim * such license, approval or letter.
113316303Sjkim *
114316303Sjkim *****************************************************************************
115316303Sjkim *
116316303Sjkim * Alternatively, you may choose to be licensed under the terms of the
117316303Sjkim * following license:
118316303Sjkim *
119217365Sjkim * Redistribution and use in source and binary forms, with or without
120217365Sjkim * modification, are permitted provided that the following conditions
121217365Sjkim * are met:
122217365Sjkim * 1. Redistributions of source code must retain the above copyright
123217365Sjkim *    notice, this list of conditions, and the following disclaimer,
124217365Sjkim *    without modification.
125217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
127217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
128217365Sjkim *    including a substantially similar Disclaimer requirement for further
129217365Sjkim *    binary redistribution.
130217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
131217365Sjkim *    of any contributors may be used to endorse or promote products derived
132217365Sjkim *    from this software without specific prior written permission.
133167802Sjkim *
134316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145316303Sjkim *
146316303Sjkim * Alternatively, you may choose to be licensed under the terms of the
147217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
148217365Sjkim * Software Foundation.
149167802Sjkim *
150316303Sjkim *****************************************************************************/
151167802Sjkim
152193529Sjkim#include <contrib/dev/acpica/include/acpi.h>
153193529Sjkim#include <contrib/dev/acpica/include/accommon.h>
154193529Sjkim#include <contrib/dev/acpica/include/acparser.h>
155193529Sjkim#include <contrib/dev/acpica/include/amlcode.h>
156193529Sjkim#include <contrib/dev/acpica/include/acdisasm.h>
157193529Sjkim#include <contrib/dev/acpica/include/acdispat.h>
158193529Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
159193529Sjkim#include <contrib/dev/acpica/include/acapps.h>
160167802Sjkim
161167802Sjkim
162167802Sjkim#define _COMPONENT          ACPI_TOOLS
163167802Sjkim        ACPI_MODULE_NAME    ("adwalk")
164167802Sjkim
165167802Sjkim/*
166167802Sjkim * aslmap - opcode mappings and reserved method names
167167802Sjkim */
168167802SjkimACPI_OBJECT_TYPE
169167802SjkimAslMapNamedOpcodeToDataType (
170167802Sjkim    UINT16                  Opcode);
171167802Sjkim
172167802Sjkim/* Local prototypes */
173167802Sjkim
174167802Sjkimstatic ACPI_STATUS
175167802SjkimAcpiDmFindOrphanDescending (
176167802Sjkim    ACPI_PARSE_OBJECT       *Op,
177167802Sjkim    UINT32                  Level,
178167802Sjkim    void                    *Context);
179167802Sjkim
180167802Sjkimstatic ACPI_STATUS
181167802SjkimAcpiDmDumpDescending (
182167802Sjkim    ACPI_PARSE_OBJECT       *Op,
183167802Sjkim    UINT32                  Level,
184167802Sjkim    void                    *Context);
185167802Sjkim
186167802Sjkimstatic ACPI_STATUS
187167802SjkimAcpiDmXrefDescendingOp (
188167802Sjkim    ACPI_PARSE_OBJECT       *Op,
189167802Sjkim    UINT32                  Level,
190167802Sjkim    void                    *Context);
191167802Sjkim
192167802Sjkimstatic ACPI_STATUS
193167802SjkimAcpiDmCommonAscendingOp (
194167802Sjkim    ACPI_PARSE_OBJECT       *Op,
195167802Sjkim    UINT32                  Level,
196167802Sjkim    void                    *Context);
197167802Sjkim
198167802Sjkimstatic ACPI_STATUS
199167802SjkimAcpiDmLoadDescendingOp (
200167802Sjkim    ACPI_PARSE_OBJECT       *Op,
201167802Sjkim    UINT32                  Level,
202167802Sjkim    void                    *Context);
203167802Sjkim
204167802Sjkimstatic UINT32
205167802SjkimAcpiDmInspectPossibleArgs (
206167802Sjkim    UINT32                  CurrentOpArgCount,
207167802Sjkim    UINT32                  TargetCount,
208167802Sjkim    ACPI_PARSE_OBJECT       *Op);
209167802Sjkim
210167802Sjkimstatic ACPI_STATUS
211322877SjkimAcpiDmCommonDescendingOp (
212167802Sjkim    ACPI_PARSE_OBJECT       *Op,
213167802Sjkim    UINT32                  Level,
214167802Sjkim    void                    *Context);
215167802Sjkim
216322877Sjkimstatic ACPI_STATUS
217322877SjkimAcpiDmProcessResourceDescriptors (
218322877Sjkim    ACPI_PARSE_OBJECT       *Op,
219322877Sjkim    UINT32                  Level,
220322877Sjkim    void                    *Context);
221167802Sjkim
222167802Sjkim/*******************************************************************************
223167802Sjkim *
224167802Sjkim * FUNCTION:    AcpiDmDumpTree
225167802Sjkim *
226198237Sjkim * PARAMETERS:  Origin              - Starting object
227167802Sjkim *
228167802Sjkim * RETURN:      None
229167802Sjkim *
230167802Sjkim * DESCRIPTION: Parse tree walk to format and output the nodes
231167802Sjkim *
232167802Sjkim ******************************************************************************/
233167802Sjkim
234167802Sjkimvoid
235167802SjkimAcpiDmDumpTree (
236167802Sjkim    ACPI_PARSE_OBJECT       *Origin)
237167802Sjkim{
238167802Sjkim    ACPI_OP_WALK_INFO       Info;
239167802Sjkim
240167802Sjkim
241167802Sjkim    if (!Origin)
242167802Sjkim    {
243167802Sjkim        return;
244167802Sjkim    }
245167802Sjkim
246167802Sjkim    AcpiOsPrintf ("/*\nAML Parse Tree\n\n");
247167802Sjkim    Info.Flags = 0;
248167802Sjkim    Info.Count = 0;
249167802Sjkim    Info.Level = 0;
250167802Sjkim    Info.WalkState = NULL;
251298714Sjkim
252167802Sjkim    AcpiDmWalkParseTree (Origin, AcpiDmDumpDescending, NULL, &Info);
253167802Sjkim    AcpiOsPrintf ("*/\n\n");
254167802Sjkim}
255167802Sjkim
256167802Sjkim
257167802Sjkim/*******************************************************************************
258167802Sjkim *
259167802Sjkim * FUNCTION:    AcpiDmFindOrphanMethods
260167802Sjkim *
261198237Sjkim * PARAMETERS:  Origin              - Starting object
262167802Sjkim *
263167802Sjkim * RETURN:      None
264167802Sjkim *
265167802Sjkim * DESCRIPTION: Parse tree walk to find "orphaned" method invocations -- methods
266167802Sjkim *              that are not resolved in the namespace
267167802Sjkim *
268167802Sjkim ******************************************************************************/
269167802Sjkim
270167802Sjkimvoid
271167802SjkimAcpiDmFindOrphanMethods (
272167802Sjkim    ACPI_PARSE_OBJECT       *Origin)
273167802Sjkim{
274167802Sjkim    ACPI_OP_WALK_INFO       Info;
275167802Sjkim
276167802Sjkim
277167802Sjkim    if (!Origin)
278167802Sjkim    {
279167802Sjkim        return;
280167802Sjkim    }
281167802Sjkim
282167802Sjkim    Info.Flags = 0;
283167802Sjkim    Info.Level = 0;
284167802Sjkim    Info.WalkState = NULL;
285298714Sjkim
286167802Sjkim    AcpiDmWalkParseTree (Origin, AcpiDmFindOrphanDescending, NULL, &Info);
287167802Sjkim}
288167802Sjkim
289167802Sjkim
290167802Sjkim/*******************************************************************************
291167802Sjkim *
292167802Sjkim * FUNCTION:    AcpiDmFinishNamespaceLoad
293167802Sjkim *
294167802Sjkim * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
295167802Sjkim *              NamespaceRoot       - Root of the internal namespace
296193529Sjkim *              OwnerId             - OwnerId of the table to be disassembled
297167802Sjkim *
298167802Sjkim * RETURN:      None
299167802Sjkim *
300167802Sjkim * DESCRIPTION: Load all namespace items that are created within control
301167802Sjkim *              methods. Used before namespace cross reference
302167802Sjkim *
303167802Sjkim ******************************************************************************/
304167802Sjkim
305167802Sjkimvoid
306167802SjkimAcpiDmFinishNamespaceLoad (
307167802Sjkim    ACPI_PARSE_OBJECT       *ParseTreeRoot,
308193529Sjkim    ACPI_NAMESPACE_NODE     *NamespaceRoot,
309193529Sjkim    ACPI_OWNER_ID           OwnerId)
310167802Sjkim{
311167802Sjkim    ACPI_STATUS             Status;
312167802Sjkim    ACPI_OP_WALK_INFO       Info;
313167802Sjkim    ACPI_WALK_STATE         *WalkState;
314167802Sjkim
315167802Sjkim
316167802Sjkim    if (!ParseTreeRoot)
317167802Sjkim    {
318167802Sjkim        return;
319167802Sjkim    }
320167802Sjkim
321167802Sjkim    /* Create and initialize a new walk state */
322167802Sjkim
323193529Sjkim    WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
324167802Sjkim    if (!WalkState)
325167802Sjkim    {
326167802Sjkim        return;
327167802Sjkim    }
328167802Sjkim
329298714Sjkim    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type,
330298714Sjkim        WalkState);
331167802Sjkim    if (ACPI_FAILURE (Status))
332167802Sjkim    {
333167802Sjkim        return;
334167802Sjkim    }
335167802Sjkim
336167802Sjkim    Info.Flags = 0;
337167802Sjkim    Info.Level = 0;
338167802Sjkim    Info.WalkState = WalkState;
339298714Sjkim
340167802Sjkim    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmLoadDescendingOp,
341167802Sjkim        AcpiDmCommonAscendingOp, &Info);
342167802Sjkim    ACPI_FREE (WalkState);
343167802Sjkim}
344167802Sjkim
345167802Sjkim
346167802Sjkim/*******************************************************************************
347167802Sjkim *
348167802Sjkim * FUNCTION:    AcpiDmCrossReferenceNamespace
349167802Sjkim *
350167802Sjkim * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
351167802Sjkim *              NamespaceRoot       - Root of the internal namespace
352193529Sjkim *              OwnerId             - OwnerId of the table to be disassembled
353167802Sjkim *
354167802Sjkim * RETURN:      None
355167802Sjkim *
356167802Sjkim * DESCRIPTION: Cross reference the namespace to create externals
357167802Sjkim *
358167802Sjkim ******************************************************************************/
359167802Sjkim
360167802Sjkimvoid
361167802SjkimAcpiDmCrossReferenceNamespace (
362167802Sjkim    ACPI_PARSE_OBJECT       *ParseTreeRoot,
363193529Sjkim    ACPI_NAMESPACE_NODE     *NamespaceRoot,
364193529Sjkim    ACPI_OWNER_ID           OwnerId)
365167802Sjkim{
366167802Sjkim    ACPI_STATUS             Status;
367167802Sjkim    ACPI_OP_WALK_INFO       Info;
368167802Sjkim    ACPI_WALK_STATE         *WalkState;
369167802Sjkim
370167802Sjkim
371167802Sjkim    if (!ParseTreeRoot)
372167802Sjkim    {
373167802Sjkim        return;
374167802Sjkim    }
375167802Sjkim
376167802Sjkim    /* Create and initialize a new walk state */
377167802Sjkim
378193529Sjkim    WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
379167802Sjkim    if (!WalkState)
380167802Sjkim    {
381167802Sjkim        return;
382167802Sjkim    }
383167802Sjkim
384298714Sjkim    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type,
385298714Sjkim        WalkState);
386167802Sjkim    if (ACPI_FAILURE (Status))
387167802Sjkim    {
388167802Sjkim        return;
389167802Sjkim    }
390167802Sjkim
391167802Sjkim    Info.Flags = 0;
392167802Sjkim    Info.Level = 0;
393167802Sjkim    Info.WalkState = WalkState;
394298714Sjkim
395167802Sjkim    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmXrefDescendingOp,
396167802Sjkim        AcpiDmCommonAscendingOp, &Info);
397167802Sjkim    ACPI_FREE (WalkState);
398167802Sjkim}
399167802Sjkim
400167802Sjkim
401167802Sjkim/*******************************************************************************
402167802Sjkim *
403322877Sjkim * FUNCTION:    AcpiDmConvertParseObjects
404167802Sjkim *
405167802Sjkim * PARAMETERS:  ParseTreeRoot       - Root of the parse tree
406167802Sjkim *              NamespaceRoot       - Root of the internal namespace
407167802Sjkim *
408167802Sjkim * RETURN:      None
409167802Sjkim *
410322877Sjkim * DESCRIPTION: Begin parse tree walk to perform conversions needed for
411322877Sjkim *              disassembly. These include resource descriptors and switch/case
412322877Sjkim *              operations.
413167802Sjkim *
414167802Sjkim ******************************************************************************/
415167802Sjkim
416167802Sjkimvoid
417322877SjkimAcpiDmConvertParseObjects (
418167802Sjkim    ACPI_PARSE_OBJECT       *ParseTreeRoot,
419167802Sjkim    ACPI_NAMESPACE_NODE     *NamespaceRoot)
420167802Sjkim{
421167802Sjkim    ACPI_STATUS             Status;
422167802Sjkim    ACPI_OP_WALK_INFO       Info;
423167802Sjkim    ACPI_WALK_STATE         *WalkState;
424167802Sjkim
425167802Sjkim
426167802Sjkim    if (!ParseTreeRoot)
427167802Sjkim    {
428167802Sjkim        return;
429167802Sjkim    }
430167802Sjkim
431167802Sjkim    /* Create and initialize a new walk state */
432167802Sjkim
433167802Sjkim    WalkState = AcpiDsCreateWalkState (0, ParseTreeRoot, NULL, NULL);
434167802Sjkim    if (!WalkState)
435167802Sjkim    {
436167802Sjkim        return;
437167802Sjkim    }
438167802Sjkim
439298714Sjkim    Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type,
440298714Sjkim        WalkState);
441167802Sjkim    if (ACPI_FAILURE (Status))
442167802Sjkim    {
443298714Sjkim        ACPI_FREE (WalkState);
444167802Sjkim        return;
445167802Sjkim    }
446167802Sjkim
447167802Sjkim    Info.Flags = 0;
448167802Sjkim    Info.Level = 0;
449167802Sjkim    Info.WalkState = WalkState;
450298714Sjkim
451322877Sjkim    AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmCommonDescendingOp,
452167802Sjkim        AcpiDmCommonAscendingOp, &Info);
453167802Sjkim    ACPI_FREE (WalkState);
454322877Sjkim
455322877Sjkim    if (AcpiGbl_TempListHead) {
456322877Sjkim        AcpiDmClearTempList();
457322877Sjkim    }
458322877Sjkim
459167802Sjkim    return;
460167802Sjkim}
461167802Sjkim
462167802Sjkim
463167802Sjkim/*******************************************************************************
464167802Sjkim *
465167802Sjkim * FUNCTION:    AcpiDmDumpDescending
466167802Sjkim *
467167802Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
468167802Sjkim *
469167802Sjkim * RETURN:      Status
470167802Sjkim *
471167802Sjkim * DESCRIPTION: Format and print contents of one parse Op.
472167802Sjkim *
473167802Sjkim ******************************************************************************/
474167802Sjkim
475167802Sjkimstatic ACPI_STATUS
476167802SjkimAcpiDmDumpDescending (
477167802Sjkim    ACPI_PARSE_OBJECT       *Op,
478167802Sjkim    UINT32                  Level,
479167802Sjkim    void                    *Context)
480167802Sjkim{
481167802Sjkim    ACPI_OP_WALK_INFO       *Info = Context;
482167802Sjkim    char                    *Path;
483167802Sjkim
484167802Sjkim
485167802Sjkim    if (!Op)
486167802Sjkim    {
487167802Sjkim        return (AE_OK);
488167802Sjkim    }
489167802Sjkim
490167802Sjkim    /* Most of the information (count, level, name) here */
491167802Sjkim
492198237Sjkim    Info->Count++;
493167802Sjkim    AcpiOsPrintf ("% 5d [%2.2d] ", Info->Count, Level);
494167802Sjkim    AcpiDmIndent (Level);
495167802Sjkim    AcpiOsPrintf ("%-28s", AcpiPsGetOpcodeName (Op->Common.AmlOpcode));
496167802Sjkim
497167802Sjkim    /* Extra info is helpful */
498167802Sjkim
499167802Sjkim    switch (Op->Common.AmlOpcode)
500167802Sjkim    {
501167802Sjkim    case AML_BYTE_OP:
502254745Sjkim
503254745Sjkim        AcpiOsPrintf ("%2.2X", (UINT32) Op->Common.Value.Integer);
504254745Sjkim        break;
505254745Sjkim
506167802Sjkim    case AML_WORD_OP:
507254745Sjkim
508254745Sjkim        AcpiOsPrintf ("%4.4X", (UINT32) Op->Common.Value.Integer);
509254745Sjkim        break;
510254745Sjkim
511167802Sjkim    case AML_DWORD_OP:
512250838Sjkim
513254745Sjkim        AcpiOsPrintf ("%8.8X", (UINT32) Op->Common.Value.Integer);
514167802Sjkim        break;
515167802Sjkim
516228110Sjkim    case AML_QWORD_OP:
517250838Sjkim
518228110Sjkim        AcpiOsPrintf ("%8.8X%8.8X", ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
519228110Sjkim        break;
520228110Sjkim
521167802Sjkim    case AML_INT_NAMEPATH_OP:
522250838Sjkim
523167802Sjkim        if (Op->Common.Value.String)
524167802Sjkim        {
525167802Sjkim            AcpiNsExternalizeName (ACPI_UINT32_MAX, Op->Common.Value.String,
526298714Sjkim                NULL, &Path);
527167802Sjkim            AcpiOsPrintf ("%s %p", Path, Op->Common.Node);
528167802Sjkim            ACPI_FREE (Path);
529167802Sjkim        }
530167802Sjkim        else
531167802Sjkim        {
532167802Sjkim            AcpiOsPrintf ("[NULL]");
533167802Sjkim        }
534167802Sjkim        break;
535167802Sjkim
536167802Sjkim    case AML_NAME_OP:
537167802Sjkim    case AML_METHOD_OP:
538167802Sjkim    case AML_DEVICE_OP:
539322877Sjkim
540322877Sjkim        AcpiOsPrintf ("%4.4s",
541322877Sjkim            ACPI_CAST_PTR (char, &Op->Named.Name));
542322877Sjkim        break;
543322877Sjkim
544167802Sjkim    case AML_INT_NAMEDFIELD_OP:
545250838Sjkim
546322877Sjkim        AcpiOsPrintf ("%4.4s Length: (bits) %8.8X%8.8X (bytes) %8.8X%8.8X",
547322877Sjkim            ACPI_CAST_PTR (char, &Op->Named.Name),
548322877Sjkim            ACPI_FORMAT_UINT64 (Op->Common.Value.Integer),
549322877Sjkim            ACPI_FORMAT_UINT64 (Op->Common.Value.Integer / 8));
550167802Sjkim        break;
551193529Sjkim
552322877Sjkim
553193529Sjkim    default:
554250838Sjkim
555193529Sjkim        break;
556167802Sjkim    }
557167802Sjkim
558167802Sjkim    AcpiOsPrintf ("\n");
559167802Sjkim    return (AE_OK);
560167802Sjkim}
561167802Sjkim
562167802Sjkim
563167802Sjkim/*******************************************************************************
564167802Sjkim *
565167802Sjkim * FUNCTION:    AcpiDmFindOrphanDescending
566167802Sjkim *
567167802Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
568167802Sjkim *
569167802Sjkim * RETURN:      Status
570167802Sjkim *
571167802Sjkim * DESCRIPTION: Check namepath Ops for orphaned method invocations
572167802Sjkim *
573298714Sjkim * Note: Parts of this are experimental, under possible further development.
574167802Sjkim *
575167802Sjkim ******************************************************************************/
576167802Sjkim
577167802Sjkimstatic ACPI_STATUS
578167802SjkimAcpiDmFindOrphanDescending (
579167802Sjkim    ACPI_PARSE_OBJECT       *Op,
580167802Sjkim    UINT32                  Level,
581167802Sjkim    void                    *Context)
582167802Sjkim{
583167802Sjkim    const ACPI_OPCODE_INFO  *OpInfo;
584167802Sjkim    ACPI_PARSE_OBJECT       *ChildOp;
585167802Sjkim    ACPI_PARSE_OBJECT       *NextOp;
586167802Sjkim    ACPI_PARSE_OBJECT       *ParentOp;
587167802Sjkim    UINT32                  ArgCount;
588167802Sjkim
589167802Sjkim
590167802Sjkim    if (!Op)
591167802Sjkim    {
592167802Sjkim        return (AE_OK);
593167802Sjkim    }
594167802Sjkim
595167802Sjkim    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
596167802Sjkim
597167802Sjkim    switch (Op->Common.AmlOpcode)
598167802Sjkim    {
599167802Sjkim#ifdef ACPI_UNDER_DEVELOPMENT
600167802Sjkim    case AML_ADD_OP:
601250838Sjkim
602167802Sjkim        ChildOp = Op->Common.Value.Arg;
603167802Sjkim        if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
604167802Sjkim            !ChildOp->Common.Node)
605167802Sjkim        {
606167802Sjkim            AcpiNsExternalizeName (ACPI_UINT32_MAX, ChildOp->Common.Value.String,
607272444Sjkim                NULL, &Path);
608272444Sjkim            AcpiOsPrintf ("/* %-16s A-NAMEPATH: %s  */\n",
609272444Sjkim                Op->Common.AmlOpName, Path);
610167802Sjkim            ACPI_FREE (Path);
611167802Sjkim
612167802Sjkim            NextOp = Op->Common.Next;
613167802Sjkim            if (!NextOp)
614167802Sjkim            {
615167802Sjkim                /* This NamePath has no args, assume it is an integer */
616167802Sjkim
617272444Sjkim                AcpiDmAddOpToExternalList (ChildOp,
618272444Sjkim                    ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
619167802Sjkim                return (AE_OK);
620167802Sjkim            }
621167802Sjkim
622167802Sjkim            ArgCount = AcpiDmInspectPossibleArgs (3, 1, NextOp);
623272444Sjkim            AcpiOsPrintf ("/* A-CHILDREN: %u Actual %u */\n",
624272444Sjkim                ArgCount, AcpiDmCountChildren (Op));
625167802Sjkim
626167802Sjkim            if (ArgCount < 1)
627167802Sjkim            {
628167802Sjkim                /* One Arg means this is just a Store(Name,Target) */
629167802Sjkim
630272444Sjkim                AcpiDmAddOpToExternalList (ChildOp,
631272444Sjkim                    ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
632167802Sjkim                return (AE_OK);
633167802Sjkim            }
634167802Sjkim
635272444Sjkim            AcpiDmAddOpToExternalList (ChildOp,
636272444Sjkim                ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
637167802Sjkim        }
638167802Sjkim        break;
639298714Sjkim
640167802Sjkim#endif
641167802Sjkim
642167802Sjkim    case AML_STORE_OP:
643167802Sjkim
644167802Sjkim        ChildOp = Op->Common.Value.Arg;
645167802Sjkim        if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
646167802Sjkim            !ChildOp->Common.Node)
647167802Sjkim        {
648167802Sjkim            NextOp = Op->Common.Next;
649167802Sjkim            if (!NextOp)
650167802Sjkim            {
651167802Sjkim                /* This NamePath has no args, assume it is an integer */
652167802Sjkim
653272444Sjkim                AcpiDmAddOpToExternalList (ChildOp,
654272444Sjkim                    ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
655167802Sjkim                return (AE_OK);
656167802Sjkim            }
657167802Sjkim
658167802Sjkim            ArgCount = AcpiDmInspectPossibleArgs (2, 1, NextOp);
659167802Sjkim            if (ArgCount <= 1)
660167802Sjkim            {
661167802Sjkim                /* One Arg means this is just a Store(Name,Target) */
662167802Sjkim
663272444Sjkim                AcpiDmAddOpToExternalList (ChildOp,
664298714Sjkim                    ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, ArgCount, 0);
665167802Sjkim                return (AE_OK);
666167802Sjkim            }
667167802Sjkim
668272444Sjkim            AcpiDmAddOpToExternalList (ChildOp,
669272444Sjkim                ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
670167802Sjkim        }
671167802Sjkim        break;
672167802Sjkim
673167802Sjkim    case AML_INT_NAMEPATH_OP:
674167802Sjkim
675167802Sjkim        /* Must examine parent to see if this namepath is an argument */
676167802Sjkim
677167802Sjkim        ParentOp = Op->Common.Parent;
678167802Sjkim        OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
679167802Sjkim
680167802Sjkim        if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
681167802Sjkim            (OpInfo->Class != AML_CLASS_CREATE) &&
682235945Sjkim            (OpInfo->ObjectType != ACPI_TYPE_LOCAL_ALIAS) &&
683167802Sjkim            (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
684167802Sjkim            !Op->Common.Node)
685167802Sjkim        {
686298714Sjkim            ArgCount = AcpiDmInspectPossibleArgs (0, 0, Op);
687167802Sjkim
688167802Sjkim            /*
689167802Sjkim             * Check if namepath is a predicate for if/while or lone parameter to
690167802Sjkim             * a return.
691167802Sjkim             */
692167802Sjkim            if (ArgCount == 0)
693167802Sjkim            {
694167802Sjkim                if (((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
695167802Sjkim                     (ParentOp->Common.AmlOpcode == AML_WHILE_OP) ||
696167802Sjkim                     (ParentOp->Common.AmlOpcode == AML_RETURN_OP)) &&
697167802Sjkim
698167802Sjkim                     /* And namepath is the first argument */
699167802Sjkim                     (ParentOp->Common.Value.Arg == Op))
700167802Sjkim                {
701272444Sjkim                    AcpiDmAddOpToExternalList (Op,
702272444Sjkim                        Op->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
703167802Sjkim                    break;
704167802Sjkim                }
705167802Sjkim            }
706167802Sjkim
707167802Sjkim            /*
708167802Sjkim             * This is a standalone namestring (not a parameter to another
709167802Sjkim             * operator) - it *must* be a method invocation, nothing else is
710167802Sjkim             * grammatically possible.
711167802Sjkim             */
712272444Sjkim            AcpiDmAddOpToExternalList (Op,
713272444Sjkim                Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
714167802Sjkim        }
715167802Sjkim        break;
716193529Sjkim
717193529Sjkim    default:
718250838Sjkim
719193529Sjkim        break;
720167802Sjkim    }
721167802Sjkim
722167802Sjkim    return (AE_OK);
723167802Sjkim}
724167802Sjkim
725167802Sjkim
726167802Sjkim/*******************************************************************************
727167802Sjkim *
728167802Sjkim * FUNCTION:    AcpiDmLoadDescendingOp
729167802Sjkim *
730167802Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
731167802Sjkim *
732167802Sjkim * RETURN:      Status
733167802Sjkim *
734167802Sjkim * DESCRIPTION: Descending handler for namespace control method object load
735167802Sjkim *
736167802Sjkim ******************************************************************************/
737167802Sjkim
738167802Sjkimstatic ACPI_STATUS
739167802SjkimAcpiDmLoadDescendingOp (
740167802Sjkim    ACPI_PARSE_OBJECT       *Op,
741167802Sjkim    UINT32                  Level,
742167802Sjkim    void                    *Context)
743167802Sjkim{
744167802Sjkim    ACPI_OP_WALK_INFO       *Info = Context;
745167802Sjkim    const ACPI_OPCODE_INFO  *OpInfo;
746167802Sjkim    ACPI_WALK_STATE         *WalkState;
747167802Sjkim    ACPI_OBJECT_TYPE        ObjectType;
748167802Sjkim    ACPI_STATUS             Status;
749167802Sjkim    char                    *Path = NULL;
750167802Sjkim    ACPI_PARSE_OBJECT       *NextOp;
751167802Sjkim    ACPI_NAMESPACE_NODE     *Node;
752193529Sjkim    char                    FieldPath[5];
753193529Sjkim    BOOLEAN                 PreDefined = FALSE;
754193529Sjkim    UINT8                   PreDefineIndex = 0;
755167802Sjkim
756167802Sjkim
757167802Sjkim    WalkState = Info->WalkState;
758167802Sjkim    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
759167802Sjkim    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
760167802Sjkim
761167802Sjkim    /* Only interested in operators that create new names */
762167802Sjkim
763167802Sjkim    if (!(OpInfo->Flags & AML_NAMED) &&
764167802Sjkim        !(OpInfo->Flags & AML_CREATE))
765167802Sjkim    {
766167802Sjkim        goto Exit;
767167802Sjkim    }
768167802Sjkim
769167802Sjkim    /* Get the NamePath from the appropriate place */
770167802Sjkim
771167802Sjkim    if (OpInfo->Flags & AML_NAMED)
772167802Sjkim    {
773167802Sjkim        /* For all named operators, get the new name */
774167802Sjkim
775322877Sjkim        Path = Op->Named.Path;
776193529Sjkim
777193529Sjkim        if (!Path && Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
778193529Sjkim        {
779193529Sjkim            *ACPI_CAST_PTR (UINT32, &FieldPath[0]) = Op->Named.Name;
780193529Sjkim            FieldPath[4] = 0;
781193529Sjkim            Path = FieldPath;
782193529Sjkim        }
783167802Sjkim    }
784167802Sjkim    else if (OpInfo->Flags & AML_CREATE)
785167802Sjkim    {
786167802Sjkim        /* New name is the last child */
787167802Sjkim
788167802Sjkim        NextOp = Op->Common.Value.Arg;
789167802Sjkim
790167802Sjkim        while (NextOp->Common.Next)
791167802Sjkim        {
792167802Sjkim            NextOp = NextOp->Common.Next;
793167802Sjkim        }
794298714Sjkim
795167802Sjkim        Path = NextOp->Common.Value.String;
796167802Sjkim    }
797167802Sjkim
798167802Sjkim    if (!Path)
799167802Sjkim    {
800167802Sjkim        goto Exit;
801167802Sjkim    }
802167802Sjkim
803167802Sjkim    /* Insert the name into the namespace */
804167802Sjkim
805167802Sjkim    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
806298714Sjkim        ACPI_IMODE_LOAD_PASS2, ACPI_NS_DONT_OPEN_SCOPE,
807298714Sjkim        WalkState, &Node);
808167802Sjkim
809167802Sjkim    Op->Common.Node = Node;
810167802Sjkim
811193529Sjkim    if (ACPI_SUCCESS (Status))
812193529Sjkim    {
813193529Sjkim        /* Check if it's a predefined node */
814167802Sjkim
815193529Sjkim        while (AcpiGbl_PreDefinedNames[PreDefineIndex].Name)
816193529Sjkim        {
817241973Sjkim            if (ACPI_COMPARE_NAME (Node->Name.Ascii,
818241973Sjkim                AcpiGbl_PreDefinedNames[PreDefineIndex].Name))
819193529Sjkim            {
820193529Sjkim                PreDefined = TRUE;
821193529Sjkim                break;
822193529Sjkim            }
823193529Sjkim
824193529Sjkim            PreDefineIndex++;
825193529Sjkim        }
826193529Sjkim
827193529Sjkim        /*
828193529Sjkim         * Set node owner id if it satisfies all the following conditions:
829193529Sjkim         * 1) Not a predefined node, _SB_ etc
830193529Sjkim         * 2) Not the root node
831193529Sjkim         * 3) Not a node created by Scope
832193529Sjkim         */
833193529Sjkim
834193529Sjkim        if (!PreDefined && Node != AcpiGbl_RootNode &&
835193529Sjkim            Op->Common.AmlOpcode != AML_SCOPE_OP)
836193529Sjkim        {
837193529Sjkim            Node->OwnerId = WalkState->OwnerId;
838193529Sjkim        }
839193529Sjkim    }
840193529Sjkim
841193529Sjkim
842167802SjkimExit:
843167802Sjkim
844167802Sjkim    if (AcpiNsOpensScope (ObjectType))
845167802Sjkim    {
846167802Sjkim        if (Op->Common.Node)
847167802Sjkim        {
848298714Sjkim            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
849298714Sjkim                WalkState);
850167802Sjkim            if (ACPI_FAILURE (Status))
851167802Sjkim            {
852167802Sjkim                return (Status);
853167802Sjkim            }
854167802Sjkim        }
855167802Sjkim    }
856167802Sjkim
857167802Sjkim    return (AE_OK);
858167802Sjkim}
859167802Sjkim
860167802Sjkim
861167802Sjkim/*******************************************************************************
862167802Sjkim *
863167802Sjkim * FUNCTION:    AcpiDmXrefDescendingOp
864167802Sjkim *
865167802Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
866167802Sjkim *
867167802Sjkim * RETURN:      Status
868167802Sjkim *
869167802Sjkim * DESCRIPTION: Descending handler for namespace cross reference
870167802Sjkim *
871167802Sjkim ******************************************************************************/
872167802Sjkim
873167802Sjkimstatic ACPI_STATUS
874167802SjkimAcpiDmXrefDescendingOp (
875167802Sjkim    ACPI_PARSE_OBJECT       *Op,
876167802Sjkim    UINT32                  Level,
877167802Sjkim    void                    *Context)
878167802Sjkim{
879167802Sjkim    ACPI_OP_WALK_INFO       *Info = Context;
880167802Sjkim    const ACPI_OPCODE_INFO  *OpInfo;
881167802Sjkim    ACPI_WALK_STATE         *WalkState;
882167802Sjkim    ACPI_OBJECT_TYPE        ObjectType;
883193529Sjkim    ACPI_OBJECT_TYPE        ObjectType2;
884167802Sjkim    ACPI_STATUS             Status;
885167802Sjkim    char                    *Path = NULL;
886167802Sjkim    ACPI_PARSE_OBJECT       *NextOp;
887167802Sjkim    ACPI_NAMESPACE_NODE     *Node;
888193529Sjkim    ACPI_OPERAND_OBJECT     *Object;
889212761Sjkim    UINT32                  ParamCount = 0;
890272444Sjkim    char                    *Pathname;
891298714Sjkim    UINT16                  Flags = 0;
892167802Sjkim
893167802Sjkim
894167802Sjkim    WalkState = Info->WalkState;
895167802Sjkim    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
896167802Sjkim    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
897167802Sjkim
898167802Sjkim    if ((!(OpInfo->Flags & AML_NAMED)) &&
899167802Sjkim        (!(OpInfo->Flags & AML_CREATE)) &&
900272444Sjkim        (Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP) &&
901272444Sjkim        (Op->Common.AmlOpcode != AML_NOTIFY_OP))
902167802Sjkim    {
903167802Sjkim        goto Exit;
904167802Sjkim    }
905167802Sjkim
906167802Sjkim    /* Get the NamePath from the appropriate place */
907167802Sjkim
908167802Sjkim    if (OpInfo->Flags & AML_NAMED)
909167802Sjkim    {
910235945Sjkim        /*
911235945Sjkim         * Only these two operators (Alias, Scope) refer to an existing
912235945Sjkim         * name, it is the first argument
913235945Sjkim         */
914235945Sjkim        if (Op->Common.AmlOpcode == AML_ALIAS_OP)
915167802Sjkim        {
916235945Sjkim            ObjectType = ACPI_TYPE_ANY;
917235945Sjkim
918235945Sjkim            NextOp = Op->Common.Value.Arg;
919235945Sjkim            NextOp = NextOp->Common.Value.Arg;
920235945Sjkim            if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
921235945Sjkim            {
922235945Sjkim                Path = NextOp->Common.Value.String;
923235945Sjkim            }
924235945Sjkim        }
925322877Sjkim        else if (Op->Common.AmlOpcode == AML_SCOPE_OP ||
926322877Sjkim                 Op->Common.AmlOpcode == AML_EXTERNAL_OP)
927235945Sjkim        {
928322877Sjkim            Path = Op->Named.Path;
929167802Sjkim        }
930167802Sjkim    }
931167802Sjkim    else if (OpInfo->Flags & AML_CREATE)
932167802Sjkim    {
933167802Sjkim        /* Referenced Buffer Name is the first child */
934167802Sjkim
935235945Sjkim        ObjectType = ACPI_TYPE_BUFFER; /* Change from TYPE_BUFFER_FIELD */
936235945Sjkim
937167802Sjkim        NextOp = Op->Common.Value.Arg;
938167802Sjkim        if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
939167802Sjkim        {
940167802Sjkim            Path = NextOp->Common.Value.String;
941167802Sjkim        }
942167802Sjkim    }
943272444Sjkim    else if (Op->Common.AmlOpcode == AML_NOTIFY_OP)
944272444Sjkim    {
945272444Sjkim        Path = Op->Common.Value.Arg->Asl.Value.String;
946272444Sjkim    }
947167802Sjkim    else
948167802Sjkim    {
949167802Sjkim        Path = Op->Common.Value.String;
950167802Sjkim    }
951167802Sjkim
952167802Sjkim    if (!Path)
953167802Sjkim    {
954167802Sjkim        goto Exit;
955167802Sjkim    }
956167802Sjkim
957167802Sjkim    /*
958241973Sjkim     * Lookup the name in the namespace. Name must exist at this point, or it
959167802Sjkim     * is an invalid reference.
960167802Sjkim     *
961167802Sjkim     * The namespace is also used as a lookup table for references to resource
962167802Sjkim     * descriptors and the fields within them.
963167802Sjkim     */
964272444Sjkim    Node = NULL;
965167802Sjkim    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
966298714Sjkim        ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
967298714Sjkim        WalkState, &Node);
968298714Sjkim
969235945Sjkim    if (ACPI_SUCCESS (Status) && (Node->Flags & ANOBJ_IS_EXTERNAL))
970235945Sjkim    {
971272444Sjkim        /* Node was created by an External() statement */
972272444Sjkim
973235945Sjkim        Status = AE_NOT_FOUND;
974235945Sjkim    }
975235945Sjkim
976167802Sjkim    if (ACPI_FAILURE (Status))
977167802Sjkim    {
978167802Sjkim        if (Status == AE_NOT_FOUND)
979167802Sjkim        {
980167802Sjkim            /*
981272444Sjkim             * Add this symbol as an external declaration, except if the
982272444Sjkim             * parent is a CondRefOf operator. For this operator, we do not
983272444Sjkim             * need an external, nor do we want one, since this can cause
984272444Sjkim             * disassembly problems if the symbol is actually a control
985272444Sjkim             * method.
986167802Sjkim             */
987272444Sjkim            if (!(Op->Asl.Parent &&
988316303Sjkim                (Op->Asl.Parent->Asl.AmlOpcode == AML_CONDITIONAL_REF_OF_OP)))
989272444Sjkim            {
990272444Sjkim                if (Node)
991272444Sjkim                {
992272444Sjkim                    AcpiDmAddNodeToExternalList (Node,
993298714Sjkim                        (UINT8) ObjectType, 7, Flags);
994272444Sjkim                }
995272444Sjkim                else
996272444Sjkim                {
997272444Sjkim                    AcpiDmAddOpToExternalList (Op, Path,
998298714Sjkim                        (UINT8) ObjectType, 7, Flags);
999272444Sjkim                }
1000272444Sjkim            }
1001167802Sjkim        }
1002167802Sjkim    }
1003193529Sjkim
1004193529Sjkim    /*
1005272444Sjkim     * Found the node, but check if it came from an external table.
1006272444Sjkim     * Add it to external list. Note: Node->OwnerId == 0 indicates
1007272444Sjkim     * one of the built-in ACPI Names (_OS_ etc.) which can safely
1008272444Sjkim     * be ignored.
1009193529Sjkim     */
1010272444Sjkim    else if (Node->OwnerId &&
1011272444Sjkim            (WalkState->OwnerId != Node->OwnerId))
1012193529Sjkim    {
1013193529Sjkim        ObjectType2 = ObjectType;
1014193529Sjkim
1015193529Sjkim        Object = AcpiNsGetAttachedObject (Node);
1016193529Sjkim        if (Object)
1017193529Sjkim        {
1018193529Sjkim            ObjectType2 = Object->Common.Type;
1019212761Sjkim            if (ObjectType2 == ACPI_TYPE_METHOD)
1020212761Sjkim            {
1021212761Sjkim                ParamCount = Object->Method.ParamCount;
1022212761Sjkim            }
1023193529Sjkim        }
1024193529Sjkim
1025272444Sjkim        Pathname = AcpiNsGetExternalPathname (Node);
1026272444Sjkim        if (!Pathname)
1027272444Sjkim        {
1028272444Sjkim            return (AE_NO_MEMORY);
1029272444Sjkim        }
1030272444Sjkim
1031272444Sjkim        AcpiDmAddNodeToExternalList (Node, (UINT8) ObjectType2,
1032272444Sjkim            ParamCount, ACPI_EXT_RESOLVED_REFERENCE);
1033272444Sjkim
1034272444Sjkim        ACPI_FREE (Pathname);
1035193529Sjkim        Op->Common.Node = Node;
1036193529Sjkim    }
1037167802Sjkim    else
1038167802Sjkim    {
1039167802Sjkim        Op->Common.Node = Node;
1040167802Sjkim    }
1041167802Sjkim
1042167802Sjkim
1043167802SjkimExit:
1044167802Sjkim    /* Open new scope if necessary */
1045167802Sjkim
1046167802Sjkim    if (AcpiNsOpensScope (ObjectType))
1047167802Sjkim    {
1048167802Sjkim        if (Op->Common.Node)
1049167802Sjkim        {
1050298714Sjkim            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
1051298714Sjkim                WalkState);
1052167802Sjkim            if (ACPI_FAILURE (Status))
1053167802Sjkim            {
1054167802Sjkim                return (Status);
1055167802Sjkim            }
1056167802Sjkim        }
1057167802Sjkim    }
1058167802Sjkim
1059167802Sjkim    return (AE_OK);
1060167802Sjkim}
1061167802Sjkim
1062322877Sjkim/*******************************************************************************
1063322877Sjkim *
1064322877Sjkim * FUNCTION:    AcpiDmCommonDescendingOp
1065322877Sjkim *
1066322877Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
1067322877Sjkim *
1068322877Sjkim * RETURN:      ACPI_STATUS
1069322877Sjkim *
1070322877Sjkim * DESCRIPTION: Perform parse tree preprocessing before main disassembly walk.
1071322877Sjkim *
1072322877Sjkim ******************************************************************************/
1073167802Sjkim
1074322877Sjkimstatic ACPI_STATUS
1075322877SjkimAcpiDmCommonDescendingOp (
1076322877Sjkim    ACPI_PARSE_OBJECT       *Op,
1077322877Sjkim    UINT32                  Level,
1078322877Sjkim    void                    *Context)
1079322877Sjkim{
1080322877Sjkim    ACPI_STATUS             Status;
1081322877Sjkim
1082322877Sjkim
1083322877Sjkim    /* Resource descriptor conversion */
1084322877Sjkim
1085322877Sjkim    Status = AcpiDmProcessResourceDescriptors (Op, Level, Context);
1086322877Sjkim    if (ACPI_FAILURE (Status))
1087322877Sjkim    {
1088322877Sjkim        return (Status);
1089322877Sjkim    }
1090322877Sjkim
1091322877Sjkim    /* Switch/Case conversion */
1092322877Sjkim
1093322877Sjkim    Status = AcpiDmProcessSwitch (Op);
1094322877Sjkim    return (AE_OK);
1095322877Sjkim}
1096322877Sjkim
1097322877Sjkim
1098167802Sjkim/*******************************************************************************
1099167802Sjkim *
1100322877Sjkim * FUNCTION:    AcpiDmProcessResourceDescriptors
1101167802Sjkim *
1102167802Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
1103167802Sjkim *
1104322877Sjkim * RETURN:      ACPI_STATUS
1105167802Sjkim *
1106322877Sjkim * DESCRIPTION: Convert fixed-offset references to resource descriptors to
1107322877Sjkim *              symbolic references. Should only be called after namespace has
1108322877Sjkim *              been cross referenced.
1109167802Sjkim *
1110167802Sjkim ******************************************************************************/
1111167802Sjkim
1112167802Sjkimstatic ACPI_STATUS
1113322877SjkimAcpiDmProcessResourceDescriptors (
1114167802Sjkim    ACPI_PARSE_OBJECT       *Op,
1115167802Sjkim    UINT32                  Level,
1116167802Sjkim    void                    *Context)
1117167802Sjkim{
1118167802Sjkim    ACPI_OP_WALK_INFO       *Info = Context;
1119167802Sjkim    const ACPI_OPCODE_INFO  *OpInfo;
1120167802Sjkim    ACPI_WALK_STATE         *WalkState;
1121167802Sjkim    ACPI_OBJECT_TYPE        ObjectType;
1122167802Sjkim    ACPI_STATUS             Status;
1123167802Sjkim
1124167802Sjkim
1125167802Sjkim    WalkState = Info->WalkState;
1126167802Sjkim    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1127167802Sjkim
1128167802Sjkim    /* Open new scope if necessary */
1129167802Sjkim
1130167802Sjkim    ObjectType = OpInfo->ObjectType;
1131167802Sjkim    if (AcpiNsOpensScope (ObjectType))
1132167802Sjkim    {
1133167802Sjkim        if (Op->Common.Node)
1134167802Sjkim        {
1135167802Sjkim
1136298714Sjkim            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
1137298714Sjkim                WalkState);
1138167802Sjkim            if (ACPI_FAILURE (Status))
1139167802Sjkim            {
1140167802Sjkim                return (Status);
1141167802Sjkim            }
1142167802Sjkim        }
1143167802Sjkim    }
1144167802Sjkim
1145167802Sjkim    /*
1146167802Sjkim     * Check if this operator contains a reference to a resource descriptor.
1147167802Sjkim     * If so, convert the reference into a symbolic reference.
1148167802Sjkim     */
1149167802Sjkim    AcpiDmCheckResourceReference (Op, WalkState);
1150167802Sjkim    return (AE_OK);
1151167802Sjkim}
1152167802Sjkim
1153167802Sjkim/*******************************************************************************
1154167802Sjkim *
1155167802Sjkim * FUNCTION:    AcpiDmCommonAscendingOp
1156167802Sjkim *
1157167802Sjkim * PARAMETERS:  ASL_WALK_CALLBACK
1158167802Sjkim *
1159167802Sjkim * RETURN:      None
1160167802Sjkim *
1161167802Sjkim * DESCRIPTION: Ascending handler for combined parse/namespace walks. Closes
1162167802Sjkim *              scope if necessary.
1163167802Sjkim *
1164167802Sjkim ******************************************************************************/
1165167802Sjkim
1166167802Sjkimstatic ACPI_STATUS
1167167802SjkimAcpiDmCommonAscendingOp (
1168167802Sjkim    ACPI_PARSE_OBJECT       *Op,
1169167802Sjkim    UINT32                  Level,
1170167802Sjkim    void                    *Context)
1171167802Sjkim{
1172167802Sjkim    ACPI_OP_WALK_INFO       *Info = Context;
1173167802Sjkim    ACPI_OBJECT_TYPE        ObjectType;
1174167802Sjkim
1175167802Sjkim
1176167802Sjkim    /* Close scope if necessary */
1177167802Sjkim
1178167802Sjkim    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
1179167802Sjkim
1180167802Sjkim    if (AcpiNsOpensScope (ObjectType))
1181167802Sjkim    {
1182167802Sjkim        (void) AcpiDsScopeStackPop (Info->WalkState);
1183167802Sjkim    }
1184167802Sjkim
1185167802Sjkim    return (AE_OK);
1186167802Sjkim}
1187167802Sjkim
1188167802Sjkim/*******************************************************************************
1189167802Sjkim *
1190167802Sjkim * FUNCTION:    AcpiDmInspectPossibleArgs
1191167802Sjkim *
1192167802Sjkim * PARAMETERS:  CurrentOpArgCount   - Which arg of the current op was the
1193167802Sjkim *                                    possible method invocation found
1194167802Sjkim *              TargetCount         - Number of targets (0,1,2) for this op
1195167802Sjkim *              Op                  - Parse op
1196167802Sjkim *
1197167802Sjkim * RETURN:      Status
1198167802Sjkim *
1199167802Sjkim * DESCRIPTION: Examine following args and next ops for possible arguments
1200167802Sjkim *              for an unrecognized method invocation.
1201167802Sjkim *
1202167802Sjkim ******************************************************************************/
1203167802Sjkim
1204167802Sjkimstatic UINT32
1205167802SjkimAcpiDmInspectPossibleArgs (
1206167802Sjkim    UINT32                  CurrentOpArgCount,
1207167802Sjkim    UINT32                  TargetCount,
1208167802Sjkim    ACPI_PARSE_OBJECT       *Op)
1209167802Sjkim{
1210167802Sjkim    const ACPI_OPCODE_INFO  *OpInfo;
1211167802Sjkim    UINT32                  i;
1212298714Sjkim    UINT32                  ArgumentCount = 0;
1213298714Sjkim    ACPI_PARSE_OBJECT       *NextOp;
1214298714Sjkim    ACPI_PARSE_OBJECT       *ExecuteOp;
1215167802Sjkim
1216167802Sjkim
1217298714Sjkim    if (!Op)
1218298714Sjkim    {
1219298714Sjkim        return (0);
1220298714Sjkim    }
1221167802Sjkim
1222167802Sjkim    /* Lookahead for the maximum number of possible arguments */
1223167802Sjkim
1224298714Sjkim    NextOp = Op->Common.Next;
1225298714Sjkim
1226298714Sjkim    for (i = 0; (i < ACPI_METHOD_NUM_ARGS) && NextOp; i++)
1227167802Sjkim    {
1228298714Sjkim        OpInfo = AcpiPsGetOpcodeInfo (NextOp->Common.AmlOpcode);
1229167802Sjkim
1230298714Sjkim        /* Any one of these operators is "very probably" not a method arg */
1231167802Sjkim
1232298714Sjkim        if ((NextOp->Common.AmlOpcode == AML_STORE_OP) ||
1233298714Sjkim            (NextOp->Common.AmlOpcode == AML_NOTIFY_OP) ||
1234298714Sjkim            (OpInfo->Class == AML_CLASS_CONTROL) ||
1235298714Sjkim            (OpInfo->Class == AML_CLASS_CREATE) ||
1236298714Sjkim            (OpInfo->Class == AML_CLASS_NAMED_OBJECT))
1237167802Sjkim        {
1238167802Sjkim            break;
1239167802Sjkim        }
1240167802Sjkim
1241298714Sjkim        if (OpInfo->Class == AML_CLASS_EXECUTE)
1242167802Sjkim        {
1243298714Sjkim            /* Probable that this is method arg if there is no target */
1244298714Sjkim
1245298714Sjkim            ExecuteOp = NextOp->Common.Value.Arg;
1246298714Sjkim            while (ExecuteOp)
1247298714Sjkim            {
1248298714Sjkim                if ((ExecuteOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
1249298714Sjkim                    (ExecuteOp->Common.Value.Arg == NULL))
1250298714Sjkim                {
1251298714Sjkim                    /* No target, could be a method arg */
1252298714Sjkim
1253298714Sjkim                    break;
1254298714Sjkim                }
1255298714Sjkim
1256298714Sjkim                if (NextOp->Common.AmlOpcode == AML_REF_OF_OP)
1257298714Sjkim                {
1258298714Sjkim                    break;
1259298714Sjkim                }
1260298714Sjkim
1261298714Sjkim                ExecuteOp = ExecuteOp->Common.Next;
1262298714Sjkim            }
1263298714Sjkim
1264298714Sjkim            if (!ExecuteOp)
1265298714Sjkim            {
1266298714Sjkim                /* Has a target, not method arg */
1267298714Sjkim
1268298714Sjkim                return (ArgumentCount);
1269298714Sjkim            }
1270167802Sjkim        }
1271167802Sjkim
1272298714Sjkim        ArgumentCount++;
1273298714Sjkim        NextOp = NextOp->Common.Next;
1274167802Sjkim    }
1275167802Sjkim
1276298714Sjkim    return (ArgumentCount);
1277167802Sjkim}
1278