Skip to content

Commit aa34226

Browse files
Erik Schmaussrafaeljw
authored andcommitted
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: acpica/acpica@47f5607c Signed-off-by: Erik Schmauss <erik.schmauss@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent f2fee24 commit aa34226

File tree

5 files changed

+22
-289
lines changed

5 files changed

+22
-289
lines changed

drivers/acpi/acpica/evrgnini.c

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -516,25 +516,6 @@ acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj)
516516
handler_obj = obj_desc->common_notify.handler;
517517
break;
518518

519-
case ACPI_TYPE_METHOD:
520-
/*
521-
* If we are executing module level code, the original
522-
* Node's object was replaced by this Method object and we
523-
* saved the handler in the method object.
524-
*
525-
* Note: Only used for the legacy MLC support. Will
526-
* be removed in the future.
527-
*
528-
* See acpi_ns_exec_module_code
529-
*/
530-
if (!acpi_gbl_execute_tables_as_methods &&
531-
obj_desc->method.
532-
info_flags & ACPI_METHOD_MODULE_LEVEL) {
533-
handler_obj =
534-
obj_desc->method.dispatch.handler;
535-
}
536-
break;
537-
538519
default:
539520

540521
/* Ignore other objects */

drivers/acpi/acpica/nsparse.c

Lines changed: 12 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -253,61 +253,19 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
253253

254254
ACPI_FUNCTION_TRACE(ns_parse_table);
255255

256-
if (acpi_gbl_execute_tables_as_methods) {
257-
/*
258-
* This case executes the AML table as one large control method.
259-
* The point of this is to execute any module-level code in-place
260-
* as the table is parsed. Some AML code depends on this behavior.
261-
*
262-
* It is a run-time option at this time, but will eventually become
263-
* the default.
264-
*
265-
* Note: This causes the table to only have a single-pass parse.
266-
* However, this is compatible with other ACPI implementations.
267-
*/
268-
ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE,
269-
"%s: **** Start table execution pass\n",
270-
ACPI_GET_FUNCTION_NAME));
271-
272-
status = acpi_ns_execute_table(table_index, start_node);
273-
if (ACPI_FAILURE(status)) {
274-
return_ACPI_STATUS(status);
275-
}
276-
} else {
277-
/*
278-
* AML Parse, pass 1
279-
*
280-
* In this pass, we load most of the namespace. Control methods
281-
* are not parsed until later. A parse tree is not created.
282-
* Instead, each Parser Op subtree is deleted when it is finished.
283-
* This saves a great deal of memory, and allows a small cache of
284-
* parse objects to service the entire parse. The second pass of
285-
* the parse then performs another complete parse of the AML.
286-
*/
287-
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
288-
289-
status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
290-
table_index, start_node);
291-
if (ACPI_FAILURE(status)) {
292-
return_ACPI_STATUS(status);
293-
}
256+
/*
257+
* Executes the AML table as one large control method.
258+
* The point of this is to execute any module-level code in-place
259+
* as the table is parsed. Some AML code depends on this behavior.
260+
*
261+
* Note: This causes the table to only have a single-pass parse.
262+
* However, this is compatible with other ACPI implementations.
263+
*/
264+
ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE,
265+
"%s: **** Start table execution pass\n",
266+
ACPI_GET_FUNCTION_NAME));
294267

295-
/*
296-
* AML Parse, pass 2
297-
*
298-
* In this pass, we resolve forward references and other things
299-
* that could not be completed during the first pass.
300-
* Another complete parse of the AML is performed, but the
301-
* overhead of this is compensated for by the fact that the
302-
* parse objects are all cached.
303-
*/
304-
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
305-
status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
306-
table_index, start_node);
307-
if (ACPI_FAILURE(status)) {
308-
return_ACPI_STATUS(status);
309-
}
310-
}
268+
status = acpi_ns_execute_table(table_index, start_node);
311269

312270
return_ACPI_STATUS(status);
313271
}

drivers/acpi/acpica/psloop.c

Lines changed: 0 additions & 193 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ static acpi_status
3232
acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
3333
u8 * aml_op_start, union acpi_parse_object *op);
3434

