linux/drivers/acpi/acpica/exconfig.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/******************************************************************************
   3 *
   4 * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes)
   5 *
   6 * Copyright (C) 2000 - 2020, Intel Corp.
   7 *
   8 *****************************************************************************/
   9
  10#include <acpi/acpi.h>
  11#include "accommon.h"
  12#include "acinterp.h"
  13#include "acnamesp.h"
  14#include "actables.h"
  15#include "acdispat.h"
  16#include "acevents.h"
  17#include "amlcode.h"
  18
  19#define _COMPONENT          ACPI_EXECUTER
  20ACPI_MODULE_NAME("exconfig")
  21
  22/* Local prototypes */
  23static acpi_status
  24acpi_ex_add_table(u32 table_index, union acpi_operand_object **ddb_handle);
  25
  26static acpi_status
  27acpi_ex_region_read(union acpi_operand_object *obj_desc,
  28                    u32 length, u8 *buffer);
  29
  30/*******************************************************************************
  31 *
  32 * FUNCTION:    acpi_ex_add_table
  33 *
  34 * PARAMETERS:  table               - Pointer to raw table
  35 *              parent_node         - Where to load the table (scope)
  36 *              ddb_handle          - Where to return the table handle.
  37 *
  38 * RETURN:      Status
  39 *
  40 * DESCRIPTION: Common function to Install and Load an ACPI table with a
  41 *              returned table handle.
  42 *
  43 ******************************************************************************/
  44
  45static acpi_status
  46acpi_ex_add_table(u32 table_index, union acpi_operand_object **ddb_handle)
  47{
  48        union acpi_operand_object *obj_desc;
  49
  50        ACPI_FUNCTION_TRACE(ex_add_table);
  51
  52        /* Create an object to be the table handle */
  53
  54        obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE);
  55        if (!obj_desc) {
  56                return_ACPI_STATUS(AE_NO_MEMORY);
  57        }
  58
  59        /* Init the table handle */
  60
  61        obj_desc->common.flags |= AOPOBJ_DATA_VALID;
  62        obj_desc->reference.class = ACPI_REFCLASS_TABLE;
  63        obj_desc->reference.value = table_index;
  64        *ddb_handle = obj_desc;
  65        return_ACPI_STATUS(AE_OK);
  66}
  67
  68/*******************************************************************************
  69 *
  70 * FUNCTION:    acpi_ex_load_table_op
  71 *
  72 * PARAMETERS:  walk_state          - Current state with operands
  73 *              return_desc         - Where to store the return object
  74 *
  75 * RETURN:      Status
  76 *
  77 * DESCRIPTION: Load an ACPI table from the RSDT/XSDT
  78 *
  79 ******************************************************************************/
  80
  81acpi_status
  82acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
  83                      union acpi_operand_object **return_desc)
  84{
  85        acpi_status status;
  86        union acpi_operand_object **operand = &walk_state->operands[0];
  87        struct acpi_namespace_node *parent_node;
  88        struct acpi_namespace_node *start_node;
  89        struct acpi_namespace_node *parameter_node = NULL;
  90        union acpi_operand_object *ddb_handle;
  91        u32 table_index;
  92
  93        ACPI_FUNCTION_TRACE(ex_load_table_op);
  94
  95        /* Find the ACPI table in the RSDT/XSDT */
  96
  97        acpi_ex_exit_interpreter();
  98        status = acpi_tb_find_table(operand[0]->string.pointer,
  99                                    operand[1]->string.pointer,
 100                                    operand[2]->string.pointer, &table_index);
 101        acpi_ex_enter_interpreter();
 102        if (ACPI_FAILURE(status)) {
 103                if (status != AE_NOT_FOUND) {
 104                        return_ACPI_STATUS(status);
 105                }
 106
 107                /* Table not found, return an Integer=0 and AE_OK */
 108
 109                ddb_handle = acpi_ut_create_integer_object((u64) 0);
 110                if (!ddb_handle) {
 111                        return_ACPI_STATUS(AE_NO_MEMORY);
 112                }
 113
 114                *return_desc = ddb_handle;
 115                return_ACPI_STATUS(AE_OK);
 116        }
 117
 118        /* Default nodes */
 119
 120        start_node = walk_state->scope_info->scope.node;
 121        parent_node = acpi_gbl_root_node;
 122
 123        /* root_path (optional parameter) */
 124
 125        if (operand[3]->string.length > 0) {
 126                /*
 127                 * Find the node referenced by the root_path_string. This is the
 128                 * location within the namespace where the table will be loaded.
 129                 */
 130                status = acpi_ns_get_node_unlocked(start_node,
 131                                                   operand[3]->string.pointer,
 132                                                   ACPI_NS_SEARCH_PARENT,
 133                                                   &parent_node);
 134                if (ACPI_FAILURE(status)) {
 135                        return_ACPI_STATUS(status);
 136                }
 137        }
 138
 139        /* parameter_path (optional parameter) */
 140
 141        if (operand[4]->string.length > 0) {
 142                if ((operand[4]->string.pointer[0] != AML_ROOT_PREFIX) &&
 143                    (operand[4]->string.pointer[0] != AML_PARENT_PREFIX)) {
 144                        /*
 145                         * Path is not absolute, so it will be relative to the node
 146                         * referenced by the root_path_string (or the NS root if omitted)
 147                         */
 148                        start_node = parent_node;
 149                }
 150
 151                /* Find the node referenced by the parameter_path_string */
 152
 153                status = acpi_ns_get_node_unlocked(start_node,
 154                                                   operand[4]->string.pointer,
 155                                                   ACPI_NS_SEARCH_PARENT,
 156                                                   &parameter_node);
 157                if (ACPI_FAILURE(status)) {
 158                        return_ACPI_STATUS(status);
 159                }
 160        }
 161
 162        /* Load the table into the namespace */
 163
 164        ACPI_INFO(("Dynamic OEM Table Load:"));
 165        acpi_ex_exit_interpreter();
 166        status = acpi_tb_load_table(table_index, parent_node);
 167        acpi_ex_enter_interpreter();
 168        if (ACPI_FAILURE(status)) {
 169                return_ACPI_STATUS(status);
 170        }
 171
 172        status = acpi_ex_add_table(table_index, &ddb_handle);
 173        if (ACPI_FAILURE(status)) {
 174                return_ACPI_STATUS(status);
 175        }
 176
 177        /* Complete the initialization/resolution of new objects */
 178
 179        acpi_ex_exit_interpreter();
 180        acpi_ns_initialize_objects();
 181        acpi_ex_enter_interpreter();
 182
 183        /* Parameter Data (optional) */
 184
 185        if (parameter_node) {
 186
 187                /* Store the parameter data into the optional parameter object */
 188
 189                status = acpi_ex_store(operand[5],
 190                                       ACPI_CAST_PTR(union acpi_operand_object,
 191                                                     parameter_node),
 192                                       walk_state);
 193                if (ACPI_FAILURE(status)) {
 194                        (void)acpi_ex_unload_table(ddb_handle);
 195
 196                        acpi_ut_remove_reference(ddb_handle);
 197                        return_ACPI_STATUS(status);
 198                }
 199        }
 200
 201        *return_desc = ddb_handle;
 202        return_ACPI_STATUS(status);
 203}
 204
 205/*******************************************************************************
 206 *
 207 * FUNCTION:    acpi_ex_region_read
 208 *
 209 * PARAMETERS:  obj_desc        - Region descriptor
 210 *              length          - Number of bytes to read
 211 *              buffer          - Pointer to where to put the data
 212 *
 213 * RETURN:      Status
 214 *
 215 * DESCRIPTION: Read data from an operation region. The read starts from the
 216 *              beginning of the region.
 217 *
 218 ******************************************************************************/
 219
 220static acpi_status
 221acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer)
 222{
 223        acpi_status status;
 224        u64 value;
 225        u32 region_offset = 0;
 226        u32 i;
 227
 228        /* Bytewise reads */
 229
 230        for (i = 0; i < length; i++) {
 231                status =
 232                    acpi_ev_address_space_dispatch(obj_desc, NULL, ACPI_READ,
 233                                                   region_offset, 8, &value);
 234                if (ACPI_FAILURE(status)) {
 235                        return (status);
 236                }
 237
 238                *buffer = (u8)value;
 239                buffer++;
 240                region_offset++;
 241        }
 242
 243        return (AE_OK);
 244}
 245
 246/*******************************************************************************
 247 *
 248 * FUNCTION:    acpi_ex_load_op
 249 *
 250 * PARAMETERS:  obj_desc        - Region or Buffer/Field where the table will be
 251 *                                obtained
 252 *              target          - Where a handle to the table will be stored
 253 *              walk_state      - Current state
 254 *
 255 * RETURN:      Status
 256 *
 257 * DESCRIPTION: Load an ACPI table from a field or operation region
 258 *
 259 * NOTE: Region Fields (Field, bank_field, index_fields) are resolved to buffer
 260 *       objects before this code is reached.
 261 *
 262 *       If source is an operation region, it must refer to system_memory, as
 263 *       per the ACPI specification.
 264 *
 265 ******************************************************************************/
 266
 267acpi_status
 268acpi_ex_load_op(union acpi_operand_object *obj_desc,
 269                union acpi_operand_object *target,
 270                struct acpi_walk_state *walk_state)
 271{
 272        union acpi_operand_object *ddb_handle;
 273        struct acpi_table_header *table_header;
 274        struct acpi_table_header *table;
 275        u32 table_index;
 276        acpi_status status;
 277        u32 length;
 278
 279        ACPI_FUNCTION_TRACE(ex_load_op);
 280
 281        /* Source Object can be either an op_region or a Buffer/Field */
 282
 283        switch (obj_desc->common.type) {
 284        case ACPI_TYPE_REGION:
 285
 286                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 287                                  "Load table from Region %p\n", obj_desc));
 288
 289                /* Region must be system_memory (from ACPI spec) */
 290
 291                if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
 292                        return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 293                }
 294
 295                /*
 296                 * If the Region Address and Length have not been previously
 297                 * evaluated, evaluate them now and save the results.
 298                 */
 299                if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
 300                        status = acpi_ds_get_region_arguments(obj_desc);
 301                        if (ACPI_FAILURE(status)) {
 302                                return_ACPI_STATUS(status);
 303                        }
 304                }
 305
 306                /* Get the table header first so we can get the table length */
 307
 308                table_header = ACPI_ALLOCATE(sizeof(struct acpi_table_header));
 309                if (!table_header) {
 310                        return_ACPI_STATUS(AE_NO_MEMORY);
 311                }
 312
 313                status =
 314                    acpi_ex_region_read(obj_desc,
 315                                        sizeof(struct acpi_table_header),
 316                                        ACPI_CAST_PTR(u8, table_header));
 317                length = table_header->length;
 318                ACPI_FREE(table_header);
 319
 320                if (ACPI_FAILURE(status)) {
 321                        return_ACPI_STATUS(status);
 322                }
 323
 324                /* Must have at least an ACPI table header */
 325
 326                if (length < sizeof(struct acpi_table_header)) {
 327                        return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
 328                }
 329
 330                /*
 331                 * The original implementation simply mapped the table, with no copy.
 332                 * However, the memory region is not guaranteed to remain stable and
 333                 * we must copy the table to a local buffer. For example, the memory
 334                 * region is corrupted after suspend on some machines. Dynamically
 335                 * loaded tables are usually small, so this overhead is minimal.
 336                 *
 337                 * The latest implementation (5/2009) does not use a mapping at all.
 338                 * We use the low-level operation region interface to read the table
 339                 * instead of the obvious optimization of using a direct mapping.
 340                 * This maintains a consistent use of operation regions across the
 341                 * entire subsystem. This is important if additional processing must
 342                 * be performed in the (possibly user-installed) operation region
 343                 * handler. For example, acpi_exec and ASLTS depend on this.
 344                 */
 345
 346                /* Allocate a buffer for the table */
 347
 348                table = ACPI_ALLOCATE(length);
 349                if (!table) {
 350                        return_ACPI_STATUS(AE_NO_MEMORY);
 351                }
 352
 353                /* Read the entire table */
 354
 355                status = acpi_ex_region_read(obj_desc, length,
 356                                             ACPI_CAST_PTR(u8, table));
 357                if (ACPI_FAILURE(status)) {
 358                        ACPI_FREE(table);
 359                        return_ACPI_STATUS(status);
 360                }
 361                break;
 362
 363        case ACPI_TYPE_BUFFER:  /* Buffer or resolved region_field */
 364
 365                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 366                                  "Load table from Buffer or Field %p\n",
 367                                  obj_desc));
 368
 369                /* Must have at least an ACPI table header */
 370
 371                if (obj_desc->buffer.length < sizeof(struct acpi_table_header)) {
 372                        return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
 373                }
 374
 375                /* Get the actual table length from the table header */
 376
 377                table_header =
 378                    ACPI_CAST_PTR(struct acpi_table_header,
 379                                  obj_desc->buffer.pointer);
 380                length = table_header->length;
 381
 382                /* Table cannot extend beyond the buffer */
 383
 384                if (length > obj_desc->buffer.length) {
 385                        return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
 386                }
 387                if (length < sizeof(struct acpi_table_header)) {
 388                        return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
 389                }
 390
 391                /*
 392                 * Copy the table from the buffer because the buffer could be
 393                 * modified or even deleted in the future
 394                 */
 395                table = ACPI_ALLOCATE(length);
 396                if (!table) {
 397                        return_ACPI_STATUS(AE_NO_MEMORY);
 398                }
 399
 400                memcpy(table, table_header, length);
 401                break;
 402
 403        default:
 404
 405                return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 406        }
 407
 408        /* Install the new table into the local data structures */
 409
 410        ACPI_INFO(("Dynamic OEM Table Load:"));
 411        acpi_ex_exit_interpreter();
 412        status = acpi_tb_install_and_load_table(ACPI_PTR_TO_PHYSADDR(table),
 413                                                ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
 414                                                TRUE, &table_index);
 415        acpi_ex_enter_interpreter();
 416        if (ACPI_FAILURE(status)) {
 417
 418                /* Delete allocated table buffer */
 419
 420                ACPI_FREE(table);
 421                return_ACPI_STATUS(status);
 422        }
 423
 424        /*
 425         * Add the table to the namespace.
 426         *
 427         * Note: Load the table objects relative to the root of the namespace.
 428         * This appears to go against the ACPI specification, but we do it for
 429         * compatibility with other ACPI implementations.
 430         */
 431        status = acpi_ex_add_table(table_index, &ddb_handle);
 432        if (ACPI_FAILURE(status)) {
 433
 434                /* On error, table_ptr was deallocated above */
 435
 436                return_ACPI_STATUS(status);
 437        }
 438
 439        /* Complete the initialization/resolution of new objects */
 440
 441        acpi_ex_exit_interpreter();
 442        acpi_ns_initialize_objects();
 443        acpi_ex_enter_interpreter();
 444
 445        /* Store the ddb_handle into the Target operand */
 446
 447        status = acpi_ex_store(ddb_handle, target, walk_state);
 448        if (ACPI_FAILURE(status)) {
 449                (void)acpi_ex_unload_table(ddb_handle);
 450
 451                /* table_ptr was deallocated above */
 452
 453                acpi_ut_remove_reference(ddb_handle);
 454                return_ACPI_STATUS(status);
 455        }
 456
 457        /* Remove the reference by added by acpi_ex_store above */
 458
 459        acpi_ut_remove_reference(ddb_handle);
 460        return_ACPI_STATUS(status);
 461}
 462
 463/*******************************************************************************
 464 *
 465 * FUNCTION:    acpi_ex_unload_table
 466 *
 467 * PARAMETERS:  ddb_handle          - Handle to a previously loaded table
 468 *
 469 * RETURN:      Status
 470 *
 471 * DESCRIPTION: Unload an ACPI table
 472 *
 473 ******************************************************************************/
 474
 475acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
 476{
 477        acpi_status status = AE_OK;
 478        union acpi_operand_object *table_desc = ddb_handle;
 479        u32 table_index;
 480
 481        ACPI_FUNCTION_TRACE(ex_unload_table);
 482
 483        /*
 484         * Temporarily emit a warning so that the ASL for the machine can be
 485         * hopefully obtained. This is to say that the Unload() operator is
 486         * extremely rare if not completely unused.
 487         */
 488        ACPI_WARNING((AE_INFO, "Received request to unload an ACPI table"));
 489
 490        /*
 491         * May 2018: Unload is no longer supported for the following reasons:
 492         * 1) A correct implementation on some hosts may not be possible.
 493         * 2) Other ACPI implementations do not correctly/fully support it.
 494         * 3) It requires host device driver support which does not exist.
 495         *    (To properly support namespace unload out from underneath.)
 496         * 4) This AML operator has never been seen in the field.
 497         */
 498        ACPI_EXCEPTION((AE_INFO, AE_NOT_IMPLEMENTED,
 499                        "AML Unload operator is not supported"));
 500
 501        /*
 502         * Validate the handle
 503         * Although the handle is partially validated in acpi_ex_reconfiguration()
 504         * when it calls acpi_ex_resolve_operands(), the handle is more completely
 505         * validated here.
 506         *
 507         * Handle must be a valid operand object of type reference. Also, the
 508         * ddb_handle must still be marked valid (table has not been previously
 509         * unloaded)
 510         */
 511        if ((!ddb_handle) ||
 512            (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
 513            (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE) ||
 514            (!(ddb_handle->common.flags & AOPOBJ_DATA_VALID))) {
 515                return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 516        }
 517
 518        /* Get the table index from the ddb_handle */
 519
 520        table_index = table_desc->reference.value;
 521
 522        /*
 523         * Release the interpreter lock so that the table lock won't have
 524         * strict order requirement against it.
 525         */
 526        acpi_ex_exit_interpreter();
 527        status = acpi_tb_unload_table(table_index);
 528        acpi_ex_enter_interpreter();
 529
 530        /*
 531         * Invalidate the handle. We do this because the handle may be stored
 532         * in a named object and may not be actually deleted until much later.
 533         */
 534        if (ACPI_SUCCESS(status)) {
 535                ddb_handle->common.flags &= ~AOPOBJ_DATA_VALID;
 536        }
 537        return_ACPI_STATUS(status);
 538}
 539