0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "amlcode.h"
0013 #include "acdispat.h"
0014 #include "acinterp.h"
0015 #include "acnamesp.h"
0016
0017 #define _COMPONENT ACPI_EXECUTER
0018 ACPI_MODULE_NAME("exresolv")
0019
0020
0021 static acpi_status
0022 acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
0023 struct acpi_walk_state *walk_state);
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 acpi_status
0041 acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr,
0042 struct acpi_walk_state *walk_state)
0043 {
0044 acpi_status status;
0045
0046 ACPI_FUNCTION_TRACE_PTR(ex_resolve_to_value, stack_ptr);
0047
0048 if (!stack_ptr || !*stack_ptr) {
0049 ACPI_ERROR((AE_INFO, "Internal - null pointer"));
0050 return_ACPI_STATUS(AE_AML_NO_OPERAND);
0051 }
0052
0053
0054
0055
0056
0057
0058 if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_OPERAND) {
0059 status = acpi_ex_resolve_object_to_value(stack_ptr, walk_state);
0060 if (ACPI_FAILURE(status)) {
0061 return_ACPI_STATUS(status);
0062 }
0063
0064 if (!*stack_ptr) {
0065 ACPI_ERROR((AE_INFO, "Internal - null pointer"));
0066 return_ACPI_STATUS(AE_AML_NO_OPERAND);
0067 }
0068 }
0069
0070
0071
0072
0073
0074 if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_NAMED) {
0075 status =
0076 acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
0077 (struct acpi_namespace_node,
0078 stack_ptr), walk_state);
0079 if (ACPI_FAILURE(status)) {
0080 return_ACPI_STATUS(status);
0081 }
0082 }
0083
0084 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Resolved object %p\n", *stack_ptr));
0085 return_ACPI_STATUS(AE_OK);
0086 }
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102 static acpi_status
0103 acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
0104 struct acpi_walk_state *walk_state)
0105 {
0106 acpi_status status = AE_OK;
0107 union acpi_operand_object *stack_desc;
0108 union acpi_operand_object *obj_desc = NULL;
0109 u8 ref_type;
0110
0111 ACPI_FUNCTION_TRACE(ex_resolve_object_to_value);
0112
0113 stack_desc = *stack_ptr;
0114
0115
0116
0117 switch (stack_desc->common.type) {
0118 case ACPI_TYPE_LOCAL_REFERENCE:
0119
0120 ref_type = stack_desc->reference.class;
0121
0122 switch (ref_type) {
0123 case ACPI_REFCLASS_LOCAL:
0124 case ACPI_REFCLASS_ARG:
0125
0126
0127
0128
0129 status = acpi_ds_method_data_get_value(ref_type,
0130 stack_desc->
0131 reference.value,
0132 walk_state,
0133 &obj_desc);
0134 if (ACPI_FAILURE(status)) {
0135 return_ACPI_STATUS(status);
0136 }
0137
0138 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0139 "[Arg/Local %X] ValueObj is %p\n",
0140 stack_desc->reference.value,
0141 obj_desc));
0142
0143
0144
0145
0146
0147 acpi_ut_remove_reference(stack_desc);
0148 *stack_ptr = obj_desc;
0149 break;
0150
0151 case ACPI_REFCLASS_INDEX:
0152
0153 switch (stack_desc->reference.target_type) {
0154 case ACPI_TYPE_BUFFER_FIELD:
0155
0156
0157 break;
0158
0159 case ACPI_TYPE_PACKAGE:
0160
0161
0162
0163 if ((walk_state->opcode ==
0164 AML_INT_METHODCALL_OP)
0165 || (walk_state->opcode ==
0166 AML_COPY_OBJECT_OP)) {
0167 break;
0168 }
0169
0170
0171
0172 obj_desc = *stack_desc->reference.where;
0173 if (obj_desc) {
0174
0175
0176
0177
0178
0179 acpi_ut_add_reference(obj_desc);
0180 *stack_ptr = obj_desc;
0181 } else {
0182
0183
0184
0185
0186 ACPI_ERROR((AE_INFO,
0187 "Attempt to dereference an Index to "
0188 "NULL package element Idx=%p",
0189 stack_desc));
0190 status = AE_AML_UNINITIALIZED_ELEMENT;
0191 }
0192 break;
0193
0194 default:
0195
0196
0197
0198 ACPI_ERROR((AE_INFO,
0199 "Unknown TargetType 0x%X in Index/Reference object %p",
0200 stack_desc->reference.target_type,
0201 stack_desc));
0202 status = AE_AML_INTERNAL;
0203 break;
0204 }
0205 break;
0206
0207 case ACPI_REFCLASS_REFOF:
0208 case ACPI_REFCLASS_DEBUG:
0209 case ACPI_REFCLASS_TABLE:
0210
0211
0212
0213 break;
0214
0215 case ACPI_REFCLASS_NAME:
0216
0217
0218
0219 if ((stack_desc->reference.node->type ==
0220 ACPI_TYPE_DEVICE)
0221 || (stack_desc->reference.node->type ==
0222 ACPI_TYPE_THERMAL)) {
0223
0224
0225
0226 *stack_ptr = (void *)stack_desc->reference.node;
0227 } else {
0228
0229
0230 *stack_ptr =
0231 (stack_desc->reference.node)->object;
0232 acpi_ut_add_reference(*stack_ptr);
0233 }
0234
0235 acpi_ut_remove_reference(stack_desc);
0236 break;
0237
0238 default:
0239
0240 ACPI_ERROR((AE_INFO,
0241 "Unknown Reference type 0x%X in %p",
0242 ref_type, stack_desc));
0243 status = AE_AML_INTERNAL;
0244 break;
0245 }
0246 break;
0247
0248 case ACPI_TYPE_BUFFER:
0249
0250 status = acpi_ds_get_buffer_arguments(stack_desc);
0251 break;
0252
0253 case ACPI_TYPE_PACKAGE:
0254
0255 status = acpi_ds_get_package_arguments(stack_desc);
0256 break;
0257
0258 case ACPI_TYPE_BUFFER_FIELD:
0259 case ACPI_TYPE_LOCAL_REGION_FIELD:
0260 case ACPI_TYPE_LOCAL_BANK_FIELD:
0261 case ACPI_TYPE_LOCAL_INDEX_FIELD:
0262
0263 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0264 "FieldRead SourceDesc=%p Type=%X\n",
0265 stack_desc, stack_desc->common.type));
0266
0267 status =
0268 acpi_ex_read_data_from_field(walk_state, stack_desc,
0269 &obj_desc);
0270
0271
0272
0273 acpi_ut_remove_reference(*stack_ptr);
0274 *stack_ptr = (void *)obj_desc;
0275 break;
0276
0277 default:
0278
0279 break;
0280 }
0281
0282 return_ACPI_STATUS(status);
0283 }
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301 acpi_status
0302 acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
0303 union acpi_operand_object *operand,
0304 acpi_object_type *return_type,
0305 union acpi_operand_object **return_desc)
0306 {
0307 union acpi_operand_object *obj_desc = ACPI_CAST_PTR(void, operand);
0308 struct acpi_namespace_node *node =
0309 ACPI_CAST_PTR(struct acpi_namespace_node, operand);
0310 acpi_object_type type;
0311 acpi_status status;
0312
0313 ACPI_FUNCTION_TRACE(acpi_ex_resolve_multiple);
0314
0315
0316
0317 switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
0318 case ACPI_DESC_TYPE_OPERAND:
0319
0320 type = obj_desc->common.type;
0321 break;
0322
0323 case ACPI_DESC_TYPE_NAMED:
0324
0325 type = ((struct acpi_namespace_node *)obj_desc)->type;
0326 obj_desc = acpi_ns_get_attached_object(node);
0327
0328
0329
0330 if (type == ACPI_TYPE_LOCAL_ALIAS) {
0331 type = ((struct acpi_namespace_node *)obj_desc)->type;
0332 obj_desc = acpi_ns_get_attached_object((struct
0333 acpi_namespace_node
0334 *)obj_desc);
0335 }
0336
0337 switch (type) {
0338 case ACPI_TYPE_DEVICE:
0339 case ACPI_TYPE_THERMAL:
0340
0341
0342 break;
0343
0344 default:
0345
0346
0347
0348 if (!obj_desc) {
0349 ACPI_ERROR((AE_INFO,
0350 "[%4.4s] Node is unresolved or uninitialized",
0351 acpi_ut_get_node_name(node)));
0352 return_ACPI_STATUS(AE_AML_UNINITIALIZED_NODE);
0353 }
0354 break;
0355 }
0356 break;
0357
0358 default:
0359 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0360 }
0361
0362
0363
0364 if (type != ACPI_TYPE_LOCAL_REFERENCE) {
0365 goto exit;
0366 }
0367
0368
0369
0370
0371
0372
0373
0374 while (obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
0375 switch (obj_desc->reference.class) {
0376 case ACPI_REFCLASS_REFOF:
0377 case ACPI_REFCLASS_NAME:
0378
0379
0380
0381 if (obj_desc->reference.class == ACPI_REFCLASS_REFOF) {
0382 node = obj_desc->reference.object;
0383 } else {
0384
0385 node = obj_desc->reference.node;
0386 }
0387
0388
0389
0390 if (ACPI_GET_DESCRIPTOR_TYPE(node) !=
0391 ACPI_DESC_TYPE_NAMED) {
0392 ACPI_ERROR((AE_INFO,
0393 "Not a namespace node %p [%s]",
0394 node,
0395 acpi_ut_get_descriptor_name(node)));
0396 return_ACPI_STATUS(AE_AML_INTERNAL);
0397 }
0398
0399
0400
0401 obj_desc = acpi_ns_get_attached_object(node);
0402 if (!obj_desc) {
0403
0404
0405
0406 type = acpi_ns_get_type(node);
0407 goto exit;
0408 }
0409
0410
0411
0412 if (obj_desc == operand) {
0413 return_ACPI_STATUS(AE_AML_CIRCULAR_REFERENCE);
0414 }
0415 break;
0416
0417 case ACPI_REFCLASS_INDEX:
0418
0419
0420
0421 type = obj_desc->reference.target_type;
0422 if (type != ACPI_TYPE_PACKAGE) {
0423 goto exit;
0424 }
0425
0426
0427
0428
0429
0430
0431
0432
0433 obj_desc = *(obj_desc->reference.where);
0434 if (!obj_desc) {
0435
0436
0437
0438 type = 0;
0439 goto exit;
0440 }
0441 break;
0442
0443 case ACPI_REFCLASS_TABLE:
0444
0445 type = ACPI_TYPE_DDB_HANDLE;
0446 goto exit;
0447
0448 case ACPI_REFCLASS_LOCAL:
0449 case ACPI_REFCLASS_ARG:
0450
0451 if (return_desc) {
0452 status =
0453 acpi_ds_method_data_get_value(obj_desc->
0454 reference.
0455 class,
0456 obj_desc->
0457 reference.
0458 value,
0459 walk_state,
0460 &obj_desc);
0461 if (ACPI_FAILURE(status)) {
0462 return_ACPI_STATUS(status);
0463 }
0464 acpi_ut_remove_reference(obj_desc);
0465 } else {
0466 status =
0467 acpi_ds_method_data_get_node(obj_desc->
0468 reference.
0469 class,
0470 obj_desc->
0471 reference.
0472 value,
0473 walk_state,
0474 &node);
0475 if (ACPI_FAILURE(status)) {
0476 return_ACPI_STATUS(status);
0477 }
0478
0479 obj_desc = acpi_ns_get_attached_object(node);
0480 if (!obj_desc) {
0481 type = ACPI_TYPE_ANY;
0482 goto exit;
0483 }
0484 }
0485 break;
0486
0487 case ACPI_REFCLASS_DEBUG:
0488
0489
0490
0491 type = ACPI_TYPE_DEBUG_OBJECT;
0492 goto exit;
0493
0494 default:
0495
0496 ACPI_ERROR((AE_INFO,
0497 "Unknown Reference Class 0x%2.2X",
0498 obj_desc->reference.class));
0499 return_ACPI_STATUS(AE_AML_INTERNAL);
0500 }
0501 }
0502
0503
0504
0505
0506
0507 type = obj_desc->common.type;
0508
0509 exit:
0510
0511
0512 switch (type) {
0513 case ACPI_TYPE_LOCAL_REGION_FIELD:
0514 case ACPI_TYPE_LOCAL_BANK_FIELD:
0515 case ACPI_TYPE_LOCAL_INDEX_FIELD:
0516
0517 type = ACPI_TYPE_FIELD_UNIT;
0518 break;
0519
0520 case ACPI_TYPE_LOCAL_SCOPE:
0521
0522
0523
0524 type = ACPI_TYPE_ANY;
0525 break;
0526
0527 default:
0528
0529
0530
0531 break;
0532 }
0533
0534 *return_type = type;
0535 if (return_desc) {
0536 *return_desc = obj_desc;
0537 }
0538 return_ACPI_STATUS(AE_OK);
0539 }