blob: 9835213269e66facf9b5956969f46c842f3a152b [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/******************************************************************************
2 *
3 * Module Name: tbinstal - ACPI table installation and removal
4 *
5 *****************************************************************************/
6
7/*
Bob Moorefbb7a2d2014-02-08 09:42:25 +08008 * Copyright (C) 2000 - 2014, Intel Corp.
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * 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
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <acpi/acpi.h>
Len Browne2f7a772009-01-09 00:30:03 -050045#include "accommon.h"
46#include "acnamesp.h"
47#include "actables.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#define _COMPONENT ACPI_TABLES
Len Brown4be44fc2005-08-05 00:44:28 -040050ACPI_MODULE_NAME("tbinstal")
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Lv Zheng86dfc6f32014-04-04 12:38:57 +080052/* Local prototypes */
53static acpi_status
54acpi_tb_acquire_temporal_table(struct acpi_table_desc *table_desc,
55 acpi_physical_address address, u8 flags);
56
57static void acpi_tb_release_temporal_table(struct acpi_table_desc *table_desc);
58
59static acpi_status acpi_tb_acquire_root_table_entry(u32 *table_index);
60
61static u8
62acpi_tb_is_equivalent_table(struct acpi_table_desc *table_desc,
63 u32 table_index);
64
Lv Zheng7f9fc992014-04-04 12:38:42 +080065/*******************************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 *
Lv Zheng7f9fc992014-04-04 12:38:42 +080067 * FUNCTION: acpi_tb_acquire_table
Linus Torvalds1da177e2005-04-16 15:20:36 -070068 *
Lv Zheng7f9fc992014-04-04 12:38:42 +080069 * PARAMETERS: table_desc - Table descriptor
70 * table_ptr - Where table is returned
71 * table_length - Where table length is returned
72 * table_flags - Where table allocation flags are returned
Linus Torvalds1da177e2005-04-16 15:20:36 -070073 *
74 * RETURN: Status
75 *
Lv Zheng7f9fc992014-04-04 12:38:42 +080076 * DESCRIPTION: Acquire a table. It can be used for tables not maintained in
77 * acpi_gbl_root_table_list.
78 *
79 ******************************************************************************/
Lv Zheng86dfc6f32014-04-04 12:38:57 +080080
Lv Zheng7f9fc992014-04-04 12:38:42 +080081acpi_status
82acpi_tb_acquire_table(struct acpi_table_desc *table_desc,
83 struct acpi_table_header **table_ptr,
84 u32 *table_length, u8 *table_flags)
85{
86 struct acpi_table_header *table = NULL;
87
88 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
Lv Zheng8a216d72014-04-04 12:39:04 +080089 case ACPI_TABLE_ORIGIN_INTERN_PHYSICAL:
Lv Zheng7f9fc992014-04-04 12:38:42 +080090
91 table =
92 acpi_os_map_memory(table_desc->address, table_desc->length);
93 break;
94
Lv Zheng8a216d72014-04-04 12:39:04 +080095 case ACPI_TABLE_ORIGIN_INTERN_VIRTUAL:
96 case ACPI_TABLE_ORIGIN_EXTERN_VIRTUAL:
Lv Zheng7f9fc992014-04-04 12:38:42 +080097
98 table =
99 ACPI_CAST_PTR(struct acpi_table_header,
100 table_desc->address);
101 break;
102
103 default:
104
105 break;
106 }
107
108 /* Table is not valid yet */
109
110 if (!table) {
111 return (AE_NO_MEMORY);
112 }
113
114 /* Fill the return values */
115
116 *table_ptr = table;
117 *table_length = table_desc->length;
118 *table_flags = table_desc->flags;
119
120 return (AE_OK);
121}
122
123/*******************************************************************************
124 *
125 * FUNCTION: acpi_tb_release_table
126 *
127 * PARAMETERS: table - Pointer for the table
128 * table_length - Length for the table
129 * table_flags - Allocation flags for the table
130 *
131 * RETURN: None
132 *
133 * DESCRIPTION: Release a table. The reversal of acpi_tb_acquire_table().
134 *
135 ******************************************************************************/
136
137void
138acpi_tb_release_table(struct acpi_table_header *table,
139 u32 table_length, u8 table_flags)
140{
141 switch (table_flags & ACPI_TABLE_ORIGIN_MASK) {
Lv Zheng8a216d72014-04-04 12:39:04 +0800142 case ACPI_TABLE_ORIGIN_INTERN_PHYSICAL:
Lv Zheng7f9fc992014-04-04 12:38:42 +0800143
144 acpi_os_unmap_memory(table, table_length);
145 break;
146
Lv Zheng8a216d72014-04-04 12:39:04 +0800147 case ACPI_TABLE_ORIGIN_INTERN_VIRTUAL:
148 case ACPI_TABLE_ORIGIN_EXTERN_VIRTUAL:
Lv Zheng7f9fc992014-04-04 12:38:42 +0800149 default:
150
151 break;
152 }
153}
154
155/******************************************************************************
156 *
157 * FUNCTION: acpi_tb_validate_table
158 *
159 * PARAMETERS: table_desc - Table descriptor
160 *
161 * RETURN: Status
162 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800163 * DESCRIPTION: This function is called to validate the table, the returned
164 * table descriptor is in "VALIDATED" state.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300166 *****************************************************************************/
Lv Zheng7f9fc992014-04-04 12:38:42 +0800167
168acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169{
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300170 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171
Lv Zheng7f9fc992014-04-04 12:38:42 +0800172 ACPI_FUNCTION_TRACE(tb_validate_table);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173
Lv Zheng7f9fc992014-04-04 12:38:42 +0800174 /* Validate the table if necessary */
Robert Moore44f6c012005-04-18 22:49:35 -0400175
Bob Mooref3d2e782007-02-02 19:48:18 +0300176 if (!table_desc->pointer) {
Lv Zheng7f9fc992014-04-04 12:38:42 +0800177 status = acpi_tb_acquire_table(table_desc, &table_desc->pointer,
178 &table_desc->length,
179 &table_desc->flags);
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800180 if (!table_desc->pointer) {
181 status = AE_NO_MEMORY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 }
183 }
184
Bob Moorec5fc42a2007-02-02 19:48:19 +0300185 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186}
187
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188/*******************************************************************************
189 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800190 * FUNCTION: acpi_tb_invalidate_table
191 *
192 * PARAMETERS: table_desc - Table descriptor
193 *
194 * RETURN: None
195 *
196 * DESCRIPTION: Invalidate one internal ACPI table, this is reversal of
197 * acpi_tb_validate_table().
198 *
199 ******************************************************************************/
200
201void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc)
202{
203
204 ACPI_FUNCTION_TRACE(tb_invalidate_table);
205
206 /* Table must be validated */
207
208 if (!table_desc->pointer) {
209 return_VOID;
210 }
211
212 acpi_tb_release_table(table_desc->pointer, table_desc->length,
213 table_desc->flags);
214 table_desc->pointer = NULL;
215
216 return_VOID;
217}
218
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800219/******************************************************************************
Lv Zheng7f9fc992014-04-04 12:38:42 +0800220 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800221 * FUNCTION: acpi_tb_verify_table
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 *
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300223 * PARAMETERS: table_desc - Table descriptor
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800224 * signature - Table signature to verify
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225 *
226 * RETURN: Status
227 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800228 * DESCRIPTION: This function is called to validate and verify the table, the
229 * returned table descriptor is in "VALIDATED" state.
230 *
231 *****************************************************************************/
232
233acpi_status
234acpi_tb_verify_table(struct acpi_table_desc *table_desc, char *signature)
235{
236 acpi_status status = AE_OK;
237
238 ACPI_FUNCTION_TRACE(tb_verify_table);
239
240 /* Validate the table */
241
242 status = acpi_tb_validate_table(table_desc);
243 if (ACPI_FAILURE(status)) {
244 return_ACPI_STATUS(AE_NO_MEMORY);
245 }
246
247 /* If a particular signature is expected (DSDT/FACS), it must match */
248
249 if (signature && !ACPI_COMPARE_NAME(&table_desc->signature, signature)) {
250 ACPI_BIOS_ERROR((AE_INFO,
251 "Invalid signature 0x%X for ACPI table, expected [%s]",
252 table_desc->signature.integer, signature));
253 status = AE_BAD_SIGNATURE;
254 goto invalidate_and_exit;
255 }
256
257 /* Verify the checksum */
258
259 status =
260 acpi_tb_verify_checksum(table_desc->pointer, table_desc->length);
261 if (ACPI_FAILURE(status)) {
262 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
263 "%4.4s " ACPI_PRINTF_UINT
264 " Attempted table install failed",
265 acpi_ut_valid_acpi_name(table_desc->signature.
266 ascii) ? table_desc->
267 signature.ascii : "????",
268 ACPI_FORMAT_TO_UINT(table_desc->address)));
269 goto invalidate_and_exit;
270 }
271
272 return_ACPI_STATUS(AE_OK);
273
274invalidate_and_exit:
275 acpi_tb_invalidate_table(table_desc);
276 return_ACPI_STATUS(status);
277}
278
279/*******************************************************************************
280 *
281 * FUNCTION: acpi_tb_install_table
282 *
283 * PARAMETERS: table_desc - Table descriptor
284 * address - Physical address of the table
285 * flags - Allocation flags of the table
286 * table - Pointer to the table
287 *
288 * RETURN: None
289 *
290 * DESCRIPTION: Install an ACPI table into the global data structure.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 *
292 ******************************************************************************/
293
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800294void
295acpi_tb_install_table(struct acpi_table_desc *table_desc,
296 acpi_physical_address address,
297 u8 flags, struct acpi_table_header *table)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298{
Bob Moorebc45b1d2008-06-10 14:12:50 +0800299 /*
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800300 * Initialize the table entry. Set the pointer to NULL, since the
301 * table is not fully mapped at this time.
Bob Moorebc45b1d2008-06-10 14:12:50 +0800302 */
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800303 ACPI_MEMSET(table_desc, 0, sizeof(struct acpi_table_desc));
304 table_desc->address = address;
305 table_desc->length = table->length;
306 table_desc->flags = flags;
307 ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature);
308}
Bob Moorec8cefe32011-06-14 10:42:53 +0800309
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800310/*******************************************************************************
311 *
312 * FUNCTION: acpi_tb_acquire_temporal_table
313 *
314 * PARAMETERS: table_desc - Table descriptor to be acquired
315 * address - Address of the table
316 * flags - Allocation flags of the table
317 *
318 * RETURN: Status
319 *
320 * DESCRIPTION: This function validates the table header to obtain the length
321 * of a table and fills the table descriptor to make its state as
322 * "INSTALLED". Such table descriptor is only used for verified
323 * installation.
324 *
325 ******************************************************************************/
326
327static acpi_status
328acpi_tb_acquire_temporal_table(struct acpi_table_desc *table_desc,
329 acpi_physical_address address, u8 flags)
330{
331 struct acpi_table_header *table_header;
332
333 switch (flags & ACPI_TABLE_ORIGIN_MASK) {
Lv Zheng8a216d72014-04-04 12:39:04 +0800334 case ACPI_TABLE_ORIGIN_INTERN_PHYSICAL:
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800335
336 /* Try to obtain the length of the table */
337
338 table_header =
339 acpi_os_map_memory(address,
340 sizeof(struct acpi_table_header));
341 if (!table_header) {
342 return (AE_NO_MEMORY);
343 }
344 acpi_tb_install_table(table_desc, address, flags, table_header);
345 acpi_os_unmap_memory(table_header,
346 sizeof(struct acpi_table_header));
347 return (AE_OK);
348
Lv Zheng8a216d72014-04-04 12:39:04 +0800349 case ACPI_TABLE_ORIGIN_INTERN_VIRTUAL:
350 case ACPI_TABLE_ORIGIN_EXTERN_VIRTUAL:
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800351
352 table_header = ACPI_CAST_PTR(struct acpi_table_header, address);
353 if (!table_header) {
354 return (AE_NO_MEMORY);
355 }
356 acpi_tb_install_table(table_desc, address, flags, table_header);
357 return (AE_OK);
358
359 default:
360
361 break;
Bob Moorec8cefe32011-06-14 10:42:53 +0800362 }
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300363
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800364 /* Table is not valid yet */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800366 return (AE_NO_MEMORY);
367}
Bob Mooref3d2e782007-02-02 19:48:18 +0300368
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800369/*******************************************************************************
370 *
371 * FUNCTION: acpi_tb_release_temporal_table
372 *
373 * PARAMETERS: table_desc - Table descriptor to be released
374 *
375 * RETURN: Status
376 *
377 * DESCRIPTION: The reversal of acpi_tb_acquire_temporal_table().
378 *
379 ******************************************************************************/
Bob Mooref3d2e782007-02-02 19:48:18 +0300380
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800381static void acpi_tb_release_temporal_table(struct acpi_table_desc *table_desc)
382{
383 /*
384 * Note that the .Address is maintained by the callers of
385 * acpi_tb_acquire_temporal_table(), thus do not invoke acpi_tb_uninstall_table()
386 * where .Address will be freed.
387 */
388 acpi_tb_invalidate_table(table_desc);
389}
Bob Mooree56f5612008-07-04 10:48:43 +0800390
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800391/*******************************************************************************
392 *
393 * FUNCTION: acpi_tb_install_and_override_table
394 *
395 * PARAMETERS: table_index - Index into root table array
396 * new_table_desc - New table descriptor to install
Lv Zhengcaf4a152014-04-04 12:39:18 +0800397 * override - Whether override should be performed
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800398 *
399 * RETURN: None
400 *
401 * DESCRIPTION: Install an ACPI table into the global data structure. The
402 * table override mechanism is called to allow the host
403 * OS to replace any table before it is installed in the root
404 * table array.
405 *
406 ******************************************************************************/
Bob Mooref3d2e782007-02-02 19:48:18 +0300407
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800408void
409acpi_tb_install_and_override_table(u32 table_index,
Lv Zhengcaf4a152014-04-04 12:39:18 +0800410 struct acpi_table_desc *new_table_desc,
411 u8 override)
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800412{
413 if (table_index >= acpi_gbl_root_table_list.current_table_count) {
414 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 }
416
Bob Moored3ccaff2009-02-03 14:43:04 +0800417 /*
418 * ACPI Table Override:
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800419 *
420 * Before we install the table, let the host OS override it with a new
421 * one if desired. Any table within the RSDT/XSDT can be replaced,
422 * including the DSDT which is pointed to by the FADT.
Bob Moored3ccaff2009-02-03 14:43:04 +0800423 */
Lv Zhengcaf4a152014-04-04 12:39:18 +0800424 if (override) {
425 acpi_tb_override_table(new_table_desc);
426 }
Lv Zheng7f9fc992014-04-04 12:38:42 +0800427
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800428 acpi_tb_install_table(&acpi_gbl_root_table_list.tables[table_index],
429 new_table_desc->address, new_table_desc->flags,
430 new_table_desc->pointer);
Lv Zheng7f9fc992014-04-04 12:38:42 +0800431
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800432 acpi_tb_print_table_header(new_table_desc->address,
433 new_table_desc->pointer);
434
435 /* Set the global integer width (based upon revision of the DSDT) */
436
437 if (table_index == ACPI_TABLE_INDEX_DSDT) {
438 acpi_ut_set_integer_width(new_table_desc->pointer->revision);
439 }
440}
441
442/*******************************************************************************
443 *
444 * FUNCTION: acpi_tb_install_fixed_table
445 *
446 * PARAMETERS: address - Physical address of DSDT or FACS
447 * signature - Table signature, NULL if no need to
448 * match
449 * table_index - Index into root table array
450 *
451 * RETURN: Status
452 *
453 * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data
454 * structure.
455 *
456 ******************************************************************************/
457
458acpi_status
459acpi_tb_install_fixed_table(acpi_physical_address address,
460 char *signature, u32 table_index)
461{
462 struct acpi_table_desc new_table_desc;
463 acpi_status status;
464
465 ACPI_FUNCTION_TRACE(tb_install_fixed_table);
466
467 if (!address) {
468 ACPI_ERROR((AE_INFO,
469 "Null physical address for ACPI table [%s]",
470 signature));
471 return (AE_NO_MEMORY);
472 }
473
474 /* Fill a table descriptor for validation */
475
476 status = acpi_tb_acquire_temporal_table(&new_table_desc, address,
Lv Zheng8a216d72014-04-04 12:39:04 +0800477 ACPI_TABLE_ORIGIN_INTERN_PHYSICAL);
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800478 if (ACPI_FAILURE(status)) {
479 ACPI_ERROR((AE_INFO, "Could not acquire table length at %p",
480 ACPI_CAST_PTR(void, address)));
481 return_ACPI_STATUS(status);
482 }
483
484 /* Validate and verify a table before installation */
485
486 status = acpi_tb_verify_table(&new_table_desc, signature);
487 if (ACPI_FAILURE(status)) {
488 goto release_and_exit;
489 }
490
Lv Zhengcaf4a152014-04-04 12:39:18 +0800491 acpi_tb_install_and_override_table(table_index, &new_table_desc, TRUE);
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800492
493release_and_exit:
494
495 /* Release the temporal table descriptor */
496
497 acpi_tb_release_temporal_table(&new_table_desc);
498 return_ACPI_STATUS(status);
499}
500
501/*******************************************************************************
502 *
503 * FUNCTION: acpi_tb_is_equivalent_table
504 *
505 * PARAMETERS: table_desc - Table 1 descriptor to be compared
506 * table_index - Index of table 2 to be compared
507 *
508 * RETURN: TRUE if 2 tables are equivalent
509 *
510 * DESCRIPTION: This function is called to compare a table with what have
511 * already been installed in the root table list.
512 *
513 ******************************************************************************/
514
515static u8
516acpi_tb_is_equivalent_table(struct acpi_table_desc *table_desc, u32 table_index)
517{
518 acpi_status status = AE_OK;
519 u8 is_equivalent;
520 struct acpi_table_header *table;
521 u32 table_length;
522 u8 table_flags;
523
524 status =
525 acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
526 &table, &table_length, &table_flags);
527 if (ACPI_FAILURE(status)) {
528 return (FALSE);
529 }
530
531 /*
532 * Check for a table match on the entire table length,
533 * not just the header.
534 */
535 is_equivalent = (u8)((table_desc->length != table_length ||
536 ACPI_MEMCMP(table_desc->pointer, table,
537 table_length)) ? FALSE : TRUE);
538
539 /* Release the acquired table */
540
541 acpi_tb_release_table(table, table_length, table_flags);
542
543 return (is_equivalent);
544}
545
546/*******************************************************************************
547 *
548 * FUNCTION: acpi_tb_install_non_fixed_table
549 *
Lv Zheng8a216d72014-04-04 12:39:04 +0800550 * PARAMETERS: address - Address of the table (might be a virtual
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800551 * address depending on the table_flags)
552 * flags - Flags for the table
553 * reload - Whether reload should be performed
Lv Zhengcaf4a152014-04-04 12:39:18 +0800554 * override - Whether override should be performed
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800555 * table_index - Where the table index is returned
556 *
557 * RETURN: Status
558 *
559 * DESCRIPTION: This function is called to install an ACPI table that is
560 * neither DSDT nor FACS.
561 * When this function is called by "Load" or "LoadTable" opcodes,
562 * or by acpi_load_table() API, the "Reload" parameter is set.
563 * After sucessfully returning from this function, table is
564 * "INSTALLED" but not "VALIDATED".
565 *
566 ******************************************************************************/
567
568acpi_status
569acpi_tb_install_non_fixed_table(acpi_physical_address address,
Lv Zhengcaf4a152014-04-04 12:39:18 +0800570 u8 flags,
571 u8 reload, u8 override, u32 *table_index)
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800572{
573 u32 i;
574 acpi_status status = AE_OK;
575 struct acpi_table_desc new_table_desc;
576
577 ACPI_FUNCTION_TRACE(tb_install_non_fixed_table);
578
579 /* Acquire a temporal table descriptor for validation */
580
581 status =
582 acpi_tb_acquire_temporal_table(&new_table_desc, address, flags);
583 if (ACPI_FAILURE(status)) {
584 ACPI_ERROR((AE_INFO, "Could not acquire table length at %p",
585 ACPI_CAST_PTR(void, address)));
586 return_ACPI_STATUS(status);
587 }
588
Lv Zhenga94e88c2014-04-04 12:39:11 +0800589 /*
590 * Optionally do not load any SSDTs from the RSDT/XSDT. This can
591 * be useful for debugging ACPI problems on some machines.
592 */
593 if (!reload && acpi_gbl_disable_ssdt_table_install &&
594 ACPI_COMPARE_NAME(&new_table_desc.signature, ACPI_SIG_SSDT)) {
595 ACPI_INFO((AE_INFO, "Ignoring installation of %4.4s at %p",
596 new_table_desc.signature.ascii, ACPI_CAST_PTR(void,
597 address)));
598 goto release_and_exit;
599 }
600
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800601 /* Validate and verify a table before installation */
602
603 status = acpi_tb_verify_table(&new_table_desc, NULL);
604 if (ACPI_FAILURE(status)) {
605 goto release_and_exit;
606 }
607
608 if (reload) {
609 /*
610 * Validate the incoming table signature.
611 *
612 * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
613 * 2) We added support for OEMx tables, signature "OEM".
614 * 3) Valid tables were encountered with a null signature, so we just
615 * gave up on validating the signature, (05/2008).
616 * 4) We encountered non-AML tables such as the MADT, which caused
617 * interpreter errors and kernel faults. So now, we once again allow
618 * only "SSDT", "OEMx", and now, also a null signature. (05/2011).
619 */
620 if ((new_table_desc.signature.ascii[0] != 0x00) &&
621 (!ACPI_COMPARE_NAME
622 (&new_table_desc.signature, ACPI_SIG_SSDT))
623 && (ACPI_STRNCMP(new_table_desc.signature.ascii, "OEM", 3)))
624 {
625 ACPI_BIOS_ERROR((AE_INFO,
626 "Table has invalid signature [%4.4s] (0x%8.8X), "
627 "must be SSDT or OEMx",
628 acpi_ut_valid_acpi_name(new_table_desc.
629 signature.
630 ascii) ?
631 new_table_desc.signature.
632 ascii : "????",
633 new_table_desc.signature.integer));
634
635 status = AE_BAD_SIGNATURE;
636 goto release_and_exit;
637 }
638
639 /* Check if table is already registered */
640
641 for (i = 0; i < acpi_gbl_root_table_list.current_table_count;
642 ++i) {
643 /*
644 * Check for a table match on the entire table length,
645 * not just the header.
646 */
647 if (!acpi_tb_is_equivalent_table(&new_table_desc, i)) {
648 continue;
649 }
650
651 /*
652 * Note: the current mechanism does not unregister a table if it is
653 * dynamically unloaded. The related namespace entries are deleted,
654 * but the table remains in the root table list.
655 *
656 * The assumption here is that the number of different tables that
657 * will be loaded is actually small, and there is minimal overhead
658 * in just keeping the table in case it is needed again.
659 *
660 * If this assumption changes in the future (perhaps on large
661 * machines with many table load/unload operations), tables will
662 * need to be unregistered when they are unloaded, and slots in the
663 * root table list should be reused when empty.
664 */
665 if (acpi_gbl_root_table_list.tables[i].
666 flags & ACPI_TABLE_IS_LOADED) {
667
668 /* Table is still loaded, this is an error */
669
670 status = AE_ALREADY_EXISTS;
671 goto release_and_exit;
672 } else {
673 /*
674 * Table was unloaded, allow it to be reloaded.
675 * As we are going to return AE_OK to the caller, we should
676 * take the responsibility of freeing the input descriptor.
677 * Refill the input descriptor to ensure
678 * acpi_tb_install_and_override_table() can be called again to
679 * indicate the re-installation.
680 */
681 acpi_tb_uninstall_table(&new_table_desc);
682 *table_index = i;
683 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
684 return_ACPI_STATUS(AE_OK);
685 }
686 }
Lv Zheng7f9fc992014-04-04 12:38:42 +0800687 }
Bob Moored3ccaff2009-02-03 14:43:04 +0800688
Bob Mooree56f5612008-07-04 10:48:43 +0800689 /* Add the table to the global root table list */
690
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800691 status = acpi_tb_acquire_root_table_entry(&i);
Len Brown4be44fc2005-08-05 00:44:28 -0400692 if (ACPI_FAILURE(status)) {
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800693 goto release_and_exit;
Robert Moore0c9938c2005-07-29 15:15:00 -0700694 }
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800695 *table_index = i;
Lv Zhengcaf4a152014-04-04 12:39:18 +0800696 acpi_tb_install_and_override_table(i, &new_table_desc, override);
Robert Moore0c9938c2005-07-29 15:15:00 -0700697
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800698release_and_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800700 /* Release the temporal table descriptor */
701
702 acpi_tb_release_temporal_table(&new_table_desc);
Len Brown4be44fc2005-08-05 00:44:28 -0400703 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704}
705
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706/*******************************************************************************
707 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800708 * FUNCTION: acpi_tb_override_table
Bob Mooref7b004a2012-02-14 18:31:56 +0800709 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800710 * PARAMETERS: old_table_desc - Validated table descriptor to be
711 * overridden
Bob Mooref7b004a2012-02-14 18:31:56 +0800712 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800713 * RETURN: None
Bob Mooref7b004a2012-02-14 18:31:56 +0800714 *
715 * DESCRIPTION: Attempt table override by calling the OSL override functions.
716 * Note: If the table is overridden, then the entire new table
Lv Zheng7f9fc992014-04-04 12:38:42 +0800717 * is acquired and returned by this function.
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800718 * Before/after invocation, the table descriptor is in a state
719 * that is "VALIDATED".
Bob Mooref7b004a2012-02-14 18:31:56 +0800720 *
721 ******************************************************************************/
722
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800723void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
Bob Mooref7b004a2012-02-14 18:31:56 +0800724{
725 acpi_status status;
Bob Mooref7b004a2012-02-14 18:31:56 +0800726 char *override_type;
Lv Zheng7f9fc992014-04-04 12:38:42 +0800727 struct acpi_table_desc new_table_desc;
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800728 struct acpi_table_header *table;
729 acpi_physical_address address;
730 u32 length;
Bob Mooref7b004a2012-02-14 18:31:56 +0800731
732 /* (1) Attempt logical override (returns a logical address) */
733
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800734 status = acpi_os_table_override(old_table_desc->pointer, &table);
735 if (ACPI_SUCCESS(status) && table) {
736 acpi_tb_acquire_temporal_table(&new_table_desc,
737 ACPI_PTR_TO_PHYSADDR(table),
Lv Zheng8a216d72014-04-04 12:39:04 +0800738 ACPI_TABLE_ORIGIN_EXTERN_VIRTUAL);
Bob Mooref7b004a2012-02-14 18:31:56 +0800739 override_type = "Logical";
740 goto finish_override;
741 }
742
743 /* (2) Attempt physical override (returns a physical address) */
744
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800745 status = acpi_os_physical_table_override(old_table_desc->pointer,
746 &address, &length);
747 if (ACPI_SUCCESS(status) && address && length) {
748 acpi_tb_acquire_temporal_table(&new_table_desc, address,
Lv Zheng8a216d72014-04-04 12:39:04 +0800749 ACPI_TABLE_ORIGIN_INTERN_PHYSICAL);
Bob Mooref7b004a2012-02-14 18:31:56 +0800750 override_type = "Physical";
Bob Mooref7b004a2012-02-14 18:31:56 +0800751 goto finish_override;
752 }
753
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800754 return; /* There was no override */
Bob Mooref7b004a2012-02-14 18:31:56 +0800755
Lv Zheng10622bf2013-10-29 09:30:02 +0800756finish_override:
Bob Mooref7b004a2012-02-14 18:31:56 +0800757
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800758 /* Validate and verify a table before overriding */
759
760 status = acpi_tb_verify_table(&new_table_desc, NULL);
Lv Zheng7f9fc992014-04-04 12:38:42 +0800761 if (ACPI_FAILURE(status)) {
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800762 return;
Lv Zheng7f9fc992014-04-04 12:38:42 +0800763 }
764
Bob Moore2e19f8d2014-02-08 09:42:07 +0800765 ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT
766 " %s table override, new table: " ACPI_PRINTF_UINT,
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800767 old_table_desc->signature.ascii,
768 ACPI_FORMAT_TO_UINT(old_table_desc->address),
Lv Zheng7f9fc992014-04-04 12:38:42 +0800769 override_type, ACPI_FORMAT_TO_UINT(new_table_desc.address)));
Bob Mooref7b004a2012-02-14 18:31:56 +0800770
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800771 /* We can now uninstall the original table */
Bob Mooref7b004a2012-02-14 18:31:56 +0800772
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800773 acpi_tb_uninstall_table(old_table_desc);
Bob Mooref7b004a2012-02-14 18:31:56 +0800774
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800775 /*
776 * Replace the original table descriptor and keep its state as
777 * "VALIDATED".
778 */
779 acpi_tb_install_table(old_table_desc, new_table_desc.address,
780 new_table_desc.flags, new_table_desc.pointer);
781 acpi_tb_validate_table(old_table_desc);
Bob Mooref7b004a2012-02-14 18:31:56 +0800782
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800783 /* Release the temporal table descriptor */
Bob Mooref7b004a2012-02-14 18:31:56 +0800784
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800785 acpi_tb_release_temporal_table(&new_table_desc);
Bob Mooref7b004a2012-02-14 18:31:56 +0800786}
787
788/*******************************************************************************
789 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300790 * FUNCTION: acpi_tb_resize_root_table_list
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300792 * PARAMETERS: None
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793 *
794 * RETURN: Status
795 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300796 * DESCRIPTION: Expand the size of global table array
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797 *
798 ******************************************************************************/
799
Bob Mooref3d2e782007-02-02 19:48:18 +0300800acpi_status acpi_tb_resize_root_table_list(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801{
Bob Mooref3d2e782007-02-02 19:48:18 +0300802 struct acpi_table_desc *tables;
Lv Zheng2bc198c2012-09-13 09:29:06 -0700803 u32 table_count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804
Bob Mooref3d2e782007-02-02 19:48:18 +0300805 ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806
Bob Mooref3d2e782007-02-02 19:48:18 +0300807 /* allow_resize flag is a parameter to acpi_initialize_tables */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808
Bob Moorec5fc42a2007-02-02 19:48:19 +0300809 if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300810 ACPI_ERROR((AE_INFO,
811 "Resize of Root Table Array is not allowed"));
812 return_ACPI_STATUS(AE_SUPPORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 }
814
Bob Mooref3d2e782007-02-02 19:48:18 +0300815 /* Increase the Table Array size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816
Lv Zheng2bc198c2012-09-13 09:29:06 -0700817 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
818 table_count = acpi_gbl_root_table_list.max_table_count;
819 } else {
820 table_count = acpi_gbl_root_table_list.current_table_count;
821 }
822
823 tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count +
Bob Mooreec41f192009-02-18 15:03:30 +0800824 ACPI_ROOT_TABLE_SIZE_INCREMENT) *
825 sizeof(struct acpi_table_desc));
Bob Mooref3d2e782007-02-02 19:48:18 +0300826 if (!tables) {
827 ACPI_ERROR((AE_INFO,
828 "Could not allocate new root table array"));
Len Brown4be44fc2005-08-05 00:44:28 -0400829 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 }
831
Bob Mooref3d2e782007-02-02 19:48:18 +0300832 /* Copy and free the previous table array */
Robert Mooref9f46012005-07-08 00:00:00 -0400833
Bob Mooref3d2e782007-02-02 19:48:18 +0300834 if (acpi_gbl_root_table_list.tables) {
835 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
Lv Zheng2bc198c2012-09-13 09:29:06 -0700836 (acpi_size) table_count *
837 sizeof(struct acpi_table_desc));
Robert Mooref9f46012005-07-08 00:00:00 -0400838
Bob Moorec5fc42a2007-02-02 19:48:19 +0300839 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300840 ACPI_FREE(acpi_gbl_root_table_list.tables);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 }
842 }
843
Bob Mooref3d2e782007-02-02 19:48:18 +0300844 acpi_gbl_root_table_list.tables = tables;
Lv Zheng2bc198c2012-09-13 09:29:06 -0700845 acpi_gbl_root_table_list.max_table_count =
846 table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
847 acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848
Len Brown4be44fc2005-08-05 00:44:28 -0400849 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850}
851
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852/*******************************************************************************
853 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800854 * FUNCTION: acpi_tb_acquire_root_table_entry
855 *
856 * PARAMETERS: table_index - Where table index is returned
857 *
858 * RETURN: Status and table index.
859 *
860 * DESCRIPTION: Allocate a new ACPI table entry to the global table list
861 *
862 ******************************************************************************/
863
864static acpi_status acpi_tb_acquire_root_table_entry(u32 *table_index)
865{
866 acpi_status status;
867
868 /* Ensure that there is room for the table in the Root Table List */
869
870 if (acpi_gbl_root_table_list.current_table_count >=
871 acpi_gbl_root_table_list.max_table_count) {
872 status = acpi_tb_resize_root_table_list();
873 if (ACPI_FAILURE(status)) {
874 return (status);
875 }
876 }
877
878 *table_index = acpi_gbl_root_table_list.current_table_count;
879 acpi_gbl_root_table_list.current_table_count++;
880 return (AE_OK);
881}
882
883/*******************************************************************************
884 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300885 * FUNCTION: acpi_tb_store_table
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886 *
Bob Mooreba494be2012-07-12 09:40:10 +0800887 * PARAMETERS: address - Table address
888 * table - Table header
889 * length - Table length
890 * flags - flags
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300892 * RETURN: Status and table index.
893 *
894 * DESCRIPTION: Add an ACPI table to the global table list
895 *
896 ******************************************************************************/
897
898acpi_status
899acpi_tb_store_table(acpi_physical_address address,
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800900 struct acpi_table_header * table,
Bob Moore67a119f2008-06-10 13:42:13 +0800901 u32 length, u8 flags, u32 *table_index)
Bob Mooref3d2e782007-02-02 19:48:18 +0300902{
Bob Mooreb9ee2042010-04-27 11:16:14 +0800903 acpi_status status;
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800904 struct acpi_table_desc *table_desc;
Bob Mooref3d2e782007-02-02 19:48:18 +0300905
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800906 status = acpi_tb_acquire_root_table_entry(table_index);
907 if (ACPI_FAILURE(status)) {
908 return (status);
Bob Mooref3d2e782007-02-02 19:48:18 +0300909 }
910
911 /* Initialize added table */
912
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800913 table_desc = &acpi_gbl_root_table_list.tables[*table_index];
914 acpi_tb_install_table(table_desc, address, flags, table);
915 table_desc->pointer = table;
Bob Mooref3d2e782007-02-02 19:48:18 +0300916
Bob Mooreb9ee2042010-04-27 11:16:14 +0800917 return (AE_OK);
Bob Mooref3d2e782007-02-02 19:48:18 +0300918}
919
920/*******************************************************************************
921 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800922 * FUNCTION: acpi_tb_uninstall_table
Bob Mooref3d2e782007-02-02 19:48:18 +0300923 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800924 * PARAMETERS: table_desc - Table descriptor
Bob Mooref3d2e782007-02-02 19:48:18 +0300925 *
926 * RETURN: None
927 *
928 * DESCRIPTION: Delete one internal ACPI table
929 *
930 ******************************************************************************/
931
Lv Zheng7f9fc992014-04-04 12:38:42 +0800932void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc)
Bob Mooref3d2e782007-02-02 19:48:18 +0300933{
Lv Zheng55829822014-04-04 12:38:18 +0800934
Lv Zheng7f9fc992014-04-04 12:38:42 +0800935 ACPI_FUNCTION_TRACE(tb_uninstall_table);
Lv Zheng55829822014-04-04 12:38:18 +0800936
Lv Zheng7f9fc992014-04-04 12:38:42 +0800937 /* Table must be installed */
938
939 if (!table_desc->address) {
940 return_VOID;
Bob Mooref3d2e782007-02-02 19:48:18 +0300941 }
Lv Zheng55829822014-04-04 12:38:18 +0800942
Lv Zheng7f9fc992014-04-04 12:38:42 +0800943 acpi_tb_invalidate_table(table_desc);
Chao Guan1d1ea1b2013-06-08 00:58:14 +0000944
Lv Zheng7f9fc992014-04-04 12:38:42 +0800945 if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
Lv Zheng8a216d72014-04-04 12:39:04 +0800946 ACPI_TABLE_ORIGIN_INTERN_VIRTUAL) {
Lv Zheng7f9fc992014-04-04 12:38:42 +0800947 ACPI_FREE(ACPI_CAST_PTR(void, table_desc->address));
Bob Mooref3d2e782007-02-02 19:48:18 +0300948 }
949
Lv Zheng7f9fc992014-04-04 12:38:42 +0800950 table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL);
951
952 return_VOID;
Bob Mooref3d2e782007-02-02 19:48:18 +0300953}
954
955/*******************************************************************************
956 *
957 * FUNCTION: acpi_tb_terminate
958 *
959 * PARAMETERS: None
960 *
961 * RETURN: None
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962 *
963 * DESCRIPTION: Delete all internal ACPI tables
964 *
965 ******************************************************************************/
966
Bob Mooref3d2e782007-02-02 19:48:18 +0300967void acpi_tb_terminate(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968{
Bob Moore67a119f2008-06-10 13:42:13 +0800969 u32 i;
Bob Mooref3d2e782007-02-02 19:48:18 +0300970
971 ACPI_FUNCTION_TRACE(tb_terminate);
972
973 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
974
975 /* Delete the individual tables */
976
Bob Mooreb9ee2042010-04-27 11:16:14 +0800977 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
Lv Zheng7f9fc992014-04-04 12:38:42 +0800978 acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]);
Bob Mooref3d2e782007-02-02 19:48:18 +0300979 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980
981 /*
Bob Mooref3d2e782007-02-02 19:48:18 +0300982 * Delete the root table array if allocated locally. Array cannot be
983 * mapped, so we don't need to check for that flag.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 */
Bob Moorec5fc42a2007-02-02 19:48:19 +0300985 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300986 ACPI_FREE(acpi_gbl_root_table_list.tables);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987 }
Bob Mooref3d2e782007-02-02 19:48:18 +0300988
989 acpi_gbl_root_table_list.tables = NULL;
990 acpi_gbl_root_table_list.flags = 0;
Bob Mooreb9ee2042010-04-27 11:16:14 +0800991 acpi_gbl_root_table_list.current_table_count = 0;
Bob Mooref3d2e782007-02-02 19:48:18 +0300992
993 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
994 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Bob Moore68aafc32012-10-31 02:26:01 +0000995
996 return_VOID;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997}
998
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999/*******************************************************************************
1000 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001001 * FUNCTION: acpi_tb_delete_namespace_by_owner
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001003 * PARAMETERS: table_index - Table index
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 *
Bob Moore8a335a232009-03-09 16:31:04 +08001005 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001007 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008 *
1009 ******************************************************************************/
1010
Bob Moore8a335a232009-03-09 16:31:04 +08001011acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012{
Bob Mooref3d2e782007-02-02 19:48:18 +03001013 acpi_owner_id owner_id;
Bob Moore8a335a232009-03-09 16:31:04 +08001014 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015
Bob Moore8a335a232009-03-09 16:31:04 +08001016 ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
1017
1018 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
1019 if (ACPI_FAILURE(status)) {
1020 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 }
1022
Bob Mooreb9ee2042010-04-27 11:16:14 +08001023 if (table_index >= acpi_gbl_root_table_list.current_table_count) {
Bob Moore8a335a232009-03-09 16:31:04 +08001024
1025 /* The table index does not exist */
1026
1027 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1028 return_ACPI_STATUS(AE_NOT_EXIST);
1029 }
1030
1031 /* Get the owner ID for this table, used to delete namespace nodes */
1032
1033 owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
Len Brown4be44fc2005-08-05 00:44:28 -04001034 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Bob Moore8a335a232009-03-09 16:31:04 +08001035
1036 /*
1037 * Need to acquire the namespace writer lock to prevent interference
1038 * with any concurrent namespace walks. The interpreter must be
1039 * released during the deletion since the acquisition of the deletion
1040 * lock may block, and also since the execution of a namespace walk
1041 * must be allowed to use the interpreter.
1042 */
Bob Mooree4c1ebf2009-04-22 13:02:06 +08001043 (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
Bob Moore8a335a232009-03-09 16:31:04 +08001044 status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
1045
Bob Mooref3d2e782007-02-02 19:48:18 +03001046 acpi_ns_delete_namespace_by_owner(owner_id);
Bob Moore8a335a232009-03-09 16:31:04 +08001047 if (ACPI_FAILURE(status)) {
1048 return_ACPI_STATUS(status);
1049 }
1050
1051 acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
1052
1053 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
1054 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055}
1056
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057/*******************************************************************************
1058 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001059 * FUNCTION: acpi_tb_allocate_owner_id
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001061 * PARAMETERS: table_index - Table index
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001063 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001065 * DESCRIPTION: Allocates owner_id in table_desc
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 *
1067 ******************************************************************************/
1068
Bob Moore67a119f2008-06-10 13:42:13 +08001069acpi_status acpi_tb_allocate_owner_id(u32 table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070{
Bob Mooref3d2e782007-02-02 19:48:18 +03001071 acpi_status status = AE_BAD_PARAMETER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072
Bob Mooref3d2e782007-02-02 19:48:18 +03001073 ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074
Bob Mooref3d2e782007-02-02 19:48:18 +03001075 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +08001076 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +03001077 status = acpi_ut_allocate_owner_id
1078 (&(acpi_gbl_root_table_list.tables[table_index].owner_id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079 }
1080
Bob Mooref3d2e782007-02-02 19:48:18 +03001081 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1082 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083}
1084
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085/*******************************************************************************
1086 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001087 * FUNCTION: acpi_tb_release_owner_id
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001089 * PARAMETERS: table_index - Table index
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001091 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001093 * DESCRIPTION: Releases owner_id in table_desc
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 *
1095 ******************************************************************************/
1096
Bob Moore67a119f2008-06-10 13:42:13 +08001097acpi_status acpi_tb_release_owner_id(u32 table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098{
Bob Mooref3d2e782007-02-02 19:48:18 +03001099 acpi_status status = AE_BAD_PARAMETER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100
Bob Mooref3d2e782007-02-02 19:48:18 +03001101 ACPI_FUNCTION_TRACE(tb_release_owner_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102
Bob Mooref3d2e782007-02-02 19:48:18 +03001103 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +08001104 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +03001105 acpi_ut_release_owner_id(&
1106 (acpi_gbl_root_table_list.
1107 tables[table_index].owner_id));
1108 status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109 }
1110
Bob Mooref3d2e782007-02-02 19:48:18 +03001111 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1112 return_ACPI_STATUS(status);
1113}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114
Bob Mooref3d2e782007-02-02 19:48:18 +03001115/*******************************************************************************
1116 *
1117 * FUNCTION: acpi_tb_get_owner_id
1118 *
1119 * PARAMETERS: table_index - Table index
1120 * owner_id - Where the table owner_id is returned
1121 *
1122 * RETURN: Status
1123 *
1124 * DESCRIPTION: returns owner_id for the ACPI table
1125 *
1126 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127
Lv Zheng55829822014-04-04 12:38:18 +08001128acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id * owner_id)
Bob Mooref3d2e782007-02-02 19:48:18 +03001129{
1130 acpi_status status = AE_BAD_PARAMETER;
1131
1132 ACPI_FUNCTION_TRACE(tb_get_owner_id);
1133
1134 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +08001135 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +03001136 *owner_id =
1137 acpi_gbl_root_table_list.tables[table_index].owner_id;
1138 status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139 }
1140
Bob Mooref3d2e782007-02-02 19:48:18 +03001141 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1142 return_ACPI_STATUS(status);
1143}
1144
1145/*******************************************************************************
1146 *
1147 * FUNCTION: acpi_tb_is_table_loaded
1148 *
1149 * PARAMETERS: table_index - Table index
1150 *
1151 * RETURN: Table Loaded Flag
1152 *
1153 ******************************************************************************/
1154
Bob Moore67a119f2008-06-10 13:42:13 +08001155u8 acpi_tb_is_table_loaded(u32 table_index)
Bob Mooref3d2e782007-02-02 19:48:18 +03001156{
1157 u8 is_loaded = FALSE;
1158
1159 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +08001160 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +03001161 is_loaded = (u8)
Bob Mooreec41f192009-02-18 15:03:30 +08001162 (acpi_gbl_root_table_list.tables[table_index].flags &
1163 ACPI_TABLE_IS_LOADED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 }
1165
Bob Mooref3d2e782007-02-02 19:48:18 +03001166 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1167 return (is_loaded);
1168}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169
Bob Mooref3d2e782007-02-02 19:48:18 +03001170/*******************************************************************************
1171 *
1172 * FUNCTION: acpi_tb_set_table_loaded_flag
1173 *
1174 * PARAMETERS: table_index - Table index
1175 * is_loaded - TRUE if table is loaded, FALSE otherwise
1176 *
1177 * RETURN: None
1178 *
1179 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
1180 *
1181 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182
Bob Moore67a119f2008-06-10 13:42:13 +08001183void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
Bob Mooref3d2e782007-02-02 19:48:18 +03001184{
Bob Mooref6dd9222006-07-07 20:44:38 -04001185
Bob Mooref3d2e782007-02-02 19:48:18 +03001186 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +08001187 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +03001188 if (is_loaded) {
1189 acpi_gbl_root_table_list.tables[table_index].flags |=
Bob Moorec5fc42a2007-02-02 19:48:19 +03001190 ACPI_TABLE_IS_LOADED;
Bob Mooref3d2e782007-02-02 19:48:18 +03001191 } else {
1192 acpi_gbl_root_table_list.tables[table_index].flags &=
Bob Moorec5fc42a2007-02-02 19:48:19 +03001193 ~ACPI_TABLE_IS_LOADED;
Bob Mooref3d2e782007-02-02 19:48:18 +03001194 }
1195 }
Bob Mooref6dd9222006-07-07 20:44:38 -04001196
Bob Mooref3d2e782007-02-02 19:48:18 +03001197 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198}