1 /******************************************************************************
3 * Module Name: dsopcode - Dispatcher Op Region support and handling of
6 *****************************************************************************/
8 /******************************************************************************
12 * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
13 * All rights reserved.
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights. You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code. No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
38 * The above copyright and patent license is granted only if the following
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision. In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change. Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee. Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution. In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
73 * 3.4. Intel retains all right, title, and interest in and to the Original
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
81 * 4. Disclaimer and Export Compliance
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government. In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
115 *****************************************************************************/
117 #define __DSOPCODE_C__
120 #include "accommon.h"
121 #include "acparser.h"
123 #include "acdispat.h"
124 #include "acinterp.h"
125 #include "acnamesp.h"
126 #include "acevents.h"
127 #include "actables.h"
129 #define _COMPONENT ACPI_DISPATCHER
130 ACPI_MODULE_NAME ("dsopcode")
132 /* Local prototypes */
135 AcpiDsExecuteArguments (
136 ACPI_NAMESPACE_NODE
*Node
,
137 ACPI_NAMESPACE_NODE
*ScopeNode
,
142 AcpiDsInitBufferField (
144 ACPI_OPERAND_OBJECT
*ObjDesc
,
145 ACPI_OPERAND_OBJECT
*BufferDesc
,
146 ACPI_OPERAND_OBJECT
*OffsetDesc
,
147 ACPI_OPERAND_OBJECT
*LengthDesc
,
148 ACPI_OPERAND_OBJECT
*ResultDesc
);
151 /*******************************************************************************
153 * FUNCTION: AcpiDsExecuteArguments
155 * PARAMETERS: Node - Object NS node
156 * ScopeNode - Parent NS node
157 * AmlLength - Length of executable AML
158 * AmlStart - Pointer to the AML
162 * DESCRIPTION: Late (deferred) execution of region or field arguments
164 ******************************************************************************/
167 AcpiDsExecuteArguments (
168 ACPI_NAMESPACE_NODE
*Node
,
169 ACPI_NAMESPACE_NODE
*ScopeNode
,
174 ACPI_PARSE_OBJECT
*Op
;
175 ACPI_WALK_STATE
*WalkState
;
178 ACPI_FUNCTION_TRACE (DsExecuteArguments
);
182 * Allocate a new parser op to be the root of the parsed tree
184 Op
= AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP
);
187 return_ACPI_STATUS (AE_NO_MEMORY
);
190 /* Save the Node for use in AcpiPsParseAml */
192 Op
->Common
.Node
= ScopeNode
;
194 /* Create and initialize a new parser state */
196 WalkState
= AcpiDsCreateWalkState (0, NULL
, NULL
, NULL
);
199 Status
= AE_NO_MEMORY
;
203 Status
= AcpiDsInitAmlWalk (WalkState
, Op
, NULL
, AmlStart
,
204 AmlLength
, NULL
, ACPI_IMODE_LOAD_PASS1
);
205 if (ACPI_FAILURE (Status
))
207 AcpiDsDeleteWalkState (WalkState
);
211 /* Mark this parse as a deferred opcode */
213 WalkState
->ParseFlags
= ACPI_PARSE_DEFERRED_OP
;
214 WalkState
->DeferredNode
= Node
;
216 /* Pass1: Parse the entire declaration */
218 Status
= AcpiPsParseAml (WalkState
);
219 if (ACPI_FAILURE (Status
))
224 /* Get and init the Op created above */
226 Op
->Common
.Node
= Node
;
227 AcpiPsDeleteParseTree (Op
);
229 /* Evaluate the deferred arguments */
231 Op
= AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP
);
234 return_ACPI_STATUS (AE_NO_MEMORY
);
237 Op
->Common
.Node
= ScopeNode
;
239 /* Create and initialize a new parser state */
241 WalkState
= AcpiDsCreateWalkState (0, NULL
, NULL
, NULL
);
244 Status
= AE_NO_MEMORY
;
248 /* Execute the opcode and arguments */
250 Status
= AcpiDsInitAmlWalk (WalkState
, Op
, NULL
, AmlStart
,
251 AmlLength
, NULL
, ACPI_IMODE_EXECUTE
);
252 if (ACPI_FAILURE (Status
))
254 AcpiDsDeleteWalkState (WalkState
);
258 /* Mark this execution as a deferred opcode */
260 WalkState
->DeferredNode
= Node
;
261 Status
= AcpiPsParseAml (WalkState
);
264 AcpiPsDeleteParseTree (Op
);
265 return_ACPI_STATUS (Status
);
269 /*******************************************************************************
271 * FUNCTION: AcpiDsGetBufferFieldArguments
273 * PARAMETERS: ObjDesc - A valid BufferField object
277 * DESCRIPTION: Get BufferField Buffer and Index. This implements the late
278 * evaluation of these field attributes.
280 ******************************************************************************/
283 AcpiDsGetBufferFieldArguments (
284 ACPI_OPERAND_OBJECT
*ObjDesc
)
286 ACPI_OPERAND_OBJECT
*ExtraDesc
;
287 ACPI_NAMESPACE_NODE
*Node
;
291 ACPI_FUNCTION_TRACE_PTR (DsGetBufferFieldArguments
, ObjDesc
);
294 if (ObjDesc
->Common
.Flags
& AOPOBJ_DATA_VALID
)
296 return_ACPI_STATUS (AE_OK
);
299 /* Get the AML pointer (method object) and BufferField node */
301 ExtraDesc
= AcpiNsGetSecondaryObject (ObjDesc
);
302 Node
= ObjDesc
->BufferField
.Node
;
304 ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_BUFFER_FIELD
, Node
, NULL
));
305 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC
, "[%4.4s] BufferField Arg Init\n",
306 AcpiUtGetNodeName (Node
)));
308 /* Execute the AML code for the TermArg arguments */
310 Status
= AcpiDsExecuteArguments (Node
, Node
->Parent
,
311 ExtraDesc
->Extra
.AmlLength
, ExtraDesc
->Extra
.AmlStart
);
312 return_ACPI_STATUS (Status
);
316 /*******************************************************************************
318 * FUNCTION: AcpiDsGetBankFieldArguments
320 * PARAMETERS: ObjDesc - A valid BankField object
324 * DESCRIPTION: Get BankField BankValue. This implements the late
325 * evaluation of these field attributes.
327 ******************************************************************************/
330 AcpiDsGetBankFieldArguments (
331 ACPI_OPERAND_OBJECT
*ObjDesc
)
333 ACPI_OPERAND_OBJECT
*ExtraDesc
;
334 ACPI_NAMESPACE_NODE
*Node
;
338 ACPI_FUNCTION_TRACE_PTR (DsGetBankFieldArguments
, ObjDesc
);
341 if (ObjDesc
->Common
.Flags
& AOPOBJ_DATA_VALID
)
343 return_ACPI_STATUS (AE_OK
);
346 /* Get the AML pointer (method object) and BankField node */
348 ExtraDesc
= AcpiNsGetSecondaryObject (ObjDesc
);
349 Node
= ObjDesc
->BankField
.Node
;
351 ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_LOCAL_BANK_FIELD
, Node
, NULL
));
352 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC
, "[%4.4s] BankField Arg Init\n",
353 AcpiUtGetNodeName (Node
)));
355 /* Execute the AML code for the TermArg arguments */
357 Status
= AcpiDsExecuteArguments (Node
, Node
->Parent
,
358 ExtraDesc
->Extra
.AmlLength
, ExtraDesc
->Extra
.AmlStart
);
359 return_ACPI_STATUS (Status
);
363 /*******************************************************************************
365 * FUNCTION: AcpiDsGetBufferArguments
367 * PARAMETERS: ObjDesc - A valid Buffer object
371 * DESCRIPTION: Get Buffer length and initializer byte list. This implements
372 * the late evaluation of these attributes.
374 ******************************************************************************/
377 AcpiDsGetBufferArguments (
378 ACPI_OPERAND_OBJECT
*ObjDesc
)
380 ACPI_NAMESPACE_NODE
*Node
;
384 ACPI_FUNCTION_TRACE_PTR (DsGetBufferArguments
, ObjDesc
);
387 if (ObjDesc
->Common
.Flags
& AOPOBJ_DATA_VALID
)
389 return_ACPI_STATUS (AE_OK
);
392 /* Get the Buffer node */
394 Node
= ObjDesc
->Buffer
.Node
;
397 ACPI_ERROR ((AE_INFO
,
398 "No pointer back to namespace node in buffer object %p", ObjDesc
));
399 return_ACPI_STATUS (AE_AML_INTERNAL
);
402 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC
, "Buffer Arg Init\n"));
404 /* Execute the AML code for the TermArg arguments */
406 Status
= AcpiDsExecuteArguments (Node
, Node
,
407 ObjDesc
->Buffer
.AmlLength
, ObjDesc
->Buffer
.AmlStart
);
408 return_ACPI_STATUS (Status
);
412 /*******************************************************************************
414 * FUNCTION: AcpiDsGetPackageArguments
416 * PARAMETERS: ObjDesc - A valid Package object
420 * DESCRIPTION: Get Package length and initializer byte list. This implements
421 * the late evaluation of these attributes.
423 ******************************************************************************/
426 AcpiDsGetPackageArguments (
427 ACPI_OPERAND_OBJECT
*ObjDesc
)
429 ACPI_NAMESPACE_NODE
*Node
;
433 ACPI_FUNCTION_TRACE_PTR (DsGetPackageArguments
, ObjDesc
);
436 if (ObjDesc
->Common
.Flags
& AOPOBJ_DATA_VALID
)
438 return_ACPI_STATUS (AE_OK
);
441 /* Get the Package node */
443 Node
= ObjDesc
->Package
.Node
;
446 ACPI_ERROR ((AE_INFO
,
447 "No pointer back to namespace node in package %p", ObjDesc
));
448 return_ACPI_STATUS (AE_AML_INTERNAL
);
451 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC
, "Package Arg Init\n"));
453 /* Execute the AML code for the TermArg arguments */
455 Status
= AcpiDsExecuteArguments (Node
, Node
,
456 ObjDesc
->Package
.AmlLength
, ObjDesc
->Package
.AmlStart
);
457 return_ACPI_STATUS (Status
);
461 /*****************************************************************************
463 * FUNCTION: AcpiDsGetRegionArguments
465 * PARAMETERS: ObjDesc - A valid region object
469 * DESCRIPTION: Get region address and length. This implements the late
470 * evaluation of these region attributes.
472 ****************************************************************************/
475 AcpiDsGetRegionArguments (
476 ACPI_OPERAND_OBJECT
*ObjDesc
)
478 ACPI_NAMESPACE_NODE
*Node
;
480 ACPI_OPERAND_OBJECT
*ExtraDesc
;
483 ACPI_FUNCTION_TRACE_PTR (DsGetRegionArguments
, ObjDesc
);
486 if (ObjDesc
->Region
.Flags
& AOPOBJ_DATA_VALID
)
488 return_ACPI_STATUS (AE_OK
);
491 ExtraDesc
= AcpiNsGetSecondaryObject (ObjDesc
);
494 return_ACPI_STATUS (AE_NOT_EXIST
);
497 /* Get the Region node */
499 Node
= ObjDesc
->Region
.Node
;
501 ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_REGION
, Node
, NULL
));
503 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC
, "[%4.4s] OpRegion Arg Init at AML %p\n",
504 AcpiUtGetNodeName (Node
), ExtraDesc
->Extra
.AmlStart
));
506 /* Execute the argument AML */
508 Status
= AcpiDsExecuteArguments (Node
, Node
->Parent
,
509 ExtraDesc
->Extra
.AmlLength
, ExtraDesc
->Extra
.AmlStart
);
510 return_ACPI_STATUS (Status
);
514 /*******************************************************************************
516 * FUNCTION: AcpiDsInitializeRegion
518 * PARAMETERS: ObjHandle - Region namespace node
522 * DESCRIPTION: Front end to EvInitializeRegion
524 ******************************************************************************/
527 AcpiDsInitializeRegion (
528 ACPI_HANDLE ObjHandle
)
530 ACPI_OPERAND_OBJECT
*ObjDesc
;
534 ObjDesc
= AcpiNsGetAttachedObject (ObjHandle
);
536 /* Namespace is NOT locked */
538 Status
= AcpiEvInitializeRegion (ObjDesc
, FALSE
);
543 /*******************************************************************************
545 * FUNCTION: AcpiDsInitBufferField
547 * PARAMETERS: AmlOpcode - CreateXxxField
548 * ObjDesc - BufferField object
549 * BufferDesc - Host Buffer
550 * OffsetDesc - Offset into buffer
551 * LengthDesc - Length of field (CREATE_FIELD_OP only)
552 * ResultDesc - Where to store the result
556 * DESCRIPTION: Perform actual initialization of a buffer field
558 ******************************************************************************/
561 AcpiDsInitBufferField (
563 ACPI_OPERAND_OBJECT
*ObjDesc
,
564 ACPI_OPERAND_OBJECT
*BufferDesc
,
565 ACPI_OPERAND_OBJECT
*OffsetDesc
,
566 ACPI_OPERAND_OBJECT
*LengthDesc
,
567 ACPI_OPERAND_OBJECT
*ResultDesc
)
576 ACPI_FUNCTION_TRACE_PTR (DsInitBufferField
, ObjDesc
);
579 /* Host object must be a Buffer */
581 if (BufferDesc
->Common
.Type
!= ACPI_TYPE_BUFFER
)
583 ACPI_ERROR ((AE_INFO
,
584 "Target of Create Field is not a Buffer object - %s",
585 AcpiUtGetObjectTypeName (BufferDesc
)));
587 Status
= AE_AML_OPERAND_TYPE
;
592 * The last parameter to all of these opcodes (ResultDesc) started
593 * out as a NameString, and should therefore now be a NS node
594 * after resolution in AcpiExResolveOperands().
596 if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc
) != ACPI_DESC_TYPE_NAMED
)
598 ACPI_ERROR ((AE_INFO
,
599 "(%s) destination not a NS Node [%s]",
600 AcpiPsGetOpcodeName (AmlOpcode
),
601 AcpiUtGetDescriptorName (ResultDesc
)));
603 Status
= AE_AML_OPERAND_TYPE
;
607 Offset
= (UINT32
) OffsetDesc
->Integer
.Value
;
610 * Setup the Bit offsets and counts, according to the opcode
614 case AML_CREATE_FIELD_OP
:
616 /* Offset is in bits, count is in bits */
618 FieldFlags
= AML_FIELD_ACCESS_BYTE
;
620 BitCount
= (UINT32
) LengthDesc
->Integer
.Value
;
622 /* Must have a valid (>0) bit count */
626 ACPI_ERROR ((AE_INFO
,
627 "Attempt to CreateField of length zero"));
628 Status
= AE_AML_OPERAND_VALUE
;
633 case AML_CREATE_BIT_FIELD_OP
:
635 /* Offset is in bits, Field is one bit */
639 FieldFlags
= AML_FIELD_ACCESS_BYTE
;
642 case AML_CREATE_BYTE_FIELD_OP
:
644 /* Offset is in bytes, field is one byte */
646 BitOffset
= 8 * Offset
;
648 FieldFlags
= AML_FIELD_ACCESS_BYTE
;
651 case AML_CREATE_WORD_FIELD_OP
:
653 /* Offset is in bytes, field is one word */
655 BitOffset
= 8 * Offset
;
657 FieldFlags
= AML_FIELD_ACCESS_WORD
;
660 case AML_CREATE_DWORD_FIELD_OP
:
662 /* Offset is in bytes, field is one dword */
664 BitOffset
= 8 * Offset
;
666 FieldFlags
= AML_FIELD_ACCESS_DWORD
;
669 case AML_CREATE_QWORD_FIELD_OP
:
671 /* Offset is in bytes, field is one qword */
673 BitOffset
= 8 * Offset
;
675 FieldFlags
= AML_FIELD_ACCESS_QWORD
;
680 ACPI_ERROR ((AE_INFO
,
681 "Unknown field creation opcode 0x%02X",
683 Status
= AE_AML_BAD_OPCODE
;
687 /* Entire field must fit within the current length of the buffer */
689 if ((BitOffset
+ BitCount
) >
690 (8 * (UINT32
) BufferDesc
->Buffer
.Length
))
692 ACPI_ERROR ((AE_INFO
,
693 "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
694 AcpiUtGetNodeName (ResultDesc
),
695 BitOffset
+ BitCount
,
696 AcpiUtGetNodeName (BufferDesc
->Buffer
.Node
),
697 8 * (UINT32
) BufferDesc
->Buffer
.Length
));
698 Status
= AE_AML_BUFFER_LIMIT
;
703 * Initialize areas of the field object that are common to all fields
704 * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
705 * UPDATE_RULE = 0 (UPDATE_PRESERVE)
707 Status
= AcpiExPrepCommonFieldObject (ObjDesc
, FieldFlags
, 0,
708 BitOffset
, BitCount
);
709 if (ACPI_FAILURE (Status
))
714 ObjDesc
->BufferField
.BufferObj
= BufferDesc
;
716 /* Reference count for BufferDesc inherits ObjDesc count */
718 BufferDesc
->Common
.ReferenceCount
= (UINT16
)
719 (BufferDesc
->Common
.ReferenceCount
+ ObjDesc
->Common
.ReferenceCount
);
724 /* Always delete the operands */
726 AcpiUtRemoveReference (OffsetDesc
);
727 AcpiUtRemoveReference (BufferDesc
);
729 if (AmlOpcode
== AML_CREATE_FIELD_OP
)
731 AcpiUtRemoveReference (LengthDesc
);
734 /* On failure, delete the result descriptor */
736 if (ACPI_FAILURE (Status
))
738 AcpiUtRemoveReference (ResultDesc
); /* Result descriptor */
742 /* Now the address and length are valid for this BufferField */
744 ObjDesc
->BufferField
.Flags
|= AOPOBJ_DATA_VALID
;
747 return_ACPI_STATUS (Status
);
751 /*******************************************************************************
753 * FUNCTION: AcpiDsEvalBufferFieldOperands
755 * PARAMETERS: WalkState - Current walk
756 * Op - A valid BufferField Op object
760 * DESCRIPTION: Get BufferField Buffer and Index
761 * Called from AcpiDsExecEndOp during BufferField parse tree walk
763 ******************************************************************************/
766 AcpiDsEvalBufferFieldOperands (
767 ACPI_WALK_STATE
*WalkState
,
768 ACPI_PARSE_OBJECT
*Op
)
771 ACPI_OPERAND_OBJECT
*ObjDesc
;
772 ACPI_NAMESPACE_NODE
*Node
;
773 ACPI_PARSE_OBJECT
*NextOp
;
776 ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands
, Op
);
780 * This is where we evaluate the address and length fields of the
781 * CreateXxxField declaration
783 Node
= Op
->Common
.Node
;
785 /* NextOp points to the op that holds the Buffer */
787 NextOp
= Op
->Common
.Value
.Arg
;
789 /* Evaluate/create the address and length operands */
791 Status
= AcpiDsCreateOperands (WalkState
, NextOp
);
792 if (ACPI_FAILURE (Status
))
794 return_ACPI_STATUS (Status
);
797 ObjDesc
= AcpiNsGetAttachedObject (Node
);
800 return_ACPI_STATUS (AE_NOT_EXIST
);
803 /* Resolve the operands */
805 Status
= AcpiExResolveOperands (Op
->Common
.AmlOpcode
,
806 ACPI_WALK_OPERANDS
, WalkState
);
807 if (ACPI_FAILURE (Status
))
809 ACPI_ERROR ((AE_INFO
, "(%s) bad operand(s), status 0x%X",
810 AcpiPsGetOpcodeName (Op
->Common
.AmlOpcode
), Status
));
812 return_ACPI_STATUS (Status
);
815 /* Initialize the Buffer Field */
817 if (Op
->Common
.AmlOpcode
== AML_CREATE_FIELD_OP
)
819 /* NOTE: Slightly different operands for this opcode */
821 Status
= AcpiDsInitBufferField (Op
->Common
.AmlOpcode
, ObjDesc
,
822 WalkState
->Operands
[0], WalkState
->Operands
[1],
823 WalkState
->Operands
[2], WalkState
->Operands
[3]);
827 /* All other, CreateXxxField opcodes */
829 Status
= AcpiDsInitBufferField (Op
->Common
.AmlOpcode
, ObjDesc
,
830 WalkState
->Operands
[0], WalkState
->Operands
[1],
831 NULL
, WalkState
->Operands
[2]);
834 return_ACPI_STATUS (Status
);
838 /*******************************************************************************
840 * FUNCTION: AcpiDsEvalRegionOperands
842 * PARAMETERS: WalkState - Current walk
843 * Op - A valid region Op object
847 * DESCRIPTION: Get region address and length
848 * Called from AcpiDsExecEndOp during OpRegion parse tree walk
850 ******************************************************************************/
853 AcpiDsEvalRegionOperands (
854 ACPI_WALK_STATE
*WalkState
,
855 ACPI_PARSE_OBJECT
*Op
)
858 ACPI_OPERAND_OBJECT
*ObjDesc
;
859 ACPI_OPERAND_OBJECT
*OperandDesc
;
860 ACPI_NAMESPACE_NODE
*Node
;
861 ACPI_PARSE_OBJECT
*NextOp
;
864 ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands
, Op
);
868 * This is where we evaluate the address and length fields of the
869 * OpRegion declaration
871 Node
= Op
->Common
.Node
;
873 /* NextOp points to the op that holds the SpaceID */
875 NextOp
= Op
->Common
.Value
.Arg
;
877 /* NextOp points to address op */
879 NextOp
= NextOp
->Common
.Next
;
881 /* Evaluate/create the address and length operands */
883 Status
= AcpiDsCreateOperands (WalkState
, NextOp
);
884 if (ACPI_FAILURE (Status
))
886 return_ACPI_STATUS (Status
);
889 /* Resolve the length and address operands to numbers */
891 Status
= AcpiExResolveOperands (Op
->Common
.AmlOpcode
,
892 ACPI_WALK_OPERANDS
, WalkState
);
893 if (ACPI_FAILURE (Status
))
895 return_ACPI_STATUS (Status
);
898 ObjDesc
= AcpiNsGetAttachedObject (Node
);
901 return_ACPI_STATUS (AE_NOT_EXIST
);
905 * Get the length operand and save it
908 OperandDesc
= WalkState
->Operands
[WalkState
->NumOperands
- 1];
910 ObjDesc
->Region
.Length
= (UINT32
) OperandDesc
->Integer
.Value
;
911 AcpiUtRemoveReference (OperandDesc
);
914 * Get the address and save it
915 * (at top of stack - 1)
917 OperandDesc
= WalkState
->Operands
[WalkState
->NumOperands
- 2];
919 ObjDesc
->Region
.Address
= (ACPI_PHYSICAL_ADDRESS
)
920 OperandDesc
->Integer
.Value
;
921 AcpiUtRemoveReference (OperandDesc
);
923 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC
, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
925 ACPI_FORMAT_NATIVE_UINT (ObjDesc
->Region
.Address
),
926 ObjDesc
->Region
.Length
));
928 /* Now the address and length are valid for this opregion */
930 ObjDesc
->Region
.Flags
|= AOPOBJ_DATA_VALID
;
932 return_ACPI_STATUS (Status
);
936 /*******************************************************************************
938 * FUNCTION: AcpiDsEvalTableRegionOperands
940 * PARAMETERS: WalkState - Current walk
941 * Op - A valid region Op object
945 * DESCRIPTION: Get region address and length
946 * Called from AcpiDsExecEndOp during DataTableRegion parse tree walk
948 ******************************************************************************/
951 AcpiDsEvalTableRegionOperands (
952 ACPI_WALK_STATE
*WalkState
,
953 ACPI_PARSE_OBJECT
*Op
)
956 ACPI_OPERAND_OBJECT
*ObjDesc
;
957 ACPI_OPERAND_OBJECT
**Operand
;
958 ACPI_NAMESPACE_NODE
*Node
;
959 ACPI_PARSE_OBJECT
*NextOp
;
961 ACPI_TABLE_HEADER
*Table
;
964 ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands
, Op
);
968 * This is where we evaluate the SignatureString and OemIDString
969 * and OemTableIDString of the DataTableRegion declaration
971 Node
= Op
->Common
.Node
;
973 /* NextOp points to SignatureString op */
975 NextOp
= Op
->Common
.Value
.Arg
;
978 * Evaluate/create the SignatureString and OemIDString
979 * and OemTableIDString operands
981 Status
= AcpiDsCreateOperands (WalkState
, NextOp
);
982 if (ACPI_FAILURE (Status
))
984 return_ACPI_STATUS (Status
);
988 * Resolve the SignatureString and OemIDString
989 * and OemTableIDString operands
991 Status
= AcpiExResolveOperands (Op
->Common
.AmlOpcode
,
992 ACPI_WALK_OPERANDS
, WalkState
);
993 if (ACPI_FAILURE (Status
))
995 return_ACPI_STATUS (Status
);
998 Operand
= &WalkState
->Operands
[0];
1000 /* Find the ACPI table */
1002 Status
= AcpiTbFindTable (Operand
[0]->String
.Pointer
,
1003 Operand
[1]->String
.Pointer
, Operand
[2]->String
.Pointer
,
1005 if (ACPI_FAILURE (Status
))
1007 return_ACPI_STATUS (Status
);
1010 AcpiUtRemoveReference (Operand
[0]);
1011 AcpiUtRemoveReference (Operand
[1]);
1012 AcpiUtRemoveReference (Operand
[2]);
1014 Status
= AcpiGetTableByIndex (TableIndex
, &Table
);
1015 if (ACPI_FAILURE (Status
))
1017 return_ACPI_STATUS (Status
);
1020 ObjDesc
= AcpiNsGetAttachedObject (Node
);
1023 return_ACPI_STATUS (AE_NOT_EXIST
);
1026 ObjDesc
->Region
.Address
= (ACPI_PHYSICAL_ADDRESS
) ACPI_TO_INTEGER (Table
);
1027 ObjDesc
->Region
.Length
= Table
->Length
;
1029 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC
, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
1031 ACPI_FORMAT_NATIVE_UINT (ObjDesc
->Region
.Address
),
1032 ObjDesc
->Region
.Length
));
1034 /* Now the address and length are valid for this opregion */
1036 ObjDesc
->Region
.Flags
|= AOPOBJ_DATA_VALID
;
1038 return_ACPI_STATUS (Status
);
1042 /*******************************************************************************
1044 * FUNCTION: AcpiDsEvalDataObjectOperands
1046 * PARAMETERS: WalkState - Current walk
1047 * Op - A valid DataObject Op object
1048 * ObjDesc - DataObject
1052 * DESCRIPTION: Get the operands and complete the following data object types:
1055 ******************************************************************************/
1058 AcpiDsEvalDataObjectOperands (
1059 ACPI_WALK_STATE
*WalkState
,
1060 ACPI_PARSE_OBJECT
*Op
,
1061 ACPI_OPERAND_OBJECT
*ObjDesc
)
1064 ACPI_OPERAND_OBJECT
*ArgDesc
;
1068 ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands
);
1071 /* The first operand (for all of these data objects) is the length */
1074 * Set proper index into operand stack for AcpiDsObjStackPush
1075 * invoked inside AcpiDsCreateOperand.
1077 WalkState
->OperandIndex
= WalkState
->NumOperands
;
1079 Status
= AcpiDsCreateOperand (WalkState
, Op
->Common
.Value
.Arg
, 1);
1080 if (ACPI_FAILURE (Status
))
1082 return_ACPI_STATUS (Status
);
1085 Status
= AcpiExResolveOperands (WalkState
->Opcode
,
1086 &(WalkState
->Operands
[WalkState
->NumOperands
-1]),
1088 if (ACPI_FAILURE (Status
))
1090 return_ACPI_STATUS (Status
);
1093 /* Extract length operand */
1095 ArgDesc
= WalkState
->Operands
[WalkState
->NumOperands
- 1];
1096 Length
= (UINT32
) ArgDesc
->Integer
.Value
;
1098 /* Cleanup for length operand */
1100 Status
= AcpiDsObjStackPop (1, WalkState
);
1101 if (ACPI_FAILURE (Status
))
1103 return_ACPI_STATUS (Status
);
1106 AcpiUtRemoveReference (ArgDesc
);
1109 * Create the actual data object
1111 switch (Op
->Common
.AmlOpcode
)
1115 Status
= AcpiDsBuildInternalBufferObj (WalkState
, Op
, Length
, &ObjDesc
);
1118 case AML_PACKAGE_OP
:
1119 case AML_VAR_PACKAGE_OP
:
1121 Status
= AcpiDsBuildInternalPackageObj (WalkState
, Op
, Length
, &ObjDesc
);
1125 return_ACPI_STATUS (AE_AML_BAD_OPCODE
);
1128 if (ACPI_SUCCESS (Status
))
1131 * Return the object in the WalkState, unless the parent is a package -
1132 * in this case, the return object will be stored in the parse tree
1135 if ((!Op
->Common
.Parent
) ||
1136 ((Op
->Common
.Parent
->Common
.AmlOpcode
!= AML_PACKAGE_OP
) &&
1137 (Op
->Common
.Parent
->Common
.AmlOpcode
!= AML_VAR_PACKAGE_OP
) &&
1138 (Op
->Common
.Parent
->Common
.AmlOpcode
!= AML_NAME_OP
)))
1140 WalkState
->ResultObj
= ObjDesc
;
1144 return_ACPI_STATUS (Status
);
1148 /*******************************************************************************
1150 * FUNCTION: AcpiDsEvalBankFieldOperands
1152 * PARAMETERS: WalkState - Current walk
1153 * Op - A valid BankField Op object
1157 * DESCRIPTION: Get BankField BankValue
1158 * Called from AcpiDsExecEndOp during BankField parse tree walk
1160 ******************************************************************************/
1163 AcpiDsEvalBankFieldOperands (
1164 ACPI_WALK_STATE
*WalkState
,
1165 ACPI_PARSE_OBJECT
*Op
)
1168 ACPI_OPERAND_OBJECT
*ObjDesc
;
1169 ACPI_OPERAND_OBJECT
*OperandDesc
;
1170 ACPI_NAMESPACE_NODE
*Node
;
1171 ACPI_PARSE_OBJECT
*NextOp
;
1172 ACPI_PARSE_OBJECT
*Arg
;
1175 ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands
, Op
);
1179 * This is where we evaluate the BankValue field of the
1180 * BankField declaration
1183 /* NextOp points to the op that holds the Region */
1185 NextOp
= Op
->Common
.Value
.Arg
;
1187 /* NextOp points to the op that holds the Bank Register */
1189 NextOp
= NextOp
->Common
.Next
;
1191 /* NextOp points to the op that holds the Bank Value */
1193 NextOp
= NextOp
->Common
.Next
;
1196 * Set proper index into operand stack for AcpiDsObjStackPush
1197 * invoked inside AcpiDsCreateOperand.
1199 * We use WalkState->Operands[0] to store the evaluated BankValue
1201 WalkState
->OperandIndex
= 0;
1203 Status
= AcpiDsCreateOperand (WalkState
, NextOp
, 0);
1204 if (ACPI_FAILURE (Status
))
1206 return_ACPI_STATUS (Status
);
1209 Status
= AcpiExResolveToValue (&WalkState
->Operands
[0], WalkState
);
1210 if (ACPI_FAILURE (Status
))
1212 return_ACPI_STATUS (Status
);
1215 ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS
,
1216 AcpiPsGetOpcodeName (Op
->Common
.AmlOpcode
), 1);
1218 * Get the BankValue operand and save it
1221 OperandDesc
= WalkState
->Operands
[0];
1223 /* Arg points to the start Bank Field */
1225 Arg
= AcpiPsGetArg (Op
, 4);
1228 /* Ignore OFFSET and ACCESSAS terms here */
1230 if (Arg
->Common
.AmlOpcode
== AML_INT_NAMEDFIELD_OP
)
1232 Node
= Arg
->Common
.Node
;
1234 ObjDesc
= AcpiNsGetAttachedObject (Node
);
1237 return_ACPI_STATUS (AE_NOT_EXIST
);
1240 ObjDesc
->BankField
.Value
= (UINT32
) OperandDesc
->Integer
.Value
;
1243 /* Move to next field in the list */
1245 Arg
= Arg
->Common
.Next
;
1248 AcpiUtRemoveReference (OperandDesc
);
1249 return_ACPI_STATUS (Status
);
1253 /*******************************************************************************
1255 * FUNCTION: AcpiDsExecBeginControlOp
1257 * PARAMETERS: WalkList - The list that owns the walk stack
1258 * Op - The control Op
1262 * DESCRIPTION: Handles all control ops encountered during control method
1265 ******************************************************************************/
1268 AcpiDsExecBeginControlOp (
1269 ACPI_WALK_STATE
*WalkState
,
1270 ACPI_PARSE_OBJECT
*Op
)
1272 ACPI_STATUS Status
= AE_OK
;
1273 ACPI_GENERIC_STATE
*ControlState
;
1276 ACPI_FUNCTION_NAME (DsExecBeginControlOp
);
1279 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH
, "Op=%p Opcode=%2.2X State=%p\n", Op
,
1280 Op
->Common
.AmlOpcode
, WalkState
));
1282 switch (Op
->Common
.AmlOpcode
)
1287 * If this is an additional iteration of a while loop, continue.
1288 * There is no need to allocate a new control state.
1290 if (WalkState
->ControlState
)
1292 if (WalkState
->ControlState
->Control
.AmlPredicateStart
==
1293 (WalkState
->ParserState
.Aml
- 1))
1295 /* Reset the state to start-of-loop */
1297 WalkState
->ControlState
->Common
.State
= ACPI_CONTROL_CONDITIONAL_EXECUTING
;
1302 /*lint -fallthrough */
1307 * IF/WHILE: Create a new control state to manage these
1308 * constructs. We need to manage these as a stack, in order
1309 * to handle nesting.
1311 ControlState
= AcpiUtCreateControlState ();
1314 Status
= AE_NO_MEMORY
;
1318 * Save a pointer to the predicate for multiple executions
1321 ControlState
->Control
.AmlPredicateStart
= WalkState
->ParserState
.Aml
- 1;
1322 ControlState
->Control
.PackageEnd
= WalkState
->ParserState
.PkgEnd
;
1323 ControlState
->Control
.Opcode
= Op
->Common
.AmlOpcode
;
1326 /* Push the control state on this walk's control stack */
1328 AcpiUtPushGenericState (&WalkState
->ControlState
, ControlState
);
1333 /* Predicate is in the state object */
1334 /* If predicate is true, the IF was executed, ignore ELSE part */
1336 if (WalkState
->LastPredicate
)
1338 Status
= AE_CTRL_TRUE
;
1355 /*******************************************************************************
1357 * FUNCTION: AcpiDsExecEndControlOp
1359 * PARAMETERS: WalkList - The list that owns the walk stack
1360 * Op - The control Op
1364 * DESCRIPTION: Handles all control ops encountered during control method
1367 ******************************************************************************/
1370 AcpiDsExecEndControlOp (
1371 ACPI_WALK_STATE
*WalkState
,
1372 ACPI_PARSE_OBJECT
*Op
)
1374 ACPI_STATUS Status
= AE_OK
;
1375 ACPI_GENERIC_STATE
*ControlState
;
1378 ACPI_FUNCTION_NAME (DsExecEndControlOp
);
1381 switch (Op
->Common
.AmlOpcode
)
1385 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH
, "[IF_OP] Op=%p\n", Op
));
1388 * Save the result of the predicate in case there is an
1391 WalkState
->LastPredicate
=
1392 (BOOLEAN
) WalkState
->ControlState
->Common
.Value
;
1395 * Pop the control state that was created at the start
1396 * of the IF and free it
1398 ControlState
= AcpiUtPopGenericState (&WalkState
->ControlState
);
1399 AcpiUtDeleteGenericState (ControlState
);
1410 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH
, "[WHILE_OP] Op=%p\n", Op
));
1412 ControlState
= WalkState
->ControlState
;
1413 if (ControlState
->Common
.Value
)
1415 /* Predicate was true, the body of the loop was just executed */
1418 * This loop counter mechanism allows the interpreter to escape
1419 * possibly infinite loops. This can occur in poorly written AML
1420 * when the hardware does not respond within a while loop and the
1421 * loop does not implement a timeout.
1423 ControlState
->Control
.LoopCount
++;
1424 if (ControlState
->Control
.LoopCount
> ACPI_MAX_LOOP_ITERATIONS
)
1426 Status
= AE_AML_INFINITE_LOOP
;
1431 * Go back and evaluate the predicate and maybe execute the loop
1434 Status
= AE_CTRL_PENDING
;
1435 WalkState
->AmlLastWhile
= ControlState
->Control
.AmlPredicateStart
;
1439 /* Predicate was false, terminate this while loop */
1441 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH
,
1442 "[WHILE_OP] termination! Op=%p\n",Op
));
1444 /* Pop this control state and free it */
1446 ControlState
= AcpiUtPopGenericState (&WalkState
->ControlState
);
1447 AcpiUtDeleteGenericState (ControlState
);
1453 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH
,
1454 "[RETURN_OP] Op=%p Arg=%p\n",Op
, Op
->Common
.Value
.Arg
));
1457 * One optional operand -- the return value
1458 * It can be either an immediate operand or a result that
1459 * has been bubbled up the tree
1461 if (Op
->Common
.Value
.Arg
)
1463 /* Since we have a real Return(), delete any implicit return */
1465 AcpiDsClearImplicitReturn (WalkState
);
1467 /* Return statement has an immediate operand */
1469 Status
= AcpiDsCreateOperands (WalkState
, Op
->Common
.Value
.Arg
);
1470 if (ACPI_FAILURE (Status
))
1476 * If value being returned is a Reference (such as
1477 * an arg or local), resolve it now because it may
1478 * cease to exist at the end of the method.
1480 Status
= AcpiExResolveToValue (&WalkState
->Operands
[0], WalkState
);
1481 if (ACPI_FAILURE (Status
))
1487 * Get the return value and save as the last result
1488 * value. This is the only place where WalkState->ReturnDesc
1489 * is set to anything other than zero!
1491 WalkState
->ReturnDesc
= WalkState
->Operands
[0];
1493 else if (WalkState
->ResultCount
)
1495 /* Since we have a real Return(), delete any implicit return */
1497 AcpiDsClearImplicitReturn (WalkState
);
1500 * The return value has come from a previous calculation.
1502 * If value being returned is a Reference (such as
1503 * an arg or local), resolve it now because it may
1504 * cease to exist at the end of the method.
1506 * Allow references created by the Index operator to return unchanged.
1508 if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState
->Results
->Results
.ObjDesc
[0]) == ACPI_DESC_TYPE_OPERAND
) &&
1509 ((WalkState
->Results
->Results
.ObjDesc
[0])->Common
.Type
== ACPI_TYPE_LOCAL_REFERENCE
) &&
1510 ((WalkState
->Results
->Results
.ObjDesc
[0])->Reference
.Class
!= ACPI_REFCLASS_INDEX
))
1512 Status
= AcpiExResolveToValue (&WalkState
->Results
->Results
.ObjDesc
[0], WalkState
);
1513 if (ACPI_FAILURE (Status
))
1519 WalkState
->ReturnDesc
= WalkState
->Results
->Results
.ObjDesc
[0];
1523 /* No return operand */
1525 if (WalkState
->NumOperands
)
1527 AcpiUtRemoveReference (WalkState
->Operands
[0]);
1530 WalkState
->Operands
[0] = NULL
;
1531 WalkState
->NumOperands
= 0;
1532 WalkState
->ReturnDesc
= NULL
;
1536 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH
,
1537 "Completed RETURN_OP State=%p, RetVal=%p\n",
1538 WalkState
, WalkState
->ReturnDesc
));
1540 /* End the control method execution right now */
1542 Status
= AE_CTRL_TERMINATE
;
1548 /* Just do nothing! */
1552 case AML_BREAK_POINT_OP
:
1555 * Set the single-step flag. This will cause the debugger (if present)
1556 * to break to the console within the AML debugger at the start of the
1557 * next AML instruction.
1559 ACPI_DEBUGGER_EXEC (
1560 AcpiGbl_CmSingleStep
= TRUE
);
1561 ACPI_DEBUGGER_EXEC (
1562 AcpiOsPrintf ("**break** Executed AML BreakPoint opcode\n"));
1564 /* Call to the OSL in case OS wants a piece of the action */
1566 Status
= AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT
,
1567 "Executed AML Breakpoint opcode");
1572 case AML_CONTINUE_OP
: /* ACPI 2.0 */
1575 /* Pop and delete control states until we find a while */
1577 while (WalkState
->ControlState
&&
1578 (WalkState
->ControlState
->Control
.Opcode
!= AML_WHILE_OP
))
1580 ControlState
= AcpiUtPopGenericState (&WalkState
->ControlState
);
1581 AcpiUtDeleteGenericState (ControlState
);
1584 /* No while found? */
1586 if (!WalkState
->ControlState
)
1588 return (AE_AML_NO_WHILE
);
1591 /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */
1593 WalkState
->AmlLastWhile
= WalkState
->ControlState
->Control
.PackageEnd
;
1595 /* Return status depending on opcode */
1597 if (Op
->Common
.AmlOpcode
== AML_BREAK_OP
)
1599 Status
= AE_CTRL_BREAK
;
1603 Status
= AE_CTRL_CONTINUE
;
1610 ACPI_ERROR ((AE_INFO
, "Unknown control opcode=0x%X Op=%p",
1611 Op
->Common
.AmlOpcode
, Op
));
1613 Status
= AE_AML_BAD_OPCODE
;