root/drivers/acpi/acpica/exstoren.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ex_store_object_to_object

   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 - 2019, 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
  17 ACPI_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  ******************************************************************************/
  33 acpi_status
  34 acpi_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 
 156 acpi_status
 157 acpi_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 }

/* [<][>][^][v][top][bottom][index][help] */