xref: /freebsd/sys/contrib/dev/acpica/components/parser/pstree.c (revision a159c266a93c3c4f229864954c5f963acd8f60f2)
1*a159c266SJung-uk Kim /******************************************************************************
2*a159c266SJung-uk Kim  *
3*a159c266SJung-uk Kim  * Module Name: pstree - Parser op tree manipulation/traversal/search
4*a159c266SJung-uk Kim  *
5*a159c266SJung-uk Kim  *****************************************************************************/
6*a159c266SJung-uk Kim 
7*a159c266SJung-uk Kim /*
8*a159c266SJung-uk Kim  * Copyright (C) 2000 - 2012, Intel Corp.
9*a159c266SJung-uk Kim  * All rights reserved.
10*a159c266SJung-uk Kim  *
11*a159c266SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12*a159c266SJung-uk Kim  * modification, are permitted provided that the following conditions
13*a159c266SJung-uk Kim  * are met:
14*a159c266SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15*a159c266SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16*a159c266SJung-uk Kim  *    without modification.
17*a159c266SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*a159c266SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19*a159c266SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20*a159c266SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21*a159c266SJung-uk Kim  *    binary redistribution.
22*a159c266SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23*a159c266SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24*a159c266SJung-uk Kim  *    from this software without specific prior written permission.
25*a159c266SJung-uk Kim  *
26*a159c266SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27*a159c266SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28*a159c266SJung-uk Kim  * Software Foundation.
29*a159c266SJung-uk Kim  *
30*a159c266SJung-uk Kim  * NO WARRANTY
31*a159c266SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*a159c266SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*a159c266SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*a159c266SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*a159c266SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*a159c266SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*a159c266SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*a159c266SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*a159c266SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*a159c266SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*a159c266SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42*a159c266SJung-uk Kim  */
43*a159c266SJung-uk Kim 
44*a159c266SJung-uk Kim 
45*a159c266SJung-uk Kim #define __PSTREE_C__
46*a159c266SJung-uk Kim 
47*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
48*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
49*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acparser.h>
50*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
51*a159c266SJung-uk Kim 
52*a159c266SJung-uk Kim #define _COMPONENT          ACPI_PARSER
53*a159c266SJung-uk Kim         ACPI_MODULE_NAME    ("pstree")
54*a159c266SJung-uk Kim 
55*a159c266SJung-uk Kim /* Local prototypes */
56*a159c266SJung-uk Kim 
57*a159c266SJung-uk Kim #ifdef ACPI_OBSOLETE_FUNCTIONS
58*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *
59*a159c266SJung-uk Kim AcpiPsGetChild (
60*a159c266SJung-uk Kim     ACPI_PARSE_OBJECT       *op);
61*a159c266SJung-uk Kim #endif
62*a159c266SJung-uk Kim 
63*a159c266SJung-uk Kim 
64*a159c266SJung-uk Kim /*******************************************************************************
65*a159c266SJung-uk Kim  *
66*a159c266SJung-uk Kim  * FUNCTION:    AcpiPsGetArg
67*a159c266SJung-uk Kim  *
68*a159c266SJung-uk Kim  * PARAMETERS:  Op              - Get an argument for this op
69*a159c266SJung-uk Kim  *              Argn            - Nth argument to get
70*a159c266SJung-uk Kim  *
71*a159c266SJung-uk Kim  * RETURN:      The argument (as an Op object). NULL if argument does not exist
72*a159c266SJung-uk Kim  *
73*a159c266SJung-uk Kim  * DESCRIPTION: Get the specified op's argument.
74*a159c266SJung-uk Kim  *
75*a159c266SJung-uk Kim  ******************************************************************************/
76*a159c266SJung-uk Kim 
77*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *
78*a159c266SJung-uk Kim AcpiPsGetArg (
79*a159c266SJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
80*a159c266SJung-uk Kim     UINT32                  Argn)
81*a159c266SJung-uk Kim {
82*a159c266SJung-uk Kim     ACPI_PARSE_OBJECT       *Arg = NULL;
83*a159c266SJung-uk Kim     const ACPI_OPCODE_INFO  *OpInfo;
84*a159c266SJung-uk Kim 
85*a159c266SJung-uk Kim 
86*a159c266SJung-uk Kim     ACPI_FUNCTION_ENTRY ();
87*a159c266SJung-uk Kim 
88*a159c266SJung-uk Kim /*
89*a159c266SJung-uk Kim     if (Op->Common.AmlOpcode == AML_INT_CONNECTION_OP)
90*a159c266SJung-uk Kim     {
91*a159c266SJung-uk Kim         return (Op->Common.Value.Arg);
92*a159c266SJung-uk Kim     }
93*a159c266SJung-uk Kim */
94*a159c266SJung-uk Kim     /* Get the info structure for this opcode */
95*a159c266SJung-uk Kim 
96*a159c266SJung-uk Kim     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
97*a159c266SJung-uk Kim     if (OpInfo->Class == AML_CLASS_UNKNOWN)
98*a159c266SJung-uk Kim     {
99*a159c266SJung-uk Kim         /* Invalid opcode or ASCII character */
100*a159c266SJung-uk Kim 
101*a159c266SJung-uk Kim         return (NULL);
102*a159c266SJung-uk Kim     }
103*a159c266SJung-uk Kim 
104*a159c266SJung-uk Kim     /* Check if this opcode requires argument sub-objects */
105*a159c266SJung-uk Kim 
106*a159c266SJung-uk Kim     if (!(OpInfo->Flags & AML_HAS_ARGS))
107*a159c266SJung-uk Kim     {
108*a159c266SJung-uk Kim         /* Has no linked argument objects */
109*a159c266SJung-uk Kim 
110*a159c266SJung-uk Kim         return (NULL);
111*a159c266SJung-uk Kim     }
112*a159c266SJung-uk Kim 
113*a159c266SJung-uk Kim     /* Get the requested argument object */
114*a159c266SJung-uk Kim 
115*a159c266SJung-uk Kim     Arg = Op->Common.Value.Arg;
116*a159c266SJung-uk Kim     while (Arg && Argn)
117*a159c266SJung-uk Kim     {
118*a159c266SJung-uk Kim         Argn--;
119*a159c266SJung-uk Kim         Arg = Arg->Common.Next;
120*a159c266SJung-uk Kim     }
121*a159c266SJung-uk Kim 
122*a159c266SJung-uk Kim     return (Arg);
123*a159c266SJung-uk Kim }
124*a159c266SJung-uk Kim 
125*a159c266SJung-uk Kim 
126*a159c266SJung-uk Kim /*******************************************************************************
127*a159c266SJung-uk Kim  *
128*a159c266SJung-uk Kim  * FUNCTION:    AcpiPsAppendArg
129*a159c266SJung-uk Kim  *
130*a159c266SJung-uk Kim  * PARAMETERS:  Op              - Append an argument to this Op.
131*a159c266SJung-uk Kim  *              Arg             - Argument Op to append
132*a159c266SJung-uk Kim  *
133*a159c266SJung-uk Kim  * RETURN:      None.
134*a159c266SJung-uk Kim  *
135*a159c266SJung-uk Kim  * DESCRIPTION: Append an argument to an op's argument list (a NULL arg is OK)
136*a159c266SJung-uk Kim  *
137*a159c266SJung-uk Kim  ******************************************************************************/
138*a159c266SJung-uk Kim 
139*a159c266SJung-uk Kim void
140*a159c266SJung-uk Kim AcpiPsAppendArg (
141*a159c266SJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
142*a159c266SJung-uk Kim     ACPI_PARSE_OBJECT       *Arg)
143*a159c266SJung-uk Kim {
144*a159c266SJung-uk Kim     ACPI_PARSE_OBJECT       *PrevArg;
145*a159c266SJung-uk Kim     const ACPI_OPCODE_INFO  *OpInfo;
146*a159c266SJung-uk Kim 
147*a159c266SJung-uk Kim 
148*a159c266SJung-uk Kim     ACPI_FUNCTION_ENTRY ();
149*a159c266SJung-uk Kim 
150*a159c266SJung-uk Kim 
151*a159c266SJung-uk Kim     if (!Op)
152*a159c266SJung-uk Kim     {
153*a159c266SJung-uk Kim         return;
154*a159c266SJung-uk Kim     }
155*a159c266SJung-uk Kim 
156*a159c266SJung-uk Kim     /* Get the info structure for this opcode */
157*a159c266SJung-uk Kim 
158*a159c266SJung-uk Kim     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
159*a159c266SJung-uk Kim     if (OpInfo->Class == AML_CLASS_UNKNOWN)
160*a159c266SJung-uk Kim     {
161*a159c266SJung-uk Kim         /* Invalid opcode */
162*a159c266SJung-uk Kim 
163*a159c266SJung-uk Kim         ACPI_ERROR ((AE_INFO, "Invalid AML Opcode: 0x%2.2X",
164*a159c266SJung-uk Kim             Op->Common.AmlOpcode));
165*a159c266SJung-uk Kim         return;
166*a159c266SJung-uk Kim     }
167*a159c266SJung-uk Kim 
168*a159c266SJung-uk Kim     /* Check if this opcode requires argument sub-objects */
169*a159c266SJung-uk Kim 
170*a159c266SJung-uk Kim     if (!(OpInfo->Flags & AML_HAS_ARGS))
171*a159c266SJung-uk Kim     {
172*a159c266SJung-uk Kim         /* Has no linked argument objects */
173*a159c266SJung-uk Kim 
174*a159c266SJung-uk Kim         return;
175*a159c266SJung-uk Kim     }
176*a159c266SJung-uk Kim 
177*a159c266SJung-uk Kim     /* Append the argument to the linked argument list */
178*a159c266SJung-uk Kim 
179*a159c266SJung-uk Kim     if (Op->Common.Value.Arg)
180*a159c266SJung-uk Kim     {
181*a159c266SJung-uk Kim         /* Append to existing argument list */
182*a159c266SJung-uk Kim 
183*a159c266SJung-uk Kim         PrevArg = Op->Common.Value.Arg;
184*a159c266SJung-uk Kim         while (PrevArg->Common.Next)
185*a159c266SJung-uk Kim         {
186*a159c266SJung-uk Kim             PrevArg = PrevArg->Common.Next;
187*a159c266SJung-uk Kim         }
188*a159c266SJung-uk Kim         PrevArg->Common.Next = Arg;
189*a159c266SJung-uk Kim     }
190*a159c266SJung-uk Kim     else
191*a159c266SJung-uk Kim     {
192*a159c266SJung-uk Kim         /* No argument list, this will be the first argument */
193*a159c266SJung-uk Kim 
194*a159c266SJung-uk Kim         Op->Common.Value.Arg = Arg;
195*a159c266SJung-uk Kim     }
196*a159c266SJung-uk Kim 
197*a159c266SJung-uk Kim     /* Set the parent in this arg and any args linked after it */
198*a159c266SJung-uk Kim 
199*a159c266SJung-uk Kim     while (Arg)
200*a159c266SJung-uk Kim     {
201*a159c266SJung-uk Kim         Arg->Common.Parent = Op;
202*a159c266SJung-uk Kim         Arg = Arg->Common.Next;
203*a159c266SJung-uk Kim 
204*a159c266SJung-uk Kim         Op->Common.ArgListLength++;
205*a159c266SJung-uk Kim     }
206*a159c266SJung-uk Kim }
207*a159c266SJung-uk Kim 
208*a159c266SJung-uk Kim 
209*a159c266SJung-uk Kim /*******************************************************************************
210*a159c266SJung-uk Kim  *
211*a159c266SJung-uk Kim  * FUNCTION:    AcpiPsGetDepthNext
212*a159c266SJung-uk Kim  *
213*a159c266SJung-uk Kim  * PARAMETERS:  Origin          - Root of subtree to search
214*a159c266SJung-uk Kim  *              Op              - Last (previous) Op that was found
215*a159c266SJung-uk Kim  *
216*a159c266SJung-uk Kim  * RETURN:      Next Op found in the search.
217*a159c266SJung-uk Kim  *
218*a159c266SJung-uk Kim  * DESCRIPTION: Get next op in tree (walking the tree in depth-first order)
219*a159c266SJung-uk Kim  *              Return NULL when reaching "origin" or when walking up from root
220*a159c266SJung-uk Kim  *
221*a159c266SJung-uk Kim  ******************************************************************************/
222*a159c266SJung-uk Kim 
223*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *
224*a159c266SJung-uk Kim AcpiPsGetDepthNext (
225*a159c266SJung-uk Kim     ACPI_PARSE_OBJECT       *Origin,
226*a159c266SJung-uk Kim     ACPI_PARSE_OBJECT       *Op)
227*a159c266SJung-uk Kim {
228*a159c266SJung-uk Kim     ACPI_PARSE_OBJECT       *Next = NULL;
229*a159c266SJung-uk Kim     ACPI_PARSE_OBJECT       *Parent;
230*a159c266SJung-uk Kim     ACPI_PARSE_OBJECT       *Arg;
231*a159c266SJung-uk Kim 
232*a159c266SJung-uk Kim 
233*a159c266SJung-uk Kim     ACPI_FUNCTION_ENTRY ();
234*a159c266SJung-uk Kim 
235*a159c266SJung-uk Kim 
236*a159c266SJung-uk Kim     if (!Op)
237*a159c266SJung-uk Kim     {
238*a159c266SJung-uk Kim         return (NULL);
239*a159c266SJung-uk Kim     }
240*a159c266SJung-uk Kim 
241*a159c266SJung-uk Kim     /* Look for an argument or child */
242*a159c266SJung-uk Kim 
243*a159c266SJung-uk Kim     Next = AcpiPsGetArg (Op, 0);
244*a159c266SJung-uk Kim     if (Next)
245*a159c266SJung-uk Kim     {
246*a159c266SJung-uk Kim         return (Next);
247*a159c266SJung-uk Kim     }
248*a159c266SJung-uk Kim 
249*a159c266SJung-uk Kim     /* Look for a sibling */
250*a159c266SJung-uk Kim 
251*a159c266SJung-uk Kim     Next = Op->Common.Next;
252*a159c266SJung-uk Kim     if (Next)
253*a159c266SJung-uk Kim     {
254*a159c266SJung-uk Kim         return (Next);
255*a159c266SJung-uk Kim     }
256*a159c266SJung-uk Kim 
257*a159c266SJung-uk Kim     /* Look for a sibling of parent */
258*a159c266SJung-uk Kim 
259*a159c266SJung-uk Kim     Parent = Op->Common.Parent;
260*a159c266SJung-uk Kim 
261*a159c266SJung-uk Kim     while (Parent)
262*a159c266SJung-uk Kim     {
263*a159c266SJung-uk Kim         Arg = AcpiPsGetArg (Parent, 0);
264*a159c266SJung-uk Kim         while (Arg && (Arg != Origin) && (Arg != Op))
265*a159c266SJung-uk Kim         {
266*a159c266SJung-uk Kim             Arg = Arg->Common.Next;
267*a159c266SJung-uk Kim         }
268*a159c266SJung-uk Kim 
269*a159c266SJung-uk Kim         if (Arg == Origin)
270*a159c266SJung-uk Kim         {
271*a159c266SJung-uk Kim             /* Reached parent of origin, end search */
272*a159c266SJung-uk Kim 
273*a159c266SJung-uk Kim             return (NULL);
274*a159c266SJung-uk Kim         }
275*a159c266SJung-uk Kim 
276*a159c266SJung-uk Kim         if (Parent->Common.Next)
277*a159c266SJung-uk Kim         {
278*a159c266SJung-uk Kim             /* Found sibling of parent */
279*a159c266SJung-uk Kim 
280*a159c266SJung-uk Kim             return (Parent->Common.Next);
281*a159c266SJung-uk Kim         }
282*a159c266SJung-uk Kim 
283*a159c266SJung-uk Kim         Op = Parent;
284*a159c266SJung-uk Kim         Parent = Parent->Common.Parent;
285*a159c266SJung-uk Kim     }
286*a159c266SJung-uk Kim 
287*a159c266SJung-uk Kim     return (Next);
288*a159c266SJung-uk Kim }
289*a159c266SJung-uk Kim 
290*a159c266SJung-uk Kim 
291*a159c266SJung-uk Kim #ifdef ACPI_OBSOLETE_FUNCTIONS
292*a159c266SJung-uk Kim /*******************************************************************************
293*a159c266SJung-uk Kim  *
294*a159c266SJung-uk Kim  * FUNCTION:    AcpiPsGetChild
295*a159c266SJung-uk Kim  *
296*a159c266SJung-uk Kim  * PARAMETERS:  Op              - Get the child of this Op
297*a159c266SJung-uk Kim  *
298*a159c266SJung-uk Kim  * RETURN:      Child Op, Null if none is found.
299*a159c266SJung-uk Kim  *
300*a159c266SJung-uk Kim  * DESCRIPTION: Get op's children or NULL if none
301*a159c266SJung-uk Kim  *
302*a159c266SJung-uk Kim  ******************************************************************************/
303*a159c266SJung-uk Kim 
304*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *
305*a159c266SJung-uk Kim AcpiPsGetChild (
306*a159c266SJung-uk Kim     ACPI_PARSE_OBJECT       *Op)
307*a159c266SJung-uk Kim {
308*a159c266SJung-uk Kim     ACPI_PARSE_OBJECT       *Child = NULL;
309*a159c266SJung-uk Kim 
310*a159c266SJung-uk Kim 
311*a159c266SJung-uk Kim     ACPI_FUNCTION_ENTRY ();
312*a159c266SJung-uk Kim 
313*a159c266SJung-uk Kim 
314*a159c266SJung-uk Kim     switch (Op->Common.AmlOpcode)
315*a159c266SJung-uk Kim     {
316*a159c266SJung-uk Kim     case AML_SCOPE_OP:
317*a159c266SJung-uk Kim     case AML_ELSE_OP:
318*a159c266SJung-uk Kim     case AML_DEVICE_OP:
319*a159c266SJung-uk Kim     case AML_THERMAL_ZONE_OP:
320*a159c266SJung-uk Kim     case AML_INT_METHODCALL_OP:
321*a159c266SJung-uk Kim 
322*a159c266SJung-uk Kim         Child = AcpiPsGetArg (Op, 0);
323*a159c266SJung-uk Kim         break;
324*a159c266SJung-uk Kim 
325*a159c266SJung-uk Kim 
326*a159c266SJung-uk Kim     case AML_BUFFER_OP:
327*a159c266SJung-uk Kim     case AML_PACKAGE_OP:
328*a159c266SJung-uk Kim     case AML_METHOD_OP:
329*a159c266SJung-uk Kim     case AML_IF_OP:
330*a159c266SJung-uk Kim     case AML_WHILE_OP:
331*a159c266SJung-uk Kim     case AML_FIELD_OP:
332*a159c266SJung-uk Kim 
333*a159c266SJung-uk Kim         Child = AcpiPsGetArg (Op, 1);
334*a159c266SJung-uk Kim         break;
335*a159c266SJung-uk Kim 
336*a159c266SJung-uk Kim 
337*a159c266SJung-uk Kim     case AML_POWER_RES_OP:
338*a159c266SJung-uk Kim     case AML_INDEX_FIELD_OP:
339*a159c266SJung-uk Kim 
340*a159c266SJung-uk Kim         Child = AcpiPsGetArg (Op, 2);
341*a159c266SJung-uk Kim         break;
342*a159c266SJung-uk Kim 
343*a159c266SJung-uk Kim 
344*a159c266SJung-uk Kim     case AML_PROCESSOR_OP:
345*a159c266SJung-uk Kim     case AML_BANK_FIELD_OP:
346*a159c266SJung-uk Kim 
347*a159c266SJung-uk Kim         Child = AcpiPsGetArg (Op, 3);
348*a159c266SJung-uk Kim         break;
349*a159c266SJung-uk Kim 
350*a159c266SJung-uk Kim 
351*a159c266SJung-uk Kim     default:
352*a159c266SJung-uk Kim         /* All others have no children */
353*a159c266SJung-uk Kim         break;
354*a159c266SJung-uk Kim     }
355*a159c266SJung-uk Kim 
356*a159c266SJung-uk Kim     return (Child);
357*a159c266SJung-uk Kim }
358*a159c266SJung-uk Kim #endif
359*a159c266SJung-uk Kim 
360*a159c266SJung-uk Kim 
361