linux/drivers/acpi/acpica/psloop.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Module Name: psloop - Main AML parse loop
   4 *
   5 *****************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2008, Intel Corp.
   9 * All rights reserved.
  10 *
  11 * Redistribution and use in source and binary forms, with or without
  12 * modification, are permitted provided that the following conditions
  13 * are met:
  14 * 1. Redistributions of source code must retain the above copyright
  15 *    notice, this list of conditions, and the following disclaimer,
  16 *    without modification.
  17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18 *    substantially similar to the "NO WARRANTY" disclaimer below
  19 *    ("Disclaimer") and any redistribution must be conditioned upon
  20 *    including a substantially similar Disclaimer requirement for further
  21 *    binary redistribution.
  22 * 3. Neither the names of the above-listed copyright holders nor the names
  23 *    of any contributors may be used to endorse or promote products derived
  24 *    from this software without specific prior written permission.
  25 *
  26 * Alternatively, this software may be distributed under the terms of the
  27 * GNU General Public License ("GPL") version 2 as published by the Free
  28 * Software Foundation.
  29 *
  30 * NO WARRANTY
  31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41 * POSSIBILITY OF SUCH DAMAGES.
  42 */
  43
  44/*
  45 * Parse the AML and build an operation tree as most interpreters, (such as
  46 * Perl) do. Parsing is done by hand rather than with a YACC generated parser
  47 * to tightly constrain stack and dynamic memory usage. Parsing is kept
  48 * flexible and the code fairly compact by parsing based on a list of AML
  49 * opcode templates in aml_op_info[].
  50 */
  51
  52#include <acpi/acpi.h>
  53#include "accommon.h"
  54#include "acparser.h"
  55#include "acdispat.h"
  56#include "amlcode.h"
  57
  58#define _COMPONENT          ACPI_PARSER
  59ACPI_MODULE_NAME("psloop")
  60
  61static u32 acpi_gbl_depth = 0;
  62
  63/* Local prototypes */
  64
  65static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
  66
  67static acpi_status
  68acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
  69                       u8 * aml_op_start,
  70                       union acpi_parse_object *unnamed_op,
  71                       union acpi_parse_object **op);
  72
  73static acpi_status
  74acpi_ps_create_op(struct acpi_walk_state *walk_state,
  75                  u8 * aml_op_start, union acpi_parse_object **new_op);
  76
  77static acpi_status
  78acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
  79                      u8 * aml_op_start, union acpi_parse_object *op);
  80
  81static acpi_status
  82acpi_ps_complete_op(struct acpi_walk_state *walk_state,
  83                    union acpi_parse_object **op, acpi_status status);
  84
  85static acpi_status
  86acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
  87                          union acpi_parse_object *op, acpi_status status);
  88
  89static void
  90acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id);
  91
  92/*******************************************************************************
  93 *
  94 * FUNCTION:    acpi_ps_get_aml_opcode
  95 *
  96 * PARAMETERS:  walk_state          - Current state
  97 *
  98 * RETURN:      Status
  99 *
 100 * DESCRIPTION: Extract the next AML opcode from the input stream.
 101 *
 102 ******************************************************************************/
 103
 104static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
 105{
 106
 107        ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
 108
 109        walk_state->aml_offset =
 110            (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml,
 111                                walk_state->parser_state.aml_start);
 112        walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
 113
 114        /*
 115         * First cut to determine what we have found:
 116         * 1) A valid AML opcode
 117         * 2) A name string
 118         * 3) An unknown/invalid opcode
 119         */
 120        walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
 121
 122        switch (walk_state->op_info->class) {
 123        case AML_CLASS_ASCII:
 124        case AML_CLASS_PREFIX:
 125                /*
 126                 * Starts with a valid prefix or ASCII char, this is a name
 127                 * string. Convert the bare name string to a namepath.
 128                 */
 129                walk_state->opcode = AML_INT_NAMEPATH_OP;
 130                walk_state->arg_types = ARGP_NAMESTRING;
 131                break;
 132
 133        case AML_CLASS_UNKNOWN:
 134
 135                /* The opcode is unrecognized. Just skip unknown opcodes */
 136
 137                ACPI_ERROR((AE_INFO,
 138                            "Found unknown opcode %X at AML address %p offset %X, ignoring",
 139                            walk_state->opcode, walk_state->parser_state.aml,
 140                            walk_state->aml_offset));
 141
 142                ACPI_DUMP_BUFFER(walk_state->parser_state.aml, 128);
 143
 144                /* Assume one-byte bad opcode */
 145
 146                walk_state->parser_state.aml++;
 147                return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
 148
 149        default:
 150
 151                /* Found opcode info, this is a normal opcode */
 152
 153                walk_state->parser_state.aml +=
 154                    acpi_ps_get_opcode_size(walk_state->opcode);
 155                walk_state->arg_types = walk_state->op_info->parse_args;
 156                break;
 157        }
 158
 159        return_ACPI_STATUS(AE_OK);
 160}
 161
 162/*******************************************************************************
 163 *
 164 * FUNCTION:    acpi_ps_build_named_op
 165 *
 166 * PARAMETERS:  walk_state          - Current state
 167 *              aml_op_start        - Begin of named Op in AML
 168 *              unnamed_op          - Early Op (not a named Op)
 169 *              Op                  - Returned Op
 170 *
 171 * RETURN:      Status
 172 *
 173 * DESCRIPTION: Parse a named Op
 174 *
 175 ******************************************************************************/
 176
 177static acpi_status
 178acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
 179                       u8 * aml_op_start,
 180                       union acpi_parse_object *unnamed_op,
 181                       union acpi_parse_object **op)
 182{
 183        acpi_status status = AE_OK;
 184        union acpi_parse_object *arg = NULL;
 185
 186        ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
 187
 188        unnamed_op->common.value.arg = NULL;
 189        unnamed_op->common.arg_list_length = 0;
 190        unnamed_op->common.aml_opcode = walk_state->opcode;
 191
 192        /*
 193         * Get and append arguments until we find the node that contains
 194         * the name (the type ARGP_NAME).
 195         */
 196        while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
 197               (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) {
 198                status =
 199                    acpi_ps_get_next_arg(walk_state,
 200                                         &(walk_state->parser_state),
 201                                         GET_CURRENT_ARG_TYPE(walk_state->
 202                                                              arg_types), &arg);
 203                if (ACPI_FAILURE(status)) {
 204                        return_ACPI_STATUS(status);
 205                }
 206
 207                acpi_ps_append_arg(unnamed_op, arg);
 208                INCREMENT_ARG_LIST(walk_state->arg_types);
 209        }
 210
 211        /*
 212         * Make sure that we found a NAME and didn't run out of arguments
 213         */
 214        if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
 215                return_ACPI_STATUS(AE_AML_NO_OPERAND);
 216        }
 217
 218        /* We know that this arg is a name, move to next arg */
 219
 220        INCREMENT_ARG_LIST(walk_state->arg_types);
 221
 222        /*
 223         * Find the object. This will either insert the object into
 224         * the namespace or simply look it up
 225         */
 226        walk_state->op = NULL;
 227
 228        status = walk_state->descending_callback(walk_state, op);
 229        if (ACPI_FAILURE(status)) {
 230                ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog"));
 231                return_ACPI_STATUS(status);
 232        }
 233
 234        if (!*op) {
 235                return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
 236        }
 237
 238        status = acpi_ps_next_parse_state(walk_state, *op, status);
 239        if (ACPI_FAILURE(status)) {
 240                if (status == AE_CTRL_PENDING) {
 241                        return_ACPI_STATUS(AE_CTRL_PARSE_PENDING);
 242                }
 243                return_ACPI_STATUS(status);
 244        }
 245
 246        acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
 247        acpi_gbl_depth++;
 248
 249        if ((*op)->common.aml_opcode == AML_REGION_OP ||
 250            (*op)->common.aml_opcode == AML_DATA_REGION_OP) {
 251                /*
 252                 * Defer final parsing of an operation_region body, because we don't
 253                 * have enough info in the first pass to parse it correctly (i.e.,
 254                 * there may be method calls within the term_arg elements of the body.)
 255                 *
 256                 * However, we must continue parsing because the opregion is not a
 257                 * standalone package -- we don't know where the end is at this point.
 258                 *
 259                 * (Length is unknown until parse of the body complete)
 260                 */
 261                (*op)->named.data = aml_op_start;
 262                (*op)->named.length = 0;
 263        }
 264
 265        return_ACPI_STATUS(AE_OK);
 266}
 267
 268/*******************************************************************************
 269 *
 270 * FUNCTION:    acpi_ps_create_op
 271 *
 272 * PARAMETERS:  walk_state          - Current state
 273 *              aml_op_start        - Op start in AML
 274 *              new_op              - Returned Op
 275 *
 276 * RETURN:      Status
 277 *
 278 * DESCRIPTION: Get Op from AML
 279 *
 280 ******************************************************************************/
 281
 282static acpi_status
 283acpi_ps_create_op(struct acpi_walk_state *walk_state,
 284                  u8 * aml_op_start, union acpi_parse_object **new_op)
 285{
 286        acpi_status status = AE_OK;
 287        union acpi_parse_object *op;
 288        union acpi_parse_object *named_op = NULL;
 289        union acpi_parse_object *parent_scope;
 290        u8 argument_count;
 291        const struct acpi_opcode_info *op_info;
 292
 293        ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
 294
 295        status = acpi_ps_get_aml_opcode(walk_state);
 296        if (status == AE_CTRL_PARSE_CONTINUE) {
 297                return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
 298        }
 299
 300        /* Create Op structure and append to parent's argument list */
 301
 302        walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
 303        op = acpi_ps_alloc_op(walk_state->opcode);
 304        if (!op) {
 305                return_ACPI_STATUS(AE_NO_MEMORY);
 306        }
 307
 308        if (walk_state->op_info->flags & AML_NAMED) {
 309                status =
 310                    acpi_ps_build_named_op(walk_state, aml_op_start, op,
 311                                           &named_op);
 312                acpi_ps_free_op(op);
 313                if (ACPI_FAILURE(status)) {
 314                        return_ACPI_STATUS(status);
 315                }
 316
 317                *new_op = named_op;
 318                return_ACPI_STATUS(AE_OK);
 319        }
 320
 321        /* Not a named opcode, just allocate Op and append to parent */
 322
 323        if (walk_state->op_info->flags & AML_CREATE) {
 324                /*
 325                 * Backup to beginning of create_xXXfield declaration
 326                 * body_length is unknown until we parse the body
 327                 */
 328                op->named.data = aml_op_start;
 329                op->named.length = 0;
 330        }
 331
 332        if (walk_state->opcode == AML_BANK_FIELD_OP) {
 333                /*
 334                 * Backup to beginning of bank_field declaration
 335                 * body_length is unknown until we parse the body
 336                 */
 337                op->named.data = aml_op_start;
 338                op->named.length = 0;
 339        }
 340
 341        parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
 342        acpi_ps_append_arg(parent_scope, op);
 343
 344        if (parent_scope) {
 345                op_info =
 346                    acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
 347                if (op_info->flags & AML_HAS_TARGET) {
 348                        argument_count =
 349                            acpi_ps_get_argument_count(op_info->type);
 350                        if (parent_scope->common.arg_list_length >
 351                            argument_count) {
 352                                op->common.flags |= ACPI_PARSEOP_TARGET;
 353                        }
 354                } else if (parent_scope->common.aml_opcode == AML_INCREMENT_OP) {
 355                        op->common.flags |= ACPI_PARSEOP_TARGET;
 356                }
 357        }
 358
 359        if (walk_state->descending_callback != NULL) {
 360                /*
 361                 * Find the object. This will either insert the object into
 362                 * the namespace or simply look it up
 363                 */
 364                walk_state->op = *new_op = op;
 365
 366                status = walk_state->descending_callback(walk_state, &op);
 367                status = acpi_ps_next_parse_state(walk_state, op, status);
 368                if (status == AE_CTRL_PENDING) {
 369                        status = AE_CTRL_PARSE_PENDING;
 370                }
 371        }
 372
 373        return_ACPI_STATUS(status);
 374}
 375
 376/*******************************************************************************
 377 *
 378 * FUNCTION:    acpi_ps_get_arguments
 379 *
 380 * PARAMETERS:  walk_state          - Current state
 381 *              aml_op_start        - Op start in AML
 382 *              Op                  - Current Op
 383 *
 384 * RETURN:      Status
 385 *
 386 * DESCRIPTION: Get arguments for passed Op.
 387 *
 388 ******************************************************************************/
 389
 390static acpi_status
 391acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
 392                      u8 * aml_op_start, union acpi_parse_object *op)
 393{
 394        acpi_status status = AE_OK;
 395        union acpi_parse_object *arg = NULL;
 396        const struct acpi_opcode_info *op_info;
 397
 398        ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state);
 399
 400        switch (op->common.aml_opcode) {
 401        case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
 402        case AML_WORD_OP:       /* AML_WORDDATA_ARG */
 403        case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
 404        case AML_QWORD_OP:      /* AML_QWORDATA_ARG */
 405        case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */
 406
 407                /* Fill in constant or string argument directly */
 408
 409                acpi_ps_get_next_simple_arg(&(walk_state->parser_state),
 410                                            GET_CURRENT_ARG_TYPE(walk_state->
 411                                                                 arg_types),
 412                                            op);
 413                break;
 414
 415        case AML_INT_NAMEPATH_OP:       /* AML_NAMESTRING_ARG */
 416
 417                status =
 418                    acpi_ps_get_next_namepath(walk_state,
 419                                              &(walk_state->parser_state), op,
 420                                              1);
 421                if (ACPI_FAILURE(status)) {
 422                        return_ACPI_STATUS(status);
 423                }
 424
 425                walk_state->arg_types = 0;
 426                break;
 427
 428        default:
 429                /*
 430                 * Op is not a constant or string, append each argument to the Op
 431                 */
 432                while (GET_CURRENT_ARG_TYPE(walk_state->arg_types)
 433                       && !walk_state->arg_count) {
 434                        walk_state->aml_offset =
 435                            (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml,
 436                                                walk_state->parser_state.
 437                                                aml_start);
 438
 439                        status =
 440                            acpi_ps_get_next_arg(walk_state,
 441                                                 &(walk_state->parser_state),
 442                                                 GET_CURRENT_ARG_TYPE
 443                                                 (walk_state->arg_types), &arg);
 444                        if (ACPI_FAILURE(status)) {
 445                                return_ACPI_STATUS(status);
 446                        }
 447
 448                        if (arg) {
 449                                arg->common.aml_offset = walk_state->aml_offset;
 450                                acpi_ps_append_arg(op, arg);
 451                        }
 452
 453                        INCREMENT_ARG_LIST(walk_state->arg_types);
 454                }
 455
 456                /*
 457                 * Handle executable code at "module-level". This refers to
 458                 * executable opcodes that appear outside of any control method.
 459                 */
 460                if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2) &&
 461                    ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) {
 462                        /*
 463                         * We want to skip If/Else/While constructs during Pass1 because we
 464                         * want to actually conditionally execute the code during Pass2.
 465                         *
 466                         * Except for disassembly, where we always want to walk the
 467                         * If/Else/While packages
 468                         */
 469                        switch (op->common.aml_opcode) {
 470                        case AML_IF_OP:
 471                        case AML_ELSE_OP:
 472                        case AML_WHILE_OP:
 473
 474                                /*
 475                                 * Currently supported module-level opcodes are:
 476                                 * IF/ELSE/WHILE. These appear to be the most common,
 477                                 * and easiest to support since they open an AML
 478                                 * package.
 479                                 */
 480                                if (walk_state->pass_number ==
 481                                    ACPI_IMODE_LOAD_PASS1) {
 482                                        acpi_ps_link_module_code(aml_op_start,
 483                                                                 walk_state->
 484                                                                 parser_state.
 485                                                                 pkg_end -
 486                                                                 aml_op_start,
 487                                                                 walk_state->
 488                                                                 owner_id);
 489                                }
 490
 491                                ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 492                                                  "Pass1: Skipping an If/Else/While body\n"));
 493
 494                                /* Skip body of if/else/while in pass 1 */
 495
 496                                walk_state->parser_state.aml =
 497                                    walk_state->parser_state.pkg_end;
 498                                walk_state->arg_count = 0;
 499                                break;
 500
 501                        default:
 502                                /*
 503                                 * Check for an unsupported executable opcode at module
 504                                 * level. We must be in PASS1, the parent must be a SCOPE,
 505                                 * The opcode class must be EXECUTE, and the opcode must
 506                                 * not be an argument to another opcode.
 507                                 */
 508                                if ((walk_state->pass_number ==
 509                                     ACPI_IMODE_LOAD_PASS1)
 510                                    && (op->common.parent->common.aml_opcode ==
 511                                        AML_SCOPE_OP)) {
 512                                        op_info =
 513                                            acpi_ps_get_opcode_info(op->common.
 514                                                                    aml_opcode);
 515                                        if ((op_info->class ==
 516                                             AML_CLASS_EXECUTE) && (!arg)) {
 517                                                ACPI_WARNING((AE_INFO,
 518                                                              "Detected an unsupported executable opcode "
 519                                                              "at module-level: [0x%.4X] at table offset 0x%.4X",
 520                                                              op->common.aml_opcode,
 521                                                              (u32)((aml_op_start - walk_state->parser_state.aml_start)
 522                                                                + sizeof(struct acpi_table_header))));
 523                                        }
 524                                }
 525                                break;
 526                        }
 527                }
 528
 529                /* Special processing for certain opcodes */
 530
 531                switch (op->common.aml_opcode) {
 532                case AML_METHOD_OP:
 533                        /*
 534                         * Skip parsing of control method because we don't have enough
 535                         * info in the first pass to parse it correctly.
 536                         *
 537                         * Save the length and address of the body
 538                         */
 539                        op->named.data = walk_state->parser_state.aml;
 540                        op->named.length = (u32)
 541                            (walk_state->parser_state.pkg_end -
 542                             walk_state->parser_state.aml);
 543
 544                        /* Skip body of method */
 545
 546                        walk_state->parser_state.aml =
 547                            walk_state->parser_state.pkg_end;
 548                        walk_state->arg_count = 0;
 549                        break;
 550
 551                case AML_BUFFER_OP:
 552                case AML_PACKAGE_OP:
 553                case AML_VAR_PACKAGE_OP:
 554
 555                        if ((op->common.parent) &&
 556                            (op->common.parent->common.aml_opcode ==
 557                             AML_NAME_OP)
 558                            && (walk_state->pass_number <=
 559                                ACPI_IMODE_LOAD_PASS2)) {
 560                                /*
 561                                 * Skip parsing of Buffers and Packages because we don't have
 562                                 * enough info in the first pass to parse them correctly.
 563                                 */
 564                                op->named.data = aml_op_start;
 565                                op->named.length = (u32)
 566                                    (walk_state->parser_state.pkg_end -
 567                                     aml_op_start);
 568
 569                                /* Skip body */
 570
 571                                walk_state->parser_state.aml =
 572                                    walk_state->parser_state.pkg_end;
 573                                walk_state->arg_count = 0;
 574                        }
 575                        break;
 576
 577                case AML_WHILE_OP:
 578
 579                        if (walk_state->control_state) {
 580                                walk_state->control_state->control.package_end =
 581                                    walk_state->parser_state.pkg_end;
 582                        }
 583                        break;
 584
 585                default:
 586
 587                        /* No action for all other opcodes */
 588                        break;
 589                }
 590
 591                break;
 592        }
 593
 594        return_ACPI_STATUS(AE_OK);
 595}
 596
 597/*******************************************************************************
 598 *
 599 * FUNCTION:    acpi_ps_link_module_code
 600 *
 601 * PARAMETERS:  aml_start           - Pointer to the AML
 602 *              aml_length          - Length of executable AML
 603 *              owner_id            - owner_id of module level code
 604 *
 605 * RETURN:      None.
 606 *
 607 * DESCRIPTION: Wrap the module-level code with a method object and link the
 608 *              object to the global list. Note, the mutex field of the method
 609 *              object is used to link multiple module-level code objects.
 610 *
 611 ******************************************************************************/
 612
 613static void
 614acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id)
 615{
 616        union acpi_operand_object *prev;
 617        union acpi_operand_object *next;
 618        union acpi_operand_object *method_obj;
 619
 620        /* Get the tail of the list */
 621
 622        prev = next = acpi_gbl_module_code_list;
 623        while (next) {
 624                prev = next;
 625                next = next->method.mutex;
 626        }
 627
 628        /*
 629         * Insert the module level code into the list. Merge it if it is
 630         * adjacent to the previous element.
 631         */
 632        if (!prev ||
 633            ((prev->method.aml_start + prev->method.aml_length) != aml_start)) {
 634
 635                /* Create, initialize, and link a new temporary method object */
 636
 637                method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
 638                if (!method_obj) {
 639                        return;
 640                }
 641
 642                method_obj->method.aml_start = aml_start;
 643                method_obj->method.aml_length = aml_length;
 644                method_obj->method.owner_id = owner_id;
 645                method_obj->method.flags |= AOPOBJ_MODULE_LEVEL;
 646
 647                if (!prev) {
 648                        acpi_gbl_module_code_list = method_obj;
 649                } else {
 650                        prev->method.mutex = method_obj;
 651                }
 652        } else {
 653                prev->method.aml_length += aml_length;
 654        }
 655}
 656
 657/*******************************************************************************
 658 *
 659 * FUNCTION:    acpi_ps_complete_op
 660 *
 661 * PARAMETERS:  walk_state          - Current state
 662 *              Op                  - Returned Op
 663 *              Status              - Parse status before complete Op
 664 *
 665 * RETURN:      Status
 666 *
 667 * DESCRIPTION: Complete Op
 668 *
 669 ******************************************************************************/
 670
 671static acpi_status
 672acpi_ps_complete_op(struct acpi_walk_state *walk_state,
 673                    union acpi_parse_object **op, acpi_status status)
 674{
 675        acpi_status status2;
 676
 677        ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
 678
 679        /*
 680         * Finished one argument of the containing scope
 681         */
 682        walk_state->parser_state.scope->parse_scope.arg_count--;
 683
 684        /* Close this Op (will result in parse subtree deletion) */
 685
 686        status2 = acpi_ps_complete_this_op(walk_state, *op);
 687        if (ACPI_FAILURE(status2)) {
 688                return_ACPI_STATUS(status2);
 689        }
 690
 691        *op = NULL;
 692
 693        switch (status) {
 694        case AE_OK:
 695                break;
 696
 697        case AE_CTRL_TRANSFER:
 698
 699                /* We are about to transfer to a called method */
 700
 701                walk_state->prev_op = NULL;
 702                walk_state->prev_arg_types = walk_state->arg_types;
 703                return_ACPI_STATUS(status);
 704
 705        case AE_CTRL_END:
 706
 707                acpi_ps_pop_scope(&(walk_state->parser_state), op,
 708                                  &walk_state->arg_types,
 709                                  &walk_state->arg_count);
 710
 711                if (*op) {
 712                        walk_state->op = *op;
 713                        walk_state->op_info =
 714                            acpi_ps_get_opcode_info((*op)->common.aml_opcode);
 715                        walk_state->opcode = (*op)->common.aml_opcode;
 716
 717                        status = walk_state->ascending_callback(walk_state);
 718                        status =
 719                            acpi_ps_next_parse_state(walk_state, *op, status);
 720
 721                        status2 = acpi_ps_complete_this_op(walk_state, *op);
 722                        if (ACPI_FAILURE(status2)) {
 723                                return_ACPI_STATUS(status2);
 724                        }
 725                }
 726
 727                status = AE_OK;
 728                break;
 729
 730        case AE_CTRL_BREAK:
 731        case AE_CTRL_CONTINUE:
 732
 733                /* Pop off scopes until we find the While */
 734
 735                while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
 736                        acpi_ps_pop_scope(&(walk_state->parser_state), op,
 737                                          &walk_state->arg_types,
 738                                          &walk_state->arg_count);
 739                }
 740
 741                /* Close this iteration of the While loop */
 742
 743                walk_state->op = *op;
 744                walk_state->op_info =
 745                    acpi_ps_get_opcode_info((*op)->common.aml_opcode);
 746                walk_state->opcode = (*op)->common.aml_opcode;
 747
 748                status = walk_state->ascending_callback(walk_state);
 749                status = acpi_ps_next_parse_state(walk_state, *op, status);
 750
 751                status2 = acpi_ps_complete_this_op(walk_state, *op);
 752                if (ACPI_FAILURE(status2)) {
 753                        return_ACPI_STATUS(status2);
 754                }
 755
 756                status = AE_OK;
 757                break;
 758
 759        case AE_CTRL_TERMINATE:
 760
 761                /* Clean up */
 762                do {
 763                        if (*op) {
 764                                status2 =
 765                                    acpi_ps_complete_this_op(walk_state, *op);
 766                                if (ACPI_FAILURE(status2)) {
 767                                        return_ACPI_STATUS(status2);
 768                                }
 769
 770                                acpi_ut_delete_generic_state
 771                                    (acpi_ut_pop_generic_state
 772                                     (&walk_state->control_state));
 773                        }
 774
 775                        acpi_ps_pop_scope(&(walk_state->parser_state), op,
 776                                          &walk_state->arg_types,
 777                                          &walk_state->arg_count);
 778
 779                } while (*op);
 780
 781                return_ACPI_STATUS(AE_OK);
 782
 783        default:                /* All other non-AE_OK status */
 784
 785                do {
 786                        if (*op) {
 787                                status2 =
 788                                    acpi_ps_complete_this_op(walk_state, *op);
 789                                if (ACPI_FAILURE(status2)) {
 790                                        return_ACPI_STATUS(status2);
 791                                }
 792                        }
 793
 794                        acpi_ps_pop_scope(&(walk_state->parser_state), op,
 795                                          &walk_state->arg_types,
 796                                          &walk_state->arg_count);
 797
 798                } while (*op);
 799
 800#if 0
 801                /*
 802                 * TBD: Cleanup parse ops on error
 803                 */
 804                if (*op == NULL) {
 805                        acpi_ps_pop_scope(parser_state, op,
 806                                          &walk_state->arg_types,
 807                                          &walk_state->arg_count);
 808                }
 809#endif
 810                walk_state->prev_op = NULL;
 811                walk_state->prev_arg_types = walk_state->arg_types;
 812                return_ACPI_STATUS(status);
 813        }
 814
 815        /* This scope complete? */
 816
 817        if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
 818                acpi_ps_pop_scope(&(walk_state->parser_state), op,
 819                                  &walk_state->arg_types,
 820                                  &walk_state->arg_count);
 821                ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
 822        } else {
 823                *op = NULL;
 824        }
 825
 826        ACPI_PREEMPTION_POINT();
 827
 828        return_ACPI_STATUS(AE_OK);
 829}
 830
 831/*******************************************************************************
 832 *
 833 * FUNCTION:    acpi_ps_complete_final_op
 834 *
 835 * PARAMETERS:  walk_state          - Current state
 836 *              Op                  - Current Op
 837 *              Status              - Current parse status before complete last
 838 *                                    Op
 839 *
 840 * RETURN:      Status
 841 *
 842 * DESCRIPTION: Complete last Op.
 843 *
 844 ******************************************************************************/
 845
 846static acpi_status
 847acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
 848                          union acpi_parse_object *op, acpi_status status)
 849{
 850        acpi_status status2;
 851
 852        ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
 853
 854        /*
 855         * Complete the last Op (if not completed), and clear the scope stack.
 856         * It is easily possible to end an AML "package" with an unbounded number
 857         * of open scopes (such as when several ASL blocks are closed with
 858         * sequential closing braces). We want to terminate each one cleanly.
 859         */
 860        ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
 861                          op));
 862        do {
 863                if (op) {
 864                        if (walk_state->ascending_callback != NULL) {
 865                                walk_state->op = op;
 866                                walk_state->op_info =
 867                                    acpi_ps_get_opcode_info(op->common.
 868                                                            aml_opcode);
 869                                walk_state->opcode = op->common.aml_opcode;
 870
 871                                status =
 872                                    walk_state->ascending_callback(walk_state);
 873                                status =
 874                                    acpi_ps_next_parse_state(walk_state, op,
 875                                                             status);
 876                                if (status == AE_CTRL_PENDING) {
 877                                        status =
 878                                            acpi_ps_complete_op(walk_state, &op,
 879                                                                AE_OK);
 880                                        if (ACPI_FAILURE(status)) {
 881                                                return_ACPI_STATUS(status);
 882                                        }
 883                                }
 884
 885                                if (status == AE_CTRL_TERMINATE) {
 886                                        status = AE_OK;
 887
 888                                        /* Clean up */
 889                                        do {
 890                                                if (op) {
 891                                                        status2 =
 892                                                            acpi_ps_complete_this_op
 893                                                            (walk_state, op);
 894                                                        if (ACPI_FAILURE
 895                                                            (status2)) {
 896                                                                return_ACPI_STATUS
 897                                                                    (status2);
 898                                                        }
 899                                                }
 900
 901                                                acpi_ps_pop_scope(&
 902                                                                  (walk_state->
 903                                                                   parser_state),
 904                                                                  &op,
 905                                                                  &walk_state->
 906                                                                  arg_types,
 907                                                                  &walk_state->
 908                                                                  arg_count);
 909
 910                                        } while (op);
 911
 912                                        return_ACPI_STATUS(status);
 913                                }
 914
 915                                else if (ACPI_FAILURE(status)) {
 916
 917                                        /* First error is most important */
 918
 919                                        (void)
 920                                            acpi_ps_complete_this_op(walk_state,
 921                                                                     op);
 922                                        return_ACPI_STATUS(status);
 923                                }
 924                        }
 925
 926                        status2 = acpi_ps_complete_this_op(walk_state, op);
 927                        if (ACPI_FAILURE(status2)) {
 928                                return_ACPI_STATUS(status2);
 929                        }
 930                }
 931
 932                acpi_ps_pop_scope(&(walk_state->parser_state), &op,
 933                                  &walk_state->arg_types,
 934                                  &walk_state->arg_count);
 935
 936        } while (op);
 937
 938        return_ACPI_STATUS(status);
 939}
 940
 941/*******************************************************************************
 942 *
 943 * FUNCTION:    acpi_ps_parse_loop
 944 *
 945 * PARAMETERS:  walk_state          - Current state
 946 *
 947 * RETURN:      Status
 948 *
 949 * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
 950 *              a tree of ops.
 951 *
 952 ******************************************************************************/
 953
 954acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
 955{
 956        acpi_status status = AE_OK;
 957        union acpi_parse_object *op = NULL;     /* current op */
 958        struct acpi_parse_state *parser_state;
 959        u8 *aml_op_start = NULL;
 960
 961        ACPI_FUNCTION_TRACE_PTR(ps_parse_loop, walk_state);
 962
 963        if (walk_state->descending_callback == NULL) {
 964                return_ACPI_STATUS(AE_BAD_PARAMETER);
 965        }
 966
 967        parser_state = &walk_state->parser_state;
 968        walk_state->arg_types = 0;
 969
 970#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
 971
 972        if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
 973
 974                /* We are restarting a preempted control method */
 975
 976                if (acpi_ps_has_completed_scope(parser_state)) {
 977                        /*
 978                         * We must check if a predicate to an IF or WHILE statement
 979                         * was just completed
 980                         */
 981                        if ((parser_state->scope->parse_scope.op) &&
 982                            ((parser_state->scope->parse_scope.op->common.
 983                              aml_opcode == AML_IF_OP)
 984                             || (parser_state->scope->parse_scope.op->common.
 985                                 aml_opcode == AML_WHILE_OP))
 986                            && (walk_state->control_state)
 987                            && (walk_state->control_state->common.state ==
 988                                ACPI_CONTROL_PREDICATE_EXECUTING)) {
 989                                /*
 990                                 * A predicate was just completed, get the value of the
 991                                 * predicate and branch based on that value
 992                                 */
 993                                walk_state->op = NULL;
 994                                status =
 995                                    acpi_ds_get_predicate_value(walk_state,
 996                                                                ACPI_TO_POINTER
 997                                                                (TRUE));
 998                                if (ACPI_FAILURE(status)
 999                                    && ((status & AE_CODE_MASK) !=
1000                                        AE_CODE_CONTROL)) {
1001                                        if (status == AE_AML_NO_RETURN_VALUE) {
1002                                                ACPI_EXCEPTION((AE_INFO, status,
1003                                                                "Invoked method did not return a value"));
1004
1005                                        }
1006
1007                                        ACPI_EXCEPTION((AE_INFO, status,
1008                                                        "GetPredicate Failed"));
1009                                        return_ACPI_STATUS(status);
1010                                }
1011
1012                                status =
1013                                    acpi_ps_next_parse_state(walk_state, op,
1014                                                             status);
1015                        }
1016
1017                        acpi_ps_pop_scope(parser_state, &op,
1018                                          &walk_state->arg_types,
1019                                          &walk_state->arg_count);
1020                        ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
1021                                          "Popped scope, Op=%p\n", op));
1022                } else if (walk_state->prev_op) {
1023
1024                        /* We were in the middle of an op */
1025
1026                        op = walk_state->prev_op;
1027                        walk_state->arg_types = walk_state->prev_arg_types;
1028                }
1029        }
1030#endif
1031
1032        /* Iterative parsing loop, while there is more AML to process: */
1033
1034        while ((parser_state->aml < parser_state->aml_end) || (op)) {
1035                aml_op_start = parser_state->aml;
1036                if (!op) {
1037                        status =
1038                            acpi_ps_create_op(walk_state, aml_op_start, &op);
1039                        if (ACPI_FAILURE(status)) {
1040                                if (status == AE_CTRL_PARSE_CONTINUE) {
1041                                        continue;
1042                                }
1043
1044                                if (status == AE_CTRL_PARSE_PENDING) {
1045                                        status = AE_OK;
1046                                }
1047
1048                                status =
1049                                    acpi_ps_complete_op(walk_state, &op,
1050                                                        status);
1051                                if (ACPI_FAILURE(status)) {
1052                                        return_ACPI_STATUS(status);
1053                                }
1054
1055                                continue;
1056                        }
1057
1058                        op->common.aml_offset = walk_state->aml_offset;
1059
1060                        if (walk_state->op_info) {
1061                                ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
1062                                                  "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n",
1063                                                  (u32) op->common.aml_opcode,
1064                                                  walk_state->op_info->name, op,
1065                                                  parser_state->aml,
1066                                                  op->common.aml_offset));
1067                        }
1068                }
1069
1070                /*
1071                 * Start arg_count at zero because we don't know if there are
1072                 * any args yet
1073                 */
1074                walk_state->arg_count = 0;
1075
1076                /* Are there any arguments that must be processed? */
1077
1078                if (walk_state->arg_types) {
1079
1080                        /* Get arguments */
1081
1082                        status =
1083                            acpi_ps_get_arguments(walk_state, aml_op_start, op);
1084                        if (ACPI_FAILURE(status)) {
1085                                status =
1086                                    acpi_ps_complete_op(walk_state, &op,
1087                                                        status);
1088                                if (ACPI_FAILURE(status)) {
1089                                        return_ACPI_STATUS(status);
1090                                }
1091
1092                                continue;
1093                        }
1094                }
1095
1096                /* Check for arguments that need to be processed */
1097
1098                if (walk_state->arg_count) {
1099                        /*
1100                         * There are arguments (complex ones), push Op and
1101                         * prepare for argument
1102                         */
1103                        status = acpi_ps_push_scope(parser_state, op,
1104                                                    walk_state->arg_types,
1105                                                    walk_state->arg_count);
1106                        if (ACPI_FAILURE(status)) {
1107                                status =
1108                                    acpi_ps_complete_op(walk_state, &op,
1109                                                        status);
1110                                if (ACPI_FAILURE(status)) {
1111                                        return_ACPI_STATUS(status);
1112                                }
1113
1114                                continue;
1115                        }
1116
1117                        op = NULL;
1118                        continue;
1119                }
1120
1121                /*
1122                 * All arguments have been processed -- Op is complete,
1123                 * prepare for next
1124                 */
1125                walk_state->op_info =
1126                    acpi_ps_get_opcode_info(op->common.aml_opcode);
1127                if (walk_state->op_info->flags & AML_NAMED) {
1128                        if (acpi_gbl_depth) {
1129                                acpi_gbl_depth--;
1130                        }
1131
1132                        if (op->common.aml_opcode == AML_REGION_OP ||
1133                            op->common.aml_opcode == AML_DATA_REGION_OP) {
1134                                /*
1135                                 * Skip parsing of control method or opregion body,
1136                                 * because we don't have enough info in the first pass
1137                                 * to parse them correctly.
1138                                 *
1139                                 * Completed parsing an op_region declaration, we now
1140                                 * know the length.
1141                                 */
1142                                op->named.length =
1143                                    (u32) (parser_state->aml - op->named.data);
1144                        }
1145                }
1146
1147                if (walk_state->op_info->flags & AML_CREATE) {
1148                        /*
1149                         * Backup to beginning of create_xXXfield declaration (1 for
1150                         * Opcode)
1151                         *
1152                         * body_length is unknown until we parse the body
1153                         */
1154                        op->named.length =
1155                            (u32) (parser_state->aml - op->named.data);
1156                }
1157
1158                if (op->common.aml_opcode == AML_BANK_FIELD_OP) {
1159                        /*
1160                         * Backup to beginning of bank_field declaration
1161                         *
1162                         * body_length is unknown until we parse the body
1163                         */
1164                        op->named.length =
1165                            (u32) (parser_state->aml - op->named.data);
1166                }
1167
1168                /* This op complete, notify the dispatcher */
1169
1170                if (walk_state->ascending_callback != NULL) {
1171                        walk_state->op = op;
1172                        walk_state->opcode = op->common.aml_opcode;
1173
1174                        status = walk_state->ascending_callback(walk_state);
1175                        status =
1176                            acpi_ps_next_parse_state(walk_state, op, status);
1177                        if (status == AE_CTRL_PENDING) {
1178                                status = AE_OK;
1179                        }
1180                }
1181
1182                status = acpi_ps_complete_op(walk_state, &op, status);
1183                if (ACPI_FAILURE(status)) {
1184                        return_ACPI_STATUS(status);
1185                }
1186
1187        }                       /* while parser_state->Aml */
1188
1189        status = acpi_ps_complete_final_op(walk_state, op, status);
1190        return_ACPI_STATUS(status);
1191}
1192