2 /******************************************************************************
4 * Module Name: exresop - AML Interpreter operand/object resolution
6 *****************************************************************************/
9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
47 #include <contrib/dev/acpica/include/acpi.h>
48 #include <contrib/dev/acpica/include/accommon.h>
49 #include <contrib/dev/acpica/include/amlcode.h>
50 #include <contrib/dev/acpica/include/acparser.h>
51 #include <contrib/dev/acpica/include/acinterp.h>
52 #include <contrib/dev/acpica/include/acnamesp.h>
55 #define _COMPONENT ACPI_EXECUTER
56 ACPI_MODULE_NAME ("exresop")
58 /* Local prototypes */
61 AcpiExCheckObjectType (
62 ACPI_OBJECT_TYPE TypeNeeded,
63 ACPI_OBJECT_TYPE ThisType,
67 /*******************************************************************************
69 * FUNCTION: AcpiExCheckObjectType
71 * PARAMETERS: TypeNeeded Object type needed
72 * ThisType Actual object type
73 * Object Object pointer
77 * DESCRIPTION: Check required type against actual type
79 ******************************************************************************/
82 AcpiExCheckObjectType (
83 ACPI_OBJECT_TYPE TypeNeeded,
84 ACPI_OBJECT_TYPE ThisType,
87 ACPI_FUNCTION_ENTRY ();
90 if (TypeNeeded == ACPI_TYPE_ANY)
92 /* All types OK, so we don't perform any typechecks */
97 if (TypeNeeded == ACPI_TYPE_LOCAL_REFERENCE)
100 * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference
101 * objects and thus allow them to be targets. (As per the ACPI
102 * specification, a store to a constant is a noop.)
104 if ((ThisType == ACPI_TYPE_INTEGER) &&
105 (((ACPI_OPERAND_OBJECT *) Object)->Common.Flags & AOPOBJ_AML_CONSTANT))
111 if (TypeNeeded != ThisType)
113 ACPI_ERROR ((AE_INFO,
114 "Needed type [%s], found [%s] %p",
115 AcpiUtGetTypeName (TypeNeeded),
116 AcpiUtGetTypeName (ThisType), Object));
118 return (AE_AML_OPERAND_TYPE);
125 /*******************************************************************************
127 * FUNCTION: AcpiExResolveOperands
129 * PARAMETERS: Opcode - Opcode being interpreted
130 * StackPtr - Pointer to the operand stack to be
132 * WalkState - Current state
136 * DESCRIPTION: Convert multiple input operands to the types required by the
139 * Each 5-bit group in ArgTypes represents one required
140 * operand and indicates the required Type. The corresponding operand
141 * will be converted to the required type if possible, otherwise we
142 * abort with an exception.
144 ******************************************************************************/
147 AcpiExResolveOperands (
149 ACPI_OPERAND_OBJECT **StackPtr,
150 ACPI_WALK_STATE *WalkState)
152 ACPI_OPERAND_OBJECT *ObjDesc;
153 ACPI_STATUS Status = AE_OK;
156 const ACPI_OPCODE_INFO *OpInfo;
158 ACPI_OBJECT_TYPE TypeNeeded;
162 ACPI_FUNCTION_TRACE_U32 (ExResolveOperands, Opcode);
165 OpInfo = AcpiPsGetOpcodeInfo (Opcode);
166 if (OpInfo->Class == AML_CLASS_UNKNOWN)
168 return_ACPI_STATUS (AE_AML_BAD_OPCODE);
171 ArgTypes = OpInfo->RuntimeArgs;
172 if (ArgTypes == ARGI_INVALID_OPCODE)
174 ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
177 return_ACPI_STATUS (AE_AML_INTERNAL);
180 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
181 "Opcode %X [%s] RequiredOperandTypes=%8.8X\n",
182 Opcode, OpInfo->Name, ArgTypes));
185 * Normal exit is with (ArgTypes == 0) at end of argument list.
186 * Function will return an exception from within the loop upon
187 * finding an entry which is not (or cannot be converted
188 * to) the required type; if stack underflows; or upon
189 * finding a NULL stack entry (which should not happen).
191 while (GET_CURRENT_ARG_TYPE (ArgTypes))
193 if (!StackPtr || !*StackPtr)
195 ACPI_ERROR ((AE_INFO, "Null stack entry at %p",
198 return_ACPI_STATUS (AE_AML_INTERNAL);
201 /* Extract useful items */
205 /* Decode the descriptor type */
207 switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
209 case ACPI_DESC_TYPE_NAMED:
213 ObjectType = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
216 * Resolve an alias object. The construction of these objects
217 * guarantees that there is only one level of alias indirection;
218 * thus, the attached object is always the aliased namespace node
220 if (ObjectType == ACPI_TYPE_LOCAL_ALIAS)
222 ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjDesc);
224 ObjectType = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
229 case ACPI_DESC_TYPE_OPERAND:
231 /* ACPI internal object */
233 ObjectType = ObjDesc->Common.Type;
235 /* Check for bad ACPI_OBJECT_TYPE */
237 if (!AcpiUtValidObjectType (ObjectType))
239 ACPI_ERROR ((AE_INFO,
240 "Bad operand object type [0x%X]", ObjectType));
242 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
245 if (ObjectType == (UINT8) ACPI_TYPE_LOCAL_REFERENCE)
247 /* Validate the Reference */
249 switch (ObjDesc->Reference.Class)
251 case ACPI_REFCLASS_DEBUG:
253 TargetOp = AML_DEBUG_OP;
255 /*lint -fallthrough */
257 case ACPI_REFCLASS_ARG:
258 case ACPI_REFCLASS_LOCAL:
259 case ACPI_REFCLASS_INDEX:
260 case ACPI_REFCLASS_REFOF:
261 case ACPI_REFCLASS_TABLE: /* DdbHandle from LOAD_OP or LOAD_TABLE_OP */
262 case ACPI_REFCLASS_NAME: /* Reference to a named object */
264 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
265 "Operand is a Reference, Class [%s] %2.2X\n",
266 AcpiUtGetReferenceName (ObjDesc),
267 ObjDesc->Reference.Class));
272 ACPI_ERROR ((AE_INFO,
273 "Unknown Reference Class 0x%2.2X in %p",
274 ObjDesc->Reference.Class, ObjDesc));
276 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
284 /* Invalid descriptor */
286 ACPI_ERROR ((AE_INFO, "Invalid descriptor %p [%s]",
287 ObjDesc, AcpiUtGetDescriptorName (ObjDesc)));
289 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
292 /* Get one argument type, point to the next */
294 ThisArgType = GET_CURRENT_ARG_TYPE (ArgTypes);
295 INCREMENT_ARG_LIST (ArgTypes);
298 * Handle cases where the object does not need to be
299 * resolved to a value
303 case ARGI_REF_OR_STRING: /* Can be a String or Reference */
305 if ((ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND) &&
306 (ObjDesc->Common.Type == ACPI_TYPE_STRING))
309 * String found - the string references a named object and
310 * must be resolved to a node
316 * Else not a string - fall through to the normal Reference
319 /*lint -fallthrough */
321 case ARGI_REFERENCE: /* References: */
322 case ARGI_INTEGER_REF:
323 case ARGI_OBJECT_REF:
324 case ARGI_DEVICE_REF:
325 case ARGI_TARGETREF: /* Allows implicit conversion rules before store */
326 case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */
327 case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion */
330 * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
331 * A Namespace Node is OK as-is
333 if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_NAMED)
338 Status = AcpiExCheckObjectType (ACPI_TYPE_LOCAL_REFERENCE,
339 ObjectType, ObjDesc);
340 if (ACPI_FAILURE (Status))
342 return_ACPI_STATUS (Status);
347 case ARGI_DATAREFOBJ: /* Store operator only */
350 * We don't want to resolve IndexOp reference objects during
351 * a store because this would be an implicit DeRefOf operation.
352 * Instead, we just want to store the reference object.
353 * -- All others must be resolved below.
355 if ((Opcode == AML_STORE_OP) &&
356 ((*StackPtr)->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
357 ((*StackPtr)->Reference.Class == ACPI_REFCLASS_INDEX))
364 /* All cases covered above */
369 * Resolve this object to a value
371 Status = AcpiExResolveToValue (StackPtr, WalkState);
372 if (ACPI_FAILURE (Status))
374 return_ACPI_STATUS (Status);
377 /* Get the resolved object */
382 * Check the resulting object (value) type
387 * For the simple cases, only one type of resolved object
392 /* Need an operand of type ACPI_TYPE_MUTEX */
394 TypeNeeded = ACPI_TYPE_MUTEX;
399 /* Need an operand of type ACPI_TYPE_EVENT */
401 TypeNeeded = ACPI_TYPE_EVENT;
404 case ARGI_PACKAGE: /* Package */
406 /* Need an operand of type ACPI_TYPE_PACKAGE */
408 TypeNeeded = ACPI_TYPE_PACKAGE;
413 /* Any operand type will do */
415 TypeNeeded = ACPI_TYPE_ANY;
420 /* Need an operand of type ACPI_TYPE_DDB_HANDLE */
422 TypeNeeded = ACPI_TYPE_LOCAL_REFERENCE;
427 * The more complex cases allow multiple resolved object types
432 * Need an operand of type ACPI_TYPE_INTEGER,
433 * But we can implicitly convert from a STRING or BUFFER
434 * Aka - "Implicit Source Operand Conversion"
436 Status = AcpiExConvertToInteger (ObjDesc, StackPtr, 16);
437 if (ACPI_FAILURE (Status))
439 if (Status == AE_TYPE)
441 ACPI_ERROR ((AE_INFO,
442 "Needed [Integer/String/Buffer], found [%s] %p",
443 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
445 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
448 return_ACPI_STATUS (Status);
451 if (ObjDesc != *StackPtr)
453 AcpiUtRemoveReference (ObjDesc);
461 * Need an operand of type ACPI_TYPE_BUFFER,
462 * But we can implicitly convert from a STRING or INTEGER
463 * Aka - "Implicit Source Operand Conversion"
465 Status = AcpiExConvertToBuffer (ObjDesc, StackPtr);
466 if (ACPI_FAILURE (Status))
468 if (Status == AE_TYPE)
470 ACPI_ERROR ((AE_INFO,
471 "Needed [Integer/String/Buffer], found [%s] %p",
472 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
474 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
477 return_ACPI_STATUS (Status);
480 if (ObjDesc != *StackPtr)
482 AcpiUtRemoveReference (ObjDesc);
490 * Need an operand of type ACPI_TYPE_STRING,
491 * But we can implicitly convert from a BUFFER or INTEGER
492 * Aka - "Implicit Source Operand Conversion"
494 Status = AcpiExConvertToString (ObjDesc, StackPtr,
495 ACPI_IMPLICIT_CONVERT_HEX);
496 if (ACPI_FAILURE (Status))
498 if (Status == AE_TYPE)
500 ACPI_ERROR ((AE_INFO,
501 "Needed [Integer/String/Buffer], found [%s] %p",
502 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
504 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
507 return_ACPI_STATUS (Status);
510 if (ObjDesc != *StackPtr)
512 AcpiUtRemoveReference (ObjDesc);
517 case ARGI_COMPUTEDATA:
519 /* Need an operand of type INTEGER, STRING or BUFFER */
521 switch (ObjDesc->Common.Type)
523 case ACPI_TYPE_INTEGER:
524 case ACPI_TYPE_STRING:
525 case ACPI_TYPE_BUFFER:
531 ACPI_ERROR ((AE_INFO,
532 "Needed [Integer/String/Buffer], found [%s] %p",
533 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
535 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
540 case ARGI_BUFFER_OR_STRING:
542 /* Need an operand of type STRING or BUFFER */
544 switch (ObjDesc->Common.Type)
546 case ACPI_TYPE_STRING:
547 case ACPI_TYPE_BUFFER:
552 case ACPI_TYPE_INTEGER:
554 /* Highest priority conversion is to type Buffer */
556 Status = AcpiExConvertToBuffer (ObjDesc, StackPtr);
557 if (ACPI_FAILURE (Status))
559 return_ACPI_STATUS (Status);
562 if (ObjDesc != *StackPtr)
564 AcpiUtRemoveReference (ObjDesc);
569 ACPI_ERROR ((AE_INFO,
570 "Needed [Integer/String/Buffer], found [%s] %p",
571 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
573 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
578 case ARGI_DATAOBJECT:
580 * ARGI_DATAOBJECT is only used by the SizeOf operator.
581 * Need a buffer, string, package, or RefOf reference.
583 * The only reference allowed here is a direct reference to
586 switch (ObjDesc->Common.Type)
588 case ACPI_TYPE_PACKAGE:
589 case ACPI_TYPE_STRING:
590 case ACPI_TYPE_BUFFER:
591 case ACPI_TYPE_LOCAL_REFERENCE:
597 ACPI_ERROR ((AE_INFO,
598 "Needed [Buffer/String/Package/Reference], found [%s] %p",
599 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
601 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
606 case ARGI_COMPLEXOBJ:
608 /* Need a buffer or package or (ACPI 2.0) String */
610 switch (ObjDesc->Common.Type)
612 case ACPI_TYPE_PACKAGE:
613 case ACPI_TYPE_STRING:
614 case ACPI_TYPE_BUFFER:
620 ACPI_ERROR ((AE_INFO,
621 "Needed [Buffer/String/Package], found [%s] %p",
622 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
624 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
629 case ARGI_REGION_OR_BUFFER: /* Used by Load() only */
631 /* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */
633 switch (ObjDesc->Common.Type)
635 case ACPI_TYPE_BUFFER:
636 case ACPI_TYPE_REGION:
642 ACPI_ERROR ((AE_INFO,
643 "Needed [Region/Buffer], found [%s] %p",
644 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
646 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
651 case ARGI_DATAREFOBJ:
653 /* Used by the Store() operator only */
655 switch (ObjDesc->Common.Type)
657 case ACPI_TYPE_INTEGER:
658 case ACPI_TYPE_PACKAGE:
659 case ACPI_TYPE_STRING:
660 case ACPI_TYPE_BUFFER:
661 case ACPI_TYPE_BUFFER_FIELD:
662 case ACPI_TYPE_LOCAL_REFERENCE:
663 case ACPI_TYPE_LOCAL_REGION_FIELD:
664 case ACPI_TYPE_LOCAL_BANK_FIELD:
665 case ACPI_TYPE_LOCAL_INDEX_FIELD:
666 case ACPI_TYPE_DDB_HANDLE:
673 if (AcpiGbl_EnableInterpreterSlack)
676 * Enable original behavior of Store(), allowing any and all
677 * objects as the source operand. The ACPI spec does not
678 * allow this, however.
683 if (TargetOp == AML_DEBUG_OP)
685 /* Allow store of any object to the Debug object */
690 ACPI_ERROR ((AE_INFO,
691 "Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p",
692 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
694 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
703 ACPI_ERROR ((AE_INFO,
704 "Internal - Unknown ARGI (required operand) type 0x%X",
707 return_ACPI_STATUS (AE_BAD_PARAMETER);
711 * Make sure that the original object was resolved to the
712 * required object type (Simple cases only).
714 Status = AcpiExCheckObjectType (TypeNeeded,
715 (*StackPtr)->Common.Type, *StackPtr);
716 if (ACPI_FAILURE (Status))
718 return_ACPI_STATUS (Status);
723 * If more operands needed, decrement StackPtr to point
724 * to next operand on stack
726 if (GET_CURRENT_ARG_TYPE (ArgTypes))
732 ACPI_DUMP_OPERANDS (WalkState->Operands,
733 AcpiPsGetOpcodeName (Opcode), WalkState->NumOperands);
735 return_ACPI_STATUS (Status);