aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/executer/exoparg2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/executer/exoparg2.c')
-rw-r--r--drivers/acpi/executer/exoparg2.c89
1 files changed, 55 insertions, 34 deletions
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
index e263a5ddd405..7d2cbc113160 100644
--- a/drivers/acpi/executer/exoparg2.c
+++ b/drivers/acpi/executer/exoparg2.c
@@ -92,7 +92,7 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state)
92 u32 value; 92 u32 value;
93 acpi_status status = AE_OK; 93 acpi_status status = AE_OK;
94 94
95 ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_0T_0R", 95 ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_0T_0R,
96 acpi_ps_get_opcode_name(walk_state->opcode)); 96 acpi_ps_get_opcode_name(walk_state->opcode));
97 97
98 /* Examine the opcode */ 98 /* Examine the opcode */
@@ -121,7 +121,7 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state)
121#ifdef ACPI_GPE_NOTIFY_CHECK 121#ifdef ACPI_GPE_NOTIFY_CHECK
122 /* 122 /*
123 * GPE method wake/notify check. Here, we want to ensure that we 123 * GPE method wake/notify check. Here, we want to ensure that we
124 * don't receive any "device_wake" Notifies from a GPE _Lxx or _Exx 124 * don't receive any "DeviceWake" Notifies from a GPE _Lxx or _Exx
125 * GPE method during system runtime. If we do, the GPE is marked 125 * GPE method during system runtime. If we do, the GPE is marked
126 * as "wake-only" and disabled. 126 * as "wake-only" and disabled.
127 * 127 *
@@ -138,6 +138,7 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state)
138 acpi_ev_check_for_wake_only_gpe(walk_state-> 138 acpi_ev_check_for_wake_only_gpe(walk_state->
139 gpe_event_info); 139 gpe_event_info);
140 if (ACPI_FAILURE(status)) { 140 if (ACPI_FAILURE(status)) {
141
141 /* AE_WAKE_ONLY_GPE only error, means ignore this notify */ 142 /* AE_WAKE_ONLY_GPE only error, means ignore this notify */
142 143
143 return_ACPI_STATUS(AE_OK) 144 return_ACPI_STATUS(AE_OK)
@@ -185,7 +186,7 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state)
185 union acpi_operand_object *return_desc2 = NULL; 186 union acpi_operand_object *return_desc2 = NULL;
186 acpi_status status; 187 acpi_status status;
187 188
188 ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_2T_1R", 189 ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_2T_1R,
189 acpi_ps_get_opcode_name(walk_state->opcode)); 190 acpi_ps_get_opcode_name(walk_state->opcode));
190 191
191 /* Execute the opcode */ 192 /* Execute the opcode */
@@ -252,6 +253,7 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state)
252 acpi_ut_remove_reference(return_desc2); 253 acpi_ut_remove_reference(return_desc2);
253 254
254 if (ACPI_FAILURE(status)) { 255 if (ACPI_FAILURE(status)) {
256
255 /* Delete the return object */ 257 /* Delete the return object */
256 258
257 acpi_ut_remove_reference(return_desc1); 259 acpi_ut_remove_reference(return_desc1);
@@ -281,12 +283,13 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state)
281 acpi_status status = AE_OK; 283 acpi_status status = AE_OK;
282 acpi_size length; 284 acpi_size length;
283 285
284 ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_1T_1R", 286 ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_1T_1R,
285 acpi_ps_get_opcode_name(walk_state->opcode)); 287 acpi_ps_get_opcode_name(walk_state->opcode));
286 288
287 /* Execute the opcode */ 289 /* Execute the opcode */
288 290
289 if (walk_state->op_info->flags & AML_MATH) { 291 if (walk_state->op_info->flags & AML_MATH) {
292
290 /* All simple math opcodes (add, etc.) */ 293 /* All simple math opcodes (add, etc.) */
291 294
292 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); 295 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
@@ -383,54 +386,70 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state)
383 goto cleanup; 386 goto cleanup;
384 } 387 }
385 388
389 /* Initialize the Index reference object */
390
386 index = operand[1]->integer.value; 391 index = operand[1]->integer.value;
392 return_desc->reference.offset = (u32) index;
393 return_desc->reference.opcode = AML_INDEX_OP;
387 394
388 /* At this point, the Source operand is a Package, Buffer, or String */ 395 /*
396 * At this point, the Source operand is a String, Buffer, or Package.
397 * Verify that the index is within range.
398 */
399 switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
400 case ACPI_TYPE_STRING:
389 401
390 if (ACPI_GET_OBJECT_TYPE(operand[0]) == ACPI_TYPE_PACKAGE) { 402 if (index >= operand[0]->string.length) {
391 /* Object to be indexed is a Package */ 403 status = AE_AML_STRING_LIMIT;
404 }
405
406 return_desc->reference.target_type =
407 ACPI_TYPE_BUFFER_FIELD;
408 break;
409
410 case ACPI_TYPE_BUFFER:
411
412 if (index >= operand[0]->buffer.length) {
413 status = AE_AML_BUFFER_LIMIT;
414 }
415
416 return_desc->reference.target_type =
417 ACPI_TYPE_BUFFER_FIELD;
418 break;
419
420 case ACPI_TYPE_PACKAGE:
392 421
393 if (index >= operand[0]->package.count) { 422 if (index >= operand[0]->package.count) {
394 ACPI_ERROR((AE_INFO,
395 "Index value (%X%8.8X) beyond package end (%X)",
396 ACPI_FORMAT_UINT64(index),
397 operand[0]->package.count));
398 status = AE_AML_PACKAGE_LIMIT; 423 status = AE_AML_PACKAGE_LIMIT;
399 goto cleanup;
400 } 424 }
401 425
402 return_desc->reference.target_type = ACPI_TYPE_PACKAGE; 426 return_desc->reference.target_type = ACPI_TYPE_PACKAGE;
403 return_desc->reference.object = operand[0];
404 return_desc->reference.where = 427 return_desc->reference.where =
405 &operand[0]->package.elements[index]; 428 &operand[0]->package.elements[index];
406 } else { 429 break;
407 /* Object to be indexed is a Buffer/String */
408 430
409 if (index >= operand[0]->buffer.length) { 431 default:
410 ACPI_ERROR((AE_INFO,
411 "Index value (%X%8.8X) beyond end of buffer (%X)",
412 ACPI_FORMAT_UINT64(index),
413 operand[0]->buffer.length));
414 status = AE_AML_BUFFER_LIMIT;
415 goto cleanup;
416 }
417 432
418 return_desc->reference.target_type = 433 status = AE_AML_INTERNAL;
419 ACPI_TYPE_BUFFER_FIELD; 434 goto cleanup;
420 return_desc->reference.object = operand[0]; 435 }
436
437 /* Failure means that the Index was beyond the end of the object */
438
439 if (ACPI_FAILURE(status)) {
440 ACPI_EXCEPTION((AE_INFO, status,
441 "Index (%X%8.8X) is beyond end of object",
442 ACPI_FORMAT_UINT64(index)));
443 goto cleanup;
421 } 444 }
422 445
423 /* 446 /*
424 * Add a reference to the target package/buffer/string for the life 447 * Save the target object and add a reference to it for the life
425 * of the index. 448 * of the index
426 */ 449 */
450 return_desc->reference.object = operand[0];
427 acpi_ut_add_reference(operand[0]); 451 acpi_ut_add_reference(operand[0]);
428 452
429 /* Complete the Index reference object */
430
431 return_desc->reference.opcode = AML_INDEX_OP;
432 return_desc->reference.offset = (u32) index;
433
434 /* Store the reference to the Target */ 453 /* Store the reference to the Target */
435 454
436 status = acpi_ex_store(return_desc, operand[2], walk_state); 455 status = acpi_ex_store(return_desc, operand[2], walk_state);
@@ -495,7 +514,7 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state)
495 acpi_status status = AE_OK; 514 acpi_status status = AE_OK;
496 u8 logical_result = FALSE; 515 u8 logical_result = FALSE;
497 516
498 ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_0T_1R", 517 ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_0T_1R,
499 acpi_ps_get_opcode_name(walk_state->opcode)); 518 acpi_ps_get_opcode_name(walk_state->opcode));
500 519
501 /* Create the internal return object */ 520 /* Create the internal return object */
@@ -509,6 +528,7 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state)
509 /* Execute the Opcode */ 528 /* Execute the Opcode */
510 529
511 if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) { 530 if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) {
531
512 /* logical_op (Operand0, Operand1) */ 532 /* logical_op (Operand0, Operand1) */
513 533
514 status = acpi_ex_do_logical_numeric_op(walk_state->opcode, 534 status = acpi_ex_do_logical_numeric_op(walk_state->opcode,
@@ -518,6 +538,7 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state)
518 value, &logical_result); 538 value, &logical_result);
519 goto store_logical_result; 539 goto store_logical_result;
520 } else if (walk_state->op_info->flags & AML_LOGICAL) { 540 } else if (walk_state->op_info->flags & AML_LOGICAL) {
541
521 /* logical_op (Operand0, Operand1) */ 542 /* logical_op (Operand0, Operand1) */
522 543
523 status = acpi_ex_do_logical_op(walk_state->opcode, operand[0], 544 status = acpi_ex_do_logical_op(walk_state->opcode, operand[0],