Linux 4.19.133
[linux/fpc-iii.git] / drivers / acpi / acpica / tbinstal.c
blob5f8e7b561c90b3532757fc653a7660ec4faba570
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
4 * Module Name: tbinstal - ACPI table installation and removal
6 * Copyright (C) 2000 - 2018, Intel Corp.
8 *****************************************************************************/
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12 #include "actables.h"
14 #define _COMPONENT ACPI_TABLES
15 ACPI_MODULE_NAME("tbinstal")
17 /*******************************************************************************
19 * FUNCTION: acpi_tb_install_table_with_override
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
25 * RETURN: None
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.
32 ******************************************************************************/
33 void
34 acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc,
35 u8 override, u32 *table_index)
37 u32 i;
38 acpi_status status;
40 status = acpi_tb_get_next_table_descriptor(&i, NULL);
41 if (ACPI_FAILURE(status)) {
42 return;
46 * ACPI Table Override:
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.
52 if (override) {
53 acpi_tb_override_table(new_table_desc);
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);
61 acpi_tb_print_table_header(new_table_desc->address,
62 new_table_desc->pointer);
64 /* This synchronizes acpi_gbl_dsdt_index */
66 *table_index = i;
68 /* Set the global integer width (based upon revision of the DSDT) */
70 if (i == acpi_gbl_dsdt_index) {
71 acpi_ut_set_integer_width(new_table_desc->pointer->revision);
75 /*******************************************************************************
77 * FUNCTION: acpi_tb_install_standard_table
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
86 * RETURN: Status
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".
94 ******************************************************************************/
96 acpi_status
97 acpi_tb_install_standard_table(acpi_physical_address address,
98 u8 flags,
99 u8 reload, u8 override, u32 *table_index)
101 u32 i;
102 acpi_status status = AE_OK;
103 struct acpi_table_desc new_table_desc;
105 ACPI_FUNCTION_TRACE(tb_install_standard_table);
107 /* Acquire a temporary table descriptor for validation */
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);
118 * Optionally do not load any SSDTs from the RSDT/XSDT. This can
119 * be useful for debugging ACPI problems on some machines.
121 if (!reload &&
122 acpi_gbl_disable_ssdt_table_install &&
123 ACPI_COMPARE_NAME(&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;
130 /* Acquire the table lock */
132 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
134 /* Validate and verify a table before installation */
136 status = acpi_tb_verify_temp_table(&new_table_desc, NULL, &i);
137 if (ACPI_FAILURE(status)) {
138 if (status == AE_CTRL_TERMINATE) {
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.
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);
152 goto unlock_and_exit;
155 /* Add the table to the global root table list */
157 acpi_tb_install_table_with_override(&new_table_desc, override,
158 table_index);
160 /* Invoke table handler */
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);
166 unlock_and_exit:
168 /* Release the table lock */
170 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
172 release_and_exit:
174 /* Release the temporary table descriptor */
176 acpi_tb_release_temp_table(&new_table_desc);
177 return_ACPI_STATUS(status);
180 /*******************************************************************************
182 * FUNCTION: acpi_tb_override_table
184 * PARAMETERS: old_table_desc - Validated table descriptor to be
185 * overridden
187 * RETURN: None
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".
195 ******************************************************************************/
197 void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
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);
206 /* (1) Attempt logical override (returns a logical address) */
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;
217 /* (2) Attempt physical override (returns a physical address) */
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;
228 return; /* There was no override */
230 finish_override:
233 * Validate and verify a table before overriding, no nested table
234 * duplication check as it's too complicated and unnecessary.
236 status = acpi_tb_verify_temp_table(&new_table_desc, NULL, NULL);
237 if (ACPI_FAILURE(status)) {
238 return;
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)));
247 /* We can now uninstall the original table */
249 acpi_tb_uninstall_table(old_table_desc);
252 * Replace the original table descriptor and keep its state as
253 * "VALIDATED".
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);
260 /* Release the temporary table descriptor */
262 acpi_tb_release_temp_table(&new_table_desc);
265 /*******************************************************************************
267 * FUNCTION: acpi_tb_uninstall_table
269 * PARAMETERS: table_desc - Table descriptor
271 * RETURN: None
273 * DESCRIPTION: Delete one internal ACPI table
275 ******************************************************************************/
277 void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc)
280 ACPI_FUNCTION_TRACE(tb_uninstall_table);
282 /* Table must be installed */
284 if (!table_desc->address) {
285 return_VOID;
288 acpi_tb_invalidate_table(table_desc);
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));
295 table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL);
296 return_VOID;