root/drivers/acpi/acpica/tbinstal.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_tb_install_standard_table
  3. acpi_tb_override_table
  4. acpi_tb_uninstall_table

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

/* [<][>][^][v][top][bottom][index][help] */