linux/drivers/acpi/acpica/tbinstal.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Module Name: tbinstal - ACPI table installation and removal
   4 *
   5 *****************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2017, 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 "actables.h"
  47
  48#define _COMPONENT          ACPI_TABLES
  49ACPI_MODULE_NAME("tbinstal")
  50
  51/*******************************************************************************
  52 *
  53 * FUNCTION:    acpi_tb_install_table_with_override
  54 *
  55 * PARAMETERS:  new_table_desc          - New table descriptor to install
  56 *              override                - Whether override should be performed
  57 *              table_index             - Where the table index is returned
  58 *
  59 * RETURN:      None
  60 *
  61 * DESCRIPTION: Install an ACPI table into the global data structure. The
  62 *              table override mechanism is called to allow the host
  63 *              OS to replace any table before it is installed in the root
  64 *              table array.
  65 *
  66 ******************************************************************************/
  67void
  68acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc,
  69                                    u8 override, u32 *table_index)
  70{
  71        u32 i;
  72        acpi_status status;
  73
  74        status = acpi_tb_get_next_table_descriptor(&i, NULL);
  75        if (ACPI_FAILURE(status)) {
  76                return;
  77        }
  78
  79        /*
  80         * ACPI Table Override:
  81         *
  82         * Before we install the table, let the host OS override it with a new
  83         * one if desired. Any table within the RSDT/XSDT can be replaced,
  84         * including the DSDT which is pointed to by the FADT.
  85         */
  86        if (override) {
  87                acpi_tb_override_table(new_table_desc);
  88        }
  89
  90        acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list.tables[i],
  91                                      new_table_desc->address,
  92                                      new_table_desc->flags,
  93                                      new_table_desc->pointer);
  94
  95        acpi_tb_print_table_header(new_table_desc->address,
  96                                   new_table_desc->pointer);
  97
  98        /* This synchronizes acpi_gbl_dsdt_index */
  99
 100        *table_index = i;
 101
 102        /* Set the global integer width (based upon revision of the DSDT) */
 103
 104        if (i == acpi_gbl_dsdt_index) {
 105                acpi_ut_set_integer_width(new_table_desc->pointer->revision);
 106        }
 107}
 108
 109/*******************************************************************************
 110 *
 111 * FUNCTION:    acpi_tb_install_standard_table
 112 *
 113 * PARAMETERS:  address             - Address of the table (might be a virtual
 114 *                                    address depending on the table_flags)
 115 *              flags               - Flags for the table
 116 *              reload              - Whether reload should be performed
 117 *              override            - Whether override should be performed
 118 *              table_index         - Where the table index is returned
 119 *
 120 * RETURN:      Status
 121 *
 122 * DESCRIPTION: This function is called to verify and install an ACPI table.
 123 *              When this function is called by "Load" or "LoadTable" opcodes,
 124 *              or by acpi_load_table() API, the "Reload" parameter is set.
 125 *              After sucessfully returning from this function, table is
 126 *              "INSTALLED" but not "VALIDATED".
 127 *
 128 ******************************************************************************/
 129
 130acpi_status
 131acpi_tb_install_standard_table(acpi_physical_address address,
 132                               u8 flags,
 133                               u8 reload, u8 override, u32 *table_index)
 134{
 135        u32 i;
 136        acpi_status status = AE_OK;
 137        struct acpi_table_desc new_table_desc;
 138
 139        ACPI_FUNCTION_TRACE(tb_install_standard_table);
 140
 141        /* Acquire a temporary table descriptor for validation */
 142
 143        status = acpi_tb_acquire_temp_table(&new_table_desc, address, flags);
 144        if (ACPI_FAILURE(status)) {
 145                ACPI_ERROR((AE_INFO,
 146                            "Could not acquire table length at %8.8X%8.8X",
 147                            ACPI_FORMAT_UINT64(address)));
 148                return_ACPI_STATUS(status);
 149        }
 150
 151        /*
 152         * Optionally do not load any SSDTs from the RSDT/XSDT. This can
 153         * be useful for debugging ACPI problems on some machines.
 154         */
 155        if (!reload &&
 156            acpi_gbl_disable_ssdt_table_install &&
 157            ACPI_COMPARE_NAME(&new_table_desc.signature, ACPI_SIG_SSDT)) {
 158                ACPI_INFO(("Ignoring installation of %4.4s at %8.8X%8.8X",
 159                           new_table_desc.signature.ascii,
 160                           ACPI_FORMAT_UINT64(address)));
 161                goto release_and_exit;
 162        }
 163
 164        /* Acquire the table lock */
 165
 166        (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 167
 168        /* Validate and verify a table before installation */
 169
 170        status = acpi_tb_verify_temp_table(&new_table_desc, NULL, &i);
 171        if (ACPI_FAILURE(status)) {
 172                if (status == AE_CTRL_TERMINATE) {
 173                        /*
 174                         * Table was unloaded, allow it to be reloaded.
 175                         * As we are going to return AE_OK to the caller, we should
 176                         * take the responsibility of freeing the input descriptor.
 177                         * Refill the input descriptor to ensure
 178                         * acpi_tb_install_table_with_override() can be called again to
 179                         * indicate the re-installation.
 180                         */
 181                        acpi_tb_uninstall_table(&new_table_desc);
 182                        (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
 183                        *table_index = i;
 184                        return_ACPI_STATUS(AE_OK);
 185                }
 186                goto unlock_and_exit;
 187        }
 188
 189        /* Add the table to the global root table list */
 190
 191        acpi_tb_install_table_with_override(&new_table_desc, override,
 192                                            table_index);
 193
 194        /* Invoke table handler */
 195
 196        (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
 197        acpi_tb_notify_table(ACPI_TABLE_EVENT_INSTALL, new_table_desc.pointer);
 198        (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 199
 200unlock_and_exit:
 201
 202        /* Release the table lock */
 203
 204        (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
 205
 206release_and_exit:
 207
 208        /* Release the temporary table descriptor */
 209
 210        acpi_tb_release_temp_table(&new_table_desc);
 211        return_ACPI_STATUS(status);
 212}
 213
 214/*******************************************************************************
 215 *
 216 * FUNCTION:    acpi_tb_override_table
 217 *
 218 * PARAMETERS:  old_table_desc      - Validated table descriptor to be
 219 *                                    overridden
 220 *
 221 * RETURN:      None
 222 *
 223 * DESCRIPTION: Attempt table override by calling the OSL override functions.
 224 *              Note: If the table is overridden, then the entire new table
 225 *              is acquired and returned by this function.
 226 *              Before/after invocation, the table descriptor is in a state
 227 *              that is "VALIDATED".
 228 *
 229 ******************************************************************************/
 230
 231void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
 232{
 233        acpi_status status;
 234        char *override_type;
 235        struct acpi_table_desc new_table_desc;
 236        struct acpi_table_header *table;
 237        acpi_physical_address address;
 238        u32 length;
 239
 240        /* (1) Attempt logical override (returns a logical address) */
 241
 242        status = acpi_os_table_override(old_table_desc->pointer, &table);
 243        if (ACPI_SUCCESS(status) && table) {
 244                acpi_tb_acquire_temp_table(&new_table_desc,
 245                                           ACPI_PTR_TO_PHYSADDR(table),
 246                                           ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL);
 247                override_type = "Logical";
 248                goto finish_override;
 249        }
 250
 251        /* (2) Attempt physical override (returns a physical address) */
 252
 253        status = acpi_os_physical_table_override(old_table_desc->pointer,
 254                                                 &address, &length);
 255        if (ACPI_SUCCESS(status) && address && length) {
 256                acpi_tb_acquire_temp_table(&new_table_desc, address,
 257                                           ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL);
 258                override_type = "Physical";
 259                goto finish_override;
 260        }
 261
 262        return;                 /* There was no override */
 263
 264finish_override:
 265
 266        /*
 267         * Validate and verify a table before overriding, no nested table
 268         * duplication check as it's too complicated and unnecessary.
 269         */
 270        status = acpi_tb_verify_temp_table(&new_table_desc, NULL, NULL);
 271        if (ACPI_FAILURE(status)) {
 272                return;
 273        }
 274
 275        ACPI_INFO(("%4.4s 0x%8.8X%8.8X"
 276                   " %s table override, new table: 0x%8.8X%8.8X",
 277                   old_table_desc->signature.ascii,
 278                   ACPI_FORMAT_UINT64(old_table_desc->address),
 279                   override_type, ACPI_FORMAT_UINT64(new_table_desc.address)));
 280
 281        /* We can now uninstall the original table */
 282
 283        acpi_tb_uninstall_table(old_table_desc);
 284
 285        /*
 286         * Replace the original table descriptor and keep its state as
 287         * "VALIDATED".
 288         */
 289        acpi_tb_init_table_descriptor(old_table_desc, new_table_desc.address,
 290                                      new_table_desc.flags,
 291                                      new_table_desc.pointer);
 292        acpi_tb_validate_temp_table(old_table_desc);
 293
 294        /* Release the temporary table descriptor */
 295
 296        acpi_tb_release_temp_table(&new_table_desc);
 297}
 298
 299/*******************************************************************************
 300 *
 301 * FUNCTION:    acpi_tb_uninstall_table
 302 *
 303 * PARAMETERS:  table_desc          - Table descriptor
 304 *
 305 * RETURN:      None
 306 *
 307 * DESCRIPTION: Delete one internal ACPI table
 308 *
 309 ******************************************************************************/
 310
 311void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc)
 312{
 313
 314        ACPI_FUNCTION_TRACE(tb_uninstall_table);
 315
 316        /* Table must be installed */
 317
 318        if (!table_desc->address) {
 319                return_VOID;
 320        }
 321
 322        acpi_tb_invalidate_table(table_desc);
 323
 324        if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
 325            ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) {
 326                ACPI_FREE(ACPI_PHYSADDR_TO_PTR(table_desc->address));
 327        }
 328
 329        table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL);
 330        return_VOID;
 331}
 332