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>
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index c8341fa..dd43b00 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -54,7 +54,7 @@
 
 /* Local prototypes */
 static acpi_status
-acpi_ex_add_table(struct acpi_table_header *table,
+acpi_ex_add_table(acpi_native_uint table_index,
 		  struct acpi_namespace_node *parent_node,
 		  union acpi_operand_object **ddb_handle);
 
@@ -74,12 +74,11 @@
  ******************************************************************************/
 
 static acpi_status
-acpi_ex_add_table(struct acpi_table_header *table,
+acpi_ex_add_table(acpi_native_uint table_index,
 		  struct acpi_namespace_node *parent_node,
 		  union acpi_operand_object **ddb_handle)
 {
 	acpi_status status;
-	struct acpi_table_desc table_info;
 	union acpi_operand_object *obj_desc;
 
 	ACPI_FUNCTION_TRACE(ex_add_table);
@@ -98,42 +97,16 @@
 
 	/* Install the new table into the local data structures */
 
-	ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc));
-
-	table_info.type = ACPI_TABLE_ID_SSDT;
-	table_info.pointer = table;
-	table_info.length = (acpi_size) table->length;
-	table_info.allocation = ACPI_MEM_ALLOCATED;
-
-	status = acpi_tb_install_table(&table_info);
-	obj_desc->reference.object = table_info.installed_desc;
-
-	if (ACPI_FAILURE(status)) {
-		if (status == AE_ALREADY_EXISTS) {
-
-			/* Table already exists, just return the handle */
-
-			return_ACPI_STATUS(AE_OK);
-		}
-		goto cleanup;
-	}
+	obj_desc->reference.object = ACPI_CAST_PTR(void, table_index);
 
 	/* Add the table to the namespace */
 
-	status = acpi_ns_load_table(table_info.installed_desc, parent_node);
+	status = acpi_ns_load_table(table_index, parent_node);
 	if (ACPI_FAILURE(status)) {
-
-		/* Uninstall table on error */
-
-		(void)acpi_tb_uninstall_table(table_info.installed_desc);
-		goto cleanup;
+		acpi_ut_remove_reference(obj_desc);
+		*ddb_handle = NULL;
 	}
 
-	return_ACPI_STATUS(AE_OK);
-
-      cleanup:
-	acpi_ut_remove_reference(obj_desc);
-	*ddb_handle = NULL;
 	return_ACPI_STATUS(status);
 }
 
@@ -156,11 +129,12 @@
 {
 	acpi_status status;
 	union acpi_operand_object **operand = &walk_state->operands[0];
-	struct acpi_table_header *table;
+	acpi_native_uint table_index;
 	struct acpi_namespace_node *parent_node;
 	struct acpi_namespace_node *start_node;
 	struct acpi_namespace_node *parameter_node = NULL;
 	union acpi_operand_object *ddb_handle;
+	struct acpi_table_header *table;
 
 	ACPI_FUNCTION_TRACE(ex_load_table_op);
 
@@ -182,7 +156,7 @@
 
 	status = acpi_tb_find_table(operand[0]->string.pointer,
 				    operand[1]->string.pointer,
-				    operand[2]->string.pointer, &table);
+				    operand[2]->string.pointer, &table_index);
 	if (ACPI_FAILURE(status)) {
 		if (status != AE_NOT_FOUND) {
 			return_ACPI_STATUS(status);
@@ -245,7 +219,7 @@
 
 	/* Load the table into the namespace */
 
-	status = acpi_ex_add_table(table, parent_node, &ddb_handle);
+	status = acpi_ex_add_table(table_index, parent_node, &ddb_handle);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -266,9 +240,13 @@
 		}
 	}
 
-	ACPI_INFO((AE_INFO,
-		   "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]",
-		   table->signature, table->oem_id, table->oem_table_id));
+	status = acpi_get_table_by_index(table_index, &table);
+	if (ACPI_SUCCESS(status)) {
+		ACPI_INFO((AE_INFO,
+			   "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]",
+			   table->signature, table->oem_id,
+			   table->oem_table_id));
+	}
 
 	*return_desc = ddb_handle;
 	return_ACPI_STATUS(status);
@@ -298,6 +276,7 @@
 	union acpi_operand_object *ddb_handle;
 	union acpi_operand_object *buffer_desc = NULL;
 	struct acpi_table_header *table_ptr = NULL;
+	acpi_native_uint table_index;
 	acpi_physical_address address;
 	struct acpi_table_header table_header;
 	acpi_integer temp;
@@ -420,8 +399,8 @@
 
 	/* The table must be either an SSDT or a PSDT */
 
-	if ((!ACPI_COMPARE_NAME(table_ptr->signature, PSDT_SIG)) &&
-	    (!ACPI_COMPARE_NAME(table_ptr->signature, SSDT_SIG))) {
+	if ((!ACPI_COMPARE_NAME(table_ptr->signature, ACPI_SIG_PSDT)) &&
+	    (!ACPI_COMPARE_NAME(table_ptr->signature, ACPI_SIG_SSDT))) {
 		ACPI_ERROR((AE_INFO,
 			    "Table has invalid signature [%4.4s], must be SSDT or PSDT",
 			    table_ptr->signature));
@@ -429,9 +408,16 @@
 		goto cleanup;
 	}
 
-	/* Install the new table into the local data structures */
+	/*
+	 * Install the new table into the local data structures
+	 */
+	status = acpi_tb_add_table(table_ptr, &table_index);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
 
-	status = acpi_ex_add_table(table_ptr, acpi_gbl_root_node, &ddb_handle);
+	status =
+	    acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle);
 	if (ACPI_FAILURE(status)) {
 
 		/* On error, table_ptr was deallocated above */
@@ -477,7 +463,7 @@
 {
 	acpi_status status = AE_OK;
 	union acpi_operand_object *table_desc = ddb_handle;
-	struct acpi_table_desc *table_info;
+	acpi_native_uint table_index;
 
 	ACPI_FUNCTION_TRACE(ex_unload_table);
 
@@ -493,19 +479,18 @@
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	/* Get the actual table descriptor from the ddb_handle */
+	/* Get the table index from the ddb_handle */
 
-	table_info = (struct acpi_table_desc *)table_desc->reference.object;
+	table_index = (acpi_native_uint) table_desc->reference.object;
 
 	/*
 	 * Delete the entire namespace under this table Node
 	 * (Offset contains the table_id)
 	 */
-	acpi_ns_delete_namespace_by_owner(table_info->owner_id);
+	acpi_tb_delete_namespace_by_owner(table_index);
+	acpi_tb_release_owner_id(table_index);
 
-	/* Delete the table itself */
-
-	(void)acpi_tb_uninstall_table(table_info->installed_desc);
+	acpi_tb_set_table_loaded_flag(table_index, FALSE);
 
 	/* Delete the table descriptor (ddb_handle) */