From f3d2e7865c816258c699ff965768e46b50d536d3 Mon Sep 17 00:00:00 2001 From: Bob Moore <robert.moore@intel.com> Date: Fri, 2 Feb 2007 19:48:18 +0300 Subject: ACPICA: Implement simplified Table Manager The Table Manager component has been completely redesigned and reimplemented. The new design is much simpler, and reduces the overall code and data size of the kernel-resident ACPICA by approximately 5%. Also, it is now possible to obtain the ACPI tables very early during kernel initialization, even before dynamic memory management is initialized. Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> Signed-off-by: Len Brown <len.brown@intel.com> --- drivers/acpi/namespace/nsload.c | 158 +++++++-------------------------------- drivers/acpi/namespace/nsparse.c | 46 +++++++++--- drivers/acpi/namespace/nsutils.c | 7 -- 3 files changed, 64 insertions(+), 147 deletions(-) (limited to 'drivers/acpi/namespace') diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c index fe75d888e183..5d555f8c167b 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/namespace/nsload.c @@ -44,13 +44,12 @@ #include <acpi/acpi.h> #include <acpi/acnamesp.h> #include <acpi/acdispat.h> +#include <acpi/actables.h> #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsload") /* Local prototypes */ -static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type); - #ifdef ACPI_FUTURE_IMPLEMENTATION acpi_status acpi_ns_unload_namespace(acpi_handle handle); @@ -62,7 +61,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); * * FUNCTION: acpi_ns_load_table * - * PARAMETERS: table_desc - Descriptor for table to be loaded + * PARAMETERS: table_index - Index for table to be loaded * Node - Owning NS node * * RETURN: Status @@ -72,42 +71,13 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); ******************************************************************************/ acpi_status -acpi_ns_load_table(struct acpi_table_desc *table_desc, +acpi_ns_load_table(acpi_native_uint table_index, struct acpi_namespace_node *node) { acpi_status status; ACPI_FUNCTION_TRACE(ns_load_table); - /* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */ - - if (! - (acpi_gbl_table_data[table_desc->type]. - flags & ACPI_TABLE_EXECUTABLE)) { - - /* Just ignore this table */ - - return_ACPI_STATUS(AE_OK); - } - - /* Check validity of the AML start and length */ - - if (!table_desc->aml_start) { - ACPI_ERROR((AE_INFO, "Null AML pointer")); - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AML block at %p\n", - table_desc->aml_start)); - - /* Ignore table if there is no AML contained within */ - - if (!table_desc->aml_length) { - ACPI_WARNING((AE_INFO, "Zero-length AML block in table [%4.4s]", - table_desc->pointer->signature)); - return_ACPI_STATUS(AE_OK); - } - /* * Parse the table and load the namespace with all named * objects found within. Control methods are NOT parsed @@ -117,15 +87,34 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, * to another control method, we can't continue parsing * because we don't know how many arguments to parse next! */ + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* If table already loaded into namespace, just return */ + + if (acpi_tb_is_table_loaded(table_index)) { + status = AE_ALREADY_EXISTS; + goto unlock; + } + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Loading table into namespace ****\n")); - status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + status = acpi_tb_allocate_owner_id(table_index); if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + goto unlock; + } + + status = acpi_ns_parse_table(table_index, node->child); + if (ACPI_SUCCESS(status)) { + acpi_tb_set_table_loaded_flag(table_index, TRUE); + } else { + acpi_tb_release_owner_id(table_index); } - status = acpi_ns_parse_table(table_desc, node->child); + unlock: (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { @@ -141,7 +130,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Begin Table Method Parsing and Object Initialization ****\n")); - status = acpi_ds_initialize_objects(table_desc, node); + status = acpi_ds_initialize_objects(table_index, node); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Completed Table Method Parsing and Object Initialization ****\n")); @@ -149,99 +138,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, return_ACPI_STATUS(status); } -/******************************************************************************* - * - * FUNCTION: acpi_ns_load_table_by_type - * - * PARAMETERS: table_type - Id of the table type to load - * - * RETURN: Status - * - * DESCRIPTION: Load an ACPI table or tables into the namespace. All tables - * of the given type are loaded. The mechanism allows this - * routine to be called repeatedly. - * - ******************************************************************************/ - -static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type) -{ - u32 i; - acpi_status status; - struct acpi_table_desc *table_desc; - - ACPI_FUNCTION_TRACE(ns_load_table_by_type); - - status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Table types supported are: - * DSDT (one), SSDT/PSDT (multiple) - */ - switch (table_type) { - case ACPI_TABLE_ID_DSDT: - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace load: DSDT\n")); - - table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_DSDT].next; - - /* If table already loaded into namespace, just return */ - - if (table_desc->loaded_into_namespace) { - goto unlock_and_exit; - } - - /* Now load the single DSDT */ - - status = acpi_ns_load_table(table_desc, acpi_gbl_root_node); - if (ACPI_SUCCESS(status)) { - table_desc->loaded_into_namespace = TRUE; - } - break; - - case ACPI_TABLE_ID_SSDT: - case ACPI_TABLE_ID_PSDT: - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Namespace load: %d SSDT or PSDTs\n", - acpi_gbl_table_lists[table_type].count)); - - /* - * Traverse list of SSDT or PSDT tables - */ - table_desc = acpi_gbl_table_lists[table_type].next; - for (i = 0; i < acpi_gbl_table_lists[table_type].count; i++) { - /* - * Only attempt to load table into namespace if it is not - * already loaded! - */ - if (!table_desc->loaded_into_namespace) { - status = - acpi_ns_load_table(table_desc, - acpi_gbl_root_node); - if (ACPI_FAILURE(status)) { - break; - } - - table_desc->loaded_into_namespace = TRUE; - } - - table_desc = table_desc->next; - } - break; - - default: - status = AE_SUPPORT; - break; - } - - unlock_and_exit: - (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - return_ACPI_STATUS(status); -} - +#ifdef ACPI_OBSOLETE_FUNCTIONS /******************************************************************************* * * FUNCTION: acpi_load_namespace @@ -288,6 +185,7 @@ acpi_status acpi_ns_load_namespace(void) return_ACPI_STATUS(status); } +#endif #ifdef ACPI_FUTURE_IMPLEMENTATION /******************************************************************************* diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c index 155505a4ef69..2e224796d56f 100644 --- a/drivers/acpi/namespace/nsparse.c +++ b/drivers/acpi/namespace/nsparse.c @@ -45,6 +45,7 @@ #include <acpi/acnamesp.h> #include <acpi/acparser.h> #include <acpi/acdispat.h> +#include <acpi/actables.h> #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsparse") @@ -62,14 +63,24 @@ ACPI_MODULE_NAME("nsparse") * ******************************************************************************/ acpi_status -acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) +acpi_ns_one_complete_parse(acpi_native_uint pass_number, + acpi_native_uint table_index) { union acpi_parse_object *parse_root; acpi_status status; + acpi_native_uint aml_length; + u8 *aml_start; struct acpi_walk_state *walk_state; + struct acpi_table_header *table; + acpi_owner_id owner_id; ACPI_FUNCTION_TRACE(ns_one_complete_parse); + status = acpi_tb_get_owner_id(table_index, &owner_id); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + /* Create and init a Root Node */ parse_root = acpi_ps_create_scope_op(); @@ -79,19 +90,34 @@ acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) /* Create and initialize a new walk state */ - walk_state = acpi_ds_create_walk_state(table_desc->owner_id, - NULL, NULL, NULL); + walk_state = acpi_ds_create_walk_state(owner_id, NULL, NULL, NULL); if (!walk_state) { acpi_ps_free_op(parse_root); return_ACPI_STATUS(AE_NO_MEMORY); } - status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, - table_desc->aml_start, - table_desc->aml_length, NULL, - pass_number); + status = acpi_get_table_by_index(table_index, &table); + if (ACPI_FAILURE(status)) { + acpi_ds_delete_walk_state(walk_state); + acpi_ps_free_op(parse_root); + return_ACPI_STATUS(status); + } + + /* Table must consist of at least a complete header */ + + if (table->length < sizeof(struct acpi_table_header)) { + status = AE_BAD_HEADER; + } else { + aml_start = (u8 *) table + sizeof(struct acpi_table_header); + aml_length = table->length - sizeof(struct acpi_table_header); + status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, + aml_start, aml_length, NULL, + (u8) pass_number); + } + if (ACPI_FAILURE(status)) { acpi_ds_delete_walk_state(walk_state); + acpi_ps_delete_parse_tree(parse_root); return_ACPI_STATUS(status); } @@ -119,7 +145,7 @@ acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) ******************************************************************************/ acpi_status -acpi_ns_parse_table(struct acpi_table_desc *table_desc, +acpi_ns_parse_table(acpi_native_uint table_index, struct acpi_namespace_node *start_node) { acpi_status status; @@ -137,7 +163,7 @@ acpi_ns_parse_table(struct acpi_table_desc *table_desc, * performs another complete parse of the AML.. */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); - status = acpi_ns_one_complete_parse(1, table_desc); + status = acpi_ns_one_complete_parse(1, table_index); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -152,7 +178,7 @@ acpi_ns_parse_table(struct acpi_table_desc *table_desc, * parse objects are all cached. */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); - status = acpi_ns_one_complete_parse(2, table_desc); + status = acpi_ns_one_complete_parse(2, table_index); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c index aa4e799d9a8c..4eb155cc406f 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/namespace/nsutils.c @@ -770,13 +770,6 @@ void acpi_ns_terminate(void) } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n")); - - /* - * 2) Now we can delete the ACPI tables - */ - acpi_tb_delete_all_tables(); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); - return_VOID; } -- cgit v1.2.3