blob: c5085b7ae8c962b4b24e2cf90e0fbe84c69fbbcf [file] [log] [blame]
Erik Schmauss95857632018-03-14 16:13:07 -07001// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/******************************************************************************
3 *
4 * Module Name: tbinstal - ACPI table installation and removal
5 *
Bob Mooreda6f8322018-01-04 10:06:38 -08006 * Copyright (C) 2000 - 2018, Intel Corp.
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 *
Erik Schmauss95857632018-03-14 16:13:07 -07008 *****************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07009
Linus Torvalds1da177e2005-04-16 15:20:36 -070010#include <acpi/acpi.h>
Len Browne2f7a772009-01-09 00:30:03 -050011#include "accommon.h"
Len Browne2f7a772009-01-09 00:30:03 -050012#include "actables.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070013
Linus Torvalds1da177e2005-04-16 15:20:36 -070014#define _COMPONENT ACPI_TABLES
Len Brown4be44fc2005-08-05 00:44:28 -040015ACPI_MODULE_NAME("tbinstal")
Linus Torvalds1da177e2005-04-16 15:20:36 -070016
Lv Zheng86dfc6f32014-04-04 12:38:57 +080017/*******************************************************************************
18 *
Bob Mooreed6f1d42014-04-04 12:39:26 +080019 * FUNCTION: acpi_tb_install_table_with_override
Lv Zheng86dfc6f32014-04-04 12:38:57 +080020 *
Lv Zheng8ec3f452015-08-25 10:29:01 +080021 * PARAMETERS: new_table_desc - New table descriptor to install
Lv Zhengcaf4a152014-04-04 12:39:18 +080022 * override - Whether override should be performed
Lv Zheng8ec3f452015-08-25 10:29:01 +080023 * table_index - Where the table index is returned
Lv Zheng86dfc6f32014-04-04 12:38:57 +080024 *
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 ******************************************************************************/
Lv Zheng86dfc6f32014-04-04 12:38:57 +080033void
Lv Zheng8ec3f452015-08-25 10:29:01 +080034acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc,
35 u8 override, u32 *table_index)
Lv Zheng86dfc6f32014-04-04 12:38:57 +080036{
Lv Zheng8ec3f452015-08-25 10:29:01 +080037 u32 i;
38 acpi_status status;
Bob Mooreed6f1d42014-04-04 12:39:26 +080039
Lv Zheng8ec3f452015-08-25 10:29:01 +080040 status = acpi_tb_get_next_table_descriptor(&i, NULL);
41 if (ACPI_FAILURE(status)) {
Lv Zheng86dfc6f32014-04-04 12:38:57 +080042 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070043 }
44
Bob Moored3ccaff2009-02-03 14:43:04 +080045 /*
46 * ACPI Table Override:
Lv Zheng86dfc6f32014-04-04 12:38:57 +080047 *
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.
Bob Moored3ccaff2009-02-03 14:43:04 +080051 */
Lv Zhengcaf4a152014-04-04 12:39:18 +080052 if (override) {
53 acpi_tb_override_table(new_table_desc);
54 }
Lv Zheng7f9fc992014-04-04 12:38:42 +080055
Lv Zheng8ec3f452015-08-25 10:29:01 +080056 acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list.tables[i],
Bob Mooreed6f1d42014-04-04 12:39:26 +080057 new_table_desc->address,
58 new_table_desc->flags,
59 new_table_desc->pointer);
Lv Zheng7f9fc992014-04-04 12:38:42 +080060
Lv Zheng86dfc6f32014-04-04 12:38:57 +080061 acpi_tb_print_table_header(new_table_desc->address,
62 new_table_desc->pointer);
63
Lv Zheng8ec3f452015-08-25 10:29:01 +080064 /* This synchronizes acpi_gbl_dsdt_index */
65
66 *table_index = i;
67
Lv Zheng86dfc6f32014-04-04 12:38:57 +080068 /* Set the global integer width (based upon revision of the DSDT) */
69
Lv Zheng8ec3f452015-08-25 10:29:01 +080070 if (i == acpi_gbl_dsdt_index) {
Lv Zheng86dfc6f32014-04-04 12:38:57 +080071 acpi_ut_set_integer_width(new_table_desc->pointer->revision);
72 }
73}
74
75/*******************************************************************************
76 *
Bob Mooreed6f1d42014-04-04 12:39:26 +080077 * FUNCTION: acpi_tb_install_standard_table
Lv Zheng86dfc6f32014-04-04 12:38:57 +080078 *
Lv Zheng8a216d72014-04-04 12:39:04 +080079 * PARAMETERS: address - Address of the table (might be a virtual
Lv Zheng86dfc6f32014-04-04 12:38:57 +080080 * address depending on the table_flags)
81 * flags - Flags for the table
82 * reload - Whether reload should be performed
Lv Zhengcaf4a152014-04-04 12:39:18 +080083 * override - Whether override should be performed
Lv Zheng86dfc6f32014-04-04 12:38:57 +080084 * table_index - Where the table index is returned
85 *
86 * RETURN: Status
87 *
Lv Zheng752db102016-09-07 14:06:17 +080088 * DESCRIPTION: This function is called to verify and install an ACPI table.
Lv Zheng86dfc6f32014-04-04 12:38:57 +080089 * When this function is called by "Load" or "LoadTable" opcodes,
90 * or by acpi_load_table() API, the "Reload" parameter is set.
91 * After sucessfully returning from this function, table is
92 * "INSTALLED" but not "VALIDATED".
93 *
94 ******************************************************************************/
95
96acpi_status
Bob Mooreed6f1d42014-04-04 12:39:26 +080097acpi_tb_install_standard_table(acpi_physical_address address,
98 u8 flags,
99 u8 reload, u8 override, u32 *table_index)
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800100{
101 u32 i;
102 acpi_status status = AE_OK;
103 struct acpi_table_desc new_table_desc;
104
Bob Mooreed6f1d42014-04-04 12:39:26 +0800105 ACPI_FUNCTION_TRACE(tb_install_standard_table);
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800106
Bob Mooreed6f1d42014-04-04 12:39:26 +0800107 /* Acquire a temporary table descriptor for validation */
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800108
Bob Mooreed6f1d42014-04-04 12:39:26 +0800109 status = acpi_tb_acquire_temp_table(&new_table_desc, address, flags);
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800110 if (ACPI_FAILURE(status)) {
Lv Zhengcc2080b2015-04-13 11:48:46 +0800111 ACPI_ERROR((AE_INFO,
112 "Could not acquire table length at %8.8X%8.8X",
113 ACPI_FORMAT_UINT64(address)));
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800114 return_ACPI_STATUS(status);
115 }
116
Lv Zhenga94e88c2014-04-04 12:39:11 +0800117 /*
118 * Optionally do not load any SSDTs from the RSDT/XSDT. This can
119 * be useful for debugging ACPI problems on some machines.
120 */
Bob Mooreed6f1d42014-04-04 12:39:26 +0800121 if (!reload &&
122 acpi_gbl_disable_ssdt_table_install &&
Lv Zhenga94e88c2014-04-04 12:39:11 +0800123 ACPI_COMPARE_NAME(&new_table_desc.signature, ACPI_SIG_SSDT)) {
Bob Moore05fb04b2016-02-19 14:16:42 +0800124 ACPI_INFO(("Ignoring installation of %4.4s at %8.8X%8.8X",
Lv Zheng6d3fd3c2015-04-13 11:48:37 +0800125 new_table_desc.signature.ascii,
Lv Zhengcc2080b2015-04-13 11:48:46 +0800126 ACPI_FORMAT_UINT64(address)));
Lv Zhenga94e88c2014-04-04 12:39:11 +0800127 goto release_and_exit;
128 }
129
Lv Zheng7a370522017-01-19 15:21:34 +0800130 /* Acquire the table lock */
131
132 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
133
Lv Zhengf9d472e2017-07-10 15:23:50 +0800134 /* Validate and verify a table before installation */
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800135
Lv Zhengf9d472e2017-07-10 15:23:50 +0800136 status = acpi_tb_verify_temp_table(&new_table_desc, NULL, &i);
137 if (ACPI_FAILURE(status)) {
138 if (status == AE_CTRL_TERMINATE) {
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800139 /*
Lv Zhengf9d472e2017-07-10 15:23:50 +0800140 * 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.
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800146 */
Lv Zhengf9d472e2017-07-10 15:23:50 +0800147 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);
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800151 }
Lv Zhengf9d472e2017-07-10 15:23:50 +0800152 goto unlock_and_exit;
Lv Zheng7f9fc992014-04-04 12:38:42 +0800153 }
Bob Moored3ccaff2009-02-03 14:43:04 +0800154
Bob Mooree56f5612008-07-04 10:48:43 +0800155 /* Add the table to the global root table list */
156
Lv Zheng8ec3f452015-08-25 10:29:01 +0800157 acpi_tb_install_table_with_override(&new_table_desc, override,
158 table_index);
Robert Moore0c9938c2005-07-29 15:15:00 -0700159
Lv Zheng9b019b02017-07-10 15:23:28 +0800160 /* Invoke table handler */
Lv Zhengbdbe5df2016-09-07 14:06:32 +0800161
Lv Zheng7a370522017-01-19 15:21:34 +0800162 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Lv Zheng9b019b02017-07-10 15:23:28 +0800163 acpi_tb_notify_table(ACPI_TABLE_EVENT_INSTALL, new_table_desc.pointer);
Lv Zheng7a370522017-01-19 15:21:34 +0800164 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
165
166unlock_and_exit:
167
168 /* Release the table lock */
169
170 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Lv Zhengbdbe5df2016-09-07 14:06:32 +0800171
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800172release_and_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173
Bob Mooreed6f1d42014-04-04 12:39:26 +0800174 /* Release the temporary table descriptor */
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800175
Bob Mooreed6f1d42014-04-04 12:39:26 +0800176 acpi_tb_release_temp_table(&new_table_desc);
Len Brown4be44fc2005-08-05 00:44:28 -0400177 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178}
179
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180/*******************************************************************************
181 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800182 * FUNCTION: acpi_tb_override_table
Bob Mooref7b004a2012-02-14 18:31:56 +0800183 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800184 * PARAMETERS: old_table_desc - Validated table descriptor to be
185 * overridden
Bob Mooref7b004a2012-02-14 18:31:56 +0800186 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800187 * RETURN: None
Bob Mooref7b004a2012-02-14 18:31:56 +0800188 *
189 * DESCRIPTION: Attempt table override by calling the OSL override functions.
190 * Note: If the table is overridden, then the entire new table
Lv Zheng7f9fc992014-04-04 12:38:42 +0800191 * is acquired and returned by this function.
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800192 * Before/after invocation, the table descriptor is in a state
193 * that is "VALIDATED".
Bob Mooref7b004a2012-02-14 18:31:56 +0800194 *
195 ******************************************************************************/
196
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800197void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
Bob Mooref7b004a2012-02-14 18:31:56 +0800198{
199 acpi_status status;
Lv Zheng7f9fc992014-04-04 12:38:42 +0800200 struct acpi_table_desc new_table_desc;
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800201 struct acpi_table_header *table;
202 acpi_physical_address address;
203 u32 length;
Erik Schmauss0fe0beb2018-03-14 16:13:05 -0700204 ACPI_ERROR_ONLY(char *override_type);
Bob Mooref7b004a2012-02-14 18:31:56 +0800205
206 /* (1) Attempt logical override (returns a logical address) */
207
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800208 status = acpi_os_table_override(old_table_desc->pointer, &table);
209 if (ACPI_SUCCESS(status) && table) {
Bob Mooreed6f1d42014-04-04 12:39:26 +0800210 acpi_tb_acquire_temp_table(&new_table_desc,
211 ACPI_PTR_TO_PHYSADDR(table),
212 ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL);
Erik Schmauss0fe0beb2018-03-14 16:13:05 -0700213 ACPI_ERROR_ONLY(override_type = "Logical");
Bob Mooref7b004a2012-02-14 18:31:56 +0800214 goto finish_override;
215 }
216
217 /* (2) Attempt physical override (returns a physical address) */
218
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800219 status = acpi_os_physical_table_override(old_table_desc->pointer,
220 &address, &length);
221 if (ACPI_SUCCESS(status) && address && length) {
Bob Mooreed6f1d42014-04-04 12:39:26 +0800222 acpi_tb_acquire_temp_table(&new_table_desc, address,
223 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL);
Erik Schmauss0fe0beb2018-03-14 16:13:05 -0700224 ACPI_ERROR_ONLY(override_type = "Physical");
Bob Mooref7b004a2012-02-14 18:31:56 +0800225 goto finish_override;
226 }
227
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800228 return; /* There was no override */
Bob Mooref7b004a2012-02-14 18:31:56 +0800229
Lv Zheng10622bf2013-10-29 09:30:02 +0800230finish_override:
Bob Mooref7b004a2012-02-14 18:31:56 +0800231
Lv Zhengf9d472e2017-07-10 15:23:50 +0800232 /*
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);
Lv Zheng7f9fc992014-04-04 12:38:42 +0800237 if (ACPI_FAILURE(status)) {
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800238 return;
Lv Zheng7f9fc992014-04-04 12:38:42 +0800239 }
240
Bob Moore05fb04b2016-02-19 14:16:42 +0800241 ACPI_INFO(("%4.4s 0x%8.8X%8.8X"
Lv Zheng1d0a0b22015-04-13 11:48:52 +0800242 " %s table override, new table: 0x%8.8X%8.8X",
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800243 old_table_desc->signature.ascii,
Lv Zheng1d0a0b22015-04-13 11:48:52 +0800244 ACPI_FORMAT_UINT64(old_table_desc->address),
245 override_type, ACPI_FORMAT_UINT64(new_table_desc.address)));
Bob Mooref7b004a2012-02-14 18:31:56 +0800246
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800247 /* We can now uninstall the original table */
Bob Mooref7b004a2012-02-14 18:31:56 +0800248
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800249 acpi_tb_uninstall_table(old_table_desc);
Bob Mooref7b004a2012-02-14 18:31:56 +0800250
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800251 /*
252 * Replace the original table descriptor and keep its state as
253 * "VALIDATED".
254 */
Bob Mooreed6f1d42014-04-04 12:39:26 +0800255 acpi_tb_init_table_descriptor(old_table_desc, new_table_desc.address,
256 new_table_desc.flags,
257 new_table_desc.pointer);
Lv Zheng47d68c72014-05-31 08:14:44 +0800258 acpi_tb_validate_temp_table(old_table_desc);
Bob Mooref7b004a2012-02-14 18:31:56 +0800259
Bob Mooreed6f1d42014-04-04 12:39:26 +0800260 /* Release the temporary table descriptor */
Bob Mooref7b004a2012-02-14 18:31:56 +0800261
Bob Mooreed6f1d42014-04-04 12:39:26 +0800262 acpi_tb_release_temp_table(&new_table_desc);
Bob Mooref7b004a2012-02-14 18:31:56 +0800263}
264
265/*******************************************************************************
266 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800267 * FUNCTION: acpi_tb_uninstall_table
Bob Mooref3d2e782007-02-02 19:48:18 +0300268 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800269 * PARAMETERS: table_desc - Table descriptor
Bob Mooref3d2e782007-02-02 19:48:18 +0300270 *
271 * RETURN: None
272 *
273 * DESCRIPTION: Delete one internal ACPI table
274 *
275 ******************************************************************************/
276
Lv Zheng7f9fc992014-04-04 12:38:42 +0800277void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc)
Bob Mooref3d2e782007-02-02 19:48:18 +0300278{
Lv Zheng55829822014-04-04 12:38:18 +0800279
Lv Zheng7f9fc992014-04-04 12:38:42 +0800280 ACPI_FUNCTION_TRACE(tb_uninstall_table);
Lv Zheng55829822014-04-04 12:38:18 +0800281
Lv Zheng7f9fc992014-04-04 12:38:42 +0800282 /* Table must be installed */
283
284 if (!table_desc->address) {
285 return_VOID;
Bob Mooref3d2e782007-02-02 19:48:18 +0300286 }
Lv Zheng55829822014-04-04 12:38:18 +0800287
Lv Zheng7f9fc992014-04-04 12:38:42 +0800288 acpi_tb_invalidate_table(table_desc);
Chao Guan1d1ea1b2013-06-08 00:58:14 +0000289
Lv Zheng7f9fc992014-04-04 12:38:42 +0800290 if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
Bob Mooreed6f1d42014-04-04 12:39:26 +0800291 ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) {
Lv Zheng6d3fd3c2015-04-13 11:48:37 +0800292 ACPI_FREE(ACPI_PHYSADDR_TO_PTR(table_desc->address));
Bob Mooref3d2e782007-02-02 19:48:18 +0300293 }
294
Lv Zheng7f9fc992014-04-04 12:38:42 +0800295 table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL);
Lv Zheng7f9fc992014-04-04 12:38:42 +0800296 return_VOID;
Bob Mooref3d2e782007-02-02 19:48:18 +0300297}