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.c77
1 files changed, 49 insertions, 28 deletions
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
index e263a5ddd405..5e1abb12c748 100644
--- a/drivers/acpi/executer/exoparg2.c
+++ b/drivers/acpi/executer/exoparg2.c
@@ -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)
@@ -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);
@@ -287,6 +289,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state)
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;
394 return_desc->reference.object = operand[0];
387 395
388 /* At this point, the Source operand is a Package, Buffer, or String */ 396 /*
397 * At this point, the Source operand is a String, Buffer, or Package.
398 * Verify that the index is within range.
399 */
400 switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
401 case ACPI_TYPE_STRING:
389 402
390 if (ACPI_GET_OBJECT_TYPE(operand[0]) == ACPI_TYPE_PACKAGE) { 403 if (index >= operand[0]->string.length) {
391 /* Object to be indexed is a Package */ 404 status = AE_AML_STRING_LIMIT;
405 }
406
407 return_desc->reference.target_type =
408 ACPI_TYPE_BUFFER_FIELD;
409 break;
410
411 case ACPI_TYPE_BUFFER:
412
413 if (index >= operand[0]->buffer.length) {
414 status = AE_AML_BUFFER_LIMIT;
415 }
416
417 return_desc->reference.target_type =
418 ACPI_TYPE_BUFFER_FIELD;
419 break;
420
421 case ACPI_TYPE_PACKAGE:
392 422
393 if (index >= operand[0]->package.count) { 423 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; 424 status = AE_AML_PACKAGE_LIMIT;
399 goto cleanup;
400 } 425 }
401 426
402 return_desc->reference.target_type = ACPI_TYPE_PACKAGE; 427 return_desc->reference.target_type = ACPI_TYPE_PACKAGE;
403 return_desc->reference.object = operand[0];
404 return_desc->reference.where = 428 return_desc->reference.where =
405 &operand[0]->package.elements[index]; 429 &operand[0]->package.elements[index];
406 } else { 430 break;
407 /* Object to be indexed is a Buffer/String */
408 431
409 if (index >= operand[0]->buffer.length) { 432 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 433
418 return_desc->reference.target_type = 434 status = AE_AML_INTERNAL;
419 ACPI_TYPE_BUFFER_FIELD; 435 goto cleanup;
420 return_desc->reference.object = operand[0]; 436 }
437
438 /* Failure means that the Index was beyond the end of the object */
439
440 if (ACPI_FAILURE(status)) {
441 ACPI_EXCEPTION((AE_INFO, status,
442 "Index (%X%8.8X) is beyond end of object",
443 ACPI_FORMAT_UINT64(index)));
444 goto cleanup;
421 } 445 }
422 446
423 /* 447 /*
424 * Add a reference to the target package/buffer/string for the life 448 * Add a reference to the target package/buffer/string for the life
425 * of the index. 449 * of the index
426 */ 450 */
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);
@@ -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],