From aa342261bde5ff177935c3a4f17f0bf2bf81babf Mon Sep 17 00:00:00 2001 From: Erik Schmauss Date: Fri, 15 Feb 2019 13:36:06 -0800 Subject: ACPICA: Remove legacy module-level code support ACPICA commit 47f5607c204719d9239a12b889df725225098c8f Module-level code refers to executable ASL code that runs during table load. This is typically used in ASL to declare named objects based on a condition evaluated during table load like so: definition_block(...) { opreation_region (OPR1, system_memory, ...) Field (OPR1) { FLD1, 8 /* Assume that FLD1's value is 0x1 */ } /* The if statement below is referred to as module-level code */ If (FLD1) { /* Declare DEV1 conditionally */ Device (DEV1) {...} } Device (DEV2) { ... } } In legacy module-level code, the execution of the If statement was deferred after other modules were loaded. The order of code execution for the table above is the following: 1.) Load OPR1 to the ACPI Namespace 2.) Load FLD1 to the ACPI Namespace (not intended for drivers) 3.) Load DEV2 to the ACPI Namespace 4.) Execute If (FLD1) and load DEV1 if the condition is true This legacy approach can be problematic for tables that look like the following: definition_block(...) { opreation_region (OPR1, system_memory, ...) Field (OPR1) { FLD1, 8 /* Assume that FLD1's value is 0x1 */ } /* The if statement below is referred to as module-level code */ If (FLD1) { /* Declare DEV1 conditionally */ Device (DEV1) {...} } Scope (DEV1) { /* Add objects DEV1's scope */ Name (OBJ1, 0x1234) } } When loading this in the legacy approach, Scope DEV1 gets evaluated before the If statement. The following is the order of execution: 1.) Load OPR1 to the ACPI Namespace 2.) Load FLD1 to the ACPI Namespace (not intended for drivers) 3.) Add OBJ1 under DEV1's scope -- ERROR. DEV1 does not exist 4.) Execute If (FLD1) and load DEV1 if the condition is true The legacy approach can never succeed for tables like this due to the deferral of the module-level code. Due to this limitation, a new module-level code was developed. This new approach exeutes if statements in the order that they appear in the definition block. With this approach, the order of execution for the above defintion block is as follows: 1.) Load OPR1 to the ACPI Namespace 2.) Load FLD1 to the ACPI Namespace (not intended for drivers) 3.) Execute If (FLD1) and load DEV1 because the condition is true 4.) Add OBJ1 under DEV1's scope. Since DEV1 is loaded in the namespace in step 3, step 4 executes successfully. This change removes support for the legacy module-level code execution. From this point onward, the new module-level code execution will be the official approach. Link: https://github.com/acpica/acpica/commit/47f5607c Signed-off-by: Erik Schmauss Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/nsparse.c | 66 ++++++++----------------------------------- 1 file changed, 12 insertions(+), 54 deletions(-) (limited to 'drivers/acpi/acpica/nsparse.c') diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index bfa408f7fd39..c0b4f7bedfab 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c @@ -253,61 +253,19 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node) ACPI_FUNCTION_TRACE(ns_parse_table); - if (acpi_gbl_execute_tables_as_methods) { - /* - * This case executes the AML table as one large control method. - * The point of this is to execute any module-level code in-place - * as the table is parsed. Some AML code depends on this behavior. - * - * It is a run-time option at this time, but will eventually become - * the default. - * - * Note: This causes the table to only have a single-pass parse. - * However, this is compatible with other ACPI implementations. - */ - ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE, - "%s: **** Start table execution pass\n", - ACPI_GET_FUNCTION_NAME)); - - 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); - } + /* + * Executes the AML table as one large control method. + * The point of this is to execute any module-level code in-place + * as the table is parsed. Some AML code depends on this behavior. + * + * Note: This causes the table to only have a single-pass parse. + * However, this is compatible with other ACPI implementations. + */ + ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE, + "%s: **** Start table execution pass\n", + ACPI_GET_FUNCTION_NAME)); - /* - * 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); return_ACPI_STATUS(status); } -- cgit v1.2.3