162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 262306a36Sopenharmony_ci/****************************************************************************** 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Module Name: exresop - AML Interpreter operand/object resolution 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 2000 - 2023, Intel Corp. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci *****************************************************************************/ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <acpi/acpi.h> 1162306a36Sopenharmony_ci#include "accommon.h" 1262306a36Sopenharmony_ci#include "amlcode.h" 1362306a36Sopenharmony_ci#include "acparser.h" 1462306a36Sopenharmony_ci#include "acinterp.h" 1562306a36Sopenharmony_ci#include "acnamesp.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#define _COMPONENT ACPI_EXECUTER 1862306a36Sopenharmony_ciACPI_MODULE_NAME("exresop") 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci/* Local prototypes */ 2162306a36Sopenharmony_cistatic acpi_status 2262306a36Sopenharmony_ciacpi_ex_check_object_type(acpi_object_type type_needed, 2362306a36Sopenharmony_ci acpi_object_type this_type, void *object); 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/******************************************************************************* 2662306a36Sopenharmony_ci * 2762306a36Sopenharmony_ci * FUNCTION: acpi_ex_check_object_type 2862306a36Sopenharmony_ci * 2962306a36Sopenharmony_ci * PARAMETERS: type_needed Object type needed 3062306a36Sopenharmony_ci * this_type Actual object type 3162306a36Sopenharmony_ci * Object Object pointer 3262306a36Sopenharmony_ci * 3362306a36Sopenharmony_ci * RETURN: Status 3462306a36Sopenharmony_ci * 3562306a36Sopenharmony_ci * DESCRIPTION: Check required type against actual type 3662306a36Sopenharmony_ci * 3762306a36Sopenharmony_ci ******************************************************************************/ 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic acpi_status 4062306a36Sopenharmony_ciacpi_ex_check_object_type(acpi_object_type type_needed, 4162306a36Sopenharmony_ci acpi_object_type this_type, void *object) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci ACPI_FUNCTION_ENTRY(); 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci if (type_needed == ACPI_TYPE_ANY) { 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci /* All types OK, so we don't perform any typechecks */ 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci return (AE_OK); 5062306a36Sopenharmony_ci } 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci if (type_needed == ACPI_TYPE_LOCAL_REFERENCE) { 5362306a36Sopenharmony_ci /* 5462306a36Sopenharmony_ci * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference 5562306a36Sopenharmony_ci * objects and thus allow them to be targets. (As per the ACPI 5662306a36Sopenharmony_ci * specification, a store to a constant is a noop.) 5762306a36Sopenharmony_ci */ 5862306a36Sopenharmony_ci if ((this_type == ACPI_TYPE_INTEGER) && 5962306a36Sopenharmony_ci (((union acpi_operand_object *)object)->common.flags & 6062306a36Sopenharmony_ci AOPOBJ_AML_CONSTANT)) { 6162306a36Sopenharmony_ci return (AE_OK); 6262306a36Sopenharmony_ci } 6362306a36Sopenharmony_ci } 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci if (type_needed != this_type) { 6662306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 6762306a36Sopenharmony_ci "Needed type [%s], found [%s] %p", 6862306a36Sopenharmony_ci acpi_ut_get_type_name(type_needed), 6962306a36Sopenharmony_ci acpi_ut_get_type_name(this_type), object)); 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci return (AE_AML_OPERAND_TYPE); 7262306a36Sopenharmony_ci } 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci return (AE_OK); 7562306a36Sopenharmony_ci} 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci/******************************************************************************* 7862306a36Sopenharmony_ci * 7962306a36Sopenharmony_ci * FUNCTION: acpi_ex_resolve_operands 8062306a36Sopenharmony_ci * 8162306a36Sopenharmony_ci * PARAMETERS: opcode - Opcode being interpreted 8262306a36Sopenharmony_ci * stack_ptr - Pointer to the operand stack to be 8362306a36Sopenharmony_ci * resolved 8462306a36Sopenharmony_ci * walk_state - Current state 8562306a36Sopenharmony_ci * 8662306a36Sopenharmony_ci * RETURN: Status 8762306a36Sopenharmony_ci * 8862306a36Sopenharmony_ci * DESCRIPTION: Convert multiple input operands to the types required by the 8962306a36Sopenharmony_ci * target operator. 9062306a36Sopenharmony_ci * 9162306a36Sopenharmony_ci * Each 5-bit group in arg_types represents one required 9262306a36Sopenharmony_ci * operand and indicates the required Type. The corresponding operand 9362306a36Sopenharmony_ci * will be converted to the required type if possible, otherwise we 9462306a36Sopenharmony_ci * abort with an exception. 9562306a36Sopenharmony_ci * 9662306a36Sopenharmony_ci ******************************************************************************/ 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ciacpi_status 9962306a36Sopenharmony_ciacpi_ex_resolve_operands(u16 opcode, 10062306a36Sopenharmony_ci union acpi_operand_object **stack_ptr, 10162306a36Sopenharmony_ci struct acpi_walk_state *walk_state) 10262306a36Sopenharmony_ci{ 10362306a36Sopenharmony_ci union acpi_operand_object *obj_desc; 10462306a36Sopenharmony_ci acpi_status status = AE_OK; 10562306a36Sopenharmony_ci u8 object_type; 10662306a36Sopenharmony_ci u32 arg_types; 10762306a36Sopenharmony_ci const struct acpi_opcode_info *op_info; 10862306a36Sopenharmony_ci u32 this_arg_type; 10962306a36Sopenharmony_ci acpi_object_type type_needed; 11062306a36Sopenharmony_ci u16 target_op = 0; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci ACPI_FUNCTION_TRACE_U32(ex_resolve_operands, opcode); 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci op_info = acpi_ps_get_opcode_info(opcode); 11562306a36Sopenharmony_ci if (op_info->class == AML_CLASS_UNKNOWN) { 11662306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_BAD_OPCODE); 11762306a36Sopenharmony_ci } 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci arg_types = op_info->runtime_args; 12062306a36Sopenharmony_ci if (arg_types == ARGI_INVALID_OPCODE) { 12162306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X", opcode)); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_INTERNAL); 12462306a36Sopenharmony_ci } 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 12762306a36Sopenharmony_ci "Opcode %X [%s] RequiredOperandTypes=%8.8X\n", 12862306a36Sopenharmony_ci opcode, op_info->name, arg_types)); 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci /* 13162306a36Sopenharmony_ci * Normal exit is with (arg_types == 0) at end of argument list. 13262306a36Sopenharmony_ci * Function will return an exception from within the loop upon 13362306a36Sopenharmony_ci * finding an entry which is not (or cannot be converted 13462306a36Sopenharmony_ci * to) the required type; if stack underflows; or upon 13562306a36Sopenharmony_ci * finding a NULL stack entry (which should not happen). 13662306a36Sopenharmony_ci */ 13762306a36Sopenharmony_ci while (GET_CURRENT_ARG_TYPE(arg_types)) { 13862306a36Sopenharmony_ci if (!stack_ptr || !*stack_ptr) { 13962306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, "Null stack entry at %p", 14062306a36Sopenharmony_ci stack_ptr)); 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_INTERNAL); 14362306a36Sopenharmony_ci } 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci /* Extract useful items */ 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci obj_desc = *stack_ptr; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci /* Decode the descriptor type */ 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) { 15262306a36Sopenharmony_ci case ACPI_DESC_TYPE_NAMED: 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci /* Namespace Node */ 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci object_type = 15762306a36Sopenharmony_ci ((struct acpi_namespace_node *)obj_desc)->type; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci /* 16062306a36Sopenharmony_ci * Resolve an alias object. The construction of these objects 16162306a36Sopenharmony_ci * guarantees that there is only one level of alias indirection; 16262306a36Sopenharmony_ci * thus, the attached object is always the aliased namespace node 16362306a36Sopenharmony_ci */ 16462306a36Sopenharmony_ci if (object_type == ACPI_TYPE_LOCAL_ALIAS) { 16562306a36Sopenharmony_ci obj_desc = acpi_ns_get_attached_object((struct 16662306a36Sopenharmony_ci acpi_namespace_node 16762306a36Sopenharmony_ci *) 16862306a36Sopenharmony_ci obj_desc); 16962306a36Sopenharmony_ci *stack_ptr = obj_desc; 17062306a36Sopenharmony_ci object_type = 17162306a36Sopenharmony_ci ((struct acpi_namespace_node *)obj_desc)-> 17262306a36Sopenharmony_ci type; 17362306a36Sopenharmony_ci } 17462306a36Sopenharmony_ci break; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci case ACPI_DESC_TYPE_OPERAND: 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci /* ACPI internal object */ 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci object_type = obj_desc->common.type; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci /* Check for bad acpi_object_type */ 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci if (!acpi_ut_valid_object_type(object_type)) { 18562306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 18662306a36Sopenharmony_ci "Bad operand object type [0x%X]", 18762306a36Sopenharmony_ci object_type)); 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 19062306a36Sopenharmony_ci } 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) { 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci /* Validate the Reference */ 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci switch (obj_desc->reference.class) { 19762306a36Sopenharmony_ci case ACPI_REFCLASS_DEBUG: 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci target_op = AML_DEBUG_OP; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci ACPI_FALLTHROUGH; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci case ACPI_REFCLASS_ARG: 20462306a36Sopenharmony_ci case ACPI_REFCLASS_LOCAL: 20562306a36Sopenharmony_ci case ACPI_REFCLASS_INDEX: 20662306a36Sopenharmony_ci case ACPI_REFCLASS_REFOF: 20762306a36Sopenharmony_ci case ACPI_REFCLASS_TABLE: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */ 20862306a36Sopenharmony_ci case ACPI_REFCLASS_NAME: /* Reference to a named object */ 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 21162306a36Sopenharmony_ci "Operand is a Reference, Class [%s] %2.2X\n", 21262306a36Sopenharmony_ci acpi_ut_get_reference_name 21362306a36Sopenharmony_ci (obj_desc), 21462306a36Sopenharmony_ci obj_desc->reference. 21562306a36Sopenharmony_ci class)); 21662306a36Sopenharmony_ci break; 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci default: 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 22162306a36Sopenharmony_ci "Unknown Reference Class 0x%2.2X in %p", 22262306a36Sopenharmony_ci obj_desc->reference.class, 22362306a36Sopenharmony_ci obj_desc)); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 22662306a36Sopenharmony_ci } 22762306a36Sopenharmony_ci } 22862306a36Sopenharmony_ci break; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci default: 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci /* Invalid descriptor */ 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, "Invalid descriptor %p [%s]", 23562306a36Sopenharmony_ci obj_desc, 23662306a36Sopenharmony_ci acpi_ut_get_descriptor_name(obj_desc))); 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 23962306a36Sopenharmony_ci } 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci /* Get one argument type, point to the next */ 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci this_arg_type = GET_CURRENT_ARG_TYPE(arg_types); 24462306a36Sopenharmony_ci INCREMENT_ARG_LIST(arg_types); 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci /* 24762306a36Sopenharmony_ci * Handle cases where the object does not need to be 24862306a36Sopenharmony_ci * resolved to a value 24962306a36Sopenharmony_ci */ 25062306a36Sopenharmony_ci switch (this_arg_type) { 25162306a36Sopenharmony_ci case ARGI_REF_OR_STRING: /* Can be a String or Reference */ 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == 25462306a36Sopenharmony_ci ACPI_DESC_TYPE_OPERAND) && 25562306a36Sopenharmony_ci (obj_desc->common.type == ACPI_TYPE_STRING)) { 25662306a36Sopenharmony_ci /* 25762306a36Sopenharmony_ci * String found - the string references a named object and 25862306a36Sopenharmony_ci * must be resolved to a node 25962306a36Sopenharmony_ci */ 26062306a36Sopenharmony_ci goto next_operand; 26162306a36Sopenharmony_ci } 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci /* 26462306a36Sopenharmony_ci * Else not a string - fall through to the normal Reference 26562306a36Sopenharmony_ci * case below 26662306a36Sopenharmony_ci */ 26762306a36Sopenharmony_ci ACPI_FALLTHROUGH; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci case ARGI_REFERENCE: /* References: */ 27062306a36Sopenharmony_ci case ARGI_INTEGER_REF: 27162306a36Sopenharmony_ci case ARGI_OBJECT_REF: 27262306a36Sopenharmony_ci case ARGI_DEVICE_REF: 27362306a36Sopenharmony_ci case ARGI_TARGETREF: /* Allows implicit conversion rules before store */ 27462306a36Sopenharmony_ci case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */ 27562306a36Sopenharmony_ci case ARGI_SIMPLE_TARGET: /* Name, Local, or arg - no implicit conversion */ 27662306a36Sopenharmony_ci case ARGI_STORE_TARGET: 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci /* 27962306a36Sopenharmony_ci * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE 28062306a36Sopenharmony_ci * A Namespace Node is OK as-is 28162306a36Sopenharmony_ci */ 28262306a36Sopenharmony_ci if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == 28362306a36Sopenharmony_ci ACPI_DESC_TYPE_NAMED) { 28462306a36Sopenharmony_ci goto next_operand; 28562306a36Sopenharmony_ci } 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci status = 28862306a36Sopenharmony_ci acpi_ex_check_object_type(ACPI_TYPE_LOCAL_REFERENCE, 28962306a36Sopenharmony_ci object_type, obj_desc); 29062306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 29162306a36Sopenharmony_ci return_ACPI_STATUS(status); 29262306a36Sopenharmony_ci } 29362306a36Sopenharmony_ci goto next_operand; 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci case ARGI_DATAREFOBJ: /* Store operator only */ 29662306a36Sopenharmony_ci /* 29762306a36Sopenharmony_ci * We don't want to resolve index_op reference objects during 29862306a36Sopenharmony_ci * a store because this would be an implicit de_ref_of operation. 29962306a36Sopenharmony_ci * Instead, we just want to store the reference object. 30062306a36Sopenharmony_ci * -- All others must be resolved below. 30162306a36Sopenharmony_ci */ 30262306a36Sopenharmony_ci if ((opcode == AML_STORE_OP) && 30362306a36Sopenharmony_ci ((*stack_ptr)->common.type == 30462306a36Sopenharmony_ci ACPI_TYPE_LOCAL_REFERENCE) 30562306a36Sopenharmony_ci && ((*stack_ptr)->reference.class == 30662306a36Sopenharmony_ci ACPI_REFCLASS_INDEX)) { 30762306a36Sopenharmony_ci goto next_operand; 30862306a36Sopenharmony_ci } 30962306a36Sopenharmony_ci break; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci default: 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci /* All cases covered above */ 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci break; 31662306a36Sopenharmony_ci } 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci /* 31962306a36Sopenharmony_ci * Resolve this object to a value 32062306a36Sopenharmony_ci */ 32162306a36Sopenharmony_ci status = acpi_ex_resolve_to_value(stack_ptr, walk_state); 32262306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 32362306a36Sopenharmony_ci return_ACPI_STATUS(status); 32462306a36Sopenharmony_ci } 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci /* Get the resolved object */ 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci obj_desc = *stack_ptr; 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci /* 33162306a36Sopenharmony_ci * Check the resulting object (value) type 33262306a36Sopenharmony_ci */ 33362306a36Sopenharmony_ci switch (this_arg_type) { 33462306a36Sopenharmony_ci /* 33562306a36Sopenharmony_ci * For the simple cases, only one type of resolved object 33662306a36Sopenharmony_ci * is allowed 33762306a36Sopenharmony_ci */ 33862306a36Sopenharmony_ci case ARGI_MUTEX: 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci /* Need an operand of type ACPI_TYPE_MUTEX */ 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci type_needed = ACPI_TYPE_MUTEX; 34362306a36Sopenharmony_ci break; 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci case ARGI_EVENT: 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci /* Need an operand of type ACPI_TYPE_EVENT */ 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci type_needed = ACPI_TYPE_EVENT; 35062306a36Sopenharmony_ci break; 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci case ARGI_PACKAGE: /* Package */ 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci /* Need an operand of type ACPI_TYPE_PACKAGE */ 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ci type_needed = ACPI_TYPE_PACKAGE; 35762306a36Sopenharmony_ci break; 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci case ARGI_ANYTYPE: 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci /* Any operand type will do */ 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci type_needed = ACPI_TYPE_ANY; 36462306a36Sopenharmony_ci break; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci case ARGI_DDBHANDLE: 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci /* Need an operand of type ACPI_TYPE_DDB_HANDLE */ 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci type_needed = ACPI_TYPE_LOCAL_REFERENCE; 37162306a36Sopenharmony_ci break; 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci /* 37462306a36Sopenharmony_ci * The more complex cases allow multiple resolved object types 37562306a36Sopenharmony_ci */ 37662306a36Sopenharmony_ci case ARGI_INTEGER: 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci /* 37962306a36Sopenharmony_ci * Need an operand of type ACPI_TYPE_INTEGER, but we can 38062306a36Sopenharmony_ci * implicitly convert from a STRING or BUFFER. 38162306a36Sopenharmony_ci * 38262306a36Sopenharmony_ci * Known as "Implicit Source Operand Conversion" 38362306a36Sopenharmony_ci */ 38462306a36Sopenharmony_ci status = acpi_ex_convert_to_integer(obj_desc, stack_ptr, 38562306a36Sopenharmony_ci ACPI_IMPLICIT_CONVERSION); 38662306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 38762306a36Sopenharmony_ci if (status == AE_TYPE) { 38862306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 38962306a36Sopenharmony_ci "Needed [Integer/String/Buffer], found [%s] %p", 39062306a36Sopenharmony_ci acpi_ut_get_object_type_name 39162306a36Sopenharmony_ci (obj_desc), obj_desc)); 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 39462306a36Sopenharmony_ci } 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci return_ACPI_STATUS(status); 39762306a36Sopenharmony_ci } 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci if (obj_desc != *stack_ptr) { 40062306a36Sopenharmony_ci acpi_ut_remove_reference(obj_desc); 40162306a36Sopenharmony_ci } 40262306a36Sopenharmony_ci goto next_operand; 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci case ARGI_BUFFER: 40562306a36Sopenharmony_ci /* 40662306a36Sopenharmony_ci * Need an operand of type ACPI_TYPE_BUFFER, 40762306a36Sopenharmony_ci * But we can implicitly convert from a STRING or INTEGER 40862306a36Sopenharmony_ci * aka - "Implicit Source Operand Conversion" 40962306a36Sopenharmony_ci */ 41062306a36Sopenharmony_ci status = acpi_ex_convert_to_buffer(obj_desc, stack_ptr); 41162306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 41262306a36Sopenharmony_ci if (status == AE_TYPE) { 41362306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 41462306a36Sopenharmony_ci "Needed [Integer/String/Buffer], found [%s] %p", 41562306a36Sopenharmony_ci acpi_ut_get_object_type_name 41662306a36Sopenharmony_ci (obj_desc), obj_desc)); 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 41962306a36Sopenharmony_ci } 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci return_ACPI_STATUS(status); 42262306a36Sopenharmony_ci } 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci if (obj_desc != *stack_ptr) { 42562306a36Sopenharmony_ci acpi_ut_remove_reference(obj_desc); 42662306a36Sopenharmony_ci } 42762306a36Sopenharmony_ci goto next_operand; 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci case ARGI_STRING: 43062306a36Sopenharmony_ci /* 43162306a36Sopenharmony_ci * Need an operand of type ACPI_TYPE_STRING, 43262306a36Sopenharmony_ci * But we can implicitly convert from a BUFFER or INTEGER 43362306a36Sopenharmony_ci * aka - "Implicit Source Operand Conversion" 43462306a36Sopenharmony_ci */ 43562306a36Sopenharmony_ci status = 43662306a36Sopenharmony_ci acpi_ex_convert_to_string(obj_desc, stack_ptr, 43762306a36Sopenharmony_ci ACPI_IMPLICIT_CONVERT_HEX); 43862306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 43962306a36Sopenharmony_ci if (status == AE_TYPE) { 44062306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 44162306a36Sopenharmony_ci "Needed [Integer/String/Buffer], found [%s] %p", 44262306a36Sopenharmony_ci acpi_ut_get_object_type_name 44362306a36Sopenharmony_ci (obj_desc), obj_desc)); 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 44662306a36Sopenharmony_ci } 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci return_ACPI_STATUS(status); 44962306a36Sopenharmony_ci } 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci if (obj_desc != *stack_ptr) { 45262306a36Sopenharmony_ci acpi_ut_remove_reference(obj_desc); 45362306a36Sopenharmony_ci } 45462306a36Sopenharmony_ci goto next_operand; 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci case ARGI_COMPUTEDATA: 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci /* Need an operand of type INTEGER, STRING or BUFFER */ 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci switch (obj_desc->common.type) { 46162306a36Sopenharmony_ci case ACPI_TYPE_INTEGER: 46262306a36Sopenharmony_ci case ACPI_TYPE_STRING: 46362306a36Sopenharmony_ci case ACPI_TYPE_BUFFER: 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci /* Valid operand */ 46662306a36Sopenharmony_ci break; 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci default: 46962306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 47062306a36Sopenharmony_ci "Needed [Integer/String/Buffer], found [%s] %p", 47162306a36Sopenharmony_ci acpi_ut_get_object_type_name 47262306a36Sopenharmony_ci (obj_desc), obj_desc)); 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 47562306a36Sopenharmony_ci } 47662306a36Sopenharmony_ci goto next_operand; 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci case ARGI_BUFFER_OR_STRING: 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci /* Need an operand of type STRING or BUFFER */ 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_ci switch (obj_desc->common.type) { 48362306a36Sopenharmony_ci case ACPI_TYPE_STRING: 48462306a36Sopenharmony_ci case ACPI_TYPE_BUFFER: 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci /* Valid operand */ 48762306a36Sopenharmony_ci break; 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci case ACPI_TYPE_INTEGER: 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci /* Highest priority conversion is to type Buffer */ 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_ci status = 49462306a36Sopenharmony_ci acpi_ex_convert_to_buffer(obj_desc, 49562306a36Sopenharmony_ci stack_ptr); 49662306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 49762306a36Sopenharmony_ci return_ACPI_STATUS(status); 49862306a36Sopenharmony_ci } 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_ci if (obj_desc != *stack_ptr) { 50162306a36Sopenharmony_ci acpi_ut_remove_reference(obj_desc); 50262306a36Sopenharmony_ci } 50362306a36Sopenharmony_ci break; 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci default: 50662306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 50762306a36Sopenharmony_ci "Needed [Integer/String/Buffer], found [%s] %p", 50862306a36Sopenharmony_ci acpi_ut_get_object_type_name 50962306a36Sopenharmony_ci (obj_desc), obj_desc)); 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 51262306a36Sopenharmony_ci } 51362306a36Sopenharmony_ci goto next_operand; 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci case ARGI_DATAOBJECT: 51662306a36Sopenharmony_ci /* 51762306a36Sopenharmony_ci * ARGI_DATAOBJECT is only used by the size_of operator. 51862306a36Sopenharmony_ci * Need a buffer, string, package, or ref_of reference. 51962306a36Sopenharmony_ci * 52062306a36Sopenharmony_ci * The only reference allowed here is a direct reference to 52162306a36Sopenharmony_ci * a namespace node. 52262306a36Sopenharmony_ci */ 52362306a36Sopenharmony_ci switch (obj_desc->common.type) { 52462306a36Sopenharmony_ci case ACPI_TYPE_PACKAGE: 52562306a36Sopenharmony_ci case ACPI_TYPE_STRING: 52662306a36Sopenharmony_ci case ACPI_TYPE_BUFFER: 52762306a36Sopenharmony_ci case ACPI_TYPE_LOCAL_REFERENCE: 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci /* Valid operand */ 53062306a36Sopenharmony_ci break; 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci default: 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 53562306a36Sopenharmony_ci "Needed [Buffer/String/Package/Reference], found [%s] %p", 53662306a36Sopenharmony_ci acpi_ut_get_object_type_name 53762306a36Sopenharmony_ci (obj_desc), obj_desc)); 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 54062306a36Sopenharmony_ci } 54162306a36Sopenharmony_ci goto next_operand; 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_ci case ARGI_COMPLEXOBJ: 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci /* Need a buffer or package or (ACPI 2.0) String */ 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_ci switch (obj_desc->common.type) { 54862306a36Sopenharmony_ci case ACPI_TYPE_PACKAGE: 54962306a36Sopenharmony_ci case ACPI_TYPE_STRING: 55062306a36Sopenharmony_ci case ACPI_TYPE_BUFFER: 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci /* Valid operand */ 55362306a36Sopenharmony_ci break; 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_ci default: 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 55862306a36Sopenharmony_ci "Needed [Buffer/String/Package], found [%s] %p", 55962306a36Sopenharmony_ci acpi_ut_get_object_type_name 56062306a36Sopenharmony_ci (obj_desc), obj_desc)); 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 56362306a36Sopenharmony_ci } 56462306a36Sopenharmony_ci goto next_operand; 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci case ARGI_REGION_OR_BUFFER: /* Used by Load() only */ 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_ci /* 56962306a36Sopenharmony_ci * Need an operand of type REGION or a BUFFER 57062306a36Sopenharmony_ci * (which could be a resolved region field) 57162306a36Sopenharmony_ci */ 57262306a36Sopenharmony_ci switch (obj_desc->common.type) { 57362306a36Sopenharmony_ci case ACPI_TYPE_BUFFER: 57462306a36Sopenharmony_ci case ACPI_TYPE_REGION: 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci /* Valid operand */ 57762306a36Sopenharmony_ci break; 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci default: 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 58262306a36Sopenharmony_ci "Needed [Region/Buffer], found [%s] %p", 58362306a36Sopenharmony_ci acpi_ut_get_object_type_name 58462306a36Sopenharmony_ci (obj_desc), obj_desc)); 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 58762306a36Sopenharmony_ci } 58862306a36Sopenharmony_ci goto next_operand; 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci case ARGI_DATAREFOBJ: 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ci /* Used by the Store() operator only */ 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_ci switch (obj_desc->common.type) { 59562306a36Sopenharmony_ci case ACPI_TYPE_INTEGER: 59662306a36Sopenharmony_ci case ACPI_TYPE_PACKAGE: 59762306a36Sopenharmony_ci case ACPI_TYPE_STRING: 59862306a36Sopenharmony_ci case ACPI_TYPE_BUFFER: 59962306a36Sopenharmony_ci case ACPI_TYPE_BUFFER_FIELD: 60062306a36Sopenharmony_ci case ACPI_TYPE_LOCAL_REFERENCE: 60162306a36Sopenharmony_ci case ACPI_TYPE_LOCAL_REGION_FIELD: 60262306a36Sopenharmony_ci case ACPI_TYPE_LOCAL_BANK_FIELD: 60362306a36Sopenharmony_ci case ACPI_TYPE_LOCAL_INDEX_FIELD: 60462306a36Sopenharmony_ci case ACPI_TYPE_DDB_HANDLE: 60562306a36Sopenharmony_ci 60662306a36Sopenharmony_ci /* Valid operand */ 60762306a36Sopenharmony_ci break; 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci default: 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci if (acpi_gbl_enable_interpreter_slack) { 61262306a36Sopenharmony_ci /* 61362306a36Sopenharmony_ci * Enable original behavior of Store(), allowing any 61462306a36Sopenharmony_ci * and all objects as the source operand. The ACPI 61562306a36Sopenharmony_ci * spec does not allow this, however. 61662306a36Sopenharmony_ci */ 61762306a36Sopenharmony_ci break; 61862306a36Sopenharmony_ci } 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_ci if (target_op == AML_DEBUG_OP) { 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci /* Allow store of any object to the Debug object */ 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ci break; 62562306a36Sopenharmony_ci } 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 62862306a36Sopenharmony_ci "Needed Integer/Buffer/String/Package/Ref/Ddb]" 62962306a36Sopenharmony_ci ", found [%s] %p", 63062306a36Sopenharmony_ci acpi_ut_get_object_type_name 63162306a36Sopenharmony_ci (obj_desc), obj_desc)); 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 63462306a36Sopenharmony_ci } 63562306a36Sopenharmony_ci goto next_operand; 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_ci default: 63862306a36Sopenharmony_ci 63962306a36Sopenharmony_ci /* Unknown type */ 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 64262306a36Sopenharmony_ci "Internal - Unknown ARGI (required operand) type 0x%X", 64362306a36Sopenharmony_ci this_arg_type)); 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci return_ACPI_STATUS(AE_BAD_PARAMETER); 64662306a36Sopenharmony_ci } 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci /* 64962306a36Sopenharmony_ci * Make sure that the original object was resolved to the 65062306a36Sopenharmony_ci * required object type (Simple cases only). 65162306a36Sopenharmony_ci */ 65262306a36Sopenharmony_ci status = 65362306a36Sopenharmony_ci acpi_ex_check_object_type(type_needed, 65462306a36Sopenharmony_ci (*stack_ptr)->common.type, 65562306a36Sopenharmony_ci *stack_ptr); 65662306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 65762306a36Sopenharmony_ci return_ACPI_STATUS(status); 65862306a36Sopenharmony_ci } 65962306a36Sopenharmony_ci 66062306a36Sopenharmony_cinext_operand: 66162306a36Sopenharmony_ci /* 66262306a36Sopenharmony_ci * If more operands needed, decrement stack_ptr to point 66362306a36Sopenharmony_ci * to next operand on stack 66462306a36Sopenharmony_ci */ 66562306a36Sopenharmony_ci if (GET_CURRENT_ARG_TYPE(arg_types)) { 66662306a36Sopenharmony_ci stack_ptr--; 66762306a36Sopenharmony_ci } 66862306a36Sopenharmony_ci } 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_ci ACPI_DUMP_OPERANDS(walk_state->operands, 67162306a36Sopenharmony_ci acpi_ps_get_opcode_name(opcode), 67262306a36Sopenharmony_ci walk_state->num_operands); 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_ci return_ACPI_STATUS(status); 67562306a36Sopenharmony_ci} 676