35-
static void
36-
acpi_ps_link_module_code(union acpi_parse_object *parent_op,
37-
u8 *aml_start, u32 aml_length, acpi_owner_id owner_id);
38-
3935
/*******************************************************************************
4036
*
4137
* FUNCTION: acpi_ps_get_arguments
@@ -56,7 +52,6 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
5652
{
5753
acpi_status status = AE_OK;
5854
union acpi_parse_object *arg = NULL;
59-
const struct acpi_opcode_info *op_info;
6055

6156
ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state);
6257

@@ -136,96 +131,6 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
136131
walk_state->arg_count,
137132
walk_state->pass_number));
138133

139-
/*
140-
* This case handles the legacy option that groups all module-level
141-
* code blocks together and defers execution until all of the tables
142-
* are loaded. Execute all of these blocks at this time.
143-
* Execute any module-level code that was detected during the table
144-
* load phase.
145-
*
146-
* Note: this option is deprecated and will be eliminated in the
147-
* future. Use of this option can cause problems with AML code that
148-
* depends upon in-order immediate execution of module-level code.
149-
*/
150-
if (!acpi_gbl_execute_tables_as_methods &&
151-
(walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2) &&
152-
((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) {
153-
/*
154-
* We want to skip If/Else/While constructs during Pass1 because we
155-
* want to actually conditionally execute the code during Pass2.
156-
*
157-
* Except for disassembly, where we always want to walk the
158-
* If/Else/While packages
159-
*/
160-
switch (op->common.aml_opcode) {
161-
case AML_IF_OP:
162-
case AML_ELSE_OP:
163-
case AML_WHILE_OP:
164-
/*
165-
* Currently supported module-level opcodes are:
166-
* IF/ELSE/WHILE. These appear to be the most common,
167-
* and easiest to support since they open an AML
168-
* package.
169-
*/
170-
if (walk_state->pass_number ==
171-
ACPI_IMODE_LOAD_PASS1) {
172-
acpi_ps_link_module_code(op->common.
173-
parent,
174-
aml_op_start,
175-
(u32)
176-
(walk_state->
177-
parser_state.
178-
pkg_end -
179-
aml_op_start),
180-
walk_state->
181-
owner_id);
182-
}
183-
184-
ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
185-
"Pass1: Skipping an If/Else/While body\n"));
186-
187-
/* Skip body of if/else/while in pass 1 */
188-
189-
walk_state->parser_state.aml =
190-
walk_state->parser_state.pkg_end;
191-
walk_state->arg_count = 0;
192-
break;
193-
194-
default:
195-
/*
196-
* Check for an unsupported executable opcode at module
197-
* level. We must be in PASS1, the parent must be a SCOPE,
198-
* The opcode class must be EXECUTE, and the opcode must
199-
* not be an argument to another opcode.
200-
*/
201-
if ((walk_state->pass_number ==
202-
ACPI_IMODE_LOAD_PASS1)
203-
&& (op->common.parent->common.aml_opcode ==
204-
AML_SCOPE_OP)) {
205-
op_info =
206-
acpi_ps_get_opcode_info(op->common.
207-
aml_opcode);
208-
if ((op_info->class ==
209-
AML_CLASS_EXECUTE) && (!arg)) {
210-
ACPI_WARNING((AE_INFO,
211-
"Unsupported module-level executable opcode "
212-
"0x%.2X at table offset 0x%.4X",
213-
op->common.
214-
aml_opcode,
215-
(u32)
216-
(ACPI_PTR_DIFF
217-
(aml_op_start,
218-
walk_state->
219-
parser_state.
220-
aml_start) +
221-
sizeof(struct
222-
acpi_table_header))));
223-
}
224-
}
225-
break;
226-
}
227-
}
228-
229134
/* Special processing for certain opcodes */
230135

231136
switch (op->common.aml_opcode) {
@@ -300,104 +205,6 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
300205
return_ACPI_STATUS(AE_OK);
301206
}
302207

