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 - 2016, 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 type [Integer/Buffer/String], found [%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,
 356                            "Target is not of type [Package/BufferField]"));
 357                status = AE_AML_TARGET_TYPE;
 358                break;
 359        }
 360
 361        return_ACPI_STATUS(status);
 362}
 363
 364/*******************************************************************************
 365 *
 366 * FUNCTION:    acpi_ex_store_object_to_node
 367 *
 368 * PARAMETERS:  source_desc             - Value to be stored
 369 *              node                    - Named object to receive the value
 370 *              walk_state              - Current walk state
 371 *              implicit_conversion     - Perform implicit conversion (yes/no)
 372 *
 373 * RETURN:      Status
 374 *
 375 * DESCRIPTION: Store the object to the named object.
 376 *
 377 * The assignment of an object to a named object is handled here.
 378 * The value passed in will replace the current value (if any)
 379 * with the input value.
 380 *
 381 * When storing into an object the data is converted to the
 382 * target object type then stored in the object. This means
 383 * that the target object type (for an initialized target) will
 384 * not be changed by a store operation. A copy_object can change
 385 * the target type, however.
 386 *
 387 * The implicit_conversion flag is set to NO/FALSE only when
 388 * storing to an arg_x -- as per the rules of the ACPI spec.
 389 *
 390 * Assumes parameters are already validated.
 391 *
 392 ******************************************************************************/
 393
 394acpi_status
 395acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
 396                             struct acpi_namespace_node *node,
 397                             struct acpi_walk_state *walk_state,
 398                             u8 implicit_conversion)
 399{
 400        acpi_status status = AE_OK;
 401        union acpi_operand_object *target_desc;
 402        union acpi_operand_object *new_desc;
 403        acpi_object_type target_type;
 404
 405        ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_node, source_desc);
 406
 407        /* Get current type of the node, and object attached to Node */
 408
 409        target_type = acpi_ns_get_type(node);
 410        target_desc = acpi_ns_get_attached_object(node);
 411
 412        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p [%s] to node %p [%s]\n",
 413                          source_desc,
 414                          acpi_ut_get_object_type_name(source_desc), node,
 415                          acpi_ut_get_type_name(target_type)));
 416
 417        /* Only limited target types possible for everything except copy_object */
 418
 419        if (walk_state->opcode != AML_COPY_OP) {
 420                /*
 421                 * Only copy_object allows all object types to be overwritten. For
 422                 * target_ref(s), there are restrictions on the object types that
 423                 * are allowed.
 424                 *
 425                 * Allowable operations/typing for Store:
 426                 *
 427                 * 1) Simple Store
 428                 *      Integer     --> Integer (Named/Local/Arg)
 429                 *      String      --> String  (Named/Local/Arg)
 430                 *      Buffer      --> Buffer  (Named/Local/Arg)
 431                 *      Package     --> Package (Named/Local/Arg)
 432                 *
 433                 * 2) Store with implicit conversion
 434                 *      Integer     --> String or Buffer  (Named)
 435                 *      String      --> Integer or Buffer (Named)
 436                 *      Buffer      --> Integer or String (Named)
 437                 */
 438                switch (target_type) {
 439                case ACPI_TYPE_PACKAGE:
 440                        /*
 441                         * Here, can only store a package to an existing package.
 442                         * Storing a package to a Local/Arg is OK, and handled
 443                         * elsewhere.
 444                         */
 445                        if (walk_state->opcode == AML_STORE_OP) {
 446                                if (source_desc->common.type !=
 447                                    ACPI_TYPE_PACKAGE) {
 448                                        ACPI_ERROR((AE_INFO,
 449                                                    "Cannot assign type [%s] to [Package] "
 450                                                    "(source must be type Pkg)",
 451                                                    acpi_ut_get_object_type_name
 452                                                    (source_desc)));
 453
 454                                        return_ACPI_STATUS(AE_AML_TARGET_TYPE);
 455                                }
 456                                break;
 457                        }
 458
 459                        /* Fallthrough */
 460
 461                case ACPI_TYPE_DEVICE:
 462                case ACPI_TYPE_EVENT:
 463                case ACPI_TYPE_MUTEX:
 464                case ACPI_TYPE_REGION:
 465                case ACPI_TYPE_POWER:
 466                case ACPI_TYPE_PROCESSOR:
 467                case ACPI_TYPE_THERMAL:
 468
 469                        ACPI_ERROR((AE_INFO,
 470                                    "Target must be [Buffer/Integer/String/Reference]"
 471                                    ", found [%s] (%4.4s)",
 472                                    acpi_ut_get_type_name(node->type),
 473                                    node->name.ascii));
 474
 475                        return_ACPI_STATUS(AE_AML_TARGET_TYPE);
 476
 477                default:
 478                        break;
 479                }
 480        }
 481
 482        /*
 483         * Resolve the source object to an actual value
 484         * (If it is a reference object)
 485         */
 486        status = acpi_ex_resolve_object(&source_desc, target_type, walk_state);
 487        if (ACPI_FAILURE(status)) {
 488                return_ACPI_STATUS(status);
 489        }
 490
 491        /* Do the actual store operation */
 492
 493        switch (target_type) {
 494                /*
 495                 * The simple data types all support implicit source operand
 496                 * conversion before the store.
 497                 */
 498        case ACPI_TYPE_INTEGER:
 499        case ACPI_TYPE_STRING:
 500        case ACPI_TYPE_BUFFER:
 501
 502                if ((walk_state->opcode == AML_COPY_OP) || !implicit_conversion) {
 503                        /*
 504                         * However, copy_object and Stores to arg_x do not perform
 505                         * an implicit conversion, as per the ACPI specification.
 506                         * A direct store is performed instead.
 507                         */
 508                        status =
 509                            acpi_ex_store_direct_to_node(source_desc, node,
 510                                                         walk_state);
 511                        break;
 512                }
 513
 514                /* Store with implicit source operand conversion support */
 515
 516                status =
 517                    acpi_ex_store_object_to_object(source_desc, target_desc,
 518                                                   &new_desc, walk_state);
 519                if (ACPI_FAILURE(status)) {
 520                        return_ACPI_STATUS(status);
 521                }
 522
 523                if (new_desc != target_desc) {
 524                        /*
 525                         * Store the new new_desc as the new value of the Name, and set
 526                         * the Name's type to that of the value being stored in it.
 527                         * source_desc reference count is incremented by attach_object.
 528                         *
 529                         * Note: This may change the type of the node if an explicit
 530                         * store has been performed such that the node/object type
 531                         * has been changed.
 532                         */
 533                        status =
 534                            acpi_ns_attach_object(node, new_desc,
 535                                                  new_desc->common.type);
 536
 537                        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 538                                          "Store type [%s] into [%s] via Convert/Attach\n",
 539                                          acpi_ut_get_object_type_name
 540                                          (source_desc),
 541                                          acpi_ut_get_object_type_name
 542                                          (new_desc)));
 543                }
 544                break;
 545
 546        case ACPI_TYPE_BUFFER_FIELD:
 547        case ACPI_TYPE_LOCAL_REGION_FIELD:
 548        case ACPI_TYPE_LOCAL_BANK_FIELD:
 549        case ACPI_TYPE_LOCAL_INDEX_FIELD:
 550                /*
 551                 * For all fields, always write the source data to the target
 552                 * field. Any required implicit source operand conversion is
 553                 * performed in the function below as necessary. Note, field
 554                 * objects must retain their original type permanently.
 555                 */
 556                status = acpi_ex_write_data_to_field(source_desc, target_desc,
 557                                                     &walk_state->result_obj);
 558                break;
 559
 560        default:
 561                /*
 562                 * copy_object operator: No conversions for all other types.
 563                 * Instead, directly store a copy of the source object.
 564                 *
 565                 * This is the ACPI spec-defined behavior for the copy_object
 566                 * operator. (Note, for this default case, all normal
 567                 * Store/Target operations exited above with an error).
 568                 */
 569                status =
 570                    acpi_ex_store_direct_to_node(source_desc, node, walk_state);
 571                break;
 572        }
 573
 574        return_ACPI_STATUS(status);
 575}
 576
 577/*******************************************************************************
 578 *
 579 * FUNCTION:    acpi_ex_store_direct_to_node
 580 *
 581 * PARAMETERS:  source_desc             - Value to be stored
 582 *              node                    - Named object to receive the value
 583 *              walk_state              - Current walk state
 584 *
 585 * RETURN:      Status
 586 *
 587 * DESCRIPTION: "Store" an object directly to a node. This involves a copy
 588 *              and an attach.
 589 *
 590 ******************************************************************************/
 591
 592static acpi_status
 593acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
 594                             struct acpi_namespace_node *node,
 595                             struct acpi_walk_state *walk_state)
 596{
 597        acpi_status status;
 598        union acpi_operand_object *new_desc;
 599
 600        ACPI_FUNCTION_TRACE(ex_store_direct_to_node);
 601
 602        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 603                          "Storing [%s] (%p) directly into node [%s] (%p)"
 604                          " with no implicit conversion\n",
 605                          acpi_ut_get_object_type_name(source_desc),
 606                          source_desc, acpi_ut_get_type_name(node->type),
 607                          node));
 608
 609        /* Copy the source object to a new object */
 610
 611        status =
 612            acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, walk_state);
 613        if (ACPI_FAILURE(status)) {
 614                return_ACPI_STATUS(status);
 615        }
 616
 617        /* Attach the new object to the node */
 618
 619        status = acpi_ns_attach_object(node, new_desc, new_desc->common.type);
 620        acpi_ut_remove_reference(new_desc);
 621        return_ACPI_STATUS(status);
 622}
 623