From 773069d48030e670cf2032a13ddf16a2e0034df3 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 10 Apr 2008 19:06:36 +0400 Subject: ACPICA: Several fixes for internal method result stack fixes STACK_OVERFLOW exception on nested method calls. internal bugzilla 262 and 275. Signed-off-by: Bob Moore Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/dispatcher/dsutils.c | 52 ++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 14 deletions(-) (limited to 'drivers/acpi/dispatcher/dsutils.c') diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index 71503c036f7c..d2a8cfdaec22 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.c @@ -630,9 +630,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, * Use value that was already previously returned * by the evaluation of this argument */ - status = - acpi_ds_result_pop_from_bottom(&obj_desc, - walk_state); + status = acpi_ds_result_pop(&obj_desc, walk_state); if (ACPI_FAILURE(status)) { /* * Only error is underflow, and this indicates @@ -698,27 +696,54 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, { acpi_status status = AE_OK; union acpi_parse_object *arg; - u32 arg_count = 0; + union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS]; + u8 arg_count = 0; + u8 count = 0; + u8 index = walk_state->num_operands; + u8 i; ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg); - /* For all arguments in the list... */ + /* Get all arguments in the list */ arg = first_arg; while (arg) { - status = acpi_ds_create_operand(walk_state, arg, arg_count); - if (ACPI_FAILURE(status)) { - goto cleanup; + if (index >= ACPI_OBJ_NUM_OPERANDS) { + return_ACPI_STATUS(AE_BAD_DATA); } - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "Arg #%d (%p) done, Arg1=%p\n", arg_count, - arg, first_arg)); + arguments[index] = arg; + walk_state->operands[index] = NULL; /* Move on to next argument, if any */ arg = arg->common.next; arg_count++; + index++; + } + + index--; + + /* It is the appropriate order to get objects from the Result stack */ + + for (i = 0; i < arg_count; i++) { + arg = arguments[index]; + + /* Force the filling of the operand stack in inverse order */ + + walk_state->operand_index = index; + + status = acpi_ds_create_operand(walk_state, arg, index); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + + count++; + index--; + + ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, + "Arg #%d (%p) done, Arg1=%p\n", index, arg, + first_arg)); } return_ACPI_STATUS(status); @@ -729,9 +754,8 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, * pop everything off of the operand stack and delete those * objects */ - (void)acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); + acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); - ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", - (arg_count + 1))); + ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index)); return_ACPI_STATUS(status); } -- cgit v1.2.3 From 4e3156b183aa087bc19804b3295c7c1a71f64752 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 10 Apr 2008 19:06:37 +0400 Subject: 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 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/dispatcher/dsutils.c | 113 +++++++++++++++++++++++++++++++++++++- 1 file changed, 110 insertions(+), 3 deletions(-) (limited to 'drivers/acpi/dispatcher/dsutils.c') 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, /* A valid name must be looked up in the namespace */ if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && - (arg->common.value.string)) { + (arg->common.value.string) && + !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) { ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", arg)); @@ -595,7 +596,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, } else { /* Check for null name case */ - if (arg->common.aml_opcode == AML_INT_NAMEPATH_OP) { + if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && + !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) { /* * If the name is null, this means that this is an * optional result parameter that was not specified @@ -617,7 +619,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, return_ACPI_STATUS(AE_NOT_IMPLEMENTED); } - if (op_info->flags & AML_HAS_RETVAL) { + if ((op_info->flags & AML_HAS_RETVAL) + || (arg->common.flags & ACPI_PARSEOP_IN_STACK)) { ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Argument previously created, already stacked\n")); @@ -759,3 +762,107 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index)); return_ACPI_STATUS(status); } + +/***************************************************************************** + * + * FUNCTION: acpi_ds_evaluate_name_path + * + * PARAMETERS: walk_state - Current state of the parse tree walk, + * the opcode of current operation should be + * AML_INT_NAMEPATH_OP + * + * RETURN: Status + * + * DESCRIPTION: Translate the -name_path- parse tree object to the equivalent + * interpreter object, convert it to value, if needed, duplicate + * it, if needed, and push it onto the current result stack. + * + ****************************************************************************/ + +acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state) +{ + acpi_status status = AE_OK; + union acpi_parse_object *op = walk_state->op; + union acpi_operand_object **operand = &walk_state->operands[0]; + union acpi_operand_object *new_obj_desc; + u8 type; + + ACPI_FUNCTION_TRACE_PTR(ds_evaluate_name_path, walk_state); + + if (!op->common.parent) { + + /* This happens after certain exception processing */ + + goto exit; + } + + if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) || + (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) || + (op->common.parent->common.aml_opcode == AML_REF_OF_OP)) { + + /* TBD: Should we specify this feature as a bit of op_info->Flags of these opcodes? */ + + goto exit; + } + + status = acpi_ds_create_operand(walk_state, op, 0); + if (ACPI_FAILURE(status)) { + goto exit; + } + + if (op->common.flags & ACPI_PARSEOP_TARGET) { + new_obj_desc = *operand; + goto push_result; + } + + type = ACPI_GET_OBJECT_TYPE(*operand); + + status = acpi_ex_resolve_to_value(operand, walk_state); + if (ACPI_FAILURE(status)) { + goto exit; + } + + if (type == ACPI_TYPE_INTEGER) { + + /* It was incremented by acpi_ex_resolve_to_value */ + + acpi_ut_remove_reference(*operand); + + status = + acpi_ut_copy_iobject_to_iobject(*operand, &new_obj_desc, + walk_state); + if (ACPI_FAILURE(status)) { + goto exit; + } + } else { + /* + * The object either was anew created or is + * a Namespace node - don't decrement it. + */ + new_obj_desc = *operand; + } + + /* Cleanup for name-path operand */ + + status = acpi_ds_obj_stack_pop(1, walk_state); + if (ACPI_FAILURE(status)) { + walk_state->result_obj = new_obj_desc; + goto exit; + } + + push_result: + + walk_state->result_obj = new_obj_desc; + + status = acpi_ds_result_push(walk_state->result_obj, walk_state); + if (ACPI_SUCCESS(status)) { + + /* Force to take it from stack */ + + op->common.flags |= ACPI_PARSEOP_IN_STACK; + } + + exit: + + return_ACPI_STATUS(status); +} -- cgit v1.2.3 From b7f9f04228eae2cf5adc2ffeb494d4970a8dd8a5 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 10 Apr 2008 19:06:40 +0400 Subject: ACPICA: Cosmetic changes only, no functional changes Lint changes, fix compiler warnings, etc. Signed-off-by: Bob Moore Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/dispatcher/dsutils.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/acpi/dispatcher/dsutils.c') diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index 36518b4a79c2..97d01dcdc972 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.c @@ -700,10 +700,9 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, acpi_status status = AE_OK; union acpi_parse_object *arg; union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS]; - u8 arg_count = 0; - u8 count = 0; - u8 index = walk_state->num_operands; - u8 i; + u32 arg_count = 0; + u32 index = walk_state->num_operands; + u32 i; ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg); @@ -734,14 +733,13 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, /* Force the filling of the operand stack in inverse order */ - walk_state->operand_index = index; + walk_state->operand_index = (u8) index; status = acpi_ds_create_operand(walk_state, arg, index); if (ACPI_FAILURE(status)) { goto cleanup; } - count++; index--; ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, -- cgit v1.2.3 From ef805d956320ffa36d068673d5c5eb2a7d13209b Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 10 Apr 2008 19:06:41 +0400 Subject: ACPICA: Implemented full argument resolution support for the BankValue argument to BankField Previously, only constants were supported, now any TermArg may be used. http://www.acpica.org/bugzilla/show_bug.cgi?id=387 http://www.acpica.org/bugzilla/show_bug.cgi?id=393 Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/dispatcher/dsutils.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/acpi/dispatcher/dsutils.c') diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index 97d01dcdc972..f6c28d7b46c5 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.c @@ -278,7 +278,9 @@ acpi_ds_is_result_used(union acpi_parse_object * op, AML_VAR_PACKAGE_OP) || (op->common.parent->common.aml_opcode == AML_BUFFER_OP) || (op->common.parent->common.aml_opcode == - AML_INT_EVAL_SUBTREE_OP)) { + AML_INT_EVAL_SUBTREE_OP) + || (op->common.parent->common.aml_opcode == + AML_BANK_FIELD_OP)) { /* * These opcodes allow term_arg(s) as operands and therefore * the operands can be method calls. The result is used. -- cgit v1.2.3 From 75a44ce00b312f57264f42a0a985d17cd9994b98 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Wed, 23 Apr 2008 23:00:13 -0400 Subject: ACPICA: update Intel copyright Signed-off-by: Len Brown --- drivers/acpi/dispatcher/dsutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi/dispatcher/dsutils.c') diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index f6c28d7b46c5..b398982f0d8b 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2008, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without -- cgit v1.2.3