cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

tbdata.c (30369B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: tbdata - Table manager data structure functions
      5 *
      6 * Copyright (C) 2000 - 2022, Intel Corp.
      7 *
      8 *****************************************************************************/
      9
     10#include <acpi/acpi.h>
     11#include "accommon.h"
     12#include "acnamesp.h"
     13#include "actables.h"
     14#include "acevents.h"
     15
     16#define _COMPONENT          ACPI_TABLES
     17ACPI_MODULE_NAME("tbdata")
     18
     19/* Local prototypes */
     20static acpi_status
     21acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index);
     22
     23static u8
     24acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index);
     25
     26/*******************************************************************************
     27 *
     28 * FUNCTION:    acpi_tb_compare_tables
     29 *
     30 * PARAMETERS:  table_desc          - Table 1 descriptor to be compared
     31 *              table_index         - Index of table 2 to be compared
     32 *
     33 * RETURN:      TRUE if both tables are identical.
     34 *
     35 * DESCRIPTION: This function compares a table with another table that has
     36 *              already been installed in the root table list.
     37 *
     38 ******************************************************************************/
     39
     40static u8
     41acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
     42{
     43	acpi_status status = AE_OK;
     44	u8 is_identical;
     45	struct acpi_table_header *table;
     46	u32 table_length;
     47	u8 table_flags;
     48
     49	status =
     50	    acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
     51				  &table, &table_length, &table_flags);
     52	if (ACPI_FAILURE(status)) {
     53		return (FALSE);
     54	}
     55
     56	/*
     57	 * Check for a table match on the entire table length,
     58	 * not just the header.
     59	 */
     60	is_identical = (u8)((table_desc->length != table_length ||
     61			     memcmp(table_desc->pointer, table, table_length)) ?
     62			    FALSE : TRUE);
     63
     64	/* Release the acquired table */
     65
     66	acpi_tb_release_table(table, table_length, table_flags);
     67	return (is_identical);
     68}
     69
     70/*******************************************************************************
     71 *
     72 * FUNCTION:    acpi_tb_init_table_descriptor
     73 *
     74 * PARAMETERS:  table_desc              - Table descriptor
     75 *              address                 - Physical address of the table
     76 *              flags                   - Allocation flags of the table
     77 *              table                   - Pointer to the table
     78 *
     79 * RETURN:      None
     80 *
     81 * DESCRIPTION: Initialize a new table descriptor
     82 *
     83 ******************************************************************************/
     84
     85void
     86acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc,
     87			      acpi_physical_address address,
     88			      u8 flags, struct acpi_table_header *table)
     89{
     90
     91	/*
     92	 * Initialize the table descriptor. Set the pointer to NULL for external
     93	 * tables, since the table is not fully mapped at this time.
     94	 */
     95	memset(table_desc, 0, sizeof(struct acpi_table_desc));
     96	table_desc->address = address;
     97	table_desc->length = table->length;
     98	table_desc->flags = flags;
     99	ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature);
    100
    101	switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
    102	case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
    103	case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
    104
    105		table_desc->pointer = table;
    106		break;
    107
    108	case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
    109	default:
    110
    111		break;
    112	}
    113}
    114
    115/*******************************************************************************
    116 *
    117 * FUNCTION:    acpi_tb_acquire_table
    118 *
    119 * PARAMETERS:  table_desc          - Table descriptor
    120 *              table_ptr           - Where table is returned
    121 *              table_length        - Where table length is returned
    122 *              table_flags         - Where table allocation flags are returned
    123 *
    124 * RETURN:      Status
    125 *
    126 * DESCRIPTION: Acquire an ACPI table. It can be used for tables not
    127 *              maintained in the acpi_gbl_root_table_list.
    128 *
    129 ******************************************************************************/
    130
    131acpi_status
    132acpi_tb_acquire_table(struct acpi_table_desc *table_desc,
    133		      struct acpi_table_header **table_ptr,
    134		      u32 *table_length, u8 *table_flags)
    135{
    136	struct acpi_table_header *table = NULL;
    137
    138	switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
    139	case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
    140
    141		table =
    142		    acpi_os_map_memory(table_desc->address, table_desc->length);
    143		break;
    144
    145	case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
    146	case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
    147
    148		table = table_desc->pointer;
    149		break;
    150
    151	default:
    152
    153		break;
    154	}
    155
    156	/* Table is not valid yet */
    157
    158	if (!table) {
    159		return (AE_NO_MEMORY);
    160	}
    161
    162	/* Fill the return values */
    163
    164	*table_ptr = table;
    165	*table_length = table_desc->length;
    166	*table_flags = table_desc->flags;
    167	return (AE_OK);
    168}
    169
    170/*******************************************************************************
    171 *
    172 * FUNCTION:    acpi_tb_release_table
    173 *
    174 * PARAMETERS:  table               - Pointer for the table
    175 *              table_length        - Length for the table
    176 *              table_flags         - Allocation flags for the table
    177 *
    178 * RETURN:      None
    179 *
    180 * DESCRIPTION: Release a table. The inverse of acpi_tb_acquire_table().
    181 *
    182 ******************************************************************************/
    183
    184void
    185acpi_tb_release_table(struct acpi_table_header *table,
    186		      u32 table_length, u8 table_flags)
    187{
    188
    189	switch (table_flags & ACPI_TABLE_ORIGIN_MASK) {
    190	case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
    191
    192		acpi_os_unmap_memory(table, table_length);
    193		break;
    194
    195	case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
    196	case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
    197	default:
    198
    199		break;
    200	}
    201}
    202
    203/*******************************************************************************
    204 *
    205 * FUNCTION:    acpi_tb_acquire_temp_table
    206 *
    207 * PARAMETERS:  table_desc          - Table descriptor to be acquired
    208 *              address             - Address of the table
    209 *              flags               - Allocation flags of the table
    210 *              table               - Pointer to the table (required for virtual
    211 *                                    origins, optional for physical)
    212 *
    213 * RETURN:      Status
    214 *
    215 * DESCRIPTION: This function validates the table header to obtain the length
    216 *              of a table and fills the table descriptor to make its state as
    217 *              "INSTALLED". Such a table descriptor is only used for verified
    218 *              installation.
    219 *
    220 ******************************************************************************/
    221
    222acpi_status
    223acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc,
    224			   acpi_physical_address address,
    225			   u8 flags, struct acpi_table_header *table)
    226{
    227	u8 mapped_table = FALSE;
    228
    229	switch (flags & ACPI_TABLE_ORIGIN_MASK) {
    230	case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
    231
    232		/* Get the length of the full table from the header */
    233
    234		if (!table) {
    235			table =
    236			    acpi_os_map_memory(address,
    237					       sizeof(struct
    238						      acpi_table_header));
    239			if (!table) {
    240				return (AE_NO_MEMORY);
    241			}
    242
    243			mapped_table = TRUE;
    244		}
    245
    246		break;
    247
    248	case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
    249	case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
    250
    251		if (!table) {
    252			return (AE_BAD_PARAMETER);
    253		}
    254
    255		break;
    256
    257	default:
    258
    259		/* Table is not valid yet */
    260
    261		return (AE_NO_MEMORY);
    262	}
    263
    264	acpi_tb_init_table_descriptor(table_desc, address, flags, table);
    265	if (mapped_table) {
    266		acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
    267	}
    268
    269	return (AE_OK);
    270}
    271
    272/*******************************************************************************
    273 *
    274 * FUNCTION:    acpi_tb_release_temp_table
    275 *
    276 * PARAMETERS:  table_desc          - Table descriptor to be released
    277 *
    278 * RETURN:      Status
    279 *
    280 * DESCRIPTION: The inverse of acpi_tb_acquire_temp_table().
    281 *
    282 *****************************************************************************/
    283
    284void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc)
    285{
    286
    287	/*
    288	 * Note that the .Address is maintained by the callers of
    289	 * acpi_tb_acquire_temp_table(), thus do not invoke acpi_tb_uninstall_table()
    290	 * where .Address will be freed.
    291	 */
    292	acpi_tb_invalidate_table(table_desc);
    293}
    294
    295/******************************************************************************
    296 *
    297 * FUNCTION:    acpi_tb_validate_table
    298 *
    299 * PARAMETERS:  table_desc          - Table descriptor
    300 *
    301 * RETURN:      Status
    302 *
    303 * DESCRIPTION: This function is called to validate the table, the returned
    304 *              table descriptor is in "VALIDATED" state.
    305 *
    306 *****************************************************************************/
    307
    308acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc)
    309{
    310	acpi_status status = AE_OK;
    311
    312	ACPI_FUNCTION_TRACE(tb_validate_table);
    313
    314	/* Validate the table if necessary */
    315
    316	if (!table_desc->pointer) {
    317		status = acpi_tb_acquire_table(table_desc, &table_desc->pointer,
    318					       &table_desc->length,
    319					       &table_desc->flags);
    320		if (!table_desc->pointer) {
    321			status = AE_NO_MEMORY;
    322		}
    323	}
    324
    325	return_ACPI_STATUS(status);
    326}
    327
    328/*******************************************************************************
    329 *
    330 * FUNCTION:    acpi_tb_invalidate_table
    331 *
    332 * PARAMETERS:  table_desc          - Table descriptor
    333 *
    334 * RETURN:      None
    335 *
    336 * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of
    337 *              acpi_tb_validate_table().
    338 *
    339 ******************************************************************************/
    340
    341void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc)
    342{
    343
    344	ACPI_FUNCTION_TRACE(tb_invalidate_table);
    345
    346	/* Table must be validated */
    347
    348	if (!table_desc->pointer) {
    349		return_VOID;
    350	}
    351
    352	acpi_tb_release_table(table_desc->pointer, table_desc->length,
    353			      table_desc->flags);
    354
    355	switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
    356	case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
    357
    358		table_desc->pointer = NULL;
    359		break;
    360
    361	case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
    362	case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
    363	default:
    364
    365		break;
    366	}
    367
    368	return_VOID;
    369}
    370
    371/******************************************************************************
    372 *
    373 * FUNCTION:    acpi_tb_validate_temp_table
    374 *
    375 * PARAMETERS:  table_desc          - Table descriptor
    376 *
    377 * RETURN:      Status
    378 *
    379 * DESCRIPTION: This function is called to validate the table, the returned
    380 *              table descriptor is in "VALIDATED" state.
    381 *
    382 *****************************************************************************/
    383
    384acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
    385{
    386
    387	if (!table_desc->pointer && !acpi_gbl_enable_table_validation) {
    388		/*
    389		 * Only validates the header of the table.
    390		 * Note that Length contains the size of the mapping after invoking
    391		 * this work around, this value is required by
    392		 * acpi_tb_release_temp_table().
    393		 * We can do this because in acpi_init_table_descriptor(), the Length
    394		 * field of the installed descriptor is filled with the actual
    395		 * table length obtaining from the table header.
    396		 */
    397		table_desc->length = sizeof(struct acpi_table_header);
    398	}
    399
    400	return (acpi_tb_validate_table(table_desc));
    401}
    402
    403/*******************************************************************************
    404 *
    405 * FUNCTION:    acpi_tb_check_duplication
    406 *
    407 * PARAMETERS:  table_desc          - Table descriptor
    408 *              table_index         - Where the table index is returned
    409 *
    410 * RETURN:      Status
    411 *
    412 * DESCRIPTION: Avoid installing duplicated tables. However table override and
    413 *              user aided dynamic table load is allowed, thus comparing the
    414 *              address of the table is not sufficient, and checking the entire
    415 *              table content is required.
    416 *
    417 ******************************************************************************/
    418
    419static acpi_status
    420acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index)
    421{
    422	u32 i;
    423
    424	ACPI_FUNCTION_TRACE(tb_check_duplication);
    425
    426	/* Check if table is already registered */
    427
    428	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
    429
    430		/* Do not compare with unverified tables */
    431
    432		if (!
    433		    (acpi_gbl_root_table_list.tables[i].
    434		     flags & ACPI_TABLE_IS_VERIFIED)) {
    435			continue;
    436		}
    437
    438		/*
    439		 * Check for a table match on the entire table length,
    440		 * not just the header.
    441		 */
    442		if (!acpi_tb_compare_tables(table_desc, i)) {
    443			continue;
    444		}
    445
    446		/*
    447		 * Note: the current mechanism does not unregister a table if it is
    448		 * dynamically unloaded. The related namespace entries are deleted,
    449		 * but the table remains in the root table list.
    450		 *
    451		 * The assumption here is that the number of different tables that
    452		 * will be loaded is actually small, and there is minimal overhead
    453		 * in just keeping the table in case it is needed again.
    454		 *
    455		 * If this assumption changes in the future (perhaps on large
    456		 * machines with many table load/unload operations), tables will
    457		 * need to be unregistered when they are unloaded, and slots in the
    458		 * root table list should be reused when empty.
    459		 */
    460		if (acpi_gbl_root_table_list.tables[i].flags &
    461		    ACPI_TABLE_IS_LOADED) {
    462
    463			/* Table is still loaded, this is an error */
    464
    465			return_ACPI_STATUS(AE_ALREADY_EXISTS);
    466		} else {
    467			*table_index = i;
    468			return_ACPI_STATUS(AE_CTRL_TERMINATE);
    469		}
    470	}
    471
    472	/* Indicate no duplication to the caller */
    473
    474	return_ACPI_STATUS(AE_OK);
    475}
    476
    477/******************************************************************************
    478 *
    479 * FUNCTION:    acpi_tb_verify_temp_table
    480 *
    481 * PARAMETERS:  table_desc          - Table descriptor
    482 *              signature           - Table signature to verify
    483 *              table_index         - Where the table index is returned
    484 *
    485 * RETURN:      Status
    486 *
    487 * DESCRIPTION: This function is called to validate and verify the table, the
    488 *              returned table descriptor is in "VALIDATED" state.
    489 *              Note that 'TableIndex' is required to be set to !NULL to
    490 *              enable duplication check.
    491 *
    492 *****************************************************************************/
    493
    494acpi_status
    495acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
    496			  char *signature, u32 *table_index)
    497{
    498	acpi_status status = AE_OK;
    499
    500	ACPI_FUNCTION_TRACE(tb_verify_temp_table);
    501
    502	/* Validate the table */
    503
    504	status = acpi_tb_validate_temp_table(table_desc);
    505	if (ACPI_FAILURE(status)) {
    506		return_ACPI_STATUS(AE_NO_MEMORY);
    507	}
    508
    509	/* If a particular signature is expected (DSDT/FACS), it must match */
    510
    511	if (signature &&
    512	    !ACPI_COMPARE_NAMESEG(&table_desc->signature, signature)) {
    513		ACPI_BIOS_ERROR((AE_INFO,
    514				 "Invalid signature 0x%X for ACPI table, expected [%s]",
    515				 table_desc->signature.integer, signature));
    516		status = AE_BAD_SIGNATURE;
    517		goto invalidate_and_exit;
    518	}
    519
    520	if (acpi_gbl_enable_table_validation) {
    521
    522		/* Verify the checksum */
    523
    524		status =
    525		    acpi_tb_verify_checksum(table_desc->pointer,
    526					    table_desc->length);
    527		if (ACPI_FAILURE(status)) {
    528			ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
    529					"%4.4s 0x%8.8X%8.8X"
    530					" Attempted table install failed",
    531					acpi_ut_valid_nameseg(table_desc->
    532							      signature.
    533							      ascii) ?
    534					table_desc->signature.ascii : "????",
    535					ACPI_FORMAT_UINT64(table_desc->
    536							   address)));
    537
    538			goto invalidate_and_exit;
    539		}
    540
    541		/* Avoid duplications */
    542
    543		if (table_index) {
    544			status =
    545			    acpi_tb_check_duplication(table_desc, table_index);
    546			if (ACPI_FAILURE(status)) {
    547				if (status != AE_CTRL_TERMINATE) {
    548					ACPI_EXCEPTION((AE_INFO, status,
    549							"%4.4s 0x%8.8X%8.8X"
    550							" Table is already loaded",
    551							acpi_ut_valid_nameseg
    552							(table_desc->signature.
    553							 ascii) ? table_desc->
    554							signature.
    555							ascii : "????",
    556							ACPI_FORMAT_UINT64
    557							(table_desc->address)));
    558				}
    559
    560				goto invalidate_and_exit;
    561			}
    562		}
    563
    564		table_desc->flags |= ACPI_TABLE_IS_VERIFIED;
    565	}
    566
    567	return_ACPI_STATUS(status);
    568
    569invalidate_and_exit:
    570	acpi_tb_invalidate_table(table_desc);
    571	return_ACPI_STATUS(status);
    572}
    573
    574/*******************************************************************************
    575 *
    576 * FUNCTION:    acpi_tb_resize_root_table_list
    577 *
    578 * PARAMETERS:  None
    579 *
    580 * RETURN:      Status
    581 *
    582 * DESCRIPTION: Expand the size of global table array
    583 *
    584 ******************************************************************************/
    585
    586acpi_status acpi_tb_resize_root_table_list(void)
    587{
    588	struct acpi_table_desc *tables;
    589	u32 table_count;
    590	u32 current_table_count, max_table_count;
    591	u32 i;
    592
    593	ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
    594
    595	/* allow_resize flag is a parameter to acpi_initialize_tables */
    596
    597	if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
    598		ACPI_ERROR((AE_INFO,
    599			    "Resize of Root Table Array is not allowed"));
    600		return_ACPI_STATUS(AE_SUPPORT);
    601	}
    602
    603	/* Increase the Table Array size */
    604
    605	if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
    606		table_count = acpi_gbl_root_table_list.max_table_count;
    607	} else {
    608		table_count = acpi_gbl_root_table_list.current_table_count;
    609	}
    610
    611	max_table_count = table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
    612	tables = ACPI_ALLOCATE_ZEROED(((acpi_size)max_table_count) *
    613				      sizeof(struct acpi_table_desc));
    614	if (!tables) {
    615		ACPI_ERROR((AE_INFO,
    616			    "Could not allocate new root table array"));
    617		return_ACPI_STATUS(AE_NO_MEMORY);
    618	}
    619
    620	/* Copy and free the previous table array */
    621
    622	current_table_count = 0;
    623	if (acpi_gbl_root_table_list.tables) {
    624		for (i = 0; i < table_count; i++) {
    625			if (acpi_gbl_root_table_list.tables[i].address) {
    626				memcpy(tables + current_table_count,
    627				       acpi_gbl_root_table_list.tables + i,
    628				       sizeof(struct acpi_table_desc));
    629				current_table_count++;
    630			}
    631		}
    632
    633		if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
    634			ACPI_FREE(acpi_gbl_root_table_list.tables);
    635		}
    636	}
    637
    638	acpi_gbl_root_table_list.tables = tables;
    639	acpi_gbl_root_table_list.max_table_count = max_table_count;
    640	acpi_gbl_root_table_list.current_table_count = current_table_count;
    641	acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
    642
    643	return_ACPI_STATUS(AE_OK);
    644}
    645
    646/*******************************************************************************
    647 *
    648 * FUNCTION:    acpi_tb_get_next_table_descriptor
    649 *
    650 * PARAMETERS:  table_index         - Where table index is returned
    651 *              table_desc          - Where table descriptor is returned
    652 *
    653 * RETURN:      Status and table index/descriptor.
    654 *
    655 * DESCRIPTION: Allocate a new ACPI table entry to the global table list
    656 *
    657 ******************************************************************************/
    658
    659acpi_status
    660acpi_tb_get_next_table_descriptor(u32 *table_index,
    661				  struct acpi_table_desc **table_desc)
    662{
    663	acpi_status status;
    664	u32 i;
    665
    666	/* Ensure that there is room for the table in the Root Table List */
    667
    668	if (acpi_gbl_root_table_list.current_table_count >=
    669	    acpi_gbl_root_table_list.max_table_count) {
    670		status = acpi_tb_resize_root_table_list();
    671		if (ACPI_FAILURE(status)) {
    672			return (status);
    673		}
    674	}
    675
    676	i = acpi_gbl_root_table_list.current_table_count;
    677	acpi_gbl_root_table_list.current_table_count++;
    678
    679	if (table_index) {
    680		*table_index = i;
    681	}
    682	if (table_desc) {
    683		*table_desc = &acpi_gbl_root_table_list.tables[i];
    684	}
    685
    686	return (AE_OK);
    687}
    688
    689/*******************************************************************************
    690 *
    691 * FUNCTION:    acpi_tb_terminate
    692 *
    693 * PARAMETERS:  None
    694 *
    695 * RETURN:      None
    696 *
    697 * DESCRIPTION: Delete all internal ACPI tables
    698 *
    699 ******************************************************************************/
    700
    701void acpi_tb_terminate(void)
    702{
    703	u32 i;
    704
    705	ACPI_FUNCTION_TRACE(tb_terminate);
    706
    707	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
    708
    709	/* Delete the individual tables */
    710
    711	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
    712		acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]);
    713	}
    714
    715	/*
    716	 * Delete the root table array if allocated locally. Array cannot be
    717	 * mapped, so we don't need to check for that flag.
    718	 */
    719	if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
    720		ACPI_FREE(acpi_gbl_root_table_list.tables);
    721	}
    722
    723	acpi_gbl_root_table_list.tables = NULL;
    724	acpi_gbl_root_table_list.flags = 0;
    725	acpi_gbl_root_table_list.current_table_count = 0;
    726
    727	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
    728
    729	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
    730	return_VOID;
    731}
    732
    733/*******************************************************************************
    734 *
    735 * FUNCTION:    acpi_tb_delete_namespace_by_owner
    736 *
    737 * PARAMETERS:  table_index         - Table index
    738 *
    739 * RETURN:      Status
    740 *
    741 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
    742 *
    743 ******************************************************************************/
    744
    745acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
    746{
    747	acpi_owner_id owner_id;
    748	acpi_status status;
    749
    750	ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
    751
    752	status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
    753	if (ACPI_FAILURE(status)) {
    754		return_ACPI_STATUS(status);
    755	}
    756
    757	if (table_index >= acpi_gbl_root_table_list.current_table_count) {
    758
    759		/* The table index does not exist */
    760
    761		(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
    762		return_ACPI_STATUS(AE_NOT_EXIST);
    763	}
    764
    765	/* Get the owner ID for this table, used to delete namespace nodes */
    766
    767	owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
    768	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
    769
    770	/*
    771	 * Need to acquire the namespace writer lock to prevent interference
    772	 * with any concurrent namespace walks. The interpreter must be
    773	 * released during the deletion since the acquisition of the deletion
    774	 * lock may block, and also since the execution of a namespace walk
    775	 * must be allowed to use the interpreter.
    776	 */
    777	status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
    778	if (ACPI_FAILURE(status)) {
    779		return_ACPI_STATUS(status);
    780	}
    781
    782	acpi_ns_delete_namespace_by_owner(owner_id);
    783	acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
    784	return_ACPI_STATUS(status);
    785}
    786
    787/*******************************************************************************
    788 *
    789 * FUNCTION:    acpi_tb_allocate_owner_id
    790 *
    791 * PARAMETERS:  table_index         - Table index
    792 *
    793 * RETURN:      Status
    794 *
    795 * DESCRIPTION: Allocates owner_id in table_desc
    796 *
    797 ******************************************************************************/
    798
    799acpi_status acpi_tb_allocate_owner_id(u32 table_index)
    800{
    801	acpi_status status = AE_BAD_PARAMETER;
    802
    803	ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
    804
    805	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
    806	if (table_index < acpi_gbl_root_table_list.current_table_count) {
    807		status =
    808		    acpi_ut_allocate_owner_id(&
    809					      (acpi_gbl_root_table_list.
    810					       tables[table_index].owner_id));
    811	}
    812
    813	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
    814	return_ACPI_STATUS(status);
    815}
    816
    817/*******************************************************************************
    818 *
    819 * FUNCTION:    acpi_tb_release_owner_id
    820 *
    821 * PARAMETERS:  table_index         - Table index
    822 *
    823 * RETURN:      Status
    824 *
    825 * DESCRIPTION: Releases owner_id in table_desc
    826 *
    827 ******************************************************************************/
    828
    829acpi_status acpi_tb_release_owner_id(u32 table_index)
    830{
    831	acpi_status status = AE_BAD_PARAMETER;
    832
    833	ACPI_FUNCTION_TRACE(tb_release_owner_id);
    834
    835	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
    836	if (table_index < acpi_gbl_root_table_list.current_table_count) {
    837		acpi_ut_release_owner_id(&
    838					 (acpi_gbl_root_table_list.
    839					  tables[table_index].owner_id));
    840		status = AE_OK;
    841	}
    842
    843	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
    844	return_ACPI_STATUS(status);
    845}
    846
    847/*******************************************************************************
    848 *
    849 * FUNCTION:    acpi_tb_get_owner_id
    850 *
    851 * PARAMETERS:  table_index         - Table index
    852 *              owner_id            - Where the table owner_id is returned
    853 *
    854 * RETURN:      Status
    855 *
    856 * DESCRIPTION: returns owner_id for the ACPI table
    857 *
    858 ******************************************************************************/
    859
    860acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id)
    861{
    862	acpi_status status = AE_BAD_PARAMETER;
    863
    864	ACPI_FUNCTION_TRACE(tb_get_owner_id);
    865
    866	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
    867	if (table_index < acpi_gbl_root_table_list.current_table_count) {
    868		*owner_id =
    869		    acpi_gbl_root_table_list.tables[table_index].owner_id;
    870		status = AE_OK;
    871	}
    872
    873	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
    874	return_ACPI_STATUS(status);
    875}
    876
    877/*******************************************************************************
    878 *
    879 * FUNCTION:    acpi_tb_is_table_loaded
    880 *
    881 * PARAMETERS:  table_index         - Index into the root table
    882 *
    883 * RETURN:      Table Loaded Flag
    884 *
    885 ******************************************************************************/
    886
    887u8 acpi_tb_is_table_loaded(u32 table_index)
    888{
    889	u8 is_loaded = FALSE;
    890
    891	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
    892	if (table_index < acpi_gbl_root_table_list.current_table_count) {
    893		is_loaded = (u8)
    894		    (acpi_gbl_root_table_list.tables[table_index].flags &
    895		     ACPI_TABLE_IS_LOADED);
    896	}
    897
    898	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
    899	return (is_loaded);
    900}
    901
    902/*******************************************************************************
    903 *
    904 * FUNCTION:    acpi_tb_set_table_loaded_flag
    905 *
    906 * PARAMETERS:  table_index         - Table index
    907 *              is_loaded           - TRUE if table is loaded, FALSE otherwise
    908 *
    909 * RETURN:      None
    910 *
    911 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
    912 *
    913 ******************************************************************************/
    914
    915void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
    916{
    917
    918	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
    919	if (table_index < acpi_gbl_root_table_list.current_table_count) {
    920		if (is_loaded) {
    921			acpi_gbl_root_table_list.tables[table_index].flags |=
    922			    ACPI_TABLE_IS_LOADED;
    923		} else {
    924			acpi_gbl_root_table_list.tables[table_index].flags &=
    925			    ~ACPI_TABLE_IS_LOADED;
    926		}
    927	}
    928
    929	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
    930}
    931
    932/*******************************************************************************
    933 *
    934 * FUNCTION:    acpi_tb_load_table
    935 *
    936 * PARAMETERS:  table_index             - Table index
    937 *              parent_node             - Where table index is returned
    938 *
    939 * RETURN:      Status
    940 *
    941 * DESCRIPTION: Load an ACPI table
    942 *
    943 ******************************************************************************/
    944
    945acpi_status
    946acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node)
    947{
    948	struct acpi_table_header *table;
    949	acpi_status status;
    950	acpi_owner_id owner_id;
    951
    952	ACPI_FUNCTION_TRACE(tb_load_table);
    953
    954	/*
    955	 * Note: Now table is "INSTALLED", it must be validated before
    956	 * using.
    957	 */
    958	status = acpi_get_table_by_index(table_index, &table);
    959	if (ACPI_FAILURE(status)) {
    960		return_ACPI_STATUS(status);
    961	}
    962
    963	status = acpi_ns_load_table(table_index, parent_node);
    964	if (ACPI_FAILURE(status)) {
    965		return_ACPI_STATUS(status);
    966	}
    967
    968	/*
    969	 * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
    970	 * responsible for discovering any new wake GPEs by running _PRW methods
    971	 * that may have been loaded by this table.
    972	 */
    973	status = acpi_tb_get_owner_id(table_index, &owner_id);
    974	if (ACPI_SUCCESS(status)) {
    975		acpi_ev_update_gpes(owner_id);
    976	}
    977
    978	/* Invoke table handler */
    979
    980	acpi_tb_notify_table(ACPI_TABLE_EVENT_LOAD, table);
    981	return_ACPI_STATUS(status);
    982}
    983
    984/*******************************************************************************
    985 *
    986 * FUNCTION:    acpi_tb_install_and_load_table
    987 *
    988 * PARAMETERS:  address                 - Physical address of the table
    989 *              flags                   - Allocation flags of the table
    990 *              table                   - Pointer to the table (required for
    991 *                                        virtual origins, optional for
    992 *                                        physical)
    993 *              override                - Whether override should be performed
    994 *              table_index             - Where table index is returned
    995 *
    996 * RETURN:      Status
    997 *
    998 * DESCRIPTION: Install and load an ACPI table
    999 *
   1000 ******************************************************************************/
   1001
   1002acpi_status
   1003acpi_tb_install_and_load_table(acpi_physical_address address,
   1004			       u8 flags,
   1005			       struct acpi_table_header *table,
   1006			       u8 override, u32 *table_index)
   1007{
   1008	acpi_status status;
   1009	u32 i;
   1010
   1011	ACPI_FUNCTION_TRACE(tb_install_and_load_table);
   1012
   1013	/* Install the table and load it into the namespace */
   1014
   1015	status = acpi_tb_install_standard_table(address, flags, table, TRUE,
   1016						override, &i);
   1017	if (ACPI_FAILURE(status)) {
   1018		goto exit;
   1019	}
   1020
   1021	status = acpi_tb_load_table(i, acpi_gbl_root_node);
   1022
   1023exit:
   1024	*table_index = i;
   1025	return_ACPI_STATUS(status);
   1026}
   1027
   1028ACPI_EXPORT_SYMBOL(acpi_tb_install_and_load_table)
   1029
   1030/*******************************************************************************
   1031 *
   1032 * FUNCTION:    acpi_tb_unload_table
   1033 *
   1034 * PARAMETERS:  table_index             - Table index
   1035 *
   1036 * RETURN:      Status
   1037 *
   1038 * DESCRIPTION: Unload an ACPI table
   1039 *
   1040 ******************************************************************************/
   1041
   1042acpi_status acpi_tb_unload_table(u32 table_index)
   1043{
   1044	acpi_status status = AE_OK;
   1045	struct acpi_table_header *table;
   1046
   1047	ACPI_FUNCTION_TRACE(tb_unload_table);
   1048
   1049	/* Ensure the table is still loaded */
   1050
   1051	if (!acpi_tb_is_table_loaded(table_index)) {
   1052		return_ACPI_STATUS(AE_NOT_EXIST);
   1053	}
   1054
   1055	/* Invoke table handler */
   1056
   1057	status = acpi_get_table_by_index(table_index, &table);
   1058	if (ACPI_SUCCESS(status)) {
   1059		acpi_tb_notify_table(ACPI_TABLE_EVENT_UNLOAD, table);
   1060	}
   1061
   1062	/* Delete the portion of the namespace owned by this table */
   1063
   1064	status = acpi_tb_delete_namespace_by_owner(table_index);
   1065	if (ACPI_FAILURE(status)) {
   1066		return_ACPI_STATUS(status);
   1067	}
   1068
   1069	(void)acpi_tb_release_owner_id(table_index);
   1070	acpi_tb_set_table_loaded_flag(table_index, FALSE);
   1071	return_ACPI_STATUS(status);
   1072}
   1073
   1074ACPI_EXPORT_SYMBOL(acpi_tb_unload_table)
   1075
   1076/*******************************************************************************
   1077 *
   1078 * FUNCTION:    acpi_tb_notify_table
   1079 *
   1080 * PARAMETERS:  event               - Table event
   1081 *              table               - Validated table pointer
   1082 *
   1083 * RETURN:      None
   1084 *
   1085 * DESCRIPTION: Notify a table event to the users.
   1086 *
   1087 ******************************************************************************/
   1088
   1089void acpi_tb_notify_table(u32 event, void *table)
   1090{
   1091	/* Invoke table handler if present */
   1092
   1093	if (acpi_gbl_table_handler) {
   1094		(void)acpi_gbl_table_handler(event, table,
   1095					     acpi_gbl_table_handler_context);
   1096	}
   1097}