Path: blob/main/sys/contrib/dev/acpica/components/dispatcher/dsutils.c
48521 views
/*******************************************************************************1*2* Module Name: dsutils - Dispatcher utilities3*4******************************************************************************/56/******************************************************************************7*8* 1. Copyright Notice9*10* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.11* All rights reserved.12*13* 2. License14*15* 2.1. This is your license from Intel Corp. under its intellectual property16* rights. You may have additional license terms from the party that provided17* you this software, covering your right to use that party's intellectual18* property rights.19*20* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a21* copy of the source code appearing in this file ("Covered Code") an22* irrevocable, perpetual, worldwide license under Intel's copyrights in the23* base code distributed originally by Intel ("Original Intel Code") to copy,24* make derivatives, distribute, use and display any portion of the Covered25* Code in any form, with the right to sublicense such rights; and26*27* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent28* license (with the right to sublicense), under only those claims of Intel29* patents that are infringed by the Original Intel Code, to make, use, sell,30* offer to sell, and import the Covered Code and derivative works thereof31* solely to the minimum extent necessary to exercise the above copyright32* license, and in no event shall the patent license extend to any additions33* to or modifications of the Original Intel Code. No other license or right34* is granted directly or by implication, estoppel or otherwise;35*36* The above copyright and patent license is granted only if the following37* conditions are met:38*39* 3. Conditions40*41* 3.1. Redistribution of Source with Rights to Further Distribute Source.42* Redistribution of source code of any substantial portion of the Covered43* Code or modification with rights to further distribute source must include44* the above Copyright Notice, the above License, this list of Conditions,45* and the following Disclaimer and Export Compliance provision. In addition,46* Licensee must cause all Covered Code to which Licensee contributes to47* contain a file documenting the changes Licensee made to create that Covered48* Code and the date of any change. Licensee must include in that file the49* documentation of any changes made by any predecessor Licensee. Licensee50* must include a prominent statement that the modification is derived,51* directly or indirectly, from Original Intel Code.52*53* 3.2. Redistribution of Source with no Rights to Further Distribute Source.54* Redistribution of source code of any substantial portion of the Covered55* Code or modification without rights to further distribute source must56* include the following Disclaimer and Export Compliance provision in the57* documentation and/or other materials provided with distribution. In58* addition, Licensee may not authorize further sublicense of source of any59* portion of the Covered Code, and must include terms to the effect that the60* license from Licensee to its licensee is limited to the intellectual61* property embodied in the software Licensee provides to its licensee, and62* not to intellectual property embodied in modifications its licensee may63* make.64*65* 3.3. Redistribution of Executable. Redistribution in executable form of any66* substantial portion of the Covered Code or modification must reproduce the67* above Copyright Notice, and the following Disclaimer and Export Compliance68* provision in the documentation and/or other materials provided with the69* distribution.70*71* 3.4. Intel retains all right, title, and interest in and to the Original72* Intel Code.73*74* 3.5. Neither the name Intel nor any other trademark owned or controlled by75* Intel shall be used in advertising or otherwise to promote the sale, use or76* other dealings in products derived from or relating to the Covered Code77* without prior written authorization from Intel.78*79* 4. Disclaimer and Export Compliance80*81* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED82* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE83* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,84* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY85* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY86* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A87* PARTICULAR PURPOSE.88*89* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES90* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR91* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,92* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY93* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL94* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS95* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY96* LIMITED REMEDY.97*98* 4.3. Licensee shall not export, either directly or indirectly, any of this99* software or system incorporating such software without first obtaining any100* required license or other approval from the U. S. Department of Commerce or101* any other agency or department of the United States Government. In the102* event Licensee exports any such software from the United States or103* re-exports any such software from a foreign destination, Licensee shall104* ensure that the distribution and export/re-export of the software is in105* compliance with all laws, regulations, orders, or other restrictions of the106* U.S. Export Administration Regulations. Licensee agrees that neither it nor107* any of its subsidiaries will export/re-export any technical data, process,108* software, or service, directly or indirectly, to any country for which the109* United States government or any agency thereof requires an export license,110* other governmental approval, or letter of assurance, without first obtaining111* such license, approval or letter.112*113*****************************************************************************114*115* Alternatively, you may choose to be licensed under the terms of the116* following license:117*118* Redistribution and use in source and binary forms, with or without119* modification, are permitted provided that the following conditions120* are met:121* 1. Redistributions of source code must retain the above copyright122* notice, this list of conditions, and the following disclaimer,123* without modification.124* 2. Redistributions in binary form must reproduce at minimum a disclaimer125* substantially similar to the "NO WARRANTY" disclaimer below126* ("Disclaimer") and any redistribution must be conditioned upon127* including a substantially similar Disclaimer requirement for further128* binary redistribution.129* 3. Neither the names of the above-listed copyright holders nor the names130* of any contributors may be used to endorse or promote products derived131* from this software without specific prior written permission.132*133* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS134* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT135* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR136* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT137* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,138* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT139* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,140* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY141* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT142* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE143* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.144*145* Alternatively, you may choose to be licensed under the terms of the146* GNU General Public License ("GPL") version 2 as published by the Free147* Software Foundation.148*149*****************************************************************************/150151#include <contrib/dev/acpica/include/acpi.h>152#include <contrib/dev/acpica/include/accommon.h>153#include <contrib/dev/acpica/include/acparser.h>154#include <contrib/dev/acpica/include/amlcode.h>155#include <contrib/dev/acpica/include/acdispat.h>156#include <contrib/dev/acpica/include/acinterp.h>157#include <contrib/dev/acpica/include/acnamesp.h>158#include <contrib/dev/acpica/include/acdebug.h>159160#define _COMPONENT ACPI_DISPATCHER161ACPI_MODULE_NAME ("dsutils")162163164/*******************************************************************************165*166* FUNCTION: AcpiDsClearImplicitReturn167*168* PARAMETERS: WalkState - Current State169*170* RETURN: None.171*172* DESCRIPTION: Clear and remove a reference on an implicit return value. Used173* to delete "stale" return values (if enabled, the return value174* from every operator is saved at least momentarily, in case the175* parent method exits.)176*177******************************************************************************/178179void180AcpiDsClearImplicitReturn (181ACPI_WALK_STATE *WalkState)182{183ACPI_FUNCTION_NAME (DsClearImplicitReturn);184185186/*187* Slack must be enabled for this feature188*/189if (!AcpiGbl_EnableInterpreterSlack)190{191return;192}193194if (WalkState->ImplicitReturnObj)195{196/*197* Delete any "stale" implicit return. However, in198* complex statements, the implicit return value can be199* bubbled up several levels.200*/201ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,202"Removing reference on stale implicit return obj %p\n",203WalkState->ImplicitReturnObj));204205AcpiUtRemoveReference (WalkState->ImplicitReturnObj);206WalkState->ImplicitReturnObj = NULL;207}208}209210211/*******************************************************************************212*213* FUNCTION: AcpiDsDoImplicitReturn214*215* PARAMETERS: ReturnDesc - The return value216* WalkState - Current State217* AddReference - True if a reference should be added to the218* return object219*220* RETURN: TRUE if implicit return enabled, FALSE otherwise221*222* DESCRIPTION: Implements the optional "implicit return". We save the result223* of every ASL operator and control method invocation in case the224* parent method exit. Before storing a new return value, we225* delete the previous return value.226*227******************************************************************************/228229BOOLEAN230AcpiDsDoImplicitReturn (231ACPI_OPERAND_OBJECT *ReturnDesc,232ACPI_WALK_STATE *WalkState,233BOOLEAN AddReference)234{235ACPI_FUNCTION_NAME (DsDoImplicitReturn);236237238/*239* Slack must be enabled for this feature, and we must240* have a valid return object241*/242if ((!AcpiGbl_EnableInterpreterSlack) ||243(!ReturnDesc))244{245return (FALSE);246}247248ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,249"Result %p will be implicitly returned; Prev=%p\n",250ReturnDesc,251WalkState->ImplicitReturnObj));252253/*254* Delete any "stale" implicit return value first. However, in255* complex statements, the implicit return value can be256* bubbled up several levels, so we don't clear the value if it257* is the same as the ReturnDesc.258*/259if (WalkState->ImplicitReturnObj)260{261if (WalkState->ImplicitReturnObj == ReturnDesc)262{263return (TRUE);264}265AcpiDsClearImplicitReturn (WalkState);266}267268/* Save the implicit return value, add a reference if requested */269270WalkState->ImplicitReturnObj = ReturnDesc;271if (AddReference)272{273AcpiUtAddReference (ReturnDesc);274}275276return (TRUE);277}278279280/*******************************************************************************281*282* FUNCTION: AcpiDsIsResultUsed283*284* PARAMETERS: Op - Current Op285* WalkState - Current State286*287* RETURN: TRUE if result is used, FALSE otherwise288*289* DESCRIPTION: Check if a result object will be used by the parent290*291******************************************************************************/292293BOOLEAN294AcpiDsIsResultUsed (295ACPI_PARSE_OBJECT *Op,296ACPI_WALK_STATE *WalkState)297{298const ACPI_OPCODE_INFO *ParentInfo;299300ACPI_FUNCTION_TRACE_PTR (DsIsResultUsed, Op);301302303/* Must have both an Op and a Result Object */304305if (!Op)306{307ACPI_ERROR ((AE_INFO, "Null Op"));308return_UINT8 (TRUE);309}310311/*312* We know that this operator is not a313* Return() operator (would not come here.) The following code is the314* optional support for a so-called "implicit return". Some AML code315* assumes that the last value of the method is "implicitly" returned316* to the caller. Just save the last result as the return value.317* NOTE: this is optional because the ASL language does not actually318* support this behavior.319*/320(void) AcpiDsDoImplicitReturn (WalkState->ResultObj, WalkState, TRUE);321322/*323* Now determine if the parent will use the result324*325* If there is no parent, or the parent is a ScopeOp, we are executing326* at the method level. An executing method typically has no parent,327* since each method is parsed separately. A method invoked externally328* via ExecuteControlMethod has a ScopeOp as the parent.329*/330if ((!Op->Common.Parent) ||331(Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP))332{333/* No parent, the return value cannot possibly be used */334335ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,336"At Method level, result of [%s] not used\n",337AcpiPsGetOpcodeName (Op->Common.AmlOpcode)));338return_UINT8 (FALSE);339}340341/* Get info on the parent. The RootOp is AML_SCOPE */342343ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode);344if (ParentInfo->Class == AML_CLASS_UNKNOWN)345{346ACPI_ERROR ((AE_INFO,347"Unknown parent opcode Op=%p", Op));348return_UINT8 (FALSE);349}350351/*352* Decide what to do with the result based on the parent. If353* the parent opcode will not use the result, delete the object.354* Otherwise leave it as is, it will be deleted when it is used355* as an operand later.356*/357switch (ParentInfo->Class)358{359case AML_CLASS_CONTROL:360361switch (Op->Common.Parent->Common.AmlOpcode)362{363case AML_RETURN_OP:364365/* Never delete the return value associated with a return opcode */366367goto ResultUsed;368369case AML_IF_OP:370case AML_WHILE_OP:371/*372* If we are executing the predicate AND this is the predicate op,373* we will use the return value374*/375if ((WalkState->ControlState->Common.State ==376ACPI_CONTROL_PREDICATE_EXECUTING) &&377(WalkState->ControlState->Control.PredicateOp == Op))378{379goto ResultUsed;380}381break;382383default:384385/* Ignore other control opcodes */386387break;388}389390/* The general control opcode returns no result */391392goto ResultNotUsed;393394case AML_CLASS_CREATE:395/*396* These opcodes allow TermArg(s) as operands and therefore397* the operands can be method calls. The result is used.398*/399goto ResultUsed;400401case AML_CLASS_NAMED_OBJECT:402403if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP) ||404(Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP) ||405(Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||406(Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP) ||407(Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP) ||408(Op->Common.Parent->Common.AmlOpcode == AML_INT_EVAL_SUBTREE_OP) ||409(Op->Common.Parent->Common.AmlOpcode == AML_BANK_FIELD_OP))410{411/*412* These opcodes allow TermArg(s) as operands and therefore413* the operands can be method calls. The result is used.414*/415goto ResultUsed;416}417418goto ResultNotUsed;419420default:421/*422* In all other cases. the parent will actually use the return423* object, so keep it.424*/425goto ResultUsed;426}427428429ResultUsed:430ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,431"Result of [%s] used by Parent [%s] Op=%p\n",432AcpiPsGetOpcodeName (Op->Common.AmlOpcode),433AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));434435return_UINT8 (TRUE);436437438ResultNotUsed:439ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,440"Result of [%s] not used by Parent [%s] Op=%p\n",441AcpiPsGetOpcodeName (Op->Common.AmlOpcode),442AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));443444return_UINT8 (FALSE);445}446447448/*******************************************************************************449*450* FUNCTION: AcpiDsDeleteResultIfNotUsed451*452* PARAMETERS: Op - Current parse Op453* ResultObj - Result of the operation454* WalkState - Current state455*456* RETURN: Status457*458* DESCRIPTION: Used after interpretation of an opcode. If there is an internal459* result descriptor, check if the parent opcode will actually use460* this result. If not, delete the result now so that it will461* not become orphaned.462*463******************************************************************************/464465void466AcpiDsDeleteResultIfNotUsed (467ACPI_PARSE_OBJECT *Op,468ACPI_OPERAND_OBJECT *ResultObj,469ACPI_WALK_STATE *WalkState)470{471ACPI_OPERAND_OBJECT *ObjDesc;472ACPI_STATUS Status;473474475ACPI_FUNCTION_TRACE_PTR (DsDeleteResultIfNotUsed, ResultObj);476477478if (!Op)479{480ACPI_ERROR ((AE_INFO, "Null Op"));481return_VOID;482}483484if (!ResultObj)485{486return_VOID;487}488489if (!AcpiDsIsResultUsed (Op, WalkState))490{491/* Must pop the result stack (ObjDesc should be equal to ResultObj) */492493Status = AcpiDsResultPop (&ObjDesc, WalkState);494if (ACPI_SUCCESS (Status))495{496AcpiUtRemoveReference (ResultObj);497}498}499500return_VOID;501}502503504/*******************************************************************************505*506* FUNCTION: AcpiDsResolveOperands507*508* PARAMETERS: WalkState - Current walk state with operands on stack509*510* RETURN: Status511*512* DESCRIPTION: Resolve all operands to their values. Used to prepare513* arguments to a control method invocation (a call from one514* method to another.)515*516******************************************************************************/517518ACPI_STATUS519AcpiDsResolveOperands (520ACPI_WALK_STATE *WalkState)521{522UINT32 i;523ACPI_STATUS Status = AE_OK;524525526ACPI_FUNCTION_TRACE_PTR (DsResolveOperands, WalkState);527528529/*530* Attempt to resolve each of the valid operands531* Method arguments are passed by reference, not by value. This means532* that the actual objects are passed, not copies of the objects.533*/534for (i = 0; i < WalkState->NumOperands; i++)535{536Status = AcpiExResolveToValue (&WalkState->Operands[i], WalkState);537if (ACPI_FAILURE (Status))538{539break;540}541}542543return_ACPI_STATUS (Status);544}545546547/*******************************************************************************548*549* FUNCTION: AcpiDsClearOperands550*551* PARAMETERS: WalkState - Current walk state with operands on stack552*553* RETURN: None554*555* DESCRIPTION: Clear all operands on the current walk state operand stack.556*557******************************************************************************/558559void560AcpiDsClearOperands (561ACPI_WALK_STATE *WalkState)562{563UINT32 i;564565566ACPI_FUNCTION_TRACE_PTR (DsClearOperands, WalkState);567568569/* Remove a reference on each operand on the stack */570571for (i = 0; i < WalkState->NumOperands; i++)572{573/*574* Remove a reference to all operands, including both575* "Arguments" and "Targets".576*/577AcpiUtRemoveReference (WalkState->Operands[i]);578WalkState->Operands[i] = NULL;579}580581WalkState->NumOperands = 0;582return_VOID;583}584585586/*******************************************************************************587*588* FUNCTION: AcpiDsCreateOperand589*590* PARAMETERS: WalkState - Current walk state591* Arg - Parse object for the argument592* ArgIndex - Which argument (zero based)593*594* RETURN: Status595*596* DESCRIPTION: Translate a parse tree object that is an argument to an AML597* opcode to the equivalent interpreter object. This may include598* looking up a name or entering a new name into the internal599* namespace.600*601******************************************************************************/602603ACPI_STATUS604AcpiDsCreateOperand (605ACPI_WALK_STATE *WalkState,606ACPI_PARSE_OBJECT *Arg,607UINT32 ArgIndex)608{609ACPI_STATUS Status = AE_OK;610char *NameString;611UINT32 NameLength;612ACPI_OPERAND_OBJECT *ObjDesc;613ACPI_PARSE_OBJECT *ParentOp;614UINT16 Opcode;615ACPI_INTERPRETER_MODE InterpreterMode;616const ACPI_OPCODE_INFO *OpInfo;617618619ACPI_FUNCTION_TRACE_PTR (DsCreateOperand, Arg);620621622/* A valid name must be looked up in the namespace */623624if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&625(Arg->Common.Value.String) &&626!(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))627{628ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", Arg));629630/* Get the entire name string from the AML stream */631632Status = AcpiExGetNameString (ACPI_TYPE_ANY,633Arg->Common.Value.Buffer, &NameString, &NameLength);634635if (ACPI_FAILURE (Status))636{637return_ACPI_STATUS (Status);638}639640/* All prefixes have been handled, and the name is in NameString */641642/*643* Special handling for BufferField declarations. This is a deferred644* opcode that unfortunately defines the field name as the last645* parameter instead of the first. We get here when we are performing646* the deferred execution, so the actual name of the field is already647* in the namespace. We don't want to attempt to look it up again648* because we may be executing in a different scope than where the649* actual opcode exists.650*/651if ((WalkState->DeferredNode) &&652(WalkState->DeferredNode->Type == ACPI_TYPE_BUFFER_FIELD) &&653(ArgIndex == (UINT32)654((WalkState->Opcode == AML_CREATE_FIELD_OP) ? 3 : 2)))655{656ObjDesc = ACPI_CAST_PTR (657ACPI_OPERAND_OBJECT, WalkState->DeferredNode);658Status = AE_OK;659}660else /* All other opcodes */661{662/*663* Differentiate between a namespace "create" operation664* versus a "lookup" operation (IMODE_LOAD_PASS2 vs.665* IMODE_EXECUTE) in order to support the creation of666* namespace objects during the execution of control methods.667*/668ParentOp = Arg->Common.Parent;669OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);670671if ((OpInfo->Flags & AML_NSNODE) &&672(ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&673(ParentOp->Common.AmlOpcode != AML_REGION_OP) &&674(ParentOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP))675{676/* Enter name into namespace if not found */677678InterpreterMode = ACPI_IMODE_LOAD_PASS2;679}680else681{682/* Return a failure if name not found */683684InterpreterMode = ACPI_IMODE_EXECUTE;685}686687Status = AcpiNsLookup (WalkState->ScopeInfo, NameString,688ACPI_TYPE_ANY, InterpreterMode,689ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, WalkState,690ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc));691/*692* The only case where we pass through (ignore) a NOT_FOUND693* error is for the CondRefOf opcode.694*/695if (Status == AE_NOT_FOUND)696{697if (ParentOp->Common.AmlOpcode == AML_CONDITIONAL_REF_OF_OP)698{699/*700* For the Conditional Reference op, it's OK if701* the name is not found; We just need a way to702* indicate this to the interpreter, set the703* object to the root704*/705ObjDesc = ACPI_CAST_PTR (706ACPI_OPERAND_OBJECT, AcpiGbl_RootNode);707Status = AE_OK;708}709else if (ParentOp->Common.AmlOpcode == AML_EXTERNAL_OP)710{711/*712* This opcode should never appear here. It is used only713* by AML disassemblers and is surrounded by an If(0)714* by the ASL compiler.715*716* Therefore, if we see it here, it is a serious error.717*/718Status = AE_AML_BAD_OPCODE;719}720else721{722/*723* We just plain didn't find it -- which is a724* very serious error at this point725*/726Status = AE_AML_NAME_NOT_FOUND;727}728}729730if (ACPI_FAILURE (Status))731{732ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,733NameString, Status);734}735}736737/* Free the namestring created above */738739ACPI_FREE (NameString);740741/* Check status from the lookup */742743if (ACPI_FAILURE (Status))744{745return_ACPI_STATUS (Status);746}747748/* Put the resulting object onto the current object stack */749750Status = AcpiDsObjStackPush (ObjDesc, WalkState);751if (ACPI_FAILURE (Status))752{753return_ACPI_STATUS (Status);754}755756AcpiDbDisplayArgumentObject (ObjDesc, WalkState);757}758else759{760/* Check for null name case */761762if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&763!(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))764{765/*766* If the name is null, this means that this is an767* optional result parameter that was not specified768* in the original ASL. Create a Zero Constant for a769* placeholder. (Store to a constant is a Noop.)770*/771Opcode = AML_ZERO_OP; /* Has no arguments! */772773ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,774"Null namepath: Arg=%p\n", Arg));775}776else777{778Opcode = Arg->Common.AmlOpcode;779}780781/* Get the object type of the argument */782783OpInfo = AcpiPsGetOpcodeInfo (Opcode);784if (OpInfo->ObjectType == ACPI_TYPE_INVALID)785{786return_ACPI_STATUS (AE_NOT_IMPLEMENTED);787}788789if ((OpInfo->Flags & AML_HAS_RETVAL) ||790(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))791{792/*793* Use value that was already previously returned794* by the evaluation of this argument795*/796Status = AcpiDsResultPop (&ObjDesc, WalkState);797if (ACPI_FAILURE (Status))798{799/*800* Only error is underflow, and this indicates801* a missing or null operand!802*/803ACPI_EXCEPTION ((AE_INFO, Status,804"Missing or null operand"));805return_ACPI_STATUS (Status);806}807}808else809{810/* Create an ACPI_INTERNAL_OBJECT for the argument */811812ObjDesc = AcpiUtCreateInternalObject (OpInfo->ObjectType);813if (!ObjDesc)814{815return_ACPI_STATUS (AE_NO_MEMORY);816}817818/* Initialize the new object */819820Status = AcpiDsInitObjectFromOp (821WalkState, Arg, Opcode, &ObjDesc);822if (ACPI_FAILURE (Status))823{824AcpiUtDeleteObjectDesc (ObjDesc);825return_ACPI_STATUS (Status);826}827}828829/* Put the operand object on the object stack */830831Status = AcpiDsObjStackPush (ObjDesc, WalkState);832if (ACPI_FAILURE (Status))833{834return_ACPI_STATUS (Status);835}836837AcpiDbDisplayArgumentObject (ObjDesc, WalkState);838}839840return_ACPI_STATUS (AE_OK);841}842843844/*******************************************************************************845*846* FUNCTION: AcpiDsCreateOperands847*848* PARAMETERS: WalkState - Current state849* FirstArg - First argument of a parser argument tree850*851* RETURN: Status852*853* DESCRIPTION: Convert an operator's arguments from a parse tree format to854* namespace objects and place those argument object on the object855* stack in preparation for evaluation by the interpreter.856*857******************************************************************************/858859ACPI_STATUS860AcpiDsCreateOperands (861ACPI_WALK_STATE *WalkState,862ACPI_PARSE_OBJECT *FirstArg)863{864ACPI_STATUS Status = AE_OK;865ACPI_PARSE_OBJECT *Arg;866ACPI_PARSE_OBJECT *Arguments[ACPI_OBJ_NUM_OPERANDS];867UINT32 ArgCount = 0;868UINT32 Index = WalkState->NumOperands;869UINT32 PrevNumOperands = WalkState->NumOperands;870UINT32 NewNumOperands;871UINT32 i;872873874ACPI_FUNCTION_TRACE_PTR (DsCreateOperands, FirstArg);875876877/* Get all arguments in the list */878879Arg = FirstArg;880while (Arg)881{882if (Index >= ACPI_OBJ_NUM_OPERANDS)883{884return_ACPI_STATUS (AE_BAD_DATA);885}886887Arguments[Index] = Arg;888WalkState->Operands [Index] = NULL;889890/* Move on to next argument, if any */891892Arg = Arg->Common.Next;893ArgCount++;894Index++;895}896897ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,898"NumOperands %d, ArgCount %d, Index %d\n",899WalkState->NumOperands, ArgCount, Index));900901/* Create the interpreter arguments, in reverse order */902903NewNumOperands = Index;904Index--;905for (i = 0; i < ArgCount; i++)906{907Arg = Arguments[Index];908WalkState->OperandIndex = (UINT8) Index;909910Status = AcpiDsCreateOperand (WalkState, Arg, Index);911if (ACPI_FAILURE (Status))912{913goto Cleanup;914}915916ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,917"Created Arg #%u (%p) %u args total\n",918Index, Arg, ArgCount));919Index--;920}921922return_ACPI_STATUS (Status);923924925Cleanup:926/*927* We must undo everything done above; meaning that we must928* pop everything off of the operand stack and delete those929* objects930*/931WalkState->NumOperands = (UINT8) (i);932AcpiDsObjStackPopAndDelete (NewNumOperands, WalkState);933934/* Restore operand count */935WalkState->NumOperands = (UINT8) (PrevNumOperands);936937ACPI_EXCEPTION ((AE_INFO, Status, "While creating Arg %u", Index));938return_ACPI_STATUS (Status);939}940941942/*****************************************************************************943*944* FUNCTION: AcpiDsEvaluateNamePath945*946* PARAMETERS: WalkState - Current state of the parse tree walk,947* the opcode of current operation should be948* AML_INT_NAMEPATH_OP949*950* RETURN: Status951*952* DESCRIPTION: Translate the -NamePath- parse tree object to the equivalent953* interpreter object, convert it to value, if needed, duplicate954* it, if needed, and push it onto the current result stack.955*956****************************************************************************/957958ACPI_STATUS959AcpiDsEvaluateNamePath (960ACPI_WALK_STATE *WalkState)961{962ACPI_STATUS Status = AE_OK;963ACPI_PARSE_OBJECT *Op = WalkState->Op;964ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];965ACPI_OPERAND_OBJECT *NewObjDesc;966UINT8 Type;967968969ACPI_FUNCTION_TRACE_PTR (DsEvaluateNamePath, WalkState);970971972if (!Op->Common.Parent)973{974/* This happens after certain exception processing */975976goto Exit;977}978979if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||980(Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP) ||981(Op->Common.Parent->Common.AmlOpcode == AML_REF_OF_OP))982{983/* TBD: Should we specify this feature as a bit of OpInfo->Flags of these opcodes? */984985goto Exit;986}987988Status = AcpiDsCreateOperand (WalkState, Op, 0);989if (ACPI_FAILURE (Status))990{991goto Exit;992}993994if (Op->Common.Flags & ACPI_PARSEOP_TARGET)995{996NewObjDesc = *Operand;997goto PushResult;998}9991000Type = (*Operand)->Common.Type;10011002Status = AcpiExResolveToValue (Operand, WalkState);1003if (ACPI_FAILURE (Status))1004{1005goto Exit;1006}10071008if (Type == ACPI_TYPE_INTEGER)1009{1010/* It was incremented by AcpiExResolveToValue */10111012AcpiUtRemoveReference (*Operand);10131014Status = AcpiUtCopyIobjectToIobject (1015*Operand, &NewObjDesc, WalkState);1016if (ACPI_FAILURE (Status))1017{1018goto Exit;1019}1020}1021else1022{1023/*1024* The object either was anew created or is1025* a Namespace node - don't decrement it.1026*/1027NewObjDesc = *Operand;1028}10291030/* Cleanup for name-path operand */10311032Status = AcpiDsObjStackPop (1, WalkState);1033if (ACPI_FAILURE (Status))1034{1035WalkState->ResultObj = NewObjDesc;1036goto Exit;1037}10381039PushResult:10401041WalkState->ResultObj = NewObjDesc;10421043Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);1044if (ACPI_SUCCESS (Status))1045{1046/* Force to take it from stack */10471048Op->Common.Flags |= ACPI_PARSEOP_IN_STACK;1049}10501051Exit:10521053return_ACPI_STATUS (Status);1054}105510561057