brintos

brintos / linux-shallow public Read only

0
0
Text · 7.6 KiB · b01ae01 Raw
262 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************3 *4 * Module Name: exstoren - AML Interpreter object store support,5 *                        Store to Node (namespace object)6 *7 * Copyright (C) 2000 - 2023, Intel Corp.8 *9 *****************************************************************************/10 11#include <acpi/acpi.h>12#include "accommon.h"13#include "acinterp.h"14#include "amlcode.h"15 16#define _COMPONENT          ACPI_EXECUTER17ACPI_MODULE_NAME("exstoren")18 19/*******************************************************************************20 *21 * FUNCTION:    acpi_ex_resolve_object22 *23 * PARAMETERS:  source_desc_ptr     - Pointer to the source object24 *              target_type         - Current type of the target25 *              walk_state          - Current walk state26 *27 * RETURN:      Status, resolved object in source_desc_ptr.28 *29 * DESCRIPTION: Resolve an object. If the object is a reference, dereference30 *              it and return the actual object in the source_desc_ptr.31 *32 ******************************************************************************/33acpi_status34acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,35		       acpi_object_type target_type,36		       struct acpi_walk_state *walk_state)37{38	union acpi_operand_object *source_desc = *source_desc_ptr;39	acpi_status status = AE_OK;40 41	ACPI_FUNCTION_TRACE(ex_resolve_object);42 43	/* Ensure we have a Target that can be stored to */44 45	switch (target_type) {46	case ACPI_TYPE_BUFFER_FIELD:47	case ACPI_TYPE_LOCAL_REGION_FIELD:48	case ACPI_TYPE_LOCAL_BANK_FIELD:49	case ACPI_TYPE_LOCAL_INDEX_FIELD:50		/*51		 * These cases all require only Integers or values that52		 * can be converted to Integers (Strings or Buffers)53		 */54	case ACPI_TYPE_INTEGER:55	case ACPI_TYPE_STRING:56	case ACPI_TYPE_BUFFER:57		/*58		 * Stores into a Field/Region or into a Integer/Buffer/String59		 * are all essentially the same. This case handles the60		 * "interchangeable" types Integer, String, and Buffer.61		 */62		if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {63 64			/* Resolve a reference object first */65 66			status =67			    acpi_ex_resolve_to_value(source_desc_ptr,68						     walk_state);69			if (ACPI_FAILURE(status)) {70				break;71			}72		}73 74		/* For copy_object, no further validation necessary */75 76		if (walk_state->opcode == AML_COPY_OBJECT_OP) {77			break;78		}79 80		/* Must have a Integer, Buffer, or String */81 82		if ((source_desc->common.type != ACPI_TYPE_INTEGER) &&83		    (source_desc->common.type != ACPI_TYPE_BUFFER) &&84		    (source_desc->common.type != ACPI_TYPE_STRING) &&85		    !((source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&86		      (source_desc->reference.class == ACPI_REFCLASS_TABLE))) {87 88			/* Conversion successful but still not a valid type */89 90			ACPI_ERROR((AE_INFO,91				    "Cannot assign type [%s] to [%s] (must be type Int/Str/Buf)",92				    acpi_ut_get_object_type_name(source_desc),93				    acpi_ut_get_type_name(target_type)));94 95			status = AE_AML_OPERAND_TYPE;96		}97		break;98 99	case ACPI_TYPE_LOCAL_ALIAS:100	case ACPI_TYPE_LOCAL_METHOD_ALIAS:101		/*102		 * All aliases should have been resolved earlier, during the103		 * operand resolution phase.104		 */105		ACPI_ERROR((AE_INFO, "Store into an unresolved Alias object"));106		status = AE_AML_INTERNAL;107		break;108 109	case ACPI_TYPE_PACKAGE:110	default:111		/*112		 * All other types than Alias and the various Fields come here,113		 * including the untyped case - ACPI_TYPE_ANY.114		 */115		break;116	}117 118	return_ACPI_STATUS(status);119}120 121/*******************************************************************************122 *123 * FUNCTION:    acpi_ex_store_object_to_object124 *125 * PARAMETERS:  source_desc         - Object to store126 *              dest_desc           - Object to receive a copy of the source127 *              new_desc            - New object if dest_desc is obsoleted128 *              walk_state          - Current walk state129 *130 * RETURN:      Status131 *132 * DESCRIPTION: "Store" an object to another object. This may include133 *              converting the source type to the target type (implicit134 *              conversion), and a copy of the value of the source to135 *              the target.136 *137 *              The Assignment of an object to another (not named) object138 *              is handled here.139 *              The Source passed in will replace the current value (if any)140 *              with the input value.141 *142 *              When storing into an object the data is converted to the143 *              target object type then stored in the object. This means144 *              that the target object type (for an initialized target) will145 *              not be changed by a store operation.146 *147 *              This module allows destination types of Number, String,148 *              Buffer, and Package.149 *150 *              Assumes parameters are already validated. NOTE: source_desc151 *              resolution (from a reference object) must be performed by152 *              the caller if necessary.153 *154 ******************************************************************************/155 156acpi_status157acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,158			       union acpi_operand_object *dest_desc,159			       union acpi_operand_object **new_desc,160			       struct acpi_walk_state *walk_state)161{162	union acpi_operand_object *actual_src_desc;163	acpi_status status = AE_OK;164 165	ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_object, source_desc);166 167	actual_src_desc = source_desc;168	if (!dest_desc) {169		/*170		 * There is no destination object (An uninitialized node or171		 * package element), so we can simply copy the source object172		 * creating a new destination object173		 */174		status =175		    acpi_ut_copy_iobject_to_iobject(actual_src_desc, new_desc,176						    walk_state);177		return_ACPI_STATUS(status);178	}179 180	if (source_desc->common.type != dest_desc->common.type) {181		/*182		 * The source type does not match the type of the destination.183		 * Perform the "implicit conversion" of the source to the current type184		 * of the target as per the ACPI specification.185		 *186		 * If no conversion performed, actual_src_desc = source_desc.187		 * Otherwise, actual_src_desc is a temporary object to hold the188		 * converted object.189		 */190		status = acpi_ex_convert_to_target_type(dest_desc->common.type,191							source_desc,192							&actual_src_desc,193							walk_state);194		if (ACPI_FAILURE(status)) {195			return_ACPI_STATUS(status);196		}197 198		if (source_desc == actual_src_desc) {199			/*200			 * No conversion was performed. Return the source_desc as the201			 * new object.202			 */203			*new_desc = source_desc;204			return_ACPI_STATUS(AE_OK);205		}206	}207 208	/*209	 * We now have two objects of identical types, and we can perform a210	 * copy of the *value* of the source object.211	 */212	switch (dest_desc->common.type) {213	case ACPI_TYPE_INTEGER:214 215		dest_desc->integer.value = actual_src_desc->integer.value;216 217		/* Truncate value if we are executing from a 32-bit ACPI table */218 219		(void)acpi_ex_truncate_for32bit_table(dest_desc);220		break;221 222	case ACPI_TYPE_STRING:223 224		status =225		    acpi_ex_store_string_to_string(actual_src_desc, dest_desc);226		break;227 228	case ACPI_TYPE_BUFFER:229 230		status =231		    acpi_ex_store_buffer_to_buffer(actual_src_desc, dest_desc);232		break;233 234	case ACPI_TYPE_PACKAGE:235 236		status =237		    acpi_ut_copy_iobject_to_iobject(actual_src_desc, &dest_desc,238						    walk_state);239		break;240 241	default:242		/*243		 * All other types come here.244		 */245		ACPI_WARNING((AE_INFO, "Store into type [%s] not implemented",246			      acpi_ut_get_object_type_name(dest_desc)));247 248		status = AE_NOT_IMPLEMENTED;249		break;250	}251 252	if (actual_src_desc != source_desc) {253 254		/* Delete the intermediate (temporary) source object */255 256		acpi_ut_remove_reference(actual_src_desc);257	}258 259	*new_desc = dest_desc;260	return_ACPI_STATUS(status);261}262