]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/dsopcode.c
This commit was generated by cvs2svn to compensate for changes in r162911,
[FreeBSD/FreeBSD.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: 1.103 $
6  *
7  *****************************************************************************/
8
9 /******************************************************************************
10  *
11  * 1. Copyright Notice
12  *
13  * Some or all of this work - Copyright (c) 1999 - 2005, 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 <contrib/dev/acpica/acpi.h>
121 #include <contrib/dev/acpica/acparser.h>
122 #include <contrib/dev/acpica/amlcode.h>
123 #include <contrib/dev/acpica/acdispat.h>
124 #include <contrib/dev/acpica/acinterp.h>
125 #include <contrib/dev/acpica/acnamesp.h>
126 #include <contrib/dev/acpica/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, 1);
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, 3);
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_REPORT_ERROR ((
350                 "No pointer back to NS node in buffer obj %p\n", 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_REPORT_ERROR ((
399                 "No pointer back to NS node in package %p\n", 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     return_ACPI_STATUS (Status);
463 }
464
465
466 /*******************************************************************************
467  *
468  * FUNCTION:    AcpiDsInitializeRegion
469  *
470  * PARAMETERS:  ObjHandle       - Region namespace node
471  *
472  * RETURN:      Status
473  *
474  * DESCRIPTION: Front end to EvInitializeRegion
475  *
476  ******************************************************************************/
477
478 ACPI_STATUS
479 AcpiDsInitializeRegion (
480     ACPI_HANDLE             ObjHandle)
481 {
482     ACPI_OPERAND_OBJECT     *ObjDesc;
483     ACPI_STATUS             Status;
484
485
486     ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
487
488     /* Namespace is NOT locked */
489
490     Status = AcpiEvInitializeRegion (ObjDesc, FALSE);
491     return (Status);
492 }
493
494
495 /*******************************************************************************
496  *
497  * FUNCTION:    AcpiDsInitBufferField
498  *
499  * PARAMETERS:  AmlOpcode       - CreateXxxField
500  *              ObjDesc         - BufferField object
501  *              BufferDesc      - Host Buffer
502  *              OffsetDesc      - Offset into buffer
503  *              LengthDesc      - Length of field (CREATE_FIELD_OP only)
504  *              ResultDesc      - Where to store the result
505  *
506  * RETURN:      Status
507  *
508  * DESCRIPTION: Perform actual initialization of a buffer field
509  *
510  ******************************************************************************/
511
512 static ACPI_STATUS
513 AcpiDsInitBufferField (
514     UINT16                  AmlOpcode,
515     ACPI_OPERAND_OBJECT     *ObjDesc,
516     ACPI_OPERAND_OBJECT     *BufferDesc,
517     ACPI_OPERAND_OBJECT     *OffsetDesc,
518     ACPI_OPERAND_OBJECT     *LengthDesc,
519     ACPI_OPERAND_OBJECT     *ResultDesc)
520 {
521     UINT32                  Offset;
522     UINT32                  BitOffset;
523     UINT32                  BitCount;
524     UINT8                   FieldFlags;
525     ACPI_STATUS             Status;
526
527
528     ACPI_FUNCTION_TRACE_PTR ("DsInitBufferField", ObjDesc);
529
530
531     /* Host object must be a Buffer */
532
533     if (ACPI_GET_OBJECT_TYPE (BufferDesc) != ACPI_TYPE_BUFFER)
534     {
535         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
536             "Target of Create Field is not a Buffer object - %s\n",
537             AcpiUtGetObjectTypeName (BufferDesc)));
538
539         Status = AE_AML_OPERAND_TYPE;
540         goto Cleanup;
541     }
542
543     /*
544      * The last parameter to all of these opcodes (ResultDesc) started
545      * out as a NameString, and should therefore now be a NS node
546      * after resolution in AcpiExResolveOperands().
547      */
548     if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
549     {
550         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
551                 "(%s) destination not a NS Node [%s]\n",
552                 AcpiPsGetOpcodeName (AmlOpcode),
553                 AcpiUtGetDescriptorName (ResultDesc)));
554
555         Status = AE_AML_OPERAND_TYPE;
556         goto Cleanup;
557     }
558
559     Offset = (UINT32) OffsetDesc->Integer.Value;
560
561     /*
562      * Setup the Bit offsets and counts, according to the opcode
563      */
564     switch (AmlOpcode)
565     {
566     case AML_CREATE_FIELD_OP:
567
568         /* Offset is in bits, count is in bits */
569
570         FieldFlags = AML_FIELD_ACCESS_BYTE;
571         BitOffset  = Offset;
572         BitCount   = (UINT32) LengthDesc->Integer.Value;
573
574         /* Must have a valid (>0) bit count */
575
576         if (BitCount == 0)
577         {
578             ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
579                 "Attempt to CreateField of length 0\n"));
580             Status = AE_AML_OPERAND_VALUE;
581             goto Cleanup;
582         }
583         break;
584
585     case AML_CREATE_BIT_FIELD_OP:
586
587         /* Offset is in bits, Field is one bit */
588
589         BitOffset  = Offset;
590         BitCount   = 1;
591         FieldFlags = AML_FIELD_ACCESS_BYTE;
592         break;
593
594     case AML_CREATE_BYTE_FIELD_OP:
595
596         /* Offset is in bytes, field is one byte */
597
598         BitOffset  = 8 * Offset;
599         BitCount   = 8;
600         FieldFlags = AML_FIELD_ACCESS_BYTE;
601         break;
602
603     case AML_CREATE_WORD_FIELD_OP:
604
605         /* Offset is in bytes, field is one word */
606
607         BitOffset  = 8 * Offset;
608         BitCount   = 16;
609         FieldFlags = AML_FIELD_ACCESS_WORD;
610         break;
611
612     case AML_CREATE_DWORD_FIELD_OP:
613
614         /* Offset is in bytes, field is one dword */
615
616         BitOffset  = 8 * Offset;
617         BitCount   = 32;
618         FieldFlags = AML_FIELD_ACCESS_DWORD;
619         break;
620
621     case AML_CREATE_QWORD_FIELD_OP:
622
623         /* Offset is in bytes, field is one qword */
624
625         BitOffset  = 8 * Offset;
626         BitCount   = 64;
627         FieldFlags = AML_FIELD_ACCESS_QWORD;
628         break;
629
630     default:
631
632         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
633             "Unknown field creation opcode %02x\n",
634             AmlOpcode));
635         Status = AE_AML_BAD_OPCODE;
636         goto Cleanup;
637     }
638
639     /* Entire field must fit within the current length of the buffer */
640
641     if ((BitOffset + BitCount) >
642         (8 * (UINT32) BufferDesc->Buffer.Length))
643     {
644         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
645             "Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n",
646              AcpiUtGetNodeName (ResultDesc),
647              BitOffset + BitCount,
648              AcpiUtGetNodeName (BufferDesc->Buffer.Node),
649              8 * (UINT32) BufferDesc->Buffer.Length));
650         Status = AE_AML_BUFFER_LIMIT;
651         goto Cleanup;
652     }
653
654     /*
655      * Initialize areas of the field object that are common to all fields
656      * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
657      * UPDATE_RULE = 0 (UPDATE_PRESERVE)
658      */
659     Status = AcpiExPrepCommonFieldObject (ObjDesc, FieldFlags, 0,
660                                             BitOffset, BitCount);
661     if (ACPI_FAILURE (Status))
662     {
663         goto Cleanup;
664     }
665
666     ObjDesc->BufferField.BufferObj = BufferDesc;
667
668     /* Reference count for BufferDesc inherits ObjDesc count */
669
670     BufferDesc->Common.ReferenceCount = (UINT16)
671         (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);
672
673
674 Cleanup:
675
676     /* Always delete the operands */
677
678     AcpiUtRemoveReference (OffsetDesc);
679     AcpiUtRemoveReference (BufferDesc);
680
681     if (AmlOpcode == AML_CREATE_FIELD_OP)
682     {
683         AcpiUtRemoveReference (LengthDesc);
684     }
685
686     /* On failure, delete the result descriptor */
687
688     if (ACPI_FAILURE (Status))
689     {
690         AcpiUtRemoveReference (ResultDesc);     /* Result descriptor */
691     }
692     else
693     {
694         /* Now the address and length are valid for this BufferField */
695
696         ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
697     }
698
699     return_ACPI_STATUS (Status);
700 }
701
702
703 /*******************************************************************************
704  *
705  * FUNCTION:    AcpiDsEvalBufferFieldOperands
706  *
707  * PARAMETERS:  WalkState       - Current walk
708  *              Op              - A valid BufferField Op object
709  *
710  * RETURN:      Status
711  *
712  * DESCRIPTION: Get BufferField Buffer and Index
713  *              Called from AcpiDsExecEndOp during BufferField parse tree walk
714  *
715  ******************************************************************************/
716
717 ACPI_STATUS
718 AcpiDsEvalBufferFieldOperands (
719     ACPI_WALK_STATE         *WalkState,
720     ACPI_PARSE_OBJECT       *Op)
721 {
722     ACPI_STATUS             Status;
723     ACPI_OPERAND_OBJECT     *ObjDesc;
724     ACPI_NAMESPACE_NODE     *Node;
725     ACPI_PARSE_OBJECT       *NextOp;
726
727
728     ACPI_FUNCTION_TRACE_PTR ("DsEvalBufferFieldOperands", Op);
729
730
731     /*
732      * This is where we evaluate the address and length fields of the
733      * CreateXxxField declaration
734      */
735     Node =  Op->Common.Node;
736
737     /* NextOp points to the op that holds the Buffer */
738
739     NextOp = Op->Common.Value.Arg;
740
741     /* Evaluate/create the address and length operands */
742
743     Status = AcpiDsCreateOperands (WalkState, NextOp);
744     if (ACPI_FAILURE (Status))
745     {
746         return_ACPI_STATUS (Status);
747     }
748
749     ObjDesc = AcpiNsGetAttachedObject (Node);
750     if (!ObjDesc)
751     {
752         return_ACPI_STATUS (AE_NOT_EXIST);
753     }
754
755     /* Resolve the operands */
756
757     Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
758                     ACPI_WALK_OPERANDS, WalkState);
759
760     ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
761                     AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
762                     WalkState->NumOperands, "after AcpiExResolveOperands");
763
764     if (ACPI_FAILURE (Status))
765     {
766         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n",
767             AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
768
769         return_ACPI_STATUS (Status);
770     }
771
772     /* Initialize the Buffer Field */
773
774     if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
775     {
776         /* NOTE: Slightly different operands for this opcode */
777
778         Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
779                     WalkState->Operands[0], WalkState->Operands[1],
780                     WalkState->Operands[2], WalkState->Operands[3]);
781     }
782     else
783     {
784         /* All other, CreateXxxField opcodes */
785
786         Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
787                     WalkState->Operands[0], WalkState->Operands[1],
788                                       NULL, WalkState->Operands[2]);
789     }
790
791     return_ACPI_STATUS (Status);
792 }
793
794
795 /*******************************************************************************
796  *
797  * FUNCTION:    AcpiDsEvalRegionOperands
798  *
799  * PARAMETERS:  WalkState       - Current walk
800  *              Op              - A valid region Op object
801  *
802  * RETURN:      Status
803  *
804  * DESCRIPTION: Get region address and length
805  *              Called from AcpiDsExecEndOp during OpRegion parse tree walk
806  *
807  ******************************************************************************/
808
809 ACPI_STATUS
810 AcpiDsEvalRegionOperands (
811     ACPI_WALK_STATE         *WalkState,
812     ACPI_PARSE_OBJECT       *Op)
813 {
814     ACPI_STATUS             Status;
815     ACPI_OPERAND_OBJECT     *ObjDesc;
816     ACPI_OPERAND_OBJECT     *OperandDesc;
817     ACPI_NAMESPACE_NODE     *Node;
818     ACPI_PARSE_OBJECT       *NextOp;
819
820
821     ACPI_FUNCTION_TRACE_PTR ("DsEvalRegionOperands", Op);
822
823
824     /*
825      * This is where we evaluate the address and length fields of the
826      * OpRegion declaration
827      */
828     Node =  Op->Common.Node;
829
830     /* NextOp points to the op that holds the SpaceID */
831
832     NextOp = Op->Common.Value.Arg;
833
834     /* NextOp points to address op */
835
836     NextOp = NextOp->Common.Next;
837
838     /* Evaluate/create the address and length operands */
839
840     Status = AcpiDsCreateOperands (WalkState, NextOp);
841     if (ACPI_FAILURE (Status))
842     {
843         return_ACPI_STATUS (Status);
844     }
845
846     /* Resolve the length and address operands to numbers */
847
848     Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
849                 ACPI_WALK_OPERANDS, WalkState);
850     if (ACPI_FAILURE (Status))
851     {
852         return_ACPI_STATUS (Status);
853     }
854
855     ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
856                     AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
857                     1, "after AcpiExResolveOperands");
858
859     ObjDesc = AcpiNsGetAttachedObject (Node);
860     if (!ObjDesc)
861     {
862         return_ACPI_STATUS (AE_NOT_EXIST);
863     }
864
865     /*
866      * Get the length operand and save it
867      * (at Top of stack)
868      */
869     OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
870
871     ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
872     AcpiUtRemoveReference (OperandDesc);
873
874     /*
875      * Get the address and save it
876      * (at top of stack - 1)
877      */
878     OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
879
880     ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS)
881                                 OperandDesc->Integer.Value;
882     AcpiUtRemoveReference (OperandDesc);
883
884     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
885         ObjDesc,
886         ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
887         ObjDesc->Region.Length));
888
889     /* Now the address and length are valid for this opregion */
890
891     ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
892
893     return_ACPI_STATUS (Status);
894 }
895
896
897 /*******************************************************************************
898  *
899  * FUNCTION:    AcpiDsEvalDataObjectOperands
900  *
901  * PARAMETERS:  WalkState       - Current walk
902  *              Op              - A valid DataObject Op object
903  *              ObjDesc         - DataObject
904  *
905  * RETURN:      Status
906  *
907  * DESCRIPTION: Get the operands and complete the following data object types:
908  *              Buffer, Package.
909  *
910  ******************************************************************************/
911
912 ACPI_STATUS
913 AcpiDsEvalDataObjectOperands (
914     ACPI_WALK_STATE         *WalkState,
915     ACPI_PARSE_OBJECT       *Op,
916     ACPI_OPERAND_OBJECT     *ObjDesc)
917 {
918     ACPI_STATUS             Status;
919     ACPI_OPERAND_OBJECT     *ArgDesc;
920     UINT32                  Length;
921
922
923     ACPI_FUNCTION_TRACE ("DsEvalDataObjectOperands");
924
925
926     /* The first operand (for all of these data objects) is the length */
927
928     Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
929     if (ACPI_FAILURE (Status))
930     {
931         return_ACPI_STATUS (Status);
932     }
933
934     Status = AcpiExResolveOperands (WalkState->Opcode,
935                     &(WalkState->Operands [WalkState->NumOperands -1]),
936                     WalkState);
937     if (ACPI_FAILURE (Status))
938     {
939         return_ACPI_STATUS (Status);
940     }
941
942     /* Extract length operand */
943
944     ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
945     Length = (UINT32) ArgDesc->Integer.Value;
946
947     /* Cleanup for length operand */
948
949     Status = AcpiDsObjStackPop (1, WalkState);
950     if (ACPI_FAILURE (Status))
951     {
952         return_ACPI_STATUS (Status);
953     }
954
955     AcpiUtRemoveReference (ArgDesc);
956
957     /*
958      * Create the actual data object
959      */
960     switch (Op->Common.AmlOpcode)
961     {
962     case AML_BUFFER_OP:
963
964         Status = AcpiDsBuildInternalBufferObj (WalkState, Op, Length, &ObjDesc);
965         break;
966
967     case AML_PACKAGE_OP:
968     case AML_VAR_PACKAGE_OP:
969
970         Status = AcpiDsBuildInternalPackageObj (WalkState, Op, Length, &ObjDesc);
971         break;
972
973     default:
974         return_ACPI_STATUS (AE_AML_BAD_OPCODE);
975     }
976
977     if (ACPI_SUCCESS (Status))
978     {
979         /*
980          * Return the object in the WalkState, unless the parent is a package -
981          * in this case, the return object will be stored in the parse tree
982          * for the package.
983          */
984         if ((!Op->Common.Parent) ||
985             ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
986              (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) &&
987              (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
988         {
989             WalkState->ResultObj = ObjDesc;
990         }
991     }
992
993     return_ACPI_STATUS (Status);
994 }
995
996
997 /*******************************************************************************
998  *
999  * FUNCTION:    AcpiDsExecBeginControlOp
1000  *
1001  * PARAMETERS:  WalkList        - The list that owns the walk stack
1002  *              Op              - The control Op
1003  *
1004  * RETURN:      Status
1005  *
1006  * DESCRIPTION: Handles all control ops encountered during control method
1007  *              execution.
1008  *
1009  ******************************************************************************/
1010
1011 ACPI_STATUS
1012 AcpiDsExecBeginControlOp (
1013     ACPI_WALK_STATE         *WalkState,
1014     ACPI_PARSE_OBJECT       *Op)
1015 {
1016     ACPI_STATUS             Status = AE_OK;
1017     ACPI_GENERIC_STATE      *ControlState;
1018
1019
1020     ACPI_FUNCTION_NAME ("DsExecBeginControlOp");
1021
1022
1023     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", Op,
1024         Op->Common.AmlOpcode, WalkState));
1025
1026     switch (Op->Common.AmlOpcode)
1027     {
1028     case AML_IF_OP:
1029     case AML_WHILE_OP:
1030
1031         /*
1032          * IF/WHILE: Create a new control state to manage these
1033          * constructs. We need to manage these as a stack, in order
1034          * to handle nesting.
1035          */
1036         ControlState = AcpiUtCreateControlState ();
1037         if (!ControlState)
1038         {
1039             Status = AE_NO_MEMORY;
1040             break;
1041         }
1042         /*
1043          * Save a pointer to the predicate for multiple executions
1044          * of a loop
1045          */
1046         ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1;
1047         ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd;
1048         ControlState->Control.Opcode = Op->Common.AmlOpcode;
1049
1050
1051         /* Push the control state on this walk's control stack */
1052
1053         AcpiUtPushGenericState (&WalkState->ControlState, ControlState);
1054         break;
1055
1056     case AML_ELSE_OP:
1057
1058         /* Predicate is in the state object */
1059         /* If predicate is true, the IF was executed, ignore ELSE part */
1060
1061         if (WalkState->LastPredicate)
1062         {
1063             Status = AE_CTRL_TRUE;
1064         }
1065
1066         break;
1067
1068     case AML_RETURN_OP:
1069
1070         break;
1071
1072     default:
1073         break;
1074     }
1075
1076     return (Status);
1077 }
1078
1079
1080 /*******************************************************************************
1081  *
1082  * FUNCTION:    AcpiDsExecEndControlOp
1083  *
1084  * PARAMETERS:  WalkList        - The list that owns the walk stack
1085  *              Op              - The control Op
1086  *
1087  * RETURN:      Status
1088  *
1089  * DESCRIPTION: Handles all control ops encountered during control method
1090  *              execution.
1091  *
1092  ******************************************************************************/
1093
1094 ACPI_STATUS
1095 AcpiDsExecEndControlOp (
1096     ACPI_WALK_STATE         *WalkState,
1097     ACPI_PARSE_OBJECT       *Op)
1098 {
1099     ACPI_STATUS             Status = AE_OK;
1100     ACPI_GENERIC_STATE      *ControlState;
1101
1102
1103     ACPI_FUNCTION_NAME ("DsExecEndControlOp");
1104
1105
1106     switch (Op->Common.AmlOpcode)
1107     {
1108     case AML_IF_OP:
1109
1110         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op));
1111
1112         /*
1113          * Save the result of the predicate in case there is an
1114          * ELSE to come
1115          */
1116         WalkState->LastPredicate =
1117             (BOOLEAN) WalkState->ControlState->Common.Value;
1118
1119         /*
1120          * Pop the control state that was created at the start
1121          * of the IF and free it
1122          */
1123         ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
1124         AcpiUtDeleteGenericState (ControlState);
1125         break;
1126
1127
1128     case AML_ELSE_OP:
1129
1130         break;
1131
1132
1133     case AML_WHILE_OP:
1134
1135         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op));
1136
1137         if (WalkState->ControlState->Common.Value)
1138         {
1139             /* Predicate was true, go back and evaluate it again! */
1140
1141             Status = AE_CTRL_PENDING;
1142         }
1143
1144         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1145             "[WHILE_OP] termination! Op=%p\n",Op));
1146
1147         /* Pop this control state and free it */
1148
1149         ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
1150
1151         WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart;
1152         AcpiUtDeleteGenericState (ControlState);
1153         break;
1154
1155
1156     case AML_RETURN_OP:
1157
1158         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1159             "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg));
1160
1161         /*
1162          * One optional operand -- the return value
1163          * It can be either an immediate operand or a result that
1164          * has been bubbled up the tree
1165          */
1166         if (Op->Common.Value.Arg)
1167         {
1168             /* Since we have a real Return(), delete any implicit return */
1169
1170             AcpiDsClearImplicitReturn (WalkState);
1171
1172             /* Return statement has an immediate operand */
1173
1174             Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
1175             if (ACPI_FAILURE (Status))
1176             {
1177                 return (Status);
1178             }
1179
1180             /*
1181              * If value being returned is a Reference (such as
1182              * an arg or local), resolve it now because it may
1183              * cease to exist at the end of the method.
1184              */
1185             Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
1186             if (ACPI_FAILURE (Status))
1187             {
1188                 return (Status);
1189             }
1190
1191             /*
1192              * Get the return value and save as the last result
1193              * value.  This is the only place where WalkState->ReturnDesc
1194              * is set to anything other than zero!
1195              */
1196             WalkState->ReturnDesc = WalkState->Operands[0];
1197         }
1198         else if ((WalkState->Results) &&
1199                  (WalkState->Results->Results.NumResults > 0))
1200         {
1201             /* Since we have a real Return(), delete any implicit return */
1202
1203             AcpiDsClearImplicitReturn (WalkState);
1204
1205             /*
1206              * The return value has come from a previous calculation.
1207              *
1208              * If value being returned is a Reference (such as
1209              * an arg or local), resolve it now because it may
1210              * cease to exist at the end of the method.
1211              *
1212              * Allow references created by the Index operator to return unchanged.
1213              */
1214             if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == ACPI_DESC_TYPE_OPERAND) &&
1215                 (ACPI_GET_OBJECT_TYPE (WalkState->Results->Results.ObjDesc [0]) == ACPI_TYPE_LOCAL_REFERENCE) &&
1216                 ((WalkState->Results->Results.ObjDesc [0])->Reference.Opcode != AML_INDEX_OP))
1217             {
1218                 Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState);
1219                 if (ACPI_FAILURE (Status))
1220                 {
1221                     return (Status);
1222                 }
1223             }
1224
1225             WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0];
1226         }
1227         else
1228         {
1229             /* No return operand */
1230
1231             if (WalkState->NumOperands)
1232             {
1233                 AcpiUtRemoveReference (WalkState->Operands [0]);
1234             }
1235
1236             WalkState->Operands [0]     = NULL;
1237             WalkState->NumOperands      = 0;
1238             WalkState->ReturnDesc       = NULL;
1239         }
1240
1241
1242         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1243             "Completed RETURN_OP State=%p, RetVal=%p\n",
1244             WalkState, WalkState->ReturnDesc));
1245
1246         /* End the control method execution right now */
1247
1248         Status = AE_CTRL_TERMINATE;
1249         break;
1250
1251
1252     case AML_NOOP_OP:
1253
1254         /* Just do nothing! */
1255         break;
1256
1257
1258     case AML_BREAK_POINT_OP:
1259
1260         /* Call up to the OS service layer to handle this */
1261
1262         Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT, "Executed AML Breakpoint opcode");
1263
1264         /* If and when it returns, all done. */
1265
1266         break;
1267
1268
1269     case AML_BREAK_OP:
1270     case AML_CONTINUE_OP: /* ACPI 2.0 */
1271
1272
1273         /* Pop and delete control states until we find a while */
1274
1275         while (WalkState->ControlState &&
1276                 (WalkState->ControlState->Control.Opcode != AML_WHILE_OP))
1277         {
1278             ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
1279             AcpiUtDeleteGenericState (ControlState);
1280         }
1281
1282         /* No while found? */
1283
1284         if (!WalkState->ControlState)
1285         {
1286             return (AE_AML_NO_WHILE);
1287         }
1288
1289         /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */
1290
1291         WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd;
1292
1293         /* Return status depending on opcode */
1294
1295         if (Op->Common.AmlOpcode == AML_BREAK_OP)
1296         {
1297             Status = AE_CTRL_BREAK;
1298         }
1299         else
1300         {
1301             Status = AE_CTRL_CONTINUE;
1302         }
1303         break;
1304
1305
1306     default:
1307
1308         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown control opcode=%X Op=%p\n",
1309             Op->Common.AmlOpcode, Op));
1310
1311         Status = AE_AML_BAD_OPCODE;
1312         break;
1313     }
1314
1315     return (Status);
1316 }
1317