linux/drivers/acpi/acpica/exstore.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Module Name: exstore - AML Interpreter object store support
   4 *
   5 *****************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2014, Intel Corp.
   9 * All rights reserved.
  10 *
  11 * Redistribution and use in source and binary forms, with or without
  12 * modification, are permitted provided that the following conditions
  13 * are met:
  14 * 1. Redistributions of source code must retain the above copyright
  15 *    notice, this list of conditions, and the following disclaimer,
  16 *    without modification.
  17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18 *    substantially similar to the "NO WARRANTY" disclaimer below
  19 *    ("Disclaimer") and any redistribution must be conditioned upon
  20 *    including a substantially similar Disclaimer requirement for further
  21 *    binary redistribution.
  22 * 3. Neither the names of the above-listed copyright holders nor the names
  23 *    of any contributors may be used to endorse or promote products derived
  24 *    from this software without specific prior written permission.
  25 *
  26 * Alternatively, this software may be distributed under the terms of the
  27 * GNU General Public License ("GPL") version 2 as published by the Free
  28 * Software Foundation.
  29 *
  30 * NO WARRANTY
  31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41 * POSSIBILITY OF SUCH DAMAGES.
  42 */
  43
  44#include <acpi/acpi.h>
  45#include "accommon.h"
  46#include "acdispat.h"
  47#include "acinterp.h"
  48#include "amlcode.h"
  49#include "acnamesp.h"
  50
  51#define _COMPONENT          ACPI_EXECUTER
  52ACPI_MODULE_NAME("exstore")
  53
  54/* Local prototypes */
  55static acpi_status
  56acpi_ex_store_object_to_index(union acpi_operand_object *val_desc,
  57                              union acpi_operand_object *dest_desc,
  58                              struct acpi_walk_state *walk_state);
  59
  60static acpi_status
  61acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
  62                             struct acpi_namespace_node *node,
  63                             struct acpi_walk_state *walk_state);
  64
  65/*******************************************************************************
  66 *
  67 * FUNCTION:    acpi_ex_store
  68 *
  69 * PARAMETERS:  *source_desc        - Value to be stored
  70 *              *dest_desc          - Where to store it. Must be an NS node
  71 *                                    or union acpi_operand_object of type
  72 *                                    Reference;
  73 *              walk_state          - Current walk state
  74 *
  75 * RETURN:      Status
  76 *
  77 * DESCRIPTION: Store the value described by source_desc into the location
  78 *              described by dest_desc. Called by various interpreter
  79 *              functions to store the result of an operation into
  80 *              the destination operand -- not just simply the actual "Store"
  81 *              ASL operator.
  82 *
  83 ******************************************************************************/
  84
  85acpi_status
  86acpi_ex_store(union acpi_operand_object *source_desc,
  87              union acpi_operand_object *dest_desc,
  88              struct acpi_walk_state *walk_state)
  89{
  90        acpi_status status = AE_OK;
  91        union acpi_operand_object *ref_desc = dest_desc;
  92
  93        ACPI_FUNCTION_TRACE_PTR(ex_store, dest_desc);
  94
  95        /* Validate parameters */
  96
  97        if (!source_desc || !dest_desc) {
  98                ACPI_ERROR((AE_INFO, "Null parameter"));
  99                return_ACPI_STATUS(AE_AML_NO_OPERAND);
 100        }
 101
 102        /* dest_desc can be either a namespace node or an ACPI object */
 103
 104        if (ACPI_GET_DESCRIPTOR_TYPE(dest_desc) == ACPI_DESC_TYPE_NAMED) {
 105                /*
 106                 * Dest is a namespace node,
 107                 * Storing an object into a Named node.
 108                 */
 109                status = acpi_ex_store_object_to_node(source_desc,
 110                                                      (struct
 111                                                       acpi_namespace_node *)
 112                                                      dest_desc, walk_state,
 113                                                      ACPI_IMPLICIT_CONVERSION);
 114
 115                return_ACPI_STATUS(status);
 116        }
 117
 118        /* Destination object must be a Reference or a Constant object */
 119
 120        switch (dest_desc->common.type) {
 121        case ACPI_TYPE_LOCAL_REFERENCE:
 122
 123                break;
 124
 125        case ACPI_TYPE_INTEGER:
 126
 127                /* Allow stores to Constants -- a Noop as per ACPI spec */
 128
 129                if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
 130                        return_ACPI_STATUS(AE_OK);
 131                }
 132
 133                /*lint -fallthrough */
 134
 135        default:
 136
 137                /* Destination is not a Reference object */
 138
 139                ACPI_ERROR((AE_INFO,
 140                            "Target is not a Reference or Constant object - %s [%p]",
 141                            acpi_ut_get_object_type_name(dest_desc),
 142                            dest_desc));
 143
 144                return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 145        }
 146
 147        /*
 148         * Examine the Reference class. These cases are handled:
 149         *
 150         * 1) Store to Name (Change the object associated with a name)
 151         * 2) Store to an indexed area of a Buffer or Package
 152         * 3) Store to a Method Local or Arg
 153         * 4) Store to the debug object
 154         */
 155        switch (ref_desc->reference.class) {
 156        case ACPI_REFCLASS_REFOF:
 157
 158                /* Storing an object into a Name "container" */
 159
 160                status = acpi_ex_store_object_to_node(source_desc,
 161                                                      ref_desc->reference.
 162                                                      object, walk_state,
 163                                                      ACPI_IMPLICIT_CONVERSION);
 164                break;
 165
 166        case ACPI_REFCLASS_INDEX:
 167
 168                /* Storing to an Index (pointer into a packager or buffer) */
 169
 170                status =
 171                    acpi_ex_store_object_to_index(source_desc, ref_desc,
 172                                                  walk_state);
 173                break;
 174
 175        case ACPI_REFCLASS_LOCAL:
 176        case ACPI_REFCLASS_ARG:
 177
 178                /* Store to a method local/arg  */
 179
 180                status =
 181                    acpi_ds_store_object_to_local(ref_desc->reference.class,
 182                                                  ref_desc->reference.value,
 183                                                  source_desc, walk_state);
 184                break;
 185
 186        case ACPI_REFCLASS_DEBUG:
 187                /*
 188                 * Storing to the Debug object causes the value stored to be
 189                 * displayed and otherwise has no effect -- see ACPI Specification
 190                 */
 191                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 192                                  "**** Write to Debug Object: Object %p %s ****:\n\n",
 193                                  source_desc,
 194                                  acpi_ut_get_object_type_name(source_desc)));
 195
 196                ACPI_DEBUG_OBJECT(source_desc, 0, 0);
 197                break;
 198
 199        default:
 200
 201                ACPI_ERROR((AE_INFO, "Unknown Reference Class 0x%2.2X",
 202                            ref_desc->reference.class));
 203                ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_INFO);
 204
 205                status = AE_AML_INTERNAL;
 206                break;
 207        }
 208
 209        return_ACPI_STATUS(status);
 210}
 211
 212/*******************************************************************************
 213 *
 214 * FUNCTION:    acpi_ex_store_object_to_index
 215 *
 216 * PARAMETERS:  *source_desc            - Value to be stored
 217 *              *dest_desc              - Named object to receive the value
 218 *              walk_state              - Current walk state
 219 *
 220 * RETURN:      Status
 221 *
 222 * DESCRIPTION: Store the object to indexed Buffer or Package element
 223 *
 224 ******************************************************************************/
 225
 226static acpi_status
 227acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
 228                              union acpi_operand_object *index_desc,
 229                              struct acpi_walk_state *walk_state)
 230{
 231        acpi_status status = AE_OK;
 232        union acpi_operand_object *obj_desc;
 233        union acpi_operand_object *new_desc;
 234        u8 value = 0;
 235        u32 i;
 236
 237        ACPI_FUNCTION_TRACE(ex_store_object_to_index);
 238
 239        /*
 240         * Destination must be a reference pointer, and
 241         * must point to either a buffer or a package
 242         */
 243        switch (index_desc->reference.target_type) {
 244        case ACPI_TYPE_PACKAGE:
 245                /*
 246                 * Storing to a package element. Copy the object and replace
 247                 * any existing object with the new object. No implicit
 248                 * conversion is performed.
 249                 *
 250                 * The object at *(index_desc->Reference.Where) is the
 251                 * element within the package that is to be modified.
 252                 * The parent package object is at index_desc->Reference.Object
 253                 */
 254                obj_desc = *(index_desc->reference.where);
 255
 256                if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE &&
 257                    source_desc->reference.class == ACPI_REFCLASS_TABLE) {
 258
 259                        /* This is a DDBHandle, just add a reference to it */
 260
 261                        acpi_ut_add_reference(source_desc);
 262                        new_desc = source_desc;
 263                } else {
 264                        /* Normal object, copy it */
 265
 266                        status =
 267                            acpi_ut_copy_iobject_to_iobject(source_desc,
 268                                                            &new_desc,
 269                                                            walk_state);
 270                        if (ACPI_FAILURE(status)) {
 271                                return_ACPI_STATUS(status);
 272                        }
 273                }
 274
 275                if (obj_desc) {
 276
 277                        /* Decrement reference count by the ref count of the parent package */
 278
 279                        for (i = 0; i < ((union acpi_operand_object *)
 280                                         index_desc->reference.object)->common.
 281                             reference_count; i++) {
 282                                acpi_ut_remove_reference(obj_desc);
 283                        }
 284                }
 285
 286                *(index_desc->reference.where) = new_desc;
 287
 288                /* Increment ref count by the ref count of the parent package-1 */
 289
 290                for (i = 1; i < ((union acpi_operand_object *)
 291                                 index_desc->reference.object)->common.
 292                     reference_count; i++) {
 293                        acpi_ut_add_reference(new_desc);
 294                }
 295
 296                break;
 297
 298        case ACPI_TYPE_BUFFER_FIELD:
 299                /*
 300                 * Store into a Buffer or String (not actually a real buffer_field)
 301                 * at a location defined by an Index.
 302                 *
 303                 * The first 8-bit element of the source object is written to the
 304                 * 8-bit Buffer location defined by the Index destination object,
 305                 * according to the ACPI 2.0 specification.
 306                 */
 307
 308                /*
 309                 * Make sure the target is a Buffer or String. An error should
 310                 * not happen here, since the reference_object was constructed
 311                 * by the INDEX_OP code.
 312                 */
 313                obj_desc = index_desc->reference.object;
 314                if ((obj_desc->common.type != ACPI_TYPE_BUFFER) &&
 315                    (obj_desc->common.type != ACPI_TYPE_STRING)) {
 316                        return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 317                }
 318
 319                /*
 320                 * The assignment of the individual elements will be slightly
 321                 * different for each source type.
 322                 */
 323                switch (source_desc->common.type) {
 324                case ACPI_TYPE_INTEGER:
 325
 326                        /* Use the least-significant byte of the integer */
 327
 328                        value = (u8) (source_desc->integer.value);
 329                        break;
 330
 331                case ACPI_TYPE_BUFFER:
 332                case ACPI_TYPE_STRING:
 333
 334                        /* Note: Takes advantage of common string/buffer fields */
 335
 336                        value = source_desc->buffer.pointer[0];
 337                        break;
 338
 339                default:
 340
 341                        /* All other types are invalid */
 342
 343                        ACPI_ERROR((AE_INFO,
 344                                    "Source must be Integer/Buffer/String type, not %s",
 345                                    acpi_ut_get_object_type_name(source_desc)));
 346                        return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 347                }
 348
 349                /* Store the source value into the target buffer byte */
 350
 351                obj_desc->buffer.pointer[index_desc->reference.value] = value;
 352                break;
 353
 354        default:
 355                ACPI_ERROR((AE_INFO, "Target is not a Package or BufferField"));
 356                status = AE_AML_OPERAND_TYPE;
 357                break;
 358        }
 359
 360        return_ACPI_STATUS(status);
 361}
 362
 363/*******************************************************************************
 364 *
 365 * FUNCTION:    acpi_ex_store_object_to_node
 366 *
 367 * PARAMETERS:  source_desc             - Value to be stored
 368 *              node                    - Named object to receive the value
 369 *              walk_state              - Current walk state
 370 *              implicit_conversion     - Perform implicit conversion (yes/no)
 371 *
 372 * RETURN:      Status
 373 *
 374 * DESCRIPTION: Store the object to the named object.
 375 *
 376 *              The Assignment of an object to a named object is handled here
 377 *              The value passed in will replace the current value (if any)
 378 *              with the input value.
 379 *
 380 *              When storing into an object the data is converted to the
 381 *              target object type then stored in the object. This means
 382 *              that the target object type (for an initialized target) will
 383 *              not be changed by a store operation. A copy_object can change
 384 *              the target type, however.
 385 *
 386 *              The implicit_conversion flag is set to NO/FALSE only when
 387 *              storing to an arg_x -- as per the rules of the ACPI spec.
 388 *
 389 *              Assumes parameters are already validated.
 390 *
 391 ******************************************************************************/
 392
 393acpi_status
 394acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
 395                             struct acpi_namespace_node *node,
 396                             struct acpi_walk_state *walk_state,
 397                             u8 implicit_conversion)
 398{
 399        acpi_status status = AE_OK;
 400        union acpi_operand_object *target_desc;
 401        union acpi_operand_object *new_desc;
 402        acpi_object_type target_type;
 403
 404        ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_node, source_desc);
 405
 406        /* Get current type of the node, and object attached to Node */
 407
 408        target_type = acpi_ns_get_type(node);
 409        target_desc = acpi_ns_get_attached_object(node);
 410
 411        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p (%s) to node %p (%s)\n",
 412                          source_desc,
 413                          acpi_ut_get_object_type_name(source_desc), node,
 414                          acpi_ut_get_type_name(target_type)));
 415
 416        /*
 417         * Resolve the source object to an actual value
 418         * (If it is a reference object)
 419         */
 420        status = acpi_ex_resolve_object(&source_desc, target_type, walk_state);
 421        if (ACPI_FAILURE(status)) {
 422                return_ACPI_STATUS(status);
 423        }
 424
 425        /* Do the actual store operation */
 426
 427        switch (target_type) {
 428        case ACPI_TYPE_INTEGER:
 429        case ACPI_TYPE_STRING:
 430        case ACPI_TYPE_BUFFER:
 431                /*
 432                 * The simple data types all support implicit source operand
 433                 * conversion before the store.
 434                 */
 435
 436                if ((walk_state->opcode == AML_COPY_OP) || !implicit_conversion) {
 437                        /*
 438                         * However, copy_object and Stores to arg_x do not perform
 439                         * an implicit conversion, as per the ACPI specification.
 440                         * A direct store is performed instead.
 441                         */
 442                        status = acpi_ex_store_direct_to_node(source_desc, node,
 443                                                              walk_state);
 444                        break;
 445                }
 446
 447                /* Store with implicit source operand conversion support */
 448
 449                status =
 450                    acpi_ex_store_object_to_object(source_desc, target_desc,
 451                                                   &new_desc, walk_state);
 452                if (ACPI_FAILURE(status)) {
 453                        return_ACPI_STATUS(status);
 454                }
 455
 456                if (new_desc != target_desc) {
 457                        /*
 458                         * Store the new new_desc as the new value of the Name, and set
 459                         * the Name's type to that of the value being stored in it.
 460                         * source_desc reference count is incremented by attach_object.
 461                         *
 462                         * Note: This may change the type of the node if an explicit
 463                         * store has been performed such that the node/object type
 464                         * has been changed.
 465                         */
 466                        status = acpi_ns_attach_object(node, new_desc,
 467                                                       new_desc->common.type);
 468
 469                        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 470                                          "Store %s into %s via Convert/Attach\n",
 471                                          acpi_ut_get_object_type_name
 472                                          (source_desc),
 473                                          acpi_ut_get_object_type_name
 474                                          (new_desc)));
 475                }
 476                break;
 477
 478        case ACPI_TYPE_BUFFER_FIELD:
 479        case ACPI_TYPE_LOCAL_REGION_FIELD:
 480        case ACPI_TYPE_LOCAL_BANK_FIELD:
 481        case ACPI_TYPE_LOCAL_INDEX_FIELD:
 482                /*
 483                 * For all fields, always write the source data to the target
 484                 * field. Any required implicit source operand conversion is
 485                 * performed in the function below as necessary. Note, field
 486                 * objects must retain their original type permanently.
 487                 */
 488                status = acpi_ex_write_data_to_field(source_desc, target_desc,
 489                                                     &walk_state->result_obj);
 490                break;
 491
 492        default:
 493                /*
 494                 * No conversions for all other types. Directly store a copy of
 495                 * the source object. This is the ACPI spec-defined behavior for
 496                 * the copy_object operator.
 497                 *
 498                 * NOTE: For the Store operator, this is a departure from the
 499                 * ACPI spec, which states "If conversion is impossible, abort
 500                 * the running control method". Instead, this code implements
 501                 * "If conversion is impossible, treat the Store operation as
 502                 * a CopyObject".
 503                 */
 504                status = acpi_ex_store_direct_to_node(source_desc, node,
 505                                                      walk_state);
 506                break;
 507        }
 508
 509        return_ACPI_STATUS(status);
 510}
 511
 512/*******************************************************************************
 513 *
 514 * FUNCTION:    acpi_ex_store_direct_to_node
 515 *
 516 * PARAMETERS:  source_desc             - Value to be stored
 517 *              node                    - Named object to receive the value
 518 *              walk_state              - Current walk state
 519 *
 520 * RETURN:      Status
 521 *
 522 * DESCRIPTION: "Store" an object directly to a node. This involves a copy
 523 *              and an attach.
 524 *
 525 ******************************************************************************/
 526
 527static acpi_status
 528acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
 529                             struct acpi_namespace_node *node,
 530                             struct acpi_walk_state *walk_state)
 531{
 532        acpi_status status;
 533        union acpi_operand_object *new_desc;
 534
 535        ACPI_FUNCTION_TRACE(ex_store_direct_to_node);
 536
 537        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 538                          "Storing [%s] (%p) directly into node [%s] (%p)"
 539                          " with no implicit conversion\n",
 540                          acpi_ut_get_object_type_name(source_desc),
 541                          source_desc, acpi_ut_get_type_name(node->type),
 542                          node));
 543
 544        /* Copy the source object to a new object */
 545
 546        status =
 547            acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, walk_state);
 548        if (ACPI_FAILURE(status)) {
 549                return_ACPI_STATUS(status);
 550        }
 551
 552        /* Attach the new object to the node */
 553
 554        status = acpi_ns_attach_object(node, new_desc, new_desc->common.type);
 555        acpi_ut_remove_reference(new_desc);
 556        return_ACPI_STATUS(status);
 557}
 558