cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

exstoren.c (7818B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: exstoren - AML Interpreter object store support,
      5 *                        Store to Node (namespace object)
      6 *
      7 * Copyright (C) 2000 - 2022, 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_EXECUTER
     17ACPI_MODULE_NAME("exstoren")
     18
     19/*******************************************************************************
     20 *
     21 * FUNCTION:    acpi_ex_resolve_object
     22 *
     23 * PARAMETERS:  source_desc_ptr     - Pointer to the source object
     24 *              target_type         - Current type of the target
     25 *              walk_state          - Current walk state
     26 *
     27 * RETURN:      Status, resolved object in source_desc_ptr.
     28 *
     29 * DESCRIPTION: Resolve an object. If the object is a reference, dereference
     30 *              it and return the actual object in the source_desc_ptr.
     31 *
     32 ******************************************************************************/
     33acpi_status
     34acpi_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 that
     52		 * 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/String
     59		 * are all essentially the same. This case handles the
     60		 * "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 the
    103		 * 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_object
    124 *
    125 * PARAMETERS:  source_desc         - Object to store
    126 *              dest_desc           - Object to receive a copy of the source
    127 *              new_desc            - New object if dest_desc is obsoleted
    128 *              walk_state          - Current walk state
    129 *
    130 * RETURN:      Status
    131 *
    132 * DESCRIPTION: "Store" an object to another object. This may include
    133 *              converting the source type to the target type (implicit
    134 *              conversion), and a copy of the value of the source to
    135 *              the target.
    136 *
    137 *              The Assignment of an object to another (not named) object
    138 *              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 the
    143 *              target object type then stored in the object. This means
    144 *              that the target object type (for an initialized target) will
    145 *              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_desc
    151 *              resolution (from a reference object) must be performed by
    152 *              the caller if necessary.
    153 *
    154 ******************************************************************************/
    155
    156acpi_status
    157acpi_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 or
    171		 * package element), so we can simply copy the source object
    172		 * creating a new destination object
    173		 */
    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 type
    184		 * 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 the
    188		 * 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 the
    201			 * 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 a
    210	 * 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}