Linux Audio

Check our new training course

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