167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: dsmthdat - control method arguments and local variables 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 47193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 48193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 4967754Smsmith 5067754Smsmith 5177424Smsmith#define _COMPONENT ACPI_DISPATCHER 5291116Smsmith ACPI_MODULE_NAME ("dsmthdat") 5367754Smsmith 54151937Sjkim/* Local prototypes */ 5567754Smsmith 56151937Sjkimstatic void 57151937SjkimAcpiDsMethodDataDeleteValue ( 58193267Sjkim UINT8 Type, 59151937Sjkim UINT32 Index, 60151937Sjkim ACPI_WALK_STATE *WalkState); 61151937Sjkim 62151937Sjkimstatic ACPI_STATUS 63151937SjkimAcpiDsMethodDataSetValue ( 64193267Sjkim UINT8 Type, 65151937Sjkim UINT32 Index, 66151937Sjkim ACPI_OPERAND_OBJECT *Object, 67151937Sjkim ACPI_WALK_STATE *WalkState); 68151937Sjkim 69151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS 70151937SjkimACPI_OBJECT_TYPE 71151937SjkimAcpiDsMethodDataGetType ( 72151937Sjkim UINT16 Opcode, 73151937Sjkim UINT32 Index, 74151937Sjkim ACPI_WALK_STATE *WalkState); 75151937Sjkim#endif 76151937Sjkim 77151937Sjkim 7867754Smsmith/******************************************************************************* 7967754Smsmith * 8067754Smsmith * FUNCTION: AcpiDsMethodDataInit 8167754Smsmith * 8271867Smsmith * PARAMETERS: WalkState - Current walk state object 8367754Smsmith * 8467754Smsmith * RETURN: Status 8567754Smsmith * 8667754Smsmith * DESCRIPTION: Initialize the data structures that hold the method's arguments 87241973Sjkim * and locals. The data struct is an array of namespace nodes for 88151937Sjkim * each - this allows RefOf and DeRefOf to work properly for these 8967754Smsmith * special data types. 9067754Smsmith * 9187031Smsmith * NOTES: WalkState fields are initialized to zero by the 92167802Sjkim * ACPI_ALLOCATE_ZEROED(). 9387031Smsmith * 9487031Smsmith * A pseudo-Namespace Node is assigned to each argument and local 9587031Smsmith * so that RefOf() can return a pointer to the Node. 9687031Smsmith * 9767754Smsmith ******************************************************************************/ 9867754Smsmith 9999679Siwasakivoid 10067754SmsmithAcpiDsMethodDataInit ( 10167754Smsmith ACPI_WALK_STATE *WalkState) 10267754Smsmith{ 10367754Smsmith UINT32 i; 10467754Smsmith 10567754Smsmith 106167802Sjkim ACPI_FUNCTION_TRACE (DsMethodDataInit); 10767754Smsmith 10867754Smsmith 10967754Smsmith /* Init the method arguments */ 11067754Smsmith 111114237Snjl for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) 11267754Smsmith { 113306536Sjkim ACPI_MOVE_32_TO_32 (&WalkState->Arguments[i].Name, 114306536Sjkim NAMEOF_ARG_NTE); 115306536Sjkim 11699146Siwasaki WalkState->Arguments[i].Name.Integer |= (i << 24); 117167802Sjkim WalkState->Arguments[i].DescriptorType = ACPI_DESC_TYPE_NAMED; 118167802Sjkim WalkState->Arguments[i].Type = ACPI_TYPE_ANY; 119209746Sjkim WalkState->Arguments[i].Flags = ANOBJ_METHOD_ARG; 12067754Smsmith } 12167754Smsmith 12267754Smsmith /* Init the method locals */ 12367754Smsmith 124114237Snjl for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) 12567754Smsmith { 126306536Sjkim ACPI_MOVE_32_TO_32 (&WalkState->LocalVariables[i].Name, 127306536Sjkim NAMEOF_LOCAL_NTE); 12867754Smsmith 12999146Siwasaki WalkState->LocalVariables[i].Name.Integer |= (i << 24); 130167802Sjkim WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED; 131167802Sjkim WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY; 132209746Sjkim WalkState->LocalVariables[i].Flags = ANOBJ_METHOD_LOCAL; 13367754Smsmith } 13467754Smsmith 13599679Siwasaki return_VOID; 13667754Smsmith} 13767754Smsmith 13867754Smsmith 13967754Smsmith/******************************************************************************* 14067754Smsmith * 14167754Smsmith * FUNCTION: AcpiDsMethodDataDeleteAll 14267754Smsmith * 14371867Smsmith * PARAMETERS: WalkState - Current walk state object 14467754Smsmith * 14599679Siwasaki * RETURN: None 14667754Smsmith * 147241973Sjkim * DESCRIPTION: Delete method locals and arguments. Arguments are only 14867754Smsmith * deleted if this method was called from another method. 14967754Smsmith * 15067754Smsmith ******************************************************************************/ 15167754Smsmith 15299679Siwasakivoid 15367754SmsmithAcpiDsMethodDataDeleteAll ( 15467754Smsmith ACPI_WALK_STATE *WalkState) 15567754Smsmith{ 15667754Smsmith UINT32 Index; 15767754Smsmith 15867754Smsmith 159167802Sjkim ACPI_FUNCTION_TRACE (DsMethodDataDeleteAll); 16067754Smsmith 16167754Smsmith 16287031Smsmith /* Detach the locals */ 16367754Smsmith 164114237Snjl for (Index = 0; Index < ACPI_METHOD_NUM_LOCALS; Index++) 16567754Smsmith { 16687031Smsmith if (WalkState->LocalVariables[Index].Object) 16767754Smsmith { 168209746Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%u=%p\n", 169306536Sjkim Index, WalkState->LocalVariables[Index].Object)); 17067754Smsmith 17187031Smsmith /* Detach object (if present) and remove a reference */ 17267754Smsmith 17387031Smsmith AcpiNsDetachObject (&WalkState->LocalVariables[Index]); 17499679Siwasaki } 17567754Smsmith } 17667754Smsmith 17787031Smsmith /* Detach the arguments */ 17867754Smsmith 179114237Snjl for (Index = 0; Index < ACPI_METHOD_NUM_ARGS; Index++) 18067754Smsmith { 18187031Smsmith if (WalkState->Arguments[Index].Object) 18267754Smsmith { 183209746Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%u=%p\n", 184306536Sjkim Index, WalkState->Arguments[Index].Object)); 18567754Smsmith 18687031Smsmith /* Detach object (if present) and remove a reference */ 18767754Smsmith 18887031Smsmith AcpiNsDetachObject (&WalkState->Arguments[Index]); 18967754Smsmith } 19067754Smsmith } 19167754Smsmith 19299679Siwasaki return_VOID; 19367754Smsmith} 19467754Smsmith 19567754Smsmith 19667754Smsmith/******************************************************************************* 19767754Smsmith * 19867754Smsmith * FUNCTION: AcpiDsMethodDataInitArgs 19967754Smsmith * 20071867Smsmith * PARAMETERS: *Params - Pointer to a parameter list for the method 20171867Smsmith * MaxParamCount - The arg count for this method 20271867Smsmith * WalkState - Current walk state object 20367754Smsmith * 20467754Smsmith * RETURN: Status 20567754Smsmith * 206241973Sjkim * DESCRIPTION: Initialize arguments for a method. The parameter list is a list 20787031Smsmith * of ACPI operand objects, either null terminated or whose length 20887031Smsmith * is defined by MaxParamCount. 20967754Smsmith * 21067754Smsmith ******************************************************************************/ 21167754Smsmith 21267754SmsmithACPI_STATUS 21367754SmsmithAcpiDsMethodDataInitArgs ( 21467754Smsmith ACPI_OPERAND_OBJECT **Params, 21567754Smsmith UINT32 MaxParamCount, 21667754Smsmith ACPI_WALK_STATE *WalkState) 21767754Smsmith{ 21867754Smsmith ACPI_STATUS Status; 21987031Smsmith UINT32 Index = 0; 22067754Smsmith 22167754Smsmith 222167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsMethodDataInitArgs, Params); 22367754Smsmith 22467754Smsmith 22567754Smsmith if (!Params) 22667754Smsmith { 227306536Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 228306536Sjkim "No parameter list passed to method\n")); 22967754Smsmith return_ACPI_STATUS (AE_OK); 23067754Smsmith } 23167754Smsmith 232151937Sjkim /* Copy passed parameters into the new method stack frame */ 23367754Smsmith 234151937Sjkim while ((Index < ACPI_METHOD_NUM_ARGS) && 235151937Sjkim (Index < MaxParamCount) && 236151937Sjkim Params[Index]) 23767754Smsmith { 23887031Smsmith /* 23987031Smsmith * A valid parameter. 240126372Snjl * Store the argument in the method/walk descriptor. 241126372Snjl * Do not copy the arg in order to implement call by reference 24287031Smsmith */ 243306536Sjkim Status = AcpiDsMethodDataSetValue ( 244306536Sjkim ACPI_REFCLASS_ARG, Index, Params[Index], WalkState); 24587031Smsmith if (ACPI_FAILURE (Status)) 24667754Smsmith { 24787031Smsmith return_ACPI_STATUS (Status); 24867754Smsmith } 24967754Smsmith 25087031Smsmith Index++; 25167754Smsmith } 25267754Smsmith 253209746Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%u args passed to method\n", Index)); 25467754Smsmith return_ACPI_STATUS (AE_OK); 25567754Smsmith} 25667754Smsmith 25767754Smsmith 25867754Smsmith/******************************************************************************* 25967754Smsmith * 26087031Smsmith * FUNCTION: AcpiDsMethodDataGetNode 26167754Smsmith * 262193267Sjkim * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 263193267Sjkim * ACPI_REFCLASS_ARG 264151937Sjkim * Index - Which Local or Arg whose type to get 26571867Smsmith * WalkState - Current walk state object 266151937Sjkim * Node - Where the node is returned. 26767754Smsmith * 268151937Sjkim * RETURN: Status and node 26967754Smsmith * 270151937Sjkim * DESCRIPTION: Get the Node associated with a local or arg. 271151937Sjkim * 27267754Smsmith ******************************************************************************/ 27367754Smsmith 27467754SmsmithACPI_STATUS 27587031SmsmithAcpiDsMethodDataGetNode ( 276193267Sjkim UINT8 Type, 27767754Smsmith UINT32 Index, 27867754Smsmith ACPI_WALK_STATE *WalkState, 27987031Smsmith ACPI_NAMESPACE_NODE **Node) 28067754Smsmith{ 281167802Sjkim ACPI_FUNCTION_TRACE (DsMethodDataGetNode); 28267754Smsmith 28367754Smsmith 28467754Smsmith /* 28587031Smsmith * Method Locals and Arguments are supported 28667754Smsmith */ 287193267Sjkim switch (Type) 28867754Smsmith { 289193267Sjkim case ACPI_REFCLASS_LOCAL: 29067754Smsmith 291114237Snjl if (Index > ACPI_METHOD_MAX_LOCAL) 29267754Smsmith { 293167802Sjkim ACPI_ERROR ((AE_INFO, 294204773Sjkim "Local index %u is invalid (max %u)", 295114237Snjl Index, ACPI_METHOD_MAX_LOCAL)); 29687031Smsmith return_ACPI_STATUS (AE_AML_INVALID_INDEX); 29767754Smsmith } 29867754Smsmith 29987031Smsmith /* Return a pointer to the pseudo-node */ 30087031Smsmith 30187031Smsmith *Node = &WalkState->LocalVariables[Index]; 30267754Smsmith break; 30367754Smsmith 304193267Sjkim case ACPI_REFCLASS_ARG: 30567754Smsmith 306114237Snjl if (Index > ACPI_METHOD_MAX_ARG) 30767754Smsmith { 308167802Sjkim ACPI_ERROR ((AE_INFO, 309204773Sjkim "Arg index %u is invalid (max %u)", 310114237Snjl Index, ACPI_METHOD_MAX_ARG)); 31187031Smsmith return_ACPI_STATUS (AE_AML_INVALID_INDEX); 31267754Smsmith } 31367754Smsmith 31487031Smsmith /* Return a pointer to the pseudo-node */ 31587031Smsmith 31687031Smsmith *Node = &WalkState->Arguments[Index]; 31767754Smsmith break; 31867754Smsmith 31967754Smsmith default: 320250838Sjkim 321204773Sjkim ACPI_ERROR ((AE_INFO, "Type %u is invalid", Type)); 322193267Sjkim return_ACPI_STATUS (AE_TYPE); 32367754Smsmith } 32467754Smsmith 32567754Smsmith return_ACPI_STATUS (AE_OK); 32667754Smsmith} 32767754Smsmith 32867754Smsmith 32967754Smsmith/******************************************************************************* 33067754Smsmith * 33187031Smsmith * FUNCTION: AcpiDsMethodDataSetValue 33267754Smsmith * 333193267Sjkim * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 334193267Sjkim * ACPI_REFCLASS_ARG 335151937Sjkim * Index - Which Local or Arg to get 33667754Smsmith * Object - Object to be inserted into the stack entry 33771867Smsmith * WalkState - Current walk state object 33867754Smsmith * 33967754Smsmith * RETURN: Status 34067754Smsmith * 34177424Smsmith * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index. 342114237Snjl * Note: There is no "implicit conversion" for locals. 34367754Smsmith * 34467754Smsmith ******************************************************************************/ 34567754Smsmith 346151937Sjkimstatic ACPI_STATUS 34787031SmsmithAcpiDsMethodDataSetValue ( 348193267Sjkim UINT8 Type, 34967754Smsmith UINT32 Index, 35067754Smsmith ACPI_OPERAND_OBJECT *Object, 35167754Smsmith ACPI_WALK_STATE *WalkState) 35267754Smsmith{ 35367754Smsmith ACPI_STATUS Status; 35487031Smsmith ACPI_NAMESPACE_NODE *Node; 35567754Smsmith 35667754Smsmith 357167802Sjkim ACPI_FUNCTION_TRACE (DsMethodDataSetValue); 35867754Smsmith 35983174Smsmith 360114237Snjl ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 361209746Sjkim "NewObj %p Type %2.2X, Refs=%u [%s]\n", Object, 362193267Sjkim Type, Object->Common.ReferenceCount, 363114237Snjl AcpiUtGetTypeName (Object->Common.Type))); 364114237Snjl 36587031Smsmith /* Get the namespace node for the arg/local */ 36667754Smsmith 367193267Sjkim Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 36867754Smsmith if (ACPI_FAILURE (Status)) 36967754Smsmith { 37067754Smsmith return_ACPI_STATUS (Status); 37167754Smsmith } 37267754Smsmith 373123315Snjl /* 374122945Snjl * Increment ref count so object can't be deleted while installed. 375122945Snjl * NOTE: We do not copy the object in order to preserve the call by 376122945Snjl * reference semantics of ACPI Control Method invocation. 377122945Snjl * (See ACPI Specification 2.0C) 378114237Snjl */ 379122945Snjl AcpiUtAddReference (Object); 38067754Smsmith 381114237Snjl /* Install the object */ 382114237Snjl 383122945Snjl Node->Object = Object; 384114237Snjl return_ACPI_STATUS (Status); 38567754Smsmith} 38667754Smsmith 38767754Smsmith 38867754Smsmith/******************************************************************************* 38967754Smsmith * 39067754Smsmith * FUNCTION: AcpiDsMethodDataGetValue 39167754Smsmith * 392193267Sjkim * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 393193267Sjkim * ACPI_REFCLASS_ARG 39467754Smsmith * Index - Which localVar or argument to get 39571867Smsmith * WalkState - Current walk state object 396151937Sjkim * DestDesc - Where Arg or Local value is returned 39767754Smsmith * 39867754Smsmith * RETURN: Status 39967754Smsmith * 400151937Sjkim * DESCRIPTION: Retrieve value of selected Arg or Local for this method 40177424Smsmith * Used only in AcpiExResolveToValue(). 40267754Smsmith * 40367754Smsmith ******************************************************************************/ 40467754Smsmith 40567754SmsmithACPI_STATUS 40667754SmsmithAcpiDsMethodDataGetValue ( 407193267Sjkim UINT8 Type, 40867754Smsmith UINT32 Index, 40967754Smsmith ACPI_WALK_STATE *WalkState, 41067754Smsmith ACPI_OPERAND_OBJECT **DestDesc) 41167754Smsmith{ 41267754Smsmith ACPI_STATUS Status; 41387031Smsmith ACPI_NAMESPACE_NODE *Node; 41467754Smsmith ACPI_OPERAND_OBJECT *Object; 41567754Smsmith 41667754Smsmith 417167802Sjkim ACPI_FUNCTION_TRACE (DsMethodDataGetValue); 41867754Smsmith 41967754Smsmith 42067754Smsmith /* Validate the object descriptor */ 42167754Smsmith 42267754Smsmith if (!DestDesc) 42367754Smsmith { 424167802Sjkim ACPI_ERROR ((AE_INFO, "Null object descriptor pointer")); 42567754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 42667754Smsmith } 42767754Smsmith 42887031Smsmith /* Get the namespace node for the arg/local */ 42967754Smsmith 430193267Sjkim Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 43167754Smsmith if (ACPI_FAILURE (Status)) 43267754Smsmith { 43367754Smsmith return_ACPI_STATUS (Status); 43467754Smsmith } 43567754Smsmith 43687031Smsmith /* Get the object from the node */ 43767754Smsmith 43887031Smsmith Object = Node->Object; 43967754Smsmith 44067754Smsmith /* Examine the returned object, it must be valid. */ 44167754Smsmith 44267754Smsmith if (!Object) 44367754Smsmith { 44467754Smsmith /* 44587031Smsmith * Index points to uninitialized object. 44667754Smsmith * This means that either 1) The expected argument was 44767754Smsmith * not passed to the method, or 2) A local variable 44867754Smsmith * was referenced by the method (via the ASL) 449241973Sjkim * before it was initialized. Either case is an error. 45067754Smsmith */ 451138287Smarks 452138287Smarks /* If slack enabled, init the LocalX/ArgX to an Integer of value zero */ 453138287Smarks 454138287Smarks if (AcpiGbl_EnableInterpreterSlack) 45567754Smsmith { 456199337Sjkim Object = AcpiUtCreateIntegerObject ((UINT64) 0); 457138287Smarks if (!Object) 458138287Smarks { 459138287Smarks return_ACPI_STATUS (AE_NO_MEMORY); 460138287Smarks } 461138287Smarks 462138287Smarks Node->Object = Object; 463138287Smarks } 464138287Smarks 465138287Smarks /* Otherwise, return the error */ 466138287Smarks 467193267Sjkim else switch (Type) 468138287Smarks { 469193267Sjkim case ACPI_REFCLASS_ARG: 47071867Smsmith 471167802Sjkim ACPI_ERROR ((AE_INFO, 472204773Sjkim "Uninitialized Arg[%u] at node %p", 47387031Smsmith Index, Node)); 47471867Smsmith 47567754Smsmith return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG); 47667754Smsmith 477193267Sjkim case ACPI_REFCLASS_LOCAL: 478197104Sjkim /* 479197104Sjkim * No error message for this case, will be trapped again later to 480197104Sjkim * detect and ignore cases of Store(LocalX,LocalX) 481197104Sjkim */ 48267754Smsmith return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL); 48399679Siwasaki 48499679Siwasaki default: 485193267Sjkim 486204773Sjkim ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: 0x%X", Type)); 48799679Siwasaki return_ACPI_STATUS (AE_AML_INTERNAL); 48867754Smsmith } 48967754Smsmith } 49067754Smsmith 49167754Smsmith /* 49287031Smsmith * The Index points to an initialized and valid object. 49367754Smsmith * Return an additional reference to the object 49467754Smsmith */ 49567754Smsmith *DestDesc = Object; 49677424Smsmith AcpiUtAddReference (Object); 49767754Smsmith 49867754Smsmith return_ACPI_STATUS (AE_OK); 49967754Smsmith} 50067754Smsmith 50167754Smsmith 50267754Smsmith/******************************************************************************* 50367754Smsmith * 50467754Smsmith * FUNCTION: AcpiDsMethodDataDeleteValue 50567754Smsmith * 506193267Sjkim * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 507193267Sjkim * ACPI_REFCLASS_ARG 50867754Smsmith * Index - Which localVar or argument to delete 50971867Smsmith * WalkState - Current walk state object 51067754Smsmith * 51199679Siwasaki * RETURN: None 51267754Smsmith * 513241973Sjkim * DESCRIPTION: Delete the entry at Opcode:Index. Inserts 51467754Smsmith * a null into the stack slot after the object is deleted. 51567754Smsmith * 51667754Smsmith ******************************************************************************/ 51767754Smsmith 518151937Sjkimstatic void 51967754SmsmithAcpiDsMethodDataDeleteValue ( 520193267Sjkim UINT8 Type, 52167754Smsmith UINT32 Index, 52267754Smsmith ACPI_WALK_STATE *WalkState) 52367754Smsmith{ 52467754Smsmith ACPI_STATUS Status; 52587031Smsmith ACPI_NAMESPACE_NODE *Node; 52667754Smsmith ACPI_OPERAND_OBJECT *Object; 52767754Smsmith 52867754Smsmith 529167802Sjkim ACPI_FUNCTION_TRACE (DsMethodDataDeleteValue); 53067754Smsmith 53167754Smsmith 53287031Smsmith /* Get the namespace node for the arg/local */ 53367754Smsmith 534193267Sjkim Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 53567754Smsmith if (ACPI_FAILURE (Status)) 53667754Smsmith { 53799679Siwasaki return_VOID; 53867754Smsmith } 53967754Smsmith 54087031Smsmith /* Get the associated object */ 54167754Smsmith 54287031Smsmith Object = AcpiNsGetAttachedObject (Node); 54367754Smsmith 54467754Smsmith /* 54567754Smsmith * Undefine the Arg or Local by setting its descriptor 54667754Smsmith * pointer to NULL. Locals/Args can contain both 54767754Smsmith * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs 54867754Smsmith */ 54987031Smsmith Node->Object = NULL; 55067754Smsmith 55167754Smsmith if ((Object) && 55299679Siwasaki (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_OPERAND)) 55367754Smsmith { 55467754Smsmith /* 55587031Smsmith * There is a valid object. 55667754Smsmith * Decrement the reference count by one to balance the 55787031Smsmith * increment when the object was stored. 55867754Smsmith */ 55977424Smsmith AcpiUtRemoveReference (Object); 56067754Smsmith } 56167754Smsmith 56299679Siwasaki return_VOID; 56367754Smsmith} 56467754Smsmith 56567754Smsmith 56667754Smsmith/******************************************************************************* 56767754Smsmith * 56877424Smsmith * FUNCTION: AcpiDsStoreObjectToLocal 56967754Smsmith * 570193267Sjkim * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 571193267Sjkim * ACPI_REFCLASS_ARG 572151937Sjkim * Index - Which Local or Arg to set 57387031Smsmith * ObjDesc - Value to be stored 57471867Smsmith * WalkState - Current walk state 57567754Smsmith * 57667754Smsmith * RETURN: Status 57767754Smsmith * 578241973Sjkim * DESCRIPTION: Store a value in an Arg or Local. The ObjDesc is installed 57967754Smsmith * as the new value for the Arg or Local and the reference count 58087031Smsmith * for ObjDesc is incremented. 58167754Smsmith * 58267754Smsmith ******************************************************************************/ 58367754Smsmith 58467754SmsmithACPI_STATUS 58577424SmsmithAcpiDsStoreObjectToLocal ( 586193267Sjkim UINT8 Type, 58767754Smsmith UINT32 Index, 58887031Smsmith ACPI_OPERAND_OBJECT *ObjDesc, 58967754Smsmith ACPI_WALK_STATE *WalkState) 59067754Smsmith{ 59167754Smsmith ACPI_STATUS Status; 59287031Smsmith ACPI_NAMESPACE_NODE *Node; 59387031Smsmith ACPI_OPERAND_OBJECT *CurrentObjDesc; 594123315Snjl ACPI_OPERAND_OBJECT *NewObjDesc; 59567754Smsmith 59667754Smsmith 597167802Sjkim ACPI_FUNCTION_TRACE (DsStoreObjectToLocal); 598209746Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n", 599193267Sjkim Type, Index, ObjDesc)); 60067754Smsmith 60167754Smsmith /* Parameter validation */ 60267754Smsmith 60387031Smsmith if (!ObjDesc) 60467754Smsmith { 60567754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 60667754Smsmith } 60767754Smsmith 60887031Smsmith /* Get the namespace node for the arg/local */ 60967754Smsmith 610193267Sjkim Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 61167754Smsmith if (ACPI_FAILURE (Status)) 61267754Smsmith { 61387031Smsmith return_ACPI_STATUS (Status); 61467754Smsmith } 61567754Smsmith 61687031Smsmith CurrentObjDesc = AcpiNsGetAttachedObject (Node); 61787031Smsmith if (CurrentObjDesc == ObjDesc) 61867754Smsmith { 619114237Snjl ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n", 620114237Snjl ObjDesc)); 62187031Smsmith return_ACPI_STATUS (Status); 62267754Smsmith } 62367754Smsmith 62467754Smsmith /* 625123315Snjl * If the reference count on the object is more than one, we must 626241973Sjkim * take a copy of the object before we store. A reference count 627126372Snjl * of exactly 1 means that the object was just created during the 628126372Snjl * evaluation of an expression, and we can safely use it since it 629126372Snjl * is not used anywhere else. 630123315Snjl */ 631123315Snjl NewObjDesc = ObjDesc; 632126372Snjl if (ObjDesc->Common.ReferenceCount > 1) 633123315Snjl { 634306536Sjkim Status = AcpiUtCopyIobjectToIobject ( 635306536Sjkim ObjDesc, &NewObjDesc, WalkState); 636123315Snjl if (ACPI_FAILURE (Status)) 637123315Snjl { 638123315Snjl return_ACPI_STATUS (Status); 639123315Snjl } 640123315Snjl } 641123315Snjl 642123315Snjl /* 64367754Smsmith * If there is an object already in this slot, we either 64467754Smsmith * have to delete it, or if this is an argument and there 64567754Smsmith * is an object reference stored there, we have to do 64667754Smsmith * an indirect store! 64767754Smsmith */ 64887031Smsmith if (CurrentObjDesc) 64967754Smsmith { 65067754Smsmith /* 65167754Smsmith * Check for an indirect store if an argument 65267754Smsmith * contains an object reference (stored as an Node). 65367754Smsmith * We don't allow this automatic dereferencing for 65467754Smsmith * locals, since a store to a local should overwrite 65567754Smsmith * anything there, including an object reference. 65667754Smsmith * 65767754Smsmith * If both Arg0 and Local0 contain RefOf (Local4): 65867754Smsmith * 65967754Smsmith * Store (1, Arg0) - Causes indirect store to local4 66067754Smsmith * Store (1, Local0) - Stores 1 in local0, overwriting 66167754Smsmith * the reference to local4 66267754Smsmith * Store (1, DeRefof (Local0)) - Causes indirect store to local4 66367754Smsmith * 66467754Smsmith * Weird, but true. 66567754Smsmith */ 666193267Sjkim if (Type == ACPI_REFCLASS_ARG) 66767754Smsmith { 668114237Snjl /* 669151937Sjkim * If we have a valid reference object that came from RefOf(), 670151937Sjkim * do the indirect store 671102550Siwasaki */ 672306536Sjkim if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) == 673306536Sjkim ACPI_DESC_TYPE_OPERAND) && 674306536Sjkim (CurrentObjDesc->Common.Type == 675306536Sjkim ACPI_TYPE_LOCAL_REFERENCE) && 676306536Sjkim (CurrentObjDesc->Reference.Class == 677306536Sjkim ACPI_REFCLASS_REFOF)) 678102550Siwasaki { 679102550Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 680306536Sjkim "Arg (%p) is an ObjRef(Node), storing in node %p\n", 681306536Sjkim NewObjDesc, CurrentObjDesc)); 68267754Smsmith 683102550Siwasaki /* 684128212Snjl * Store this object to the Node (perform the indirect store) 685128212Snjl * NOTE: No implicit conversion is performed, as per the ACPI 686128212Snjl * specification rules on storing to Locals/Args. 687102550Siwasaki */ 688123315Snjl Status = AcpiExStoreObjectToNode (NewObjDesc, 689306536Sjkim CurrentObjDesc->Reference.Object, WalkState, 690306536Sjkim ACPI_NO_IMPLICIT_CONVERSION); 691123315Snjl 692123315Snjl /* Remove local reference if we copied the object above */ 693123315Snjl 694123315Snjl if (NewObjDesc != ObjDesc) 695123315Snjl { 696123315Snjl AcpiUtRemoveReference (NewObjDesc); 697123315Snjl } 698306536Sjkim 699102550Siwasaki return_ACPI_STATUS (Status); 700102550Siwasaki } 70167754Smsmith } 70267754Smsmith 703193267Sjkim /* Delete the existing object before storing the new one */ 704193267Sjkim 705193267Sjkim AcpiDsMethodDataDeleteValue (Type, Index, WalkState); 70667754Smsmith } 70767754Smsmith 70867754Smsmith /* 709123315Snjl * Install the Obj descriptor (*NewObjDesc) into 71067754Smsmith * the descriptor for the Arg or Local. 71167754Smsmith * (increments the object reference count by one) 71267754Smsmith */ 713193267Sjkim Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState); 714123315Snjl 715123315Snjl /* Remove local reference if we copied the object above */ 716123315Snjl 717123315Snjl if (NewObjDesc != ObjDesc) 718123315Snjl { 719123315Snjl AcpiUtRemoveReference (NewObjDesc); 720123315Snjl } 721123315Snjl 72267754Smsmith return_ACPI_STATUS (Status); 72367754Smsmith} 72467754Smsmith 72587031Smsmith 726151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS 727151937Sjkim/******************************************************************************* 728151937Sjkim * 729151937Sjkim * FUNCTION: AcpiDsMethodDataGetType 730151937Sjkim * 731151937Sjkim * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP 732151937Sjkim * Index - Which Local or Arg whose type to get 733151937Sjkim * WalkState - Current walk state object 734151937Sjkim * 735151937Sjkim * RETURN: Data type of current value of the selected Arg or Local 736151937Sjkim * 737151937Sjkim * DESCRIPTION: Get the type of the object stored in the Local or Arg 738151937Sjkim * 739151937Sjkim ******************************************************************************/ 740151937Sjkim 741151937SjkimACPI_OBJECT_TYPE 742151937SjkimAcpiDsMethodDataGetType ( 743151937Sjkim UINT16 Opcode, 744151937Sjkim UINT32 Index, 745151937Sjkim ACPI_WALK_STATE *WalkState) 746151937Sjkim{ 747151937Sjkim ACPI_STATUS Status; 748151937Sjkim ACPI_NAMESPACE_NODE *Node; 749151937Sjkim ACPI_OPERAND_OBJECT *Object; 750151937Sjkim 751151937Sjkim 752167802Sjkim ACPI_FUNCTION_TRACE (DsMethodDataGetType); 753151937Sjkim 754151937Sjkim 755151937Sjkim /* Get the namespace node for the arg/local */ 756151937Sjkim 757151937Sjkim Status = AcpiDsMethodDataGetNode (Opcode, Index, WalkState, &Node); 758151937Sjkim if (ACPI_FAILURE (Status)) 759151937Sjkim { 760151937Sjkim return_VALUE ((ACPI_TYPE_NOT_FOUND)); 761151937Sjkim } 762151937Sjkim 763151937Sjkim /* Get the object */ 764151937Sjkim 765151937Sjkim Object = AcpiNsGetAttachedObject (Node); 766151937Sjkim if (!Object) 767151937Sjkim { 768151937Sjkim /* Uninitialized local/arg, return TYPE_ANY */ 769151937Sjkim 770151937Sjkim return_VALUE (ACPI_TYPE_ANY); 771151937Sjkim } 772151937Sjkim 773151937Sjkim /* Get the object type */ 774151937Sjkim 775193267Sjkim return_VALUE (Object->Type); 776151937Sjkim} 777151937Sjkim#endif 778