linux/drivers/acpi/acpica/exstoren.c
<<
>>
Prefs
   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 - 2020, 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}
 262