aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
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