xref: /freebsd/sys/contrib/dev/acpica/components/disassembler/dmdeferred.c (revision f8146b882bc156c1d8ddf14bbea67253ebc064bb)
1ed17e06eSJung-uk Kim /******************************************************************************
2ed17e06eSJung-uk Kim  *
3ed17e06eSJung-uk Kim  * Module Name: dmdeferred - Disassembly of deferred AML opcodes
4ed17e06eSJung-uk Kim  *
5ed17e06eSJung-uk Kim  *****************************************************************************/
6ed17e06eSJung-uk Kim 
7ed17e06eSJung-uk Kim /*
8*f8146b88SJung-uk Kim  * Copyright (C) 2000 - 2016, Intel Corp.
9ed17e06eSJung-uk Kim  * All rights reserved.
10ed17e06eSJung-uk Kim  *
11ed17e06eSJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12ed17e06eSJung-uk Kim  * modification, are permitted provided that the following conditions
13ed17e06eSJung-uk Kim  * are met:
14ed17e06eSJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15ed17e06eSJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16ed17e06eSJung-uk Kim  *    without modification.
17ed17e06eSJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18ed17e06eSJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19ed17e06eSJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20ed17e06eSJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21ed17e06eSJung-uk Kim  *    binary redistribution.
22ed17e06eSJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23ed17e06eSJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24ed17e06eSJung-uk Kim  *    from this software without specific prior written permission.
25ed17e06eSJung-uk Kim  *
26ed17e06eSJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27ed17e06eSJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28ed17e06eSJung-uk Kim  * Software Foundation.
29ed17e06eSJung-uk Kim  *
30ed17e06eSJung-uk Kim  * NO WARRANTY
31ed17e06eSJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32ed17e06eSJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33ed17e06eSJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34ed17e06eSJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35ed17e06eSJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36ed17e06eSJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37ed17e06eSJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38ed17e06eSJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39ed17e06eSJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40ed17e06eSJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41ed17e06eSJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42ed17e06eSJung-uk Kim  */
43ed17e06eSJung-uk Kim 
44ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
45ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
46ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/acdispat.h>
47ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
48ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/acdisasm.h>
49ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/acparser.h>
50ed17e06eSJung-uk Kim 
51ed17e06eSJung-uk Kim #define _COMPONENT          ACPI_CA_DISASSEMBLER
52ed17e06eSJung-uk Kim         ACPI_MODULE_NAME    ("dmdeferred")
53ed17e06eSJung-uk Kim 
54ed17e06eSJung-uk Kim 
55ed17e06eSJung-uk Kim /* Local prototypes */
56ed17e06eSJung-uk Kim 
57ed17e06eSJung-uk Kim static ACPI_STATUS
58ed17e06eSJung-uk Kim AcpiDmDeferredParse (
59ed17e06eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
60ed17e06eSJung-uk Kim     UINT8                   *Aml,
61ed17e06eSJung-uk Kim     UINT32                  AmlLength);
62ed17e06eSJung-uk Kim 
63ed17e06eSJung-uk Kim 
64ed17e06eSJung-uk Kim /******************************************************************************
65ed17e06eSJung-uk Kim  *
66ed17e06eSJung-uk Kim  * FUNCTION:    AcpiDmParseDeferredOps
67ed17e06eSJung-uk Kim  *
68ed17e06eSJung-uk Kim  * PARAMETERS:  Root                - Root of the parse tree
69ed17e06eSJung-uk Kim  *
70ed17e06eSJung-uk Kim  * RETURN:      Status
71ed17e06eSJung-uk Kim  *
72ed17e06eSJung-uk Kim  * DESCRIPTION: Parse the deferred opcodes (Methods, regions, etc.)
73ed17e06eSJung-uk Kim  *
74ed17e06eSJung-uk Kim  *****************************************************************************/
75ed17e06eSJung-uk Kim 
76ed17e06eSJung-uk Kim ACPI_STATUS
77ed17e06eSJung-uk Kim AcpiDmParseDeferredOps (
78ed17e06eSJung-uk Kim     ACPI_PARSE_OBJECT       *Root)
79ed17e06eSJung-uk Kim {
80ed17e06eSJung-uk Kim     const ACPI_OPCODE_INFO  *OpInfo;
81ed17e06eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op = Root;
82ed17e06eSJung-uk Kim     ACPI_STATUS             Status;
83ed17e06eSJung-uk Kim 
84ed17e06eSJung-uk Kim 
85efcc2a30SJung-uk Kim     ACPI_FUNCTION_ENTRY ();
86ed17e06eSJung-uk Kim 
87ed17e06eSJung-uk Kim 
88ed17e06eSJung-uk Kim     /* Traverse the entire parse tree */
89ed17e06eSJung-uk Kim 
90ed17e06eSJung-uk Kim     while (Op)
91ed17e06eSJung-uk Kim     {
92ed17e06eSJung-uk Kim         OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
93ed17e06eSJung-uk Kim         if (!(OpInfo->Flags & AML_DEFER))
94ed17e06eSJung-uk Kim         {
95ed17e06eSJung-uk Kim             Op = AcpiPsGetDepthNext (Root, Op);
96ed17e06eSJung-uk Kim             continue;
97ed17e06eSJung-uk Kim         }
98ed17e06eSJung-uk Kim 
99ed17e06eSJung-uk Kim         /* Now we know we have a deferred opcode */
100ed17e06eSJung-uk Kim 
101ed17e06eSJung-uk Kim         switch (Op->Common.AmlOpcode)
102ed17e06eSJung-uk Kim         {
103ed17e06eSJung-uk Kim         case AML_METHOD_OP:
104ed17e06eSJung-uk Kim         case AML_BUFFER_OP:
105ed17e06eSJung-uk Kim         case AML_PACKAGE_OP:
106ed17e06eSJung-uk Kim         case AML_VAR_PACKAGE_OP:
107ed17e06eSJung-uk Kim 
108*f8146b88SJung-uk Kim             Status = AcpiDmDeferredParse (
109*f8146b88SJung-uk Kim                 Op, Op->Named.Data, Op->Named.Length);
110ed17e06eSJung-uk Kim             if (ACPI_FAILURE (Status))
111ed17e06eSJung-uk Kim             {
112ed17e06eSJung-uk Kim                 return (Status);
113ed17e06eSJung-uk Kim             }
114ed17e06eSJung-uk Kim             break;
115ed17e06eSJung-uk Kim 
116ed17e06eSJung-uk Kim         /* We don't need to do anything for these deferred opcodes */
117ed17e06eSJung-uk Kim 
118ed17e06eSJung-uk Kim         case AML_REGION_OP:
119ed17e06eSJung-uk Kim         case AML_DATA_REGION_OP:
120ed17e06eSJung-uk Kim         case AML_CREATE_QWORD_FIELD_OP:
121ed17e06eSJung-uk Kim         case AML_CREATE_DWORD_FIELD_OP:
122ed17e06eSJung-uk Kim         case AML_CREATE_WORD_FIELD_OP:
123ed17e06eSJung-uk Kim         case AML_CREATE_BYTE_FIELD_OP:
124ed17e06eSJung-uk Kim         case AML_CREATE_BIT_FIELD_OP:
125ed17e06eSJung-uk Kim         case AML_CREATE_FIELD_OP:
126ed17e06eSJung-uk Kim         case AML_BANK_FIELD_OP:
127ed17e06eSJung-uk Kim 
128ed17e06eSJung-uk Kim             break;
129ed17e06eSJung-uk Kim 
130ed17e06eSJung-uk Kim         default:
131a9d8d09cSJung-uk Kim 
132ed17e06eSJung-uk Kim             ACPI_ERROR ((AE_INFO, "Unhandled deferred AML opcode [0x%.4X]",
133ed17e06eSJung-uk Kim                  Op->Common.AmlOpcode));
134ed17e06eSJung-uk Kim             break;
135ed17e06eSJung-uk Kim         }
136ed17e06eSJung-uk Kim 
137ed17e06eSJung-uk Kim         Op = AcpiPsGetDepthNext (Root, Op);
138ed17e06eSJung-uk Kim     }
139ed17e06eSJung-uk Kim 
140ed17e06eSJung-uk Kim     return (AE_OK);
141ed17e06eSJung-uk Kim }
142ed17e06eSJung-uk Kim 
143ed17e06eSJung-uk Kim 
144ed17e06eSJung-uk Kim /******************************************************************************
145ed17e06eSJung-uk Kim  *
146ed17e06eSJung-uk Kim  * FUNCTION:    AcpiDmDeferredParse
147ed17e06eSJung-uk Kim  *
148ed17e06eSJung-uk Kim  * PARAMETERS:  Op                  - Root Op of the deferred opcode
149ed17e06eSJung-uk Kim  *              Aml                 - Pointer to the raw AML
150ed17e06eSJung-uk Kim  *              AmlLength           - Length of the AML
151ed17e06eSJung-uk Kim  *
152ed17e06eSJung-uk Kim  * RETURN:      Status
153ed17e06eSJung-uk Kim  *
154ed17e06eSJung-uk Kim  * DESCRIPTION: Parse one deferred opcode
155ed17e06eSJung-uk Kim  *              (Methods, operation regions, etc.)
156ed17e06eSJung-uk Kim  *
157ed17e06eSJung-uk Kim  *****************************************************************************/
158ed17e06eSJung-uk Kim 
159ed17e06eSJung-uk Kim static ACPI_STATUS
160ed17e06eSJung-uk Kim AcpiDmDeferredParse (
161ed17e06eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
162ed17e06eSJung-uk Kim     UINT8                   *Aml,
163ed17e06eSJung-uk Kim     UINT32                  AmlLength)
164ed17e06eSJung-uk Kim {
165ed17e06eSJung-uk Kim     ACPI_WALK_STATE         *WalkState;
166ed17e06eSJung-uk Kim     ACPI_STATUS             Status;
167ed17e06eSJung-uk Kim     ACPI_PARSE_OBJECT       *SearchOp;
168ed17e06eSJung-uk Kim     ACPI_PARSE_OBJECT       *StartOp;
169ed17e06eSJung-uk Kim     ACPI_PARSE_OBJECT       *NewRootOp;
170ed17e06eSJung-uk Kim     ACPI_PARSE_OBJECT       *ExtraOp;
171ed17e06eSJung-uk Kim 
172ed17e06eSJung-uk Kim 
173ed17e06eSJung-uk Kim     ACPI_FUNCTION_TRACE (DmDeferredParse);
174ed17e06eSJung-uk Kim 
175ed17e06eSJung-uk Kim 
176ed17e06eSJung-uk Kim     if (!Aml || !AmlLength)
177ed17e06eSJung-uk Kim     {
178ed17e06eSJung-uk Kim         return_ACPI_STATUS (AE_OK);
179ed17e06eSJung-uk Kim     }
180ed17e06eSJung-uk Kim 
181ed17e06eSJung-uk Kim     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing deferred opcode %s [%4.4s]\n",
182ed17e06eSJung-uk Kim         Op->Common.AmlOpName, (char *) &Op->Named.Name));
183ed17e06eSJung-uk Kim 
184ed17e06eSJung-uk Kim     /* Need a new walk state to parse the AML */
185ed17e06eSJung-uk Kim 
186ed17e06eSJung-uk Kim     WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
187ed17e06eSJung-uk Kim     if (!WalkState)
188ed17e06eSJung-uk Kim     {
189ed17e06eSJung-uk Kim         return_ACPI_STATUS (AE_NO_MEMORY);
190ed17e06eSJung-uk Kim     }
191ed17e06eSJung-uk Kim 
192ed17e06eSJung-uk Kim     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Aml,
193ed17e06eSJung-uk Kim         AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
194ed17e06eSJung-uk Kim     if (ACPI_FAILURE (Status))
195ed17e06eSJung-uk Kim     {
196ed17e06eSJung-uk Kim         return_ACPI_STATUS (Status);
197ed17e06eSJung-uk Kim     }
198ed17e06eSJung-uk Kim 
199ed17e06eSJung-uk Kim     /* Parse the AML for this deferred opcode */
200ed17e06eSJung-uk Kim 
201ed17e06eSJung-uk Kim     WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
202ed17e06eSJung-uk Kim     WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
203ed17e06eSJung-uk Kim     Status = AcpiPsParseAml (WalkState);
204ed17e06eSJung-uk Kim 
205ed17e06eSJung-uk Kim     StartOp = (Op->Common.Value.Arg)->Common.Next;
206ed17e06eSJung-uk Kim     SearchOp = StartOp;
207ed17e06eSJung-uk Kim     while (SearchOp)
208ed17e06eSJung-uk Kim     {
209ed17e06eSJung-uk Kim         SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
210ed17e06eSJung-uk Kim     }
211ed17e06eSJung-uk Kim 
212ed17e06eSJung-uk Kim     /*
213ed17e06eSJung-uk Kim      * For Buffer and Package opcodes, link the newly parsed subtree
214ed17e06eSJung-uk Kim      * into the main parse tree
215ed17e06eSJung-uk Kim      */
216ed17e06eSJung-uk Kim     switch (Op->Common.AmlOpcode)
217ed17e06eSJung-uk Kim     {
218ed17e06eSJung-uk Kim     case AML_BUFFER_OP:
219ed17e06eSJung-uk Kim     case AML_PACKAGE_OP:
220ed17e06eSJung-uk Kim     case AML_VAR_PACKAGE_OP:
221ed17e06eSJung-uk Kim 
222ed17e06eSJung-uk Kim         switch (Op->Common.AmlOpcode)
223ed17e06eSJung-uk Kim         {
224ed17e06eSJung-uk Kim         case AML_PACKAGE_OP:
225ed17e06eSJung-uk Kim 
226ed17e06eSJung-uk Kim             ExtraOp = Op->Common.Value.Arg;
227ed17e06eSJung-uk Kim             NewRootOp = ExtraOp->Common.Next;
228ed17e06eSJung-uk Kim             ACPI_FREE (ExtraOp);
229ed17e06eSJung-uk Kim             break;
230ed17e06eSJung-uk Kim 
231ed17e06eSJung-uk Kim         case AML_VAR_PACKAGE_OP:
232ed17e06eSJung-uk Kim         case AML_BUFFER_OP:
233ed17e06eSJung-uk Kim         default:
234ed17e06eSJung-uk Kim 
235ed17e06eSJung-uk Kim             NewRootOp = Op->Common.Value.Arg;
236ed17e06eSJung-uk Kim             break;
237ed17e06eSJung-uk Kim         }
238ed17e06eSJung-uk Kim 
239ed17e06eSJung-uk Kim         Op->Common.Value.Arg = NewRootOp->Common.Value.Arg;
240ed17e06eSJung-uk Kim 
241ed17e06eSJung-uk Kim         /* Must point all parents to the main tree */
242ed17e06eSJung-uk Kim 
243ed17e06eSJung-uk Kim         StartOp = Op;
244ed17e06eSJung-uk Kim         SearchOp = StartOp;
245ed17e06eSJung-uk Kim         while (SearchOp)
246ed17e06eSJung-uk Kim         {
247ed17e06eSJung-uk Kim             if (SearchOp->Common.Parent == NewRootOp)
248ed17e06eSJung-uk Kim             {
249ed17e06eSJung-uk Kim                 SearchOp->Common.Parent = Op;
250ed17e06eSJung-uk Kim             }
251ed17e06eSJung-uk Kim 
252ed17e06eSJung-uk Kim             SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
253ed17e06eSJung-uk Kim         }
254ed17e06eSJung-uk Kim 
255ed17e06eSJung-uk Kim         ACPI_FREE (NewRootOp);
256ed17e06eSJung-uk Kim         break;
257ed17e06eSJung-uk Kim 
258ed17e06eSJung-uk Kim     default:
259a9d8d09cSJung-uk Kim 
260ed17e06eSJung-uk Kim         break;
261ed17e06eSJung-uk Kim     }
262ed17e06eSJung-uk Kim 
263ed17e06eSJung-uk Kim     return_ACPI_STATUS (AE_OK);
264ed17e06eSJung-uk Kim }
265