linux/drivers/acpi/acpica/exstoren.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Module Name: exstoren - AML Interpreter object store support,
   4 *                        Store to Node (namespace object)
   5 *
   6 *****************************************************************************/
   7
   8/*
   9 * Copyright (C) 2000 - 2016, Intel Corp.
  10 * All rights reserved.
  11 *
  12 * Redistribution and use in source and binary forms, with or without
  13 * modification, are permitted provided that the following conditions
  14 * are met:
  15 * 1. Redistributions of source code must retain the above copyright
  16 *    notice, this list of conditions, and the following disclaimer,
  17 *    without modification.
  18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  19 *    substantially similar to the "NO WARRANTY" disclaimer below
  20 *    ("Disclaimer") and any redistribution must be conditioned upon
  21 *    including a substantially similar Disclaimer requirement for further
  22 *    binary redistribution.
  23 * 3. Neither the names of the above-listed copyright holders nor the names
  24 *    of any contributors may be used to endorse or promote products derived
  25 *    from this software without specific prior written permission.
  26 *
  27 * Alternatively, this software may be distributed under the terms of the
  28 * GNU General Public License ("GPL") version 2 as published by the Free
  29 * Software Foundation.
  30 *
  31 * NO WARRANTY
  32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  42 * POSSIBILITY OF SUCH DAMAGES.
  43 */
  44
  45#include <acpi/acpi.h>
  46#include "accommon.h"
  47#include "acinterp.h"
  48#include "amlcode.h"
  49
  50#define _COMPONENT          ACPI_EXECUTER
  51ACPI_MODULE_NAME("exstoren")
  52
  53/*******************************************************************************
  54 *
  55 * FUNCTION:    acpi_ex_resolve_object
  56 *
  57 * PARAMETERS:  source_desc_ptr     - Pointer to the source object
  58 *              target_type         - Current type of the target
  59 *              walk_state          - Current walk state
  60 *
  61 * RETURN:      Status, resolved object in source_desc_ptr.
  62 *
  63 * DESCRIPTION: Resolve an object. If the object is a reference, dereference
  64 *              it and return the actual object in the source_desc_ptr.
  65 *
  66 ******************************************************************************/
  67acpi_status
  68acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
  69                       acpi_object_type target_type,
  70                       struct acpi_walk_state *walk_state)
  71{
  72        union acpi_operand_object *source_desc = *source_desc_ptr;
  73        acpi_status status = AE_OK;
  74
  75        ACPI_FUNCTION_TRACE(ex_resolve_object);
  76
  77        /* Ensure we have a Target that can be stored to */
  78
  79        switch (target_type) {
  80        case ACPI_TYPE_BUFFER_FIELD:
  81        case ACPI_TYPE_LOCAL_REGION_FIELD:
  82        case ACPI_TYPE_LOCAL_BANK_FIELD:
  83        case ACPI_TYPE_LOCAL_INDEX_FIELD:
  84                /*
  85                 * These cases all require only Integers or values that
  86                 * can be converted to Integers (Strings or Buffers)
  87                 */
  88        case ACPI_TYPE_INTEGER:
  89        case ACPI_TYPE_STRING:
  90        case ACPI_TYPE_BUFFER:
  91                /*
  92                 * Stores into a Field/Region or into a Integer/Buffer/String
  93                 * are all essentially the same. This case handles the
  94                 * "interchangeable" types Integer, String, and Buffer.
  95                 */
  96                if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
  97
  98                        /* Resolve a reference object first */
  99
 100                        status =
 101                            acpi_ex_resolve_to_value(source_desc_ptr,
 102                                                     walk_state);
 103                        if (ACPI_FAILURE(status)) {
 104                                break;
 105                        }
 106                }
 107
 108                /* For copy_object, no further validation necessary */
 109
 110                if (walk_state->opcode == AML_COPY_OP) {
 111                        break;
 112                }
 113
 114                /* Must have a Integer, Buffer, or String */
 115
 116                if ((source_desc->common.type != ACPI_TYPE_INTEGER) &&
 117                    (source_desc->common.type != ACPI_TYPE_BUFFER) &&
 118                    (source_desc->common.type != ACPI_TYPE_STRING) &&
 119                    !((source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
 120                      (source_desc->reference.class == ACPI_REFCLASS_TABLE))) {
 121
 122                        /* Conversion successful but still not a valid type */
 123
 124                        ACPI_ERROR((AE_INFO,
 125                                    "Cannot assign type [%s] to [%s] (must be type Int/Str/Buf)",
 126                                    acpi_ut_get_object_type_name(source_desc),
 127                                    acpi_ut_get_type_name(target_type)));
 128
 129                        status = AE_AML_OPERAND_TYPE;
 130                }
 131                break;
 132
 133        case ACPI_TYPE_LOCAL_ALIAS:
 134        case ACPI_TYPE_LOCAL_METHOD_ALIAS:
 135                /*
 136                 * All aliases should have been resolved earlier, during the
 137                 * operand resolution phase.
 138                 */
 139                ACPI_ERROR((AE_INFO, "Store into an unresolved Alias object"));
 140                status = AE_AML_INTERNAL;
 141                break;
 142
 143        case ACPI_TYPE_PACKAGE:
 144        default:
 145                /*
 146                 * All other types than Alias and the various Fields come here,
 147                 * including the untyped case - ACPI_TYPE_ANY.
 148                 */
 149                break;
 150        }
 151
 152        return_ACPI_STATUS(status);
 153}
 154
 155/*******************************************************************************
 156 *
 157 * FUNCTION:    acpi_ex_store_object_to_object
 158 *
 159 * PARAMETERS:  source_desc         - Object to store
 160 *              dest_desc           - Object to receive a copy of the source
 161 *              new_desc            - New object if dest_desc is obsoleted
 162 *              walk_state          - Current walk state
 163 *
 164 * RETURN:      Status
 165 *
 166 * DESCRIPTION: "Store" an object to another object. This may include
 167 *              converting the source type to the target type (implicit
 168 *              conversion), and a copy of the value of the source to
 169 *              the target.
 170 *
 171 *              The Assignment of an object to another (not named) object
 172 *              is handled here.
 173 *              The Source passed in will replace the current value (if any)
 174 *              with the input value.
 175 *
 176 *              When storing into an object the data is converted to the
 177 *              target object type then stored in the object. This means
 178 *              that the target object type (for an initialized target) will
 179 *              not be changed by a store operation.
 180 *
 181 *              This module allows destination types of Number, String,
 182 *              Buffer, and Package.
 183 *
 184 *              Assumes parameters are already validated. NOTE: source_desc
 185 *              resolution (from a reference object) must be performed by
 186 *              the caller if necessary.
 187 *
 188 ******************************************************************************/
 189
 190acpi_status
 191acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
 192                               union acpi_operand_object *dest_desc,
 193                               union acpi_operand_object **new_desc,
 194                               struct acpi_walk_state *walk_state)
 195{
 196        union acpi_operand_object *actual_src_desc;
 197        acpi_status status = AE_OK;
 198
 199        ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_object, source_desc);
 200
 201        actual_src_desc = source_desc;
 202        if (!dest_desc) {
 203                /*
 204                 * There is no destination object (An uninitialized node or
 205                 * package element), so we can simply copy the source object
 206                 * creating a new destination object
 207                 */
 208                status =
 209                    acpi_ut_copy_iobject_to_iobject(actual_src_desc, new_desc,
 210                                                    walk_state);
 211                return_ACPI_STATUS(status);
 212        }
 213
 214        if (source_desc->common.type != dest_desc->common.type) {
 215                /*
 216                 * The source type does not match the type of the destination.
 217                 * Perform the "implicit conversion" of the source to the current type
 218                 * of the target as per the ACPI specification.
 219                 *
 220                 * If no conversion performed, actual_src_desc = source_desc.
 221                 * Otherwise, actual_src_desc is a temporary object to hold the
 222                 * converted object.
 223                 */
 224                status = acpi_ex_convert_to_target_type(dest_desc->common.type,
 225                                                        source_desc,
 226                                                        &actual_src_desc,
 227                                                        walk_state);
 228                if (ACPI_FAILURE(status)) {
 229                        return_ACPI_STATUS(status);
 230                }
 231
 232                if (source_desc == actual_src_desc) {
 233                        /*
 234                         * No conversion was performed. Return the source_desc as the
 235                         * new object.
 236                         */
 237                        *new_desc = source_desc;
 238                        return_ACPI_STATUS(AE_OK);
 239                }
 240        }
 241
 242        /*
 243         * We now have two objects of identical types, and we can perform a
 244         * copy of the *value* of the source object.
 245         */
 246        switch (dest_desc->common.type) {
 247        case ACPI_TYPE_INTEGER:
 248
 249                dest_desc->integer.value = actual_src_desc->integer.value;
 250
 251                /* Truncate value if we are executing from a 32-bit ACPI table */
 252
 253                (void)acpi_ex_truncate_for32bit_table(dest_desc);
 254                break;
 255
 256        case ACPI_TYPE_STRING:
 257
 258                status =
 259                    acpi_ex_store_string_to_string(actual_src_desc, dest_desc);
 260                break;
 261
 262        case ACPI_TYPE_BUFFER:
 263
 264                status =
 265                    acpi_ex_store_buffer_to_buffer(actual_src_desc, dest_desc);
 266                break;
 267
 268        case ACPI_TYPE_PACKAGE:
 269
 270                status =
 271                    acpi_ut_copy_iobject_to_iobject(actual_src_desc, &dest_desc,
 272                                                    walk_state);
 273                break;
 274
 275        default:
 276                /*
 277                 * All other types come here.
 278                 */
 279                ACPI_WARNING((AE_INFO, "Store into type [%s] not implemented",
 280                              acpi_ut_get_object_type_name(dest_desc)));
 281
 282                status = AE_NOT_IMPLEMENTED;
 283                break;
 284        }
 285
 286        if (actual_src_desc != source_desc) {
 287
 288                /* Delete the intermediate (temporary) source object */
 289
 290                acpi_ut_remove_reference(actual_src_desc);
 291        }
 292
 293        *new_desc = dest_desc;
 294        return_ACPI_STATUS(status);
 295}
 296