/******************************************************************************
*
* Module Name: psloop - Main AML parse loop
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2016, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
/*
* Parse the AML and build an operation tree as most interpreters, (such as
* Perl) do. Parsing is done by hand rather than with a YACC generated parser
* to tightly constrain stack and dynamic memory usage. Parsing is kept
* flexible and the code fairly compact by parsing based on a list of AML
* opcode templates in AmlOpInfo[].
*/
#include "acpi.h"
#include "accommon.h"
#include "acinterp.h"
#include "acparser.h"
#include "acdispat.h"
#include "amlcode.h"
ACPI_MODULE_NAME ("psloop")
/* Local prototypes */
static ACPI_STATUS
static void
/*******************************************************************************
*
* FUNCTION: AcpiPsGetArguments
*
* PARAMETERS: WalkState - Current state
* AmlOpStart - Op start in AML
* Op - Current Op
*
* RETURN: Status
*
* DESCRIPTION: Get arguments for passed Op.
*
******************************************************************************/
static ACPI_STATUS
{
{
case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
case AML_WORD_OP: /* AML_WORDDATA_ARG */
case AML_DWORD_OP: /* AML_DWORDATA_ARG */
case AML_QWORD_OP: /* AML_QWORDATA_ARG */
case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */
/* Fill in constant or string argument directly */
break;
case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
if (ACPI_FAILURE (Status))
{
}
break;
default:
/*
* Op is not a constant or string, append each argument to the Op
*/
{
if (ACPI_FAILURE (Status))
{
}
if (Arg)
{
}
}
/*
* Handle executable code at "module-level". This refers to
* executable opcodes that appear outside of any control method.
*/
{
/*
* want to actually conditionally execute the code during Pass2.
*
* Except for disassembly, where we always want to walk the
*/
{
case AML_IF_OP:
case AML_ELSE_OP:
case AML_WHILE_OP:
/*
* Currently supported module-level opcodes are:
* and easiest to support since they open an AML
* package.
*/
{
}
break;
default:
/*
* Check for an unsupported executable opcode at module
* level. We must be in PASS1, the parent must be a SCOPE,
* The opcode class must be EXECUTE, and the opcode must
* not be an argument to another opcode.
*/
{
(!Arg))
{
"Unsupported module-level executable opcode "
"0x%.2X at table offset 0x%.4X",
sizeof (ACPI_TABLE_HEADER))));
}
}
break;
}
}
/* Special processing for certain opcodes */
{
case AML_METHOD_OP:
/*
* Skip parsing of control method because we don't have enough
* info in the first pass to parse it correctly.
*
* Save the length and address of the body
*/
/* Skip body of method */
break;
case AML_BUFFER_OP:
case AML_PACKAGE_OP:
case AML_VAR_PACKAGE_OP:
{
/*
* Skip parsing of Buffers and Packages because we don't have
* enough info in the first pass to parse them correctly.
*/
/* Skip body */
}
break;
case AML_WHILE_OP:
if (WalkState->ControlState)
{
}
break;
default:
/* No action for all other opcodes */
break;
}
break;
}
}
/*******************************************************************************
*
* FUNCTION: AcpiPsLinkModuleCode
*
* PARAMETERS: ParentOp - Parent parser op
* AmlStart - Pointer to the AML
* AmlLength - Length of executable AML
* OwnerId - OwnerId of module level code
*
* RETURN: None.
*
* DESCRIPTION: Wrap the module-level code with a method object and link the
* object to the global list. Note, the mutex field of the method
* object is used to link multiple module-level code objects.
*
******************************************************************************/
static void
{
/* Get the tail of the list */
while (Next)
{
}
/*
* Insert the module level code into the list. Merge it if it is
* adjacent to the previous element.
*/
if (!Prev ||
{
/* Create, initialize, and link a new temporary method object */
if (!MethodObj)
{
}
{
}
else
{
}
/*
* Save the parent node in NextObject. This is cheating, but we
* don't want to expand the method object.
*/
if (!Prev)
{
}
else
{
}
}
else
{
"Appending to existing code block: %p\n", Prev));
}
}
/*******************************************************************************
*
* FUNCTION: AcpiPsParseLoop
*
* PARAMETERS: WalkState - Current state
*
* RETURN: Status
*
* DESCRIPTION: Parse AML (pointed to by the current parser state) and return
* a tree of ops.
*
******************************************************************************/
{
{
}
#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
{
/* We are restarting a preempted control method */
{
/*
* We must check if a predicate to an IF or WHILE statement
* was just completed
*/
(WalkState->ControlState) &&
{
/*
* A predicate was just completed, get the value of the
* predicate and branch based on that value
*/
if (ACPI_FAILURE (Status) &&
{
if (Status == AE_AML_NO_RETURN_VALUE)
{
"Invoked method did not return a value"));
}
}
}
}
{
/* We were in the middle of an op */
}
}
#endif
/* Iterative parsing loop, while there is more AML to process: */
{
if (!Op)
{
if (ACPI_FAILURE (Status))
{
if (Status == AE_CTRL_PARSE_CONTINUE)
{
continue;
}
if (Status == AE_CTRL_PARSE_PENDING)
{
}
if (Status == AE_CTRL_TERMINATE)
{
}
if (ACPI_FAILURE (Status))
{
}
continue;
}
}
/*
* Start ArgCount at zero because we don't know if there are
* any args yet
*/
/* Are there any arguments that must be processed? */
{
/* Get arguments */
if (ACPI_FAILURE (Status))
{
if (ACPI_FAILURE (Status))
{
}
continue;
}
}
/* Check for arguments that need to be processed */
{
/*
* There are arguments (complex ones), push Op and
* prepare for argument
*/
if (ACPI_FAILURE (Status))
{
if (ACPI_FAILURE (Status))
{
}
continue;
}
continue;
}
/*
* All arguments have been processed -- Op is complete,
* prepare for next
*/
{
{
/*
* Skip parsing of control method or opregion body,
* because we don't have enough info in the first pass
* to parse them correctly.
*
* Completed parsing an OpRegion declaration, we now
* know the length.
*/
}
}
{
/*
* Backup to beginning of CreateXXXfield declaration (1 for
* Opcode)
*
* BodyLength is unknown until we parse the body
*/
}
{
/*
* Backup to beginning of BankField declaration
*
* BodyLength is unknown until we parse the body
*/
}
/* This op complete, notify the dispatcher */
{
if (Status == AE_CTRL_PENDING)
{
}
}
if (ACPI_FAILURE (Status))
{
}
} /* while ParserState->Aml */
}