167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: dsmthdat - control method arguments and local variables 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 7217365Sjkim/* 8245582Sjkim * Copyright (C) 2000 - 2013, 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 4467754Smsmith#define __DSMTHDAT_C__ 4567754Smsmith 46193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 47193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 48193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 50193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 5167754Smsmith 5267754Smsmith 5377424Smsmith#define _COMPONENT ACPI_DISPATCHER 5491116Smsmith ACPI_MODULE_NAME ("dsmthdat") 5567754Smsmith 56151937Sjkim/* Local prototypes */ 5767754Smsmith 58151937Sjkimstatic void 59151937SjkimAcpiDsMethodDataDeleteValue ( 60193267Sjkim UINT8 Type, 61151937Sjkim UINT32 Index, 62151937Sjkim ACPI_WALK_STATE *WalkState); 63151937Sjkim 64151937Sjkimstatic ACPI_STATUS 65151937SjkimAcpiDsMethodDataSetValue ( 66193267Sjkim UINT8 Type, 67151937Sjkim UINT32 Index, 68151937Sjkim ACPI_OPERAND_OBJECT *Object, 69151937Sjkim ACPI_WALK_STATE *WalkState); 70151937Sjkim 71151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS 72151937SjkimACPI_OBJECT_TYPE 73151937SjkimAcpiDsMethodDataGetType ( 74151937Sjkim UINT16 Opcode, 75151937Sjkim UINT32 Index, 76151937Sjkim ACPI_WALK_STATE *WalkState); 77151937Sjkim#endif 78151937Sjkim 79151937Sjkim 8067754Smsmith/******************************************************************************* 8167754Smsmith * 8267754Smsmith * FUNCTION: AcpiDsMethodDataInit 8367754Smsmith * 8471867Smsmith * PARAMETERS: WalkState - Current walk state object 8567754Smsmith * 8667754Smsmith * RETURN: Status 8767754Smsmith * 8867754Smsmith * DESCRIPTION: Initialize the data structures that hold the method's arguments 89241973Sjkim * and locals. The data struct is an array of namespace nodes for 90151937Sjkim * each - this allows RefOf and DeRefOf to work properly for these 9167754Smsmith * special data types. 9267754Smsmith * 9387031Smsmith * NOTES: WalkState fields are initialized to zero by the 94167802Sjkim * ACPI_ALLOCATE_ZEROED(). 9587031Smsmith * 9687031Smsmith * A pseudo-Namespace Node is assigned to each argument and local 9787031Smsmith * so that RefOf() can return a pointer to the Node. 9887031Smsmith * 9967754Smsmith ******************************************************************************/ 10067754Smsmith 10199679Siwasakivoid 10267754SmsmithAcpiDsMethodDataInit ( 10367754Smsmith ACPI_WALK_STATE *WalkState) 10467754Smsmith{ 10567754Smsmith UINT32 i; 10667754Smsmith 10767754Smsmith 108167802Sjkim ACPI_FUNCTION_TRACE (DsMethodDataInit); 10967754Smsmith 11067754Smsmith 11167754Smsmith /* Init the method arguments */ 11267754Smsmith 113114237Snjl for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) 11467754Smsmith { 115167802Sjkim ACPI_MOVE_32_TO_32 (&WalkState->Arguments[i].Name, NAMEOF_ARG_NTE); 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 { 126167802Sjkim ACPI_MOVE_32_TO_32 (&WalkState->LocalVariables[i].Name, NAMEOF_LOCAL_NTE); 12767754Smsmith 12899146Siwasaki WalkState->LocalVariables[i].Name.Integer |= (i << 24); 129167802Sjkim WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED; 130167802Sjkim WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY; 131209746Sjkim WalkState->LocalVariables[i].Flags = ANOBJ_METHOD_LOCAL; 13267754Smsmith } 13367754Smsmith 13499679Siwasaki return_VOID; 13567754Smsmith} 13667754Smsmith 13767754Smsmith 13867754Smsmith/******************************************************************************* 13967754Smsmith * 14067754Smsmith * FUNCTION: AcpiDsMethodDataDeleteAll 14167754Smsmith * 14271867Smsmith * PARAMETERS: WalkState - Current walk state object 14367754Smsmith * 14499679Siwasaki * RETURN: None 14567754Smsmith * 146241973Sjkim * DESCRIPTION: Delete method locals and arguments. Arguments are only 14767754Smsmith * deleted if this method was called from another method. 14867754Smsmith * 14967754Smsmith ******************************************************************************/ 15067754Smsmith 15199679Siwasakivoid 15267754SmsmithAcpiDsMethodDataDeleteAll ( 15367754Smsmith ACPI_WALK_STATE *WalkState) 15467754Smsmith{ 15567754Smsmith UINT32 Index; 15667754Smsmith 15767754Smsmith 158167802Sjkim ACPI_FUNCTION_TRACE (DsMethodDataDeleteAll); 15967754Smsmith 16067754Smsmith 16187031Smsmith /* Detach the locals */ 16267754Smsmith 163114237Snjl for (Index = 0; Index < ACPI_METHOD_NUM_LOCALS; Index++) 16467754Smsmith { 16587031Smsmith if (WalkState->LocalVariables[Index].Object) 16667754Smsmith { 167209746Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%u=%p\n", 16887031Smsmith Index, WalkState->LocalVariables[Index].Object)); 16967754Smsmith 17087031Smsmith /* Detach object (if present) and remove a reference */ 17167754Smsmith 17287031Smsmith AcpiNsDetachObject (&WalkState->LocalVariables[Index]); 17399679Siwasaki } 17467754Smsmith } 17567754Smsmith 17687031Smsmith /* Detach the arguments */ 17767754Smsmith 178114237Snjl for (Index = 0; Index < ACPI_METHOD_NUM_ARGS; Index++) 17967754Smsmith { 18087031Smsmith if (WalkState->Arguments[Index].Object) 18167754Smsmith { 182209746Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%u=%p\n", 18387031Smsmith Index, WalkState->Arguments[Index].Object)); 18467754Smsmith 18587031Smsmith /* Detach object (if present) and remove a reference */ 18667754Smsmith 18787031Smsmith AcpiNsDetachObject (&WalkState->Arguments[Index]); 18867754Smsmith } 18967754Smsmith } 19067754Smsmith 19199679Siwasaki return_VOID; 19267754Smsmith} 19367754Smsmith 19467754Smsmith 19567754Smsmith/******************************************************************************* 19667754Smsmith * 19767754Smsmith * FUNCTION: AcpiDsMethodDataInitArgs 19867754Smsmith * 19971867Smsmith * PARAMETERS: *Params - Pointer to a parameter list for the method 20071867Smsmith * MaxParamCount - The arg count for this method 20171867Smsmith * WalkState - Current walk state object 20267754Smsmith * 20367754Smsmith * RETURN: Status 20467754Smsmith * 205241973Sjkim * DESCRIPTION: Initialize arguments for a method. The parameter list is a list 20687031Smsmith * of ACPI operand objects, either null terminated or whose length 20787031Smsmith * is defined by MaxParamCount. 20867754Smsmith * 20967754Smsmith ******************************************************************************/ 21067754Smsmith 21167754SmsmithACPI_STATUS 21267754SmsmithAcpiDsMethodDataInitArgs ( 21367754Smsmith ACPI_OPERAND_OBJECT **Params, 21467754Smsmith UINT32 MaxParamCount, 21567754Smsmith ACPI_WALK_STATE *WalkState) 21667754Smsmith{ 21767754Smsmith ACPI_STATUS Status; 21887031Smsmith UINT32 Index = 0; 21967754Smsmith 22067754Smsmith 221167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsMethodDataInitArgs, Params); 22267754Smsmith 22367754Smsmith 22467754Smsmith if (!Params) 22567754Smsmith { 22682367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n")); 22767754Smsmith return_ACPI_STATUS (AE_OK); 22867754Smsmith } 22967754Smsmith 230151937Sjkim /* Copy passed parameters into the new method stack frame */ 23167754Smsmith 232151937Sjkim while ((Index < ACPI_METHOD_NUM_ARGS) && 233151937Sjkim (Index < MaxParamCount) && 234151937Sjkim Params[Index]) 23567754Smsmith { 23687031Smsmith /* 23787031Smsmith * A valid parameter. 238126372Snjl * Store the argument in the method/walk descriptor. 239126372Snjl * Do not copy the arg in order to implement call by reference 24087031Smsmith */ 241193267Sjkim Status = AcpiDsMethodDataSetValue (ACPI_REFCLASS_ARG, Index, 242151937Sjkim Params[Index], WalkState); 24387031Smsmith if (ACPI_FAILURE (Status)) 24467754Smsmith { 24587031Smsmith return_ACPI_STATUS (Status); 24667754Smsmith } 24767754Smsmith 24887031Smsmith Index++; 24967754Smsmith } 25067754Smsmith 251209746Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%u args passed to method\n", Index)); 25267754Smsmith return_ACPI_STATUS (AE_OK); 25367754Smsmith} 25467754Smsmith 25567754Smsmith 25667754Smsmith/******************************************************************************* 25767754Smsmith * 25887031Smsmith * FUNCTION: AcpiDsMethodDataGetNode 25967754Smsmith * 260193267Sjkim * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 261193267Sjkim * ACPI_REFCLASS_ARG 262151937Sjkim * Index - Which Local or Arg whose type to get 26371867Smsmith * WalkState - Current walk state object 264151937Sjkim * Node - Where the node is returned. 26567754Smsmith * 266151937Sjkim * RETURN: Status and node 26767754Smsmith * 268151937Sjkim * DESCRIPTION: Get the Node associated with a local or arg. 269151937Sjkim * 27067754Smsmith ******************************************************************************/ 27167754Smsmith 27267754SmsmithACPI_STATUS 27387031SmsmithAcpiDsMethodDataGetNode ( 274193267Sjkim UINT8 Type, 27567754Smsmith UINT32 Index, 27667754Smsmith ACPI_WALK_STATE *WalkState, 27787031Smsmith ACPI_NAMESPACE_NODE **Node) 27867754Smsmith{ 279167802Sjkim ACPI_FUNCTION_TRACE (DsMethodDataGetNode); 28067754Smsmith 28167754Smsmith 28267754Smsmith /* 28387031Smsmith * Method Locals and Arguments are supported 28467754Smsmith */ 285193267Sjkim switch (Type) 28667754Smsmith { 287193267Sjkim case ACPI_REFCLASS_LOCAL: 28867754Smsmith 289114237Snjl if (Index > ACPI_METHOD_MAX_LOCAL) 29067754Smsmith { 291167802Sjkim ACPI_ERROR ((AE_INFO, 292204773Sjkim "Local index %u is invalid (max %u)", 293114237Snjl Index, ACPI_METHOD_MAX_LOCAL)); 29487031Smsmith return_ACPI_STATUS (AE_AML_INVALID_INDEX); 29567754Smsmith } 29667754Smsmith 29787031Smsmith /* Return a pointer to the pseudo-node */ 29887031Smsmith 29987031Smsmith *Node = &WalkState->LocalVariables[Index]; 30067754Smsmith break; 30167754Smsmith 302193267Sjkim case ACPI_REFCLASS_ARG: 30367754Smsmith 304114237Snjl if (Index > ACPI_METHOD_MAX_ARG) 30567754Smsmith { 306167802Sjkim ACPI_ERROR ((AE_INFO, 307204773Sjkim "Arg index %u is invalid (max %u)", 308114237Snjl Index, ACPI_METHOD_MAX_ARG)); 30987031Smsmith return_ACPI_STATUS (AE_AML_INVALID_INDEX); 31067754Smsmith } 31167754Smsmith 31287031Smsmith /* Return a pointer to the pseudo-node */ 31387031Smsmith 31487031Smsmith *Node = &WalkState->Arguments[Index]; 31567754Smsmith break; 31667754Smsmith 31767754Smsmith default: 318250838Sjkim 319204773Sjkim ACPI_ERROR ((AE_INFO, "Type %u is invalid", Type)); 320193267Sjkim return_ACPI_STATUS (AE_TYPE); 32167754Smsmith } 32267754Smsmith 32367754Smsmith return_ACPI_STATUS (AE_OK); 32467754Smsmith} 32567754Smsmith 32667754Smsmith 32767754Smsmith/******************************************************************************* 32867754Smsmith * 32987031Smsmith * FUNCTION: AcpiDsMethodDataSetValue 33067754Smsmith * 331193267Sjkim * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 332193267Sjkim * ACPI_REFCLASS_ARG 333151937Sjkim * Index - Which Local or Arg to get 33467754Smsmith * Object - Object to be inserted into the stack entry 33571867Smsmith * WalkState - Current walk state object 33667754Smsmith * 33767754Smsmith * RETURN: Status 33867754Smsmith * 33977424Smsmith * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index. 340114237Snjl * Note: There is no "implicit conversion" for locals. 34167754Smsmith * 34267754Smsmith ******************************************************************************/ 34367754Smsmith 344151937Sjkimstatic ACPI_STATUS 34587031SmsmithAcpiDsMethodDataSetValue ( 346193267Sjkim UINT8 Type, 34767754Smsmith UINT32 Index, 34867754Smsmith ACPI_OPERAND_OBJECT *Object, 34967754Smsmith ACPI_WALK_STATE *WalkState) 35067754Smsmith{ 35167754Smsmith ACPI_STATUS Status; 35287031Smsmith ACPI_NAMESPACE_NODE *Node; 35367754Smsmith 35467754Smsmith 355167802Sjkim ACPI_FUNCTION_TRACE (DsMethodDataSetValue); 35667754Smsmith 35783174Smsmith 358114237Snjl ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 359209746Sjkim "NewObj %p Type %2.2X, Refs=%u [%s]\n", Object, 360193267Sjkim Type, Object->Common.ReferenceCount, 361114237Snjl AcpiUtGetTypeName (Object->Common.Type))); 362114237Snjl 36387031Smsmith /* Get the namespace node for the arg/local */ 36467754Smsmith 365193267Sjkim Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 36667754Smsmith if (ACPI_FAILURE (Status)) 36767754Smsmith { 36867754Smsmith return_ACPI_STATUS (Status); 36967754Smsmith } 37067754Smsmith 371123315Snjl /* 372122945Snjl * Increment ref count so object can't be deleted while installed. 373122945Snjl * NOTE: We do not copy the object in order to preserve the call by 374122945Snjl * reference semantics of ACPI Control Method invocation. 375122945Snjl * (See ACPI Specification 2.0C) 376114237Snjl */ 377122945Snjl AcpiUtAddReference (Object); 37867754Smsmith 379114237Snjl /* Install the object */ 380114237Snjl 381122945Snjl Node->Object = Object; 382114237Snjl return_ACPI_STATUS (Status); 38367754Smsmith} 38467754Smsmith 38567754Smsmith 38667754Smsmith/******************************************************************************* 38767754Smsmith * 38867754Smsmith * FUNCTION: AcpiDsMethodDataGetValue 38967754Smsmith * 390193267Sjkim * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 391193267Sjkim * ACPI_REFCLASS_ARG 39267754Smsmith * Index - Which localVar or argument to get 39371867Smsmith * WalkState - Current walk state object 394151937Sjkim * DestDesc - Where Arg or Local value is returned 39567754Smsmith * 39667754Smsmith * RETURN: Status 39767754Smsmith * 398151937Sjkim * DESCRIPTION: Retrieve value of selected Arg or Local for this method 39977424Smsmith * Used only in AcpiExResolveToValue(). 40067754Smsmith * 40167754Smsmith ******************************************************************************/ 40267754Smsmith 40367754SmsmithACPI_STATUS 40467754SmsmithAcpiDsMethodDataGetValue ( 405193267Sjkim UINT8 Type, 40667754Smsmith UINT32 Index, 40767754Smsmith ACPI_WALK_STATE *WalkState, 40867754Smsmith ACPI_OPERAND_OBJECT **DestDesc) 40967754Smsmith{ 41067754Smsmith ACPI_STATUS Status; 41187031Smsmith ACPI_NAMESPACE_NODE *Node; 41267754Smsmith ACPI_OPERAND_OBJECT *Object; 41367754Smsmith 41467754Smsmith 415167802Sjkim ACPI_FUNCTION_TRACE (DsMethodDataGetValue); 41667754Smsmith 41767754Smsmith 41867754Smsmith /* Validate the object descriptor */ 41967754Smsmith 42067754Smsmith if (!DestDesc) 42167754Smsmith { 422167802Sjkim ACPI_ERROR ((AE_INFO, "Null object descriptor pointer")); 42367754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 42467754Smsmith } 42567754Smsmith 42687031Smsmith /* Get the namespace node for the arg/local */ 42767754Smsmith 428193267Sjkim Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 42967754Smsmith if (ACPI_FAILURE (Status)) 43067754Smsmith { 43167754Smsmith return_ACPI_STATUS (Status); 43267754Smsmith } 43367754Smsmith 43487031Smsmith /* Get the object from the node */ 43567754Smsmith 43687031Smsmith Object = Node->Object; 43767754Smsmith 43867754Smsmith /* Examine the returned object, it must be valid. */ 43967754Smsmith 44067754Smsmith if (!Object) 44167754Smsmith { 44267754Smsmith /* 44387031Smsmith * Index points to uninitialized object. 44467754Smsmith * This means that either 1) The expected argument was 44567754Smsmith * not passed to the method, or 2) A local variable 44667754Smsmith * was referenced by the method (via the ASL) 447241973Sjkim * before it was initialized. Either case is an error. 44867754Smsmith */ 449138287Smarks 450138287Smarks /* If slack enabled, init the LocalX/ArgX to an Integer of value zero */ 451138287Smarks 452138287Smarks if (AcpiGbl_EnableInterpreterSlack) 45367754Smsmith { 454199337Sjkim Object = AcpiUtCreateIntegerObject ((UINT64) 0); 455138287Smarks if (!Object) 456138287Smarks { 457138287Smarks return_ACPI_STATUS (AE_NO_MEMORY); 458138287Smarks } 459138287Smarks 460138287Smarks Node->Object = Object; 461138287Smarks } 462138287Smarks 463138287Smarks /* Otherwise, return the error */ 464138287Smarks 465193267Sjkim else switch (Type) 466138287Smarks { 467193267Sjkim case ACPI_REFCLASS_ARG: 46871867Smsmith 469167802Sjkim ACPI_ERROR ((AE_INFO, 470204773Sjkim "Uninitialized Arg[%u] at node %p", 47187031Smsmith Index, Node)); 47271867Smsmith 47367754Smsmith return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG); 47467754Smsmith 475193267Sjkim case ACPI_REFCLASS_LOCAL: 476197104Sjkim /* 477197104Sjkim * No error message for this case, will be trapped again later to 478197104Sjkim * detect and ignore cases of Store(LocalX,LocalX) 479197104Sjkim */ 48067754Smsmith return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL); 48199679Siwasaki 48299679Siwasaki default: 483193267Sjkim 484204773Sjkim ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: 0x%X", Type)); 48599679Siwasaki return_ACPI_STATUS (AE_AML_INTERNAL); 48667754Smsmith } 48767754Smsmith } 48867754Smsmith 48967754Smsmith /* 49087031Smsmith * The Index points to an initialized and valid object. 49167754Smsmith * Return an additional reference to the object 49267754Smsmith */ 49367754Smsmith *DestDesc = Object; 49477424Smsmith AcpiUtAddReference (Object); 49567754Smsmith 49667754Smsmith return_ACPI_STATUS (AE_OK); 49767754Smsmith} 49867754Smsmith 49967754Smsmith 50067754Smsmith/******************************************************************************* 50167754Smsmith * 50267754Smsmith * FUNCTION: AcpiDsMethodDataDeleteValue 50367754Smsmith * 504193267Sjkim * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 505193267Sjkim * ACPI_REFCLASS_ARG 50667754Smsmith * Index - Which localVar or argument to delete 50771867Smsmith * WalkState - Current walk state object 50867754Smsmith * 50999679Siwasaki * RETURN: None 51067754Smsmith * 511241973Sjkim * DESCRIPTION: Delete the entry at Opcode:Index. Inserts 51267754Smsmith * a null into the stack slot after the object is deleted. 51367754Smsmith * 51467754Smsmith ******************************************************************************/ 51567754Smsmith 516151937Sjkimstatic void 51767754SmsmithAcpiDsMethodDataDeleteValue ( 518193267Sjkim UINT8 Type, 51967754Smsmith UINT32 Index, 52067754Smsmith ACPI_WALK_STATE *WalkState) 52167754Smsmith{ 52267754Smsmith ACPI_STATUS Status; 52387031Smsmith ACPI_NAMESPACE_NODE *Node; 52467754Smsmith ACPI_OPERAND_OBJECT *Object; 52567754Smsmith 52667754Smsmith 527167802Sjkim ACPI_FUNCTION_TRACE (DsMethodDataDeleteValue); 52867754Smsmith 52967754Smsmith 53087031Smsmith /* Get the namespace node for the arg/local */ 53167754Smsmith 532193267Sjkim Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 53367754Smsmith if (ACPI_FAILURE (Status)) 53467754Smsmith { 53599679Siwasaki return_VOID; 53667754Smsmith } 53767754Smsmith 53887031Smsmith /* Get the associated object */ 53967754Smsmith 54087031Smsmith Object = AcpiNsGetAttachedObject (Node); 54167754Smsmith 54267754Smsmith /* 54367754Smsmith * Undefine the Arg or Local by setting its descriptor 54467754Smsmith * pointer to NULL. Locals/Args can contain both 54567754Smsmith * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs 54667754Smsmith */ 54787031Smsmith Node->Object = NULL; 54867754Smsmith 54967754Smsmith if ((Object) && 55099679Siwasaki (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_OPERAND)) 55167754Smsmith { 55267754Smsmith /* 55387031Smsmith * There is a valid object. 55467754Smsmith * Decrement the reference count by one to balance the 55587031Smsmith * increment when the object was stored. 55667754Smsmith */ 55777424Smsmith AcpiUtRemoveReference (Object); 55867754Smsmith } 55967754Smsmith 56099679Siwasaki return_VOID; 56167754Smsmith} 56267754Smsmith 56367754Smsmith 56467754Smsmith/******************************************************************************* 56567754Smsmith * 56677424Smsmith * FUNCTION: AcpiDsStoreObjectToLocal 56767754Smsmith * 568193267Sjkim * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 569193267Sjkim * ACPI_REFCLASS_ARG 570151937Sjkim * Index - Which Local or Arg to set 57187031Smsmith * ObjDesc - Value to be stored 57271867Smsmith * WalkState - Current walk state 57367754Smsmith * 57467754Smsmith * RETURN: Status 57567754Smsmith * 576241973Sjkim * DESCRIPTION: Store a value in an Arg or Local. The ObjDesc is installed 57767754Smsmith * as the new value for the Arg or Local and the reference count 57887031Smsmith * for ObjDesc is incremented. 57967754Smsmith * 58067754Smsmith ******************************************************************************/ 58167754Smsmith 58267754SmsmithACPI_STATUS 58377424SmsmithAcpiDsStoreObjectToLocal ( 584193267Sjkim UINT8 Type, 58567754Smsmith UINT32 Index, 58687031Smsmith ACPI_OPERAND_OBJECT *ObjDesc, 58767754Smsmith ACPI_WALK_STATE *WalkState) 58867754Smsmith{ 58967754Smsmith ACPI_STATUS Status; 59087031Smsmith ACPI_NAMESPACE_NODE *Node; 59187031Smsmith ACPI_OPERAND_OBJECT *CurrentObjDesc; 592123315Snjl ACPI_OPERAND_OBJECT *NewObjDesc; 59367754Smsmith 59467754Smsmith 595167802Sjkim ACPI_FUNCTION_TRACE (DsStoreObjectToLocal); 596209746Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n", 597193267Sjkim Type, Index, ObjDesc)); 59867754Smsmith 59967754Smsmith /* Parameter validation */ 60067754Smsmith 60187031Smsmith if (!ObjDesc) 60267754Smsmith { 60367754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 60467754Smsmith } 60567754Smsmith 60687031Smsmith /* Get the namespace node for the arg/local */ 60767754Smsmith 608193267Sjkim Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 60967754Smsmith if (ACPI_FAILURE (Status)) 61067754Smsmith { 61187031Smsmith return_ACPI_STATUS (Status); 61267754Smsmith } 61367754Smsmith 61487031Smsmith CurrentObjDesc = AcpiNsGetAttachedObject (Node); 61587031Smsmith if (CurrentObjDesc == ObjDesc) 61667754Smsmith { 617114237Snjl ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n", 618114237Snjl ObjDesc)); 61987031Smsmith return_ACPI_STATUS (Status); 62067754Smsmith } 62167754Smsmith 62267754Smsmith /* 623123315Snjl * If the reference count on the object is more than one, we must 624241973Sjkim * take a copy of the object before we store. A reference count 625126372Snjl * of exactly 1 means that the object was just created during the 626126372Snjl * evaluation of an expression, and we can safely use it since it 627126372Snjl * is not used anywhere else. 628123315Snjl */ 629123315Snjl NewObjDesc = ObjDesc; 630126372Snjl if (ObjDesc->Common.ReferenceCount > 1) 631123315Snjl { 632123315Snjl Status = AcpiUtCopyIobjectToIobject (ObjDesc, &NewObjDesc, WalkState); 633123315Snjl if (ACPI_FAILURE (Status)) 634123315Snjl { 635123315Snjl return_ACPI_STATUS (Status); 636123315Snjl } 637123315Snjl } 638123315Snjl 639123315Snjl /* 64067754Smsmith * If there is an object already in this slot, we either 64167754Smsmith * have to delete it, or if this is an argument and there 64267754Smsmith * is an object reference stored there, we have to do 64367754Smsmith * an indirect store! 64467754Smsmith */ 64587031Smsmith if (CurrentObjDesc) 64667754Smsmith { 64767754Smsmith /* 64867754Smsmith * Check for an indirect store if an argument 64967754Smsmith * contains an object reference (stored as an Node). 65067754Smsmith * We don't allow this automatic dereferencing for 65167754Smsmith * locals, since a store to a local should overwrite 65267754Smsmith * anything there, including an object reference. 65367754Smsmith * 65467754Smsmith * If both Arg0 and Local0 contain RefOf (Local4): 65567754Smsmith * 65667754Smsmith * Store (1, Arg0) - Causes indirect store to local4 65767754Smsmith * Store (1, Local0) - Stores 1 in local0, overwriting 65867754Smsmith * the reference to local4 65967754Smsmith * Store (1, DeRefof (Local0)) - Causes indirect store to local4 66067754Smsmith * 66167754Smsmith * Weird, but true. 66267754Smsmith */ 663193267Sjkim if (Type == ACPI_REFCLASS_ARG) 66467754Smsmith { 665114237Snjl /* 666151937Sjkim * If we have a valid reference object that came from RefOf(), 667151937Sjkim * do the indirect store 668102550Siwasaki */ 669151937Sjkim if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) == ACPI_DESC_TYPE_OPERAND) && 670151937Sjkim (CurrentObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && 671193267Sjkim (CurrentObjDesc->Reference.Class == ACPI_REFCLASS_REFOF)) 672102550Siwasaki { 673102550Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 674123315Snjl "Arg (%p) is an ObjRef(Node), storing in node %p\n", 675123315Snjl NewObjDesc, CurrentObjDesc)); 67667754Smsmith 677102550Siwasaki /* 678128212Snjl * Store this object to the Node (perform the indirect store) 679128212Snjl * NOTE: No implicit conversion is performed, as per the ACPI 680128212Snjl * specification rules on storing to Locals/Args. 681102550Siwasaki */ 682123315Snjl Status = AcpiExStoreObjectToNode (NewObjDesc, 683128212Snjl CurrentObjDesc->Reference.Object, WalkState, 684128212Snjl ACPI_NO_IMPLICIT_CONVERSION); 685123315Snjl 686123315Snjl /* Remove local reference if we copied the object above */ 687123315Snjl 688123315Snjl if (NewObjDesc != ObjDesc) 689123315Snjl { 690123315Snjl AcpiUtRemoveReference (NewObjDesc); 691123315Snjl } 692102550Siwasaki return_ACPI_STATUS (Status); 693102550Siwasaki } 69467754Smsmith } 69567754Smsmith 696193267Sjkim /* Delete the existing object before storing the new one */ 697193267Sjkim 698193267Sjkim AcpiDsMethodDataDeleteValue (Type, Index, WalkState); 69967754Smsmith } 70067754Smsmith 70167754Smsmith /* 702123315Snjl * Install the Obj descriptor (*NewObjDesc) into 70367754Smsmith * the descriptor for the Arg or Local. 70467754Smsmith * (increments the object reference count by one) 70567754Smsmith */ 706193267Sjkim Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState); 707123315Snjl 708123315Snjl /* Remove local reference if we copied the object above */ 709123315Snjl 710123315Snjl if (NewObjDesc != ObjDesc) 711123315Snjl { 712123315Snjl AcpiUtRemoveReference (NewObjDesc); 713123315Snjl } 714123315Snjl 71567754Smsmith return_ACPI_STATUS (Status); 71667754Smsmith} 71767754Smsmith 71887031Smsmith 719151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS 720151937Sjkim/******************************************************************************* 721151937Sjkim * 722151937Sjkim * FUNCTION: AcpiDsMethodDataGetType 723151937Sjkim * 724151937Sjkim * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP 725151937Sjkim * Index - Which Local or Arg whose type to get 726151937Sjkim * WalkState - Current walk state object 727151937Sjkim * 728151937Sjkim * RETURN: Data type of current value of the selected Arg or Local 729151937Sjkim * 730151937Sjkim * DESCRIPTION: Get the type of the object stored in the Local or Arg 731151937Sjkim * 732151937Sjkim ******************************************************************************/ 733151937Sjkim 734151937SjkimACPI_OBJECT_TYPE 735151937SjkimAcpiDsMethodDataGetType ( 736151937Sjkim UINT16 Opcode, 737151937Sjkim UINT32 Index, 738151937Sjkim ACPI_WALK_STATE *WalkState) 739151937Sjkim{ 740151937Sjkim ACPI_STATUS Status; 741151937Sjkim ACPI_NAMESPACE_NODE *Node; 742151937Sjkim ACPI_OPERAND_OBJECT *Object; 743151937Sjkim 744151937Sjkim 745167802Sjkim ACPI_FUNCTION_TRACE (DsMethodDataGetType); 746151937Sjkim 747151937Sjkim 748151937Sjkim /* Get the namespace node for the arg/local */ 749151937Sjkim 750151937Sjkim Status = AcpiDsMethodDataGetNode (Opcode, Index, WalkState, &Node); 751151937Sjkim if (ACPI_FAILURE (Status)) 752151937Sjkim { 753151937Sjkim return_VALUE ((ACPI_TYPE_NOT_FOUND)); 754151937Sjkim } 755151937Sjkim 756151937Sjkim /* Get the object */ 757151937Sjkim 758151937Sjkim Object = AcpiNsGetAttachedObject (Node); 759151937Sjkim if (!Object) 760151937Sjkim { 761151937Sjkim /* Uninitialized local/arg, return TYPE_ANY */ 762151937Sjkim 763151937Sjkim return_VALUE (ACPI_TYPE_ANY); 764151937Sjkim } 765151937Sjkim 766151937Sjkim /* Get the object type */ 767151937Sjkim 768193267Sjkim return_VALUE (Object->Type); 769151937Sjkim} 770151937Sjkim#endif 771