LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - tbinstal.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 45 81 55.6 %
Date: 2022-04-01 14:58:12 Functions: 3 4 75.0 %
Branches: 12 34 35.3 %

           Branch data     Line data    Source code
       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 - 2020, 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                 :         15 : acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc,
      35                 :            :                                     u8 override, u32 *table_index)
      36                 :            : {
      37                 :         15 :         u32 i;
      38                 :         15 :         acpi_status status;
      39                 :            : 
      40                 :         15 :         status = acpi_tb_get_next_table_descriptor(&i, NULL);
      41         [ -  + ]:         15 :         if (ACPI_FAILURE(status)) {
      42                 :          0 :                 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         [ +  - ]:         15 :         if (override) {
      53                 :         15 :                 acpi_tb_override_table(new_table_desc);
      54                 :            :         }
      55                 :            : 
      56                 :         15 :         acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list.tables[i],
      57                 :            :                                       new_table_desc->address,
      58                 :         15 :                                       new_table_desc->flags,
      59                 :            :                                       new_table_desc->pointer);
      60                 :            : 
      61                 :         15 :         acpi_tb_print_table_header(new_table_desc->address,
      62                 :            :                                    new_table_desc->pointer);
      63                 :            : 
      64                 :            :         /* This synchronizes acpi_gbl_dsdt_index */
      65                 :            : 
      66                 :         15 :         *table_index = i;
      67                 :            : 
      68                 :            :         /* Set the global integer width (based upon revision of the DSDT) */
      69                 :            : 
      70         [ +  + ]:         15 :         if (i == acpi_gbl_dsdt_index) {
      71                 :          3 :                 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                 :         15 : acpi_tb_install_standard_table(acpi_physical_address address,
      98                 :            :                                u8 flags,
      99                 :            :                                u8 reload, u8 override, u32 *table_index)
     100                 :            : {
     101                 :         15 :         u32 i;
     102                 :         15 :         acpi_status status = AE_OK;
     103                 :         15 :         struct acpi_table_desc new_table_desc;
     104                 :            : 
     105                 :         15 :         ACPI_FUNCTION_TRACE(tb_install_standard_table);
     106                 :            : 
     107                 :            :         /* Acquire a temporary table descriptor for validation */
     108                 :            : 
     109                 :         15 :         status = acpi_tb_acquire_temp_table(&new_table_desc, address, flags);
     110         [ -  + ]:         15 :         if (ACPI_FAILURE(status)) {
     111                 :          0 :                 ACPI_ERROR((AE_INFO,
     112                 :            :                             "Could not acquire table length at %8.8X%8.8X",
     113                 :            :                             ACPI_FORMAT_UINT64(address)));
     114                 :          0 :                 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   [ +  -  -  + ]:         15 :         if (!reload &&
     122                 :          0 :             acpi_gbl_disable_ssdt_table_install &&
     123         [ #  # ]:          0 :             ACPI_COMPARE_NAMESEG(&new_table_desc.signature, ACPI_SIG_SSDT)) {
     124                 :          0 :                 ACPI_INFO(("Ignoring installation of %4.4s at %8.8X%8.8X",
     125                 :            :                            new_table_desc.signature.ascii,
     126                 :            :                            ACPI_FORMAT_UINT64(address)));
     127                 :          0 :                 goto release_and_exit;
     128                 :            :         }
     129                 :            : 
     130                 :            :         /* Acquire the table lock */
     131                 :            : 
     132                 :         15 :         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
     133                 :            : 
     134                 :            :         /* Validate and verify a table before installation */
     135                 :            : 
     136                 :         15 :         status = acpi_tb_verify_temp_table(&new_table_desc, NULL, &i);
     137         [ -  + ]:         15 :         if (ACPI_FAILURE(status)) {
     138         [ #  # ]:          0 :                 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                 :          0 :                         acpi_tb_uninstall_table(&new_table_desc);
     148                 :          0 :                         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
     149                 :          0 :                         *table_index = i;
     150                 :          0 :                         return_ACPI_STATUS(AE_OK);
     151                 :            :                 }
     152                 :          0 :                 goto unlock_and_exit;
     153                 :            :         }
     154                 :            : 
     155                 :            :         /* Add the table to the global root table list */
     156                 :            : 
     157                 :         15 :         acpi_tb_install_table_with_override(&new_table_desc, override,
     158                 :            :                                             table_index);
     159                 :            : 
     160                 :            :         /* Invoke table handler */
     161                 :            : 
     162                 :         15 :         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
     163                 :         15 :         acpi_tb_notify_table(ACPI_TABLE_EVENT_INSTALL, new_table_desc.pointer);
     164                 :         15 :         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
     165                 :            : 
     166                 :         15 : unlock_and_exit:
     167                 :            : 
     168                 :            :         /* Release the table lock */
     169                 :            : 
     170                 :         15 :         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
     171                 :            : 
     172                 :         15 : release_and_exit:
     173                 :            : 
     174                 :            :         /* Release the temporary table descriptor */
     175                 :            : 
     176                 :         15 :         acpi_tb_release_temp_table(&new_table_desc);
     177                 :         15 :         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                 :         15 : void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
     198                 :            : {
     199                 :         15 :         acpi_status status;
     200                 :         15 :         struct acpi_table_desc new_table_desc;
     201                 :         15 :         struct acpi_table_header *table;
     202                 :         15 :         acpi_physical_address address;
     203                 :         15 :         u32 length;
     204                 :         15 :         ACPI_ERROR_ONLY(char *override_type);
     205                 :            : 
     206                 :            :         /* (1) Attempt logical override (returns a logical address) */
     207                 :            : 
     208                 :         15 :         status = acpi_os_table_override(old_table_desc->pointer, &table);
     209   [ +  -  -  + ]:         15 :         if (ACPI_SUCCESS(status) && table) {
     210                 :          0 :                 acpi_tb_acquire_temp_table(&new_table_desc,
     211                 :            :                                            ACPI_PTR_TO_PHYSADDR(table),
     212                 :            :                                            ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL);
     213                 :          0 :                 ACPI_ERROR_ONLY(override_type = "Logical");
     214                 :          0 :                 goto finish_override;
     215                 :            :         }
     216                 :            : 
     217                 :            :         /* (2) Attempt physical override (returns a physical address) */
     218                 :            : 
     219                 :         15 :         status = acpi_os_physical_table_override(old_table_desc->pointer,
     220                 :            :                                                  &address, &length);
     221   [ +  -  -  +  :         15 :         if (ACPI_SUCCESS(status) && address && length) {
                   -  - ]
     222                 :          0 :                 acpi_tb_acquire_temp_table(&new_table_desc, address,
     223                 :            :                                            ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL);
     224                 :          0 :                 ACPI_ERROR_ONLY(override_type = "Physical");
     225                 :          0 :                 goto finish_override;
     226                 :            :         }
     227                 :            : 
     228                 :         15 :         return;                 /* There was no override */
     229                 :            : 
     230                 :          0 : 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                 :          0 :         status = acpi_tb_verify_temp_table(&new_table_desc, NULL, NULL);
     237         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     238                 :            :                 return;
     239                 :            :         }
     240                 :            : 
     241                 :          0 :         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                 :          0 :         acpi_tb_uninstall_table(old_table_desc);
     250                 :            : 
     251                 :            :         /*
     252                 :            :          * Replace the original table descriptor and keep its state as
     253                 :            :          * "VALIDATED".
     254                 :            :          */
     255                 :          0 :         acpi_tb_init_table_descriptor(old_table_desc, new_table_desc.address,
     256                 :          0 :                                       new_table_desc.flags,
     257                 :            :                                       new_table_desc.pointer);
     258                 :          0 :         acpi_tb_validate_temp_table(old_table_desc);
     259                 :            : 
     260                 :            :         /* Release the temporary table descriptor */
     261                 :            : 
     262                 :          0 :         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                 :          0 : void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc)
     278                 :            : {
     279                 :            : 
     280                 :          0 :         ACPI_FUNCTION_TRACE(tb_uninstall_table);
     281                 :            : 
     282                 :            :         /* Table must be installed */
     283                 :            : 
     284         [ #  # ]:          0 :         if (!table_desc->address) {
     285                 :            :                 return_VOID;
     286                 :            :         }
     287                 :            : 
     288                 :          0 :         acpi_tb_invalidate_table(table_desc);
     289                 :            : 
     290         [ #  # ]:          0 :         if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
     291                 :            :             ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) {
     292                 :          0 :                 ACPI_FREE(ACPI_PHYSADDR_TO_PTR(table_desc->address));
     293                 :            :         }
     294                 :            : 
     295                 :          0 :         table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL);
     296                 :          0 :         return_VOID;
     297                 :            : }

Generated by: LCOV version 1.14