0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acdispat.h"
0013 #include "acinterp.h"
0014 #include "amlcode.h"
0015 #include "acnamesp.h"
0016
0017 #define _COMPONENT ACPI_EXECUTER
0018 ACPI_MODULE_NAME("exstore")
0019
0020
0021 static acpi_status
0022 acpi_ex_store_object_to_index(union acpi_operand_object *val_desc,
0023 union acpi_operand_object *dest_desc,
0024 struct acpi_walk_state *walk_state);
0025
0026 static acpi_status
0027 acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
0028 struct acpi_namespace_node *node,
0029 struct acpi_walk_state *walk_state);
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 acpi_status
0052 acpi_ex_store(union acpi_operand_object *source_desc,
0053 union acpi_operand_object *dest_desc,
0054 struct acpi_walk_state *walk_state)
0055 {
0056 acpi_status status = AE_OK;
0057 union acpi_operand_object *ref_desc = dest_desc;
0058
0059 ACPI_FUNCTION_TRACE_PTR(ex_store, dest_desc);
0060
0061
0062
0063 if (!source_desc || !dest_desc) {
0064 ACPI_ERROR((AE_INFO, "Null parameter"));
0065 return_ACPI_STATUS(AE_AML_NO_OPERAND);
0066 }
0067
0068
0069
0070 if (ACPI_GET_DESCRIPTOR_TYPE(dest_desc) == ACPI_DESC_TYPE_NAMED) {
0071
0072
0073
0074
0075 status = acpi_ex_store_object_to_node(source_desc,
0076 (struct
0077 acpi_namespace_node *)
0078 dest_desc, walk_state,
0079 ACPI_IMPLICIT_CONVERSION);
0080
0081 return_ACPI_STATUS(status);
0082 }
0083
0084
0085
0086 switch (dest_desc->common.type) {
0087 case ACPI_TYPE_LOCAL_REFERENCE:
0088
0089 break;
0090
0091 case ACPI_TYPE_INTEGER:
0092
0093
0094
0095 if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
0096 return_ACPI_STATUS(AE_OK);
0097 }
0098
0099 ACPI_FALLTHROUGH;
0100
0101 default:
0102
0103
0104
0105 ACPI_ERROR((AE_INFO,
0106 "Target is not a Reference or Constant object - [%s] %p",
0107 acpi_ut_get_object_type_name(dest_desc),
0108 dest_desc));
0109
0110 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0111 }
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 switch (ref_desc->reference.class) {
0122 case ACPI_REFCLASS_REFOF:
0123
0124
0125
0126 status = acpi_ex_store_object_to_node(source_desc,
0127 ref_desc->reference.
0128 object, walk_state,
0129 ACPI_IMPLICIT_CONVERSION);
0130 break;
0131
0132 case ACPI_REFCLASS_INDEX:
0133
0134
0135
0136 status =
0137 acpi_ex_store_object_to_index(source_desc, ref_desc,
0138 walk_state);
0139 break;
0140
0141 case ACPI_REFCLASS_LOCAL:
0142 case ACPI_REFCLASS_ARG:
0143
0144
0145
0146 status =
0147 acpi_ds_store_object_to_local(ref_desc->reference.class,
0148 ref_desc->reference.value,
0149 source_desc, walk_state);
0150 break;
0151
0152 case ACPI_REFCLASS_DEBUG:
0153
0154
0155
0156
0157 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0158 "**** Write to Debug Object: Object %p [%s] ****:\n\n",
0159 source_desc,
0160 acpi_ut_get_object_type_name(source_desc)));
0161
0162 ACPI_DEBUG_OBJECT(source_desc, 0, 0);
0163 break;
0164
0165 default:
0166
0167 ACPI_ERROR((AE_INFO, "Unknown Reference Class 0x%2.2X",
0168 ref_desc->reference.class));
0169 ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_INFO);
0170
0171 status = AE_AML_INTERNAL;
0172 break;
0173 }
0174
0175 return_ACPI_STATUS(status);
0176 }
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192 static acpi_status
0193 acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
0194 union acpi_operand_object *index_desc,
0195 struct acpi_walk_state *walk_state)
0196 {
0197 acpi_status status = AE_OK;
0198 union acpi_operand_object *obj_desc;
0199 union acpi_operand_object *new_desc;
0200 u8 value = 0;
0201 u32 i;
0202
0203 ACPI_FUNCTION_TRACE(ex_store_object_to_index);
0204
0205
0206
0207
0208
0209 switch (index_desc->reference.target_type) {
0210 case ACPI_TYPE_PACKAGE:
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220 obj_desc = *(index_desc->reference.where);
0221
0222 if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE &&
0223 source_desc->reference.class == ACPI_REFCLASS_TABLE) {
0224
0225
0226
0227 acpi_ut_add_reference(source_desc);
0228 new_desc = source_desc;
0229 } else {
0230
0231
0232 status =
0233 acpi_ut_copy_iobject_to_iobject(source_desc,
0234 &new_desc,
0235 walk_state);
0236 if (ACPI_FAILURE(status)) {
0237 return_ACPI_STATUS(status);
0238 }
0239 }
0240
0241 if (obj_desc) {
0242
0243
0244
0245 for (i = 0; i < ((union acpi_operand_object *)
0246 index_desc->reference.object)->common.
0247 reference_count; i++) {
0248 acpi_ut_remove_reference(obj_desc);
0249 }
0250 }
0251
0252 *(index_desc->reference.where) = new_desc;
0253
0254
0255
0256 for (i = 1; i < ((union acpi_operand_object *)
0257 index_desc->reference.object)->common.
0258 reference_count; i++) {
0259 acpi_ut_add_reference(new_desc);
0260 }
0261
0262 break;
0263
0264 case ACPI_TYPE_BUFFER_FIELD:
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279 obj_desc = index_desc->reference.object;
0280 if ((obj_desc->common.type != ACPI_TYPE_BUFFER) &&
0281 (obj_desc->common.type != ACPI_TYPE_STRING)) {
0282 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0283 }
0284
0285
0286
0287
0288
0289 switch (source_desc->common.type) {
0290 case ACPI_TYPE_INTEGER:
0291
0292
0293
0294 value = (u8) (source_desc->integer.value);
0295 break;
0296
0297 case ACPI_TYPE_BUFFER:
0298 case ACPI_TYPE_STRING:
0299
0300
0301
0302 value = source_desc->buffer.pointer[0];
0303 break;
0304
0305 default:
0306
0307
0308
0309 ACPI_ERROR((AE_INFO,
0310 "Source must be type [Integer/Buffer/String], found [%s]",
0311 acpi_ut_get_object_type_name(source_desc)));
0312 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0313 }
0314
0315
0316
0317 obj_desc->buffer.pointer[index_desc->reference.value] = value;
0318 break;
0319
0320 default:
0321 ACPI_ERROR((AE_INFO,
0322 "Target is not of type [Package/BufferField]"));
0323 status = AE_AML_TARGET_TYPE;
0324 break;
0325 }
0326
0327 return_ACPI_STATUS(status);
0328 }
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360 acpi_status
0361 acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
0362 struct acpi_namespace_node *node,
0363 struct acpi_walk_state *walk_state,
0364 u8 implicit_conversion)
0365 {
0366 acpi_status status = AE_OK;
0367 union acpi_operand_object *target_desc;
0368 union acpi_operand_object *new_desc;
0369 acpi_object_type target_type;
0370
0371 ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_node, source_desc);
0372
0373
0374
0375 target_type = acpi_ns_get_type(node);
0376 target_desc = acpi_ns_get_attached_object(node);
0377
0378 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p [%s] to node %p [%s]\n",
0379 source_desc,
0380 acpi_ut_get_object_type_name(source_desc), node,
0381 acpi_ut_get_type_name(target_type)));
0382
0383
0384
0385 if (walk_state->opcode != AML_COPY_OBJECT_OP) {
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404 switch (target_type) {
0405 case ACPI_TYPE_PACKAGE:
0406
0407
0408
0409
0410
0411 if (walk_state->opcode == AML_STORE_OP) {
0412 if (source_desc->common.type !=
0413 ACPI_TYPE_PACKAGE) {
0414 ACPI_ERROR((AE_INFO,
0415 "Cannot assign type [%s] to [Package] "
0416 "(source must be type Pkg)",
0417 acpi_ut_get_object_type_name
0418 (source_desc)));
0419
0420 return_ACPI_STATUS(AE_AML_TARGET_TYPE);
0421 }
0422 break;
0423 }
0424
0425 ACPI_FALLTHROUGH;
0426
0427 case ACPI_TYPE_DEVICE:
0428 case ACPI_TYPE_EVENT:
0429 case ACPI_TYPE_MUTEX:
0430 case ACPI_TYPE_REGION:
0431 case ACPI_TYPE_POWER:
0432 case ACPI_TYPE_PROCESSOR:
0433 case ACPI_TYPE_THERMAL:
0434
0435 ACPI_ERROR((AE_INFO,
0436 "Target must be [Buffer/Integer/String/Reference]"
0437 ", found [%s] (%4.4s)",
0438 acpi_ut_get_type_name(node->type),
0439 node->name.ascii));
0440
0441 return_ACPI_STATUS(AE_AML_TARGET_TYPE);
0442
0443 default:
0444 break;
0445 }
0446 }
0447
0448
0449
0450
0451
0452 status = acpi_ex_resolve_object(&source_desc, target_type, walk_state);
0453 if (ACPI_FAILURE(status)) {
0454 return_ACPI_STATUS(status);
0455 }
0456
0457
0458
0459 switch (target_type) {
0460
0461
0462
0463
0464 case ACPI_TYPE_INTEGER:
0465 case ACPI_TYPE_STRING:
0466 case ACPI_TYPE_BUFFER:
0467
0468 if ((walk_state->opcode == AML_COPY_OBJECT_OP) ||
0469 !implicit_conversion) {
0470
0471
0472
0473
0474
0475 status =
0476 acpi_ex_store_direct_to_node(source_desc, node,
0477 walk_state);
0478 break;
0479 }
0480
0481
0482
0483 status =
0484 acpi_ex_store_object_to_object(source_desc, target_desc,
0485 &new_desc, walk_state);
0486 if (ACPI_FAILURE(status)) {
0487 return_ACPI_STATUS(status);
0488 }
0489
0490 if (new_desc != target_desc) {
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500 status =
0501 acpi_ns_attach_object(node, new_desc,
0502 new_desc->common.type);
0503
0504 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0505 "Store type [%s] into [%s] via Convert/Attach\n",
0506 acpi_ut_get_object_type_name
0507 (source_desc),
0508 acpi_ut_get_object_type_name
0509 (new_desc)));
0510 }
0511 break;
0512
0513 case ACPI_TYPE_BUFFER_FIELD:
0514 case ACPI_TYPE_LOCAL_REGION_FIELD:
0515 case ACPI_TYPE_LOCAL_BANK_FIELD:
0516 case ACPI_TYPE_LOCAL_INDEX_FIELD:
0517
0518
0519
0520
0521
0522
0523 status = acpi_ex_write_data_to_field(source_desc, target_desc,
0524 &walk_state->result_obj);
0525 break;
0526
0527 default:
0528
0529
0530
0531
0532
0533
0534
0535
0536 status =
0537 acpi_ex_store_direct_to_node(source_desc, node, walk_state);
0538 break;
0539 }
0540
0541 return_ACPI_STATUS(status);
0542 }
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559 static acpi_status
0560 acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
0561 struct acpi_namespace_node *node,
0562 struct acpi_walk_state *walk_state)
0563 {
0564 acpi_status status;
0565 union acpi_operand_object *new_desc;
0566
0567 ACPI_FUNCTION_TRACE(ex_store_direct_to_node);
0568
0569 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0570 "Storing [%s] (%p) directly into node [%s] (%p)"
0571 " with no implicit conversion\n",
0572 acpi_ut_get_object_type_name(source_desc),
0573 source_desc, acpi_ut_get_type_name(node->type),
0574 node));
0575
0576
0577
0578 status =
0579 acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, walk_state);
0580 if (ACPI_FAILURE(status)) {
0581 return_ACPI_STATUS(status);
0582 }
0583
0584
0585
0586 status = acpi_ns_attach_object(node, new_desc, new_desc->common.type);
0587 acpi_ut_remove_reference(new_desc);
0588 return_ACPI_STATUS(status);
0589 }