Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: tbdata - Table manager data structure functions
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acnamesp.h"
0013 #include "actables.h"
0014 #include "acevents.h"
0015 
0016 #define _COMPONENT          ACPI_TABLES
0017 ACPI_MODULE_NAME("tbdata")
0018 
0019 /* Local prototypes */
0020 static acpi_status
0021 acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index);
0022 
0023 static u8
0024 acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index);
0025 
0026 /*******************************************************************************
0027  *
0028  * FUNCTION:    acpi_tb_compare_tables
0029  *
0030  * PARAMETERS:  table_desc          - Table 1 descriptor to be compared
0031  *              table_index         - Index of table 2 to be compared
0032  *
0033  * RETURN:      TRUE if both tables are identical.
0034  *
0035  * DESCRIPTION: This function compares a table with another table that has
0036  *              already been installed in the root table list.
0037  *
0038  ******************************************************************************/
0039 
0040 static u8
0041 acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
0042 {
0043     acpi_status status = AE_OK;
0044     u8 is_identical;
0045     struct acpi_table_header *table;
0046     u32 table_length;
0047     u8 table_flags;
0048 
0049     status =
0050         acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
0051                   &table, &table_length, &table_flags);
0052     if (ACPI_FAILURE(status)) {
0053         return (FALSE);
0054     }
0055 
0056     /*
0057      * Check for a table match on the entire table length,
0058      * not just the header.
0059      */
0060     is_identical = (u8)((table_desc->length != table_length ||
0061                  memcmp(table_desc->pointer, table, table_length)) ?
0062                 FALSE : TRUE);
0063 
0064     /* Release the acquired table */
0065 
0066     acpi_tb_release_table(table, table_length, table_flags);
0067     return (is_identical);
0068 }
0069 
0070 /*******************************************************************************
0071  *
0072  * FUNCTION:    acpi_tb_init_table_descriptor
0073  *
0074  * PARAMETERS:  table_desc              - Table descriptor
0075  *              address                 - Physical address of the table
0076  *              flags                   - Allocation flags of the table
0077  *              table                   - Pointer to the table
0078  *
0079  * RETURN:      None
0080  *
0081  * DESCRIPTION: Initialize a new table descriptor
0082  *
0083  ******************************************************************************/
0084 
0085 void
0086 acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc,
0087                   acpi_physical_address address,
0088                   u8 flags, struct acpi_table_header *table)
0089 {
0090 
0091     /*
0092      * Initialize the table descriptor. Set the pointer to NULL for external
0093      * tables, since the table is not fully mapped at this time.
0094      */
0095     memset(table_desc, 0, sizeof(struct acpi_table_desc));
0096     table_desc->address = address;
0097     table_desc->length = table->length;
0098     table_desc->flags = flags;
0099     ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature);
0100 
0101     switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
0102     case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
0103     case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
0104 
0105         table_desc->pointer = table;
0106         break;
0107 
0108     case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
0109     default:
0110 
0111         break;
0112     }
0113 }
0114 
0115 /*******************************************************************************
0116  *
0117  * FUNCTION:    acpi_tb_acquire_table
0118  *
0119  * PARAMETERS:  table_desc          - Table descriptor
0120  *              table_ptr           - Where table is returned
0121  *              table_length        - Where table length is returned
0122  *              table_flags         - Where table allocation flags are returned
0123  *
0124  * RETURN:      Status
0125  *
0126  * DESCRIPTION: Acquire an ACPI table. It can be used for tables not
0127  *              maintained in the acpi_gbl_root_table_list.
0128  *
0129  ******************************************************************************/
0130 
0131 acpi_status
0132 acpi_tb_acquire_table(struct acpi_table_desc *table_desc,
0133               struct acpi_table_header **table_ptr,
0134               u32 *table_length, u8 *table_flags)
0135 {
0136     struct acpi_table_header *table = NULL;
0137 
0138     switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
0139     case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
0140 
0141         table =
0142             acpi_os_map_memory(table_desc->address, table_desc->length);
0143         break;
0144 
0145     case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
0146     case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
0147 
0148         table = table_desc->pointer;
0149         break;
0150 
0151     default:
0152 
0153         break;
0154     }
0155 
0156     /* Table is not valid yet */
0157 
0158     if (!table) {
0159         return (AE_NO_MEMORY);
0160     }
0161 
0162     /* Fill the return values */
0163 
0164     *table_ptr = table;
0165     *table_length = table_desc->length;
0166     *table_flags = table_desc->flags;
0167     return (AE_OK);
0168 }
0169 
0170 /*******************************************************************************
0171  *
0172  * FUNCTION:    acpi_tb_release_table
0173  *
0174  * PARAMETERS:  table               - Pointer for the table
0175  *              table_length        - Length for the table
0176  *              table_flags         - Allocation flags for the table
0177  *
0178  * RETURN:      None
0179  *
0180  * DESCRIPTION: Release a table. The inverse of acpi_tb_acquire_table().
0181  *
0182  ******************************************************************************/
0183 
0184 void
0185 acpi_tb_release_table(struct acpi_table_header *table,
0186               u32 table_length, u8 table_flags)
0187 {
0188 
0189     switch (table_flags & ACPI_TABLE_ORIGIN_MASK) {
0190     case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
0191 
0192         acpi_os_unmap_memory(table, table_length);
0193         break;
0194 
0195     case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
0196     case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
0197     default:
0198 
0199         break;
0200     }
0201 }
0202 
0203 /*******************************************************************************
0204  *
0205  * FUNCTION:    acpi_tb_acquire_temp_table
0206  *
0207  * PARAMETERS:  table_desc          - Table descriptor to be acquired
0208  *              address             - Address of the table
0209  *              flags               - Allocation flags of the table
0210  *              table               - Pointer to the table (required for virtual
0211  *                                    origins, optional for physical)
0212  *
0213  * RETURN:      Status
0214  *
0215  * DESCRIPTION: This function validates the table header to obtain the length
0216  *              of a table and fills the table descriptor to make its state as
0217  *              "INSTALLED". Such a table descriptor is only used for verified
0218  *              installation.
0219  *
0220  ******************************************************************************/
0221 
0222 acpi_status
0223 acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc,
0224                acpi_physical_address address,
0225                u8 flags, struct acpi_table_header *table)
0226 {
0227     u8 mapped_table = FALSE;
0228 
0229     switch (flags & ACPI_TABLE_ORIGIN_MASK) {
0230     case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
0231 
0232         /* Get the length of the full table from the header */
0233 
0234         if (!table) {
0235             table =
0236                 acpi_os_map_memory(address,
0237                            sizeof(struct
0238                               acpi_table_header));
0239             if (!table) {
0240                 return (AE_NO_MEMORY);
0241             }
0242 
0243             mapped_table = TRUE;
0244         }
0245 
0246         break;
0247 
0248     case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
0249     case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
0250 
0251         if (!table) {
0252             return (AE_BAD_PARAMETER);
0253         }
0254 
0255         break;
0256 
0257     default:
0258 
0259         /* Table is not valid yet */
0260 
0261         return (AE_NO_MEMORY);
0262     }
0263 
0264     acpi_tb_init_table_descriptor(table_desc, address, flags, table);
0265     if (mapped_table) {
0266         acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
0267     }
0268 
0269     return (AE_OK);
0270 }
0271 
0272 /*******************************************************************************
0273  *
0274  * FUNCTION:    acpi_tb_release_temp_table
0275  *
0276  * PARAMETERS:  table_desc          - Table descriptor to be released
0277  *
0278  * RETURN:      Status
0279  *
0280  * DESCRIPTION: The inverse of acpi_tb_acquire_temp_table().
0281  *
0282  *****************************************************************************/
0283 
0284 void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc)
0285 {
0286 
0287     /*
0288      * Note that the .Address is maintained by the callers of
0289      * acpi_tb_acquire_temp_table(), thus do not invoke acpi_tb_uninstall_table()
0290      * where .Address will be freed.
0291      */
0292     acpi_tb_invalidate_table(table_desc);
0293 }
0294 
0295 /******************************************************************************
0296  *
0297  * FUNCTION:    acpi_tb_validate_table
0298  *
0299  * PARAMETERS:  table_desc          - Table descriptor
0300  *
0301  * RETURN:      Status
0302  *
0303  * DESCRIPTION: This function is called to validate the table, the returned
0304  *              table descriptor is in "VALIDATED" state.
0305  *
0306  *****************************************************************************/
0307 
0308 acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc)
0309 {
0310     acpi_status status = AE_OK;
0311 
0312     ACPI_FUNCTION_TRACE(tb_validate_table);
0313 
0314     /* Validate the table if necessary */
0315 
0316     if (!table_desc->pointer) {
0317         status = acpi_tb_acquire_table(table_desc, &table_desc->pointer,
0318                            &table_desc->length,
0319                            &table_desc->flags);
0320         if (!table_desc->pointer) {
0321             status = AE_NO_MEMORY;
0322         }
0323     }
0324 
0325     return_ACPI_STATUS(status);
0326 }
0327 
0328 /*******************************************************************************
0329  *
0330  * FUNCTION:    acpi_tb_invalidate_table
0331  *
0332  * PARAMETERS:  table_desc          - Table descriptor
0333  *
0334  * RETURN:      None
0335  *
0336  * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of
0337  *              acpi_tb_validate_table().
0338  *
0339  ******************************************************************************/
0340 
0341 void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc)
0342 {
0343 
0344     ACPI_FUNCTION_TRACE(tb_invalidate_table);
0345 
0346     /* Table must be validated */
0347 
0348     if (!table_desc->pointer) {
0349         return_VOID;
0350     }
0351 
0352     acpi_tb_release_table(table_desc->pointer, table_desc->length,
0353                   table_desc->flags);
0354 
0355     switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
0356     case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
0357 
0358         table_desc->pointer = NULL;
0359         break;
0360 
0361     case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
0362     case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
0363     default:
0364 
0365         break;
0366     }
0367 
0368     return_VOID;
0369 }
0370 
0371 /******************************************************************************
0372  *
0373  * FUNCTION:    acpi_tb_validate_temp_table
0374  *
0375  * PARAMETERS:  table_desc          - Table descriptor
0376  *
0377  * RETURN:      Status
0378  *
0379  * DESCRIPTION: This function is called to validate the table, the returned
0380  *              table descriptor is in "VALIDATED" state.
0381  *
0382  *****************************************************************************/
0383 
0384 acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
0385 {
0386 
0387     if (!table_desc->pointer && !acpi_gbl_enable_table_validation) {
0388         /*
0389          * Only validates the header of the table.
0390          * Note that Length contains the size of the mapping after invoking
0391          * this work around, this value is required by
0392          * acpi_tb_release_temp_table().
0393          * We can do this because in acpi_init_table_descriptor(), the Length
0394          * field of the installed descriptor is filled with the actual
0395          * table length obtaining from the table header.
0396          */
0397         table_desc->length = sizeof(struct acpi_table_header);
0398     }
0399 
0400     return (acpi_tb_validate_table(table_desc));
0401 }
0402 
0403 /*******************************************************************************
0404  *
0405  * FUNCTION:    acpi_tb_check_duplication
0406  *
0407  * PARAMETERS:  table_desc          - Table descriptor
0408  *              table_index         - Where the table index is returned
0409  *
0410  * RETURN:      Status
0411  *
0412  * DESCRIPTION: Avoid installing duplicated tables. However table override and
0413  *              user aided dynamic table load is allowed, thus comparing the
0414  *              address of the table is not sufficient, and checking the entire
0415  *              table content is required.
0416  *
0417  ******************************************************************************/
0418 
0419 static acpi_status
0420 acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index)
0421 {
0422     u32 i;
0423 
0424     ACPI_FUNCTION_TRACE(tb_check_duplication);
0425 
0426     /* Check if table is already registered */
0427 
0428     for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
0429 
0430         /* Do not compare with unverified tables */
0431 
0432         if (!
0433             (acpi_gbl_root_table_list.tables[i].
0434              flags & ACPI_TABLE_IS_VERIFIED)) {
0435             continue;
0436         }
0437 
0438         /*
0439          * Check for a table match on the entire table length,
0440          * not just the header.
0441          */
0442         if (!acpi_tb_compare_tables(table_desc, i)) {
0443             continue;
0444         }
0445 
0446         /*
0447          * Note: the current mechanism does not unregister a table if it is
0448          * dynamically unloaded. The related namespace entries are deleted,
0449          * but the table remains in the root table list.
0450          *
0451          * The assumption here is that the number of different tables that
0452          * will be loaded is actually small, and there is minimal overhead
0453          * in just keeping the table in case it is needed again.
0454          *
0455          * If this assumption changes in the future (perhaps on large
0456          * machines with many table load/unload operations), tables will
0457          * need to be unregistered when they are unloaded, and slots in the
0458          * root table list should be reused when empty.
0459          */
0460         if (acpi_gbl_root_table_list.tables[i].flags &
0461             ACPI_TABLE_IS_LOADED) {
0462 
0463             /* Table is still loaded, this is an error */
0464 
0465             return_ACPI_STATUS(AE_ALREADY_EXISTS);
0466         } else {
0467             *table_index = i;
0468             return_ACPI_STATUS(AE_CTRL_TERMINATE);
0469         }
0470     }
0471 
0472     /* Indicate no duplication to the caller */
0473 
0474     return_ACPI_STATUS(AE_OK);
0475 }
0476 
0477 /******************************************************************************
0478  *
0479  * FUNCTION:    acpi_tb_verify_temp_table
0480  *
0481  * PARAMETERS:  table_desc          - Table descriptor
0482  *              signature           - Table signature to verify
0483  *              table_index         - Where the table index is returned
0484  *
0485  * RETURN:      Status
0486  *
0487  * DESCRIPTION: This function is called to validate and verify the table, the
0488  *              returned table descriptor is in "VALIDATED" state.
0489  *              Note that 'TableIndex' is required to be set to !NULL to
0490  *              enable duplication check.
0491  *
0492  *****************************************************************************/
0493 
0494 acpi_status
0495 acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
0496               char *signature, u32 *table_index)
0497 {
0498     acpi_status status = AE_OK;
0499 
0500     ACPI_FUNCTION_TRACE(tb_verify_temp_table);
0501 
0502     /* Validate the table */
0503 
0504     status = acpi_tb_validate_temp_table(table_desc);
0505     if (ACPI_FAILURE(status)) {
0506         return_ACPI_STATUS(AE_NO_MEMORY);
0507     }
0508 
0509     /* If a particular signature is expected (DSDT/FACS), it must match */
0510 
0511     if (signature &&
0512         !ACPI_COMPARE_NAMESEG(&table_desc->signature, signature)) {
0513         ACPI_BIOS_ERROR((AE_INFO,
0514                  "Invalid signature 0x%X for ACPI table, expected [%s]",
0515                  table_desc->signature.integer, signature));
0516         status = AE_BAD_SIGNATURE;
0517         goto invalidate_and_exit;
0518     }
0519 
0520     if (acpi_gbl_enable_table_validation) {
0521 
0522         /* Verify the checksum */
0523 
0524         status =
0525             acpi_tb_verify_checksum(table_desc->pointer,
0526                         table_desc->length);
0527         if (ACPI_FAILURE(status)) {
0528             ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
0529                     "%4.4s 0x%8.8X%8.8X"
0530                     " Attempted table install failed",
0531                     acpi_ut_valid_nameseg(table_desc->
0532                                   signature.
0533                                   ascii) ?
0534                     table_desc->signature.ascii : "????",
0535                     ACPI_FORMAT_UINT64(table_desc->
0536                                address)));
0537 
0538             goto invalidate_and_exit;
0539         }
0540 
0541         /* Avoid duplications */
0542 
0543         if (table_index) {
0544             status =
0545                 acpi_tb_check_duplication(table_desc, table_index);
0546             if (ACPI_FAILURE(status)) {
0547                 if (status != AE_CTRL_TERMINATE) {
0548                     ACPI_EXCEPTION((AE_INFO, status,
0549                             "%4.4s 0x%8.8X%8.8X"
0550                             " Table is already loaded",
0551                             acpi_ut_valid_nameseg
0552                             (table_desc->signature.
0553                              ascii) ? table_desc->
0554                             signature.
0555                             ascii : "????",
0556                             ACPI_FORMAT_UINT64
0557                             (table_desc->address)));
0558                 }
0559 
0560                 goto invalidate_and_exit;
0561             }
0562         }
0563 
0564         table_desc->flags |= ACPI_TABLE_IS_VERIFIED;
0565     }
0566 
0567     return_ACPI_STATUS(status);
0568 
0569 invalidate_and_exit:
0570     acpi_tb_invalidate_table(table_desc);
0571     return_ACPI_STATUS(status);
0572 }
0573 
0574 /*******************************************************************************
0575  *
0576  * FUNCTION:    acpi_tb_resize_root_table_list
0577  *
0578  * PARAMETERS:  None
0579  *
0580  * RETURN:      Status
0581  *
0582  * DESCRIPTION: Expand the size of global table array
0583  *
0584  ******************************************************************************/
0585 
0586 acpi_status acpi_tb_resize_root_table_list(void)
0587 {
0588     struct acpi_table_desc *tables;
0589     u32 table_count;
0590     u32 current_table_count, max_table_count;
0591     u32 i;
0592 
0593     ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
0594 
0595     /* allow_resize flag is a parameter to acpi_initialize_tables */
0596 
0597     if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
0598         ACPI_ERROR((AE_INFO,
0599                 "Resize of Root Table Array is not allowed"));
0600         return_ACPI_STATUS(AE_SUPPORT);
0601     }
0602 
0603     /* Increase the Table Array size */
0604 
0605     if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
0606         table_count = acpi_gbl_root_table_list.max_table_count;
0607     } else {
0608         table_count = acpi_gbl_root_table_list.current_table_count;
0609     }
0610 
0611     max_table_count = table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
0612     tables = ACPI_ALLOCATE_ZEROED(((acpi_size)max_table_count) *
0613                       sizeof(struct acpi_table_desc));
0614     if (!tables) {
0615         ACPI_ERROR((AE_INFO,
0616                 "Could not allocate new root table array"));
0617         return_ACPI_STATUS(AE_NO_MEMORY);
0618     }
0619 
0620     /* Copy and free the previous table array */
0621 
0622     current_table_count = 0;
0623     if (acpi_gbl_root_table_list.tables) {
0624         for (i = 0; i < table_count; i++) {
0625             if (acpi_gbl_root_table_list.tables[i].address) {
0626                 memcpy(tables + current_table_count,
0627                        acpi_gbl_root_table_list.tables + i,
0628                        sizeof(struct acpi_table_desc));
0629                 current_table_count++;
0630             }
0631         }
0632 
0633         if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
0634             ACPI_FREE(acpi_gbl_root_table_list.tables);
0635         }
0636     }
0637 
0638     acpi_gbl_root_table_list.tables = tables;
0639     acpi_gbl_root_table_list.max_table_count = max_table_count;
0640     acpi_gbl_root_table_list.current_table_count = current_table_count;
0641     acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
0642 
0643     return_ACPI_STATUS(AE_OK);
0644 }
0645 
0646 /*******************************************************************************
0647  *
0648  * FUNCTION:    acpi_tb_get_next_table_descriptor
0649  *
0650  * PARAMETERS:  table_index         - Where table index is returned
0651  *              table_desc          - Where table descriptor is returned
0652  *
0653  * RETURN:      Status and table index/descriptor.
0654  *
0655  * DESCRIPTION: Allocate a new ACPI table entry to the global table list
0656  *
0657  ******************************************************************************/
0658 
0659 acpi_status
0660 acpi_tb_get_next_table_descriptor(u32 *table_index,
0661                   struct acpi_table_desc **table_desc)
0662 {
0663     acpi_status status;
0664     u32 i;
0665 
0666     /* Ensure that there is room for the table in the Root Table List */
0667 
0668     if (acpi_gbl_root_table_list.current_table_count >=
0669         acpi_gbl_root_table_list.max_table_count) {
0670         status = acpi_tb_resize_root_table_list();
0671         if (ACPI_FAILURE(status)) {
0672             return (status);
0673         }
0674     }
0675 
0676     i = acpi_gbl_root_table_list.current_table_count;
0677     acpi_gbl_root_table_list.current_table_count++;
0678 
0679     if (table_index) {
0680         *table_index = i;
0681     }
0682     if (table_desc) {
0683         *table_desc = &acpi_gbl_root_table_list.tables[i];
0684     }
0685 
0686     return (AE_OK);
0687 }
0688 
0689 /*******************************************************************************
0690  *
0691  * FUNCTION:    acpi_tb_terminate
0692  *
0693  * PARAMETERS:  None
0694  *
0695  * RETURN:      None
0696  *
0697  * DESCRIPTION: Delete all internal ACPI tables
0698  *
0699  ******************************************************************************/
0700 
0701 void acpi_tb_terminate(void)
0702 {
0703     u32 i;
0704 
0705     ACPI_FUNCTION_TRACE(tb_terminate);
0706 
0707     (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0708 
0709     /* Delete the individual tables */
0710 
0711     for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
0712         acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]);
0713     }
0714 
0715     /*
0716      * Delete the root table array if allocated locally. Array cannot be
0717      * mapped, so we don't need to check for that flag.
0718      */
0719     if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
0720         ACPI_FREE(acpi_gbl_root_table_list.tables);
0721     }
0722 
0723     acpi_gbl_root_table_list.tables = NULL;
0724     acpi_gbl_root_table_list.flags = 0;
0725     acpi_gbl_root_table_list.current_table_count = 0;
0726 
0727     ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
0728 
0729     (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0730     return_VOID;
0731 }
0732 
0733 /*******************************************************************************
0734  *
0735  * FUNCTION:    acpi_tb_delete_namespace_by_owner
0736  *
0737  * PARAMETERS:  table_index         - Table index
0738  *
0739  * RETURN:      Status
0740  *
0741  * DESCRIPTION: Delete all namespace objects created when this table was loaded.
0742  *
0743  ******************************************************************************/
0744 
0745 acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
0746 {
0747     acpi_owner_id owner_id;
0748     acpi_status status;
0749 
0750     ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
0751 
0752     status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0753     if (ACPI_FAILURE(status)) {
0754         return_ACPI_STATUS(status);
0755     }
0756 
0757     if (table_index >= acpi_gbl_root_table_list.current_table_count) {
0758 
0759         /* The table index does not exist */
0760 
0761         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0762         return_ACPI_STATUS(AE_NOT_EXIST);
0763     }
0764 
0765     /* Get the owner ID for this table, used to delete namespace nodes */
0766 
0767     owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
0768     (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0769 
0770     /*
0771      * Need to acquire the namespace writer lock to prevent interference
0772      * with any concurrent namespace walks. The interpreter must be
0773      * released during the deletion since the acquisition of the deletion
0774      * lock may block, and also since the execution of a namespace walk
0775      * must be allowed to use the interpreter.
0776      */
0777     status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
0778     if (ACPI_FAILURE(status)) {
0779         return_ACPI_STATUS(status);
0780     }
0781 
0782     acpi_ns_delete_namespace_by_owner(owner_id);
0783     acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
0784     return_ACPI_STATUS(status);
0785 }
0786 
0787 /*******************************************************************************
0788  *
0789  * FUNCTION:    acpi_tb_allocate_owner_id
0790  *
0791  * PARAMETERS:  table_index         - Table index
0792  *
0793  * RETURN:      Status
0794  *
0795  * DESCRIPTION: Allocates owner_id in table_desc
0796  *
0797  ******************************************************************************/
0798 
0799 acpi_status acpi_tb_allocate_owner_id(u32 table_index)
0800 {
0801     acpi_status status = AE_BAD_PARAMETER;
0802 
0803     ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
0804 
0805     (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0806     if (table_index < acpi_gbl_root_table_list.current_table_count) {
0807         status =
0808             acpi_ut_allocate_owner_id(&
0809                           (acpi_gbl_root_table_list.
0810                            tables[table_index].owner_id));
0811     }
0812 
0813     (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0814     return_ACPI_STATUS(status);
0815 }
0816 
0817 /*******************************************************************************
0818  *
0819  * FUNCTION:    acpi_tb_release_owner_id
0820  *
0821  * PARAMETERS:  table_index         - Table index
0822  *
0823  * RETURN:      Status
0824  *
0825  * DESCRIPTION: Releases owner_id in table_desc
0826  *
0827  ******************************************************************************/
0828 
0829 acpi_status acpi_tb_release_owner_id(u32 table_index)
0830 {
0831     acpi_status status = AE_BAD_PARAMETER;
0832 
0833     ACPI_FUNCTION_TRACE(tb_release_owner_id);
0834 
0835     (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0836     if (table_index < acpi_gbl_root_table_list.current_table_count) {
0837         acpi_ut_release_owner_id(&
0838                      (acpi_gbl_root_table_list.
0839                       tables[table_index].owner_id));
0840         status = AE_OK;
0841     }
0842 
0843     (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0844     return_ACPI_STATUS(status);
0845 }
0846 
0847 /*******************************************************************************
0848  *
0849  * FUNCTION:    acpi_tb_get_owner_id
0850  *
0851  * PARAMETERS:  table_index         - Table index
0852  *              owner_id            - Where the table owner_id is returned
0853  *
0854  * RETURN:      Status
0855  *
0856  * DESCRIPTION: returns owner_id for the ACPI table
0857  *
0858  ******************************************************************************/
0859 
0860 acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id)
0861 {
0862     acpi_status status = AE_BAD_PARAMETER;
0863 
0864     ACPI_FUNCTION_TRACE(tb_get_owner_id);
0865 
0866     (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0867     if (table_index < acpi_gbl_root_table_list.current_table_count) {
0868         *owner_id =
0869             acpi_gbl_root_table_list.tables[table_index].owner_id;
0870         status = AE_OK;
0871     }
0872 
0873     (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0874     return_ACPI_STATUS(status);
0875 }
0876 
0877 /*******************************************************************************
0878  *
0879  * FUNCTION:    acpi_tb_is_table_loaded
0880  *
0881  * PARAMETERS:  table_index         - Index into the root table
0882  *
0883  * RETURN:      Table Loaded Flag
0884  *
0885  ******************************************************************************/
0886 
0887 u8 acpi_tb_is_table_loaded(u32 table_index)
0888 {
0889     u8 is_loaded = FALSE;
0890 
0891     (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0892     if (table_index < acpi_gbl_root_table_list.current_table_count) {
0893         is_loaded = (u8)
0894             (acpi_gbl_root_table_list.tables[table_index].flags &
0895              ACPI_TABLE_IS_LOADED);
0896     }
0897 
0898     (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0899     return (is_loaded);
0900 }
0901 
0902 /*******************************************************************************
0903  *
0904  * FUNCTION:    acpi_tb_set_table_loaded_flag
0905  *
0906  * PARAMETERS:  table_index         - Table index
0907  *              is_loaded           - TRUE if table is loaded, FALSE otherwise
0908  *
0909  * RETURN:      None
0910  *
0911  * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
0912  *
0913  ******************************************************************************/
0914 
0915 void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
0916 {
0917 
0918     (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
0919     if (table_index < acpi_gbl_root_table_list.current_table_count) {
0920         if (is_loaded) {
0921             acpi_gbl_root_table_list.tables[table_index].flags |=
0922                 ACPI_TABLE_IS_LOADED;
0923         } else {
0924             acpi_gbl_root_table_list.tables[table_index].flags &=
0925                 ~ACPI_TABLE_IS_LOADED;
0926         }
0927     }
0928 
0929     (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
0930 }
0931 
0932 /*******************************************************************************
0933  *
0934  * FUNCTION:    acpi_tb_load_table
0935  *
0936  * PARAMETERS:  table_index             - Table index
0937  *              parent_node             - Where table index is returned
0938  *
0939  * RETURN:      Status
0940  *
0941  * DESCRIPTION: Load an ACPI table
0942  *
0943  ******************************************************************************/
0944 
0945 acpi_status
0946 acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node)
0947 {
0948     struct acpi_table_header *table;
0949     acpi_status status;
0950     acpi_owner_id owner_id;
0951 
0952     ACPI_FUNCTION_TRACE(tb_load_table);
0953 
0954     /*
0955      * Note: Now table is "INSTALLED", it must be validated before
0956      * using.
0957      */
0958     status = acpi_get_table_by_index(table_index, &table);
0959     if (ACPI_FAILURE(status)) {
0960         return_ACPI_STATUS(status);
0961     }
0962 
0963     status = acpi_ns_load_table(table_index, parent_node);
0964     if (ACPI_FAILURE(status)) {
0965         return_ACPI_STATUS(status);
0966     }
0967 
0968     /*
0969      * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
0970      * responsible for discovering any new wake GPEs by running _PRW methods
0971      * that may have been loaded by this table.
0972      */
0973     status = acpi_tb_get_owner_id(table_index, &owner_id);
0974     if (ACPI_SUCCESS(status)) {
0975         acpi_ev_update_gpes(owner_id);
0976     }
0977 
0978     /* Invoke table handler */
0979 
0980     acpi_tb_notify_table(ACPI_TABLE_EVENT_LOAD, table);
0981     return_ACPI_STATUS(status);
0982 }
0983 
0984 /*******************************************************************************
0985  *
0986  * FUNCTION:    acpi_tb_install_and_load_table
0987  *
0988  * PARAMETERS:  address                 - Physical address of the table
0989  *              flags                   - Allocation flags of the table
0990  *              table                   - Pointer to the table (required for
0991  *                                        virtual origins, optional for
0992  *                                        physical)
0993  *              override                - Whether override should be performed
0994  *              table_index             - Where table index is returned
0995  *
0996  * RETURN:      Status
0997  *
0998  * DESCRIPTION: Install and load an ACPI table
0999  *
1000  ******************************************************************************/
1001 
1002 acpi_status
1003 acpi_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 
1023 exit:
1024     *table_index = i;
1025     return_ACPI_STATUS(status);
1026 }
1027 
1028 ACPI_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 
1042 acpi_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 
1074 ACPI_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 
1089 void 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 }