Merge from vendor branch LIBARCHIVE:
[dragonfly.git] / sys / contrib / dev / acpica-unix-20061109 / interpreter / dispatcher / dsopcode.c
1 /******************************************************************************
2  *
3  * Module Name: dsopcode - Dispatcher Op Region support and handling of
4  *                         "control" opcodes
5  *              $Revision: 1.109 $
6  *
7  *****************************************************************************/
8
9 /******************************************************************************
10  *
11  * 1. Copyright Notice
12  *
13  * Some or all of this work - Copyright (c) 1999 - 2006, 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
118 #define __DSOPCODE_C__
119
120 #include "acpi.h"
121 #include "acparser.h"
122 #include "amlcode.h"
123 #include "acdispat.h"
124 #include "acinterp.h"
125 #include "acnamesp.h"
126 #include "acevents.h"
127
128 #define _COMPONENT          ACPI_DISPATCHER
129         ACPI_MODULE_NAME    ("dsopcode")
130
131 /* Local prototypes */
132
133 static ACPI_STATUS
134 AcpiDsExecuteArguments (
135     ACPI_NAMESPACE_NODE     *Node,
136     ACPI_NAMESPACE_NODE     *ScopeNode,
137     UINT32                  AmlLength,
138     UINT8                   *AmlStart);
139
140 static ACPI_STATUS
141 AcpiDsInitBufferField (
142     UINT16                  AmlOpcode,
143     ACPI_OPERAND_OBJECT     *ObjDesc,
144     ACPI_OPERAND_OBJECT     *BufferDesc,
145     ACPI_OPERAND_OBJECT     *OffsetDesc,
146     ACPI_OPERAND_OBJECT     *LengthDesc,
147     ACPI_OPERAND_OBJECT     *ResultDesc);
148
149
150 /*******************************************************************************
151  *
152  * FUNCTION:    AcpiDsExecuteArguments
153  *
154  * PARAMETERS:  Node                - Object NS node
155  *              ScopeNode           - Parent NS node
156  *              AmlLength           - Length of executable AML
157  *              AmlStart            - Pointer to the AML
158  *
159  * RETURN:      Status.
160  *
161  * DESCRIPTION: Late (deferred) execution of region or field arguments
162  *
163  ******************************************************************************/
164
165 static ACPI_STATUS
166 AcpiDsExecuteArguments (
167     ACPI_NAMESPACE_NODE     *Node,
168     ACPI_NAMESPACE_NODE     *ScopeNode,
169     UINT32                  AmlLength,
170     UINT8                   *AmlStart)
171 {
172     ACPI_STATUS             Status;
173     ACPI_PARSE_OBJECT       *Op;
174     ACPI_WALK_STATE         *WalkState;
175
176
177     ACPI_FUNCTION_TRACE (DsExecuteArguments);
178
179
180     /*
181      * Allocate a new parser op to be the root of the parsed tree
182      */
183     Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
184     if (!Op)
185     {
186         return_ACPI_STATUS (AE_NO_MEMORY);
187     }
188
189     /* Save the Node for use in AcpiPsParseAml */
190
191     Op->Common.Node = ScopeNode;
192
193     /* Create and initialize a new parser state */
194
195     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
196     if (!WalkState)
197     {
198         Status = AE_NO_MEMORY;
199         goto Cleanup;
200     }
201
202     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
203                     AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
204     if (ACPI_FAILURE (Status))
205     {
206         AcpiDsDeleteWalkState (WalkState);
207         goto Cleanup;
208     }
209
210     /* Mark this parse as a deferred opcode */
211
212     WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP;
213     WalkState->DeferredNode = Node;
214
215     /* Pass1: Parse the entire declaration */
216
217     Status = AcpiPsParseAml (WalkState);
218     if (ACPI_FAILURE (Status))
219     {
220         goto Cleanup;
221     }
222
223     /* Get and init the Op created above */
224
225     Op->Common.Node = Node;
226     AcpiPsDeleteParseTree (Op);
227
228     /* Evaluate the deferred arguments */
229
230     Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
231     if (!Op)
232     {
233         return_ACPI_STATUS (AE_NO_MEMORY);
234     }
235
236     Op->Common.Node = ScopeNode;
237
238     /* Create and initialize a new parser state */
239
240     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
241     if (!WalkState)
242     {
243         Status = AE_NO_MEMORY;
244         goto Cleanup;
245     }
246
247     /* Execute the opcode and arguments */
248
249     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
250                     AmlLength, NULL, ACPI_IMODE_EXECUTE);
251     if (ACPI_FAILURE (Status))
252     {
253         AcpiDsDeleteWalkState (WalkState);
254         goto Cleanup;
255     }
256
257     /* Mark this execution as a deferred opcode */
258
259     WalkState->DeferredNode = Node;
260     Status = AcpiPsParseAml (WalkState);
261
262 Cleanup:
263     AcpiPsDeleteParseTree (Op);
264     return_ACPI_STATUS (Status);
265 }
266
267
268 /*******************************************************************************
269  *
270  * FUNCTION:    AcpiDsGetBufferFieldArguments
271  *
272  * PARAMETERS:  ObjDesc         - A valid BufferField object
273  *
274  * RETURN:      Status.
275  *
276  * DESCRIPTION: Get BufferField Buffer and Index.  This implements the late
277  *              evaluation of these field attributes.
278  *
279  ******************************************************************************/
280
281 ACPI_STATUS
282 AcpiDsGetBufferFieldArguments (
283     ACPI_OPERAND_OBJECT     *ObjDesc)
284 {
285     ACPI_OPERAND_OBJECT     *ExtraDesc;
286     ACPI_NAMESPACE_NODE     *Node;
287     ACPI_STATUS             Status;
288
289
290     ACPI_FUNCTION_TRACE_PTR (DsGetBufferFieldArguments, ObjDesc);
291
292
293     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
294     {
295         return_ACPI_STATUS (AE_OK);
296     }
297
298     /* Get the AML pointer (method object) and BufferField node */
299
300     ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
301     Node = ObjDesc->BufferField.Node;
302
303     ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_BUFFER_FIELD, Node, NULL));
304     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
305         AcpiUtGetNodeName (Node)));
306
307     /* Execute the AML code for the TermArg arguments */
308
309     Status = AcpiDsExecuteArguments (Node, AcpiNsGetParentNode (Node),
310                 ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
311     return_ACPI_STATUS (Status);
312 }
313
314
315 /*******************************************************************************
316  *
317  * FUNCTION:    AcpiDsGetBufferArguments
318  *
319  * PARAMETERS:  ObjDesc         - A valid Buffer object
320  *
321  * RETURN:      Status.
322  *
323  * DESCRIPTION: Get Buffer length and initializer byte list.  This implements
324  *              the late evaluation of these attributes.
325  *
326  ******************************************************************************/
327
328 ACPI_STATUS
329 AcpiDsGetBufferArguments (
330     ACPI_OPERAND_OBJECT     *ObjDesc)
331 {
332     ACPI_NAMESPACE_NODE     *Node;
333     ACPI_STATUS             Status;
334
335
336     ACPI_FUNCTION_TRACE_PTR (DsGetBufferArguments, ObjDesc);
337
338
339     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
340     {
341         return_ACPI_STATUS (AE_OK);
342     }
343
344     /* Get the Buffer node */
345
346     Node = ObjDesc->Buffer.Node;
347     if (!Node)
348     {
349         ACPI_ERROR ((AE_INFO,
350             "No pointer back to NS node in buffer obj %p", ObjDesc));
351         return_ACPI_STATUS (AE_AML_INTERNAL);
352     }
353
354     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
355
356     /* Execute the AML code for the TermArg arguments */
357
358     Status = AcpiDsExecuteArguments (Node, Node,
359                 ObjDesc->Buffer.AmlLength, ObjDesc->Buffer.AmlStart);
360     return_ACPI_STATUS (Status);
361 }
362
363
364 /*******************************************************************************
365  *
366  * FUNCTION:    AcpiDsGetPackageArguments
367  *
368  * PARAMETERS:  ObjDesc         - A valid Package object
369  *
370  * RETURN:      Status.
371  *
372  * DESCRIPTION: Get Package length and initializer byte list.  This implements
373  *              the late evaluation of these attributes.
374  *
375  ******************************************************************************/
376
377 ACPI_STATUS
378 AcpiDsGetPackageArguments (
379     ACPI_OPERAND_OBJECT     *ObjDesc)
380 {
381     ACPI_NAMESPACE_NODE     *Node;
382     ACPI_STATUS             Status;
383
384
385     ACPI_FUNCTION_TRACE_PTR (DsGetPackageArguments, ObjDesc);
386
387
388     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
389     {
390         return_ACPI_STATUS (AE_OK);
391     }
392
393     /* Get the Package node */
394
395     Node = ObjDesc->Package.Node;
396     if (!Node)
397     {
398         ACPI_ERROR ((AE_INFO,
399             "No pointer back to NS node in package %p", ObjDesc));
400         return_ACPI_STATUS (AE_AML_INTERNAL);
401     }
402
403     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n"));
404
405     /* Execute the AML code for the TermArg arguments */
406
407     Status = AcpiDsExecuteArguments (Node, Node,
408                 ObjDesc->Package.AmlLength, ObjDesc->Package.AmlStart);
409     return_ACPI_STATUS (Status);
410 }
411
412
413 /*****************************************************************************
414  *
415  * FUNCTION:    AcpiDsGetRegionArguments
416  *
417  * PARAMETERS:  ObjDesc         - A valid region object
418  *
419  * RETURN:      Status.
420  *
421  * DESCRIPTION: Get region address and length.  This implements the late
422  *              evaluation of these region attributes.
423  *
424  ****************************************************************************/
425
426 ACPI_STATUS
427 AcpiDsGetRegionArguments (
428     ACPI_OPERAND_OBJECT     *ObjDesc)
429 {
430     ACPI_NAMESPACE_NODE     *Node;
431     ACPI_STATUS             Status;
432     ACPI_OPERAND_OBJECT     *ExtraDesc;
433
434
435     ACPI_FUNCTION_TRACE_PTR (DsGetRegionArguments, ObjDesc);
436
437
438     if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
439     {
440         return_ACPI_STATUS (AE_OK);
441     }
442
443     ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
444     if (!ExtraDesc)
445     {
446         return_ACPI_STATUS (AE_NOT_EXIST);
447     }
448
449     /* Get the Region node */
450
451     Node = ObjDesc->Region.Node;
452
453     ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_REGION, Node, NULL));
454
455     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
456         AcpiUtGetNodeName (Node), ExtraDesc->Extra.AmlStart));
457
458     /* Execute the argument AML */
459
460     Status = AcpiDsExecuteArguments (Node, AcpiNsGetParentNode (Node),
461                 ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
462     if (ACPI_FAILURE (Status))
463     {
464         return_ACPI_STATUS (Status);
465     }
466
467     /* Validate the region address/length via the host OS */
468
469     Status = AcpiOsValidateAddress (ObjDesc->Region.SpaceId,
470                 ObjDesc->Region.Address, (ACPI_SIZE) ObjDesc->Region.Length);
471     if (ACPI_FAILURE (Status))
472     {
473         /*
474          * Invalid address/length. We will emit an error message and mark
475          * the region as invalid, so that it will cause an additional error if
476          * it is ever used. Then return AE_OK.
477          */
478         ACPI_EXCEPTION ((AE_INFO, Status,
479             "During address validation of OpRegion [%4.4s]", Node->Name.Ascii));
480         ObjDesc->Common.Flags |= AOPOBJ_INVALID;
481         Status = AE_OK;
482     }
483
484     return_ACPI_STATUS (Status);
485 }
486
487
488 /*******************************************************************************
489  *
490  * FUNCTION:    AcpiDsInitializeRegion
491  *
492  * PARAMETERS:  ObjHandle       - Region namespace node
493  *
494  * RETURN:      Status
495  *
496  * DESCRIPTION: Front end to EvInitializeRegion
497  *
498  ******************************************************************************/
499
500 ACPI_STATUS
501 AcpiDsInitializeRegion (
502     ACPI_HANDLE             ObjHandle)
503 {
504     ACPI_OPERAND_OBJECT     *ObjDesc;
505     ACPI_STATUS             Status;
506
507
508     ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
509
510     /* Namespace is NOT locked */
511
512     Status = AcpiEvInitializeRegion (ObjDesc, FALSE);
513     return (Status);
514 }
515
516
517 /*******************************************************************************
518  *
519  * FUNCTION:    AcpiDsInitBufferField
520  *
521  * PARAMETERS:  AmlOpcode       - CreateXxxField
522  *              ObjDesc         - BufferField object
523  *              BufferDesc      - Host Buffer
524  *              OffsetDesc      - Offset into buffer
525  *              LengthDesc      - Length of field (CREATE_FIELD_OP only)
526  *              ResultDesc      - Where to store the result
527  *
528  * RETURN:      Status
529  *
530  * DESCRIPTION: Perform actual initialization of a buffer field
531  *
532  ******************************************************************************/
533
534 static ACPI_STATUS
535 AcpiDsInitBufferField (
536     UINT16                  AmlOpcode,
537     ACPI_OPERAND_OBJECT     *ObjDesc,
538     ACPI_OPERAND_OBJECT     *BufferDesc,
539     ACPI_OPERAND_OBJECT     *OffsetDesc,
540     ACPI_OPERAND_OBJECT     *LengthDesc,
541     ACPI_OPERAND_OBJECT     *ResultDesc)
542 {
543     UINT32                  Offset;
544     UINT32                  BitOffset;
545     UINT32                  BitCount;
546     UINT8                   FieldFlags;
547     ACPI_STATUS             Status;
548
549
550     ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc);
551
552
553     /* Host object must be a Buffer */
554
555     if (ACPI_GET_OBJECT_TYPE (BufferDesc) != ACPI_TYPE_BUFFER)
556     {
557         ACPI_ERROR ((AE_INFO,
558             "Target of Create Field is not a Buffer object - %s",
559             AcpiUtGetObjectTypeName (BufferDesc)));
560
561         Status = AE_AML_OPERAND_TYPE;
562         goto Cleanup;
563     }
564
565     /*
566      * The last parameter to all of these opcodes (ResultDesc) started
567      * out as a NameString, and should therefore now be a NS node
568      * after resolution in AcpiExResolveOperands().
569      */
570     if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
571     {
572         ACPI_ERROR ((AE_INFO,
573             "(%s) destination not a NS Node [%s]",
574             AcpiPsGetOpcodeName (AmlOpcode),
575             AcpiUtGetDescriptorName (ResultDesc)));
576
577         Status = AE_AML_OPERAND_TYPE;
578         goto Cleanup;
579     }
580
581     Offset = (UINT32) OffsetDesc->Integer.Value;
582
583     /*
584      * Setup the Bit offsets and counts, according to the opcode
585      */
586     switch (AmlOpcode)
587     {
588     case AML_CREATE_FIELD_OP:
589
590         /* Offset is in bits, count is in bits */
591
592         FieldFlags = AML_FIELD_ACCESS_BYTE;
593         BitOffset  = Offset;
594         BitCount   = (UINT32) LengthDesc->Integer.Value;
595
596         /* Must have a valid (>0) bit count */
597
598         if (BitCount == 0)
599         {
600             ACPI_ERROR ((AE_INFO,
601                 "Attempt to CreateField of length zero"));
602             Status = AE_AML_OPERAND_VALUE;
603             goto Cleanup;
604         }
605         break;
606
607     case AML_CREATE_BIT_FIELD_OP:
608
609         /* Offset is in bits, Field is one bit */
610
611         BitOffset  = Offset;
612         BitCount   = 1;
613         FieldFlags = AML_FIELD_ACCESS_BYTE;
614         break;
615
616     case AML_CREATE_BYTE_FIELD_OP:
617
618         /* Offset is in bytes, field is one byte */
619
620         BitOffset  = 8 * Offset;
621         BitCount   = 8;
622         FieldFlags = AML_FIELD_ACCESS_BYTE;
623         break;
624
625     case AML_CREATE_WORD_FIELD_OP:
626
627         /* Offset is in bytes, field is one word */
628
629         BitOffset  = 8 * Offset;
630         BitCount   = 16;
631         FieldFlags = AML_FIELD_ACCESS_WORD;
632         break;
633
634     case AML_CREATE_DWORD_FIELD_OP:
635
636         /* Offset is in bytes, field is one dword */
637
638         BitOffset  = 8 * Offset;
639         BitCount   = 32;
640         FieldFlags = AML_FIELD_ACCESS_DWORD;
641         break;
642
643     case AML_CREATE_QWORD_FIELD_OP:
644
645         /* Offset is in bytes, field is one qword */
646
647         BitOffset  = 8 * Offset;
648         BitCount   = 64;
649         FieldFlags = AML_FIELD_ACCESS_QWORD;
650         break;
651
652     default:
653
654         ACPI_ERROR ((AE_INFO,
655             "Unknown field creation opcode %02x",
656             AmlOpcode));
657         Status = AE_AML_BAD_OPCODE;
658         goto Cleanup;
659     }
660
661     /* Entire field must fit within the current length of the buffer */
662
663     if ((BitOffset + BitCount) >
664         (8 * (UINT32) BufferDesc->Buffer.Length))
665     {
666         ACPI_ERROR ((AE_INFO,
667             "Field [%4.4s] at %d exceeds Buffer [%4.4s] size %d (bits)",
668             AcpiUtGetNodeName (ResultDesc),
669             BitOffset + BitCount,
670             AcpiUtGetNodeName (BufferDesc->Buffer.Node),
671             8 * (UINT32) BufferDesc->Buffer.Length));
672         Status = AE_AML_BUFFER_LIMIT;
673         goto Cleanup;
674     }
675
676     /*
677      * Initialize areas of the field object that are common to all fields
678      * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
679      * UPDATE_RULE = 0 (UPDATE_PRESERVE)
680      */
681     Status = AcpiExPrepCommonFieldObject (ObjDesc, FieldFlags, 0,
682                                             BitOffset, BitCount);
683     if (ACPI_FAILURE (Status))
684     {
685         goto Cleanup;
686     }
687
688     ObjDesc->BufferField.BufferObj = BufferDesc;
689
690     /* Reference count for BufferDesc inherits ObjDesc count */
691
692     BufferDesc->Common.ReferenceCount = (UINT16)
693         (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);
694
695
696 Cleanup:
697
698     /* Always delete the operands */
699
700     AcpiUtRemoveReference (OffsetDesc);
701     AcpiUtRemoveReference (BufferDesc);
702
703     if (AmlOpcode == AML_CREATE_FIELD_OP)
704     {
705         AcpiUtRemoveReference (LengthDesc);
706     }
707
708     /* On failure, delete the result descriptor */
709
710     if (ACPI_FAILURE (Status))
711     {
712         AcpiUtRemoveReference (ResultDesc);     /* Result descriptor */
713     }
714     else
715     {
716         /* Now the address and length are valid for this BufferField */
717
718         ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
719     }
720
721     return_ACPI_STATUS (Status);
722 }
723
724
725 /*******************************************************************************
726  *
727  * FUNCTION:    AcpiDsEvalBufferFieldOperands
728  *
729  * PARAMETERS:  WalkState       - Current walk
730  *              Op              - A valid BufferField Op object
731  *
732  * RETURN:      Status
733  *
734  * DESCRIPTION: Get BufferField Buffer and Index
735  *              Called from AcpiDsExecEndOp during BufferField parse tree walk
736  *
737  ******************************************************************************/
738
739 ACPI_STATUS
740 AcpiDsEvalBufferFieldOperands (
741     ACPI_WALK_STATE         *WalkState,
742     ACPI_PARSE_OBJECT       *Op)
743 {
744     ACPI_STATUS             Status;
745     ACPI_OPERAND_OBJECT     *ObjDesc;
746     ACPI_NAMESPACE_NODE     *Node;
747     ACPI_PARSE_OBJECT       *NextOp;
748
749
750     ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op);
751
752
753     /*
754      * This is where we evaluate the address and length fields of the
755      * CreateXxxField declaration
756      */
757     Node =  Op->Common.Node;
758
759     /* NextOp points to the op that holds the Buffer */
760
761     NextOp = Op->Common.Value.Arg;
762
763     /* Evaluate/create the address and length operands */
764
765     Status = AcpiDsCreateOperands (WalkState, NextOp);
766     if (ACPI_FAILURE (Status))
767     {
768         return_ACPI_STATUS (Status);
769     }
770
771     ObjDesc = AcpiNsGetAttachedObject (Node);
772     if (!ObjDesc)
773     {
774         return_ACPI_STATUS (AE_NOT_EXIST);
775     }
776
777     /* Resolve the operands */
778
779     Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
780                     ACPI_WALK_OPERANDS, WalkState);
781
782     ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
783                     AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
784                     WalkState->NumOperands, "after AcpiExResolveOperands");
785
786     if (ACPI_FAILURE (Status))
787     {
788         ACPI_ERROR ((AE_INFO, "(%s) bad operand(s) (%X)",
789             AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
790
791         return_ACPI_STATUS (Status);
792     }
793
794     /* Initialize the Buffer Field */
795
796     if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
797     {
798         /* NOTE: Slightly different operands for this opcode */
799
800         Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
801                     WalkState->Operands[0], WalkState->Operands[1],
802                     WalkState->Operands[2], WalkState->Operands[3]);
803     }
804     else
805     {
806         /* All other, CreateXxxField opcodes */
807
808         Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
809                     WalkState->Operands[0], WalkState->Operands[1],
810                                       NULL, WalkState->Operands[2]);
811     }
812
813     return_ACPI_STATUS (Status);
814 }
815
816
817 /*******************************************************************************
818  *
819  * FUNCTION:    AcpiDsEvalRegionOperands
820  *
821  * PARAMETERS:  WalkState       - Current walk
822  *              Op              - A valid region Op object
823  *
824  * RETURN:      Status
825  *
826  * DESCRIPTION: Get region address and length
827  *              Called from AcpiDsExecEndOp during OpRegion parse tree walk
828  *
829  ******************************************************************************/
830
831 ACPI_STATUS
832 AcpiDsEvalRegionOperands (
833     ACPI_WALK_STATE         *WalkState,
834     ACPI_PARSE_OBJECT       *Op)
835 {
836     ACPI_STATUS             Status;
837     ACPI_OPERAND_OBJECT     *ObjDesc;
838     ACPI_OPERAND_OBJECT     *OperandDesc;
839     ACPI_NAMESPACE_NODE     *Node;
840     ACPI_PARSE_OBJECT       *NextOp;
841
842
843     ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op);
844
845
846     /*
847      * This is where we evaluate the address and length fields of the
848      * OpRegion declaration
849      */
850     Node =  Op->Common.Node;
851
852     /* NextOp points to the op that holds the SpaceID */
853
854     NextOp = Op->Common.Value.Arg;
855
856     /* NextOp points to address op */
857
858     NextOp = NextOp->Common.Next;
859
860     /* Evaluate/create the address and length operands */
861
862     Status = AcpiDsCreateOperands (WalkState, NextOp);
863     if (ACPI_FAILURE (Status))
864     {
865         return_ACPI_STATUS (Status);
866     }
867
868     /* Resolve the length and address operands to numbers */
869
870     Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
871                 ACPI_WALK_OPERANDS, WalkState);
872     if (ACPI_FAILURE (Status))
873     {
874         return_ACPI_STATUS (Status);
875     }
876
877     ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
878                     AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
879                     1, "after AcpiExResolveOperands");
880
881     ObjDesc = AcpiNsGetAttachedObject (Node);
882     if (!ObjDesc)
883     {
884         return_ACPI_STATUS (AE_NOT_EXIST);
885     }
886
887     /*
888      * Get the length operand and save it
889      * (at Top of stack)
890      */
891     OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
892
893     ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
894     AcpiUtRemoveReference (OperandDesc);
895
896     /*
897      * Get the address and save it
898      * (at top of stack - 1)
899      */
900     OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
901
902     ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS)
903                                 OperandDesc->Integer.Value;
904     AcpiUtRemoveReference (OperandDesc);
905
906     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
907         ObjDesc,
908         ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
909         ObjDesc->Region.Length));
910
911     /* Now the address and length are valid for this opregion */
912
913     ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
914
915     return_ACPI_STATUS (Status);
916 }
917
918
919 /*******************************************************************************
920  *
921  * FUNCTION:    AcpiDsEvalDataObjectOperands
922  *
923  * PARAMETERS:  WalkState       - Current walk
924  *              Op              - A valid DataObject Op object
925  *              ObjDesc         - DataObject
926  *
927  * RETURN:      Status
928  *
929  * DESCRIPTION: Get the operands and complete the following data object types:
930  *              Buffer, Package.
931  *
932  ******************************************************************************/
933
934 ACPI_STATUS
935 AcpiDsEvalDataObjectOperands (
936     ACPI_WALK_STATE         *WalkState,
937     ACPI_PARSE_OBJECT       *Op,
938     ACPI_OPERAND_OBJECT     *ObjDesc)
939 {
940     ACPI_STATUS             Status;
941     ACPI_OPERAND_OBJECT     *ArgDesc;
942     UINT32                  Length;
943
944
945     ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands);
946
947
948     /* The first operand (for all of these data objects) is the length */
949
950     Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
951     if (ACPI_FAILURE (Status))
952     {
953         return_ACPI_STATUS (Status);
954     }
955
956     Status = AcpiExResolveOperands (WalkState->Opcode,
957                     &(WalkState->Operands [WalkState->NumOperands -1]),
958                     WalkState);
959     if (ACPI_FAILURE (Status))
960     {
961         return_ACPI_STATUS (Status);
962     }
963
964     /* Extract length operand */
965
966     ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
967     Length = (UINT32) ArgDesc->Integer.Value;
968
969     /* Cleanup for length operand */
970
971     Status = AcpiDsObjStackPop (1, WalkState);
972     if (ACPI_FAILURE (Status))
973     {
974         return_ACPI_STATUS (Status);
975     }
976
977     AcpiUtRemoveReference (ArgDesc);
978
979     /*
980      * Create the actual data object
981      */
982     switch (Op->Common.AmlOpcode)
983     {
984     case AML_BUFFER_OP:
985
986         Status = AcpiDsBuildInternalBufferObj (WalkState, Op, Length, &ObjDesc);
987         break;
988
989     case AML_PACKAGE_OP:
990     case AML_VAR_PACKAGE_OP:
991
992         Status = AcpiDsBuildInternalPackageObj (WalkState, Op, Length, &ObjDesc);
993         break;
994
995     default:
996         return_ACPI_STATUS (AE_AML_BAD_OPCODE);
997     }
998
999     if (ACPI_SUCCESS (Status))
1000     {
1001         /*
1002          * Return the object in the WalkState, unless the parent is a package -
1003          * in this case, the return object will be stored in the parse tree
1004          * for the package.
1005          */
1006         if ((!Op->Common.Parent) ||
1007             ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
1008              (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) &&
1009              (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
1010         {
1011             WalkState->ResultObj = ObjDesc;
1012         }
1013     }
1014
1015     return_ACPI_STATUS (Status);
1016 }
1017
1018
1019 /*******************************************************************************
1020  *
1021  * FUNCTION:    AcpiDsExecBeginControlOp
1022  *
1023  * PARAMETERS:  WalkList        - The list that owns the walk stack
1024  *              Op              - The control Op
1025  *
1026  * RETURN:      Status
1027  *
1028  * DESCRIPTION: Handles all control ops encountered during control method
1029  *              execution.
1030  *
1031  ******************************************************************************/
1032
1033 ACPI_STATUS
1034 AcpiDsExecBeginControlOp (
1035     ACPI_WALK_STATE         *WalkState,
1036     ACPI_PARSE_OBJECT       *Op)
1037 {
1038     ACPI_STATUS             Status = AE_OK;
1039     ACPI_GENERIC_STATE      *ControlState;
1040
1041
1042     ACPI_FUNCTION_NAME (DsExecBeginControlOp);
1043
1044
1045     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", Op,
1046         Op->Common.AmlOpcode, WalkState));
1047
1048     switch (Op->Common.AmlOpcode)
1049     {
1050     case AML_IF_OP:
1051     case AML_WHILE_OP:
1052
1053         /*
1054          * IF/WHILE: Create a new control state to manage these
1055          * constructs. We need to manage these as a stack, in order
1056          * to handle nesting.
1057          */
1058         ControlState = AcpiUtCreateControlState ();
1059         if (!ControlState)
1060         {
1061             Status = AE_NO_MEMORY;
1062             break;
1063         }
1064         /*
1065          * Save a pointer to the predicate for multiple executions
1066          * of a loop
1067          */
1068         ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1;
1069         ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd;
1070         ControlState->Control.Opcode = Op->Common.AmlOpcode;
1071
1072
1073         /* Push the control state on this walk's control stack */
1074
1075         AcpiUtPushGenericState (&WalkState->ControlState, ControlState);
1076         break;
1077
1078     case AML_ELSE_OP:
1079
1080         /* Predicate is in the state object */
1081         /* If predicate is true, the IF was executed, ignore ELSE part */
1082
1083         if (WalkState->LastPredicate)
1084         {
1085             Status = AE_CTRL_TRUE;
1086         }
1087
1088         break;
1089
1090     case AML_RETURN_OP:
1091
1092         break;
1093
1094     default:
1095         break;
1096     }
1097
1098     return (Status);
1099 }
1100
1101
1102 /*******************************************************************************
1103  *
1104  * FUNCTION:    AcpiDsExecEndControlOp
1105  *
1106  * PARAMETERS:  WalkList        - The list that owns the walk stack
1107  *              Op              - The control Op
1108  *
1109  * RETURN:      Status
1110  *
1111  * DESCRIPTION: Handles all control ops encountered during control method
1112  *              execution.
1113  *
1114  ******************************************************************************/
1115
1116 ACPI_STATUS
1117 AcpiDsExecEndControlOp (
1118     ACPI_WALK_STATE         *WalkState,
1119     ACPI_PARSE_OBJECT       *Op)
1120 {
1121     ACPI_STATUS             Status = AE_OK;
1122     ACPI_GENERIC_STATE      *ControlState;
1123
1124
1125     ACPI_FUNCTION_NAME (DsExecEndControlOp);
1126
1127
1128     switch (Op->Common.AmlOpcode)
1129     {
1130     case AML_IF_OP:
1131
1132         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op));
1133
1134         /*
1135          * Save the result of the predicate in case there is an
1136          * ELSE to come
1137          */
1138         WalkState->LastPredicate =
1139             (BOOLEAN) WalkState->ControlState->Common.Value;
1140
1141         /*
1142          * Pop the control state that was created at the start
1143          * of the IF and free it
1144          */
1145         ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
1146         AcpiUtDeleteGenericState (ControlState);
1147         break;
1148
1149
1150     case AML_ELSE_OP:
1151
1152         break;
1153
1154
1155     case AML_WHILE_OP:
1156
1157         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op));
1158
1159         if (WalkState->ControlState->Common.Value)
1160         {
1161             /* Predicate was true, go back and evaluate it again! */
1162
1163             Status = AE_CTRL_PENDING;
1164         }
1165
1166         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1167             "[WHILE_OP] termination! Op=%p\n",Op));
1168
1169         /* Pop this control state and free it */
1170
1171         ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
1172
1173         WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart;
1174         AcpiUtDeleteGenericState (ControlState);
1175         break;
1176
1177
1178     case AML_RETURN_OP:
1179
1180         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1181             "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg));
1182
1183         /*
1184          * One optional operand -- the return value
1185          * It can be either an immediate operand or a result that
1186          * has been bubbled up the tree
1187          */
1188         if (Op->Common.Value.Arg)
1189         {
1190             /* Since we have a real Return(), delete any implicit return */
1191
1192             AcpiDsClearImplicitReturn (WalkState);
1193
1194             /* Return statement has an immediate operand */
1195
1196             Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
1197             if (ACPI_FAILURE (Status))
1198             {
1199                 return (Status);
1200             }
1201
1202             /*
1203              * If value being returned is a Reference (such as
1204              * an arg or local), resolve it now because it may
1205              * cease to exist at the end of the method.
1206              */
1207             Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
1208             if (ACPI_FAILURE (Status))
1209             {
1210                 return (Status);
1211             }
1212
1213             /*
1214              * Get the return value and save as the last result
1215              * value.  This is the only place where WalkState->ReturnDesc
1216              * is set to anything other than zero!
1217              */
1218             WalkState->ReturnDesc = WalkState->Operands[0];
1219         }
1220         else if ((WalkState->Results) &&
1221                  (WalkState->Results->Results.NumResults > 0))
1222         {
1223             /* Since we have a real Return(), delete any implicit return */
1224
1225             AcpiDsClearImplicitReturn (WalkState);
1226
1227             /*
1228              * The return value has come from a previous calculation.
1229              *
1230              * If value being returned is a Reference (such as
1231              * an arg or local), resolve it now because it may
1232              * cease to exist at the end of the method.
1233              *
1234              * Allow references created by the Index operator to return unchanged.
1235              */
1236             if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == ACPI_DESC_TYPE_OPERAND) &&
1237                 (ACPI_GET_OBJECT_TYPE (WalkState->Results->Results.ObjDesc [0]) == ACPI_TYPE_LOCAL_REFERENCE) &&
1238                 ((WalkState->Results->Results.ObjDesc [0])->Reference.Opcode != AML_INDEX_OP))
1239             {
1240                 Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState);
1241                 if (ACPI_FAILURE (Status))
1242                 {
1243                     return (Status);
1244                 }
1245             }
1246
1247             WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0];
1248         }
1249         else
1250         {
1251             /* No return operand */
1252
1253             if (WalkState->NumOperands)
1254             {
1255                 AcpiUtRemoveReference (WalkState->Operands [0]);
1256             }
1257
1258             WalkState->Operands [0]     = NULL;
1259             WalkState->NumOperands      = 0;
1260             WalkState->ReturnDesc       = NULL;
1261         }
1262
1263
1264         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1265             "Completed RETURN_OP State=%p, RetVal=%p\n",
1266             WalkState, WalkState->ReturnDesc));
1267
1268         /* End the control method execution right now */
1269
1270         Status = AE_CTRL_TERMINATE;
1271         break;
1272
1273
1274     case AML_NOOP_OP:
1275
1276         /* Just do nothing! */
1277         break;
1278
1279
1280     case AML_BREAK_POINT_OP:
1281
1282         /* Call up to the OS service layer to handle this */
1283
1284         Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT, "Executed AML Breakpoint opcode");
1285
1286         /* If and when it returns, all done. */
1287
1288         break;
1289
1290
1291     case AML_BREAK_OP:
1292     case AML_CONTINUE_OP: /* ACPI 2.0 */
1293
1294
1295         /* Pop and delete control states until we find a while */
1296
1297         while (WalkState->ControlState &&
1298                 (WalkState->ControlState->Control.Opcode != AML_WHILE_OP))
1299         {
1300             ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
1301             AcpiUtDeleteGenericState (ControlState);
1302         }
1303
1304         /* No while found? */
1305
1306         if (!WalkState->ControlState)
1307         {
1308             return (AE_AML_NO_WHILE);
1309         }
1310
1311         /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */
1312
1313         WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd;
1314
1315         /* Return status depending on opcode */
1316
1317         if (Op->Common.AmlOpcode == AML_BREAK_OP)
1318         {
1319             Status = AE_CTRL_BREAK;
1320         }
1321         else
1322         {
1323             Status = AE_CTRL_CONTINUE;
1324         }
1325         break;
1326
1327
1328     default:
1329
1330         ACPI_ERROR ((AE_INFO, "Unknown control opcode=%X Op=%p",
1331             Op->Common.AmlOpcode, Op));
1332
1333         Status = AE_AML_BAD_OPCODE;
1334         break;
1335     }
1336
1337     return (Status);
1338 }
1339