162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 262306a36Sopenharmony_ci/****************************************************************************** 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Module Name: dsobject - Dispatcher object management routines 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 "acparser.h" 1362306a36Sopenharmony_ci#include "amlcode.h" 1462306a36Sopenharmony_ci#include "acdispat.h" 1562306a36Sopenharmony_ci#include "acnamesp.h" 1662306a36Sopenharmony_ci#include "acinterp.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#define _COMPONENT ACPI_DISPATCHER 1962306a36Sopenharmony_ciACPI_MODULE_NAME("dsobject") 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/******************************************************************************* 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci * FUNCTION: acpi_ds_build_internal_object 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * PARAMETERS: walk_state - Current walk state 2662306a36Sopenharmony_ci * op - Parser object to be translated 2762306a36Sopenharmony_ci * obj_desc_ptr - Where the ACPI internal object is returned 2862306a36Sopenharmony_ci * 2962306a36Sopenharmony_ci * RETURN: Status 3062306a36Sopenharmony_ci * 3162306a36Sopenharmony_ci * DESCRIPTION: Translate a parser Op object to the equivalent namespace object 3262306a36Sopenharmony_ci * Simple objects are any objects other than a package object! 3362306a36Sopenharmony_ci * 3462306a36Sopenharmony_ci ******************************************************************************/ 3562306a36Sopenharmony_ciacpi_status 3662306a36Sopenharmony_ciacpi_ds_build_internal_object(struct acpi_walk_state *walk_state, 3762306a36Sopenharmony_ci union acpi_parse_object *op, 3862306a36Sopenharmony_ci union acpi_operand_object **obj_desc_ptr) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci union acpi_operand_object *obj_desc; 4162306a36Sopenharmony_ci acpi_status status; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(ds_build_internal_object); 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci *obj_desc_ptr = NULL; 4662306a36Sopenharmony_ci if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) { 4762306a36Sopenharmony_ci /* 4862306a36Sopenharmony_ci * This is a named object reference. If this name was 4962306a36Sopenharmony_ci * previously looked up in the namespace, it was stored in 5062306a36Sopenharmony_ci * this op. Otherwise, go ahead and look it up now 5162306a36Sopenharmony_ci */ 5262306a36Sopenharmony_ci if (!op->common.node) { 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci /* Check if we are resolving a named reference within a package */ 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci if ((op->common.parent->common.aml_opcode == 5762306a36Sopenharmony_ci AML_PACKAGE_OP) 5862306a36Sopenharmony_ci || (op->common.parent->common.aml_opcode == 5962306a36Sopenharmony_ci AML_VARIABLE_PACKAGE_OP)) { 6062306a36Sopenharmony_ci /* 6162306a36Sopenharmony_ci * We won't resolve package elements here, we will do this 6262306a36Sopenharmony_ci * after all ACPI tables are loaded into the namespace. This 6362306a36Sopenharmony_ci * behavior supports both forward references to named objects 6462306a36Sopenharmony_ci * and external references to objects in other tables. 6562306a36Sopenharmony_ci */ 6662306a36Sopenharmony_ci goto create_new_object; 6762306a36Sopenharmony_ci } else { 6862306a36Sopenharmony_ci status = acpi_ns_lookup(walk_state->scope_info, 6962306a36Sopenharmony_ci op->common.value.string, 7062306a36Sopenharmony_ci ACPI_TYPE_ANY, 7162306a36Sopenharmony_ci ACPI_IMODE_EXECUTE, 7262306a36Sopenharmony_ci ACPI_NS_SEARCH_PARENT | 7362306a36Sopenharmony_ci ACPI_NS_DONT_OPEN_SCOPE, 7462306a36Sopenharmony_ci NULL, 7562306a36Sopenharmony_ci ACPI_CAST_INDIRECT_PTR 7662306a36Sopenharmony_ci (struct 7762306a36Sopenharmony_ci acpi_namespace_node, 7862306a36Sopenharmony_ci &(op->common.node))); 7962306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 8062306a36Sopenharmony_ci ACPI_ERROR_NAMESPACE(walk_state-> 8162306a36Sopenharmony_ci scope_info, 8262306a36Sopenharmony_ci op->common.value. 8362306a36Sopenharmony_ci string, status); 8462306a36Sopenharmony_ci return_ACPI_STATUS(status); 8562306a36Sopenharmony_ci } 8662306a36Sopenharmony_ci } 8762306a36Sopenharmony_ci } 8862306a36Sopenharmony_ci } 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cicreate_new_object: 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci /* Create and init a new internal ACPI object */ 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci obj_desc = acpi_ut_create_internal_object((acpi_ps_get_opcode_info 9562306a36Sopenharmony_ci (op->common.aml_opcode))-> 9662306a36Sopenharmony_ci object_type); 9762306a36Sopenharmony_ci if (!obj_desc) { 9862306a36Sopenharmony_ci return_ACPI_STATUS(AE_NO_MEMORY); 9962306a36Sopenharmony_ci } 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci status = 10262306a36Sopenharmony_ci acpi_ds_init_object_from_op(walk_state, op, op->common.aml_opcode, 10362306a36Sopenharmony_ci &obj_desc); 10462306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 10562306a36Sopenharmony_ci acpi_ut_remove_reference(obj_desc); 10662306a36Sopenharmony_ci return_ACPI_STATUS(status); 10762306a36Sopenharmony_ci } 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci /* 11062306a36Sopenharmony_ci * Handling for unresolved package reference elements. 11162306a36Sopenharmony_ci * These are elements that are namepaths. 11262306a36Sopenharmony_ci */ 11362306a36Sopenharmony_ci if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) || 11462306a36Sopenharmony_ci (op->common.parent->common.aml_opcode == AML_VARIABLE_PACKAGE_OP)) { 11562306a36Sopenharmony_ci obj_desc->reference.resolved = TRUE; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci if ((op->common.aml_opcode == AML_INT_NAMEPATH_OP) && 11862306a36Sopenharmony_ci !obj_desc->reference.node) { 11962306a36Sopenharmony_ci /* 12062306a36Sopenharmony_ci * Name was unresolved above. 12162306a36Sopenharmony_ci * Get the prefix node for later lookup 12262306a36Sopenharmony_ci */ 12362306a36Sopenharmony_ci obj_desc->reference.node = 12462306a36Sopenharmony_ci walk_state->scope_info->scope.node; 12562306a36Sopenharmony_ci obj_desc->reference.aml = op->common.aml; 12662306a36Sopenharmony_ci obj_desc->reference.resolved = FALSE; 12762306a36Sopenharmony_ci } 12862306a36Sopenharmony_ci } 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci *obj_desc_ptr = obj_desc; 13162306a36Sopenharmony_ci return_ACPI_STATUS(status); 13262306a36Sopenharmony_ci} 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci/******************************************************************************* 13562306a36Sopenharmony_ci * 13662306a36Sopenharmony_ci * FUNCTION: acpi_ds_build_internal_buffer_obj 13762306a36Sopenharmony_ci * 13862306a36Sopenharmony_ci * PARAMETERS: walk_state - Current walk state 13962306a36Sopenharmony_ci * op - Parser object to be translated 14062306a36Sopenharmony_ci * buffer_length - Length of the buffer 14162306a36Sopenharmony_ci * obj_desc_ptr - Where the ACPI internal object is returned 14262306a36Sopenharmony_ci * 14362306a36Sopenharmony_ci * RETURN: Status 14462306a36Sopenharmony_ci * 14562306a36Sopenharmony_ci * DESCRIPTION: Translate a parser Op package object to the equivalent 14662306a36Sopenharmony_ci * namespace object 14762306a36Sopenharmony_ci * 14862306a36Sopenharmony_ci ******************************************************************************/ 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ciacpi_status 15162306a36Sopenharmony_ciacpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, 15262306a36Sopenharmony_ci union acpi_parse_object *op, 15362306a36Sopenharmony_ci u32 buffer_length, 15462306a36Sopenharmony_ci union acpi_operand_object **obj_desc_ptr) 15562306a36Sopenharmony_ci{ 15662306a36Sopenharmony_ci union acpi_parse_object *arg; 15762306a36Sopenharmony_ci union acpi_operand_object *obj_desc; 15862306a36Sopenharmony_ci union acpi_parse_object *byte_list; 15962306a36Sopenharmony_ci u32 byte_list_length = 0; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(ds_build_internal_buffer_obj); 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci /* 16462306a36Sopenharmony_ci * If we are evaluating a Named buffer object "Name (xxxx, Buffer)". 16562306a36Sopenharmony_ci * The buffer object already exists (from the NS node), otherwise it must 16662306a36Sopenharmony_ci * be created. 16762306a36Sopenharmony_ci */ 16862306a36Sopenharmony_ci obj_desc = *obj_desc_ptr; 16962306a36Sopenharmony_ci if (!obj_desc) { 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci /* Create a new buffer object */ 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER); 17462306a36Sopenharmony_ci *obj_desc_ptr = obj_desc; 17562306a36Sopenharmony_ci if (!obj_desc) { 17662306a36Sopenharmony_ci return_ACPI_STATUS(AE_NO_MEMORY); 17762306a36Sopenharmony_ci } 17862306a36Sopenharmony_ci } 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci /* 18162306a36Sopenharmony_ci * Second arg is the buffer data (optional) byte_list can be either 18262306a36Sopenharmony_ci * individual bytes or a string initializer. In either case, a 18362306a36Sopenharmony_ci * byte_list appears in the AML. 18462306a36Sopenharmony_ci */ 18562306a36Sopenharmony_ci arg = op->common.value.arg; /* skip first arg */ 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci byte_list = arg->named.next; 18862306a36Sopenharmony_ci if (byte_list) { 18962306a36Sopenharmony_ci if (byte_list->common.aml_opcode != AML_INT_BYTELIST_OP) { 19062306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 19162306a36Sopenharmony_ci "Expecting bytelist, found AML opcode 0x%X in op %p", 19262306a36Sopenharmony_ci byte_list->common.aml_opcode, byte_list)); 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci acpi_ut_remove_reference(obj_desc); 19562306a36Sopenharmony_ci return (AE_TYPE); 19662306a36Sopenharmony_ci } 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci byte_list_length = (u32) byte_list->common.value.integer; 19962306a36Sopenharmony_ci } 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci /* 20262306a36Sopenharmony_ci * The buffer length (number of bytes) will be the larger of: 20362306a36Sopenharmony_ci * 1) The specified buffer length and 20462306a36Sopenharmony_ci * 2) The length of the initializer byte list 20562306a36Sopenharmony_ci */ 20662306a36Sopenharmony_ci obj_desc->buffer.length = buffer_length; 20762306a36Sopenharmony_ci if (byte_list_length > buffer_length) { 20862306a36Sopenharmony_ci obj_desc->buffer.length = byte_list_length; 20962306a36Sopenharmony_ci } 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci /* Allocate the buffer */ 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci if (obj_desc->buffer.length == 0) { 21462306a36Sopenharmony_ci obj_desc->buffer.pointer = NULL; 21562306a36Sopenharmony_ci ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 21662306a36Sopenharmony_ci "Buffer defined with zero length in AML, creating\n")); 21762306a36Sopenharmony_ci } else { 21862306a36Sopenharmony_ci obj_desc->buffer.pointer = 21962306a36Sopenharmony_ci ACPI_ALLOCATE_ZEROED(obj_desc->buffer.length); 22062306a36Sopenharmony_ci if (!obj_desc->buffer.pointer) { 22162306a36Sopenharmony_ci acpi_ut_delete_object_desc(obj_desc); 22262306a36Sopenharmony_ci return_ACPI_STATUS(AE_NO_MEMORY); 22362306a36Sopenharmony_ci } 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci /* Initialize buffer from the byte_list (if present) */ 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci if (byte_list) { 22862306a36Sopenharmony_ci memcpy(obj_desc->buffer.pointer, byte_list->named.data, 22962306a36Sopenharmony_ci byte_list_length); 23062306a36Sopenharmony_ci } 23162306a36Sopenharmony_ci } 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci obj_desc->buffer.flags |= AOPOBJ_DATA_VALID; 23462306a36Sopenharmony_ci op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc); 23562306a36Sopenharmony_ci return_ACPI_STATUS(AE_OK); 23662306a36Sopenharmony_ci} 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci/******************************************************************************* 23962306a36Sopenharmony_ci * 24062306a36Sopenharmony_ci * FUNCTION: acpi_ds_create_node 24162306a36Sopenharmony_ci * 24262306a36Sopenharmony_ci * PARAMETERS: walk_state - Current walk state 24362306a36Sopenharmony_ci * node - NS Node to be initialized 24462306a36Sopenharmony_ci * op - Parser object to be translated 24562306a36Sopenharmony_ci * 24662306a36Sopenharmony_ci * RETURN: Status 24762306a36Sopenharmony_ci * 24862306a36Sopenharmony_ci * DESCRIPTION: Create the object to be associated with a namespace node 24962306a36Sopenharmony_ci * 25062306a36Sopenharmony_ci ******************************************************************************/ 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ciacpi_status 25362306a36Sopenharmony_ciacpi_ds_create_node(struct acpi_walk_state *walk_state, 25462306a36Sopenharmony_ci struct acpi_namespace_node *node, 25562306a36Sopenharmony_ci union acpi_parse_object *op) 25662306a36Sopenharmony_ci{ 25762306a36Sopenharmony_ci acpi_status status; 25862306a36Sopenharmony_ci union acpi_operand_object *obj_desc; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci ACPI_FUNCTION_TRACE_PTR(ds_create_node, op); 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci /* 26362306a36Sopenharmony_ci * Because of the execution pass through the non-control-method 26462306a36Sopenharmony_ci * parts of the table, we can arrive here twice. Only init 26562306a36Sopenharmony_ci * the named object node the first time through 26662306a36Sopenharmony_ci */ 26762306a36Sopenharmony_ci if (acpi_ns_get_attached_object(node)) { 26862306a36Sopenharmony_ci return_ACPI_STATUS(AE_OK); 26962306a36Sopenharmony_ci } 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci if (!op->common.value.arg) { 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci /* No arguments, there is nothing to do */ 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci return_ACPI_STATUS(AE_OK); 27662306a36Sopenharmony_ci } 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci /* Build an internal object for the argument(s) */ 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci status = 28162306a36Sopenharmony_ci acpi_ds_build_internal_object(walk_state, op->common.value.arg, 28262306a36Sopenharmony_ci &obj_desc); 28362306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 28462306a36Sopenharmony_ci return_ACPI_STATUS(status); 28562306a36Sopenharmony_ci } 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci /* Re-type the object according to its argument */ 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci node->type = obj_desc->common.type; 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci /* Attach obj to node */ 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci status = acpi_ns_attach_object(node, obj_desc, node->type); 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci /* Remove local reference to the object */ 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci acpi_ut_remove_reference(obj_desc); 29862306a36Sopenharmony_ci return_ACPI_STATUS(status); 29962306a36Sopenharmony_ci} 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci/******************************************************************************* 30262306a36Sopenharmony_ci * 30362306a36Sopenharmony_ci * FUNCTION: acpi_ds_init_object_from_op 30462306a36Sopenharmony_ci * 30562306a36Sopenharmony_ci * PARAMETERS: walk_state - Current walk state 30662306a36Sopenharmony_ci * op - Parser op used to init the internal object 30762306a36Sopenharmony_ci * opcode - AML opcode associated with the object 30862306a36Sopenharmony_ci * ret_obj_desc - Namespace object to be initialized 30962306a36Sopenharmony_ci * 31062306a36Sopenharmony_ci * RETURN: Status 31162306a36Sopenharmony_ci * 31262306a36Sopenharmony_ci * DESCRIPTION: Initialize a namespace object from a parser Op and its 31362306a36Sopenharmony_ci * associated arguments. The namespace object is a more compact 31462306a36Sopenharmony_ci * representation of the Op and its arguments. 31562306a36Sopenharmony_ci * 31662306a36Sopenharmony_ci ******************************************************************************/ 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ciacpi_status 31962306a36Sopenharmony_ciacpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, 32062306a36Sopenharmony_ci union acpi_parse_object *op, 32162306a36Sopenharmony_ci u16 opcode, 32262306a36Sopenharmony_ci union acpi_operand_object **ret_obj_desc) 32362306a36Sopenharmony_ci{ 32462306a36Sopenharmony_ci const struct acpi_opcode_info *op_info; 32562306a36Sopenharmony_ci union acpi_operand_object *obj_desc; 32662306a36Sopenharmony_ci acpi_status status = AE_OK; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(ds_init_object_from_op); 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci obj_desc = *ret_obj_desc; 33162306a36Sopenharmony_ci op_info = acpi_ps_get_opcode_info(opcode); 33262306a36Sopenharmony_ci if (op_info->class == AML_CLASS_UNKNOWN) { 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci /* Unknown opcode */ 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci return_ACPI_STATUS(AE_TYPE); 33762306a36Sopenharmony_ci } 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci /* Perform per-object initialization */ 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci switch (obj_desc->common.type) { 34262306a36Sopenharmony_ci case ACPI_TYPE_BUFFER: 34362306a36Sopenharmony_ci /* 34462306a36Sopenharmony_ci * Defer evaluation of Buffer term_arg operand 34562306a36Sopenharmony_ci */ 34662306a36Sopenharmony_ci obj_desc->buffer.node = 34762306a36Sopenharmony_ci ACPI_CAST_PTR(struct acpi_namespace_node, 34862306a36Sopenharmony_ci walk_state->operands[0]); 34962306a36Sopenharmony_ci obj_desc->buffer.aml_start = op->named.data; 35062306a36Sopenharmony_ci obj_desc->buffer.aml_length = op->named.length; 35162306a36Sopenharmony_ci break; 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci case ACPI_TYPE_PACKAGE: 35462306a36Sopenharmony_ci /* 35562306a36Sopenharmony_ci * Defer evaluation of Package term_arg operand and all 35662306a36Sopenharmony_ci * package elements. (01/2017): We defer the element 35762306a36Sopenharmony_ci * resolution to allow forward references from the package 35862306a36Sopenharmony_ci * in order to provide compatibility with other ACPI 35962306a36Sopenharmony_ci * implementations. 36062306a36Sopenharmony_ci */ 36162306a36Sopenharmony_ci obj_desc->package.node = 36262306a36Sopenharmony_ci ACPI_CAST_PTR(struct acpi_namespace_node, 36362306a36Sopenharmony_ci walk_state->operands[0]); 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci if (!op->named.data) { 36662306a36Sopenharmony_ci return_ACPI_STATUS(AE_OK); 36762306a36Sopenharmony_ci } 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci obj_desc->package.aml_start = op->named.data; 37062306a36Sopenharmony_ci obj_desc->package.aml_length = op->named.length; 37162306a36Sopenharmony_ci break; 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci case ACPI_TYPE_INTEGER: 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci switch (op_info->type) { 37662306a36Sopenharmony_ci case AML_TYPE_CONSTANT: 37762306a36Sopenharmony_ci /* 37862306a36Sopenharmony_ci * Resolve AML Constants here - AND ONLY HERE! 37962306a36Sopenharmony_ci * All constants are integers. 38062306a36Sopenharmony_ci * We mark the integer with a flag that indicates that it started 38162306a36Sopenharmony_ci * life as a constant -- so that stores to constants will perform 38262306a36Sopenharmony_ci * as expected (noop). zero_op is used as a placeholder for optional 38362306a36Sopenharmony_ci * target operands. 38462306a36Sopenharmony_ci */ 38562306a36Sopenharmony_ci obj_desc->common.flags = AOPOBJ_AML_CONSTANT; 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci switch (opcode) { 38862306a36Sopenharmony_ci case AML_ZERO_OP: 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci obj_desc->integer.value = 0; 39162306a36Sopenharmony_ci break; 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci case AML_ONE_OP: 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci obj_desc->integer.value = 1; 39662306a36Sopenharmony_ci break; 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci case AML_ONES_OP: 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci obj_desc->integer.value = ACPI_UINT64_MAX; 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci /* Truncate value if we are executing from a 32-bit ACPI table */ 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci (void)acpi_ex_truncate_for32bit_table(obj_desc); 40562306a36Sopenharmony_ci break; 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci case AML_REVISION_OP: 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci obj_desc->integer.value = ACPI_CA_VERSION; 41062306a36Sopenharmony_ci break; 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci default: 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 41562306a36Sopenharmony_ci "Unknown constant opcode 0x%X", 41662306a36Sopenharmony_ci opcode)); 41762306a36Sopenharmony_ci status = AE_AML_OPERAND_TYPE; 41862306a36Sopenharmony_ci break; 41962306a36Sopenharmony_ci } 42062306a36Sopenharmony_ci break; 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci case AML_TYPE_LITERAL: 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci obj_desc->integer.value = op->common.value.integer; 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci if (acpi_ex_truncate_for32bit_table(obj_desc)) { 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci /* Warn if we found a 64-bit constant in a 32-bit table */ 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci ACPI_WARNING((AE_INFO, 43162306a36Sopenharmony_ci "Truncated 64-bit constant found in 32-bit table: %8.8X%8.8X => %8.8X", 43262306a36Sopenharmony_ci ACPI_FORMAT_UINT64(op->common. 43362306a36Sopenharmony_ci value.integer), 43462306a36Sopenharmony_ci (u32)obj_desc->integer.value)); 43562306a36Sopenharmony_ci } 43662306a36Sopenharmony_ci break; 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci default: 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, "Unknown Integer type 0x%X", 44162306a36Sopenharmony_ci op_info->type)); 44262306a36Sopenharmony_ci status = AE_AML_OPERAND_TYPE; 44362306a36Sopenharmony_ci break; 44462306a36Sopenharmony_ci } 44562306a36Sopenharmony_ci break; 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci case ACPI_TYPE_STRING: 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci obj_desc->string.pointer = op->common.value.string; 45062306a36Sopenharmony_ci obj_desc->string.length = (u32)strlen(op->common.value.string); 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci /* 45362306a36Sopenharmony_ci * The string is contained in the ACPI table, don't ever try 45462306a36Sopenharmony_ci * to delete it 45562306a36Sopenharmony_ci */ 45662306a36Sopenharmony_ci obj_desc->common.flags |= AOPOBJ_STATIC_POINTER; 45762306a36Sopenharmony_ci break; 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci case ACPI_TYPE_METHOD: 46062306a36Sopenharmony_ci break; 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci case ACPI_TYPE_LOCAL_REFERENCE: 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci switch (op_info->type) { 46562306a36Sopenharmony_ci case AML_TYPE_LOCAL_VARIABLE: 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_ci /* Local ID (0-7) is (AML opcode - base AML_FIRST_LOCAL_OP) */ 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci obj_desc->reference.value = 47062306a36Sopenharmony_ci ((u32)opcode) - AML_FIRST_LOCAL_OP; 47162306a36Sopenharmony_ci obj_desc->reference.class = ACPI_REFCLASS_LOCAL; 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci status = 47462306a36Sopenharmony_ci acpi_ds_method_data_get_node(ACPI_REFCLASS_LOCAL, 47562306a36Sopenharmony_ci obj_desc->reference. 47662306a36Sopenharmony_ci value, walk_state, 47762306a36Sopenharmony_ci ACPI_CAST_INDIRECT_PTR 47862306a36Sopenharmony_ci (struct 47962306a36Sopenharmony_ci acpi_namespace_node, 48062306a36Sopenharmony_ci &obj_desc->reference. 48162306a36Sopenharmony_ci object)); 48262306a36Sopenharmony_ci break; 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ci case AML_TYPE_METHOD_ARGUMENT: 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci /* Arg ID (0-6) is (AML opcode - base AML_FIRST_ARG_OP) */ 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci obj_desc->reference.value = 48962306a36Sopenharmony_ci ((u32)opcode) - AML_FIRST_ARG_OP; 49062306a36Sopenharmony_ci obj_desc->reference.class = ACPI_REFCLASS_ARG; 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci status = acpi_ds_method_data_get_node(ACPI_REFCLASS_ARG, 49362306a36Sopenharmony_ci obj_desc-> 49462306a36Sopenharmony_ci reference.value, 49562306a36Sopenharmony_ci walk_state, 49662306a36Sopenharmony_ci ACPI_CAST_INDIRECT_PTR 49762306a36Sopenharmony_ci (struct 49862306a36Sopenharmony_ci acpi_namespace_node, 49962306a36Sopenharmony_ci &obj_desc-> 50062306a36Sopenharmony_ci reference. 50162306a36Sopenharmony_ci object)); 50262306a36Sopenharmony_ci break; 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci default: /* Object name or Debug object */ 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci switch (op->common.aml_opcode) { 50762306a36Sopenharmony_ci case AML_INT_NAMEPATH_OP: 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci /* Node was saved in Op */ 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci obj_desc->reference.node = op->common.node; 51262306a36Sopenharmony_ci obj_desc->reference.class = ACPI_REFCLASS_NAME; 51362306a36Sopenharmony_ci if (op->common.node) { 51462306a36Sopenharmony_ci obj_desc->reference.object = 51562306a36Sopenharmony_ci op->common.node->object; 51662306a36Sopenharmony_ci } 51762306a36Sopenharmony_ci break; 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_ci case AML_DEBUG_OP: 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci obj_desc->reference.class = ACPI_REFCLASS_DEBUG; 52262306a36Sopenharmony_ci break; 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci default: 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 52762306a36Sopenharmony_ci "Unimplemented reference type for AML opcode: 0x%4.4X", 52862306a36Sopenharmony_ci opcode)); 52962306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 53062306a36Sopenharmony_ci } 53162306a36Sopenharmony_ci break; 53262306a36Sopenharmony_ci } 53362306a36Sopenharmony_ci break; 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci default: 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, "Unimplemented data type: 0x%X", 53862306a36Sopenharmony_ci obj_desc->common.type)); 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci status = AE_AML_OPERAND_TYPE; 54162306a36Sopenharmony_ci break; 54262306a36Sopenharmony_ci } 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci return_ACPI_STATUS(status); 54562306a36Sopenharmony_ci} 546