1db2bae30SDana Myers /******************************************************************************* 2db2bae30SDana Myers * 3db2bae30SDana Myers * Module Name: dsmthdat - control method arguments and local variables 4db2bae30SDana Myers * 5db2bae30SDana Myers ******************************************************************************/ 6db2bae30SDana Myers 726f3cdf0SGordon Ross /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 9db2bae30SDana Myers * All rights reserved. 10db2bae30SDana Myers * 1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1326f3cdf0SGordon Ross * are met: 1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1626f3cdf0SGordon Ross * without modification. 1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2126f3cdf0SGordon Ross * binary redistribution. 2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2426f3cdf0SGordon Ross * from this software without specific prior written permission. 25db2bae30SDana Myers * 2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2826f3cdf0SGordon Ross * Software Foundation. 29db2bae30SDana Myers * 3026f3cdf0SGordon Ross * NO WARRANTY 3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4226f3cdf0SGordon Ross */ 43db2bae30SDana Myers 44db2bae30SDana Myers #include "acpi.h" 45aa2aa9a6SDana Myers #include "accommon.h" 46db2bae30SDana Myers #include "acdispat.h" 47db2bae30SDana Myers #include "acnamesp.h" 48db2bae30SDana Myers #include "acinterp.h" 49db2bae30SDana Myers 50db2bae30SDana Myers 51db2bae30SDana Myers #define _COMPONENT ACPI_DISPATCHER 52db2bae30SDana Myers ACPI_MODULE_NAME ("dsmthdat") 53db2bae30SDana Myers 54db2bae30SDana Myers /* Local prototypes */ 55db2bae30SDana Myers 56db2bae30SDana Myers static void 57db2bae30SDana Myers AcpiDsMethodDataDeleteValue ( 58db2bae30SDana Myers UINT8 Type, 59db2bae30SDana Myers UINT32 Index, 60db2bae30SDana Myers ACPI_WALK_STATE *WalkState); 61db2bae30SDana Myers 62db2bae30SDana Myers static ACPI_STATUS 63db2bae30SDana Myers AcpiDsMethodDataSetValue ( 64db2bae30SDana Myers UINT8 Type, 65db2bae30SDana Myers UINT32 Index, 66db2bae30SDana Myers ACPI_OPERAND_OBJECT *Object, 67db2bae30SDana Myers ACPI_WALK_STATE *WalkState); 68db2bae30SDana Myers 69db2bae30SDana Myers #ifdef ACPI_OBSOLETE_FUNCTIONS 70db2bae30SDana Myers ACPI_OBJECT_TYPE 71db2bae30SDana Myers AcpiDsMethodDataGetType ( 72db2bae30SDana Myers UINT16 Opcode, 73db2bae30SDana Myers UINT32 Index, 74db2bae30SDana Myers ACPI_WALK_STATE *WalkState); 75db2bae30SDana Myers #endif 76db2bae30SDana Myers 77db2bae30SDana Myers 78db2bae30SDana Myers /******************************************************************************* 79db2bae30SDana Myers * 80db2bae30SDana Myers * FUNCTION: AcpiDsMethodDataInit 81db2bae30SDana Myers * 82db2bae30SDana Myers * PARAMETERS: WalkState - Current walk state object 83db2bae30SDana Myers * 84db2bae30SDana Myers * RETURN: Status 85db2bae30SDana Myers * 86db2bae30SDana Myers * DESCRIPTION: Initialize the data structures that hold the method's arguments 87db2bae30SDana Myers * and locals. The data struct is an array of namespace nodes for 88db2bae30SDana Myers * each - this allows RefOf and DeRefOf to work properly for these 89db2bae30SDana Myers * special data types. 90db2bae30SDana Myers * 91db2bae30SDana Myers * NOTES: WalkState fields are initialized to zero by the 92db2bae30SDana Myers * ACPI_ALLOCATE_ZEROED(). 93db2bae30SDana Myers * 94db2bae30SDana Myers * A pseudo-Namespace Node is assigned to each argument and local 95db2bae30SDana Myers * so that RefOf() can return a pointer to the Node. 96db2bae30SDana Myers * 97db2bae30SDana Myers ******************************************************************************/ 98db2bae30SDana Myers 99db2bae30SDana Myers void 100db2bae30SDana Myers AcpiDsMethodDataInit ( 101db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 102db2bae30SDana Myers { 103db2bae30SDana Myers UINT32 i; 104db2bae30SDana Myers 105db2bae30SDana Myers 106db2bae30SDana Myers ACPI_FUNCTION_TRACE (DsMethodDataInit); 107db2bae30SDana Myers 108db2bae30SDana Myers 109db2bae30SDana Myers /* Init the method arguments */ 110db2bae30SDana Myers 111db2bae30SDana Myers for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) 112db2bae30SDana Myers { 113*385cc6b4SJerry Jelinek ACPI_MOVE_32_TO_32 (&WalkState->Arguments[i].Name, 114*385cc6b4SJerry Jelinek NAMEOF_ARG_NTE); 115*385cc6b4SJerry Jelinek 116db2bae30SDana Myers WalkState->Arguments[i].Name.Integer |= (i << 24); 117db2bae30SDana Myers WalkState->Arguments[i].DescriptorType = ACPI_DESC_TYPE_NAMED; 118db2bae30SDana Myers WalkState->Arguments[i].Type = ACPI_TYPE_ANY; 11926f3cdf0SGordon Ross WalkState->Arguments[i].Flags = ANOBJ_METHOD_ARG; 120db2bae30SDana Myers } 121db2bae30SDana Myers 122db2bae30SDana Myers /* Init the method locals */ 123db2bae30SDana Myers 124db2bae30SDana Myers for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) 125db2bae30SDana Myers { 126*385cc6b4SJerry Jelinek ACPI_MOVE_32_TO_32 (&WalkState->LocalVariables[i].Name, 127*385cc6b4SJerry Jelinek NAMEOF_LOCAL_NTE); 128db2bae30SDana Myers 129db2bae30SDana Myers WalkState->LocalVariables[i].Name.Integer |= (i << 24); 130db2bae30SDana Myers WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED; 131db2bae30SDana Myers WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY; 13226f3cdf0SGordon Ross WalkState->LocalVariables[i].Flags = ANOBJ_METHOD_LOCAL; 133db2bae30SDana Myers } 134db2bae30SDana Myers 135db2bae30SDana Myers return_VOID; 136db2bae30SDana Myers } 137db2bae30SDana Myers 138db2bae30SDana Myers 139db2bae30SDana Myers /******************************************************************************* 140db2bae30SDana Myers * 141db2bae30SDana Myers * FUNCTION: AcpiDsMethodDataDeleteAll 142db2bae30SDana Myers * 143db2bae30SDana Myers * PARAMETERS: WalkState - Current walk state object 144db2bae30SDana Myers * 145db2bae30SDana Myers * RETURN: None 146db2bae30SDana Myers * 147db2bae30SDana Myers * DESCRIPTION: Delete method locals and arguments. Arguments are only 148db2bae30SDana Myers * deleted if this method was called from another method. 149db2bae30SDana Myers * 150db2bae30SDana Myers ******************************************************************************/ 151db2bae30SDana Myers 152db2bae30SDana Myers void 153db2bae30SDana Myers AcpiDsMethodDataDeleteAll ( 154db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 155db2bae30SDana Myers { 156db2bae30SDana Myers UINT32 Index; 157db2bae30SDana Myers 158db2bae30SDana Myers 159db2bae30SDana Myers ACPI_FUNCTION_TRACE (DsMethodDataDeleteAll); 160db2bae30SDana Myers 161db2bae30SDana Myers 162db2bae30SDana Myers /* Detach the locals */ 163db2bae30SDana Myers 164db2bae30SDana Myers for (Index = 0; Index < ACPI_METHOD_NUM_LOCALS; Index++) 165db2bae30SDana Myers { 166db2bae30SDana Myers if (WalkState->LocalVariables[Index].Object) 167db2bae30SDana Myers { 16826f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%u=%p\n", 169db2bae30SDana Myers Index, WalkState->LocalVariables[Index].Object)); 170db2bae30SDana Myers 171db2bae30SDana Myers /* Detach object (if present) and remove a reference */ 172db2bae30SDana Myers 173db2bae30SDana Myers AcpiNsDetachObject (&WalkState->LocalVariables[Index]); 174db2bae30SDana Myers } 175db2bae30SDana Myers } 176db2bae30SDana Myers 177db2bae30SDana Myers /* Detach the arguments */ 178db2bae30SDana Myers 179db2bae30SDana Myers for (Index = 0; Index < ACPI_METHOD_NUM_ARGS; Index++) 180db2bae30SDana Myers { 181db2bae30SDana Myers if (WalkState->Arguments[Index].Object) 182db2bae30SDana Myers { 18326f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%u=%p\n", 184db2bae30SDana Myers Index, WalkState->Arguments[Index].Object)); 185db2bae30SDana Myers 186db2bae30SDana Myers /* Detach object (if present) and remove a reference */ 187db2bae30SDana Myers 188db2bae30SDana Myers AcpiNsDetachObject (&WalkState->Arguments[Index]); 189db2bae30SDana Myers } 190db2bae30SDana Myers } 191db2bae30SDana Myers 192db2bae30SDana Myers return_VOID; 193db2bae30SDana Myers } 194db2bae30SDana Myers 195db2bae30SDana Myers 196db2bae30SDana Myers /******************************************************************************* 197db2bae30SDana Myers * 198db2bae30SDana Myers * FUNCTION: AcpiDsMethodDataInitArgs 199db2bae30SDana Myers * 200db2bae30SDana Myers * PARAMETERS: *Params - Pointer to a parameter list for the method 201db2bae30SDana Myers * MaxParamCount - The arg count for this method 202db2bae30SDana Myers * WalkState - Current walk state object 203db2bae30SDana Myers * 204db2bae30SDana Myers * RETURN: Status 205db2bae30SDana Myers * 206db2bae30SDana Myers * DESCRIPTION: Initialize arguments for a method. The parameter list is a list 207db2bae30SDana Myers * of ACPI operand objects, either null terminated or whose length 208db2bae30SDana Myers * is defined by MaxParamCount. 209db2bae30SDana Myers * 210db2bae30SDana Myers ******************************************************************************/ 211db2bae30SDana Myers 212db2bae30SDana Myers ACPI_STATUS 213db2bae30SDana Myers AcpiDsMethodDataInitArgs ( 214db2bae30SDana Myers ACPI_OPERAND_OBJECT **Params, 215db2bae30SDana Myers UINT32 MaxParamCount, 216db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 217db2bae30SDana Myers { 218db2bae30SDana Myers ACPI_STATUS Status; 219db2bae30SDana Myers UINT32 Index = 0; 220db2bae30SDana Myers 221db2bae30SDana Myers 222db2bae30SDana Myers ACPI_FUNCTION_TRACE_PTR (DsMethodDataInitArgs, Params); 223db2bae30SDana Myers 224db2bae30SDana Myers 225db2bae30SDana Myers if (!Params) 226db2bae30SDana Myers { 227*385cc6b4SJerry Jelinek ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 228*385cc6b4SJerry Jelinek "No parameter list passed to method\n")); 229db2bae30SDana Myers return_ACPI_STATUS (AE_OK); 230db2bae30SDana Myers } 231db2bae30SDana Myers 232db2bae30SDana Myers /* Copy passed parameters into the new method stack frame */ 233db2bae30SDana Myers 234db2bae30SDana Myers while ((Index < ACPI_METHOD_NUM_ARGS) && 235db2bae30SDana Myers (Index < MaxParamCount) && 236db2bae30SDana Myers Params[Index]) 237db2bae30SDana Myers { 238db2bae30SDana Myers /* 239db2bae30SDana Myers * A valid parameter. 240db2bae30SDana Myers * Store the argument in the method/walk descriptor. 241db2bae30SDana Myers * Do not copy the arg in order to implement call by reference 242db2bae30SDana Myers */ 243*385cc6b4SJerry Jelinek Status = AcpiDsMethodDataSetValue ( 244*385cc6b4SJerry Jelinek ACPI_REFCLASS_ARG, Index, Params[Index], WalkState); 245db2bae30SDana Myers if (ACPI_FAILURE (Status)) 246db2bae30SDana Myers { 247db2bae30SDana Myers return_ACPI_STATUS (Status); 248db2bae30SDana Myers } 249db2bae30SDana Myers 250db2bae30SDana Myers Index++; 251db2bae30SDana Myers } 252db2bae30SDana Myers 25326f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%u args passed to method\n", Index)); 254db2bae30SDana Myers return_ACPI_STATUS (AE_OK); 255db2bae30SDana Myers } 256db2bae30SDana Myers 257db2bae30SDana Myers 258db2bae30SDana Myers /******************************************************************************* 259db2bae30SDana Myers * 260db2bae30SDana Myers * FUNCTION: AcpiDsMethodDataGetNode 261db2bae30SDana Myers * 262db2bae30SDana Myers * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 263db2bae30SDana Myers * ACPI_REFCLASS_ARG 264db2bae30SDana Myers * Index - Which Local or Arg whose type to get 265db2bae30SDana Myers * WalkState - Current walk state object 266db2bae30SDana Myers * Node - Where the node is returned. 267db2bae30SDana Myers * 268db2bae30SDana Myers * RETURN: Status and node 269db2bae30SDana Myers * 270db2bae30SDana Myers * DESCRIPTION: Get the Node associated with a local or arg. 271db2bae30SDana Myers * 272db2bae30SDana Myers ******************************************************************************/ 273db2bae30SDana Myers 274db2bae30SDana Myers ACPI_STATUS 275db2bae30SDana Myers AcpiDsMethodDataGetNode ( 276db2bae30SDana Myers UINT8 Type, 277db2bae30SDana Myers UINT32 Index, 278db2bae30SDana Myers ACPI_WALK_STATE *WalkState, 279db2bae30SDana Myers ACPI_NAMESPACE_NODE **Node) 280db2bae30SDana Myers { 281db2bae30SDana Myers ACPI_FUNCTION_TRACE (DsMethodDataGetNode); 282db2bae30SDana Myers 283db2bae30SDana Myers 284db2bae30SDana Myers /* 285db2bae30SDana Myers * Method Locals and Arguments are supported 286db2bae30SDana Myers */ 287db2bae30SDana Myers switch (Type) 288db2bae30SDana Myers { 289db2bae30SDana Myers case ACPI_REFCLASS_LOCAL: 290db2bae30SDana Myers 291db2bae30SDana Myers if (Index > ACPI_METHOD_MAX_LOCAL) 292db2bae30SDana Myers { 293db2bae30SDana Myers ACPI_ERROR ((AE_INFO, 29426f3cdf0SGordon Ross "Local index %u is invalid (max %u)", 295db2bae30SDana Myers Index, ACPI_METHOD_MAX_LOCAL)); 296db2bae30SDana Myers return_ACPI_STATUS (AE_AML_INVALID_INDEX); 297db2bae30SDana Myers } 298db2bae30SDana Myers 299db2bae30SDana Myers /* Return a pointer to the pseudo-node */ 300db2bae30SDana Myers 301db2bae30SDana Myers *Node = &WalkState->LocalVariables[Index]; 302db2bae30SDana Myers break; 303db2bae30SDana Myers 304db2bae30SDana Myers case ACPI_REFCLASS_ARG: 305db2bae30SDana Myers 306db2bae30SDana Myers if (Index > ACPI_METHOD_MAX_ARG) 307db2bae30SDana Myers { 308db2bae30SDana Myers ACPI_ERROR ((AE_INFO, 30926f3cdf0SGordon Ross "Arg index %u is invalid (max %u)", 310db2bae30SDana Myers Index, ACPI_METHOD_MAX_ARG)); 311db2bae30SDana Myers return_ACPI_STATUS (AE_AML_INVALID_INDEX); 312db2bae30SDana Myers } 313db2bae30SDana Myers 314db2bae30SDana Myers /* Return a pointer to the pseudo-node */ 315db2bae30SDana Myers 316db2bae30SDana Myers *Node = &WalkState->Arguments[Index]; 317db2bae30SDana Myers break; 318db2bae30SDana Myers 319db2bae30SDana Myers default: 320*385cc6b4SJerry Jelinek 32126f3cdf0SGordon Ross ACPI_ERROR ((AE_INFO, "Type %u is invalid", Type)); 322db2bae30SDana Myers return_ACPI_STATUS (AE_TYPE); 323db2bae30SDana Myers } 324db2bae30SDana Myers 325db2bae30SDana Myers return_ACPI_STATUS (AE_OK); 326db2bae30SDana Myers } 327db2bae30SDana Myers 328db2bae30SDana Myers 329db2bae30SDana Myers /******************************************************************************* 330db2bae30SDana Myers * 331db2bae30SDana Myers * FUNCTION: AcpiDsMethodDataSetValue 332db2bae30SDana Myers * 333db2bae30SDana Myers * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 334db2bae30SDana Myers * ACPI_REFCLASS_ARG 335db2bae30SDana Myers * Index - Which Local or Arg to get 336db2bae30SDana Myers * Object - Object to be inserted into the stack entry 337db2bae30SDana Myers * WalkState - Current walk state object 338db2bae30SDana Myers * 339db2bae30SDana Myers * RETURN: Status 340db2bae30SDana Myers * 341db2bae30SDana Myers * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index. 342db2bae30SDana Myers * Note: There is no "implicit conversion" for locals. 343db2bae30SDana Myers * 344db2bae30SDana Myers ******************************************************************************/ 345db2bae30SDana Myers 346db2bae30SDana Myers static ACPI_STATUS 347db2bae30SDana Myers AcpiDsMethodDataSetValue ( 348db2bae30SDana Myers UINT8 Type, 349db2bae30SDana Myers UINT32 Index, 350db2bae30SDana Myers ACPI_OPERAND_OBJECT *Object, 351db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 352db2bae30SDana Myers { 353db2bae30SDana Myers ACPI_STATUS Status; 354db2bae30SDana Myers ACPI_NAMESPACE_NODE *Node; 355db2bae30SDana Myers 356db2bae30SDana Myers 357db2bae30SDana Myers ACPI_FUNCTION_TRACE (DsMethodDataSetValue); 358db2bae30SDana Myers 359db2bae30SDana Myers 360db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 36126f3cdf0SGordon Ross "NewObj %p Type %2.2X, Refs=%u [%s]\n", Object, 362db2bae30SDana Myers Type, Object->Common.ReferenceCount, 363db2bae30SDana Myers AcpiUtGetTypeName (Object->Common.Type))); 364db2bae30SDana Myers 365db2bae30SDana Myers /* Get the namespace node for the arg/local */ 366db2bae30SDana Myers 367db2bae30SDana Myers Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 368db2bae30SDana Myers if (ACPI_FAILURE (Status)) 369db2bae30SDana Myers { 370db2bae30SDana Myers return_ACPI_STATUS (Status); 371db2bae30SDana Myers } 372db2bae30SDana Myers 373db2bae30SDana Myers /* 374db2bae30SDana Myers * Increment ref count so object can't be deleted while installed. 375db2bae30SDana Myers * NOTE: We do not copy the object in order to preserve the call by 376db2bae30SDana Myers * reference semantics of ACPI Control Method invocation. 377db2bae30SDana Myers * (See ACPI Specification 2.0C) 378db2bae30SDana Myers */ 379db2bae30SDana Myers AcpiUtAddReference (Object); 380db2bae30SDana Myers 381db2bae30SDana Myers /* Install the object */ 382db2bae30SDana Myers 383db2bae30SDana Myers Node->Object = Object; 384db2bae30SDana Myers return_ACPI_STATUS (Status); 385db2bae30SDana Myers } 386db2bae30SDana Myers 387db2bae30SDana Myers 388db2bae30SDana Myers /******************************************************************************* 389db2bae30SDana Myers * 390db2bae30SDana Myers * FUNCTION: AcpiDsMethodDataGetValue 391db2bae30SDana Myers * 392db2bae30SDana Myers * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 393db2bae30SDana Myers * ACPI_REFCLASS_ARG 394db2bae30SDana Myers * Index - Which localVar or argument to get 395db2bae30SDana Myers * WalkState - Current walk state object 396db2bae30SDana Myers * DestDesc - Where Arg or Local value is returned 397db2bae30SDana Myers * 398db2bae30SDana Myers * RETURN: Status 399db2bae30SDana Myers * 400db2bae30SDana Myers * DESCRIPTION: Retrieve value of selected Arg or Local for this method 401db2bae30SDana Myers * Used only in AcpiExResolveToValue(). 402db2bae30SDana Myers * 403db2bae30SDana Myers ******************************************************************************/ 404db2bae30SDana Myers 405db2bae30SDana Myers ACPI_STATUS 406db2bae30SDana Myers AcpiDsMethodDataGetValue ( 407db2bae30SDana Myers UINT8 Type, 408db2bae30SDana Myers UINT32 Index, 409db2bae30SDana Myers ACPI_WALK_STATE *WalkState, 410db2bae30SDana Myers ACPI_OPERAND_OBJECT **DestDesc) 411db2bae30SDana Myers { 412db2bae30SDana Myers ACPI_STATUS Status; 413db2bae30SDana Myers ACPI_NAMESPACE_NODE *Node; 414db2bae30SDana Myers ACPI_OPERAND_OBJECT *Object; 415db2bae30SDana Myers 416db2bae30SDana Myers 417db2bae30SDana Myers ACPI_FUNCTION_TRACE (DsMethodDataGetValue); 418db2bae30SDana Myers 419db2bae30SDana Myers 420db2bae30SDana Myers /* Validate the object descriptor */ 421db2bae30SDana Myers 422db2bae30SDana Myers if (!DestDesc) 423db2bae30SDana Myers { 424db2bae30SDana Myers ACPI_ERROR ((AE_INFO, "Null object descriptor pointer")); 425db2bae30SDana Myers return_ACPI_STATUS (AE_BAD_PARAMETER); 426db2bae30SDana Myers } 427db2bae30SDana Myers 428db2bae30SDana Myers /* Get the namespace node for the arg/local */ 429db2bae30SDana Myers 430db2bae30SDana Myers Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 431db2bae30SDana Myers if (ACPI_FAILURE (Status)) 432db2bae30SDana Myers { 433db2bae30SDana Myers return_ACPI_STATUS (Status); 434db2bae30SDana Myers } 435db2bae30SDana Myers 436db2bae30SDana Myers /* Get the object from the node */ 437db2bae30SDana Myers 438db2bae30SDana Myers Object = Node->Object; 439db2bae30SDana Myers 440db2bae30SDana Myers /* Examine the returned object, it must be valid. */ 441db2bae30SDana Myers 442db2bae30SDana Myers if (!Object) 443db2bae30SDana Myers { 444db2bae30SDana Myers /* 445db2bae30SDana Myers * Index points to uninitialized object. 446db2bae30SDana Myers * This means that either 1) The expected argument was 447db2bae30SDana Myers * not passed to the method, or 2) A local variable 448db2bae30SDana Myers * was referenced by the method (via the ASL) 449db2bae30SDana Myers * before it was initialized. Either case is an error. 450db2bae30SDana Myers */ 451db2bae30SDana Myers 452db2bae30SDana Myers /* If slack enabled, init the LocalX/ArgX to an Integer of value zero */ 453db2bae30SDana Myers 454db2bae30SDana Myers if (AcpiGbl_EnableInterpreterSlack) 455db2bae30SDana Myers { 45657190917SDana Myers Object = AcpiUtCreateIntegerObject ((UINT64) 0); 457db2bae30SDana Myers if (!Object) 458db2bae30SDana Myers { 459db2bae30SDana Myers return_ACPI_STATUS (AE_NO_MEMORY); 460db2bae30SDana Myers } 461db2bae30SDana Myers 462db2bae30SDana Myers Node->Object = Object; 463db2bae30SDana Myers } 464db2bae30SDana Myers 465db2bae30SDana Myers /* Otherwise, return the error */ 466db2bae30SDana Myers 467db2bae30SDana Myers else switch (Type) 468db2bae30SDana Myers { 469db2bae30SDana Myers case ACPI_REFCLASS_ARG: 470db2bae30SDana Myers 471db2bae30SDana Myers ACPI_ERROR ((AE_INFO, 47226f3cdf0SGordon Ross "Uninitialized Arg[%u] at node %p", 473db2bae30SDana Myers Index, Node)); 474db2bae30SDana Myers 475db2bae30SDana Myers return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG); 476db2bae30SDana Myers 477db2bae30SDana Myers case ACPI_REFCLASS_LOCAL: 47857190917SDana Myers /* 47957190917SDana Myers * No error message for this case, will be trapped again later to 48057190917SDana Myers * detect and ignore cases of Store(LocalX,LocalX) 48157190917SDana Myers */ 482db2bae30SDana Myers return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL); 483db2bae30SDana Myers 484db2bae30SDana Myers default: 485db2bae30SDana Myers 48626f3cdf0SGordon Ross ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: 0x%X", Type)); 487db2bae30SDana Myers return_ACPI_STATUS (AE_AML_INTERNAL); 488db2bae30SDana Myers } 489db2bae30SDana Myers } 490db2bae30SDana Myers 491db2bae30SDana Myers /* 492db2bae30SDana Myers * The Index points to an initialized and valid object. 493db2bae30SDana Myers * Return an additional reference to the object 494db2bae30SDana Myers */ 495db2bae30SDana Myers *DestDesc = Object; 496db2bae30SDana Myers AcpiUtAddReference (Object); 497db2bae30SDana Myers 498db2bae30SDana Myers return_ACPI_STATUS (AE_OK); 499db2bae30SDana Myers } 500db2bae30SDana Myers 501db2bae30SDana Myers 502db2bae30SDana Myers /******************************************************************************* 503db2bae30SDana Myers * 504db2bae30SDana Myers * FUNCTION: AcpiDsMethodDataDeleteValue 505db2bae30SDana Myers * 506db2bae30SDana Myers * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 507db2bae30SDana Myers * ACPI_REFCLASS_ARG 508db2bae30SDana Myers * Index - Which localVar or argument to delete 509db2bae30SDana Myers * WalkState - Current walk state object 510db2bae30SDana Myers * 511db2bae30SDana Myers * RETURN: None 512db2bae30SDana Myers * 513db2bae30SDana Myers * DESCRIPTION: Delete the entry at Opcode:Index. Inserts 514db2bae30SDana Myers * a null into the stack slot after the object is deleted. 515db2bae30SDana Myers * 516db2bae30SDana Myers ******************************************************************************/ 517db2bae30SDana Myers 518db2bae30SDana Myers static void 519db2bae30SDana Myers AcpiDsMethodDataDeleteValue ( 520db2bae30SDana Myers UINT8 Type, 521db2bae30SDana Myers UINT32 Index, 522db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 523db2bae30SDana Myers { 524db2bae30SDana Myers ACPI_STATUS Status; 525db2bae30SDana Myers ACPI_NAMESPACE_NODE *Node; 526db2bae30SDana Myers ACPI_OPERAND_OBJECT *Object; 527db2bae30SDana Myers 528db2bae30SDana Myers 529db2bae30SDana Myers ACPI_FUNCTION_TRACE (DsMethodDataDeleteValue); 530db2bae30SDana Myers 531db2bae30SDana Myers 532db2bae30SDana Myers /* Get the namespace node for the arg/local */ 533db2bae30SDana Myers 534db2bae30SDana Myers Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 535db2bae30SDana Myers if (ACPI_FAILURE (Status)) 536db2bae30SDana Myers { 537db2bae30SDana Myers return_VOID; 538db2bae30SDana Myers } 539db2bae30SDana Myers 540db2bae30SDana Myers /* Get the associated object */ 541db2bae30SDana Myers 542db2bae30SDana Myers Object = AcpiNsGetAttachedObject (Node); 543db2bae30SDana Myers 544db2bae30SDana Myers /* 545db2bae30SDana Myers * Undefine the Arg or Local by setting its descriptor 546db2bae30SDana Myers * pointer to NULL. Locals/Args can contain both 547db2bae30SDana Myers * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs 548db2bae30SDana Myers */ 549db2bae30SDana Myers Node->Object = NULL; 550db2bae30SDana Myers 551db2bae30SDana Myers if ((Object) && 552db2bae30SDana Myers (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_OPERAND)) 553db2bae30SDana Myers { 554db2bae30SDana Myers /* 555db2bae30SDana Myers * There is a valid object. 556db2bae30SDana Myers * Decrement the reference count by one to balance the 557db2bae30SDana Myers * increment when the object was stored. 558db2bae30SDana Myers */ 559db2bae30SDana Myers AcpiUtRemoveReference (Object); 560db2bae30SDana Myers } 561db2bae30SDana Myers 562db2bae30SDana Myers return_VOID; 563db2bae30SDana Myers } 564db2bae30SDana Myers 565db2bae30SDana Myers 566db2bae30SDana Myers /******************************************************************************* 567db2bae30SDana Myers * 568db2bae30SDana Myers * FUNCTION: AcpiDsStoreObjectToLocal 569db2bae30SDana Myers * 570db2bae30SDana Myers * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 571db2bae30SDana Myers * ACPI_REFCLASS_ARG 572db2bae30SDana Myers * Index - Which Local or Arg to set 573db2bae30SDana Myers * ObjDesc - Value to be stored 574db2bae30SDana Myers * WalkState - Current walk state 575db2bae30SDana Myers * 576db2bae30SDana Myers * RETURN: Status 577db2bae30SDana Myers * 578db2bae30SDana Myers * DESCRIPTION: Store a value in an Arg or Local. The ObjDesc is installed 579db2bae30SDana Myers * as the new value for the Arg or Local and the reference count 580db2bae30SDana Myers * for ObjDesc is incremented. 581db2bae30SDana Myers * 582db2bae30SDana Myers ******************************************************************************/ 583db2bae30SDana Myers 584db2bae30SDana Myers ACPI_STATUS 585db2bae30SDana Myers AcpiDsStoreObjectToLocal ( 586db2bae30SDana Myers UINT8 Type, 587db2bae30SDana Myers UINT32 Index, 588db2bae30SDana Myers ACPI_OPERAND_OBJECT *ObjDesc, 589db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 590db2bae30SDana Myers { 591db2bae30SDana Myers ACPI_STATUS Status; 592db2bae30SDana Myers ACPI_NAMESPACE_NODE *Node; 593db2bae30SDana Myers ACPI_OPERAND_OBJECT *CurrentObjDesc; 594db2bae30SDana Myers ACPI_OPERAND_OBJECT *NewObjDesc; 595db2bae30SDana Myers 596db2bae30SDana Myers 597db2bae30SDana Myers ACPI_FUNCTION_TRACE (DsStoreObjectToLocal); 59826f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n", 599db2bae30SDana Myers Type, Index, ObjDesc)); 600db2bae30SDana Myers 601db2bae30SDana Myers /* Parameter validation */ 602db2bae30SDana Myers 603db2bae30SDana Myers if (!ObjDesc) 604db2bae30SDana Myers { 605db2bae30SDana Myers return_ACPI_STATUS (AE_BAD_PARAMETER); 606db2bae30SDana Myers } 607db2bae30SDana Myers 608db2bae30SDana Myers /* Get the namespace node for the arg/local */ 609db2bae30SDana Myers 610db2bae30SDana Myers Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 611db2bae30SDana Myers if (ACPI_FAILURE (Status)) 612db2bae30SDana Myers { 613db2bae30SDana Myers return_ACPI_STATUS (Status); 614db2bae30SDana Myers } 615db2bae30SDana Myers 616db2bae30SDana Myers CurrentObjDesc = AcpiNsGetAttachedObject (Node); 617db2bae30SDana Myers if (CurrentObjDesc == ObjDesc) 618db2bae30SDana Myers { 619db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n", 620db2bae30SDana Myers ObjDesc)); 621db2bae30SDana Myers return_ACPI_STATUS (Status); 622db2bae30SDana Myers } 623db2bae30SDana Myers 624db2bae30SDana Myers /* 625db2bae30SDana Myers * If the reference count on the object is more than one, we must 626db2bae30SDana Myers * take a copy of the object before we store. A reference count 627db2bae30SDana Myers * of exactly 1 means that the object was just created during the 628db2bae30SDana Myers * evaluation of an expression, and we can safely use it since it 629db2bae30SDana Myers * is not used anywhere else. 630db2bae30SDana Myers */ 631db2bae30SDana Myers NewObjDesc = ObjDesc; 632db2bae30SDana Myers if (ObjDesc->Common.ReferenceCount > 1) 633db2bae30SDana Myers { 634*385cc6b4SJerry Jelinek Status = AcpiUtCopyIobjectToIobject ( 635*385cc6b4SJerry Jelinek ObjDesc, &NewObjDesc, WalkState); 636db2bae30SDana Myers if (ACPI_FAILURE (Status)) 637db2bae30SDana Myers { 638db2bae30SDana Myers return_ACPI_STATUS (Status); 639db2bae30SDana Myers } 640db2bae30SDana Myers } 641db2bae30SDana Myers 642db2bae30SDana Myers /* 643db2bae30SDana Myers * If there is an object already in this slot, we either 644db2bae30SDana Myers * have to delete it, or if this is an argument and there 645db2bae30SDana Myers * is an object reference stored there, we have to do 646db2bae30SDana Myers * an indirect store! 647db2bae30SDana Myers */ 648db2bae30SDana Myers if (CurrentObjDesc) 649db2bae30SDana Myers { 650db2bae30SDana Myers /* 651db2bae30SDana Myers * Check for an indirect store if an argument 652db2bae30SDana Myers * contains an object reference (stored as an Node). 653db2bae30SDana Myers * We don't allow this automatic dereferencing for 654db2bae30SDana Myers * locals, since a store to a local should overwrite 655db2bae30SDana Myers * anything there, including an object reference. 656db2bae30SDana Myers * 657db2bae30SDana Myers * If both Arg0 and Local0 contain RefOf (Local4): 658db2bae30SDana Myers * 659db2bae30SDana Myers * Store (1, Arg0) - Causes indirect store to local4 660db2bae30SDana Myers * Store (1, Local0) - Stores 1 in local0, overwriting 661db2bae30SDana Myers * the reference to local4 662db2bae30SDana Myers * Store (1, DeRefof (Local0)) - Causes indirect store to local4 663db2bae30SDana Myers * 664db2bae30SDana Myers * Weird, but true. 665db2bae30SDana Myers */ 666db2bae30SDana Myers if (Type == ACPI_REFCLASS_ARG) 667db2bae30SDana Myers { 668db2bae30SDana Myers /* 669db2bae30SDana Myers * If we have a valid reference object that came from RefOf(), 670db2bae30SDana Myers * do the indirect store 671db2bae30SDana Myers */ 672*385cc6b4SJerry Jelinek if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) == 673*385cc6b4SJerry Jelinek ACPI_DESC_TYPE_OPERAND) && 674*385cc6b4SJerry Jelinek (CurrentObjDesc->Common.Type == 675*385cc6b4SJerry Jelinek ACPI_TYPE_LOCAL_REFERENCE) && 676*385cc6b4SJerry Jelinek (CurrentObjDesc->Reference.Class == 677*385cc6b4SJerry Jelinek ACPI_REFCLASS_REFOF)) 678db2bae30SDana Myers { 679db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 680db2bae30SDana Myers "Arg (%p) is an ObjRef(Node), storing in node %p\n", 681db2bae30SDana Myers NewObjDesc, CurrentObjDesc)); 682db2bae30SDana Myers 683db2bae30SDana Myers /* 684db2bae30SDana Myers * Store this object to the Node (perform the indirect store) 685db2bae30SDana Myers * NOTE: No implicit conversion is performed, as per the ACPI 686db2bae30SDana Myers * specification rules on storing to Locals/Args. 687db2bae30SDana Myers */ 688db2bae30SDana Myers Status = AcpiExStoreObjectToNode (NewObjDesc, 689db2bae30SDana Myers CurrentObjDesc->Reference.Object, WalkState, 690db2bae30SDana Myers ACPI_NO_IMPLICIT_CONVERSION); 691db2bae30SDana Myers 692db2bae30SDana Myers /* Remove local reference if we copied the object above */ 693db2bae30SDana Myers 694db2bae30SDana Myers if (NewObjDesc != ObjDesc) 695db2bae30SDana Myers { 696db2bae30SDana Myers AcpiUtRemoveReference (NewObjDesc); 697db2bae30SDana Myers } 698*385cc6b4SJerry Jelinek 699db2bae30SDana Myers return_ACPI_STATUS (Status); 700db2bae30SDana Myers } 701db2bae30SDana Myers } 702db2bae30SDana Myers 703db2bae30SDana Myers /* Delete the existing object before storing the new one */ 704db2bae30SDana Myers 705db2bae30SDana Myers AcpiDsMethodDataDeleteValue (Type, Index, WalkState); 706db2bae30SDana Myers } 707db2bae30SDana Myers 708db2bae30SDana Myers /* 709db2bae30SDana Myers * Install the Obj descriptor (*NewObjDesc) into 710db2bae30SDana Myers * the descriptor for the Arg or Local. 711db2bae30SDana Myers * (increments the object reference count by one) 712db2bae30SDana Myers */ 713db2bae30SDana Myers Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState); 714db2bae30SDana Myers 715db2bae30SDana Myers /* Remove local reference if we copied the object above */ 716db2bae30SDana Myers 717db2bae30SDana Myers if (NewObjDesc != ObjDesc) 718db2bae30SDana Myers { 719db2bae30SDana Myers AcpiUtRemoveReference (NewObjDesc); 720db2bae30SDana Myers } 721db2bae30SDana Myers 722db2bae30SDana Myers return_ACPI_STATUS (Status); 723db2bae30SDana Myers } 724db2bae30SDana Myers 725db2bae30SDana Myers 726db2bae30SDana Myers #ifdef ACPI_OBSOLETE_FUNCTIONS 727db2bae30SDana Myers /******************************************************************************* 728db2bae30SDana Myers * 729db2bae30SDana Myers * FUNCTION: AcpiDsMethodDataGetType 730db2bae30SDana Myers * 731db2bae30SDana Myers * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP 732db2bae30SDana Myers * Index - Which Local or Arg whose type to get 733db2bae30SDana Myers * WalkState - Current walk state object 734db2bae30SDana Myers * 735db2bae30SDana Myers * RETURN: Data type of current value of the selected Arg or Local 736db2bae30SDana Myers * 737db2bae30SDana Myers * DESCRIPTION: Get the type of the object stored in the Local or Arg 738db2bae30SDana Myers * 739db2bae30SDana Myers ******************************************************************************/ 740db2bae30SDana Myers 741db2bae30SDana Myers ACPI_OBJECT_TYPE 742db2bae30SDana Myers AcpiDsMethodDataGetType ( 743db2bae30SDana Myers UINT16 Opcode, 744db2bae30SDana Myers UINT32 Index, 745db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 746db2bae30SDana Myers { 747db2bae30SDana Myers ACPI_STATUS Status; 748db2bae30SDana Myers ACPI_NAMESPACE_NODE *Node; 749db2bae30SDana Myers ACPI_OPERAND_OBJECT *Object; 750db2bae30SDana Myers 751db2bae30SDana Myers 752db2bae30SDana Myers ACPI_FUNCTION_TRACE (DsMethodDataGetType); 753db2bae30SDana Myers 754db2bae30SDana Myers 755db2bae30SDana Myers /* Get the namespace node for the arg/local */ 756db2bae30SDana Myers 757db2bae30SDana Myers Status = AcpiDsMethodDataGetNode (Opcode, Index, WalkState, &Node); 758db2bae30SDana Myers if (ACPI_FAILURE (Status)) 759db2bae30SDana Myers { 760db2bae30SDana Myers return_VALUE ((ACPI_TYPE_NOT_FOUND)); 761db2bae30SDana Myers } 762db2bae30SDana Myers 763db2bae30SDana Myers /* Get the object */ 764db2bae30SDana Myers 765db2bae30SDana Myers Object = AcpiNsGetAttachedObject (Node); 766db2bae30SDana Myers if (!Object) 767db2bae30SDana Myers { 768db2bae30SDana Myers /* Uninitialized local/arg, return TYPE_ANY */ 769db2bae30SDana Myers 770db2bae30SDana Myers return_VALUE (ACPI_TYPE_ANY); 771db2bae30SDana Myers } 772db2bae30SDana Myers 773db2bae30SDana Myers /* Get the object type */ 774db2bae30SDana Myers 775aa2aa9a6SDana Myers return_VALUE (Object->Type); 776db2bae30SDana Myers } 777db2bae30SDana Myers #endif 778