exstore.c revision 83174
167754Smsmith 267754Smsmith/****************************************************************************** 367754Smsmith * 477424Smsmith * Module Name: exstore - AML Interpreter object store support 583174Smsmith * $Revision: 147 $ 667754Smsmith * 767754Smsmith *****************************************************************************/ 867754Smsmith 967754Smsmith/****************************************************************************** 1067754Smsmith * 1167754Smsmith * 1. Copyright Notice 1267754Smsmith * 1371867Smsmith * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 1470243Smsmith * All rights reserved. 1567754Smsmith * 1667754Smsmith * 2. License 1767754Smsmith * 1867754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1967754Smsmith * rights. You may have additional license terms from the party that provided 2067754Smsmith * you this software, covering your right to use that party's intellectual 2167754Smsmith * property rights. 2267754Smsmith * 2367754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2467754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2567754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2667754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2767754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2867754Smsmith * Code in any form, with the right to sublicense such rights; and 2967754Smsmith * 3067754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3167754Smsmith * license (with the right to sublicense), under only those claims of Intel 3267754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3367754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3467754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3567754Smsmith * license, and in no event shall the patent license extend to any additions 3667754Smsmith * to or modifications of the Original Intel Code. No other license or right 3767754Smsmith * is granted directly or by implication, estoppel or otherwise; 3867754Smsmith * 3967754Smsmith * The above copyright and patent license is granted only if the following 4067754Smsmith * conditions are met: 4167754Smsmith * 4267754Smsmith * 3. Conditions 4367754Smsmith * 4467754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4567754Smsmith * Redistribution of source code of any substantial portion of the Covered 4667754Smsmith * Code or modification with rights to further distribute source must include 4767754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4867754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4967754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 5067754Smsmith * contain a file documenting the changes Licensee made to create that Covered 5167754Smsmith * Code and the date of any change. Licensee must include in that file the 5267754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5367754Smsmith * must include a prominent statement that the modification is derived, 5467754Smsmith * directly or indirectly, from Original Intel Code. 5567754Smsmith * 5667754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5767754Smsmith * Redistribution of source code of any substantial portion of the Covered 5867754Smsmith * Code or modification without rights to further distribute source must 5967754Smsmith * include the following Disclaimer and Export Compliance provision in the 6067754Smsmith * documentation and/or other materials provided with distribution. In 6167754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6267754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6367754Smsmith * license from Licensee to its licensee is limited to the intellectual 6467754Smsmith * property embodied in the software Licensee provides to its licensee, and 6567754Smsmith * not to intellectual property embodied in modifications its licensee may 6667754Smsmith * make. 6767754Smsmith * 6867754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 6967754Smsmith * substantial portion of the Covered Code or modification must reproduce the 7067754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 7167754Smsmith * provision in the documentation and/or other materials provided with the 7267754Smsmith * distribution. 7367754Smsmith * 7467754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7567754Smsmith * Intel Code. 7667754Smsmith * 7767754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7867754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7967754Smsmith * other dealings in products derived from or relating to the Covered Code 8067754Smsmith * without prior written authorization from Intel. 8167754Smsmith * 8267754Smsmith * 4. Disclaimer and Export Compliance 8367754Smsmith * 8467754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8567754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8667754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8767754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8867754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8967754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 9067754Smsmith * PARTICULAR PURPOSE. 9167754Smsmith * 9267754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9367754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9467754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9567754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9667754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9767754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9867754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9967754Smsmith * LIMITED REMEDY. 10067754Smsmith * 10167754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10267754Smsmith * software or system incorporating such software without first obtaining any 10367754Smsmith * required license or other approval from the U. S. Department of Commerce or 10467754Smsmith * any other agency or department of the United States Government. In the 10567754Smsmith * event Licensee exports any such software from the United States or 10667754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10767754Smsmith * ensure that the distribution and export/re-export of the software is in 10867754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 10967754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 11067754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 11167754Smsmith * software, or service, directly or indirectly, to any country for which the 11267754Smsmith * United States government or any agency thereof requires an export license, 11367754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11467754Smsmith * such license, approval or letter. 11567754Smsmith * 11667754Smsmith *****************************************************************************/ 11767754Smsmith 11877424Smsmith#define __EXSTORE_C__ 11967754Smsmith 12067754Smsmith#include "acpi.h" 12167754Smsmith#include "acparser.h" 12267754Smsmith#include "acdispat.h" 12367754Smsmith#include "acinterp.h" 12467754Smsmith#include "amlcode.h" 12567754Smsmith#include "acnamesp.h" 12667754Smsmith#include "actables.h" 12767754Smsmith 12867754Smsmith 12977424Smsmith#define _COMPONENT ACPI_EXECUTER 13077424Smsmith MODULE_NAME ("exstore") 13167754Smsmith 13267754Smsmith 13367754Smsmith/******************************************************************************* 13467754Smsmith * 13577424Smsmith * FUNCTION: AcpiExStore 13667754Smsmith * 13767754Smsmith * PARAMETERS: *ValDesc - Value to be stored 13877424Smsmith * *DestDesc - Where to store it. Must be an NS node 13977424Smsmith * or an ACPI_OPERAND_OBJECT of type 14067754Smsmith * Reference; if the latter the descriptor 14167754Smsmith * will be either reused or deleted. 14267754Smsmith * 14367754Smsmith * RETURN: Status 14467754Smsmith * 14567754Smsmith * DESCRIPTION: Store the value described by ValDesc into the location 14667754Smsmith * described by DestDesc. Called by various interpreter 14767754Smsmith * functions to store the result of an operation into 14867754Smsmith * the destination operand. 14967754Smsmith * 15067754Smsmith ******************************************************************************/ 15167754Smsmith 15267754SmsmithACPI_STATUS 15377424SmsmithAcpiExStore ( 15467754Smsmith ACPI_OPERAND_OBJECT *ValDesc, 15567754Smsmith ACPI_OPERAND_OBJECT *DestDesc, 15667754Smsmith ACPI_WALK_STATE *WalkState) 15767754Smsmith{ 15867754Smsmith ACPI_STATUS Status = AE_OK; 15971867Smsmith ACPI_OPERAND_OBJECT *RefDesc = DestDesc; 16067754Smsmith 16167754Smsmith 16277424Smsmith FUNCTION_TRACE_PTR ("ExStore", DestDesc); 16367754Smsmith 16467754Smsmith 16567754Smsmith /* Validate parameters */ 16667754Smsmith 16767754Smsmith if (!ValDesc || !DestDesc) 16867754Smsmith { 16982367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null pointer\n")); 17067754Smsmith return_ACPI_STATUS (AE_AML_NO_OPERAND); 17167754Smsmith } 17267754Smsmith 17371867Smsmith /* DestDesc can be either a namespace node or an ACPI object */ 17467754Smsmith 17567754Smsmith if (VALID_DESCRIPTOR_TYPE (DestDesc, ACPI_DESC_TYPE_NAMED)) 17667754Smsmith { 17777424Smsmith /* 17871867Smsmith * Dest is a namespace node, 17977424Smsmith * Storing an object into a Name "container" 18071867Smsmith */ 18177424Smsmith Status = AcpiExStoreObjectToNode (ValDesc, 18271867Smsmith (ACPI_NAMESPACE_NODE *) DestDesc, WalkState); 18367754Smsmith 18471867Smsmith /* All done, that's it */ 18567754Smsmith 18671867Smsmith return_ACPI_STATUS (Status); 18767754Smsmith } 18867754Smsmith 18967754Smsmith 19071867Smsmith /* Destination object must be an object of type Reference */ 19167754Smsmith 19267754Smsmith if (DestDesc->Common.Type != INTERNAL_TYPE_REFERENCE) 19367754Smsmith { 19467754Smsmith /* Destination is not an Reference */ 19567754Smsmith 19682367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 19782367Smsmith "Destination is not a ReferenceObj [%p]\n", DestDesc)); 19867754Smsmith 19967754Smsmith DUMP_STACK_ENTRY (ValDesc); 20067754Smsmith DUMP_STACK_ENTRY (DestDesc); 20177424Smsmith DUMP_OPERANDS (&DestDesc, IMODE_EXECUTE, "ExStore", 20271867Smsmith 2, "Target is not a ReferenceObj"); 20367754Smsmith 20467754Smsmith return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 20567754Smsmith } 20667754Smsmith 20767754Smsmith 20877424Smsmith /* 20971867Smsmith * Examine the Reference opcode. These cases are handled: 21071867Smsmith * 21171867Smsmith * 1) Store to Name (Change the object associated with a name) 21271867Smsmith * 2) Store to an indexed area of a Buffer or Package 21371867Smsmith * 3) Store to a Method Local or Arg 21471867Smsmith * 4) Store to the debug object 21571867Smsmith * 5) Store to a constant -- a noop 21671867Smsmith */ 21777424Smsmith switch (RefDesc->Reference.Opcode) 21867754Smsmith { 21967754Smsmith 22067754Smsmith case AML_NAME_OP: 22167754Smsmith 22271867Smsmith /* Storing an object into a Name "container" */ 22371867Smsmith 22477424Smsmith Status = AcpiExStoreObjectToNode (ValDesc, RefDesc->Reference.Object, 22567754Smsmith WalkState); 22671867Smsmith break; 22767754Smsmith 22867754Smsmith 22967754Smsmith case AML_INDEX_OP: 23067754Smsmith 23171867Smsmith /* Storing to an Index (pointer into a packager or buffer) */ 23267754Smsmith 23377424Smsmith Status = AcpiExStoreObjectToIndex (ValDesc, RefDesc, WalkState); 23471867Smsmith break; 23571867Smsmith 23671867Smsmith 23771867Smsmith case AML_LOCAL_OP: 23877424Smsmith case AML_ARG_OP: 23971867Smsmith 24077424Smsmith /* Store to a method local/arg */ 24171867Smsmith 24277424Smsmith Status = AcpiDsStoreObjectToLocal (RefDesc->Reference.Opcode, 24377424Smsmith RefDesc->Reference.Offset, ValDesc, WalkState); 24471867Smsmith break; 24571867Smsmith 24671867Smsmith 24771867Smsmith case AML_DEBUG_OP: 24871867Smsmith 24967754Smsmith /* 25071867Smsmith * Storing to the Debug object causes the value stored to be 25171867Smsmith * displayed and otherwise has no effect -- see ACPI Specification 25267754Smsmith */ 25383174Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Write to Debug Object: ****:\n\n")); 25477424Smsmith 25583174Smsmith ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %s: ", 25677424Smsmith AcpiUtGetTypeName (ValDesc->Common.Type))); 25777424Smsmith 25877424Smsmith switch (ValDesc->Common.Type) 25971867Smsmith { 26077424Smsmith case ACPI_TYPE_INTEGER: 26177424Smsmith 26283174Smsmith ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%X (%d)\n", 26377424Smsmith (UINT32) ValDesc->Integer.Value, (UINT32) ValDesc->Integer.Value)); 26477424Smsmith break; 26577424Smsmith 26677424Smsmith 26777424Smsmith case ACPI_TYPE_BUFFER: 26877424Smsmith 26983174Smsmith ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Length 0x%X\n", 27077424Smsmith (UINT32) ValDesc->Buffer.Length)); 27177424Smsmith break; 27277424Smsmith 27377424Smsmith 27477424Smsmith case ACPI_TYPE_STRING: 27577424Smsmith 27683174Smsmith ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s\n", ValDesc->String.Pointer)); 27777424Smsmith break; 27877424Smsmith 27977424Smsmith 28077424Smsmith case ACPI_TYPE_PACKAGE: 28177424Smsmith 28283174Smsmith ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Elements - 0x%X\n", 28377424Smsmith (UINT32) ValDesc->Package.Elements)); 28477424Smsmith break; 28577424Smsmith 28677424Smsmith 28777424Smsmith default: 28877424Smsmith 28983174Smsmith ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "@0x%p\n", ValDesc)); 29077424Smsmith break; 29171867Smsmith } 29267754Smsmith 29383174Smsmith ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "\n")); 29471867Smsmith break; 29571867Smsmith 29671867Smsmith 29771867Smsmith case AML_ZERO_OP: 29871867Smsmith case AML_ONE_OP: 29971867Smsmith case AML_ONES_OP: 30082367Smsmith case AML_REVISION_OP: 30171867Smsmith 30267754Smsmith /* 30371867Smsmith * Storing to a constant is a no-op -- see ACPI Specification 30471867Smsmith * Delete the reference descriptor, however 30571867Smsmith */ 30671867Smsmith break; 30771867Smsmith 30871867Smsmith 30971867Smsmith default: 31071867Smsmith 31182367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - Unknown Reference subtype %02x\n", 31277424Smsmith RefDesc->Reference.Opcode)); 31371867Smsmith 31471867Smsmith /* TBD: [Restructure] use object dump routine !! */ 31571867Smsmith 31671867Smsmith DUMP_BUFFER (RefDesc, sizeof (ACPI_OPERAND_OBJECT)); 31771867Smsmith 31871867Smsmith Status = AE_AML_INTERNAL; 31971867Smsmith break; 32071867Smsmith 32177424Smsmith } /* switch (RefDesc->Reference.Opcode) */ 32271867Smsmith 32371867Smsmith 32471867Smsmith /* Always delete the reference descriptor object */ 32571867Smsmith 32671867Smsmith if (RefDesc) 32771867Smsmith { 32877424Smsmith AcpiUtRemoveReference (RefDesc); 32971867Smsmith } 33071867Smsmith 33171867Smsmith return_ACPI_STATUS (Status); 33271867Smsmith} 33371867Smsmith 33471867Smsmith 33571867Smsmith/******************************************************************************* 33671867Smsmith * 33777424Smsmith * FUNCTION: AcpiExStoreObjectToIndex 33871867Smsmith * 33971867Smsmith * PARAMETERS: *ValDesc - Value to be stored 34077424Smsmith * *Node - Named object to receive the value 34171867Smsmith * 34271867Smsmith * RETURN: Status 34371867Smsmith * 34471867Smsmith * DESCRIPTION: Store the object to the named object. 34571867Smsmith * 34671867Smsmith ******************************************************************************/ 34771867Smsmith 34871867SmsmithACPI_STATUS 34977424SmsmithAcpiExStoreObjectToIndex ( 35071867Smsmith ACPI_OPERAND_OBJECT *ValDesc, 35171867Smsmith ACPI_OPERAND_OBJECT *DestDesc, 35271867Smsmith ACPI_WALK_STATE *WalkState) 35371867Smsmith{ 35471867Smsmith ACPI_STATUS Status = AE_OK; 35571867Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 35671867Smsmith UINT32 Length; 35771867Smsmith UINT32 i; 35871867Smsmith UINT8 Value = 0; 35971867Smsmith 36071867Smsmith 36183174Smsmith FUNCTION_TRACE ("ExStoreObjectToIndex"); 36271867Smsmith 36371867Smsmith 36471867Smsmith /* 36571867Smsmith * Destination must be a reference pointer, and 36671867Smsmith * must point to either a buffer or a package 36771867Smsmith */ 36871867Smsmith switch (DestDesc->Reference.TargetType) 36971867Smsmith { 37071867Smsmith case ACPI_TYPE_PACKAGE: 37171867Smsmith /* 37271867Smsmith * Storing to a package element is not simple. The source must be 37367754Smsmith * evaluated and converted to the type of the destination and then the 37467754Smsmith * source is copied into the destination - we can't just point to the 37567754Smsmith * source object. 37667754Smsmith */ 37767754Smsmith if (DestDesc->Reference.TargetType == ACPI_TYPE_PACKAGE) 37867754Smsmith { 37967754Smsmith /* 38067754Smsmith * The object at *(DestDesc->Reference.Where) is the 38167754Smsmith * element within the package that is to be modified. 38267754Smsmith */ 38371867Smsmith ObjDesc = *(DestDesc->Reference.Where); 38471867Smsmith if (ObjDesc) 38567754Smsmith { 38667754Smsmith /* 38767754Smsmith * If the Destination element is a package, we will delete 38867754Smsmith * that object and construct a new one. 38967754Smsmith * 39067754Smsmith * TBD: [Investigate] Should both the src and dest be required 39167754Smsmith * to be packages? 39267754Smsmith * && (ValDesc->Common.Type == ACPI_TYPE_PACKAGE) 39367754Smsmith */ 39471867Smsmith if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE) 39567754Smsmith { 39667754Smsmith /* 39767754Smsmith * Take away the reference for being part of a package and 39867754Smsmith * delete 39967754Smsmith */ 40077424Smsmith AcpiUtRemoveReference (ObjDesc); 40177424Smsmith AcpiUtRemoveReference (ObjDesc); 40267754Smsmith 40371867Smsmith ObjDesc = NULL; 40467754Smsmith } 40567754Smsmith } 40667754Smsmith 40771867Smsmith if (!ObjDesc) 40867754Smsmith { 40967754Smsmith /* 41071867Smsmith * If the ObjDesc is NULL, it means that an uninitialized package 41177424Smsmith * element has been used as a destination (this is OK), therefore, 41277424Smsmith * we must create the destination element to match the type of the 41371867Smsmith * source element NOTE: ValDesc can be of any type. 41467754Smsmith */ 41577424Smsmith ObjDesc = AcpiUtCreateInternalObject (ValDesc->Common.Type); 41671867Smsmith if (!ObjDesc) 41767754Smsmith { 41871867Smsmith return_ACPI_STATUS (AE_NO_MEMORY); 41967754Smsmith } 42067754Smsmith 42167754Smsmith /* 42267754Smsmith * If the source is a package, copy the source to the new dest 42367754Smsmith */ 42471867Smsmith if (ACPI_TYPE_PACKAGE == ObjDesc->Common.Type) 42567754Smsmith { 42677424Smsmith Status = AcpiUtCopyIpackageToIpackage (ValDesc, ObjDesc, WalkState); 42767754Smsmith if (ACPI_FAILURE (Status)) 42867754Smsmith { 42977424Smsmith AcpiUtRemoveReference (ObjDesc); 43071867Smsmith return_ACPI_STATUS (Status); 43167754Smsmith } 43267754Smsmith } 43367754Smsmith 43467754Smsmith /* 43567754Smsmith * Install the new descriptor into the package and add a 43667754Smsmith * reference to the newly created descriptor for now being 43767754Smsmith * part of the parent package 43867754Smsmith */ 43971867Smsmith *(DestDesc->Reference.Where) = ObjDesc; 44077424Smsmith AcpiUtAddReference (ObjDesc); 44167754Smsmith } 44267754Smsmith 44371867Smsmith if (ACPI_TYPE_PACKAGE != ObjDesc->Common.Type) 44467754Smsmith { 44567754Smsmith /* 44667754Smsmith * The destination element is not a package, so we need to 44767754Smsmith * convert the contents of the source (ValDesc) and copy into 44871867Smsmith * the destination (ObjDesc) 44967754Smsmith */ 45077424Smsmith Status = AcpiExStoreObjectToObject (ValDesc, ObjDesc, 45167754Smsmith WalkState); 45267754Smsmith if (ACPI_FAILURE (Status)) 45367754Smsmith { 45467754Smsmith /* 45567754Smsmith * An error occurrered when copying the internal object 45667754Smsmith * so delete the reference. 45767754Smsmith */ 45882367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 45982367Smsmith "Unable to copy the internal object\n")); 46071867Smsmith return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 46167754Smsmith } 46267754Smsmith } 46367754Smsmith } 46471867Smsmith break; 46567754Smsmith 46667754Smsmith 46771867Smsmith case ACPI_TYPE_BUFFER_FIELD: 46877424Smsmith 46977424Smsmith 47077424Smsmith /* TBD: can probably call the generic Buffer/Field routines */ 47177424Smsmith 47267754Smsmith /* 47367754Smsmith * Storing into a buffer at a location defined by an Index. 47467754Smsmith * 47567754Smsmith * Each 8-bit element of the source object is written to the 47667754Smsmith * 8-bit Buffer Field of the Index destination object. 47767754Smsmith */ 47867754Smsmith 47967754Smsmith /* 48071867Smsmith * Set the ObjDesc to the destination object and type check. 48167754Smsmith */ 48271867Smsmith ObjDesc = DestDesc->Reference.Object; 48371867Smsmith if (ObjDesc->Common.Type != ACPI_TYPE_BUFFER) 48467754Smsmith { 48571867Smsmith return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 48667754Smsmith } 48767754Smsmith 48867754Smsmith /* 48967754Smsmith * The assignment of the individual elements will be slightly 49067754Smsmith * different for each source type. 49167754Smsmith */ 49267754Smsmith switch (ValDesc->Common.Type) 49367754Smsmith { 49471867Smsmith case ACPI_TYPE_INTEGER: 49577424Smsmith /* 49677424Smsmith * Type is Integer, assign bytewise 49777424Smsmith * This loop to assign each of the elements is somewhat 49877424Smsmith * backward because of the Big Endian-ness of IA-64 49977424Smsmith */ 50071867Smsmith Length = sizeof (ACPI_INTEGER); 50167754Smsmith for (i = Length; i != 0; i--) 50267754Smsmith { 50371867Smsmith Value = (UINT8)(ValDesc->Integer.Value >> (MUL_8 (i - 1))); 50471867Smsmith ObjDesc->Buffer.Pointer[DestDesc->Reference.Offset] = Value; 50567754Smsmith } 50667754Smsmith break; 50767754Smsmith 50877424Smsmith 50967754Smsmith case ACPI_TYPE_BUFFER: 51077424Smsmith /* 51177424Smsmith * Type is Buffer, the Length is in the structure. 51277424Smsmith * Just loop through the elements and assign each one in turn. 51377424Smsmith */ 51467754Smsmith Length = ValDesc->Buffer.Length; 51567754Smsmith for (i = 0; i < Length; i++) 51667754Smsmith { 51782367Smsmith Value = ValDesc->Buffer.Pointer[i]; 51871867Smsmith ObjDesc->Buffer.Pointer[DestDesc->Reference.Offset] = Value; 51967754Smsmith } 52067754Smsmith break; 52167754Smsmith 52277424Smsmith 52367754Smsmith case ACPI_TYPE_STRING: 52477424Smsmith /* 52577424Smsmith * Type is String, the Length is in the structure. 52677424Smsmith * Just loop through the elements and assign each one in turn. 52777424Smsmith */ 52867754Smsmith Length = ValDesc->String.Length; 52967754Smsmith for (i = 0; i < Length; i++) 53067754Smsmith { 53182367Smsmith Value = ValDesc->String.Pointer[i]; 53271867Smsmith ObjDesc->Buffer.Pointer[DestDesc->Reference.Offset] = Value; 53367754Smsmith } 53467754Smsmith break; 53567754Smsmith 53677424Smsmith 53767754Smsmith default: 53877424Smsmith 53977424Smsmith /* Other types are invalid */ 54077424Smsmith 54182367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 54282367Smsmith "Source must be Number/Buffer/String type, not %X\n", 54367754Smsmith ValDesc->Common.Type)); 54467754Smsmith Status = AE_AML_OPERAND_TYPE; 54567754Smsmith break; 54667754Smsmith } 54771867Smsmith break; 54867754Smsmith 54967754Smsmith 55071867Smsmith default: 55182367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Target is not a Package or BufferField\n")); 55271867Smsmith Status = AE_AML_OPERAND_TYPE; 55367754Smsmith break; 55471867Smsmith } 55567754Smsmith 55667754Smsmith 55771867Smsmith return_ACPI_STATUS (Status); 55871867Smsmith} 55967754Smsmith 56067754Smsmith 56171867Smsmith/******************************************************************************* 56271867Smsmith * 56377424Smsmith * FUNCTION: AcpiExStoreObjectToNode 56471867Smsmith * 56571867Smsmith * PARAMETERS: *SourceDesc - Value to be stored 56677424Smsmith * *Node - Named object to receive the value 56771867Smsmith * 56871867Smsmith * RETURN: Status 56971867Smsmith * 57071867Smsmith * DESCRIPTION: Store the object to the named object. 57171867Smsmith * 57271867Smsmith * The Assignment of an object to a named object is handled here 57371867Smsmith * The val passed in will replace the current value (if any) 57471867Smsmith * with the input value. 57571867Smsmith * 57671867Smsmith * When storing into an object the data is converted to the 57771867Smsmith * target object type then stored in the object. This means 57871867Smsmith * that the target object type (for an initialized target) will 57971867Smsmith * not be changed by a store operation. 58071867Smsmith * 58171867Smsmith * NOTE: the global lock is acquired early. This will result 58271867Smsmith * in the global lock being held a bit longer. Also, if the 58371867Smsmith * function fails during set up we may get the lock when we 58471867Smsmith * don't really need it. I don't think we care. 58571867Smsmith * 58671867Smsmith ******************************************************************************/ 58767754Smsmith 58871867SmsmithACPI_STATUS 58977424SmsmithAcpiExStoreObjectToNode ( 59071867Smsmith ACPI_OPERAND_OBJECT *SourceDesc, 59171867Smsmith ACPI_NAMESPACE_NODE *Node, 59271867Smsmith ACPI_WALK_STATE *WalkState) 59371867Smsmith{ 59471867Smsmith ACPI_STATUS Status = AE_OK; 59571867Smsmith ACPI_OPERAND_OBJECT *TargetDesc; 59677424Smsmith ACPI_OBJECT_TYPE8 TargetType = ACPI_TYPE_ANY; 59767754Smsmith 59871867Smsmith 59977424Smsmith FUNCTION_TRACE ("ExStoreObjectToNode"); 60071867Smsmith 60183174Smsmith 60271867Smsmith /* 60371867Smsmith * Assuming the parameters were already validated 60471867Smsmith */ 60571867Smsmith 60671867Smsmith /* 60771867Smsmith * Get current type of the node, and object attached to Node 60871867Smsmith */ 60971867Smsmith TargetType = AcpiNsGetType (Node); 61071867Smsmith TargetDesc = AcpiNsGetAttachedObject (Node); 61171867Smsmith 61282367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Storing %p(%s) into node %p(%s)\n", 61377424Smsmith Node, AcpiUtGetTypeName (SourceDesc->Common.Type), 61477424Smsmith SourceDesc, AcpiUtGetTypeName (TargetType))); 61571867Smsmith 61671867Smsmith 61771867Smsmith /* 61871867Smsmith * Resolve the source object to an actual value 61977424Smsmith * (If it is a reference object) 62071867Smsmith */ 62177424Smsmith Status = AcpiExResolveObject (&SourceDesc, TargetType, WalkState); 62271867Smsmith if (ACPI_FAILURE (Status)) 62371867Smsmith { 62471867Smsmith return_ACPI_STATUS (Status); 62571867Smsmith } 62671867Smsmith 62771867Smsmith 62871867Smsmith /* 62977424Smsmith * Do the actual store operation 63071867Smsmith */ 63171867Smsmith switch (TargetType) 63271867Smsmith { 63377424Smsmith case ACPI_TYPE_BUFFER_FIELD: 63477424Smsmith case INTERNAL_TYPE_REGION_FIELD: 63577424Smsmith case INTERNAL_TYPE_BANK_FIELD: 63677424Smsmith case INTERNAL_TYPE_INDEX_FIELD: 63771867Smsmith 63877424Smsmith /* 63977424Smsmith * For fields, copy the source data to the target field. 64077424Smsmith */ 64177424Smsmith Status = AcpiExWriteDataToField (SourceDesc, TargetDesc); 64267754Smsmith break; 64367754Smsmith 64467754Smsmith 64571867Smsmith case ACPI_TYPE_INTEGER: 64671867Smsmith case ACPI_TYPE_STRING: 64771867Smsmith case ACPI_TYPE_BUFFER: 64867754Smsmith 64977424Smsmith /* 65071867Smsmith * These target types are all of type Integer/String/Buffer, and 65171867Smsmith * therefore support implicit conversion before the store. 65277424Smsmith * 65377424Smsmith * Copy and/or convert the source object to a new target object 65467754Smsmith */ 65577424Smsmith Status = AcpiExStoreObject (SourceDesc, TargetType, &TargetDesc, WalkState); 65671867Smsmith if (ACPI_FAILURE (Status)) 65767754Smsmith { 65871867Smsmith return_ACPI_STATUS (Status); 65967754Smsmith } 66067754Smsmith 66171867Smsmith /* 66271867Smsmith * Store the new TargetDesc as the new value of the Name, and set 66371867Smsmith * the Name's type to that of the value being stored in it. 66471867Smsmith * SourceDesc reference count is incremented by AttachObject. 66571867Smsmith */ 66671867Smsmith Status = AcpiNsAttachObject (Node, TargetDesc, TargetType); 66782367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 66882367Smsmith "Store %s into %s via Convert/Attach\n", 66977424Smsmith AcpiUtGetTypeName (TargetDesc->Common.Type), 67077424Smsmith AcpiUtGetTypeName (TargetType))); 67167754Smsmith break; 67267754Smsmith 67377424Smsmith 67467754Smsmith default: 67567754Smsmith 67671867Smsmith /* No conversions for all other types. Just attach the source object */ 67767754Smsmith 67871867Smsmith Status = AcpiNsAttachObject (Node, SourceDesc, SourceDesc->Common.Type); 67977424Smsmith 68082367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 68182367Smsmith "Store %s into %s via Attach only\n", 68277424Smsmith AcpiUtGetTypeName (SourceDesc->Common.Type), 68377424Smsmith AcpiUtGetTypeName (SourceDesc->Common.Type))); 68471867Smsmith break; 68571867Smsmith } 68667754Smsmith 68767754Smsmith 68871867Smsmith return_ACPI_STATUS (Status); 68971867Smsmith} 69067754Smsmith 69167754Smsmith 69271867Smsmith/******************************************************************************* 69371867Smsmith * 69477424Smsmith * FUNCTION: AcpiExStoreObjectToObject 69571867Smsmith * 69671867Smsmith * PARAMETERS: *SourceDesc - Value to be stored 69771867Smsmith * *DestDesc - Object to receive the value 69871867Smsmith * 69971867Smsmith * RETURN: Status 70071867Smsmith * 70171867Smsmith * DESCRIPTION: Store an object to another object. 70271867Smsmith * 70371867Smsmith * The Assignment of an object to another (not named) object 70471867Smsmith * is handled here. 70571867Smsmith * The val passed in will replace the current value (if any) 70671867Smsmith * with the input value. 70771867Smsmith * 70871867Smsmith * When storing into an object the data is converted to the 70971867Smsmith * target object type then stored in the object. This means 71071867Smsmith * that the target object type (for an initialized target) will 71171867Smsmith * not be changed by a store operation. 71271867Smsmith * 71371867Smsmith * This module allows destination types of Number, String, 71471867Smsmith * and Buffer. 71571867Smsmith * 71671867Smsmith ******************************************************************************/ 71767754Smsmith 71871867SmsmithACPI_STATUS 71977424SmsmithAcpiExStoreObjectToObject ( 72071867Smsmith ACPI_OPERAND_OBJECT *SourceDesc, 72171867Smsmith ACPI_OPERAND_OBJECT *DestDesc, 72271867Smsmith ACPI_WALK_STATE *WalkState) 72371867Smsmith{ 72471867Smsmith ACPI_STATUS Status = AE_OK; 72577424Smsmith ACPI_OBJECT_TYPE8 DestinationType = DestDesc->Common.Type; 72667754Smsmith 72771867Smsmith 72877424Smsmith FUNCTION_TRACE ("ExStoreObjectToObject"); 72971867Smsmith 73071867Smsmith 73171867Smsmith /* 73271867Smsmith * Assuming the parameters are valid! 73371867Smsmith */ 73482367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Storing %p(%s) to %p(%s)\n", 73577424Smsmith SourceDesc, AcpiUtGetTypeName (SourceDesc->Common.Type), 73677424Smsmith DestDesc, AcpiUtGetTypeName (DestDesc->Common.Type))); 73771867Smsmith 73871867Smsmith 73971867Smsmith /* 74071867Smsmith * From this interface, we only support Integers/Strings/Buffers 74171867Smsmith */ 74271867Smsmith switch (DestinationType) 74367754Smsmith { 74471867Smsmith case ACPI_TYPE_INTEGER: 74571867Smsmith case ACPI_TYPE_STRING: 74671867Smsmith case ACPI_TYPE_BUFFER: 74771867Smsmith break; 74871867Smsmith 74971867Smsmith default: 75082367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Store into %s not implemented\n", 75177424Smsmith AcpiUtGetTypeName (DestDesc->Common.Type))); 75271867Smsmith 75371867Smsmith return_ACPI_STATUS (AE_NOT_IMPLEMENTED); 75467754Smsmith } 75567754Smsmith 75671867Smsmith 75771867Smsmith /* 75871867Smsmith * Resolve the source object to an actual value 75977424Smsmith * (If it is a reference object) 76071867Smsmith */ 76177424Smsmith Status = AcpiExResolveObject (&SourceDesc, DestinationType, WalkState); 76271867Smsmith if (ACPI_FAILURE (Status)) 76371867Smsmith { 76471867Smsmith return_ACPI_STATUS (Status); 76571867Smsmith } 76671867Smsmith 76771867Smsmith 76871867Smsmith /* 76977424Smsmith * Copy and/or convert the source object to the destination object 77071867Smsmith */ 77177424Smsmith Status = AcpiExStoreObject (SourceDesc, DestinationType, &DestDesc, WalkState); 77271867Smsmith 77371867Smsmith 77467754Smsmith return_ACPI_STATUS (Status); 77567754Smsmith} 77667754Smsmith 777