dsmthdat.c revision 197104
168349Sobrien/******************************************************************************* 268349Sobrien * 368349Sobrien * Module Name: dsmthdat - control method arguments and local variables 468349Sobrien * 568349Sobrien ******************************************************************************/ 668349Sobrien 768349Sobrien/****************************************************************************** 868349Sobrien * 968349Sobrien * 1. Copyright Notice 1068349Sobrien * 1168349Sobrien * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 1268349Sobrien * All rights reserved. 1368349Sobrien * 1468349Sobrien * 2. License 1568349Sobrien * 1668349Sobrien * 2.1. This is your license from Intel Corp. under its intellectual property 1768349Sobrien * rights. You may have additional license terms from the party that provided 1868349Sobrien * you this software, covering your right to use that party's intellectual 1968349Sobrien * property rights. 2068349Sobrien * 2168349Sobrien * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2268349Sobrien * copy of the source code appearing in this file ("Covered Code") an 2368349Sobrien * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2468349Sobrien * base code distributed originally by Intel ("Original Intel Code") to copy, 2568349Sobrien * make derivatives, distribute, use and display any portion of the Covered 2668349Sobrien * Code in any form, with the right to sublicense such rights; and 2768349Sobrien * 2880588Sobrien * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 2968349Sobrien * license (with the right to sublicense), under only those claims of Intel 3068349Sobrien * patents that are infringed by the Original Intel Code, to make, use, sell, 3168349Sobrien * offer to sell, and import the Covered Code and derivative works thereof 3268349Sobrien * solely to the minimum extent necessary to exercise the above copyright 3368349Sobrien * license, and in no event shall the patent license extend to any additions 3474784Sobrien * to or modifications of the Original Intel Code. No other license or right 3574784Sobrien * is granted directly or by implication, estoppel or otherwise; 3680588Sobrien * 3774784Sobrien * The above copyright and patent license is granted only if the following 3874784Sobrien * conditions are met: 3974784Sobrien * 4068349Sobrien * 3. Conditions 4168349Sobrien * 4280588Sobrien * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4368349Sobrien * Redistribution of source code of any substantial portion of the Covered 4468349Sobrien * Code or modification with rights to further distribute source must include 4568349Sobrien * the above Copyright Notice, the above License, this list of Conditions, 4668349Sobrien * and the following Disclaimer and Export Compliance provision. In addition, 4768349Sobrien * Licensee must cause all Covered Code to which Licensee contributes to 4868349Sobrien * contain a file documenting the changes Licensee made to create that Covered 4975937Sobrien * Code and the date of any change. Licensee must include in that file the 5075937Sobrien * documentation of any changes made by any predecessor Licensee. Licensee 5175937Sobrien * must include a prominent statement that the modification is derived, 5275937Sobrien * directly or indirectly, from Original Intel Code. 5375937Sobrien * 5475937Sobrien * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5575937Sobrien * Redistribution of source code of any substantial portion of the Covered 5675937Sobrien * Code or modification without rights to further distribute source must 5775937Sobrien * include the following Disclaimer and Export Compliance provision in the 5868349Sobrien * documentation and/or other materials provided with distribution. In 5975937Sobrien * addition, Licensee may not authorize further sublicense of source of any 6075937Sobrien * portion of the Covered Code, and must include terms to the effect that the 6175937Sobrien * license from Licensee to its licensee is limited to the intellectual 6268349Sobrien * property embodied in the software Licensee provides to its licensee, and 6375937Sobrien * not to intellectual property embodied in modifications its licensee may 6475937Sobrien * make. 6575937Sobrien * 6675937Sobrien * 3.3. Redistribution of Executable. Redistribution in executable form of any 6768349Sobrien * substantial portion of the Covered Code or modification must reproduce the 6868349Sobrien * above Copyright Notice, and the following Disclaimer and Export Compliance 6968349Sobrien * provision in the documentation and/or other materials provided with the 7068349Sobrien * distribution. 7168349Sobrien * 7268349Sobrien * 3.4. Intel retains all right, title, and interest in and to the Original 7368349Sobrien * Intel Code. 7468349Sobrien * 7568349Sobrien * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7668349Sobrien * Intel shall be used in advertising or otherwise to promote the sale, use or 7774784Sobrien * other dealings in products derived from or relating to the Covered Code 7868349Sobrien * without prior written authorization from Intel. 7974784Sobrien * 8074784Sobrien * 4. Disclaimer and Export Compliance 8174784Sobrien * 8274784Sobrien * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8374784Sobrien * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8474784Sobrien * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8574784Sobrien * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8680588Sobrien * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8774784Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8874784Sobrien * PARTICULAR PURPOSE. 8974784Sobrien * 9074784Sobrien * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9168349Sobrien * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9268349Sobrien * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9368349Sobrien * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9474784Sobrien * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9568349Sobrien * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9680588Sobrien * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9780588Sobrien * LIMITED REMEDY. 9880588Sobrien * 9980588Sobrien * 4.3. Licensee shall not export, either directly or indirectly, any of this 10074784Sobrien * software or system incorporating such software without first obtaining any 10180588Sobrien * required license or other approval from the U. S. Department of Commerce or 10280588Sobrien * any other agency or department of the United States Government. In the 10380588Sobrien * event Licensee exports any such software from the United States or 10480588Sobrien * re-exports any such software from a foreign destination, Licensee shall 10580588Sobrien * ensure that the distribution and export/re-export of the software is in 10680588Sobrien * compliance with all laws, regulations, orders, or other restrictions of the 10780588Sobrien * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10880588Sobrien * any of its subsidiaries will export/re-export any technical data, process, 10980588Sobrien * software, or service, directly or indirectly, to any country for which the 11080588Sobrien * United States government or any agency thereof requires an export license, 11180588Sobrien * other governmental approval, or letter of assurance, without first obtaining 11280588Sobrien * such license, approval or letter. 11380588Sobrien * 11480588Sobrien *****************************************************************************/ 11580588Sobrien 11680588Sobrien#define __DSMTHDAT_C__ 11780588Sobrien 11880588Sobrien#include <contrib/dev/acpica/include/acpi.h> 11980588Sobrien#include <contrib/dev/acpica/include/accommon.h> 12080588Sobrien#include <contrib/dev/acpica/include/acdispat.h> 12180588Sobrien#include <contrib/dev/acpica/include/acnamesp.h> 12280588Sobrien#include <contrib/dev/acpica/include/acinterp.h> 12380588Sobrien 12480588Sobrien 12580588Sobrien#define _COMPONENT ACPI_DISPATCHER 12674784Sobrien ACPI_MODULE_NAME ("dsmthdat") 12774784Sobrien 12874784Sobrien/* Local prototypes */ 12974784Sobrien 13074784Sobrienstatic void 13174784SobrienAcpiDsMethodDataDeleteValue ( 13274784Sobrien UINT8 Type, 13374784Sobrien UINT32 Index, 13474784Sobrien ACPI_WALK_STATE *WalkState); 13574784Sobrien 13674784Sobrienstatic ACPI_STATUS 13774784SobrienAcpiDsMethodDataSetValue ( 13874784Sobrien UINT8 Type, 13974784Sobrien UINT32 Index, 14074784Sobrien ACPI_OPERAND_OBJECT *Object, 14174784Sobrien ACPI_WALK_STATE *WalkState); 14274784Sobrien 14374784Sobrien#ifdef ACPI_OBSOLETE_FUNCTIONS 14474784SobrienACPI_OBJECT_TYPE 14574784SobrienAcpiDsMethodDataGetType ( 14680588Sobrien UINT16 Opcode, 14774784Sobrien UINT32 Index, 14874784Sobrien ACPI_WALK_STATE *WalkState); 14974784Sobrien#endif 15074784Sobrien 15174784Sobrien 15274784Sobrien/******************************************************************************* 15374784Sobrien * 15474784Sobrien * FUNCTION: AcpiDsMethodDataInit 15574784Sobrien * 15674784Sobrien * PARAMETERS: WalkState - Current walk state object 15774784Sobrien * 15880588Sobrien * RETURN: Status 15980588Sobrien * 16074784Sobrien * DESCRIPTION: Initialize the data structures that hold the method's arguments 16174784Sobrien * and locals. The data struct is an array of namespace nodes for 16274784Sobrien * each - this allows RefOf and DeRefOf to work properly for these 16374784Sobrien * special data types. 16474784Sobrien * 16574784Sobrien * NOTES: WalkState fields are initialized to zero by the 16674784Sobrien * ACPI_ALLOCATE_ZEROED(). 16774784Sobrien * 16874784Sobrien * A pseudo-Namespace Node is assigned to each argument and local 16974784Sobrien * so that RefOf() can return a pointer to the Node. 17074784Sobrien * 17174784Sobrien ******************************************************************************/ 17274784Sobrien 17374784Sobrienvoid 17474784SobrienAcpiDsMethodDataInit ( 17574784Sobrien ACPI_WALK_STATE *WalkState) 17680588Sobrien{ 17774784Sobrien UINT32 i; 17874784Sobrien 17974784Sobrien 18068349Sobrien ACPI_FUNCTION_TRACE (DsMethodDataInit); 18174784Sobrien 18268349Sobrien 18374784Sobrien /* Init the method arguments */ 18468349Sobrien 18568349Sobrien for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) 18668349Sobrien { 18768349Sobrien ACPI_MOVE_32_TO_32 (&WalkState->Arguments[i].Name, NAMEOF_ARG_NTE); 18874784Sobrien WalkState->Arguments[i].Name.Integer |= (i << 24); 18968349Sobrien WalkState->Arguments[i].DescriptorType = ACPI_DESC_TYPE_NAMED; 19074784Sobrien WalkState->Arguments[i].Type = ACPI_TYPE_ANY; 19180588Sobrien WalkState->Arguments[i].Flags = 19280588Sobrien ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG; 19374784Sobrien } 19468349Sobrien 19568349Sobrien /* Init the method locals */ 19668349Sobrien 19768349Sobrien for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) 19868349Sobrien { 19968349Sobrien ACPI_MOVE_32_TO_32 (&WalkState->LocalVariables[i].Name, NAMEOF_LOCAL_NTE); 20068349Sobrien 20168349Sobrien WalkState->LocalVariables[i].Name.Integer |= (i << 24); 20268349Sobrien WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED; 20368349Sobrien WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY; 20474784Sobrien WalkState->LocalVariables[i].Flags = 20568349Sobrien ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL; 20668349Sobrien } 20768349Sobrien 20868349Sobrien return_VOID; 20968349Sobrien} 21068349Sobrien 21174784Sobrien 21274784Sobrien/******************************************************************************* 21368349Sobrien * 21468349Sobrien * FUNCTION: AcpiDsMethodDataDeleteAll 21568349Sobrien * 21668349Sobrien * PARAMETERS: WalkState - Current walk state object 21768349Sobrien * 21868349Sobrien * RETURN: None 21974784Sobrien * 22074784Sobrien * DESCRIPTION: Delete method locals and arguments. Arguments are only 22174784Sobrien * deleted if this method was called from another method. 22268349Sobrien * 22374784Sobrien ******************************************************************************/ 22474784Sobrien 22574784Sobrienvoid 22668349SobrienAcpiDsMethodDataDeleteAll ( 22774784Sobrien ACPI_WALK_STATE *WalkState) 22868349Sobrien{ 22968349Sobrien UINT32 Index; 23068349Sobrien 23168349Sobrien 23268349Sobrien ACPI_FUNCTION_TRACE (DsMethodDataDeleteAll); 23368349Sobrien 23468349Sobrien 23568349Sobrien /* Detach the locals */ 23674784Sobrien 23768349Sobrien for (Index = 0; Index < ACPI_METHOD_NUM_LOCALS; Index++) 23868349Sobrien { 23968349Sobrien if (WalkState->LocalVariables[Index].Object) 24068349Sobrien { 24168349Sobrien ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%p\n", 24268349Sobrien Index, WalkState->LocalVariables[Index].Object)); 24368349Sobrien 24474784Sobrien /* Detach object (if present) and remove a reference */ 24574784Sobrien 24674784Sobrien AcpiNsDetachObject (&WalkState->LocalVariables[Index]); 24780588Sobrien } 24880588Sobrien } 24974784Sobrien 25074784Sobrien /* Detach the arguments */ 25174784Sobrien 25274784Sobrien for (Index = 0; Index < ACPI_METHOD_NUM_ARGS; Index++) 25368349Sobrien { 25474784Sobrien if (WalkState->Arguments[Index].Object) 25568349Sobrien { 25668349Sobrien ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%p\n", 25768349Sobrien Index, WalkState->Arguments[Index].Object)); 25868349Sobrien 25968349Sobrien /* Detach object (if present) and remove a reference */ 26068349Sobrien 26168349Sobrien AcpiNsDetachObject (&WalkState->Arguments[Index]); 26268349Sobrien } 26374784Sobrien } 26468349Sobrien 26568349Sobrien return_VOID; 26668349Sobrien} 26768349Sobrien 26874784Sobrien 26974784Sobrien/******************************************************************************* 27074784Sobrien * 27174784Sobrien * FUNCTION: AcpiDsMethodDataInitArgs 27274784Sobrien * 27368349Sobrien * PARAMETERS: *Params - Pointer to a parameter list for the method 27468349Sobrien * MaxParamCount - The arg count for this method 27568349Sobrien * WalkState - Current walk state object 27668349Sobrien * 27768349Sobrien * RETURN: Status 27868349Sobrien * 27968349Sobrien * DESCRIPTION: Initialize arguments for a method. The parameter list is a list 28068349Sobrien * of ACPI operand objects, either null terminated or whose length 28168349Sobrien * is defined by MaxParamCount. 28268349Sobrien * 28368349Sobrien ******************************************************************************/ 28468349Sobrien 28568349SobrienACPI_STATUS 28668349SobrienAcpiDsMethodDataInitArgs ( 28768349Sobrien ACPI_OPERAND_OBJECT **Params, 28868349Sobrien UINT32 MaxParamCount, 28968349Sobrien ACPI_WALK_STATE *WalkState) 29068349Sobrien{ 29168349Sobrien ACPI_STATUS Status; 29268349Sobrien UINT32 Index = 0; 29368349Sobrien 29468349Sobrien 29568349Sobrien ACPI_FUNCTION_TRACE_PTR (DsMethodDataInitArgs, Params); 29668349Sobrien 29768349Sobrien 29868349Sobrien if (!Params) 29968349Sobrien { 30068349Sobrien ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n")); 30168349Sobrien return_ACPI_STATUS (AE_OK); 30280588Sobrien } 30380588Sobrien 30480588Sobrien /* Copy passed parameters into the new method stack frame */ 30568349Sobrien 30668349Sobrien while ((Index < ACPI_METHOD_NUM_ARGS) && 30768349Sobrien (Index < MaxParamCount) && 30868349Sobrien Params[Index]) 30968349Sobrien { 31068349Sobrien /* 31180588Sobrien * A valid parameter. 31268349Sobrien * Store the argument in the method/walk descriptor. 31368349Sobrien * Do not copy the arg in order to implement call by reference 31468349Sobrien */ 31568349Sobrien Status = AcpiDsMethodDataSetValue (ACPI_REFCLASS_ARG, Index, 31668349Sobrien Params[Index], WalkState); 31768349Sobrien if (ACPI_FAILURE (Status)) 31868349Sobrien { 31968349Sobrien return_ACPI_STATUS (Status); 32068349Sobrien } 32168349Sobrien 32268349Sobrien Index++; 32368349Sobrien } 32468349Sobrien 32574784Sobrien ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", Index)); 32674784Sobrien return_ACPI_STATUS (AE_OK); 32774784Sobrien} 32868349Sobrien 32974784Sobrien 33068349Sobrien/******************************************************************************* 33174784Sobrien * 33268349Sobrien * FUNCTION: AcpiDsMethodDataGetNode 33368349Sobrien * 33468349Sobrien * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 33568349Sobrien * ACPI_REFCLASS_ARG 33674784Sobrien * Index - Which Local or Arg whose type to get 33768349Sobrien * WalkState - Current walk state object 33874784Sobrien * Node - Where the node is returned. 33974784Sobrien * 34080588Sobrien * RETURN: Status and node 34180588Sobrien * 34274784Sobrien * DESCRIPTION: Get the Node associated with a local or arg. 34374784Sobrien * 34474784Sobrien ******************************************************************************/ 34568349Sobrien 34668349SobrienACPI_STATUS 34768349SobrienAcpiDsMethodDataGetNode ( 34868349Sobrien UINT8 Type, 34974784Sobrien UINT32 Index, 35074784Sobrien ACPI_WALK_STATE *WalkState, 35174784Sobrien ACPI_NAMESPACE_NODE **Node) 35268349Sobrien{ 35374784Sobrien ACPI_FUNCTION_TRACE (DsMethodDataGetNode); 35468349Sobrien 35568349Sobrien 35668349Sobrien /* 35768349Sobrien * Method Locals and Arguments are supported 35868349Sobrien */ 35968349Sobrien switch (Type) 36068349Sobrien { 36168349Sobrien case ACPI_REFCLASS_LOCAL: 36268349Sobrien 36368349Sobrien if (Index > ACPI_METHOD_MAX_LOCAL) 36468349Sobrien { 36568349Sobrien ACPI_ERROR ((AE_INFO, 36668349Sobrien "Local index %d is invalid (max %d)", 36768349Sobrien Index, ACPI_METHOD_MAX_LOCAL)); 36880588Sobrien return_ACPI_STATUS (AE_AML_INVALID_INDEX); 36968349Sobrien } 37068349Sobrien 37168349Sobrien /* Return a pointer to the pseudo-node */ 37268349Sobrien 37368349Sobrien *Node = &WalkState->LocalVariables[Index]; 37468349Sobrien break; 37568349Sobrien 37668349Sobrien case ACPI_REFCLASS_ARG: 37768349Sobrien 37874784Sobrien if (Index > ACPI_METHOD_MAX_ARG) 37974784Sobrien { 38068349Sobrien ACPI_ERROR ((AE_INFO, 38168349Sobrien "Arg index %d is invalid (max %d)", 38268349Sobrien Index, ACPI_METHOD_MAX_ARG)); 38368349Sobrien return_ACPI_STATUS (AE_AML_INVALID_INDEX); 38468349Sobrien } 38568349Sobrien 38668349Sobrien /* Return a pointer to the pseudo-node */ 38774784Sobrien 38868349Sobrien *Node = &WalkState->Arguments[Index]; 38968349Sobrien break; 39074784Sobrien 39168349Sobrien default: 39268349Sobrien ACPI_ERROR ((AE_INFO, "Type %d is invalid", Type)); 39368349Sobrien return_ACPI_STATUS (AE_TYPE); 39474784Sobrien } 39568349Sobrien 39668349Sobrien return_ACPI_STATUS (AE_OK); 39768349Sobrien} 39874784Sobrien 39968349Sobrien 40068349Sobrien/******************************************************************************* 40168349Sobrien * 40268349Sobrien * FUNCTION: AcpiDsMethodDataSetValue 40368349Sobrien * 40474784Sobrien * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 40568349Sobrien * ACPI_REFCLASS_ARG 40668349Sobrien * Index - Which Local or Arg to get 40768349Sobrien * Object - Object to be inserted into the stack entry 40868349Sobrien * WalkState - Current walk state object 40968349Sobrien * 41068349Sobrien * RETURN: Status 41168349Sobrien * 41280588Sobrien * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index. 41380588Sobrien * Note: There is no "implicit conversion" for locals. 41480588Sobrien * 41580588Sobrien ******************************************************************************/ 41680588Sobrien 41780588Sobrienstatic ACPI_STATUS 41880588SobrienAcpiDsMethodDataSetValue ( 41980588Sobrien UINT8 Type, 42080588Sobrien UINT32 Index, 42180588Sobrien ACPI_OPERAND_OBJECT *Object, 42280588Sobrien ACPI_WALK_STATE *WalkState) 42380588Sobrien{ 42480588Sobrien ACPI_STATUS Status; 42580588Sobrien ACPI_NAMESPACE_NODE *Node; 42680588Sobrien 42780588Sobrien 42880588Sobrien ACPI_FUNCTION_TRACE (DsMethodDataSetValue); 42980588Sobrien 43080588Sobrien 43180588Sobrien ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 43280588Sobrien "NewObj %p Type %2.2X, Refs=%d [%s]\n", Object, 43380588Sobrien Type, Object->Common.ReferenceCount, 43480588Sobrien AcpiUtGetTypeName (Object->Common.Type))); 43580588Sobrien 43680588Sobrien /* Get the namespace node for the arg/local */ 43780588Sobrien 43880588Sobrien Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 43980588Sobrien if (ACPI_FAILURE (Status)) 44080588Sobrien { 44180588Sobrien return_ACPI_STATUS (Status); 44280588Sobrien } 44380588Sobrien 44480588Sobrien /* 44580588Sobrien * Increment ref count so object can't be deleted while installed. 44680588Sobrien * NOTE: We do not copy the object in order to preserve the call by 44780588Sobrien * reference semantics of ACPI Control Method invocation. 44880588Sobrien * (See ACPI Specification 2.0C) 44980588Sobrien */ 45080588Sobrien AcpiUtAddReference (Object); 45174784Sobrien 45268349Sobrien /* Install the object */ 45368349Sobrien 45468349Sobrien Node->Object = Object; 45568349Sobrien return_ACPI_STATUS (Status); 45668349Sobrien} 45768349Sobrien 45868349Sobrien 45968349Sobrien/******************************************************************************* 46068349Sobrien * 46168349Sobrien * FUNCTION: AcpiDsMethodDataGetValue 46268349Sobrien * 46368349Sobrien * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 46468349Sobrien * ACPI_REFCLASS_ARG 46568349Sobrien * Index - Which localVar or argument to get 46668349Sobrien * WalkState - Current walk state object 46768349Sobrien * DestDesc - Where Arg or Local value is returned 46868349Sobrien * 46968349Sobrien * RETURN: Status 47068349Sobrien * 47168349Sobrien * DESCRIPTION: Retrieve value of selected Arg or Local for this method 47268349Sobrien * Used only in AcpiExResolveToValue(). 47368349Sobrien * 47468349Sobrien ******************************************************************************/ 47580588Sobrien 47680588SobrienACPI_STATUS 47780588SobrienAcpiDsMethodDataGetValue ( 47880588Sobrien UINT8 Type, 47968349Sobrien UINT32 Index, 48068349Sobrien ACPI_WALK_STATE *WalkState, 48168349Sobrien ACPI_OPERAND_OBJECT **DestDesc) 48268349Sobrien{ 48368349Sobrien ACPI_STATUS Status; 48468349Sobrien ACPI_NAMESPACE_NODE *Node; 48568349Sobrien ACPI_OPERAND_OBJECT *Object; 48668349Sobrien 48768349Sobrien 48868349Sobrien ACPI_FUNCTION_TRACE (DsMethodDataGetValue); 48968349Sobrien 49068349Sobrien 49168349Sobrien /* Validate the object descriptor */ 49268349Sobrien 49368349Sobrien if (!DestDesc) 49468349Sobrien { 49568349Sobrien ACPI_ERROR ((AE_INFO, "Null object descriptor pointer")); 49668349Sobrien return_ACPI_STATUS (AE_BAD_PARAMETER); 49768349Sobrien } 49868349Sobrien 49968349Sobrien /* Get the namespace node for the arg/local */ 50068349Sobrien 50168349Sobrien Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 50268349Sobrien if (ACPI_FAILURE (Status)) 50368349Sobrien { 50468349Sobrien return_ACPI_STATUS (Status); 50568349Sobrien } 50668349Sobrien 50768349Sobrien /* Get the object from the node */ 50868349Sobrien 50968349Sobrien Object = Node->Object; 51068349Sobrien 51168349Sobrien /* Examine the returned object, it must be valid. */ 51268349Sobrien 51368349Sobrien if (!Object) 51468349Sobrien { 51568349Sobrien /* 51668349Sobrien * Index points to uninitialized object. 51768349Sobrien * This means that either 1) The expected argument was 51868349Sobrien * not passed to the method, or 2) A local variable 51968349Sobrien * was referenced by the method (via the ASL) 52068349Sobrien * before it was initialized. Either case is an error. 52168349Sobrien */ 52280588Sobrien 52380588Sobrien /* If slack enabled, init the LocalX/ArgX to an Integer of value zero */ 52480588Sobrien 52580588Sobrien if (AcpiGbl_EnableInterpreterSlack) 52680588Sobrien { 52780588Sobrien Object = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 52880588Sobrien if (!Object) 52980588Sobrien { 53080588Sobrien return_ACPI_STATUS (AE_NO_MEMORY); 53180588Sobrien } 53280588Sobrien 53380588Sobrien Object->Integer.Value = 0; 53468349Sobrien Node->Object = Object; 53568349Sobrien } 53668349Sobrien 53768349Sobrien /* Otherwise, return the error */ 53868349Sobrien 53980588Sobrien else switch (Type) 54080588Sobrien { 54180588Sobrien case ACPI_REFCLASS_ARG: 54280588Sobrien 54368349Sobrien ACPI_ERROR ((AE_INFO, 54480588Sobrien "Uninitialized Arg[%d] at node %p", 54580588Sobrien Index, Node)); 54680588Sobrien 54780588Sobrien return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG); 54880588Sobrien 54968349Sobrien case ACPI_REFCLASS_LOCAL: 55068349Sobrien 55180588Sobrien /* 55280588Sobrien * No error message for this case, will be trapped again later to 55380588Sobrien * detect and ignore cases of Store(LocalX,LocalX) 55480588Sobrien */ 55580588Sobrien return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL); 55680588Sobrien 55780588Sobrien default: 55880588Sobrien 55980588Sobrien ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: %X", Type)); 56080588Sobrien return_ACPI_STATUS (AE_AML_INTERNAL); 56180588Sobrien } 56280588Sobrien } 56380588Sobrien 56480588Sobrien /* 56580588Sobrien * The Index points to an initialized and valid object. 56680588Sobrien * Return an additional reference to the object 56780588Sobrien */ 56880588Sobrien *DestDesc = Object; 56980588Sobrien AcpiUtAddReference (Object); 57080588Sobrien 57180588Sobrien return_ACPI_STATUS (AE_OK); 57280588Sobrien} 57380588Sobrien 57480588Sobrien 57580588Sobrien/******************************************************************************* 57680588Sobrien * 57780588Sobrien * FUNCTION: AcpiDsMethodDataDeleteValue 57880588Sobrien * 57980588Sobrien * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 58080588Sobrien * ACPI_REFCLASS_ARG 58180588Sobrien * Index - Which localVar or argument to delete 58280588Sobrien * WalkState - Current walk state object 58380588Sobrien * 58480588Sobrien * RETURN: None 58580588Sobrien * 58680588Sobrien * DESCRIPTION: Delete the entry at Opcode:Index. Inserts 58780588Sobrien * a null into the stack slot after the object is deleted. 58880588Sobrien * 58980588Sobrien ******************************************************************************/ 59080588Sobrien 59180588Sobrienstatic void 59280588SobrienAcpiDsMethodDataDeleteValue ( 59380588Sobrien UINT8 Type, 59480588Sobrien UINT32 Index, 59580588Sobrien ACPI_WALK_STATE *WalkState) 59668349Sobrien{ 59768349Sobrien ACPI_STATUS Status; 59868349Sobrien ACPI_NAMESPACE_NODE *Node; 59968349Sobrien ACPI_OPERAND_OBJECT *Object; 60068349Sobrien 60168349Sobrien 60268349Sobrien ACPI_FUNCTION_TRACE (DsMethodDataDeleteValue); 60368349Sobrien 60468349Sobrien 60568349Sobrien /* Get the namespace node for the arg/local */ 60668349Sobrien 60768349Sobrien Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 60868349Sobrien if (ACPI_FAILURE (Status)) 60968349Sobrien { 61068349Sobrien return_VOID; 61168349Sobrien } 61268349Sobrien 61368349Sobrien /* Get the associated object */ 61468349Sobrien 61580588Sobrien Object = AcpiNsGetAttachedObject (Node); 61680588Sobrien 61780588Sobrien /* 61880588Sobrien * Undefine the Arg or Local by setting its descriptor 61968349Sobrien * pointer to NULL. Locals/Args can contain both 62068349Sobrien * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs 62168349Sobrien */ 62268349Sobrien Node->Object = NULL; 62368349Sobrien 62468349Sobrien if ((Object) && 62568349Sobrien (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_OPERAND)) 62668349Sobrien { 62768349Sobrien /* 62868349Sobrien * There is a valid object. 62968349Sobrien * Decrement the reference count by one to balance the 63068349Sobrien * increment when the object was stored. 63168349Sobrien */ 63268349Sobrien AcpiUtRemoveReference (Object); 63368349Sobrien } 63468349Sobrien 63568349Sobrien return_VOID; 63680588Sobrien} 63768349Sobrien 63868349Sobrien 63968349Sobrien/******************************************************************************* 64068349Sobrien * 64168349Sobrien * FUNCTION: AcpiDsStoreObjectToLocal 64268349Sobrien * 64368349Sobrien * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 64468349Sobrien * ACPI_REFCLASS_ARG 64568349Sobrien * Index - Which Local or Arg to set 64668349Sobrien * ObjDesc - Value to be stored 64768349Sobrien * WalkState - Current walk state 64868349Sobrien * 64968349Sobrien * RETURN: Status 65068349Sobrien * 65168349Sobrien * DESCRIPTION: Store a value in an Arg or Local. The ObjDesc is installed 65268349Sobrien * as the new value for the Arg or Local and the reference count 65368349Sobrien * for ObjDesc is incremented. 65468349Sobrien * 65568349Sobrien ******************************************************************************/ 65668349Sobrien 65768349SobrienACPI_STATUS 65868349SobrienAcpiDsStoreObjectToLocal ( 65968349Sobrien UINT8 Type, 66068349Sobrien UINT32 Index, 66168349Sobrien ACPI_OPERAND_OBJECT *ObjDesc, 66268349Sobrien ACPI_WALK_STATE *WalkState) 66368349Sobrien{ 66468349Sobrien ACPI_STATUS Status; 66568349Sobrien ACPI_NAMESPACE_NODE *Node; 66668349Sobrien ACPI_OPERAND_OBJECT *CurrentObjDesc; 66768349Sobrien ACPI_OPERAND_OBJECT *NewObjDesc; 66868349Sobrien 66968349Sobrien 67068349Sobrien ACPI_FUNCTION_TRACE (DsStoreObjectToLocal); 67168349Sobrien ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%d Obj=%p\n", 67268349Sobrien Type, Index, ObjDesc)); 67368349Sobrien 67468349Sobrien /* Parameter validation */ 67568349Sobrien 67668349Sobrien if (!ObjDesc) 67768349Sobrien { 67868349Sobrien return_ACPI_STATUS (AE_BAD_PARAMETER); 67974784Sobrien } 68068349Sobrien 68168349Sobrien /* Get the namespace node for the arg/local */ 68274784Sobrien 68368349Sobrien Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 68468349Sobrien if (ACPI_FAILURE (Status)) 68568349Sobrien { 68668349Sobrien return_ACPI_STATUS (Status); 68768349Sobrien } 68868349Sobrien 68968349Sobrien CurrentObjDesc = AcpiNsGetAttachedObject (Node); 69068349Sobrien if (CurrentObjDesc == ObjDesc) 69168349Sobrien { 69268349Sobrien ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n", 69368349Sobrien ObjDesc)); 69468349Sobrien return_ACPI_STATUS (Status); 69568349Sobrien } 69668349Sobrien 69768349Sobrien /* 69880588Sobrien * If the reference count on the object is more than one, we must 69968349Sobrien * take a copy of the object before we store. A reference count 70068349Sobrien * of exactly 1 means that the object was just created during the 70168349Sobrien * evaluation of an expression, and we can safely use it since it 70268349Sobrien * is not used anywhere else. 70368349Sobrien */ 70468349Sobrien NewObjDesc = ObjDesc; 70568349Sobrien if (ObjDesc->Common.ReferenceCount > 1) 70668349Sobrien { 70768349Sobrien Status = AcpiUtCopyIobjectToIobject (ObjDesc, &NewObjDesc, WalkState); 70868349Sobrien if (ACPI_FAILURE (Status)) 70968349Sobrien { 71068349Sobrien return_ACPI_STATUS (Status); 71168349Sobrien } 71268349Sobrien } 71368349Sobrien 71468349Sobrien /* 71568349Sobrien * If there is an object already in this slot, we either 71668349Sobrien * have to delete it, or if this is an argument and there 71768349Sobrien * is an object reference stored there, we have to do 71868349Sobrien * an indirect store! 71968349Sobrien */ 72068349Sobrien if (CurrentObjDesc) 72168349Sobrien { 72268349Sobrien /* 72368349Sobrien * Check for an indirect store if an argument 72468349Sobrien * contains an object reference (stored as an Node). 72568349Sobrien * We don't allow this automatic dereferencing for 72668349Sobrien * locals, since a store to a local should overwrite 72768349Sobrien * anything there, including an object reference. 72868349Sobrien * 72968349Sobrien * If both Arg0 and Local0 contain RefOf (Local4): 73068349Sobrien * 73168349Sobrien * Store (1, Arg0) - Causes indirect store to local4 73268349Sobrien * Store (1, Local0) - Stores 1 in local0, overwriting 73368349Sobrien * the reference to local4 73468349Sobrien * Store (1, DeRefof (Local0)) - Causes indirect store to local4 73568349Sobrien * 73668349Sobrien * Weird, but true. 73768349Sobrien */ 73868349Sobrien if (Type == ACPI_REFCLASS_ARG) 73968349Sobrien { 74068349Sobrien /* 74168349Sobrien * If we have a valid reference object that came from RefOf(), 74268349Sobrien * do the indirect store 74368349Sobrien */ 74468349Sobrien if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) == ACPI_DESC_TYPE_OPERAND) && 74568349Sobrien (CurrentObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && 74668349Sobrien (CurrentObjDesc->Reference.Class == ACPI_REFCLASS_REFOF)) 74768349Sobrien { 74868349Sobrien ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 74968349Sobrien "Arg (%p) is an ObjRef(Node), storing in node %p\n", 75068349Sobrien NewObjDesc, CurrentObjDesc)); 75168349Sobrien 75268349Sobrien /* 75368349Sobrien * Store this object to the Node (perform the indirect store) 75468349Sobrien * NOTE: No implicit conversion is performed, as per the ACPI 75568349Sobrien * specification rules on storing to Locals/Args. 75668349Sobrien */ 75768349Sobrien Status = AcpiExStoreObjectToNode (NewObjDesc, 75868349Sobrien CurrentObjDesc->Reference.Object, WalkState, 75968349Sobrien ACPI_NO_IMPLICIT_CONVERSION); 76068349Sobrien 76168349Sobrien /* Remove local reference if we copied the object above */ 76268349Sobrien 76368349Sobrien if (NewObjDesc != ObjDesc) 76468349Sobrien { 76568349Sobrien AcpiUtRemoveReference (NewObjDesc); 76668349Sobrien } 76768349Sobrien return_ACPI_STATUS (Status); 76868349Sobrien } 76968349Sobrien } 77068349Sobrien 77168349Sobrien /* Delete the existing object before storing the new one */ 77268349Sobrien 77368349Sobrien AcpiDsMethodDataDeleteValue (Type, Index, WalkState); 77468349Sobrien } 77568349Sobrien 77668349Sobrien /* 77768349Sobrien * Install the Obj descriptor (*NewObjDesc) into 77868349Sobrien * the descriptor for the Arg or Local. 77968349Sobrien * (increments the object reference count by one) 78068349Sobrien */ 78168349Sobrien Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState); 78268349Sobrien 78368349Sobrien /* Remove local reference if we copied the object above */ 78468349Sobrien 78568349Sobrien if (NewObjDesc != ObjDesc) 78668349Sobrien { 78768349Sobrien AcpiUtRemoveReference (NewObjDesc); 78868349Sobrien } 78968349Sobrien 79068349Sobrien return_ACPI_STATUS (Status); 79168349Sobrien} 79268349Sobrien 79368349Sobrien 79468349Sobrien#ifdef ACPI_OBSOLETE_FUNCTIONS 79568349Sobrien/******************************************************************************* 79668349Sobrien * 79768349Sobrien * FUNCTION: AcpiDsMethodDataGetType 79868349Sobrien * 79968349Sobrien * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP 80068349Sobrien * Index - Which Local or Arg whose type to get 80168349Sobrien * WalkState - Current walk state object 80268349Sobrien * 80368349Sobrien * RETURN: Data type of current value of the selected Arg or Local 80468349Sobrien * 80568349Sobrien * DESCRIPTION: Get the type of the object stored in the Local or Arg 80668349Sobrien * 80768349Sobrien ******************************************************************************/ 80868349Sobrien 80968349SobrienACPI_OBJECT_TYPE 81068349SobrienAcpiDsMethodDataGetType ( 81168349Sobrien UINT16 Opcode, 81268349Sobrien UINT32 Index, 81368349Sobrien ACPI_WALK_STATE *WalkState) 81468349Sobrien{ 81568349Sobrien ACPI_STATUS Status; 81668349Sobrien ACPI_NAMESPACE_NODE *Node; 81768349Sobrien ACPI_OPERAND_OBJECT *Object; 81868349Sobrien 81968349Sobrien 82068349Sobrien ACPI_FUNCTION_TRACE (DsMethodDataGetType); 82168349Sobrien 82268349Sobrien 82368349Sobrien /* Get the namespace node for the arg/local */ 82468349Sobrien 82568349Sobrien Status = AcpiDsMethodDataGetNode (Opcode, Index, WalkState, &Node); 82668349Sobrien if (ACPI_FAILURE (Status)) 82768349Sobrien { 82868349Sobrien return_VALUE ((ACPI_TYPE_NOT_FOUND)); 82968349Sobrien } 83068349Sobrien 83168349Sobrien /* Get the object */ 83268349Sobrien 83368349Sobrien Object = AcpiNsGetAttachedObject (Node); 83468349Sobrien if (!Object) 83568349Sobrien { 83668349Sobrien /* Uninitialized local/arg, return TYPE_ANY */ 83768349Sobrien 83868349Sobrien return_VALUE (ACPI_TYPE_ANY); 83968349Sobrien } 84068349Sobrien 84168349Sobrien /* Get the object type */ 84268349Sobrien 84368349Sobrien return_VALUE (Object->Type); 84468349Sobrien} 84568349Sobrien#endif 84668349Sobrien 84768349Sobrien 84868349Sobrien