|
@@ -51,6 +51,96 @@
|
|
#define _COMPONENT ACPI_NAMESPACE
|
|
#define _COMPONENT ACPI_NAMESPACE
|
|
ACPI_MODULE_NAME("nsparse")
|
|
ACPI_MODULE_NAME("nsparse")
|
|
|
|
|
|
|
|
+/*******************************************************************************
|
|
|
|
+ *
|
|
|
|
+ * FUNCTION: ns_execute_table
|
|
|
|
+ *
|
|
|
|
+ * PARAMETERS: table_desc - An ACPI table descriptor for table to parse
|
|
|
|
+ * start_node - Where to enter the table into the namespace
|
|
|
|
+ *
|
|
|
|
+ * RETURN: Status
|
|
|
|
+ *
|
|
|
|
+ * DESCRIPTION: Load ACPI/AML table by executing the entire table as a
|
|
|
|
+ * term_list.
|
|
|
|
+ *
|
|
|
|
+ ******************************************************************************/
|
|
|
|
+acpi_status
|
|
|
|
+acpi_ns_execute_table(u32 table_index, struct acpi_namespace_node *start_node)
|
|
|
|
+{
|
|
|
|
+ acpi_status status;
|
|
|
|
+ struct acpi_table_header *table;
|
|
|
|
+ acpi_owner_id owner_id;
|
|
|
|
+ struct acpi_evaluate_info *info = NULL;
|
|
|
|
+ u32 aml_length;
|
|
|
|
+ u8 *aml_start;
|
|
|
|
+ union acpi_operand_object *method_obj = NULL;
|
|
|
|
+
|
|
|
|
+ ACPI_FUNCTION_TRACE(ns_execute_table);
|
|
|
|
+
|
|
|
|
+ status = acpi_get_table_by_index(table_index, &table);
|
|
|
|
+ if (ACPI_FAILURE(status)) {
|
|
|
|
+ return_ACPI_STATUS(status);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Table must consist of at least a complete header */
|
|
|
|
+
|
|
|
|
+ if (table->length < sizeof(struct acpi_table_header)) {
|
|
|
|
+ return_ACPI_STATUS(AE_BAD_HEADER);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ aml_start = (u8 *)table + sizeof(struct acpi_table_header);
|
|
|
|
+ aml_length = table->length - sizeof(struct acpi_table_header);
|
|
|
|
+
|
|
|
|
+ status = acpi_tb_get_owner_id(table_index, &owner_id);
|
|
|
|
+ if (ACPI_FAILURE(status)) {
|
|
|
|
+ return_ACPI_STATUS(status);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Create, initialize, and link a new temporary method object */
|
|
|
|
+
|
|
|
|
+ method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
|
|
|
|
+ if (!method_obj) {
|
|
|
|
+ return_ACPI_STATUS(AE_NO_MEMORY);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Allocate the evaluation information block */
|
|
|
|
+
|
|
|
|
+ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
|
|
|
|
+ if (!info) {
|
|
|
|
+ status = AE_NO_MEMORY;
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
|
|
|
|
+ "Create table code block: %p\n", method_obj));
|
|
|
|
+
|
|
|
|
+ method_obj->method.aml_start = aml_start;
|
|
|
|
+ method_obj->method.aml_length = aml_length;
|
|
|
|
+ method_obj->method.owner_id = owner_id;
|
|
|
|
+ method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL;
|
|
|
|
+
|
|
|
|
+ info->pass_number = ACPI_IMODE_EXECUTE;
|
|
|
|
+ info->node = start_node;
|
|
|
|
+ info->obj_desc = method_obj;
|
|
|
|
+ info->node_flags = info->node->flags;
|
|
|
|
+ info->full_pathname = acpi_ns_get_normalized_pathname(info->node, TRUE);
|
|
|
|
+ if (!info->full_pathname) {
|
|
|
|
+ status = AE_NO_MEMORY;
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ status = acpi_ps_execute_table(info);
|
|
|
|
+
|
|
|
|
+cleanup:
|
|
|
|
+ if (info) {
|
|
|
|
+ ACPI_FREE(info->full_pathname);
|
|
|
|
+ info->full_pathname = NULL;
|
|
|
|
+ }
|
|
|
|
+ ACPI_FREE(info);
|
|
|
|
+ acpi_ut_remove_reference(method_obj);
|
|
|
|
+ return_ACPI_STATUS(status);
|
|
|
|
+}
|
|
|
|
+
|
|
/*******************************************************************************
|
|
/*******************************************************************************
|
|
*
|
|
*
|
|
* FUNCTION: ns_one_complete_parse
|
|
* FUNCTION: ns_one_complete_parse
|
|
@@ -63,6 +153,7 @@ ACPI_MODULE_NAME("nsparse")
|
|
* DESCRIPTION: Perform one complete parse of an ACPI/AML table.
|
|
* DESCRIPTION: Perform one complete parse of an ACPI/AML table.
|
|
*
|
|
*
|
|
******************************************************************************/
|
|
******************************************************************************/
|
|
|
|
+
|
|
acpi_status
|
|
acpi_status
|
|
acpi_ns_one_complete_parse(u32 pass_number,
|
|
acpi_ns_one_complete_parse(u32 pass_number,
|
|
u32 table_index,
|
|
u32 table_index,
|
|
@@ -170,38 +261,47 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
|
|
|
|
|
|
ACPI_FUNCTION_TRACE(ns_parse_table);
|
|
ACPI_FUNCTION_TRACE(ns_parse_table);
|
|
|
|
|
|
- /*
|
|
|
|
- * AML Parse, pass 1
|
|
|
|
- *
|
|
|
|
- * In this pass, we load most of the namespace. Control methods
|
|
|
|
- * are not parsed until later. A parse tree is not created. Instead,
|
|
|
|
- * each Parser Op subtree is deleted when it is finished. This saves
|
|
|
|
- * a great deal of memory, and allows a small cache of parse objects
|
|
|
|
- * to service the entire parse. The second pass of the parse then
|
|
|
|
- * performs another complete parse of the AML.
|
|
|
|
- */
|
|
|
|
- ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
|
|
|
|
-
|
|
|
|
- status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
|
|
|
|
- table_index, start_node);
|
|
|
|
- if (ACPI_FAILURE(status)) {
|
|
|
|
- return_ACPI_STATUS(status);
|
|
|
|
- }
|
|
|
|
|
|
+ if (acpi_gbl_parse_table_as_term_list) {
|
|
|
|
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start load pass\n"));
|
|
|
|
|
|
- /*
|
|
|
|
- * AML Parse, pass 2
|
|
|
|
- *
|
|
|
|
- * In this pass, we resolve forward references and other things
|
|
|
|
- * that could not be completed during the first pass.
|
|
|
|
- * Another complete parse of the AML is performed, but the
|
|
|
|
- * overhead of this is compensated for by the fact that the
|
|
|
|
- * parse objects are all cached.
|
|
|
|
- */
|
|
|
|
- ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
|
|
|
|
- status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
|
|
|
|
- table_index, start_node);
|
|
|
|
- if (ACPI_FAILURE(status)) {
|
|
|
|
- return_ACPI_STATUS(status);
|
|
|
|
|
|
+ status = acpi_ns_execute_table(table_index, start_node);
|
|
|
|
+ if (ACPI_FAILURE(status)) {
|
|
|
|
+ return_ACPI_STATUS(status);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ /*
|
|
|
|
+ * AML Parse, pass 1
|
|
|
|
+ *
|
|
|
|
+ * In this pass, we load most of the namespace. Control methods
|
|
|
|
+ * are not parsed until later. A parse tree is not created.
|
|
|
|
+ * Instead, each Parser Op subtree is deleted when it is finished.
|
|
|
|
+ * This saves a great deal of memory, and allows a small cache of
|
|
|
|
+ * parse objects to service the entire parse. The second pass of
|
|
|
|
+ * the parse then performs another complete parse of the AML.
|
|
|
|
+ */
|
|
|
|
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
|
|
|
|
+
|
|
|
|
+ status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
|
|
|
|
+ table_index, start_node);
|
|
|
|
+ if (ACPI_FAILURE(status)) {
|
|
|
|
+ return_ACPI_STATUS(status);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * AML Parse, pass 2
|
|
|
|
+ *
|
|
|
|
+ * In this pass, we resolve forward references and other things
|
|
|
|
+ * that could not be completed during the first pass.
|
|
|
|
+ * Another complete parse of the AML is performed, but the
|
|
|
|
+ * overhead of this is compensated for by the fact that the
|
|
|
|
+ * parse objects are all cached.
|
|
|
|
+ */
|
|
|
|
+ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
|
|
|
|
+ status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
|
|
|
|
+ table_index, start_node);
|
|
|
|
+ if (ACPI_FAILURE(status)) {
|
|
|
|
+ return_ACPI_STATUS(status);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
return_ACPI_STATUS(status);
|
|
return_ACPI_STATUS(status);
|