diff options
author | Robert Moore <robert.moore@intel.com> | 2005-05-26 00:00:00 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2005-07-13 16:46:34 -0400 |
commit | 88ac00f5a841dcfc5c682000f4a6add0add8caac (patch) | |
tree | 80dcff8323c6c79e8706f42eb4b7c3884bc03152 /drivers/acpi/dispatcher | |
parent | 6f42ccf2fc50ecee8ea170040627f268430c1648 (diff) |
ACPICA 20050526 from Bob Moore <robert.moore@intel.com>
Implemented support to execute Type 1 and Type 2 AML
opcodes appearing at the module level (not within a control
method.) These opcodes are executed exactly once at the
time the table is loaded. This type of code was legal up
until the release of ACPI 2.0B (2002) and is now supported
within ACPI CA in order to provide backwards compatibility
with earlier BIOS implementations. This eliminates the
"Encountered executable code at module level" warning that
was previously generated upon detection of such code.
Fixed a problem in the interpreter where an AE_NOT_FOUND
exception could inadvertently be generated during the
lookup of namespace objects in the second pass parse of
ACPI tables and control methods. It appears that this
problem could occur during the resolution of forward
references to namespace objects.
Added the ACPI_MUTEX_DEBUG #ifdef to the
acpi_ut_release_mutex function, corresponding to the same
the deadlock detection debug code to be compiled out in
the normal case, improving mutex performance (and overall
subsystem performance) considerably. As suggested by
Alexey Starikovskiy.
Implemented a handful of miscellaneous fixes for possible
memory leaks on error conditions and error handling
control paths. These fixes were suggested by FreeBSD and
the Coverity Prevent source code analysis tool.
Added a check for a null RSDT pointer in
acpi_get_firmware_table (tbxfroot.c) to prevent a fault
in this error case.
Signed-off-by Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/dispatcher')
-rw-r--r-- | drivers/acpi/dispatcher/dsmethod.c | 8 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dsopcode.c | 15 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dswload.c | 56 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dswstate.c | 1 |
4 files changed, 52 insertions, 28 deletions
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 9fc3f4c033eb..c9d9a6c45ae3 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c | |||
@@ -139,7 +139,8 @@ acpi_ds_parse_method ( | |||
139 | 139 | ||
140 | walk_state = acpi_ds_create_walk_state (owner_id, NULL, NULL, NULL); | 140 | walk_state = acpi_ds_create_walk_state (owner_id, NULL, NULL, NULL); |
141 | if (!walk_state) { | 141 | if (!walk_state) { |
142 | return_ACPI_STATUS (AE_NO_MEMORY); | 142 | status = AE_NO_MEMORY; |
143 | goto cleanup; | ||
143 | } | 144 | } |
144 | 145 | ||
145 | status = acpi_ds_init_aml_walk (walk_state, op, node, | 146 | status = acpi_ds_init_aml_walk (walk_state, op, node, |
@@ -147,7 +148,7 @@ acpi_ds_parse_method ( | |||
147 | obj_desc->method.aml_length, NULL, 1); | 148 | obj_desc->method.aml_length, NULL, 1); |
148 | if (ACPI_FAILURE (status)) { | 149 | if (ACPI_FAILURE (status)) { |
149 | acpi_ds_delete_walk_state (walk_state); | 150 | acpi_ds_delete_walk_state (walk_state); |
150 | return_ACPI_STATUS (status); | 151 | goto cleanup; |
151 | } | 152 | } |
152 | 153 | ||
153 | /* | 154 | /* |
@@ -161,13 +162,14 @@ acpi_ds_parse_method ( | |||
161 | */ | 162 | */ |
162 | status = acpi_ps_parse_aml (walk_state); | 163 | status = acpi_ps_parse_aml (walk_state); |
163 | if (ACPI_FAILURE (status)) { | 164 | if (ACPI_FAILURE (status)) { |
164 | return_ACPI_STATUS (status); | 165 | goto cleanup; |
165 | } | 166 | } |
166 | 167 | ||
167 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, | 168 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, |
168 | "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n", | 169 | "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n", |
169 | acpi_ut_get_node_name (obj_handle), obj_handle, op)); | 170 | acpi_ut_get_node_name (obj_handle), obj_handle, op)); |
170 | 171 | ||
172 | cleanup: | ||
171 | acpi_ps_delete_parse_tree (op); | 173 | acpi_ps_delete_parse_tree (op); |
172 | return_ACPI_STATUS (status); | 174 | return_ACPI_STATUS (status); |
173 | } | 175 | } |
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index ba13bca28bee..750bdb1ac344 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c | |||
@@ -119,14 +119,15 @@ acpi_ds_execute_arguments ( | |||
119 | 119 | ||
120 | walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); | 120 | walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); |
121 | if (!walk_state) { | 121 | if (!walk_state) { |
122 | return_ACPI_STATUS (AE_NO_MEMORY); | 122 | status = AE_NO_MEMORY; |
123 | goto cleanup; | ||
123 | } | 124 | } |
124 | 125 | ||
125 | status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start, | 126 | status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start, |
126 | aml_length, NULL, 1); | 127 | aml_length, NULL, 1); |
127 | if (ACPI_FAILURE (status)) { | 128 | if (ACPI_FAILURE (status)) { |
128 | acpi_ds_delete_walk_state (walk_state); | 129 | acpi_ds_delete_walk_state (walk_state); |
129 | return_ACPI_STATUS (status); | 130 | goto cleanup; |
130 | } | 131 | } |
131 | 132 | ||
132 | /* Mark this parse as a deferred opcode */ | 133 | /* Mark this parse as a deferred opcode */ |
@@ -138,8 +139,7 @@ acpi_ds_execute_arguments ( | |||
138 | 139 | ||
139 | status = acpi_ps_parse_aml (walk_state); | 140 | status = acpi_ps_parse_aml (walk_state); |
140 | if (ACPI_FAILURE (status)) { | 141 | if (ACPI_FAILURE (status)) { |
141 | acpi_ps_delete_parse_tree (op); | 142 | goto cleanup; |
142 | return_ACPI_STATUS (status); | ||
143 | } | 143 | } |
144 | 144 | ||
145 | /* Get and init the Op created above */ | 145 | /* Get and init the Op created above */ |
@@ -160,7 +160,8 @@ acpi_ds_execute_arguments ( | |||
160 | 160 | ||
161 | walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); | 161 | walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); |
162 | if (!walk_state) { | 162 | if (!walk_state) { |
163 | return_ACPI_STATUS (AE_NO_MEMORY); | 163 | status = AE_NO_MEMORY; |
164 | goto cleanup; | ||
164 | } | 165 | } |
165 | 166 | ||
166 | /* Execute the opcode and arguments */ | 167 | /* Execute the opcode and arguments */ |
@@ -169,13 +170,15 @@ acpi_ds_execute_arguments ( | |||
169 | aml_length, NULL, 3); | 170 | aml_length, NULL, 3); |
170 | if (ACPI_FAILURE (status)) { | 171 | if (ACPI_FAILURE (status)) { |
171 | acpi_ds_delete_walk_state (walk_state); | 172 | acpi_ds_delete_walk_state (walk_state); |
172 | return_ACPI_STATUS (status); | 173 | goto cleanup; |
173 | } | 174 | } |
174 | 175 | ||
175 | /* Mark this execution as a deferred opcode */ | 176 | /* Mark this execution as a deferred opcode */ |
176 | 177 | ||
177 | walk_state->deferred_node = node; | 178 | walk_state->deferred_node = node; |
178 | status = acpi_ps_parse_aml (walk_state); | 179 | status = acpi_ps_parse_aml (walk_state); |
180 | |||
181 | cleanup: | ||
179 | acpi_ps_delete_parse_tree (op); | 182 | acpi_ps_delete_parse_tree (op); |
180 | return_ACPI_STATUS (status); | 183 | return_ACPI_STATUS (status); |
181 | } | 184 | } |
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index 1ac197ccfc80..e2e0a855be2c 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c | |||
@@ -145,15 +145,6 @@ acpi_ds_load1_begin_op ( | |||
145 | 145 | ||
146 | if (op) { | 146 | if (op) { |
147 | if (!(walk_state->op_info->flags & AML_NAMED)) { | 147 | if (!(walk_state->op_info->flags & AML_NAMED)) { |
148 | #if 0 | ||
149 | if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || | ||
150 | (walk_state->op_info->class == AML_CLASS_CONTROL)) { | ||
151 | acpi_os_printf ("\n\n***EXECUTABLE OPCODE %s***\n\n", | ||
152 | walk_state->op_info->name); | ||
153 | *out_op = op; | ||
154 | return (AE_CTRL_SKIP); | ||
155 | } | ||
156 | #endif | ||
157 | *out_op = op; | 148 | *out_op = op; |
158 | return (AE_OK); | 149 | return (AE_OK); |
159 | } | 150 | } |
@@ -486,6 +477,15 @@ acpi_ds_load2_begin_op ( | |||
486 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); | 477 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); |
487 | 478 | ||
488 | if (op) { | 479 | if (op) { |
480 | if ((walk_state->control_state) && | ||
481 | (walk_state->control_state->common.state == | ||
482 | ACPI_CONTROL_CONDITIONAL_EXECUTING)) { | ||
483 | /* We are executing a while loop outside of a method */ | ||
484 | |||
485 | status = acpi_ds_exec_begin_op (walk_state, out_op); | ||
486 | return_ACPI_STATUS (status); | ||
487 | } | ||
488 | |||
489 | /* We only care about Namespace opcodes here */ | 489 | /* We only care about Namespace opcodes here */ |
490 | 490 | ||
491 | if ((!(walk_state->op_info->flags & AML_NSOPCODE) && | 491 | if ((!(walk_state->op_info->flags & AML_NSOPCODE) && |
@@ -493,9 +493,14 @@ acpi_ds_load2_begin_op ( | |||
493 | (!(walk_state->op_info->flags & AML_NAMED))) { | 493 | (!(walk_state->op_info->flags & AML_NAMED))) { |
494 | if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || | 494 | if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || |
495 | (walk_state->op_info->class == AML_CLASS_CONTROL)) { | 495 | (walk_state->op_info->class == AML_CLASS_CONTROL)) { |
496 | ACPI_REPORT_WARNING (( | 496 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, |
497 | "Encountered executable code at module level, [%s]\n", | 497 | "Begin/EXEC: %s (fl %8.8X)\n", walk_state->op_info->name, |
498 | acpi_ps_get_opcode_name (walk_state->opcode))); | 498 | walk_state->op_info->flags)); |
499 | |||
500 | /* Executing a type1 or type2 opcode outside of a method */ | ||
501 | |||
502 | status = acpi_ds_exec_begin_op (walk_state, out_op); | ||
503 | return_ACPI_STATUS (status); | ||
499 | } | 504 | } |
500 | return_ACPI_STATUS (AE_OK); | 505 | return_ACPI_STATUS (AE_OK); |
501 | } | 506 | } |
@@ -657,8 +662,10 @@ acpi_ds_load2_begin_op ( | |||
657 | break; | 662 | break; |
658 | } | 663 | } |
659 | 664 | ||
665 | /* Add new entry into namespace */ | ||
666 | |||
660 | status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type, | 667 | status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type, |
661 | ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, | 668 | ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, |
662 | walk_state, &(node)); | 669 | walk_state, &(node)); |
663 | break; | 670 | break; |
664 | } | 671 | } |
@@ -668,7 +675,6 @@ acpi_ds_load2_begin_op ( | |||
668 | return_ACPI_STATUS (status); | 675 | return_ACPI_STATUS (status); |
669 | } | 676 | } |
670 | 677 | ||
671 | |||
672 | if (!op) { | 678 | if (!op) { |
673 | /* Create a new op */ | 679 | /* Create a new op */ |
674 | 680 | ||
@@ -682,9 +688,7 @@ acpi_ds_load2_begin_op ( | |||
682 | if (node) { | 688 | if (node) { |
683 | op->named.name = node->name.integer; | 689 | op->named.name = node->name.integer; |
684 | } | 690 | } |
685 | if (out_op) { | 691 | *out_op = op; |
686 | *out_op = op; | ||
687 | } | ||
688 | } | 692 | } |
689 | 693 | ||
690 | /* | 694 | /* |
@@ -731,9 +735,24 @@ acpi_ds_load2_end_op ( | |||
731 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n", | 735 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n", |
732 | walk_state->op_info->name, op, walk_state)); | 736 | walk_state->op_info->name, op, walk_state)); |
733 | 737 | ||
734 | /* Only interested in opcodes that have namespace objects */ | 738 | /* Check if opcode had an associated namespace object */ |
735 | 739 | ||
736 | if (!(walk_state->op_info->flags & AML_NSOBJECT)) { | 740 | if (!(walk_state->op_info->flags & AML_NSOBJECT)) { |
741 | #ifndef ACPI_NO_METHOD_EXECUTION | ||
742 | /* No namespace object. Executable opcode? */ | ||
743 | |||
744 | if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || | ||
745 | (walk_state->op_info->class == AML_CLASS_CONTROL)) { | ||
746 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, | ||
747 | "End/EXEC: %s (fl %8.8X)\n", walk_state->op_info->name, | ||
748 | walk_state->op_info->flags)); | ||
749 | |||
750 | /* Executing a type1 or type2 opcode outside of a method */ | ||
751 | |||
752 | status = acpi_ds_exec_end_op (walk_state); | ||
753 | return_ACPI_STATUS (status); | ||
754 | } | ||
755 | #endif | ||
737 | return_ACPI_STATUS (AE_OK); | 756 | return_ACPI_STATUS (AE_OK); |
738 | } | 757 | } |
739 | 758 | ||
@@ -742,7 +761,6 @@ acpi_ds_load2_end_op ( | |||
742 | "Ending scope Op=%p State=%p\n", op, walk_state)); | 761 | "Ending scope Op=%p State=%p\n", op, walk_state)); |
743 | } | 762 | } |
744 | 763 | ||
745 | |||
746 | object_type = walk_state->op_info->object_type; | 764 | object_type = walk_state->op_info->object_type; |
747 | 765 | ||
748 | /* | 766 | /* |
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c index 4ef0e85c677b..cc45d52225d6 100644 --- a/drivers/acpi/dispatcher/dswstate.c +++ b/drivers/acpi/dispatcher/dswstate.c | |||
@@ -762,6 +762,7 @@ acpi_ds_init_aml_walk ( | |||
762 | /* The next_op of the next_walk will be the beginning of the method */ | 762 | /* The next_op of the next_walk will be the beginning of the method */ |
763 | 763 | ||
764 | walk_state->next_op = NULL; | 764 | walk_state->next_op = NULL; |
765 | walk_state->pass_number = (u8) pass_number; | ||
765 | 766 | ||
766 | if (info) { | 767 | if (info) { |
767 | if (info->parameter_type == ACPI_PARAM_GPE) { | 768 | if (info->parameter_type == ACPI_PARAM_GPE) { |