303-
/*******************************************************************************
304-
*
305-
* FUNCTION: acpi_ps_link_module_code
306-
*
307-
* PARAMETERS: parent_op - Parent parser op
308-
* aml_start - Pointer to the AML
309-
* aml_length - Length of executable AML
310-
* owner_id - owner_id of module level code
311-
*
312-
* RETURN: None.
313-
*
314-
* DESCRIPTION: Wrap the module-level code with a method object and link the
315-
* object to the global list. Note, the mutex field of the method
316-
* object is used to link multiple module-level code objects.
317-
*
318-
* NOTE: In this legacy option, each block of detected executable AML
319-
* code that is outside of any control method is wrapped with a temporary
320-
* control method object and placed on a global list below.
321-
*
322-
* This function executes the module-level code for all tables only after
323-
* all of the tables have been loaded. It is a legacy option and is
324-
* not compatible with other ACPI implementations. See acpi_ns_load_table.
325-
*
326-
* This function will be removed when the legacy option is removed.
327-
*
328-
******************************************************************************/
329-
330-
static void
331-
acpi_ps_link_module_code(union acpi_parse_object *parent_op,
332-
u8 *aml_start, u32 aml_length, acpi_owner_id owner_id)
333-
{
334-
union acpi_operand_object *prev;
335-
union acpi_operand_object *next;
336-
union acpi_operand_object *method_obj;
337-
struct acpi_namespace_node *parent_node;
338-
339-
ACPI_FUNCTION_TRACE(ps_link_module_code);
340-
341-
/* Get the tail of the list */
342-
343-
prev = next = acpi_gbl_module_code_list;
344-
while (next) {
345-
prev = next;
346-
next = next->method.mutex;
347-
}
348-
349-
/*
350-
* Insert the module level code into the list. Merge it if it is
351-
* adjacent to the previous element.
352-
*/
353-
if (!prev ||
354-
((prev->method.aml_start + prev->method.aml_length) != aml_start)) {
355-
356-
/* Create, initialize, and link a new temporary method object */
357-
358-
method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
359-
if (!method_obj) {
360-
return_VOID;
361-
}
362-
363-
ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
364-
"Create/Link new code block: %p\n",
365-
method_obj));
366-
367-
if (parent_op->common.node) {
368-
parent_node = parent_op->common.node;
369-
} else {
370-
parent_node = acpi_gbl_root_node;
371-
}
372-
373-
method_obj->method.aml_start = aml_start;
374-
method_obj->method.aml_length = aml_length;
375-
method_obj->method.owner_id = owner_id;
376-
method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL;
377-
378-
/*
379-
* Save the parent node in next_object. This is cheating, but we
380-
* don't want to expand the method object.
381-
*/
382-
method_obj->method.next_object =
383-
ACPI_CAST_PTR(union acpi_operand_object, parent_node);
384-
385-
if (!prev) {
386-
acpi_gbl_module_code_list = method_obj;
387-
} else {
388-
prev->method.mutex = method_obj;
389-
}
390-
} else {
391-
ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
392-
"Appending to existing code block: %p\n",
393-
prev));
394-
395-
prev->method.aml_length += aml_length;
396-
}
397-
398-
return_VOID;
399-
}
400-
401208
/*******************************************************************************
402209
*
403210
* FUNCTION: acpi_ps_parse_loop

drivers/acpi/acpica/tbxfload.c

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -69,23 +69,18 @@ acpi_status ACPI_INIT_FUNCTION acpi_load_tables(void)
6969
"While loading namespace from ACPI tables"));
7070
}
7171

72-
if (acpi_gbl_execute_tables_as_methods) {
73-
/*
74-
* If the module-level code support is enabled, initialize the objects
75-
* in the namespace that remain uninitialized. This runs the executable
76-
* AML that may be part of the declaration of these name objects:
77-
* operation_regions, buffer_fields, Buffers, and Packages.
78-
*
79-
* Note: The module-level code is optional at this time, but will
80-
* become the default in the future.
81-
*/
82-
status = acpi_ns_initialize_objects();
83-
if (ACPI_FAILURE(status)) {
84-
return_ACPI_STATUS(status);
85-
}
72+
/*
73+
* Initialize the objects in the namespace that remain uninitialized.
74+
* This runs the executable AML that may be part of the declaration of
75+
* these name objects:
76+
* operation_regions, buffer_fields, Buffers, and Packages.
77+
*
78+
*/
79+
status = acpi_ns_initialize_objects();
80+
if (ACPI_SUCCESS(status)) {
81+
acpi_gbl_namespace_initialized = TRUE;
8682
}
8783

88-
acpi_gbl_namespace_initialized = TRUE;
8984
return_ACPI_STATUS(status);
9085
}
9186

include/acpi/acpixf.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,6 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_copy_dsdt_locally, FALSE);
156156
*/
157157
ACPI_INIT_GLOBAL(u8, acpi_gbl_do_not_use_xsdt, FALSE);
158158

159-
/*
160-
* Optionally support module level code by parsing an entire table as
161-
* a method as it is loaded. Default is TRUE.
162-
* NOTE, this is essentially obsolete and will be removed soon
163-
* (01/2018).
164-
*/
165-
ACPI_INIT_GLOBAL(u8, acpi_gbl_execute_tables_as_methods, TRUE);
166-
167159
/*
168160
* Optionally use 32-bit FADT addresses if and when there is a conflict
169161
* (address mismatch) between the 32-bit and 64-bit versions of the

0 commit comments

Comments
 (0)