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 "acconvert.h"
0015 #include "acnamesp.h"
0016
0017 #define _COMPONENT ACPI_PARSER
0018 ACPI_MODULE_NAME("psobject")
0019
0020
0021 static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
0036 {
0037 ACPI_ERROR_ONLY(u32 aml_offset);
0038
0039 ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
0040
0041 walk_state->aml = walk_state->parser_state.aml;
0042 walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
0043
0044
0045
0046
0047
0048
0049
0050 walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
0051
0052 switch (walk_state->op_info->class) {
0053 case AML_CLASS_ASCII:
0054 case AML_CLASS_PREFIX:
0055
0056
0057
0058
0059 walk_state->opcode = AML_INT_NAMEPATH_OP;
0060 walk_state->arg_types = ARGP_NAMESTRING;
0061 break;
0062
0063 case AML_CLASS_UNKNOWN:
0064
0065
0066
0067 if (walk_state->pass_number == 2) {
0068 ACPI_ERROR_ONLY(aml_offset =
0069 (u32)ACPI_PTR_DIFF(walk_state->aml,
0070 walk_state->
0071 parser_state.
0072 aml_start));
0073
0074 ACPI_ERROR((AE_INFO,
0075 "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
0076 walk_state->opcode,
0077 (u32)(aml_offset +
0078 sizeof(struct acpi_table_header))));
0079
0080 ACPI_DUMP_BUFFER((walk_state->parser_state.aml - 16),
0081 48);
0082
0083 #ifdef ACPI_ASL_COMPILER
0084
0085
0086
0087
0088 acpi_os_printf
0089 ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
0090 walk_state->opcode,
0091 (u32)(aml_offset +
0092 sizeof(struct acpi_table_header)));
0093
0094 ACPI_ERROR((AE_INFO,
0095 "Aborting disassembly, AML byte code is corrupt"));
0096
0097
0098
0099 acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
0100 aml - 16), 48, DB_BYTE_DISPLAY,
0101 (aml_offset +
0102 sizeof(struct acpi_table_header) -
0103 16));
0104 acpi_os_printf(" */\n");
0105
0106
0107
0108
0109
0110
0111
0112 return_ACPI_STATUS(AE_AML_BAD_OPCODE);
0113 #endif
0114 }
0115
0116
0117
0118 walk_state->parser_state.aml++;
0119 if (walk_state->opcode > 0xFF) {
0120 walk_state->parser_state.aml++;
0121 }
0122
0123 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
0124
0125 default:
0126
0127
0128
0129 walk_state->parser_state.aml +=
0130 acpi_ps_get_opcode_size(walk_state->opcode);
0131 walk_state->arg_types = walk_state->op_info->parse_args;
0132 break;
0133 }
0134
0135 return_ACPI_STATUS(AE_OK);
0136 }
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153 acpi_status
0154 acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
0155 u8 *aml_op_start,
0156 union acpi_parse_object *unnamed_op,
0157 union acpi_parse_object **op)
0158 {
0159 acpi_status status = AE_OK;
0160 union acpi_parse_object *arg = NULL;
0161
0162 ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
0163
0164 unnamed_op->common.value.arg = NULL;
0165 unnamed_op->common.arg_list_length = 0;
0166 unnamed_op->common.aml_opcode = walk_state->opcode;
0167
0168
0169
0170
0171
0172 while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
0173 (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) {
0174 ASL_CV_CAPTURE_COMMENTS(walk_state);
0175 status =
0176 acpi_ps_get_next_arg(walk_state,
0177 &(walk_state->parser_state),
0178 GET_CURRENT_ARG_TYPE(walk_state->
0179 arg_types), &arg);
0180 if (ACPI_FAILURE(status)) {
0181 return_ACPI_STATUS(status);
0182 }
0183
0184 acpi_ps_append_arg(unnamed_op, arg);
0185 INCREMENT_ARG_LIST(walk_state->arg_types);
0186 }
0187
0188
0189
0190 ASL_CV_CAPTURE_COMMENTS(walk_state);
0191
0192 #ifdef ACPI_ASL_COMPILER
0193 if (acpi_gbl_current_inline_comment != NULL) {
0194 unnamed_op->common.name_comment =
0195 acpi_gbl_current_inline_comment;
0196 acpi_gbl_current_inline_comment = NULL;
0197 }
0198 #endif
0199
0200
0201
0202
0203 if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
0204 return_ACPI_STATUS(AE_AML_NO_OPERAND);
0205 }
0206
0207
0208
0209 INCREMENT_ARG_LIST(walk_state->arg_types);
0210
0211
0212
0213
0214
0215 walk_state->op = NULL;
0216
0217 status = walk_state->descending_callback(walk_state, op);
0218 if (ACPI_FAILURE(status)) {
0219 if (status != AE_CTRL_TERMINATE) {
0220 ACPI_EXCEPTION((AE_INFO, status,
0221 "During name lookup/catalog"));
0222 }
0223 return_ACPI_STATUS(status);
0224 }
0225
0226 if (!*op) {
0227 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
0228 }
0229
0230 status = acpi_ps_next_parse_state(walk_state, *op, status);
0231 if (ACPI_FAILURE(status)) {
0232 if (status == AE_CTRL_PENDING) {
0233 status = AE_CTRL_PARSE_PENDING;
0234 }
0235 return_ACPI_STATUS(status);
0236 }
0237
0238 acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
0239
0240 #ifdef ACPI_ASL_COMPILER
0241
0242
0243
0244 (*op)->common.inline_comment = unnamed_op->common.inline_comment;
0245 (*op)->common.end_node_comment = unnamed_op->common.end_node_comment;
0246 (*op)->common.close_brace_comment =
0247 unnamed_op->common.close_brace_comment;
0248 (*op)->common.name_comment = unnamed_op->common.name_comment;
0249 (*op)->common.comment_list = unnamed_op->common.comment_list;
0250 (*op)->common.end_blk_comment = unnamed_op->common.end_blk_comment;
0251 (*op)->common.cv_filename = unnamed_op->common.cv_filename;
0252 (*op)->common.cv_parent_filename =
0253 unnamed_op->common.cv_parent_filename;
0254 (*op)->named.aml = unnamed_op->common.aml;
0255
0256 unnamed_op->common.inline_comment = NULL;
0257 unnamed_op->common.end_node_comment = NULL;
0258 unnamed_op->common.close_brace_comment = NULL;
0259 unnamed_op->common.name_comment = NULL;
0260 unnamed_op->common.comment_list = NULL;
0261 unnamed_op->common.end_blk_comment = NULL;
0262 #endif
0263
0264 if ((*op)->common.aml_opcode == AML_REGION_OP ||
0265 (*op)->common.aml_opcode == AML_DATA_REGION_OP) {
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276 (*op)->named.data = aml_op_start;
0277 (*op)->named.length = 0;
0278 }
0279
0280 return_ACPI_STATUS(AE_OK);
0281 }
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297 acpi_status
0298 acpi_ps_create_op(struct acpi_walk_state *walk_state,
0299 u8 *aml_op_start, union acpi_parse_object **new_op)
0300 {
0301 acpi_status status = AE_OK;
0302 union acpi_parse_object *op;
0303 union acpi_parse_object *named_op = NULL;
0304 union acpi_parse_object *parent_scope;
0305 u8 argument_count;
0306 const struct acpi_opcode_info *op_info;
0307
0308 ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
0309
0310 status = acpi_ps_get_aml_opcode(walk_state);
0311 if (status == AE_CTRL_PARSE_CONTINUE) {
0312 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
0313 }
0314 if (ACPI_FAILURE(status)) {
0315 return_ACPI_STATUS(status);
0316 }
0317
0318
0319
0320 walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
0321 op = acpi_ps_alloc_op(walk_state->opcode, aml_op_start);
0322 if (!op) {
0323 return_ACPI_STATUS(AE_NO_MEMORY);
0324 }
0325
0326 if (walk_state->op_info->flags & AML_NAMED) {
0327 status =
0328 acpi_ps_build_named_op(walk_state, aml_op_start, op,
0329 &named_op);
0330 acpi_ps_free_op(op);
0331
0332 #ifdef ACPI_ASL_COMPILER
0333 if (acpi_gbl_disasm_flag
0334 && walk_state->opcode == AML_EXTERNAL_OP
0335 && status == AE_NOT_FOUND) {
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346 walk_state->aml = walk_state->parser_state.aml + 2;
0347 walk_state->parser_state.aml = walk_state->aml;
0348 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
0349 }
0350 #endif
0351 if (ACPI_FAILURE(status)) {
0352 return_ACPI_STATUS(status);
0353 }
0354
0355 *new_op = named_op;
0356 return_ACPI_STATUS(AE_OK);
0357 }
0358
0359
0360
0361 if (walk_state->op_info->flags & AML_CREATE) {
0362
0363
0364
0365
0366 op->named.data = aml_op_start;
0367 op->named.length = 0;
0368 }
0369
0370 if (walk_state->opcode == AML_BANK_FIELD_OP) {
0371
0372
0373
0374
0375 op->named.data = aml_op_start;
0376 op->named.length = 0;
0377 }
0378
0379 parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
0380 acpi_ps_append_arg(parent_scope, op);
0381
0382 if (parent_scope) {
0383 op_info =
0384 acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
0385 if (op_info->flags & AML_HAS_TARGET) {
0386 argument_count =
0387 acpi_ps_get_argument_count(op_info->type);
0388 if (parent_scope->common.arg_list_length >
0389 argument_count) {
0390 op->common.flags |= ACPI_PARSEOP_TARGET;
0391 }
0392 }
0393
0394
0395
0396
0397
0398 else if ((parent_scope->common.aml_opcode == AML_INCREMENT_OP)
0399 || (parent_scope->common.aml_opcode ==
0400 AML_DECREMENT_OP)) {
0401 op->common.flags |= ACPI_PARSEOP_TARGET;
0402 }
0403 }
0404
0405 if (walk_state->descending_callback != NULL) {
0406
0407
0408
0409
0410 walk_state->op = *new_op = op;
0411
0412 status = walk_state->descending_callback(walk_state, &op);
0413 status = acpi_ps_next_parse_state(walk_state, op, status);
0414 if (status == AE_CTRL_PENDING) {
0415 status = AE_CTRL_PARSE_PENDING;
0416 }
0417 }
0418
0419 return_ACPI_STATUS(status);
0420 }
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436 acpi_status
0437 acpi_ps_complete_op(struct acpi_walk_state *walk_state,
0438 union acpi_parse_object **op, acpi_status status)
0439 {
0440 acpi_status status2;
0441
0442 ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
0443
0444
0445
0446
0447 walk_state->parser_state.scope->parse_scope.arg_count--;
0448
0449
0450
0451 status2 = acpi_ps_complete_this_op(walk_state, *op);
0452 if (ACPI_FAILURE(status2)) {
0453 return_ACPI_STATUS(status2);
0454 }
0455
0456 *op = NULL;
0457
0458 switch (status) {
0459 case AE_OK:
0460
0461 break;
0462
0463 case AE_CTRL_TRANSFER:
0464
0465
0466
0467 walk_state->prev_op = NULL;
0468 walk_state->prev_arg_types = walk_state->arg_types;
0469 return_ACPI_STATUS(status);
0470
0471 case AE_CTRL_END:
0472
0473 acpi_ps_pop_scope(&(walk_state->parser_state), op,
0474 &walk_state->arg_types,
0475 &walk_state->arg_count);
0476
0477 if (*op) {
0478 walk_state->op = *op;
0479 walk_state->op_info =
0480 acpi_ps_get_opcode_info((*op)->common.aml_opcode);
0481 walk_state->opcode = (*op)->common.aml_opcode;
0482
0483 status = walk_state->ascending_callback(walk_state);
0484 (void)acpi_ps_next_parse_state(walk_state, *op, status);
0485
0486 status2 = acpi_ps_complete_this_op(walk_state, *op);
0487 if (ACPI_FAILURE(status2)) {
0488 return_ACPI_STATUS(status2);
0489 }
0490 }
0491
0492 break;
0493
0494 case AE_CTRL_BREAK:
0495 case AE_CTRL_CONTINUE:
0496
0497
0498
0499 while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
0500 acpi_ps_pop_scope(&(walk_state->parser_state), op,
0501 &walk_state->arg_types,
0502 &walk_state->arg_count);
0503 }
0504
0505
0506
0507 walk_state->op = *op;
0508 walk_state->op_info =
0509 acpi_ps_get_opcode_info((*op)->common.aml_opcode);
0510 walk_state->opcode = (*op)->common.aml_opcode;
0511
0512 status = walk_state->ascending_callback(walk_state);
0513 (void)acpi_ps_next_parse_state(walk_state, *op, status);
0514
0515 status2 = acpi_ps_complete_this_op(walk_state, *op);
0516 if (ACPI_FAILURE(status2)) {
0517 return_ACPI_STATUS(status2);
0518 }
0519
0520 break;
0521
0522 case AE_CTRL_TERMINATE:
0523
0524
0525 do {
0526 if (*op) {
0527 status2 =
0528 acpi_ps_complete_this_op(walk_state, *op);
0529 if (ACPI_FAILURE(status2)) {
0530 return_ACPI_STATUS(status2);
0531 }
0532
0533 acpi_ut_delete_generic_state
0534 (acpi_ut_pop_generic_state
0535 (&walk_state->control_state));
0536 }
0537
0538 acpi_ps_pop_scope(&(walk_state->parser_state), op,
0539 &walk_state->arg_types,
0540 &walk_state->arg_count);
0541
0542 } while (*op);
0543
0544 return_ACPI_STATUS(AE_OK);
0545
0546 default:
0547
0548 do {
0549 if (*op) {
0550
0551
0552
0553
0554
0555 if (((*op)->common.aml_opcode == AML_REGION_OP)
0556 || ((*op)->common.aml_opcode ==
0557 AML_DATA_REGION_OP)) {
0558 acpi_ns_delete_children((*op)->common.
0559 node);
0560 acpi_ns_remove_node((*op)->common.node);
0561 (*op)->common.node = NULL;
0562 acpi_ps_delete_parse_tree(*op);
0563 }
0564
0565 status2 =
0566 acpi_ps_complete_this_op(walk_state, *op);
0567 if (ACPI_FAILURE(status2)) {
0568 return_ACPI_STATUS(status2);
0569 }
0570 }
0571
0572 acpi_ps_pop_scope(&(walk_state->parser_state), op,
0573 &walk_state->arg_types,
0574 &walk_state->arg_count);
0575
0576 } while (*op);
0577
0578 #if 0
0579
0580
0581
0582 if (*op == NULL) {
0583 acpi_ps_pop_scope(parser_state, op,
0584 &walk_state->arg_types,
0585 &walk_state->arg_count);
0586 }
0587 #endif
0588 walk_state->prev_op = NULL;
0589 walk_state->prev_arg_types = walk_state->arg_types;
0590
0591 if (walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL) {
0592
0593
0594
0595
0596
0597
0598
0599
0600 ACPI_INFO(("Ignoring error and continuing table load"));
0601 return_ACPI_STATUS(AE_OK);
0602 }
0603 return_ACPI_STATUS(status);
0604 }
0605
0606
0607
0608 if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
0609 acpi_ps_pop_scope(&(walk_state->parser_state), op,
0610 &walk_state->arg_types,
0611 &walk_state->arg_count);
0612 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
0613 } else {
0614 *op = NULL;
0615 }
0616
0617 return_ACPI_STATUS(AE_OK);
0618 }
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635 acpi_status
0636 acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
0637 union acpi_parse_object *op, acpi_status status)
0638 {
0639 acpi_status status2;
0640
0641 ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
0642
0643
0644
0645
0646
0647
0648
0649 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
0650 op));
0651 do {
0652 if (op) {
0653 if (walk_state->ascending_callback != NULL) {
0654 walk_state->op = op;
0655 walk_state->op_info =
0656 acpi_ps_get_opcode_info(op->common.
0657 aml_opcode);
0658 walk_state->opcode = op->common.aml_opcode;
0659
0660 status =
0661 walk_state->ascending_callback(walk_state);
0662 status =
0663 acpi_ps_next_parse_state(walk_state, op,
0664 status);
0665 if (status == AE_CTRL_PENDING) {
0666 status =
0667 acpi_ps_complete_op(walk_state, &op,
0668 AE_OK);
0669 if (ACPI_FAILURE(status)) {
0670 return_ACPI_STATUS(status);
0671 }
0672 }
0673
0674 if (status == AE_CTRL_TERMINATE) {
0675 status = AE_OK;
0676
0677
0678 do {
0679 if (op) {
0680 status2 =
0681 acpi_ps_complete_this_op
0682 (walk_state, op);
0683 if (ACPI_FAILURE
0684 (status2)) {
0685 return_ACPI_STATUS
0686 (status2);
0687 }
0688 }
0689
0690 acpi_ps_pop_scope(&
0691 (walk_state->
0692 parser_state),
0693 &op,
0694 &walk_state->
0695 arg_types,
0696 &walk_state->
0697 arg_count);
0698
0699 } while (op);
0700
0701 return_ACPI_STATUS(status);
0702 }
0703
0704 else if (ACPI_FAILURE(status)) {
0705
0706
0707
0708 (void)
0709 acpi_ps_complete_this_op(walk_state,
0710 op);
0711 return_ACPI_STATUS(status);
0712 }
0713 }
0714
0715 status2 = acpi_ps_complete_this_op(walk_state, op);
0716 if (ACPI_FAILURE(status2)) {
0717 return_ACPI_STATUS(status2);
0718 }
0719 }
0720
0721 acpi_ps_pop_scope(&(walk_state->parser_state), &op,
0722 &walk_state->arg_types,
0723 &walk_state->arg_count);
0724
0725 } while (op);
0726
0727 return_ACPI_STATUS(status);
0728 }