xref: /minix3/minix/drivers/power/acpi/dispatcher/dsopcode.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc /******************************************************************************
2*433d6423SLionel Sambuc  *
3*433d6423SLionel Sambuc  * Module Name: dsopcode - Dispatcher Op Region support and handling of
4*433d6423SLionel Sambuc  *                         "control" opcodes
5*433d6423SLionel Sambuc  *
6*433d6423SLionel Sambuc  *****************************************************************************/
7*433d6423SLionel Sambuc 
8*433d6423SLionel Sambuc /******************************************************************************
9*433d6423SLionel Sambuc  *
10*433d6423SLionel Sambuc  * 1. Copyright Notice
11*433d6423SLionel Sambuc  *
12*433d6423SLionel Sambuc  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
13*433d6423SLionel Sambuc  * All rights reserved.
14*433d6423SLionel Sambuc  *
15*433d6423SLionel Sambuc  * 2. License
16*433d6423SLionel Sambuc  *
17*433d6423SLionel Sambuc  * 2.1. This is your license from Intel Corp. under its intellectual property
18*433d6423SLionel Sambuc  * rights.  You may have additional license terms from the party that provided
19*433d6423SLionel Sambuc  * you this software, covering your right to use that party's intellectual
20*433d6423SLionel Sambuc  * property rights.
21*433d6423SLionel Sambuc  *
22*433d6423SLionel Sambuc  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23*433d6423SLionel Sambuc  * copy of the source code appearing in this file ("Covered Code") an
24*433d6423SLionel Sambuc  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25*433d6423SLionel Sambuc  * base code distributed originally by Intel ("Original Intel Code") to copy,
26*433d6423SLionel Sambuc  * make derivatives, distribute, use and display any portion of the Covered
27*433d6423SLionel Sambuc  * Code in any form, with the right to sublicense such rights; and
28*433d6423SLionel Sambuc  *
29*433d6423SLionel Sambuc  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30*433d6423SLionel Sambuc  * license (with the right to sublicense), under only those claims of Intel
31*433d6423SLionel Sambuc  * patents that are infringed by the Original Intel Code, to make, use, sell,
32*433d6423SLionel Sambuc  * offer to sell, and import the Covered Code and derivative works thereof
33*433d6423SLionel Sambuc  * solely to the minimum extent necessary to exercise the above copyright
34*433d6423SLionel Sambuc  * license, and in no event shall the patent license extend to any additions
35*433d6423SLionel Sambuc  * to or modifications of the Original Intel Code.  No other license or right
36*433d6423SLionel Sambuc  * is granted directly or by implication, estoppel or otherwise;
37*433d6423SLionel Sambuc  *
38*433d6423SLionel Sambuc  * The above copyright and patent license is granted only if the following
39*433d6423SLionel Sambuc  * conditions are met:
40*433d6423SLionel Sambuc  *
41*433d6423SLionel Sambuc  * 3. Conditions
42*433d6423SLionel Sambuc  *
43*433d6423SLionel Sambuc  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44*433d6423SLionel Sambuc  * Redistribution of source code of any substantial portion of the Covered
45*433d6423SLionel Sambuc  * Code or modification with rights to further distribute source must include
46*433d6423SLionel Sambuc  * the above Copyright Notice, the above License, this list of Conditions,
47*433d6423SLionel Sambuc  * and the following Disclaimer and Export Compliance provision.  In addition,
48*433d6423SLionel Sambuc  * Licensee must cause all Covered Code to which Licensee contributes to
49*433d6423SLionel Sambuc  * contain a file documenting the changes Licensee made to create that Covered
50*433d6423SLionel Sambuc  * Code and the date of any change.  Licensee must include in that file the
51*433d6423SLionel Sambuc  * documentation of any changes made by any predecessor Licensee.  Licensee
52*433d6423SLionel Sambuc  * must include a prominent statement that the modification is derived,
53*433d6423SLionel Sambuc  * directly or indirectly, from Original Intel Code.
54*433d6423SLionel Sambuc  *
55*433d6423SLionel Sambuc  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56*433d6423SLionel Sambuc  * Redistribution of source code of any substantial portion of the Covered
57*433d6423SLionel Sambuc  * Code or modification without rights to further distribute source must
58*433d6423SLionel Sambuc  * include the following Disclaimer and Export Compliance provision in the
59*433d6423SLionel Sambuc  * documentation and/or other materials provided with distribution.  In
60*433d6423SLionel Sambuc  * addition, Licensee may not authorize further sublicense of source of any
61*433d6423SLionel Sambuc  * portion of the Covered Code, and must include terms to the effect that the
62*433d6423SLionel Sambuc  * license from Licensee to its licensee is limited to the intellectual
63*433d6423SLionel Sambuc  * property embodied in the software Licensee provides to its licensee, and
64*433d6423SLionel Sambuc  * not to intellectual property embodied in modifications its licensee may
65*433d6423SLionel Sambuc  * make.
66*433d6423SLionel Sambuc  *
67*433d6423SLionel Sambuc  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68*433d6423SLionel Sambuc  * substantial portion of the Covered Code or modification must reproduce the
69*433d6423SLionel Sambuc  * above Copyright Notice, and the following Disclaimer and Export Compliance
70*433d6423SLionel Sambuc  * provision in the documentation and/or other materials provided with the
71*433d6423SLionel Sambuc  * distribution.
72*433d6423SLionel Sambuc  *
73*433d6423SLionel Sambuc  * 3.4. Intel retains all right, title, and interest in and to the Original
74*433d6423SLionel Sambuc  * Intel Code.
75*433d6423SLionel Sambuc  *
76*433d6423SLionel Sambuc  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77*433d6423SLionel Sambuc  * Intel shall be used in advertising or otherwise to promote the sale, use or
78*433d6423SLionel Sambuc  * other dealings in products derived from or relating to the Covered Code
79*433d6423SLionel Sambuc  * without prior written authorization from Intel.
80*433d6423SLionel Sambuc  *
81*433d6423SLionel Sambuc  * 4. Disclaimer and Export Compliance
82*433d6423SLionel Sambuc  *
83*433d6423SLionel Sambuc  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84*433d6423SLionel Sambuc  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85*433d6423SLionel Sambuc  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86*433d6423SLionel Sambuc  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87*433d6423SLionel Sambuc  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88*433d6423SLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89*433d6423SLionel Sambuc  * PARTICULAR PURPOSE.
90*433d6423SLionel Sambuc  *
91*433d6423SLionel Sambuc  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92*433d6423SLionel Sambuc  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93*433d6423SLionel Sambuc  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94*433d6423SLionel Sambuc  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95*433d6423SLionel Sambuc  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96*433d6423SLionel Sambuc  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97*433d6423SLionel Sambuc  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98*433d6423SLionel Sambuc  * LIMITED REMEDY.
99*433d6423SLionel Sambuc  *
100*433d6423SLionel Sambuc  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101*433d6423SLionel Sambuc  * software or system incorporating such software without first obtaining any
102*433d6423SLionel Sambuc  * required license or other approval from the U. S. Department of Commerce or
103*433d6423SLionel Sambuc  * any other agency or department of the United States Government.  In the
104*433d6423SLionel Sambuc  * event Licensee exports any such software from the United States or
105*433d6423SLionel Sambuc  * re-exports any such software from a foreign destination, Licensee shall
106*433d6423SLionel Sambuc  * ensure that the distribution and export/re-export of the software is in
107*433d6423SLionel Sambuc  * compliance with all laws, regulations, orders, or other restrictions of the
108*433d6423SLionel Sambuc  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109*433d6423SLionel Sambuc  * any of its subsidiaries will export/re-export any technical data, process,
110*433d6423SLionel Sambuc  * software, or service, directly or indirectly, to any country for which the
111*433d6423SLionel Sambuc  * United States government or any agency thereof requires an export license,
112*433d6423SLionel Sambuc  * other governmental approval, or letter of assurance, without first obtaining
113*433d6423SLionel Sambuc  * such license, approval or letter.
114*433d6423SLionel Sambuc  *
115*433d6423SLionel Sambuc  *****************************************************************************/
116*433d6423SLionel Sambuc 
117*433d6423SLionel Sambuc #define __DSOPCODE_C__
118*433d6423SLionel Sambuc 
119*433d6423SLionel Sambuc #include "acpi.h"
120*433d6423SLionel Sambuc #include "accommon.h"
121*433d6423SLionel Sambuc #include "acparser.h"
122*433d6423SLionel Sambuc #include "amlcode.h"
123*433d6423SLionel Sambuc #include "acdispat.h"
124*433d6423SLionel Sambuc #include "acinterp.h"
125*433d6423SLionel Sambuc #include "acnamesp.h"
126*433d6423SLionel Sambuc #include "acevents.h"
127*433d6423SLionel Sambuc #include "actables.h"
128*433d6423SLionel Sambuc 
129*433d6423SLionel Sambuc #define _COMPONENT          ACPI_DISPATCHER
130*433d6423SLionel Sambuc         ACPI_MODULE_NAME    ("dsopcode")
131*433d6423SLionel Sambuc 
132*433d6423SLionel Sambuc /* Local prototypes */
133*433d6423SLionel Sambuc 
134*433d6423SLionel Sambuc static ACPI_STATUS
135*433d6423SLionel Sambuc AcpiDsExecuteArguments (
136*433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *Node,
137*433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *ScopeNode,
138*433d6423SLionel Sambuc     UINT32                  AmlLength,
139*433d6423SLionel Sambuc     UINT8                   *AmlStart);
140*433d6423SLionel Sambuc 
141*433d6423SLionel Sambuc static ACPI_STATUS
142*433d6423SLionel Sambuc AcpiDsInitBufferField (
143*433d6423SLionel Sambuc     UINT16                  AmlOpcode,
144*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ObjDesc,
145*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *BufferDesc,
146*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *OffsetDesc,
147*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *LengthDesc,
148*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ResultDesc);
149*433d6423SLionel Sambuc 
150*433d6423SLionel Sambuc 
151*433d6423SLionel Sambuc /*******************************************************************************
152*433d6423SLionel Sambuc  *
153*433d6423SLionel Sambuc  * FUNCTION:    AcpiDsExecuteArguments
154*433d6423SLionel Sambuc  *
155*433d6423SLionel Sambuc  * PARAMETERS:  Node                - Object NS node
156*433d6423SLionel Sambuc  *              ScopeNode           - Parent NS node
157*433d6423SLionel Sambuc  *              AmlLength           - Length of executable AML
158*433d6423SLionel Sambuc  *              AmlStart            - Pointer to the AML
159*433d6423SLionel Sambuc  *
160*433d6423SLionel Sambuc  * RETURN:      Status.
161*433d6423SLionel Sambuc  *
162*433d6423SLionel Sambuc  * DESCRIPTION: Late (deferred) execution of region or field arguments
163*433d6423SLionel Sambuc  *
164*433d6423SLionel Sambuc  ******************************************************************************/
165*433d6423SLionel Sambuc 
166*433d6423SLionel Sambuc static ACPI_STATUS
167*433d6423SLionel Sambuc AcpiDsExecuteArguments (
168*433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *Node,
169*433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *ScopeNode,
170*433d6423SLionel Sambuc     UINT32                  AmlLength,
171*433d6423SLionel Sambuc     UINT8                   *AmlStart)
172*433d6423SLionel Sambuc {
173*433d6423SLionel Sambuc     ACPI_STATUS             Status;
174*433d6423SLionel Sambuc     ACPI_PARSE_OBJECT       *Op;
175*433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState;
176*433d6423SLionel Sambuc 
177*433d6423SLionel Sambuc 
178*433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (DsExecuteArguments);
179*433d6423SLionel Sambuc 
180*433d6423SLionel Sambuc 
181*433d6423SLionel Sambuc     /*
182*433d6423SLionel Sambuc      * Allocate a new parser op to be the root of the parsed tree
183*433d6423SLionel Sambuc      */
184*433d6423SLionel Sambuc     Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
185*433d6423SLionel Sambuc     if (!Op)
186*433d6423SLionel Sambuc     {
187*433d6423SLionel Sambuc         return_ACPI_STATUS (AE_NO_MEMORY);
188*433d6423SLionel Sambuc     }
189*433d6423SLionel Sambuc 
190*433d6423SLionel Sambuc     /* Save the Node for use in AcpiPsParseAml */
191*433d6423SLionel Sambuc 
192*433d6423SLionel Sambuc     Op->Common.Node = ScopeNode;
193*433d6423SLionel Sambuc 
194*433d6423SLionel Sambuc     /* Create and initialize a new parser state */
195*433d6423SLionel Sambuc 
196*433d6423SLionel Sambuc     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
197*433d6423SLionel Sambuc     if (!WalkState)
198*433d6423SLionel Sambuc     {
199*433d6423SLionel Sambuc         Status = AE_NO_MEMORY;
200*433d6423SLionel Sambuc         goto Cleanup;
201*433d6423SLionel Sambuc     }
202*433d6423SLionel Sambuc 
203*433d6423SLionel Sambuc     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
204*433d6423SLionel Sambuc                     AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
205*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
206*433d6423SLionel Sambuc     {
207*433d6423SLionel Sambuc         AcpiDsDeleteWalkState (WalkState);
208*433d6423SLionel Sambuc         goto Cleanup;
209*433d6423SLionel Sambuc     }
210*433d6423SLionel Sambuc 
211*433d6423SLionel Sambuc     /* Mark this parse as a deferred opcode */
212*433d6423SLionel Sambuc 
213*433d6423SLionel Sambuc     WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP;
214*433d6423SLionel Sambuc     WalkState->DeferredNode = Node;
215*433d6423SLionel Sambuc 
216*433d6423SLionel Sambuc     /* Pass1: Parse the entire declaration */
217*433d6423SLionel Sambuc 
218*433d6423SLionel Sambuc     Status = AcpiPsParseAml (WalkState);
219*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
220*433d6423SLionel Sambuc     {
221*433d6423SLionel Sambuc         goto Cleanup;
222*433d6423SLionel Sambuc     }
223*433d6423SLionel Sambuc 
224*433d6423SLionel Sambuc     /* Get and init the Op created above */
225*433d6423SLionel Sambuc 
226*433d6423SLionel Sambuc     Op->Common.Node = Node;
227*433d6423SLionel Sambuc     AcpiPsDeleteParseTree (Op);
228*433d6423SLionel Sambuc 
229*433d6423SLionel Sambuc     /* Evaluate the deferred arguments */
230*433d6423SLionel Sambuc 
231*433d6423SLionel Sambuc     Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
232*433d6423SLionel Sambuc     if (!Op)
233*433d6423SLionel Sambuc     {
234*433d6423SLionel Sambuc         return_ACPI_STATUS (AE_NO_MEMORY);
235*433d6423SLionel Sambuc     }
236*433d6423SLionel Sambuc 
237*433d6423SLionel Sambuc     Op->Common.Node = ScopeNode;
238*433d6423SLionel Sambuc 
239*433d6423SLionel Sambuc     /* Create and initialize a new parser state */
240*433d6423SLionel Sambuc 
241*433d6423SLionel Sambuc     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
242*433d6423SLionel Sambuc     if (!WalkState)
243*433d6423SLionel Sambuc     {
244*433d6423SLionel Sambuc         Status = AE_NO_MEMORY;
245*433d6423SLionel Sambuc         goto Cleanup;
246*433d6423SLionel Sambuc     }
247*433d6423SLionel Sambuc 
248*433d6423SLionel Sambuc     /* Execute the opcode and arguments */
249*433d6423SLionel Sambuc 
250*433d6423SLionel Sambuc     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
251*433d6423SLionel Sambuc                     AmlLength, NULL, ACPI_IMODE_EXECUTE);
252*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
253*433d6423SLionel Sambuc     {
254*433d6423SLionel Sambuc         AcpiDsDeleteWalkState (WalkState);
255*433d6423SLionel Sambuc         goto Cleanup;
256*433d6423SLionel Sambuc     }
257*433d6423SLionel Sambuc 
258*433d6423SLionel Sambuc     /* Mark this execution as a deferred opcode */
259*433d6423SLionel Sambuc 
260*433d6423SLionel Sambuc     WalkState->DeferredNode = Node;
261*433d6423SLionel Sambuc     Status = AcpiPsParseAml (WalkState);
262*433d6423SLionel Sambuc 
263*433d6423SLionel Sambuc Cleanup:
264*433d6423SLionel Sambuc     AcpiPsDeleteParseTree (Op);
265*433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
266*433d6423SLionel Sambuc }
267*433d6423SLionel Sambuc 
268*433d6423SLionel Sambuc 
269*433d6423SLionel Sambuc /*******************************************************************************
270*433d6423SLionel Sambuc  *
271*433d6423SLionel Sambuc  * FUNCTION:    AcpiDsGetBufferFieldArguments
272*433d6423SLionel Sambuc  *
273*433d6423SLionel Sambuc  * PARAMETERS:  ObjDesc         - A valid BufferField object
274*433d6423SLionel Sambuc  *
275*433d6423SLionel Sambuc  * RETURN:      Status.
276*433d6423SLionel Sambuc  *
277*433d6423SLionel Sambuc  * DESCRIPTION: Get BufferField Buffer and Index.  This implements the late
278*433d6423SLionel Sambuc  *              evaluation of these field attributes.
279*433d6423SLionel Sambuc  *
280*433d6423SLionel Sambuc  ******************************************************************************/
281*433d6423SLionel Sambuc 
282*433d6423SLionel Sambuc ACPI_STATUS
283*433d6423SLionel Sambuc AcpiDsGetBufferFieldArguments (
284*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ObjDesc)
285*433d6423SLionel Sambuc {
286*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ExtraDesc;
287*433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *Node;
288*433d6423SLionel Sambuc     ACPI_STATUS             Status;
289*433d6423SLionel Sambuc 
290*433d6423SLionel Sambuc 
291*433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE_PTR (DsGetBufferFieldArguments, ObjDesc);
292*433d6423SLionel Sambuc 
293*433d6423SLionel Sambuc 
294*433d6423SLionel Sambuc     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
295*433d6423SLionel Sambuc     {
296*433d6423SLionel Sambuc         return_ACPI_STATUS (AE_OK);
297*433d6423SLionel Sambuc     }
298*433d6423SLionel Sambuc 
299*433d6423SLionel Sambuc     /* Get the AML pointer (method object) and BufferField node */
300*433d6423SLionel Sambuc 
301*433d6423SLionel Sambuc     ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
302*433d6423SLionel Sambuc     Node = ObjDesc->BufferField.Node;
303*433d6423SLionel Sambuc 
304*433d6423SLionel Sambuc     ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_BUFFER_FIELD, Node, NULL));
305*433d6423SLionel Sambuc     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
306*433d6423SLionel Sambuc         AcpiUtGetNodeName (Node)));
307*433d6423SLionel Sambuc 
308*433d6423SLionel Sambuc     /* Execute the AML code for the TermArg arguments */
309*433d6423SLionel Sambuc 
310*433d6423SLionel Sambuc     Status = AcpiDsExecuteArguments (Node, Node->Parent,
311*433d6423SLionel Sambuc                 ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
312*433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
313*433d6423SLionel Sambuc }
314*433d6423SLionel Sambuc 
315*433d6423SLionel Sambuc 
316*433d6423SLionel Sambuc /*******************************************************************************
317*433d6423SLionel Sambuc  *
318*433d6423SLionel Sambuc  * FUNCTION:    AcpiDsGetBankFieldArguments
319*433d6423SLionel Sambuc  *
320*433d6423SLionel Sambuc  * PARAMETERS:  ObjDesc         - A valid BankField object
321*433d6423SLionel Sambuc  *
322*433d6423SLionel Sambuc  * RETURN:      Status.
323*433d6423SLionel Sambuc  *
324*433d6423SLionel Sambuc  * DESCRIPTION: Get BankField BankValue.  This implements the late
325*433d6423SLionel Sambuc  *              evaluation of these field attributes.
326*433d6423SLionel Sambuc  *
327*433d6423SLionel Sambuc  ******************************************************************************/
328*433d6423SLionel Sambuc 
329*433d6423SLionel Sambuc ACPI_STATUS
330*433d6423SLionel Sambuc AcpiDsGetBankFieldArguments (
331*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ObjDesc)
332*433d6423SLionel Sambuc {
333*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ExtraDesc;
334*433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *Node;
335*433d6423SLionel Sambuc     ACPI_STATUS             Status;
336*433d6423SLionel Sambuc 
337*433d6423SLionel Sambuc 
338*433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE_PTR (DsGetBankFieldArguments, ObjDesc);
339*433d6423SLionel Sambuc 
340*433d6423SLionel Sambuc 
341*433d6423SLionel Sambuc     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
342*433d6423SLionel Sambuc     {
343*433d6423SLionel Sambuc         return_ACPI_STATUS (AE_OK);
344*433d6423SLionel Sambuc     }
345*433d6423SLionel Sambuc 
346*433d6423SLionel Sambuc     /* Get the AML pointer (method object) and BankField node */
347*433d6423SLionel Sambuc 
348*433d6423SLionel Sambuc     ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
349*433d6423SLionel Sambuc     Node = ObjDesc->BankField.Node;
350*433d6423SLionel Sambuc 
351*433d6423SLionel Sambuc     ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_LOCAL_BANK_FIELD, Node, NULL));
352*433d6423SLionel Sambuc     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
353*433d6423SLionel Sambuc         AcpiUtGetNodeName (Node)));
354*433d6423SLionel Sambuc 
355*433d6423SLionel Sambuc     /* Execute the AML code for the TermArg arguments */
356*433d6423SLionel Sambuc 
357*433d6423SLionel Sambuc     Status = AcpiDsExecuteArguments (Node, Node->Parent,
358*433d6423SLionel Sambuc                 ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
359*433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
360*433d6423SLionel Sambuc }
361*433d6423SLionel Sambuc 
362*433d6423SLionel Sambuc 
363*433d6423SLionel Sambuc /*******************************************************************************
364*433d6423SLionel Sambuc  *
365*433d6423SLionel Sambuc  * FUNCTION:    AcpiDsGetBufferArguments
366*433d6423SLionel Sambuc  *
367*433d6423SLionel Sambuc  * PARAMETERS:  ObjDesc         - A valid Buffer object
368*433d6423SLionel Sambuc  *
369*433d6423SLionel Sambuc  * RETURN:      Status.
370*433d6423SLionel Sambuc  *
371*433d6423SLionel Sambuc  * DESCRIPTION: Get Buffer length and initializer byte list.  This implements
372*433d6423SLionel Sambuc  *              the late evaluation of these attributes.
373*433d6423SLionel Sambuc  *
374*433d6423SLionel Sambuc  ******************************************************************************/
375*433d6423SLionel Sambuc 
376*433d6423SLionel Sambuc ACPI_STATUS
377*433d6423SLionel Sambuc AcpiDsGetBufferArguments (
378*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ObjDesc)
379*433d6423SLionel Sambuc {
380*433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *Node;
381*433d6423SLionel Sambuc     ACPI_STATUS             Status;
382*433d6423SLionel Sambuc 
383*433d6423SLionel Sambuc 
384*433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE_PTR (DsGetBufferArguments, ObjDesc);
385*433d6423SLionel Sambuc 
386*433d6423SLionel Sambuc 
387*433d6423SLionel Sambuc     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
388*433d6423SLionel Sambuc     {
389*433d6423SLionel Sambuc         return_ACPI_STATUS (AE_OK);
390*433d6423SLionel Sambuc     }
391*433d6423SLionel Sambuc 
392*433d6423SLionel Sambuc     /* Get the Buffer node */
393*433d6423SLionel Sambuc 
394*433d6423SLionel Sambuc     Node = ObjDesc->Buffer.Node;
395*433d6423SLionel Sambuc     if (!Node)
396*433d6423SLionel Sambuc     {
397*433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO,
398*433d6423SLionel Sambuc             "No pointer back to namespace node in buffer object %p", ObjDesc));
399*433d6423SLionel Sambuc         return_ACPI_STATUS (AE_AML_INTERNAL);
400*433d6423SLionel Sambuc     }
401*433d6423SLionel Sambuc 
402*433d6423SLionel Sambuc     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
403*433d6423SLionel Sambuc 
404*433d6423SLionel Sambuc     /* Execute the AML code for the TermArg arguments */
405*433d6423SLionel Sambuc 
406*433d6423SLionel Sambuc     Status = AcpiDsExecuteArguments (Node, Node,
407*433d6423SLionel Sambuc                 ObjDesc->Buffer.AmlLength, ObjDesc->Buffer.AmlStart);
408*433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
409*433d6423SLionel Sambuc }
410*433d6423SLionel Sambuc 
411*433d6423SLionel Sambuc 
412*433d6423SLionel Sambuc /*******************************************************************************
413*433d6423SLionel Sambuc  *
414*433d6423SLionel Sambuc  * FUNCTION:    AcpiDsGetPackageArguments
415*433d6423SLionel Sambuc  *
416*433d6423SLionel Sambuc  * PARAMETERS:  ObjDesc         - A valid Package object
417*433d6423SLionel Sambuc  *
418*433d6423SLionel Sambuc  * RETURN:      Status.
419*433d6423SLionel Sambuc  *
420*433d6423SLionel Sambuc  * DESCRIPTION: Get Package length and initializer byte list.  This implements
421*433d6423SLionel Sambuc  *              the late evaluation of these attributes.
422*433d6423SLionel Sambuc  *
423*433d6423SLionel Sambuc  ******************************************************************************/
424*433d6423SLionel Sambuc 
425*433d6423SLionel Sambuc ACPI_STATUS
426*433d6423SLionel Sambuc AcpiDsGetPackageArguments (
427*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ObjDesc)
428*433d6423SLionel Sambuc {
429*433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *Node;
430*433d6423SLionel Sambuc     ACPI_STATUS             Status;
431*433d6423SLionel Sambuc 
432*433d6423SLionel Sambuc 
433*433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE_PTR (DsGetPackageArguments, ObjDesc);
434*433d6423SLionel Sambuc 
435*433d6423SLionel Sambuc 
436*433d6423SLionel Sambuc     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
437*433d6423SLionel Sambuc     {
438*433d6423SLionel Sambuc         return_ACPI_STATUS (AE_OK);
439*433d6423SLionel Sambuc     }
440*433d6423SLionel Sambuc 
441*433d6423SLionel Sambuc     /* Get the Package node */
442*433d6423SLionel Sambuc 
443*433d6423SLionel Sambuc     Node = ObjDesc->Package.Node;
444*433d6423SLionel Sambuc     if (!Node)
445*433d6423SLionel Sambuc     {
446*433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO,
447*433d6423SLionel Sambuc             "No pointer back to namespace node in package %p", ObjDesc));
448*433d6423SLionel Sambuc         return_ACPI_STATUS (AE_AML_INTERNAL);
449*433d6423SLionel Sambuc     }
450*433d6423SLionel Sambuc 
451*433d6423SLionel Sambuc     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n"));
452*433d6423SLionel Sambuc 
453*433d6423SLionel Sambuc     /* Execute the AML code for the TermArg arguments */
454*433d6423SLionel Sambuc 
455*433d6423SLionel Sambuc     Status = AcpiDsExecuteArguments (Node, Node,
456*433d6423SLionel Sambuc                 ObjDesc->Package.AmlLength, ObjDesc->Package.AmlStart);
457*433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
458*433d6423SLionel Sambuc }
459*433d6423SLionel Sambuc 
460*433d6423SLionel Sambuc 
461*433d6423SLionel Sambuc /*****************************************************************************
462*433d6423SLionel Sambuc  *
463*433d6423SLionel Sambuc  * FUNCTION:    AcpiDsGetRegionArguments
464*433d6423SLionel Sambuc  *
465*433d6423SLionel Sambuc  * PARAMETERS:  ObjDesc         - A valid region object
466*433d6423SLionel Sambuc  *
467*433d6423SLionel Sambuc  * RETURN:      Status.
468*433d6423SLionel Sambuc  *
469*433d6423SLionel Sambuc  * DESCRIPTION: Get region address and length.  This implements the late
470*433d6423SLionel Sambuc  *              evaluation of these region attributes.
471*433d6423SLionel Sambuc  *
472*433d6423SLionel Sambuc  ****************************************************************************/
473*433d6423SLionel Sambuc 
474*433d6423SLionel Sambuc ACPI_STATUS
475*433d6423SLionel Sambuc AcpiDsGetRegionArguments (
476*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ObjDesc)
477*433d6423SLionel Sambuc {
478*433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *Node;
479*433d6423SLionel Sambuc     ACPI_STATUS             Status;
480*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ExtraDesc;
481*433d6423SLionel Sambuc 
482*433d6423SLionel Sambuc 
483*433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE_PTR (DsGetRegionArguments, ObjDesc);
484*433d6423SLionel Sambuc 
485*433d6423SLionel Sambuc 
486*433d6423SLionel Sambuc     if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
487*433d6423SLionel Sambuc     {
488*433d6423SLionel Sambuc         return_ACPI_STATUS (AE_OK);
489*433d6423SLionel Sambuc     }
490*433d6423SLionel Sambuc 
491*433d6423SLionel Sambuc     ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
492*433d6423SLionel Sambuc     if (!ExtraDesc)
493*433d6423SLionel Sambuc     {
494*433d6423SLionel Sambuc         return_ACPI_STATUS (AE_NOT_EXIST);
495*433d6423SLionel Sambuc     }
496*433d6423SLionel Sambuc 
497*433d6423SLionel Sambuc     /* Get the Region node */
498*433d6423SLionel Sambuc 
499*433d6423SLionel Sambuc     Node = ObjDesc->Region.Node;
500*433d6423SLionel Sambuc 
501*433d6423SLionel Sambuc     ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_REGION, Node, NULL));
502*433d6423SLionel Sambuc 
503*433d6423SLionel Sambuc     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
504*433d6423SLionel Sambuc         AcpiUtGetNodeName (Node), ExtraDesc->Extra.AmlStart));
505*433d6423SLionel Sambuc 
506*433d6423SLionel Sambuc     /* Execute the argument AML */
507*433d6423SLionel Sambuc 
508*433d6423SLionel Sambuc     Status = AcpiDsExecuteArguments (Node, Node->Parent,
509*433d6423SLionel Sambuc                 ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
510*433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
511*433d6423SLionel Sambuc }
512*433d6423SLionel Sambuc 
513*433d6423SLionel Sambuc 
514*433d6423SLionel Sambuc /*******************************************************************************
515*433d6423SLionel Sambuc  *
516*433d6423SLionel Sambuc  * FUNCTION:    AcpiDsInitializeRegion
517*433d6423SLionel Sambuc  *
518*433d6423SLionel Sambuc  * PARAMETERS:  ObjHandle       - Region namespace node
519*433d6423SLionel Sambuc  *
520*433d6423SLionel Sambuc  * RETURN:      Status
521*433d6423SLionel Sambuc  *
522*433d6423SLionel Sambuc  * DESCRIPTION: Front end to EvInitializeRegion
523*433d6423SLionel Sambuc  *
524*433d6423SLionel Sambuc  ******************************************************************************/
525*433d6423SLionel Sambuc 
526*433d6423SLionel Sambuc ACPI_STATUS
527*433d6423SLionel Sambuc AcpiDsInitializeRegion (
528*433d6423SLionel Sambuc     ACPI_HANDLE             ObjHandle)
529*433d6423SLionel Sambuc {
530*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ObjDesc;
531*433d6423SLionel Sambuc     ACPI_STATUS             Status;
532*433d6423SLionel Sambuc 
533*433d6423SLionel Sambuc 
534*433d6423SLionel Sambuc     ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
535*433d6423SLionel Sambuc 
536*433d6423SLionel Sambuc     /* Namespace is NOT locked */
537*433d6423SLionel Sambuc 
538*433d6423SLionel Sambuc     Status = AcpiEvInitializeRegion (ObjDesc, FALSE);
539*433d6423SLionel Sambuc     return (Status);
540*433d6423SLionel Sambuc }
541*433d6423SLionel Sambuc 
542*433d6423SLionel Sambuc 
543*433d6423SLionel Sambuc /*******************************************************************************
544*433d6423SLionel Sambuc  *
545*433d6423SLionel Sambuc  * FUNCTION:    AcpiDsInitBufferField
546*433d6423SLionel Sambuc  *
547*433d6423SLionel Sambuc  * PARAMETERS:  AmlOpcode       - CreateXxxField
548*433d6423SLionel Sambuc  *              ObjDesc         - BufferField object
549*433d6423SLionel Sambuc  *              BufferDesc      - Host Buffer
550*433d6423SLionel Sambuc  *              OffsetDesc      - Offset into buffer
551*433d6423SLionel Sambuc  *              LengthDesc      - Length of field (CREATE_FIELD_OP only)
552*433d6423SLionel Sambuc  *              ResultDesc      - Where to store the result
553*433d6423SLionel Sambuc  *
554*433d6423SLionel Sambuc  * RETURN:      Status
555*433d6423SLionel Sambuc  *
556*433d6423SLionel Sambuc  * DESCRIPTION: Perform actual initialization of a buffer field
557*433d6423SLionel Sambuc  *
558*433d6423SLionel Sambuc  ******************************************************************************/
559*433d6423SLionel Sambuc 
560*433d6423SLionel Sambuc static ACPI_STATUS
561*433d6423SLionel Sambuc AcpiDsInitBufferField (
562*433d6423SLionel Sambuc     UINT16                  AmlOpcode,
563*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ObjDesc,
564*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *BufferDesc,
565*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *OffsetDesc,
566*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *LengthDesc,
567*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ResultDesc)
568*433d6423SLionel Sambuc {
569*433d6423SLionel Sambuc     UINT32                  Offset;
570*433d6423SLionel Sambuc     UINT32                  BitOffset;
571*433d6423SLionel Sambuc     UINT32                  BitCount;
572*433d6423SLionel Sambuc     UINT8                   FieldFlags;
573*433d6423SLionel Sambuc     ACPI_STATUS             Status;
574*433d6423SLionel Sambuc 
575*433d6423SLionel Sambuc 
576*433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc);
577*433d6423SLionel Sambuc 
578*433d6423SLionel Sambuc 
579*433d6423SLionel Sambuc     /* Host object must be a Buffer */
580*433d6423SLionel Sambuc 
581*433d6423SLionel Sambuc     if (BufferDesc->Common.Type != ACPI_TYPE_BUFFER)
582*433d6423SLionel Sambuc     {
583*433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO,
584*433d6423SLionel Sambuc             "Target of Create Field is not a Buffer object - %s",
585*433d6423SLionel Sambuc             AcpiUtGetObjectTypeName (BufferDesc)));
586*433d6423SLionel Sambuc 
587*433d6423SLionel Sambuc         Status = AE_AML_OPERAND_TYPE;
588*433d6423SLionel Sambuc         goto Cleanup;
589*433d6423SLionel Sambuc     }
590*433d6423SLionel Sambuc 
591*433d6423SLionel Sambuc     /*
592*433d6423SLionel Sambuc      * The last parameter to all of these opcodes (ResultDesc) started
593*433d6423SLionel Sambuc      * out as a NameString, and should therefore now be a NS node
594*433d6423SLionel Sambuc      * after resolution in AcpiExResolveOperands().
595*433d6423SLionel Sambuc      */
596*433d6423SLionel Sambuc     if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
597*433d6423SLionel Sambuc     {
598*433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO,
599*433d6423SLionel Sambuc             "(%s) destination not a NS Node [%s]",
600*433d6423SLionel Sambuc             AcpiPsGetOpcodeName (AmlOpcode),
601*433d6423SLionel Sambuc             AcpiUtGetDescriptorName (ResultDesc)));
602*433d6423SLionel Sambuc 
603*433d6423SLionel Sambuc         Status = AE_AML_OPERAND_TYPE;
604*433d6423SLionel Sambuc         goto Cleanup;
605*433d6423SLionel Sambuc     }
606*433d6423SLionel Sambuc 
607*433d6423SLionel Sambuc     Offset = (UINT32) OffsetDesc->Integer.Value;
608*433d6423SLionel Sambuc 
609*433d6423SLionel Sambuc     /*
610*433d6423SLionel Sambuc      * Setup the Bit offsets and counts, according to the opcode
611*433d6423SLionel Sambuc      */
612*433d6423SLionel Sambuc     switch (AmlOpcode)
613*433d6423SLionel Sambuc     {
614*433d6423SLionel Sambuc     case AML_CREATE_FIELD_OP:
615*433d6423SLionel Sambuc 
616*433d6423SLionel Sambuc         /* Offset is in bits, count is in bits */
617*433d6423SLionel Sambuc 
618*433d6423SLionel Sambuc         FieldFlags = AML_FIELD_ACCESS_BYTE;
619*433d6423SLionel Sambuc         BitOffset  = Offset;
620*433d6423SLionel Sambuc         BitCount   = (UINT32) LengthDesc->Integer.Value;
621*433d6423SLionel Sambuc 
622*433d6423SLionel Sambuc         /* Must have a valid (>0) bit count */
623*433d6423SLionel Sambuc 
624*433d6423SLionel Sambuc         if (BitCount == 0)
625*433d6423SLionel Sambuc         {
626*433d6423SLionel Sambuc             ACPI_ERROR ((AE_INFO,
627*433d6423SLionel Sambuc                 "Attempt to CreateField of length zero"));
628*433d6423SLionel Sambuc             Status = AE_AML_OPERAND_VALUE;
629*433d6423SLionel Sambuc             goto Cleanup;
630*433d6423SLionel Sambuc         }
631*433d6423SLionel Sambuc         break;
632*433d6423SLionel Sambuc 
633*433d6423SLionel Sambuc     case AML_CREATE_BIT_FIELD_OP:
634*433d6423SLionel Sambuc 
635*433d6423SLionel Sambuc         /* Offset is in bits, Field is one bit */
636*433d6423SLionel Sambuc 
637*433d6423SLionel Sambuc         BitOffset  = Offset;
638*433d6423SLionel Sambuc         BitCount   = 1;
639*433d6423SLionel Sambuc         FieldFlags = AML_FIELD_ACCESS_BYTE;
640*433d6423SLionel Sambuc         break;
641*433d6423SLionel Sambuc 
642*433d6423SLionel Sambuc     case AML_CREATE_BYTE_FIELD_OP:
643*433d6423SLionel Sambuc 
644*433d6423SLionel Sambuc         /* Offset is in bytes, field is one byte */
645*433d6423SLionel Sambuc 
646*433d6423SLionel Sambuc         BitOffset  = 8 * Offset;
647*433d6423SLionel Sambuc         BitCount   = 8;
648*433d6423SLionel Sambuc         FieldFlags = AML_FIELD_ACCESS_BYTE;
649*433d6423SLionel Sambuc         break;
650*433d6423SLionel Sambuc 
651*433d6423SLionel Sambuc     case AML_CREATE_WORD_FIELD_OP:
652*433d6423SLionel Sambuc 
653*433d6423SLionel Sambuc         /* Offset is in bytes, field is one word */
654*433d6423SLionel Sambuc 
655*433d6423SLionel Sambuc         BitOffset  = 8 * Offset;
656*433d6423SLionel Sambuc         BitCount   = 16;
657*433d6423SLionel Sambuc         FieldFlags = AML_FIELD_ACCESS_WORD;
658*433d6423SLionel Sambuc         break;
659*433d6423SLionel Sambuc 
660*433d6423SLionel Sambuc     case AML_CREATE_DWORD_FIELD_OP:
661*433d6423SLionel Sambuc 
662*433d6423SLionel Sambuc         /* Offset is in bytes, field is one dword */
663*433d6423SLionel Sambuc 
664*433d6423SLionel Sambuc         BitOffset  = 8 * Offset;
665*433d6423SLionel Sambuc         BitCount   = 32;
666*433d6423SLionel Sambuc         FieldFlags = AML_FIELD_ACCESS_DWORD;
667*433d6423SLionel Sambuc         break;
668*433d6423SLionel Sambuc 
669*433d6423SLionel Sambuc     case AML_CREATE_QWORD_FIELD_OP:
670*433d6423SLionel Sambuc 
671*433d6423SLionel Sambuc         /* Offset is in bytes, field is one qword */
672*433d6423SLionel Sambuc 
673*433d6423SLionel Sambuc         BitOffset  = 8 * Offset;
674*433d6423SLionel Sambuc         BitCount   = 64;
675*433d6423SLionel Sambuc         FieldFlags = AML_FIELD_ACCESS_QWORD;
676*433d6423SLionel Sambuc         break;
677*433d6423SLionel Sambuc 
678*433d6423SLionel Sambuc     default:
679*433d6423SLionel Sambuc 
680*433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO,
681*433d6423SLionel Sambuc             "Unknown field creation opcode 0x%02X",
682*433d6423SLionel Sambuc             AmlOpcode));
683*433d6423SLionel Sambuc         Status = AE_AML_BAD_OPCODE;
684*433d6423SLionel Sambuc         goto Cleanup;
685*433d6423SLionel Sambuc     }
686*433d6423SLionel Sambuc 
687*433d6423SLionel Sambuc     /* Entire field must fit within the current length of the buffer */
688*433d6423SLionel Sambuc 
689*433d6423SLionel Sambuc     if ((BitOffset + BitCount) >
690*433d6423SLionel Sambuc         (8 * (UINT32) BufferDesc->Buffer.Length))
691*433d6423SLionel Sambuc     {
692*433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO,
693*433d6423SLionel Sambuc             "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
694*433d6423SLionel Sambuc             AcpiUtGetNodeName (ResultDesc),
695*433d6423SLionel Sambuc             BitOffset + BitCount,
696*433d6423SLionel Sambuc             AcpiUtGetNodeName (BufferDesc->Buffer.Node),
697*433d6423SLionel Sambuc             8 * (UINT32) BufferDesc->Buffer.Length));
698*433d6423SLionel Sambuc         Status = AE_AML_BUFFER_LIMIT;
699*433d6423SLionel Sambuc         goto Cleanup;
700*433d6423SLionel Sambuc     }
701*433d6423SLionel Sambuc 
702*433d6423SLionel Sambuc     /*
703*433d6423SLionel Sambuc      * Initialize areas of the field object that are common to all fields
704*433d6423SLionel Sambuc      * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
705*433d6423SLionel Sambuc      * UPDATE_RULE = 0 (UPDATE_PRESERVE)
706*433d6423SLionel Sambuc      */
707*433d6423SLionel Sambuc     Status = AcpiExPrepCommonFieldObject (ObjDesc, FieldFlags, 0,
708*433d6423SLionel Sambuc                                             BitOffset, BitCount);
709*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
710*433d6423SLionel Sambuc     {
711*433d6423SLionel Sambuc         goto Cleanup;
712*433d6423SLionel Sambuc     }
713*433d6423SLionel Sambuc 
714*433d6423SLionel Sambuc     ObjDesc->BufferField.BufferObj = BufferDesc;
715*433d6423SLionel Sambuc 
716*433d6423SLionel Sambuc     /* Reference count for BufferDesc inherits ObjDesc count */
717*433d6423SLionel Sambuc 
718*433d6423SLionel Sambuc     BufferDesc->Common.ReferenceCount = (UINT16)
719*433d6423SLionel Sambuc         (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);
720*433d6423SLionel Sambuc 
721*433d6423SLionel Sambuc 
722*433d6423SLionel Sambuc Cleanup:
723*433d6423SLionel Sambuc 
724*433d6423SLionel Sambuc     /* Always delete the operands */
725*433d6423SLionel Sambuc 
726*433d6423SLionel Sambuc     AcpiUtRemoveReference (OffsetDesc);
727*433d6423SLionel Sambuc     AcpiUtRemoveReference (BufferDesc);
728*433d6423SLionel Sambuc 
729*433d6423SLionel Sambuc     if (AmlOpcode == AML_CREATE_FIELD_OP)
730*433d6423SLionel Sambuc     {
731*433d6423SLionel Sambuc         AcpiUtRemoveReference (LengthDesc);
732*433d6423SLionel Sambuc     }
733*433d6423SLionel Sambuc 
734*433d6423SLionel Sambuc     /* On failure, delete the result descriptor */
735*433d6423SLionel Sambuc 
736*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
737*433d6423SLionel Sambuc     {
738*433d6423SLionel Sambuc         AcpiUtRemoveReference (ResultDesc);     /* Result descriptor */
739*433d6423SLionel Sambuc     }
740*433d6423SLionel Sambuc     else
741*433d6423SLionel Sambuc     {
742*433d6423SLionel Sambuc         /* Now the address and length are valid for this BufferField */
743*433d6423SLionel Sambuc 
744*433d6423SLionel Sambuc         ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
745*433d6423SLionel Sambuc     }
746*433d6423SLionel Sambuc 
747*433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
748*433d6423SLionel Sambuc }
749*433d6423SLionel Sambuc 
750*433d6423SLionel Sambuc 
751*433d6423SLionel Sambuc /*******************************************************************************
752*433d6423SLionel Sambuc  *
753*433d6423SLionel Sambuc  * FUNCTION:    AcpiDsEvalBufferFieldOperands
754*433d6423SLionel Sambuc  *
755*433d6423SLionel Sambuc  * PARAMETERS:  WalkState       - Current walk
756*433d6423SLionel Sambuc  *              Op              - A valid BufferField Op object
757*433d6423SLionel Sambuc  *
758*433d6423SLionel Sambuc  * RETURN:      Status
759*433d6423SLionel Sambuc  *
760*433d6423SLionel Sambuc  * DESCRIPTION: Get BufferField Buffer and Index
761*433d6423SLionel Sambuc  *              Called from AcpiDsExecEndOp during BufferField parse tree walk
762*433d6423SLionel Sambuc  *
763*433d6423SLionel Sambuc  ******************************************************************************/
764*433d6423SLionel Sambuc 
765*433d6423SLionel Sambuc ACPI_STATUS
766*433d6423SLionel Sambuc AcpiDsEvalBufferFieldOperands (
767*433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState,
768*433d6423SLionel Sambuc     ACPI_PARSE_OBJECT       *Op)
769*433d6423SLionel Sambuc {
770*433d6423SLionel Sambuc     ACPI_STATUS             Status;
771*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ObjDesc;
772*433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *Node;
773*433d6423SLionel Sambuc     ACPI_PARSE_OBJECT       *NextOp;
774*433d6423SLionel Sambuc 
775*433d6423SLionel Sambuc 
776*433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op);
777*433d6423SLionel Sambuc 
778*433d6423SLionel Sambuc 
779*433d6423SLionel Sambuc     /*
780*433d6423SLionel Sambuc      * This is where we evaluate the address and length fields of the
781*433d6423SLionel Sambuc      * CreateXxxField declaration
782*433d6423SLionel Sambuc      */
783*433d6423SLionel Sambuc     Node =  Op->Common.Node;
784*433d6423SLionel Sambuc 
785*433d6423SLionel Sambuc     /* NextOp points to the op that holds the Buffer */
786*433d6423SLionel Sambuc 
787*433d6423SLionel Sambuc     NextOp = Op->Common.Value.Arg;
788*433d6423SLionel Sambuc 
789*433d6423SLionel Sambuc     /* Evaluate/create the address and length operands */
790*433d6423SLionel Sambuc 
791*433d6423SLionel Sambuc     Status = AcpiDsCreateOperands (WalkState, NextOp);
792*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
793*433d6423SLionel Sambuc     {
794*433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
795*433d6423SLionel Sambuc     }
796*433d6423SLionel Sambuc 
797*433d6423SLionel Sambuc     ObjDesc = AcpiNsGetAttachedObject (Node);
798*433d6423SLionel Sambuc     if (!ObjDesc)
799*433d6423SLionel Sambuc     {
800*433d6423SLionel Sambuc         return_ACPI_STATUS (AE_NOT_EXIST);
801*433d6423SLionel Sambuc     }
802*433d6423SLionel Sambuc 
803*433d6423SLionel Sambuc     /* Resolve the operands */
804*433d6423SLionel Sambuc 
805*433d6423SLionel Sambuc     Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
806*433d6423SLionel Sambuc                     ACPI_WALK_OPERANDS, WalkState);
807*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
808*433d6423SLionel Sambuc     {
809*433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
810*433d6423SLionel Sambuc             AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
811*433d6423SLionel Sambuc 
812*433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
813*433d6423SLionel Sambuc     }
814*433d6423SLionel Sambuc 
815*433d6423SLionel Sambuc     /* Initialize the Buffer Field */
816*433d6423SLionel Sambuc 
817*433d6423SLionel Sambuc     if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
818*433d6423SLionel Sambuc     {
819*433d6423SLionel Sambuc         /* NOTE: Slightly different operands for this opcode */
820*433d6423SLionel Sambuc 
821*433d6423SLionel Sambuc         Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
822*433d6423SLionel Sambuc                     WalkState->Operands[0], WalkState->Operands[1],
823*433d6423SLionel Sambuc                     WalkState->Operands[2], WalkState->Operands[3]);
824*433d6423SLionel Sambuc     }
825*433d6423SLionel Sambuc     else
826*433d6423SLionel Sambuc     {
827*433d6423SLionel Sambuc         /* All other, CreateXxxField opcodes */
828*433d6423SLionel Sambuc 
829*433d6423SLionel Sambuc         Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
830*433d6423SLionel Sambuc                     WalkState->Operands[0], WalkState->Operands[1],
831*433d6423SLionel Sambuc                                       NULL, WalkState->Operands[2]);
832*433d6423SLionel Sambuc     }
833*433d6423SLionel Sambuc 
834*433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
835*433d6423SLionel Sambuc }
836*433d6423SLionel Sambuc 
837*433d6423SLionel Sambuc 
838*433d6423SLionel Sambuc /*******************************************************************************
839*433d6423SLionel Sambuc  *
840*433d6423SLionel Sambuc  * FUNCTION:    AcpiDsEvalRegionOperands
841*433d6423SLionel Sambuc  *
842*433d6423SLionel Sambuc  * PARAMETERS:  WalkState       - Current walk
843*433d6423SLionel Sambuc  *              Op              - A valid region Op object
844*433d6423SLionel Sambuc  *
845*433d6423SLionel Sambuc  * RETURN:      Status
846*433d6423SLionel Sambuc  *
847*433d6423SLionel Sambuc  * DESCRIPTION: Get region address and length
848*433d6423SLionel Sambuc  *              Called from AcpiDsExecEndOp during OpRegion parse tree walk
849*433d6423SLionel Sambuc  *
850*433d6423SLionel Sambuc  ******************************************************************************/
851*433d6423SLionel Sambuc 
852*433d6423SLionel Sambuc ACPI_STATUS
853*433d6423SLionel Sambuc AcpiDsEvalRegionOperands (
854*433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState,
855*433d6423SLionel Sambuc     ACPI_PARSE_OBJECT       *Op)
856*433d6423SLionel Sambuc {
857*433d6423SLionel Sambuc     ACPI_STATUS             Status;
858*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ObjDesc;
859*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *OperandDesc;
860*433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *Node;
861*433d6423SLionel Sambuc     ACPI_PARSE_OBJECT       *NextOp;
862*433d6423SLionel Sambuc 
863*433d6423SLionel Sambuc 
864*433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op);
865*433d6423SLionel Sambuc 
866*433d6423SLionel Sambuc 
867*433d6423SLionel Sambuc     /*
868*433d6423SLionel Sambuc      * This is where we evaluate the address and length fields of the
869*433d6423SLionel Sambuc      * OpRegion declaration
870*433d6423SLionel Sambuc      */
871*433d6423SLionel Sambuc     Node =  Op->Common.Node;
872*433d6423SLionel Sambuc 
873*433d6423SLionel Sambuc     /* NextOp points to the op that holds the SpaceID */
874*433d6423SLionel Sambuc 
875*433d6423SLionel Sambuc     NextOp = Op->Common.Value.Arg;
876*433d6423SLionel Sambuc 
877*433d6423SLionel Sambuc     /* NextOp points to address op */
878*433d6423SLionel Sambuc 
879*433d6423SLionel Sambuc     NextOp = NextOp->Common.Next;
880*433d6423SLionel Sambuc 
881*433d6423SLionel Sambuc     /* Evaluate/create the address and length operands */
882*433d6423SLionel Sambuc 
883*433d6423SLionel Sambuc     Status = AcpiDsCreateOperands (WalkState, NextOp);
884*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
885*433d6423SLionel Sambuc     {
886*433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
887*433d6423SLionel Sambuc     }
888*433d6423SLionel Sambuc 
889*433d6423SLionel Sambuc     /* Resolve the length and address operands to numbers */
890*433d6423SLionel Sambuc 
891*433d6423SLionel Sambuc     Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
892*433d6423SLionel Sambuc                 ACPI_WALK_OPERANDS, WalkState);
893*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
894*433d6423SLionel Sambuc     {
895*433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
896*433d6423SLionel Sambuc     }
897*433d6423SLionel Sambuc 
898*433d6423SLionel Sambuc     ObjDesc = AcpiNsGetAttachedObject (Node);
899*433d6423SLionel Sambuc     if (!ObjDesc)
900*433d6423SLionel Sambuc     {
901*433d6423SLionel Sambuc         return_ACPI_STATUS (AE_NOT_EXIST);
902*433d6423SLionel Sambuc     }
903*433d6423SLionel Sambuc 
904*433d6423SLionel Sambuc     /*
905*433d6423SLionel Sambuc      * Get the length operand and save it
906*433d6423SLionel Sambuc      * (at Top of stack)
907*433d6423SLionel Sambuc      */
908*433d6423SLionel Sambuc     OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
909*433d6423SLionel Sambuc 
910*433d6423SLionel Sambuc     ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
911*433d6423SLionel Sambuc     AcpiUtRemoveReference (OperandDesc);
912*433d6423SLionel Sambuc 
913*433d6423SLionel Sambuc     /*
914*433d6423SLionel Sambuc      * Get the address and save it
915*433d6423SLionel Sambuc      * (at top of stack - 1)
916*433d6423SLionel Sambuc      */
917*433d6423SLionel Sambuc     OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
918*433d6423SLionel Sambuc 
919*433d6423SLionel Sambuc     ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS)
920*433d6423SLionel Sambuc                                 OperandDesc->Integer.Value;
921*433d6423SLionel Sambuc     AcpiUtRemoveReference (OperandDesc);
922*433d6423SLionel Sambuc 
923*433d6423SLionel Sambuc     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
924*433d6423SLionel Sambuc         ObjDesc,
925*433d6423SLionel Sambuc         ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address),
926*433d6423SLionel Sambuc         ObjDesc->Region.Length));
927*433d6423SLionel Sambuc 
928*433d6423SLionel Sambuc     /* Now the address and length are valid for this opregion */
929*433d6423SLionel Sambuc 
930*433d6423SLionel Sambuc     ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
931*433d6423SLionel Sambuc 
932*433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
933*433d6423SLionel Sambuc }
934*433d6423SLionel Sambuc 
935*433d6423SLionel Sambuc 
936*433d6423SLionel Sambuc /*******************************************************************************
937*433d6423SLionel Sambuc  *
938*433d6423SLionel Sambuc  * FUNCTION:    AcpiDsEvalTableRegionOperands
939*433d6423SLionel Sambuc  *
940*433d6423SLionel Sambuc  * PARAMETERS:  WalkState       - Current walk
941*433d6423SLionel Sambuc  *              Op              - A valid region Op object
942*433d6423SLionel Sambuc  *
943*433d6423SLionel Sambuc  * RETURN:      Status
944*433d6423SLionel Sambuc  *
945*433d6423SLionel Sambuc  * DESCRIPTION: Get region address and length
946*433d6423SLionel Sambuc  *              Called from AcpiDsExecEndOp during DataTableRegion parse tree walk
947*433d6423SLionel Sambuc  *
948*433d6423SLionel Sambuc  ******************************************************************************/
949*433d6423SLionel Sambuc 
950*433d6423SLionel Sambuc ACPI_STATUS
951*433d6423SLionel Sambuc AcpiDsEvalTableRegionOperands (
952*433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState,
953*433d6423SLionel Sambuc     ACPI_PARSE_OBJECT       *Op)
954*433d6423SLionel Sambuc {
955*433d6423SLionel Sambuc     ACPI_STATUS             Status;
956*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ObjDesc;
957*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     **Operand;
958*433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *Node;
959*433d6423SLionel Sambuc     ACPI_PARSE_OBJECT       *NextOp;
960*433d6423SLionel Sambuc     UINT32                  TableIndex;
961*433d6423SLionel Sambuc     ACPI_TABLE_HEADER       *Table;
962*433d6423SLionel Sambuc 
963*433d6423SLionel Sambuc 
964*433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op);
965*433d6423SLionel Sambuc 
966*433d6423SLionel Sambuc 
967*433d6423SLionel Sambuc     /*
968*433d6423SLionel Sambuc      * This is where we evaluate the SignatureString and OemIDString
969*433d6423SLionel Sambuc      * and OemTableIDString of the DataTableRegion declaration
970*433d6423SLionel Sambuc      */
971*433d6423SLionel Sambuc     Node =  Op->Common.Node;
972*433d6423SLionel Sambuc 
973*433d6423SLionel Sambuc     /* NextOp points to SignatureString op */
974*433d6423SLionel Sambuc 
975*433d6423SLionel Sambuc     NextOp = Op->Common.Value.Arg;
976*433d6423SLionel Sambuc 
977*433d6423SLionel Sambuc     /*
978*433d6423SLionel Sambuc      * Evaluate/create the SignatureString and OemIDString
979*433d6423SLionel Sambuc      * and OemTableIDString operands
980*433d6423SLionel Sambuc      */
981*433d6423SLionel Sambuc     Status = AcpiDsCreateOperands (WalkState, NextOp);
982*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
983*433d6423SLionel Sambuc     {
984*433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
985*433d6423SLionel Sambuc     }
986*433d6423SLionel Sambuc 
987*433d6423SLionel Sambuc     /*
988*433d6423SLionel Sambuc      * Resolve the SignatureString and OemIDString
989*433d6423SLionel Sambuc      * and OemTableIDString operands
990*433d6423SLionel Sambuc      */
991*433d6423SLionel Sambuc     Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
992*433d6423SLionel Sambuc                 ACPI_WALK_OPERANDS, WalkState);
993*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
994*433d6423SLionel Sambuc     {
995*433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
996*433d6423SLionel Sambuc     }
997*433d6423SLionel Sambuc 
998*433d6423SLionel Sambuc     Operand = &WalkState->Operands[0];
999*433d6423SLionel Sambuc 
1000*433d6423SLionel Sambuc     /* Find the ACPI table */
1001*433d6423SLionel Sambuc 
1002*433d6423SLionel Sambuc     Status = AcpiTbFindTable (Operand[0]->String.Pointer,
1003*433d6423SLionel Sambuc                 Operand[1]->String.Pointer, Operand[2]->String.Pointer,
1004*433d6423SLionel Sambuc                 &TableIndex);
1005*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
1006*433d6423SLionel Sambuc     {
1007*433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
1008*433d6423SLionel Sambuc     }
1009*433d6423SLionel Sambuc 
1010*433d6423SLionel Sambuc     AcpiUtRemoveReference (Operand[0]);
1011*433d6423SLionel Sambuc     AcpiUtRemoveReference (Operand[1]);
1012*433d6423SLionel Sambuc     AcpiUtRemoveReference (Operand[2]);
1013*433d6423SLionel Sambuc 
1014*433d6423SLionel Sambuc     Status = AcpiGetTableByIndex (TableIndex, &Table);
1015*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
1016*433d6423SLionel Sambuc     {
1017*433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
1018*433d6423SLionel Sambuc     }
1019*433d6423SLionel Sambuc 
1020*433d6423SLionel Sambuc     ObjDesc = AcpiNsGetAttachedObject (Node);
1021*433d6423SLionel Sambuc     if (!ObjDesc)
1022*433d6423SLionel Sambuc     {
1023*433d6423SLionel Sambuc         return_ACPI_STATUS (AE_NOT_EXIST);
1024*433d6423SLionel Sambuc     }
1025*433d6423SLionel Sambuc 
1026*433d6423SLionel Sambuc     ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS) ACPI_TO_INTEGER (Table);
1027*433d6423SLionel Sambuc     ObjDesc->Region.Length = Table->Length;
1028*433d6423SLionel Sambuc 
1029*433d6423SLionel Sambuc     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
1030*433d6423SLionel Sambuc         ObjDesc,
1031*433d6423SLionel Sambuc         ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address),
1032*433d6423SLionel Sambuc         ObjDesc->Region.Length));
1033*433d6423SLionel Sambuc 
1034*433d6423SLionel Sambuc     /* Now the address and length are valid for this opregion */
1035*433d6423SLionel Sambuc 
1036*433d6423SLionel Sambuc     ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
1037*433d6423SLionel Sambuc 
1038*433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
1039*433d6423SLionel Sambuc }
1040*433d6423SLionel Sambuc 
1041*433d6423SLionel Sambuc 
1042*433d6423SLionel Sambuc /*******************************************************************************
1043*433d6423SLionel Sambuc  *
1044*433d6423SLionel Sambuc  * FUNCTION:    AcpiDsEvalDataObjectOperands
1045*433d6423SLionel Sambuc  *
1046*433d6423SLionel Sambuc  * PARAMETERS:  WalkState       - Current walk
1047*433d6423SLionel Sambuc  *              Op              - A valid DataObject Op object
1048*433d6423SLionel Sambuc  *              ObjDesc         - DataObject
1049*433d6423SLionel Sambuc  *
1050*433d6423SLionel Sambuc  * RETURN:      Status
1051*433d6423SLionel Sambuc  *
1052*433d6423SLionel Sambuc  * DESCRIPTION: Get the operands and complete the following data object types:
1053*433d6423SLionel Sambuc  *              Buffer, Package.
1054*433d6423SLionel Sambuc  *
1055*433d6423SLionel Sambuc  ******************************************************************************/
1056*433d6423SLionel Sambuc 
1057*433d6423SLionel Sambuc ACPI_STATUS
1058*433d6423SLionel Sambuc AcpiDsEvalDataObjectOperands (
1059*433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState,
1060*433d6423SLionel Sambuc     ACPI_PARSE_OBJECT       *Op,
1061*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ObjDesc)
1062*433d6423SLionel Sambuc {
1063*433d6423SLionel Sambuc     ACPI_STATUS             Status;
1064*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ArgDesc;
1065*433d6423SLionel Sambuc     UINT32                  Length;
1066*433d6423SLionel Sambuc 
1067*433d6423SLionel Sambuc 
1068*433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands);
1069*433d6423SLionel Sambuc 
1070*433d6423SLionel Sambuc 
1071*433d6423SLionel Sambuc     /* The first operand (for all of these data objects) is the length */
1072*433d6423SLionel Sambuc 
1073*433d6423SLionel Sambuc     /*
1074*433d6423SLionel Sambuc      * Set proper index into operand stack for AcpiDsObjStackPush
1075*433d6423SLionel Sambuc      * invoked inside AcpiDsCreateOperand.
1076*433d6423SLionel Sambuc      */
1077*433d6423SLionel Sambuc     WalkState->OperandIndex = WalkState->NumOperands;
1078*433d6423SLionel Sambuc 
1079*433d6423SLionel Sambuc     Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
1080*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
1081*433d6423SLionel Sambuc     {
1082*433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
1083*433d6423SLionel Sambuc     }
1084*433d6423SLionel Sambuc 
1085*433d6423SLionel Sambuc     Status = AcpiExResolveOperands (WalkState->Opcode,
1086*433d6423SLionel Sambuc                     &(WalkState->Operands [WalkState->NumOperands -1]),
1087*433d6423SLionel Sambuc                     WalkState);
1088*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
1089*433d6423SLionel Sambuc     {
1090*433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
1091*433d6423SLionel Sambuc     }
1092*433d6423SLionel Sambuc 
1093*433d6423SLionel Sambuc     /* Extract length operand */
1094*433d6423SLionel Sambuc 
1095*433d6423SLionel Sambuc     ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
1096*433d6423SLionel Sambuc     Length = (UINT32) ArgDesc->Integer.Value;
1097*433d6423SLionel Sambuc 
1098*433d6423SLionel Sambuc     /* Cleanup for length operand */
1099*433d6423SLionel Sambuc 
1100*433d6423SLionel Sambuc     Status = AcpiDsObjStackPop (1, WalkState);
1101*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
1102*433d6423SLionel Sambuc     {
1103*433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
1104*433d6423SLionel Sambuc     }
1105*433d6423SLionel Sambuc 
1106*433d6423SLionel Sambuc     AcpiUtRemoveReference (ArgDesc);
1107*433d6423SLionel Sambuc 
1108*433d6423SLionel Sambuc     /*
1109*433d6423SLionel Sambuc      * Create the actual data object
1110*433d6423SLionel Sambuc      */
1111*433d6423SLionel Sambuc     switch (Op->Common.AmlOpcode)
1112*433d6423SLionel Sambuc     {
1113*433d6423SLionel Sambuc     case AML_BUFFER_OP:
1114*433d6423SLionel Sambuc 
1115*433d6423SLionel Sambuc         Status = AcpiDsBuildInternalBufferObj (WalkState, Op, Length, &ObjDesc);
1116*433d6423SLionel Sambuc         break;
1117*433d6423SLionel Sambuc 
1118*433d6423SLionel Sambuc     case AML_PACKAGE_OP:
1119*433d6423SLionel Sambuc     case AML_VAR_PACKAGE_OP:
1120*433d6423SLionel Sambuc 
1121*433d6423SLionel Sambuc         Status = AcpiDsBuildInternalPackageObj (WalkState, Op, Length, &ObjDesc);
1122*433d6423SLionel Sambuc         break;
1123*433d6423SLionel Sambuc 
1124*433d6423SLionel Sambuc     default:
1125*433d6423SLionel Sambuc         return_ACPI_STATUS (AE_AML_BAD_OPCODE);
1126*433d6423SLionel Sambuc     }
1127*433d6423SLionel Sambuc 
1128*433d6423SLionel Sambuc     if (ACPI_SUCCESS (Status))
1129*433d6423SLionel Sambuc     {
1130*433d6423SLionel Sambuc         /*
1131*433d6423SLionel Sambuc          * Return the object in the WalkState, unless the parent is a package -
1132*433d6423SLionel Sambuc          * in this case, the return object will be stored in the parse tree
1133*433d6423SLionel Sambuc          * for the package.
1134*433d6423SLionel Sambuc          */
1135*433d6423SLionel Sambuc         if ((!Op->Common.Parent) ||
1136*433d6423SLionel Sambuc             ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
1137*433d6423SLionel Sambuc              (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) &&
1138*433d6423SLionel Sambuc              (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
1139*433d6423SLionel Sambuc         {
1140*433d6423SLionel Sambuc             WalkState->ResultObj = ObjDesc;
1141*433d6423SLionel Sambuc         }
1142*433d6423SLionel Sambuc     }
1143*433d6423SLionel Sambuc 
1144*433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
1145*433d6423SLionel Sambuc }
1146*433d6423SLionel Sambuc 
1147*433d6423SLionel Sambuc 
1148*433d6423SLionel Sambuc /*******************************************************************************
1149*433d6423SLionel Sambuc  *
1150*433d6423SLionel Sambuc  * FUNCTION:    AcpiDsEvalBankFieldOperands
1151*433d6423SLionel Sambuc  *
1152*433d6423SLionel Sambuc  * PARAMETERS:  WalkState       - Current walk
1153*433d6423SLionel Sambuc  *              Op              - A valid BankField Op object
1154*433d6423SLionel Sambuc  *
1155*433d6423SLionel Sambuc  * RETURN:      Status
1156*433d6423SLionel Sambuc  *
1157*433d6423SLionel Sambuc  * DESCRIPTION: Get BankField BankValue
1158*433d6423SLionel Sambuc  *              Called from AcpiDsExecEndOp during BankField parse tree walk
1159*433d6423SLionel Sambuc  *
1160*433d6423SLionel Sambuc  ******************************************************************************/
1161*433d6423SLionel Sambuc 
1162*433d6423SLionel Sambuc ACPI_STATUS
1163*433d6423SLionel Sambuc AcpiDsEvalBankFieldOperands (
1164*433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState,
1165*433d6423SLionel Sambuc     ACPI_PARSE_OBJECT       *Op)
1166*433d6423SLionel Sambuc {
1167*433d6423SLionel Sambuc     ACPI_STATUS             Status;
1168*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ObjDesc;
1169*433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *OperandDesc;
1170*433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *Node;
1171*433d6423SLionel Sambuc     ACPI_PARSE_OBJECT       *NextOp;
1172*433d6423SLionel Sambuc     ACPI_PARSE_OBJECT       *Arg;
1173*433d6423SLionel Sambuc 
1174*433d6423SLionel Sambuc 
1175*433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands, Op);
1176*433d6423SLionel Sambuc 
1177*433d6423SLionel Sambuc 
1178*433d6423SLionel Sambuc     /*
1179*433d6423SLionel Sambuc      * This is where we evaluate the BankValue field of the
1180*433d6423SLionel Sambuc      * BankField declaration
1181*433d6423SLionel Sambuc      */
1182*433d6423SLionel Sambuc 
1183*433d6423SLionel Sambuc     /* NextOp points to the op that holds the Region */
1184*433d6423SLionel Sambuc 
1185*433d6423SLionel Sambuc     NextOp = Op->Common.Value.Arg;
1186*433d6423SLionel Sambuc 
1187*433d6423SLionel Sambuc     /* NextOp points to the op that holds the Bank Register */
1188*433d6423SLionel Sambuc 
1189*433d6423SLionel Sambuc     NextOp = NextOp->Common.Next;
1190*433d6423SLionel Sambuc 
1191*433d6423SLionel Sambuc     /* NextOp points to the op that holds the Bank Value */
1192*433d6423SLionel Sambuc 
1193*433d6423SLionel Sambuc     NextOp = NextOp->Common.Next;
1194*433d6423SLionel Sambuc 
1195*433d6423SLionel Sambuc     /*
1196*433d6423SLionel Sambuc      * Set proper index into operand stack for AcpiDsObjStackPush
1197*433d6423SLionel Sambuc      * invoked inside AcpiDsCreateOperand.
1198*433d6423SLionel Sambuc      *
1199*433d6423SLionel Sambuc      * We use WalkState->Operands[0] to store the evaluated BankValue
1200*433d6423SLionel Sambuc      */
1201*433d6423SLionel Sambuc     WalkState->OperandIndex = 0;
1202*433d6423SLionel Sambuc 
1203*433d6423SLionel Sambuc     Status = AcpiDsCreateOperand (WalkState, NextOp, 0);
1204*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
1205*433d6423SLionel Sambuc     {
1206*433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
1207*433d6423SLionel Sambuc     }
1208*433d6423SLionel Sambuc 
1209*433d6423SLionel Sambuc     Status = AcpiExResolveToValue (&WalkState->Operands[0], WalkState);
1210*433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
1211*433d6423SLionel Sambuc     {
1212*433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
1213*433d6423SLionel Sambuc     }
1214*433d6423SLionel Sambuc 
1215*433d6423SLionel Sambuc     ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS,
1216*433d6423SLionel Sambuc         AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 1);
1217*433d6423SLionel Sambuc     /*
1218*433d6423SLionel Sambuc      * Get the BankValue operand and save it
1219*433d6423SLionel Sambuc      * (at Top of stack)
1220*433d6423SLionel Sambuc      */
1221*433d6423SLionel Sambuc     OperandDesc = WalkState->Operands[0];
1222*433d6423SLionel Sambuc 
1223*433d6423SLionel Sambuc     /* Arg points to the start Bank Field */
1224*433d6423SLionel Sambuc 
1225*433d6423SLionel Sambuc     Arg = AcpiPsGetArg (Op, 4);
1226*433d6423SLionel Sambuc     while (Arg)
1227*433d6423SLionel Sambuc     {
1228*433d6423SLionel Sambuc         /* Ignore OFFSET and ACCESSAS terms here */
1229*433d6423SLionel Sambuc 
1230*433d6423SLionel Sambuc         if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
1231*433d6423SLionel Sambuc         {
1232*433d6423SLionel Sambuc             Node = Arg->Common.Node;
1233*433d6423SLionel Sambuc 
1234*433d6423SLionel Sambuc             ObjDesc = AcpiNsGetAttachedObject (Node);
1235*433d6423SLionel Sambuc             if (!ObjDesc)
1236*433d6423SLionel Sambuc             {
1237*433d6423SLionel Sambuc                 return_ACPI_STATUS (AE_NOT_EXIST);
1238*433d6423SLionel Sambuc             }
1239*433d6423SLionel Sambuc 
1240*433d6423SLionel Sambuc             ObjDesc->BankField.Value = (UINT32) OperandDesc->Integer.Value;
1241*433d6423SLionel Sambuc         }
1242*433d6423SLionel Sambuc 
1243*433d6423SLionel Sambuc         /* Move to next field in the list */
1244*433d6423SLionel Sambuc 
1245*433d6423SLionel Sambuc         Arg = Arg->Common.Next;
1246*433d6423SLionel Sambuc     }
1247*433d6423SLionel Sambuc 
1248*433d6423SLionel Sambuc     AcpiUtRemoveReference (OperandDesc);
1249*433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
1250*433d6423SLionel Sambuc }
1251*433d6423SLionel Sambuc 
1252*433d6423SLionel Sambuc 
1253*433d6423SLionel Sambuc /*******************************************************************************
1254*433d6423SLionel Sambuc  *
1255*433d6423SLionel Sambuc  * FUNCTION:    AcpiDsExecBeginControlOp
1256*433d6423SLionel Sambuc  *
1257*433d6423SLionel Sambuc  * PARAMETERS:  WalkList        - The list that owns the walk stack
1258*433d6423SLionel Sambuc  *              Op              - The control Op
1259*433d6423SLionel Sambuc  *
1260*433d6423SLionel Sambuc  * RETURN:      Status
1261*433d6423SLionel Sambuc  *
1262*433d6423SLionel Sambuc  * DESCRIPTION: Handles all control ops encountered during control method
1263*433d6423SLionel Sambuc  *              execution.
1264*433d6423SLionel Sambuc  *
1265*433d6423SLionel Sambuc  ******************************************************************************/
1266*433d6423SLionel Sambuc 
1267*433d6423SLionel Sambuc ACPI_STATUS
1268*433d6423SLionel Sambuc AcpiDsExecBeginControlOp (
1269*433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState,
1270*433d6423SLionel Sambuc     ACPI_PARSE_OBJECT       *Op)
1271*433d6423SLionel Sambuc {
1272*433d6423SLionel Sambuc     ACPI_STATUS             Status = AE_OK;
1273*433d6423SLionel Sambuc     ACPI_GENERIC_STATE      *ControlState;
1274*433d6423SLionel Sambuc 
1275*433d6423SLionel Sambuc 
1276*433d6423SLionel Sambuc     ACPI_FUNCTION_NAME (DsExecBeginControlOp);
1277*433d6423SLionel Sambuc 
1278*433d6423SLionel Sambuc 
1279*433d6423SLionel Sambuc     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", Op,
1280*433d6423SLionel Sambuc         Op->Common.AmlOpcode, WalkState));
1281*433d6423SLionel Sambuc 
1282*433d6423SLionel Sambuc     switch (Op->Common.AmlOpcode)
1283*433d6423SLionel Sambuc     {
1284*433d6423SLionel Sambuc     case AML_WHILE_OP:
1285*433d6423SLionel Sambuc 
1286*433d6423SLionel Sambuc         /*
1287*433d6423SLionel Sambuc          * If this is an additional iteration of a while loop, continue.
1288*433d6423SLionel Sambuc          * There is no need to allocate a new control state.
1289*433d6423SLionel Sambuc          */
1290*433d6423SLionel Sambuc         if (WalkState->ControlState)
1291*433d6423SLionel Sambuc         {
1292*433d6423SLionel Sambuc             if (WalkState->ControlState->Control.AmlPredicateStart ==
1293*433d6423SLionel Sambuc                 (WalkState->ParserState.Aml - 1))
1294*433d6423SLionel Sambuc             {
1295*433d6423SLionel Sambuc                 /* Reset the state to start-of-loop */
1296*433d6423SLionel Sambuc 
1297*433d6423SLionel Sambuc                 WalkState->ControlState->Common.State = ACPI_CONTROL_CONDITIONAL_EXECUTING;
1298*433d6423SLionel Sambuc                 break;
1299*433d6423SLionel Sambuc             }
1300*433d6423SLionel Sambuc         }
1301*433d6423SLionel Sambuc 
1302*433d6423SLionel Sambuc         /*lint -fallthrough */
1303*433d6423SLionel Sambuc 
1304*433d6423SLionel Sambuc     case AML_IF_OP:
1305*433d6423SLionel Sambuc 
1306*433d6423SLionel Sambuc         /*
1307*433d6423SLionel Sambuc          * IF/WHILE: Create a new control state to manage these
1308*433d6423SLionel Sambuc          * constructs. We need to manage these as a stack, in order
1309*433d6423SLionel Sambuc          * to handle nesting.
1310*433d6423SLionel Sambuc          */
1311*433d6423SLionel Sambuc         ControlState = AcpiUtCreateControlState ();
1312*433d6423SLionel Sambuc         if (!ControlState)
1313*433d6423SLionel Sambuc         {
1314*433d6423SLionel Sambuc             Status = AE_NO_MEMORY;
1315*433d6423SLionel Sambuc             break;
1316*433d6423SLionel Sambuc         }
1317*433d6423SLionel Sambuc         /*
1318*433d6423SLionel Sambuc          * Save a pointer to the predicate for multiple executions
1319*433d6423SLionel Sambuc          * of a loop
1320*433d6423SLionel Sambuc          */
1321*433d6423SLionel Sambuc         ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1;
1322*433d6423SLionel Sambuc         ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd;
1323*433d6423SLionel Sambuc         ControlState->Control.Opcode = Op->Common.AmlOpcode;
1324*433d6423SLionel Sambuc 
1325*433d6423SLionel Sambuc 
1326*433d6423SLionel Sambuc         /* Push the control state on this walk's control stack */
1327*433d6423SLionel Sambuc 
1328*433d6423SLionel Sambuc         AcpiUtPushGenericState (&WalkState->ControlState, ControlState);
1329*433d6423SLionel Sambuc         break;
1330*433d6423SLionel Sambuc 
1331*433d6423SLionel Sambuc     case AML_ELSE_OP:
1332*433d6423SLionel Sambuc 
1333*433d6423SLionel Sambuc         /* Predicate is in the state object */
1334*433d6423SLionel Sambuc         /* If predicate is true, the IF was executed, ignore ELSE part */
1335*433d6423SLionel Sambuc 
1336*433d6423SLionel Sambuc         if (WalkState->LastPredicate)
1337*433d6423SLionel Sambuc         {
1338*433d6423SLionel Sambuc             Status = AE_CTRL_TRUE;
1339*433d6423SLionel Sambuc         }
1340*433d6423SLionel Sambuc 
1341*433d6423SLionel Sambuc         break;
1342*433d6423SLionel Sambuc 
1343*433d6423SLionel Sambuc     case AML_RETURN_OP:
1344*433d6423SLionel Sambuc 
1345*433d6423SLionel Sambuc         break;
1346*433d6423SLionel Sambuc 
1347*433d6423SLionel Sambuc     default:
1348*433d6423SLionel Sambuc         break;
1349*433d6423SLionel Sambuc     }
1350*433d6423SLionel Sambuc 
1351*433d6423SLionel Sambuc     return (Status);
1352*433d6423SLionel Sambuc }
1353*433d6423SLionel Sambuc 
1354*433d6423SLionel Sambuc 
1355*433d6423SLionel Sambuc /*******************************************************************************
1356*433d6423SLionel Sambuc  *
1357*433d6423SLionel Sambuc  * FUNCTION:    AcpiDsExecEndControlOp
1358*433d6423SLionel Sambuc  *
1359*433d6423SLionel Sambuc  * PARAMETERS:  WalkList        - The list that owns the walk stack
1360*433d6423SLionel Sambuc  *              Op              - The control Op
1361*433d6423SLionel Sambuc  *
1362*433d6423SLionel Sambuc  * RETURN:      Status
1363*433d6423SLionel Sambuc  *
1364*433d6423SLionel Sambuc  * DESCRIPTION: Handles all control ops encountered during control method
1365*433d6423SLionel Sambuc  *              execution.
1366*433d6423SLionel Sambuc  *
1367*433d6423SLionel Sambuc  ******************************************************************************/
1368*433d6423SLionel Sambuc 
1369*433d6423SLionel Sambuc ACPI_STATUS
1370*433d6423SLionel Sambuc AcpiDsExecEndControlOp (
1371*433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState,
1372*433d6423SLionel Sambuc     ACPI_PARSE_OBJECT       *Op)
1373*433d6423SLionel Sambuc {
1374*433d6423SLionel Sambuc     ACPI_STATUS             Status = AE_OK;
1375*433d6423SLionel Sambuc     ACPI_GENERIC_STATE      *ControlState;
1376*433d6423SLionel Sambuc 
1377*433d6423SLionel Sambuc 
1378*433d6423SLionel Sambuc     ACPI_FUNCTION_NAME (DsExecEndControlOp);
1379*433d6423SLionel Sambuc 
1380*433d6423SLionel Sambuc 
1381*433d6423SLionel Sambuc     switch (Op->Common.AmlOpcode)
1382*433d6423SLionel Sambuc     {
1383*433d6423SLionel Sambuc     case AML_IF_OP:
1384*433d6423SLionel Sambuc 
1385*433d6423SLionel Sambuc         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op));
1386*433d6423SLionel Sambuc 
1387*433d6423SLionel Sambuc         /*
1388*433d6423SLionel Sambuc          * Save the result of the predicate in case there is an
1389*433d6423SLionel Sambuc          * ELSE to come
1390*433d6423SLionel Sambuc          */
1391*433d6423SLionel Sambuc         WalkState->LastPredicate =
1392*433d6423SLionel Sambuc             (BOOLEAN) WalkState->ControlState->Common.Value;
1393*433d6423SLionel Sambuc 
1394*433d6423SLionel Sambuc         /*
1395*433d6423SLionel Sambuc          * Pop the control state that was created at the start
1396*433d6423SLionel Sambuc          * of the IF and free it
1397*433d6423SLionel Sambuc          */
1398*433d6423SLionel Sambuc         ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
1399*433d6423SLionel Sambuc         AcpiUtDeleteGenericState (ControlState);
1400*433d6423SLionel Sambuc         break;
1401*433d6423SLionel Sambuc 
1402*433d6423SLionel Sambuc 
1403*433d6423SLionel Sambuc     case AML_ELSE_OP:
1404*433d6423SLionel Sambuc 
1405*433d6423SLionel Sambuc         break;
1406*433d6423SLionel Sambuc 
1407*433d6423SLionel Sambuc 
1408*433d6423SLionel Sambuc     case AML_WHILE_OP:
1409*433d6423SLionel Sambuc 
1410*433d6423SLionel Sambuc         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op));
1411*433d6423SLionel Sambuc 
1412*433d6423SLionel Sambuc         ControlState = WalkState->ControlState;
1413*433d6423SLionel Sambuc         if (ControlState->Common.Value)
1414*433d6423SLionel Sambuc         {
1415*433d6423SLionel Sambuc             /* Predicate was true, the body of the loop was just executed */
1416*433d6423SLionel Sambuc 
1417*433d6423SLionel Sambuc             /*
1418*433d6423SLionel Sambuc              * This loop counter mechanism allows the interpreter to escape
1419*433d6423SLionel Sambuc              * possibly infinite loops. This can occur in poorly written AML
1420*433d6423SLionel Sambuc              * when the hardware does not respond within a while loop and the
1421*433d6423SLionel Sambuc              * loop does not implement a timeout.
1422*433d6423SLionel Sambuc              */
1423*433d6423SLionel Sambuc             ControlState->Control.LoopCount++;
1424*433d6423SLionel Sambuc             if (ControlState->Control.LoopCount > ACPI_MAX_LOOP_ITERATIONS)
1425*433d6423SLionel Sambuc             {
1426*433d6423SLionel Sambuc                 Status = AE_AML_INFINITE_LOOP;
1427*433d6423SLionel Sambuc                 break;
1428*433d6423SLionel Sambuc             }
1429*433d6423SLionel Sambuc 
1430*433d6423SLionel Sambuc             /*
1431*433d6423SLionel Sambuc              * Go back and evaluate the predicate and maybe execute the loop
1432*433d6423SLionel Sambuc              * another time
1433*433d6423SLionel Sambuc              */
1434*433d6423SLionel Sambuc             Status = AE_CTRL_PENDING;
1435*433d6423SLionel Sambuc             WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart;
1436*433d6423SLionel Sambuc             break;
1437*433d6423SLionel Sambuc         }
1438*433d6423SLionel Sambuc 
1439*433d6423SLionel Sambuc         /* Predicate was false, terminate this while loop */
1440*433d6423SLionel Sambuc 
1441*433d6423SLionel Sambuc         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1442*433d6423SLionel Sambuc             "[WHILE_OP] termination! Op=%p\n",Op));
1443*433d6423SLionel Sambuc 
1444*433d6423SLionel Sambuc         /* Pop this control state and free it */
1445*433d6423SLionel Sambuc 
1446*433d6423SLionel Sambuc         ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
1447*433d6423SLionel Sambuc         AcpiUtDeleteGenericState (ControlState);
1448*433d6423SLionel Sambuc         break;
1449*433d6423SLionel Sambuc 
1450*433d6423SLionel Sambuc 
1451*433d6423SLionel Sambuc     case AML_RETURN_OP:
1452*433d6423SLionel Sambuc 
1453*433d6423SLionel Sambuc         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1454*433d6423SLionel Sambuc             "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg));
1455*433d6423SLionel Sambuc 
1456*433d6423SLionel Sambuc         /*
1457*433d6423SLionel Sambuc          * One optional operand -- the return value
1458*433d6423SLionel Sambuc          * It can be either an immediate operand or a result that
1459*433d6423SLionel Sambuc          * has been bubbled up the tree
1460*433d6423SLionel Sambuc          */
1461*433d6423SLionel Sambuc         if (Op->Common.Value.Arg)
1462*433d6423SLionel Sambuc         {
1463*433d6423SLionel Sambuc             /* Since we have a real Return(), delete any implicit return */
1464*433d6423SLionel Sambuc 
1465*433d6423SLionel Sambuc             AcpiDsClearImplicitReturn (WalkState);
1466*433d6423SLionel Sambuc 
1467*433d6423SLionel Sambuc             /* Return statement has an immediate operand */
1468*433d6423SLionel Sambuc 
1469*433d6423SLionel Sambuc             Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
1470*433d6423SLionel Sambuc             if (ACPI_FAILURE (Status))
1471*433d6423SLionel Sambuc             {
1472*433d6423SLionel Sambuc                 return (Status);
1473*433d6423SLionel Sambuc             }
1474*433d6423SLionel Sambuc 
1475*433d6423SLionel Sambuc             /*
1476*433d6423SLionel Sambuc              * If value being returned is a Reference (such as
1477*433d6423SLionel Sambuc              * an arg or local), resolve it now because it may
1478*433d6423SLionel Sambuc              * cease to exist at the end of the method.
1479*433d6423SLionel Sambuc              */
1480*433d6423SLionel Sambuc             Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
1481*433d6423SLionel Sambuc             if (ACPI_FAILURE (Status))
1482*433d6423SLionel Sambuc             {
1483*433d6423SLionel Sambuc                 return (Status);
1484*433d6423SLionel Sambuc             }
1485*433d6423SLionel Sambuc 
1486*433d6423SLionel Sambuc             /*
1487*433d6423SLionel Sambuc              * Get the return value and save as the last result
1488*433d6423SLionel Sambuc              * value.  This is the only place where WalkState->ReturnDesc
1489*433d6423SLionel Sambuc              * is set to anything other than zero!
1490*433d6423SLionel Sambuc              */
1491*433d6423SLionel Sambuc             WalkState->ReturnDesc = WalkState->Operands[0];
1492*433d6423SLionel Sambuc         }
1493*433d6423SLionel Sambuc         else if (WalkState->ResultCount)
1494*433d6423SLionel Sambuc         {
1495*433d6423SLionel Sambuc             /* Since we have a real Return(), delete any implicit return */
1496*433d6423SLionel Sambuc 
1497*433d6423SLionel Sambuc             AcpiDsClearImplicitReturn (WalkState);
1498*433d6423SLionel Sambuc 
1499*433d6423SLionel Sambuc             /*
1500*433d6423SLionel Sambuc              * The return value has come from a previous calculation.
1501*433d6423SLionel Sambuc              *
1502*433d6423SLionel Sambuc              * If value being returned is a Reference (such as
1503*433d6423SLionel Sambuc              * an arg or local), resolve it now because it may
1504*433d6423SLionel Sambuc              * cease to exist at the end of the method.
1505*433d6423SLionel Sambuc              *
1506*433d6423SLionel Sambuc              * Allow references created by the Index operator to return unchanged.
1507*433d6423SLionel Sambuc              */
1508*433d6423SLionel Sambuc             if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == ACPI_DESC_TYPE_OPERAND) &&
1509*433d6423SLionel Sambuc                 ((WalkState->Results->Results.ObjDesc [0])->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
1510*433d6423SLionel Sambuc                 ((WalkState->Results->Results.ObjDesc [0])->Reference.Class != ACPI_REFCLASS_INDEX))
1511*433d6423SLionel Sambuc             {
1512*433d6423SLionel Sambuc                 Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState);
1513*433d6423SLionel Sambuc                 if (ACPI_FAILURE (Status))
1514*433d6423SLionel Sambuc                 {
1515*433d6423SLionel Sambuc                     return (Status);
1516*433d6423SLionel Sambuc                 }
1517*433d6423SLionel Sambuc             }
1518*433d6423SLionel Sambuc 
1519*433d6423SLionel Sambuc             WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0];
1520*433d6423SLionel Sambuc         }
1521*433d6423SLionel Sambuc         else
1522*433d6423SLionel Sambuc         {
1523*433d6423SLionel Sambuc             /* No return operand */
1524*433d6423SLionel Sambuc 
1525*433d6423SLionel Sambuc             if (WalkState->NumOperands)
1526*433d6423SLionel Sambuc             {
1527*433d6423SLionel Sambuc                 AcpiUtRemoveReference (WalkState->Operands [0]);
1528*433d6423SLionel Sambuc             }
1529*433d6423SLionel Sambuc 
1530*433d6423SLionel Sambuc             WalkState->Operands [0]     = NULL;
1531*433d6423SLionel Sambuc             WalkState->NumOperands      = 0;
1532*433d6423SLionel Sambuc             WalkState->ReturnDesc       = NULL;
1533*433d6423SLionel Sambuc         }
1534*433d6423SLionel Sambuc 
1535*433d6423SLionel Sambuc 
1536*433d6423SLionel Sambuc         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1537*433d6423SLionel Sambuc             "Completed RETURN_OP State=%p, RetVal=%p\n",
1538*433d6423SLionel Sambuc             WalkState, WalkState->ReturnDesc));
1539*433d6423SLionel Sambuc 
1540*433d6423SLionel Sambuc         /* End the control method execution right now */
1541*433d6423SLionel Sambuc 
1542*433d6423SLionel Sambuc         Status = AE_CTRL_TERMINATE;
1543*433d6423SLionel Sambuc         break;
1544*433d6423SLionel Sambuc 
1545*433d6423SLionel Sambuc 
1546*433d6423SLionel Sambuc     case AML_NOOP_OP:
1547*433d6423SLionel Sambuc 
1548*433d6423SLionel Sambuc         /* Just do nothing! */
1549*433d6423SLionel Sambuc         break;
1550*433d6423SLionel Sambuc 
1551*433d6423SLionel Sambuc 
1552*433d6423SLionel Sambuc     case AML_BREAK_POINT_OP:
1553*433d6423SLionel Sambuc 
1554*433d6423SLionel Sambuc         /*
1555*433d6423SLionel Sambuc          * Set the single-step flag. This will cause the debugger (if present)
1556*433d6423SLionel Sambuc          * to break to the console within the AML debugger at the start of the
1557*433d6423SLionel Sambuc          * next AML instruction.
1558*433d6423SLionel Sambuc          */
1559*433d6423SLionel Sambuc         ACPI_DEBUGGER_EXEC (
1560*433d6423SLionel Sambuc             AcpiGbl_CmSingleStep = TRUE);
1561*433d6423SLionel Sambuc         ACPI_DEBUGGER_EXEC (
1562*433d6423SLionel Sambuc             AcpiOsPrintf ("**break** Executed AML BreakPoint opcode\n"));
1563*433d6423SLionel Sambuc 
1564*433d6423SLionel Sambuc         /* Call to the OSL in case OS wants a piece of the action */
1565*433d6423SLionel Sambuc 
1566*433d6423SLionel Sambuc         Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT,
1567*433d6423SLionel Sambuc                     "Executed AML Breakpoint opcode");
1568*433d6423SLionel Sambuc         break;
1569*433d6423SLionel Sambuc 
1570*433d6423SLionel Sambuc 
1571*433d6423SLionel Sambuc     case AML_BREAK_OP:
1572*433d6423SLionel Sambuc     case AML_CONTINUE_OP: /* ACPI 2.0 */
1573*433d6423SLionel Sambuc 
1574*433d6423SLionel Sambuc 
1575*433d6423SLionel Sambuc         /* Pop and delete control states until we find a while */
1576*433d6423SLionel Sambuc 
1577*433d6423SLionel Sambuc         while (WalkState->ControlState &&
1578*433d6423SLionel Sambuc                 (WalkState->ControlState->Control.Opcode != AML_WHILE_OP))
1579*433d6423SLionel Sambuc         {
1580*433d6423SLionel Sambuc             ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
1581*433d6423SLionel Sambuc             AcpiUtDeleteGenericState (ControlState);
1582*433d6423SLionel Sambuc         }
1583*433d6423SLionel Sambuc 
1584*433d6423SLionel Sambuc         /* No while found? */
1585*433d6423SLionel Sambuc 
1586*433d6423SLionel Sambuc         if (!WalkState->ControlState)
1587*433d6423SLionel Sambuc         {
1588*433d6423SLionel Sambuc             return (AE_AML_NO_WHILE);
1589*433d6423SLionel Sambuc         }
1590*433d6423SLionel Sambuc 
1591*433d6423SLionel Sambuc         /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */
1592*433d6423SLionel Sambuc 
1593*433d6423SLionel Sambuc         WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd;
1594*433d6423SLionel Sambuc 
1595*433d6423SLionel Sambuc         /* Return status depending on opcode */
1596*433d6423SLionel Sambuc 
1597*433d6423SLionel Sambuc         if (Op->Common.AmlOpcode == AML_BREAK_OP)
1598*433d6423SLionel Sambuc         {
1599*433d6423SLionel Sambuc             Status = AE_CTRL_BREAK;
1600*433d6423SLionel Sambuc         }
1601*433d6423SLionel Sambuc         else
1602*433d6423SLionel Sambuc         {
1603*433d6423SLionel Sambuc             Status = AE_CTRL_CONTINUE;
1604*433d6423SLionel Sambuc         }
1605*433d6423SLionel Sambuc         break;
1606*433d6423SLionel Sambuc 
1607*433d6423SLionel Sambuc 
1608*433d6423SLionel Sambuc     default:
1609*433d6423SLionel Sambuc 
1610*433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO, "Unknown control opcode=0x%X Op=%p",
1611*433d6423SLionel Sambuc             Op->Common.AmlOpcode, Op));
1612*433d6423SLionel Sambuc 
1613*433d6423SLionel Sambuc         Status = AE_AML_BAD_OPCODE;
1614*433d6423SLionel Sambuc         break;
1615*433d6423SLionel Sambuc     }
1616*433d6423SLionel Sambuc 
1617*433d6423SLionel Sambuc     return (Status);
1618*433d6423SLionel Sambuc }
1619*433d6423SLionel Sambuc 
1620