0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acparser.h"
0013 #include "amlcode.h"
0014 #include "acdispat.h"
0015 #include "acinterp.h"
0016 #include "acnamesp.h"
0017 #include "acevents.h"
0018 #ifdef ACPI_EXEC_APP
0019 #include "aecommon.h"
0020 #endif
0021
0022 #define _COMPONENT ACPI_DISPATCHER
0023 ACPI_MODULE_NAME("dswload2")
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 acpi_status
0038 acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
0039 union acpi_parse_object **out_op)
0040 {
0041 union acpi_parse_object *op;
0042 struct acpi_namespace_node *node;
0043 acpi_status status;
0044 acpi_object_type object_type;
0045 char *buffer_ptr;
0046 u32 flags;
0047
0048 ACPI_FUNCTION_TRACE(ds_load2_begin_op);
0049
0050 op = walk_state->op;
0051 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
0052 walk_state));
0053
0054 if (op) {
0055 if ((walk_state->control_state) &&
0056 (walk_state->control_state->common.state ==
0057 ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
0058
0059
0060
0061 status = acpi_ds_exec_begin_op(walk_state, out_op);
0062 return_ACPI_STATUS(status);
0063 }
0064
0065
0066
0067 if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&
0068 (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
0069 (!(walk_state->op_info->flags & AML_NAMED))) {
0070 return_ACPI_STATUS(AE_OK);
0071 }
0072
0073
0074
0075 if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
0076
0077
0078
0079 buffer_ptr = op->common.value.string;
0080 if (!buffer_ptr) {
0081
0082
0083
0084 return_ACPI_STATUS(AE_OK);
0085 }
0086 } else {
0087
0088
0089 buffer_ptr = ACPI_CAST_PTR(char, &op->named.name);
0090 }
0091 } else {
0092
0093
0094 buffer_ptr =
0095 acpi_ps_get_next_namestring(&walk_state->parser_state);
0096 }
0097
0098
0099
0100 object_type = walk_state->op_info->object_type;
0101
0102 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
0103 "State=%p Op=%p Type=%X\n", walk_state, op,
0104 object_type));
0105
0106 switch (walk_state->opcode) {
0107 case AML_FIELD_OP:
0108 case AML_BANK_FIELD_OP:
0109 case AML_INDEX_FIELD_OP:
0110
0111 node = NULL;
0112 status = AE_OK;
0113 break;
0114
0115 case AML_INT_NAMEPATH_OP:
0116
0117
0118
0119
0120
0121 status =
0122 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
0123 object_type, ACPI_IMODE_EXECUTE,
0124 ACPI_NS_SEARCH_PARENT, walk_state, &(node));
0125 break;
0126
0127 case AML_SCOPE_OP:
0128
0129
0130
0131 if (op && (op->named.node == acpi_gbl_root_node)) {
0132 node = op->named.node;
0133
0134 status =
0135 acpi_ds_scope_stack_push(node, object_type,
0136 walk_state);
0137 if (ACPI_FAILURE(status)) {
0138 return_ACPI_STATUS(status);
0139 }
0140 } else {
0141
0142
0143
0144
0145
0146 status =
0147 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
0148 object_type, ACPI_IMODE_EXECUTE,
0149 ACPI_NS_SEARCH_PARENT, walk_state,
0150 &(node));
0151 if (ACPI_FAILURE(status)) {
0152 #ifdef ACPI_ASL_COMPILER
0153 if (status == AE_NOT_FOUND) {
0154 status = AE_OK;
0155 } else {
0156 ACPI_ERROR_NAMESPACE(walk_state->
0157 scope_info,
0158 buffer_ptr,
0159 status);
0160 }
0161 #else
0162 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
0163 buffer_ptr, status);
0164 #endif
0165 return_ACPI_STATUS(status);
0166 }
0167 }
0168
0169
0170
0171
0172
0173 switch (node->type) {
0174 case ACPI_TYPE_ANY:
0175 case ACPI_TYPE_LOCAL_SCOPE:
0176 case ACPI_TYPE_DEVICE:
0177 case ACPI_TYPE_POWER:
0178 case ACPI_TYPE_PROCESSOR:
0179 case ACPI_TYPE_THERMAL:
0180
0181
0182 break;
0183
0184 case ACPI_TYPE_INTEGER:
0185 case ACPI_TYPE_STRING:
0186 case ACPI_TYPE_BUFFER:
0187
0188
0189
0190
0191
0192
0193
0194
0195 ACPI_WARNING((AE_INFO,
0196 "Type override - [%4.4s] had invalid type (%s) "
0197 "for Scope operator, changed to type ANY",
0198 acpi_ut_get_node_name(node),
0199 acpi_ut_get_type_name(node->type)));
0200
0201 node->type = ACPI_TYPE_ANY;
0202 walk_state->scope_info->common.value = ACPI_TYPE_ANY;
0203 break;
0204
0205 case ACPI_TYPE_METHOD:
0206
0207
0208
0209
0210
0211 if ((node == acpi_gbl_root_node) &&
0212 (walk_state->
0213 parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
0214 break;
0215 }
0216
0217 ACPI_FALLTHROUGH;
0218
0219 default:
0220
0221
0222
0223 ACPI_ERROR((AE_INFO,
0224 "Invalid type (%s) for target of "
0225 "Scope operator [%4.4s] (Cannot override)",
0226 acpi_ut_get_type_name(node->type),
0227 acpi_ut_get_node_name(node)));
0228
0229 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
0230 }
0231 break;
0232
0233 default:
0234
0235
0236
0237 if (op && op->common.node) {
0238
0239
0240
0241 node = op->common.node;
0242
0243 if (acpi_ns_opens_scope(object_type)) {
0244 status =
0245 acpi_ds_scope_stack_push(node, object_type,
0246 walk_state);
0247 if (ACPI_FAILURE(status)) {
0248 return_ACPI_STATUS(status);
0249 }
0250 }
0251
0252 return_ACPI_STATUS(AE_OK);
0253 }
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263 if (walk_state->deferred_node) {
0264
0265
0266
0267 node = walk_state->deferred_node;
0268 status = AE_OK;
0269 break;
0270 }
0271
0272 flags = ACPI_NS_NO_UPSEARCH;
0273 if (walk_state->pass_number == ACPI_IMODE_EXECUTE) {
0274
0275
0276
0277 flags |= ACPI_NS_ERROR_IF_FOUND;
0278
0279 if (!
0280 (walk_state->
0281 parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
0282 flags |= ACPI_NS_TEMPORARY;
0283 }
0284 }
0285 #ifdef ACPI_ASL_COMPILER
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297 if (walk_state->opcode == AML_EXTERNAL_OP) {
0298 flags |= ACPI_NS_DONT_OPEN_SCOPE;
0299 }
0300 #endif
0301
0302
0303
0304
0305
0306 if (walk_state->op_info->flags & AML_NAMED) {
0307 flags |= ACPI_NS_PREFIX_MUST_EXIST;
0308 }
0309
0310
0311
0312 status =
0313 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
0314 object_type, ACPI_IMODE_LOAD_PASS2, flags,
0315 walk_state, &node);
0316
0317 if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) {
0318 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
0319 "***New Node [%4.4s] %p is temporary\n",
0320 acpi_ut_get_node_name(node), node));
0321 }
0322 break;
0323 }
0324
0325 if (ACPI_FAILURE(status)) {
0326 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
0327 buffer_ptr, status);
0328 return_ACPI_STATUS(status);
0329 }
0330
0331 if (!op) {
0332
0333
0334
0335 op = acpi_ps_alloc_op(walk_state->opcode, walk_state->aml);
0336 if (!op) {
0337 return_ACPI_STATUS(AE_NO_MEMORY);
0338 }
0339
0340
0341
0342 if (node) {
0343 op->named.name = node->name.integer;
0344 }
0345 *out_op = op;
0346 }
0347
0348
0349
0350
0351
0352 op->common.node = node;
0353 return_ACPI_STATUS(status);
0354 }
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369 acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
0370 {
0371 union acpi_parse_object *op;
0372 acpi_status status = AE_OK;
0373 acpi_object_type object_type;
0374 struct acpi_namespace_node *node;
0375 union acpi_parse_object *arg;
0376 struct acpi_namespace_node *new_node;
0377 u32 i;
0378 u8 region_space;
0379 #ifdef ACPI_EXEC_APP
0380 union acpi_operand_object *obj_desc;
0381 char *namepath;
0382 #endif
0383
0384 ACPI_FUNCTION_TRACE(ds_load2_end_op);
0385
0386 op = walk_state->op;
0387 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
0388 walk_state->op_info->name, op, walk_state));
0389
0390
0391
0392 if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
0393 return_ACPI_STATUS(AE_OK);
0394 }
0395
0396 if (op->common.aml_opcode == AML_SCOPE_OP) {
0397 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
0398 "Ending scope Op=%p State=%p\n", op,
0399 walk_state));
0400 }
0401
0402 object_type = walk_state->op_info->object_type;
0403
0404
0405
0406
0407
0408 node = op->common.node;
0409
0410
0411
0412
0413
0414 walk_state->operands[0] = (void *)node;
0415 walk_state->num_operands = 1;
0416
0417
0418
0419 if (acpi_ns_opens_scope(object_type) &&
0420 (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
0421 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
0422 "(%s) Popping scope for Op %p\n",
0423 acpi_ut_get_type_name(object_type), op));
0424
0425 status = acpi_ds_scope_stack_pop(walk_state);
0426 if (ACPI_FAILURE(status)) {
0427 goto cleanup;
0428 }
0429 }
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
0460 "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
0461 acpi_ps_get_opcode_name(op->common.aml_opcode),
0462 walk_state, op, node));
0463
0464
0465
0466 arg = op->common.value.arg;
0467
0468 switch (walk_state->op_info->type) {
0469
0470 case AML_TYPE_CREATE_FIELD:
0471
0472
0473
0474
0475 status = acpi_ds_create_buffer_field(op, walk_state);
0476 if (ACPI_FAILURE(status)) {
0477 ACPI_EXCEPTION((AE_INFO, status,
0478 "CreateBufferField failure"));
0479 goto cleanup;
0480 }
0481 break;
0482
0483 case AML_TYPE_NAMED_FIELD:
0484
0485
0486
0487 if (walk_state->method_node) {
0488 status = acpi_ds_init_field_objects(op, walk_state);
0489 }
0490
0491 switch (op->common.aml_opcode) {
0492 case AML_INDEX_FIELD_OP:
0493
0494 status =
0495 acpi_ds_create_index_field(op,
0496 (acpi_handle)arg->common.
0497 node, walk_state);
0498 break;
0499
0500 case AML_BANK_FIELD_OP:
0501
0502 status =
0503 acpi_ds_create_bank_field(op, arg->common.node,
0504 walk_state);
0505 break;
0506
0507 case AML_FIELD_OP:
0508
0509 status =
0510 acpi_ds_create_field(op, arg->common.node,
0511 walk_state);
0512 break;
0513
0514 default:
0515
0516
0517 break;
0518 }
0519 break;
0520
0521 case AML_TYPE_NAMED_SIMPLE:
0522
0523 status = acpi_ds_create_operands(walk_state, arg);
0524 if (ACPI_FAILURE(status)) {
0525 goto cleanup;
0526 }
0527
0528 switch (op->common.aml_opcode) {
0529 case AML_PROCESSOR_OP:
0530
0531 status = acpi_ex_create_processor(walk_state);
0532 break;
0533
0534 case AML_POWER_RESOURCE_OP:
0535
0536 status = acpi_ex_create_power_resource(walk_state);
0537 break;
0538
0539 case AML_MUTEX_OP:
0540
0541 status = acpi_ex_create_mutex(walk_state);
0542 break;
0543
0544 case AML_EVENT_OP:
0545
0546 status = acpi_ex_create_event(walk_state);
0547 break;
0548
0549 case AML_ALIAS_OP:
0550
0551 status = acpi_ex_create_alias(walk_state);
0552 break;
0553
0554 default:
0555
0556
0557
0558 status = AE_OK;
0559 goto cleanup;
0560 }
0561
0562
0563
0564 for (i = 1; i < walk_state->num_operands; i++) {
0565 acpi_ut_remove_reference(walk_state->operands[i]);
0566 walk_state->operands[i] = NULL;
0567 }
0568
0569 break;
0570
0571 case AML_TYPE_NAMED_COMPLEX:
0572
0573 switch (op->common.aml_opcode) {
0574 case AML_REGION_OP:
0575 case AML_DATA_REGION_OP:
0576
0577 if (op->common.aml_opcode == AML_REGION_OP) {
0578 region_space = (acpi_adr_space_type)
0579 ((op->common.value.arg)->common.value.
0580 integer);
0581 } else {
0582 region_space = ACPI_ADR_SPACE_DATA_TABLE;
0583 }
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597 if (walk_state->method_node) {
0598
0599
0600
0601
0602 status = acpi_ex_create_region(op->named.data,
0603 op->named.length,
0604 region_space,
0605 walk_state);
0606 if (ACPI_FAILURE(status)) {
0607 return_ACPI_STATUS(status);
0608 }
0609 }
0610
0611 status =
0612 acpi_ev_initialize_region
0613 (acpi_ns_get_attached_object(node));
0614 break;
0615
0616 case AML_NAME_OP:
0617
0618 status = acpi_ds_create_node(walk_state, node, op);
0619 if (ACPI_FAILURE(status)) {
0620 goto cleanup;
0621 }
0622 #ifdef ACPI_EXEC_APP
0623
0624
0625
0626
0627 namepath = acpi_ns_get_external_pathname(node);
0628 status = ae_lookup_init_file_entry(namepath, &obj_desc);
0629 if (ACPI_SUCCESS(status)) {
0630
0631
0632
0633 if (node->object) {
0634 acpi_ns_detach_object(node);
0635 }
0636 acpi_ns_attach_object(node, obj_desc,
0637 obj_desc->common.type);
0638 }
0639 ACPI_FREE(namepath);
0640 status = AE_OK;
0641 #endif
0642 break;
0643
0644 case AML_METHOD_OP:
0645
0646
0647
0648
0649
0650
0651
0652
0653 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
0654 "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
0655 walk_state, op, op->named.node));
0656
0657 if (!acpi_ns_get_attached_object(op->named.node)) {
0658 walk_state->operands[0] =
0659 ACPI_CAST_PTR(void, op->named.node);
0660 walk_state->num_operands = 1;
0661
0662 status =
0663 acpi_ds_create_operands(walk_state,
0664 op->common.value.
0665 arg);
0666 if (ACPI_SUCCESS(status)) {
0667 status =
0668 acpi_ex_create_method(op->named.
0669 data,
0670 op->named.
0671 length,
0672 walk_state);
0673 }
0674
0675 walk_state->operands[0] = NULL;
0676 walk_state->num_operands = 0;
0677
0678 if (ACPI_FAILURE(status)) {
0679 return_ACPI_STATUS(status);
0680 }
0681 }
0682 break;
0683
0684 default:
0685
0686
0687 break;
0688 }
0689 break;
0690
0691 case AML_CLASS_INTERNAL:
0692
0693
0694 break;
0695
0696 case AML_CLASS_METHOD_CALL:
0697
0698 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
0699 "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
0700 walk_state, op, node));
0701
0702
0703
0704
0705 status =
0706 acpi_ns_lookup(walk_state->scope_info,
0707 arg->common.value.string, ACPI_TYPE_ANY,
0708 ACPI_IMODE_LOAD_PASS2,
0709 ACPI_NS_SEARCH_PARENT |
0710 ACPI_NS_DONT_OPEN_SCOPE, walk_state,
0711 &(new_node));
0712 if (ACPI_SUCCESS(status)) {
0713
0714
0715
0716
0717
0718 if (new_node->type != ACPI_TYPE_METHOD) {
0719 status = AE_AML_OPERAND_TYPE;
0720 }
0721
0722
0723
0724
0725
0726 op->common.node = new_node;
0727 } else {
0728 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
0729 arg->common.value.string, status);
0730 }
0731 break;
0732
0733 default:
0734
0735 break;
0736 }
0737
0738 cleanup:
0739
0740
0741
0742 walk_state->operands[0] = NULL;
0743 walk_state->num_operands = 0;
0744 return_ACPI_STATUS(status);
0745 }