* Intel ACPI 20030228 distribution with local DragonFly changes.
[dragonfly.git] / sys / contrib / dev / acpica / dsopcode.c
1 /******************************************************************************
2  *
3  * Module Name: dsopcode - Dispatcher Op Region support and handling of
4  *                         "control" opcodes
5  *              $Revision: 85 $
6  *
7  *****************************************************************************/
8
9 /******************************************************************************
10  *
11  * 1. Copyright Notice
12  *
13  * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp.
14  * All rights reserved.
15  *
16  * 2. License
17  *
18  * 2.1. This is your license from Intel Corp. under its intellectual property
19  * rights.  You may have additional license terms from the party that provided
20  * you this software, covering your right to use that party's intellectual
21  * property rights.
22  *
23  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24  * copy of the source code appearing in this file ("Covered Code") an
25  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26  * base code distributed originally by Intel ("Original Intel Code") to copy,
27  * make derivatives, distribute, use and display any portion of the Covered
28  * Code in any form, with the right to sublicense such rights; and
29  *
30  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31  * license (with the right to sublicense), under only those claims of Intel
32  * patents that are infringed by the Original Intel Code, to make, use, sell,
33  * offer to sell, and import the Covered Code and derivative works thereof
34  * solely to the minimum extent necessary to exercise the above copyright
35  * license, and in no event shall the patent license extend to any additions
36  * to or modifications of the Original Intel Code.  No other license or right
37  * is granted directly or by implication, estoppel or otherwise;
38  *
39  * The above copyright and patent license is granted only if the following
40  * conditions are met:
41  *
42  * 3. Conditions
43  *
44  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45  * Redistribution of source code of any substantial portion of the Covered
46  * Code or modification with rights to further distribute source must include
47  * the above Copyright Notice, the above License, this list of Conditions,
48  * and the following Disclaimer and Export Compliance provision.  In addition,
49  * Licensee must cause all Covered Code to which Licensee contributes to
50  * contain a file documenting the changes Licensee made to create that Covered
51  * Code and the date of any change.  Licensee must include in that file the
52  * documentation of any changes made by any predecessor Licensee.  Licensee
53  * must include a prominent statement that the modification is derived,
54  * directly or indirectly, from Original Intel Code.
55  *
56  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57  * Redistribution of source code of any substantial portion of the Covered
58  * Code or modification without rights to further distribute source must
59  * include the following Disclaimer and Export Compliance provision in the
60  * documentation and/or other materials provided with distribution.  In
61  * addition, Licensee may not authorize further sublicense of source of any
62  * portion of the Covered Code, and must include terms to the effect that the
63  * license from Licensee to its licensee is limited to the intellectual
64  * property embodied in the software Licensee provides to its licensee, and
65  * not to intellectual property embodied in modifications its licensee may
66  * make.
67  *
68  * 3.3. Redistribution of Executable. Redistribution in executable form of any
69  * substantial portion of the Covered Code or modification must reproduce the
70  * above Copyright Notice, and the following Disclaimer and Export Compliance
71  * provision in the documentation and/or other materials provided with the
72  * distribution.
73  *
74  * 3.4. Intel retains all right, title, and interest in and to the Original
75  * Intel Code.
76  *
77  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78  * Intel shall be used in advertising or otherwise to promote the sale, use or
79  * other dealings in products derived from or relating to the Covered Code
80  * without prior written authorization from Intel.
81  *
82  * 4. Disclaimer and Export Compliance
83  *
84  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90  * PARTICULAR PURPOSE.
91  *
92  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99  * LIMITED REMEDY.
100  *
101  * 4.3. Licensee shall not export, either directly or indirectly, any of this
102  * software or system incorporating such software without first obtaining any
103  * required license or other approval from the U. S. Department of Commerce or
104  * any other agency or department of the United States Government.  In the
105  * event Licensee exports any such software from the United States or
106  * re-exports any such software from a foreign destination, Licensee shall
107  * ensure that the distribution and export/re-export of the software is in
108  * compliance with all laws, regulations, orders, or other restrictions of the
109  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110  * any of its subsidiaries will export/re-export any technical data, process,
111  * software, or service, directly or indirectly, to any country for which the
112  * United States government or any agency thereof requires an export license,
113  * other governmental approval, or letter of assurance, without first obtaining
114  * such license, approval or letter.
115  *
116  *****************************************************************************/
117 /* $DragonFly: src/sys/contrib/dev/acpica/Attic/dsopcode.c,v 1.1 2003/09/24 03:32:15 drhodus Exp $                                                               */
118
119 #define __DSOPCODE_C__
120
121 #include "acpi.h"
122 #include "acparser.h"
123 #include "amlcode.h"
124 #include "acdispat.h"
125 #include "acinterp.h"
126 #include "acnamesp.h"
127 #include "acevents.h"
128
129 #define _COMPONENT          ACPI_DISPATCHER
130         ACPI_MODULE_NAME    ("dsopcode")
131
132
133 /*****************************************************************************
134  *
135  * FUNCTION:    AcpiDsExecuteArguments
136  *
137  * PARAMETERS:  Node                - Parent NS node
138  *              AmlLength           - Length of executable AML
139  *              AmlStart            - Pointer to the AML
140  *
141  * RETURN:      Status.
142  *
143  * DESCRIPTION: Late execution of region or field arguments
144  *
145  ****************************************************************************/
146
147 ACPI_STATUS
148 AcpiDsExecuteArguments (
149     ACPI_NAMESPACE_NODE     *Node,
150     ACPI_NAMESPACE_NODE     *ScopeNode,
151     UINT32                  AmlLength,
152     UINT8                   *AmlStart)
153 {
154     ACPI_STATUS             Status;
155     ACPI_PARSE_OBJECT       *Op;
156     ACPI_WALK_STATE         *WalkState;
157     ACPI_PARSE_OBJECT       *Arg;
158
159
160     ACPI_FUNCTION_TRACE ("AcpiDsExecuteArguments");
161
162
163     /*
164      * Allocate a new parser op to be the root of the parsed tree
165      */
166     Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
167     if (!Op)
168     {
169         return_ACPI_STATUS (AE_NO_MEMORY);
170     }
171
172     /* Save the Node for use in AcpiPsParseAml */
173
174     Op->Common.Node = ScopeNode;
175
176     /* Create and initialize a new parser state */
177
178     WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT, NULL, NULL, NULL);
179     if (!WalkState)
180     {
181         return_ACPI_STATUS (AE_NO_MEMORY);
182     }
183
184     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
185                     AmlLength, NULL, NULL, 1);
186     if (ACPI_FAILURE (Status))
187     {
188         AcpiDsDeleteWalkState (WalkState);
189         return_ACPI_STATUS (Status);
190     }
191
192     WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP;
193
194     /* Pass1: Parse the entire declaration */
195
196     Status = AcpiPsParseAml (WalkState);
197     if (ACPI_FAILURE (Status))
198     {
199         AcpiPsDeleteParseTree (Op);
200         return_ACPI_STATUS (Status);
201     }
202
203     /* Get and init the Op created above */
204
205     Arg = Op->Common.Value.Arg;
206     Op->Common.Node = Node;
207     Arg->Common.Node = Node;
208     AcpiPsDeleteParseTree (Op);
209
210     /* Evaluate the address and length arguments for the Buffer Field */
211
212     Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
213     if (!Op)
214     {
215         return_ACPI_STATUS (AE_NO_MEMORY);
216     }
217
218     Op->Common.Node = ScopeNode;
219
220     /* Create and initialize a new parser state */
221
222     WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT, NULL, NULL, NULL);
223     if (!WalkState)
224     {
225         return_ACPI_STATUS (AE_NO_MEMORY);
226     }
227
228     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
229                     AmlLength, NULL, NULL, 3);
230     if (ACPI_FAILURE (Status))
231     {
232         AcpiDsDeleteWalkState (WalkState);
233         return_ACPI_STATUS (Status);
234     }
235
236     Status = AcpiPsParseAml (WalkState);
237     AcpiPsDeleteParseTree (Op);
238     return_ACPI_STATUS (Status);
239 }
240
241
242 /*****************************************************************************
243  *
244  * FUNCTION:    AcpiDsGetBufferFieldArguments
245  *
246  * PARAMETERS:  ObjDesc         - A valid BufferField object
247  *
248  * RETURN:      Status.
249  *
250  * DESCRIPTION: Get BufferField Buffer and Index.  This implements the late
251  *              evaluation of these field attributes.
252  *
253  ****************************************************************************/
254
255 ACPI_STATUS
256 AcpiDsGetBufferFieldArguments (
257     ACPI_OPERAND_OBJECT     *ObjDesc)
258 {
259     ACPI_OPERAND_OBJECT     *ExtraDesc;
260     ACPI_NAMESPACE_NODE     *Node;
261     ACPI_STATUS             Status;
262
263
264     ACPI_FUNCTION_TRACE_PTR ("DsGetBufferFieldArguments", ObjDesc);
265
266
267     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
268     {
269         return_ACPI_STATUS (AE_OK);
270     }
271
272     /* Get the AML pointer (method object) and BufferField node */
273
274     ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
275     Node = ObjDesc->BufferField.Node;
276
277     ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_BUFFER_FIELD, Node, NULL));
278     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BufferField JIT Init\n",
279         Node->Name.Ascii));
280
281     /* Execute the AML code for the TermArg arguments */
282
283     Status = AcpiDsExecuteArguments (Node, AcpiNsGetParentNode (Node),
284                 ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
285     return_ACPI_STATUS (Status);
286 }
287
288
289 /*****************************************************************************
290  *
291  * FUNCTION:    AcpiDsGetBufferArguments
292  *
293  * PARAMETERS:  ObjDesc         - A valid Bufferobject
294  *
295  * RETURN:      Status.
296  *
297  * DESCRIPTION: Get Buffer length and initializer byte list.  This implements
298  *              the late evaluation of these attributes.
299  *
300  ****************************************************************************/
301
302 ACPI_STATUS
303 AcpiDsGetBufferArguments (
304     ACPI_OPERAND_OBJECT     *ObjDesc)
305 {
306     ACPI_NAMESPACE_NODE     *Node;
307     ACPI_STATUS             Status;
308
309
310     ACPI_FUNCTION_TRACE_PTR ("DsGetBufferArguments", ObjDesc);
311
312
313     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
314     {
315         return_ACPI_STATUS (AE_OK);
316     }
317
318     /* Get the Buffer node */
319
320     Node = ObjDesc->Buffer.Node;
321     if (!Node)
322     {
323         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
324                 "No pointer back to NS node in buffer %p\n", ObjDesc));
325         return_ACPI_STATUS (AE_AML_INTERNAL);
326     }
327
328     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer JIT Init\n"));
329
330     /* Execute the AML code for the TermArg arguments */
331
332     Status = AcpiDsExecuteArguments (Node, Node,
333                 ObjDesc->Buffer.AmlLength, ObjDesc->Buffer.AmlStart);
334     return_ACPI_STATUS (Status);
335 }
336
337
338 /*****************************************************************************
339  *
340  * FUNCTION:    AcpiDsGetPackageArguments
341  *
342  * PARAMETERS:  ObjDesc         - A valid Packageobject
343  *
344  * RETURN:      Status.
345  *
346  * DESCRIPTION: Get Package length and initializer byte list.  This implements
347  *              the late evaluation of these attributes.
348  *
349  ****************************************************************************/
350
351 ACPI_STATUS
352 AcpiDsGetPackageArguments (
353     ACPI_OPERAND_OBJECT     *ObjDesc)
354 {
355     ACPI_NAMESPACE_NODE     *Node;
356     ACPI_STATUS             Status;
357
358
359     ACPI_FUNCTION_TRACE_PTR ("DsGetPackageArguments", ObjDesc);
360
361
362     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
363     {
364         return_ACPI_STATUS (AE_OK);
365     }
366
367     /* Get the Package node */
368
369     Node = ObjDesc->Package.Node;
370     if (!Node)
371     {
372         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
373                 "No pointer back to NS node in package %p\n", ObjDesc));
374         return_ACPI_STATUS (AE_AML_INTERNAL);
375     }
376
377     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package JIT Init\n"));
378
379     /* Execute the AML code for the TermArg arguments */
380
381     Status = AcpiDsExecuteArguments (Node, Node,
382                 ObjDesc->Package.AmlLength, ObjDesc->Package.AmlStart);
383     return_ACPI_STATUS (Status);
384 }
385
386
387 /*****************************************************************************
388  *
389  * FUNCTION:    AcpiDsGetRegionArguments
390  *
391  * PARAMETERS:  ObjDesc         - A valid region object
392  *
393  * RETURN:      Status.
394  *
395  * DESCRIPTION: Get region address and length.  This implements the late
396  *              evaluation of these region attributes.
397  *
398  ****************************************************************************/
399
400 ACPI_STATUS
401 AcpiDsGetRegionArguments (
402     ACPI_OPERAND_OBJECT     *ObjDesc)
403 {
404     ACPI_NAMESPACE_NODE     *Node;
405     ACPI_STATUS             Status;
406     ACPI_OPERAND_OBJECT     *ExtraDesc;
407
408
409     ACPI_FUNCTION_TRACE_PTR ("DsGetRegionArguments", ObjDesc);
410
411
412     if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
413     {
414         return_ACPI_STATUS (AE_OK);
415     }
416
417     ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
418     if (!ExtraDesc)
419     {
420         return_ACPI_STATUS (AE_NOT_EXIST);
421     }
422
423     /* Get the Region node */
424
425     Node = ObjDesc->Region.Node;
426
427     ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_REGION, Node, NULL));
428
429     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] OpRegion Init at AML %p\n",
430         Node->Name.Ascii, ExtraDesc->Extra.AmlStart));
431
432
433     Status = AcpiDsExecuteArguments (Node, AcpiNsGetParentNode (Node),
434                 ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
435     return_ACPI_STATUS (Status);
436 }
437
438
439 /*****************************************************************************
440  *
441  * FUNCTION:    AcpiDsInitializeRegion
442  *
443  * PARAMETERS:  Op              - A valid region Op object
444  *
445  * RETURN:      Status
446  *
447  * DESCRIPTION: Front end to EvInitializeRegion
448  *
449  ****************************************************************************/
450
451 ACPI_STATUS
452 AcpiDsInitializeRegion (
453     ACPI_HANDLE             ObjHandle)
454 {
455     ACPI_OPERAND_OBJECT     *ObjDesc;
456     ACPI_STATUS             Status;
457
458
459     ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
460
461     /* Namespace is NOT locked */
462
463     Status = AcpiEvInitializeRegion (ObjDesc, FALSE);
464     return (Status);
465 }
466
467
468 /*****************************************************************************
469  *
470  * FUNCTION:    AcpiDsInitBufferField
471  *
472  * PARAMETERS:  AmlOpcode       - CreateXxxField
473  *              ObjDesc         - BufferField object
474  *              BufferDesc      - Host Buffer
475  *              OffsetDesc      - Offset into buffer
476  *              Length          - Length of field (CREATE_FIELD_OP only)
477  *              Result          - Where to store the result
478  *
479  * RETURN:      Status
480  *
481  * DESCRIPTION: Perform actual initialization of a buffer field
482  *
483  ****************************************************************************/
484
485 ACPI_STATUS
486 AcpiDsInitBufferField (
487     UINT16                  AmlOpcode,
488     ACPI_OPERAND_OBJECT     *ObjDesc,
489     ACPI_OPERAND_OBJECT     *BufferDesc,
490     ACPI_OPERAND_OBJECT     *OffsetDesc,
491     ACPI_OPERAND_OBJECT     *LengthDesc,
492     ACPI_OPERAND_OBJECT     *ResultDesc)
493 {
494     UINT32                  Offset;
495     UINT32                  BitOffset;
496     UINT32                  BitCount;
497     UINT8                   FieldFlags;
498     ACPI_STATUS             Status;
499
500
501     ACPI_FUNCTION_TRACE_PTR ("DsInitBufferField", ObjDesc);
502
503
504     /* Host object must be a Buffer */
505
506     if (ACPI_GET_OBJECT_TYPE (BufferDesc) != ACPI_TYPE_BUFFER)
507     {
508         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
509             "Target of Create Field is not a Buffer object - %s\n",
510             AcpiUtGetObjectTypeName (BufferDesc)));
511
512         Status = AE_AML_OPERAND_TYPE;
513         goto Cleanup;
514     }
515
516     /*
517      * The last parameter to all of these opcodes (ResultDesc) started
518      * out as a NameString, and should therefore now be a NS node
519      * after resolution in AcpiExResolveOperands().
520      */
521     if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
522     {
523         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination must be a NS Node\n",
524             AcpiPsGetOpcodeName (AmlOpcode)));
525
526         Status = AE_AML_OPERAND_TYPE;
527         goto Cleanup;
528     }
529
530     Offset = (UINT32) OffsetDesc->Integer.Value;
531
532     /*
533      * Setup the Bit offsets and counts, according to the opcode
534      */
535     switch (AmlOpcode)
536     {
537     case AML_CREATE_FIELD_OP:
538
539         /* Offset is in bits, count is in bits */
540
541         BitOffset  = Offset;
542         BitCount   = (UINT32) LengthDesc->Integer.Value;
543         FieldFlags = AML_FIELD_ACCESS_BYTE;
544         break;
545
546     case AML_CREATE_BIT_FIELD_OP:
547
548         /* Offset is in bits, Field is one bit */
549
550         BitOffset  = Offset;
551         BitCount   = 1;
552         FieldFlags = AML_FIELD_ACCESS_BYTE;
553         break;
554
555     case AML_CREATE_BYTE_FIELD_OP:
556
557         /* Offset is in bytes, field is one byte */
558
559         BitOffset  = 8 * Offset;
560         BitCount   = 8;
561         FieldFlags = AML_FIELD_ACCESS_BYTE;
562         break;
563
564     case AML_CREATE_WORD_FIELD_OP:
565
566         /* Offset is in bytes, field is one word */
567
568         BitOffset  = 8 * Offset;
569         BitCount   = 16;
570         FieldFlags = AML_FIELD_ACCESS_WORD;
571         break;
572
573     case AML_CREATE_DWORD_FIELD_OP:
574
575         /* Offset is in bytes, field is one dword */
576
577         BitOffset  = 8 * Offset;
578         BitCount   = 32;
579         FieldFlags = AML_FIELD_ACCESS_DWORD;
580         break;
581
582     case AML_CREATE_QWORD_FIELD_OP:
583
584         /* Offset is in bytes, field is one qword */
585
586         BitOffset  = 8 * Offset;
587         BitCount   = 64;
588         FieldFlags = AML_FIELD_ACCESS_QWORD;
589         break;
590
591     default:
592
593         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
594             "Unknown field creation opcode %02x\n",
595             AmlOpcode));
596         Status = AE_AML_BAD_OPCODE;
597         goto Cleanup;
598     }
599
600
601     /* Entire field must fit within the current length of the buffer */
602
603     if ((BitOffset + BitCount) >
604         (8 * (UINT32) BufferDesc->Buffer.Length))
605     {
606         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
607             "Field size %d exceeds Buffer size %d (bits)\n",
608              BitOffset + BitCount, 8 * (UINT32) BufferDesc->Buffer.Length));
609         Status = AE_AML_BUFFER_LIMIT;
610         goto Cleanup;
611     }
612
613     /*
614      * Initialize areas of the field object that are common to all fields
615      * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK), UPDATE_RULE = 0 (UPDATE_PRESERVE)
616      */
617     Status = AcpiExPrepCommonFieldObject (ObjDesc, FieldFlags, 0,
618                                             BitOffset, BitCount);
619     if (ACPI_FAILURE (Status))
620     {
621         goto Cleanup;
622     }
623
624     ObjDesc->BufferField.BufferObj = BufferDesc;
625
626     /* Reference count for BufferDesc inherits ObjDesc count */
627
628     BufferDesc->Common.ReferenceCount = (UINT16) (BufferDesc->Common.ReferenceCount +
629                                                   ObjDesc->Common.ReferenceCount);
630
631
632 Cleanup:
633
634     /* Always delete the operands */
635
636     AcpiUtRemoveReference (OffsetDesc);
637     AcpiUtRemoveReference (BufferDesc);
638
639     if (AmlOpcode == AML_CREATE_FIELD_OP)
640     {
641         AcpiUtRemoveReference (LengthDesc);
642     }
643
644     /* On failure, delete the result descriptor */
645
646     if (ACPI_FAILURE (Status))
647     {
648         AcpiUtRemoveReference (ResultDesc);     /* Result descriptor */
649     }
650     else
651     {
652         /* Now the address and length are valid for this BufferField */
653
654         ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
655     }
656
657     return_ACPI_STATUS (Status);
658 }
659
660
661 /*****************************************************************************
662  *
663  * FUNCTION:    AcpiDsEvalBufferFieldOperands
664  *
665  * PARAMETERS:  WalkState       - Current walk
666  *              Op              - A valid BufferField Op object
667  *
668  * RETURN:      Status
669  *
670  * DESCRIPTION: Get BufferField Buffer and Index
671  *              Called from AcpiDsExecEndOp during BufferField parse tree walk
672  *
673  ****************************************************************************/
674
675 ACPI_STATUS
676 AcpiDsEvalBufferFieldOperands (
677     ACPI_WALK_STATE         *WalkState,
678     ACPI_PARSE_OBJECT       *Op)
679 {
680     ACPI_STATUS             Status;
681     ACPI_OPERAND_OBJECT     *ObjDesc;
682     ACPI_NAMESPACE_NODE     *Node;
683     ACPI_PARSE_OBJECT       *NextOp;
684
685
686     ACPI_FUNCTION_TRACE_PTR ("DsEvalBufferFieldOperands", Op);
687
688
689     /*
690      * This is where we evaluate the address and length fields of the
691      * CreateXxxField declaration
692      */
693     Node =  Op->Common.Node;
694
695     /* NextOp points to the op that holds the Buffer */
696
697     NextOp = Op->Common.Value.Arg;
698
699     /* Evaluate/create the address and length operands */
700
701     Status = AcpiDsCreateOperands (WalkState, NextOp);
702     if (ACPI_FAILURE (Status))
703     {
704         return_ACPI_STATUS (Status);
705     }
706
707     ObjDesc = AcpiNsGetAttachedObject (Node);
708     if (!ObjDesc)
709     {
710         return_ACPI_STATUS (AE_NOT_EXIST);
711     }
712
713     /* Resolve the operands */
714
715     Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
716                     ACPI_WALK_OPERANDS, WalkState);
717
718     ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
719                     AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
720                     WalkState->NumOperands, "after AcpiExResolveOperands");
721
722     if (ACPI_FAILURE (Status))
723     {
724         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n",
725             AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
726
727         return_ACPI_STATUS (Status);
728     }
729
730     /* Initialize the Buffer Field */
731
732     if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
733     {
734         /* NOTE: Slightly different operands for this opcode */
735
736         Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
737                     WalkState->Operands[0], WalkState->Operands[1],
738                     WalkState->Operands[2], WalkState->Operands[3]);
739     }
740     else
741     {
742         /* All other, CreateXxxField opcodes */
743
744         Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
745                     WalkState->Operands[0], WalkState->Operands[1],
746                                       NULL, WalkState->Operands[2]);
747     }
748
749     return_ACPI_STATUS (Status);
750 }
751
752
753 /*****************************************************************************
754  *
755  * FUNCTION:    AcpiDsEvalRegionOperands
756  *
757  * PARAMETERS:  WalkState       - Current walk
758  *              Op              - A valid region Op object
759  *
760  * RETURN:      Status
761  *
762  * DESCRIPTION: Get region address and length
763  *              Called from AcpiDsExecEndOp during OpRegion parse tree walk
764  *
765  ****************************************************************************/
766
767 ACPI_STATUS
768 AcpiDsEvalRegionOperands (
769     ACPI_WALK_STATE         *WalkState,
770     ACPI_PARSE_OBJECT       *Op)
771 {
772     ACPI_STATUS             Status;
773     ACPI_OPERAND_OBJECT     *ObjDesc;
774     ACPI_OPERAND_OBJECT     *OperandDesc;
775     ACPI_NAMESPACE_NODE     *Node;
776     ACPI_PARSE_OBJECT       *NextOp;
777
778
779     ACPI_FUNCTION_TRACE_PTR ("DsEvalRegionOperands", Op);
780
781
782     /*
783      * This is where we evaluate the address and length fields of the OpRegion declaration
784      */
785     Node =  Op->Common.Node;
786
787     /* NextOp points to the op that holds the SpaceID */
788
789     NextOp = Op->Common.Value.Arg;
790
791     /* NextOp points to address op */
792
793     NextOp = NextOp->Common.Next;
794
795     /* Evaluate/create the address and length operands */
796
797     Status = AcpiDsCreateOperands (WalkState, NextOp);
798     if (ACPI_FAILURE (Status))
799     {
800         return_ACPI_STATUS (Status);
801     }
802
803     /* Resolve the length and address operands to numbers */
804
805     Status = AcpiExResolveOperands (Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
806     if (ACPI_FAILURE (Status))
807     {
808         return_ACPI_STATUS (Status);
809     }
810
811     ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
812                     AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
813                     1, "after AcpiExResolveOperands");
814
815     ObjDesc = AcpiNsGetAttachedObject (Node);
816     if (!ObjDesc)
817     {
818         return_ACPI_STATUS (AE_NOT_EXIST);
819     }
820
821     /*
822      * Get the length operand and save it
823      * (at Top of stack)
824      */
825     OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
826
827     ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
828     AcpiUtRemoveReference (OperandDesc);
829
830     /*
831      * Get the address and save it
832      * (at top of stack - 1)
833      */
834     OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
835
836     ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS) OperandDesc->Integer.Value;
837     AcpiUtRemoveReference (OperandDesc);
838
839     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
840         ObjDesc,
841         ACPI_HIDWORD (ObjDesc->Region.Address), ACPI_LODWORD (ObjDesc->Region.Address),
842         ObjDesc->Region.Length));
843
844     /* Now the address and length are valid for this opregion */
845
846     ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
847
848     return_ACPI_STATUS (Status);
849 }
850
851
852 /*****************************************************************************
853  *
854  * FUNCTION:    AcpiDsEvalDataObjectOperands
855  *
856  * PARAMETERS:  WalkState       - Current walk
857  *              Op              - A valid DataObject Op object
858  *              ObjDesc         - DataObject
859  *
860  * RETURN:      Status
861  *
862  * DESCRIPTION: Get the operands and complete the following data objec types:
863  *              Buffer
864  *              Package
865  *
866  ****************************************************************************/
867
868 ACPI_STATUS
869 AcpiDsEvalDataObjectOperands (
870     ACPI_WALK_STATE         *WalkState,
871     ACPI_PARSE_OBJECT       *Op,
872     ACPI_OPERAND_OBJECT     *ObjDesc)
873 {
874     ACPI_STATUS             Status;
875     ACPI_OPERAND_OBJECT     *ArgDesc;
876     UINT32                  Length;
877
878
879     ACPI_FUNCTION_TRACE ("DsEvalDataObjectOperands");
880
881
882     /* The first operand (for all of these data objects) is the length */
883
884     Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
885     if (ACPI_FAILURE (Status))
886     {
887         return_ACPI_STATUS (Status);
888     }
889
890     Status = AcpiExResolveOperands (WalkState->Opcode,
891                     &(WalkState->Operands [WalkState->NumOperands -1]),
892                     WalkState);
893     if (ACPI_FAILURE (Status))
894     {
895         return_ACPI_STATUS (Status);
896     }
897
898     /* Extract length operand */
899
900     ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
901     Length = (UINT32) ArgDesc->Integer.Value;
902
903     /* Cleanup for length operand */
904
905     Status = AcpiDsObjStackPop (1, WalkState);
906     if (ACPI_FAILURE (Status))
907     {
908         return_ACPI_STATUS (Status);
909     }
910
911     AcpiUtRemoveReference (ArgDesc);
912
913     /*
914      * Create the actual data object
915      */
916     switch (Op->Common.AmlOpcode)
917     {
918     case AML_BUFFER_OP:
919
920         Status = AcpiDsBuildInternalBufferObj (WalkState, Op, Length, &ObjDesc);
921         break;
922
923     case AML_PACKAGE_OP:
924     case AML_VAR_PACKAGE_OP:
925
926         Status = AcpiDsBuildInternalPackageObj (WalkState, Op, Length, &ObjDesc);
927         break;
928
929     default:
930         return_ACPI_STATUS (AE_AML_BAD_OPCODE);
931     }
932
933     if (ACPI_SUCCESS (Status))
934     {
935         /*
936          * Return the object in the WalkState, unless the parent is a package --
937          * in this case, the return object will be stored in the parse tree
938          * for the package.
939          */
940         if ((!Op->Common.Parent) ||
941             ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
942              (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) &&
943              (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
944         {
945             WalkState->ResultObj = ObjDesc;
946         }
947     }
948
949     return_ACPI_STATUS (Status);
950 }
951
952
953 /*******************************************************************************
954  *
955  * FUNCTION:    AcpiDsExecBeginControlOp
956  *
957  * PARAMETERS:  WalkList        - The list that owns the walk stack
958  *              Op              - The control Op
959  *
960  * RETURN:      Status
961  *
962  * DESCRIPTION: Handles all control ops encountered during control method
963  *              execution.
964  *
965  ******************************************************************************/
966
967 ACPI_STATUS
968 AcpiDsExecBeginControlOp (
969     ACPI_WALK_STATE         *WalkState,
970     ACPI_PARSE_OBJECT       *Op)
971 {
972     ACPI_STATUS             Status = AE_OK;
973     ACPI_GENERIC_STATE      *ControlState;
974
975
976     ACPI_FUNCTION_NAME ("DsExecBeginControlOp");
977
978
979     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", Op,
980         Op->Common.AmlOpcode, WalkState));
981
982     switch (Op->Common.AmlOpcode)
983     {
984     case AML_IF_OP:
985     case AML_WHILE_OP:
986
987         /*
988          * IF/WHILE: Create a new control state to manage these
989          * constructs. We need to manage these as a stack, in order
990          * to handle nesting.
991          */
992         ControlState = AcpiUtCreateControlState ();
993         if (!ControlState)
994         {
995             Status = AE_NO_MEMORY;
996             break;
997         }
998         /*
999          * Save a pointer to the predicate for multiple executions
1000          * of a loop
1001          */
1002         ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1;
1003         ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd;
1004         ControlState->Control.Opcode = Op->Common.AmlOpcode;
1005
1006
1007         /* Push the control state on this walk's control stack */
1008
1009         AcpiUtPushGenericState (&WalkState->ControlState, ControlState);
1010         break;
1011
1012     case AML_ELSE_OP:
1013
1014         /* Predicate is in the state object */
1015         /* If predicate is true, the IF was executed, ignore ELSE part */
1016
1017         if (WalkState->LastPredicate)
1018         {
1019             Status = AE_CTRL_TRUE;
1020         }
1021
1022         break;
1023
1024     case AML_RETURN_OP:
1025
1026         break;
1027
1028     default:
1029         break;
1030     }
1031
1032     return (Status);
1033 }
1034
1035
1036 /*******************************************************************************
1037  *
1038  * FUNCTION:    AcpiDsExecEndControlOp
1039  *
1040  * PARAMETERS:  WalkList        - The list that owns the walk stack
1041  *              Op              - The control Op
1042  *
1043  * RETURN:      Status
1044  *
1045  * DESCRIPTION: Handles all control ops encountered during control method
1046  *              execution.
1047  *
1048  ******************************************************************************/
1049
1050 ACPI_STATUS
1051 AcpiDsExecEndControlOp (
1052     ACPI_WALK_STATE         *WalkState,
1053     ACPI_PARSE_OBJECT       *Op)
1054 {
1055     ACPI_STATUS             Status = AE_OK;
1056     ACPI_GENERIC_STATE      *ControlState;
1057
1058
1059     ACPI_FUNCTION_NAME ("DsExecEndControlOp");
1060
1061
1062     switch (Op->Common.AmlOpcode)
1063     {
1064     case AML_IF_OP:
1065
1066         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op));
1067
1068         /*
1069          * Save the result of the predicate in case there is an
1070          * ELSE to come
1071          */
1072         WalkState->LastPredicate =
1073             (BOOLEAN) WalkState->ControlState->Common.Value;
1074
1075         /*
1076          * Pop the control state that was created at the start
1077          * of the IF and free it
1078          */
1079         ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
1080         AcpiUtDeleteGenericState (ControlState);
1081         break;
1082
1083
1084     case AML_ELSE_OP:
1085
1086         break;
1087
1088
1089     case AML_WHILE_OP:
1090
1091         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op));
1092
1093         if (WalkState->ControlState->Common.Value)
1094         {
1095             /* Predicate was true, go back and evaluate it again! */
1096
1097             Status = AE_CTRL_PENDING;
1098         }
1099
1100         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] termination! Op=%p\n", Op));
1101
1102         /* Pop this control state and free it */
1103
1104         ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
1105
1106         WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart;
1107         AcpiUtDeleteGenericState (ControlState);
1108         break;
1109
1110
1111     case AML_RETURN_OP:
1112
1113         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1114             "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg));
1115
1116         /*
1117          * One optional operand -- the return value
1118          * It can be either an immediate operand or a result that
1119          * has been bubbled up the tree
1120          */
1121         if (Op->Common.Value.Arg)
1122         {
1123             /* Return statement has an immediate operand */
1124
1125             Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
1126             if (ACPI_FAILURE (Status))
1127             {
1128                 return (Status);
1129             }
1130
1131             /*
1132              * If value being returned is a Reference (such as
1133              * an arg or local), resolve it now because it may
1134              * cease to exist at the end of the method.
1135              */
1136             Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
1137             if (ACPI_FAILURE (Status))
1138             {
1139                 return (Status);
1140             }
1141
1142             /*
1143              * Get the return value and save as the last result
1144              * value.  This is the only place where WalkState->ReturnDesc
1145              * is set to anything other than zero!
1146              */
1147             WalkState->ReturnDesc = WalkState->Operands[0];
1148         }
1149         else if ((WalkState->Results) &&
1150                  (WalkState->Results->Results.NumResults > 0))
1151         {
1152             /*
1153              * The return value has come from a previous calculation.
1154              *
1155              * If value being returned is a Reference (such as
1156              * an arg or local), resolve it now because it may
1157              * cease to exist at the end of the method.
1158              *
1159              * Allow references created by the Index operator to return unchanged.
1160              */
1161             if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == ACPI_DESC_TYPE_OPERAND) &&
1162                 (ACPI_GET_OBJECT_TYPE (WalkState->Results->Results.ObjDesc [0]) == ACPI_TYPE_LOCAL_REFERENCE) &&
1163                 ((WalkState->Results->Results.ObjDesc [0])->Reference.Opcode != AML_INDEX_OP))
1164             {
1165                 Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState);
1166                 if (ACPI_FAILURE (Status))
1167                 {
1168                     return (Status);
1169                 }
1170             }
1171
1172             WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0];
1173         }
1174         else
1175         {
1176             /* No return operand */
1177
1178             if (WalkState->NumOperands)
1179             {
1180                 AcpiUtRemoveReference (WalkState->Operands [0]);
1181             }
1182
1183             WalkState->Operands [0]     = NULL;
1184             WalkState->NumOperands      = 0;
1185             WalkState->ReturnDesc       = NULL;
1186         }
1187
1188
1189         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1190             "Completed RETURN_OP State=%p, RetVal=%p\n",
1191             WalkState, WalkState->ReturnDesc));
1192
1193         /* End the control method execution right now */
1194
1195         Status = AE_CTRL_TERMINATE;
1196         break;
1197
1198
1199     case AML_NOOP_OP:
1200
1201         /* Just do nothing! */
1202         break;
1203
1204
1205     case AML_BREAK_POINT_OP:
1206
1207         /* Call up to the OS service layer to handle this */
1208
1209         Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT, "Executed AML Breakpoint opcode");
1210
1211         /* If and when it returns, all done. */
1212
1213         break;
1214
1215
1216     case AML_BREAK_OP:
1217     case AML_CONTINUE_OP: /* ACPI 2.0 */
1218
1219
1220         /* Pop and delete control states until we find a while */
1221
1222         while (WalkState->ControlState &&
1223                 (WalkState->ControlState->Control.Opcode != AML_WHILE_OP))
1224         {
1225             ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
1226             AcpiUtDeleteGenericState (ControlState);
1227         }
1228
1229         /* No while found? */
1230
1231         if (!WalkState->ControlState)
1232         {
1233             return (AE_AML_NO_WHILE);
1234         }
1235
1236         /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */
1237
1238         WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd;
1239
1240         /* Return status depending on opcode */
1241
1242         if (Op->Common.AmlOpcode == AML_BREAK_OP)
1243         {
1244             Status = AE_CTRL_BREAK;
1245         }
1246         else
1247         {
1248             Status = AE_CTRL_CONTINUE;
1249         }
1250         break;
1251
1252
1253     default:
1254
1255         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown control opcode=%X Op=%p\n",
1256             Op->Common.AmlOpcode, Op));
1257
1258         Status = AE_AML_BAD_OPCODE;
1259         break;
1260     }
1261
1262     return (Status);
1263 }
1264