aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2008-04-10 11:06:37 -0400
committerLen Brown <len.brown@intel.com>2008-04-22 14:29:21 -0400
commit4e3156b183aa087bc19804b3295c7c1a71f64752 (patch)
tree5db51b2351f4d919b36364681e594d2b6daa3860 /drivers/acpi
parentba886cd4ac957608777fbc8d137f6b9f0450e775 (diff)
ACPICA: changed order of interpretation of operand objects
The interpreter now evaluates operands in the order that they appear (both in the AML and ASL), instead of in reverse order. This previously caused subtle incompatibilities with the MS interpreter as well as being non-intuitive. Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/dispatcher/dsutils.c113
-rw-r--r--drivers/acpi/dispatcher/dswexec.c11
-rw-r--r--drivers/acpi/executer/exutils.c3
-rw-r--r--drivers/acpi/parser/psloop.c23
-rw-r--r--drivers/acpi/parser/psopcode.c26
-rw-r--r--drivers/acpi/parser/pstree.c2
6 files changed, 170 insertions, 8 deletions
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
index d2a8cfdaec22..36518b4a79c2 100644
--- a/drivers/acpi/dispatcher/dsutils.c
+++ b/drivers/acpi/dispatcher/dsutils.c
@@ -472,7 +472,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
472 /* A valid name must be looked up in the namespace */ 472 /* A valid name must be looked up in the namespace */
473 473
474 if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && 474 if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
475 (arg->common.value.string)) { 475 (arg->common.value.string) &&
476 !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
476 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", 477 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n",
477 arg)); 478 arg));
478 479
@@ -595,7 +596,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
595 } else { 596 } else {
596 /* Check for null name case */ 597 /* Check for null name case */
597 598
598 if (arg->common.aml_opcode == AML_INT_NAMEPATH_OP) { 599 if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
600 !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
599 /* 601 /*
600 * If the name is null, this means that this is an 602 * If the name is null, this means that this is an
601 * optional result parameter that was not specified 603 * optional result parameter that was not specified
@@ -617,7 +619,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
617 return_ACPI_STATUS(AE_NOT_IMPLEMENTED); 619 return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
618 } 620 }
619 621
620 if (op_info->flags & AML_HAS_RETVAL) { 622 if ((op_info->flags & AML_HAS_RETVAL)
623 || (arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
621 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 624 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
622 "Argument previously created, already stacked\n")); 625 "Argument previously created, already stacked\n"));
623 626
@@ -759,3 +762,107 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
759 ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index)); 762 ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index));
760 return_ACPI_STATUS(status); 763 return_ACPI_STATUS(status);
761} 764}
765
766/*****************************************************************************
767 *
768 * FUNCTION: acpi_ds_evaluate_name_path
769 *
770 * PARAMETERS: walk_state - Current state of the parse tree walk,
771 * the opcode of current operation should be
772 * AML_INT_NAMEPATH_OP
773 *
774 * RETURN: Status
775 *
776 * DESCRIPTION: Translate the -name_path- parse tree object to the equivalent
777 * interpreter object, convert it to value, if needed, duplicate
778 * it, if needed, and push it onto the current result stack.
779 *
780 ****************************************************************************/
781
782acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state)
783{
784 acpi_status status = AE_OK;
785 union acpi_parse_object *op = walk_state->op;
786 union acpi_operand_object **operand = &walk_state->operands[0];
787 union acpi_operand_object *new_obj_desc;
788 u8 type;
789
790 ACPI_FUNCTION_TRACE_PTR(ds_evaluate_name_path, walk_state);
791
792 if (!op->common.parent) {
793
794 /* This happens after certain exception processing */
795
796 goto exit;
797 }
798
799 if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
800 (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) ||
801 (op->common.parent->common.aml_opcode == AML_REF_OF_OP)) {
802
803 /* TBD: Should we specify this feature as a bit of op_info->Flags of these opcodes? */
804
805 goto exit;
806 }
807
808 status = acpi_ds_create_operand(walk_state, op, 0);
809 if (ACPI_FAILURE(status)) {
810 goto exit;
811 }
812
813 if (op->common.flags & ACPI_PARSEOP_TARGET) {
814 new_obj_desc = *operand;
815 goto push_result;
816 }
817
818 type = ACPI_GET_OBJECT_TYPE(*operand);
819
820 status = acpi_ex_resolve_to_value(operand, walk_state);
821 if (ACPI_FAILURE(status)) {
822 goto exit;
823 }
824
825 if (type == ACPI_TYPE_INTEGER) {
826
827 /* It was incremented by acpi_ex_resolve_to_value */
828
829 acpi_ut_remove_reference(*operand);
830
831 status =
832 acpi_ut_copy_iobject_to_iobject(*operand, &new_obj_desc,
833 walk_state);
834 if (ACPI_FAILURE(status)) {
835 goto exit;
836 }
837 } else {
838 /*
839 * The object either was anew created or is
840 * a Namespace node - don't decrement it.
841 */
842 new_obj_desc = *operand;
843 }
844
845 /* Cleanup for name-path operand */
846
847 status = acpi_ds_obj_stack_pop(1, walk_state);
848 if (ACPI_FAILURE(status)) {
849 walk_state->result_obj = new_obj_desc;
850 goto exit;
851 }
852
853 push_result:
854
855 walk_state->result_obj = new_obj_desc;
856
857 status = acpi_ds_result_push(walk_state->result_obj, walk_state);
858 if (ACPI_SUCCESS(status)) {
859
860 /* Force to take it from stack */
861
862 op->common.flags |= ACPI_PARSEOP_IN_STACK;
863 }
864
865 exit:
866
867 return_ACPI_STATUS(status);
868}
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index 12b148587e3d..514b9d2eb3a7 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -375,10 +375,17 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
375 /* Decode the Opcode Class */ 375 /* Decode the Opcode Class */
376 376
377 switch (op_class) { 377 switch (op_class) {
378 case AML_CLASS_ARGUMENT: /* constants, literals, etc. - do nothing */ 378 case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */
379
380 if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
381 status = acpi_ds_evaluate_name_path(walk_state);
382 if (ACPI_FAILURE(status)) {
383 goto cleanup;
384 }
385 }
379 break; 386 break;
380 387
381 case AML_CLASS_EXECUTE: /* most operators with arguments */ 388 case AML_CLASS_EXECUTE: /* Most operators with arguments */
382 389
383 /* Build resolved operand stack */ 390 /* Build resolved operand stack */
384 391
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
index c0837af0acb1..c40b191f70b5 100644
--- a/drivers/acpi/executer/exutils.c
+++ b/drivers/acpi/executer/exutils.c
@@ -217,9 +217,10 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc)
217 217
218 /* 218 /*
219 * Object must be a valid number and we must be executing 219 * Object must be a valid number and we must be executing
220 * a control method 220 * a control method. NS node could be there for AML_INT_NAMEPATH_OP.
221 */ 221 */
222 if ((!obj_desc) || 222 if ((!obj_desc) ||
223 (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) ||
223 (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) { 224 (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
224 return; 225 return;
225 } 226 }
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c
index 266dd0c10218..4348b0530398 100644
--- a/drivers/acpi/parser/psloop.c
+++ b/drivers/acpi/parser/psloop.c
@@ -182,6 +182,7 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
182 ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state); 182 ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
183 183
184 unnamed_op->common.value.arg = NULL; 184 unnamed_op->common.value.arg = NULL;
185 unnamed_op->common.arg_list_length = 0;
185 unnamed_op->common.aml_opcode = walk_state->opcode; 186 unnamed_op->common.aml_opcode = walk_state->opcode;
186 187
187 /* 188 /*
@@ -280,6 +281,9 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state,
280 acpi_status status = AE_OK; 281 acpi_status status = AE_OK;
281 union acpi_parse_object *op; 282 union acpi_parse_object *op;
282 union acpi_parse_object *named_op = NULL; 283 union acpi_parse_object *named_op = NULL;
284 union acpi_parse_object *parent_scope;
285 u8 argument_count;
286 const struct acpi_opcode_info *op_info;
283 287
284 ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state); 288 ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
285 289
@@ -320,8 +324,23 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state,
320 op->named.length = 0; 324 op->named.length = 0;
321 } 325 }
322 326
323 acpi_ps_append_arg(acpi_ps_get_parent_scope 327 parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
324 (&(walk_state->parser_state)), op); 328 acpi_ps_append_arg(parent_scope, op);
329
330 if (parent_scope) {
331 op_info =
332 acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
333 if (op_info->flags & AML_HAS_TARGET) {
334 argument_count =
335 acpi_ps_get_argument_count(op_info->type);
336 if (parent_scope->common.arg_list_length >
337 argument_count) {
338 op->common.flags |= ACPI_PARSEOP_TARGET;
339 }
340 } else if (parent_scope->common.aml_opcode == AML_INCREMENT_OP) {
341 op->common.flags |= ACPI_PARSEOP_TARGET;
342 }
343 }
325 344
326 if (walk_state->descending_callback != NULL) { 345 if (walk_state->descending_callback != NULL) {
327 /* 346 /*
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
index 9296e86761d7..3bf8105d6348 100644
--- a/drivers/acpi/parser/psopcode.c
+++ b/drivers/acpi/parser/psopcode.c
@@ -49,6 +49,8 @@
49#define _COMPONENT ACPI_PARSER 49#define _COMPONENT ACPI_PARSER
50ACPI_MODULE_NAME("psopcode") 50ACPI_MODULE_NAME("psopcode")
51 51
52const u8 acpi_gbl_argument_count[] = { 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 6 };
53
52/******************************************************************************* 54/*******************************************************************************
53 * 55 *
54 * NAME: acpi_gbl_aml_op_info 56 * NAME: acpi_gbl_aml_op_info
@@ -59,6 +61,7 @@ ACPI_MODULE_NAME("psopcode")
59 * the operand type. 61 * the operand type.
60 * 62 *
61 ******************************************************************************/ 63 ******************************************************************************/
64
62/* 65/*
63 * Summary of opcode types/flags 66 * Summary of opcode types/flags
64 * 67 *
@@ -176,6 +179,7 @@ ACPI_MODULE_NAME("psopcode")
176 AML_CREATE_QWORD_FIELD_OP 179 AML_CREATE_QWORD_FIELD_OP
177 180
178 ******************************************************************************/ 181 ******************************************************************************/
182
179/* 183/*
180 * Master Opcode information table. A summary of everything we know about each 184 * Master Opcode information table. A summary of everything we know about each
181 * opcode, all in one place. 185 * opcode, all in one place.
@@ -779,3 +783,25 @@ char *acpi_ps_get_opcode_name(u16 opcode)
779 783
780#endif 784#endif
781} 785}
786
787/*******************************************************************************
788 *
789 * FUNCTION: acpi_ps_get_argument_count
790 *
791 * PARAMETERS: op_type - Type associated with the AML opcode
792 *
793 * RETURN: Argument count
794 *
795 * DESCRIPTION: Obtain the number of expected arguments for an AML opcode
796 *
797 ******************************************************************************/
798
799u8 acpi_ps_get_argument_count(u32 op_type)
800{
801
802 if (op_type <= AML_TYPE_EXEC_6A_0T_1R) {
803 return (acpi_gbl_argument_count[op_type]);
804 }
805
806 return (0);
807}
diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c
index 966e7ea2a0c4..0e1a3226665d 100644
--- a/drivers/acpi/parser/pstree.c
+++ b/drivers/acpi/parser/pstree.c
@@ -171,6 +171,8 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
171 while (arg) { 171 while (arg) {
172 arg->common.parent = op; 172 arg->common.parent = op;
173 arg = arg->common.next; 173 arg = arg->common.next;
174
175 op->common.arg_list_length++;
174 } 176 }
175} 177}
176 178