exstorob.c revision 245582
1220497Smarkm/****************************************************************************** 2220497Smarkm * 3220497Smarkm * Module Name: exstorob - AML Interpreter object store support, store to object 4220497Smarkm * 5220497Smarkm *****************************************************************************/ 6220497Smarkm 7220497Smarkm/* 8220497Smarkm * Copyright (C) 2000 - 2013, Intel Corp. 9220497Smarkm * All rights reserved. 10220497Smarkm * 11220497Smarkm * Redistribution and use in source and binary forms, with or without 12220497Smarkm * modification, are permitted provided that the following conditions 13220497Smarkm * are met: 14220497Smarkm * 1. Redistributions of source code must retain the above copyright 15220497Smarkm * notice, this list of conditions, and the following disclaimer, 16220497Smarkm * without modification. 17220497Smarkm * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18220497Smarkm * substantially similar to the "NO WARRANTY" disclaimer below 19220497Smarkm * ("Disclaimer") and any redistribution must be conditioned upon 20220497Smarkm * including a substantially similar Disclaimer requirement for further 21220497Smarkm * binary redistribution. 22220497Smarkm * 3. Neither the names of the above-listed copyright holders nor the names 23220497Smarkm * of any contributors may be used to endorse or promote products derived 24220497Smarkm * from this software without specific prior written permission. 25220497Smarkm * 26220497Smarkm * Alternatively, this software may be distributed under the terms of the 27220497Smarkm * GNU General Public License ("GPL") version 2 as published by the Free 28220497Smarkm * Software Foundation. 29220497Smarkm * 30220497Smarkm * NO WARRANTY 31220497Smarkm * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32220497Smarkm * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33220497Smarkm * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34220497Smarkm * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35220497Smarkm * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36220497Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37220497Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38220497Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39220497Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40220497Smarkm * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41220497Smarkm * POSSIBILITY OF SUCH DAMAGES. 42220497Smarkm */ 43220497Smarkm 44220497Smarkm#define __EXSTOROB_C__ 45220497Smarkm 46220497Smarkm#include <contrib/dev/acpica/include/acpi.h> 47220497Smarkm#include <contrib/dev/acpica/include/accommon.h> 48220497Smarkm#include <contrib/dev/acpica/include/acinterp.h> 49220497Smarkm 50220497Smarkm 51220497Smarkm#define _COMPONENT ACPI_EXECUTER 52220497Smarkm ACPI_MODULE_NAME ("exstorob") 53220497Smarkm 54220497Smarkm 55220497Smarkm/******************************************************************************* 56220497Smarkm * 57220497Smarkm * FUNCTION: AcpiExStoreBufferToBuffer 58220497Smarkm * 59220497Smarkm * PARAMETERS: SourceDesc - Source object to copy 60220497Smarkm * TargetDesc - Destination object of the copy 61220497Smarkm * 62220497Smarkm * RETURN: Status 63221471Sobrien * 64220497Smarkm * DESCRIPTION: Copy a buffer object to another buffer object. 65220497Smarkm * 66220497Smarkm ******************************************************************************/ 67220497Smarkm 68220497SmarkmACPI_STATUS 69220497SmarkmAcpiExStoreBufferToBuffer ( 70220497Smarkm ACPI_OPERAND_OBJECT *SourceDesc, 71220497Smarkm ACPI_OPERAND_OBJECT *TargetDesc) 72220497Smarkm{ 73220497Smarkm UINT32 Length; 74220497Smarkm UINT8 *Buffer; 75220497Smarkm 76220497Smarkm 77220497Smarkm ACPI_FUNCTION_TRACE_PTR (ExStoreBufferToBuffer, SourceDesc); 78220497Smarkm 79220497Smarkm 80220497Smarkm /* If Source and Target are the same, just return */ 81220497Smarkm 82220497Smarkm if (SourceDesc == TargetDesc) 83220497Smarkm { 84220497Smarkm return_ACPI_STATUS (AE_OK); 85220497Smarkm } 86220497Smarkm 87220497Smarkm /* We know that SourceDesc is a buffer by now */ 88220497Smarkm 89220497Smarkm Buffer = ACPI_CAST_PTR (UINT8, SourceDesc->Buffer.Pointer); 90220497Smarkm Length = SourceDesc->Buffer.Length; 91220497Smarkm 92220497Smarkm /* 93220497Smarkm * If target is a buffer of length zero or is a static buffer, 94220497Smarkm * allocate a new buffer of the proper length 95220497Smarkm */ 96220497Smarkm if ((TargetDesc->Buffer.Length == 0) || 97220497Smarkm (TargetDesc->Common.Flags & AOPOBJ_STATIC_POINTER)) 98220497Smarkm { 99220497Smarkm TargetDesc->Buffer.Pointer = ACPI_ALLOCATE (Length); 100220497Smarkm if (!TargetDesc->Buffer.Pointer) 101220497Smarkm { 102220497Smarkm return_ACPI_STATUS (AE_NO_MEMORY); 103220497Smarkm } 104220497Smarkm 105220497Smarkm TargetDesc->Buffer.Length = Length; 106220497Smarkm } 107220497Smarkm 108220497Smarkm /* Copy source buffer to target buffer */ 109220497Smarkm 110220497Smarkm if (Length <= TargetDesc->Buffer.Length) 111220497Smarkm { 112220497Smarkm /* Clear existing buffer and copy in the new one */ 113220497Smarkm 114220497Smarkm ACPI_MEMSET (TargetDesc->Buffer.Pointer, 0, TargetDesc->Buffer.Length); 115220497Smarkm ACPI_MEMCPY (TargetDesc->Buffer.Pointer, Buffer, Length); 116220497Smarkm 117220497Smarkm#ifdef ACPI_OBSOLETE_BEHAVIOR 118220497Smarkm /* 119220497Smarkm * NOTE: ACPI versions up to 3.0 specified that the buffer must be 120220497Smarkm * truncated if the string is smaller than the buffer. However, "other" 121220497Smarkm * implementations of ACPI never did this and thus became the defacto 122220497Smarkm * standard. ACPI 3.0A changes this behavior such that the buffer 123220497Smarkm * is no longer truncated. 124220497Smarkm */ 125220497Smarkm 126220497Smarkm /* 127220497Smarkm * OBSOLETE BEHAVIOR: 128220497Smarkm * If the original source was a string, we must truncate the buffer, 129220497Smarkm * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer 130220497Smarkm * copy must not truncate the original buffer. 131220497Smarkm */ 132220497Smarkm if (OriginalSrcType == ACPI_TYPE_STRING) 133220497Smarkm { 134220497Smarkm /* Set the new length of the target */ 135220497Smarkm 136220497Smarkm TargetDesc->Buffer.Length = Length; 137220497Smarkm } 138220497Smarkm#endif 139220497Smarkm } 140220497Smarkm else 141220497Smarkm { 142220497Smarkm /* Truncate the source, copy only what will fit */ 143220497Smarkm 144220497Smarkm ACPI_MEMCPY (TargetDesc->Buffer.Pointer, Buffer, 145220497Smarkm TargetDesc->Buffer.Length); 146220497Smarkm 147220497Smarkm ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 148220497Smarkm "Truncating source buffer from %X to %X\n", 149220497Smarkm Length, TargetDesc->Buffer.Length)); 150220497Smarkm } 151220497Smarkm 152220497Smarkm /* Copy flags */ 153220497Smarkm 154220497Smarkm TargetDesc->Buffer.Flags = SourceDesc->Buffer.Flags; 155220497Smarkm TargetDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER; 156220497Smarkm return_ACPI_STATUS (AE_OK); 157220497Smarkm} 158220497Smarkm 159220497Smarkm 160220497Smarkm/******************************************************************************* 161220497Smarkm * 162220497Smarkm * FUNCTION: AcpiExStoreStringToString 163220497Smarkm * 164220497Smarkm * PARAMETERS: SourceDesc - Source object to copy 165220497Smarkm * TargetDesc - Destination object of the copy 166220497Smarkm * 167220497Smarkm * RETURN: Status 168220497Smarkm * 169220497Smarkm * DESCRIPTION: Copy a String object to another String object 170220497Smarkm * 171220497Smarkm ******************************************************************************/ 172220497Smarkm 173220497SmarkmACPI_STATUS 174220497SmarkmAcpiExStoreStringToString ( 175220497Smarkm ACPI_OPERAND_OBJECT *SourceDesc, 176220497Smarkm ACPI_OPERAND_OBJECT *TargetDesc) 177220497Smarkm{ 178220497Smarkm UINT32 Length; 179220497Smarkm UINT8 *Buffer; 180220497Smarkm 181220497Smarkm 182220497Smarkm ACPI_FUNCTION_TRACE_PTR (ExStoreStringToString, SourceDesc); 183220497Smarkm 184220497Smarkm 185220497Smarkm /* If Source and Target are the same, just return */ 186220497Smarkm 187220497Smarkm if (SourceDesc == TargetDesc) 188220497Smarkm { 189220497Smarkm return_ACPI_STATUS (AE_OK); 190220497Smarkm } 191220497Smarkm 192220497Smarkm /* We know that SourceDesc is a string by now */ 193220497Smarkm 194220497Smarkm Buffer = ACPI_CAST_PTR (UINT8, SourceDesc->String.Pointer); 195220497Smarkm Length = SourceDesc->String.Length; 196220497Smarkm 197220497Smarkm /* 198220497Smarkm * Replace existing string value if it will fit and the string 199220497Smarkm * pointer is not a static pointer (part of an ACPI table) 200220497Smarkm */ 201220497Smarkm if ((Length < TargetDesc->String.Length) && 202220497Smarkm (!(TargetDesc->Common.Flags & AOPOBJ_STATIC_POINTER))) 203220497Smarkm { 204220497Smarkm /* 205220497Smarkm * String will fit in existing non-static buffer. 206220497Smarkm * Clear old string and copy in the new one 207220497Smarkm */ 208220497Smarkm ACPI_MEMSET (TargetDesc->String.Pointer, 0, 209220497Smarkm (ACPI_SIZE) TargetDesc->String.Length + 1); 210220497Smarkm ACPI_MEMCPY (TargetDesc->String.Pointer, Buffer, Length); 211220497Smarkm } 212220497Smarkm else 213220497Smarkm { 214220497Smarkm /* 215220497Smarkm * Free the current buffer, then allocate a new buffer 216220497Smarkm * large enough to hold the value 217220497Smarkm */ 218220497Smarkm if (TargetDesc->String.Pointer && 219220497Smarkm (!(TargetDesc->Common.Flags & AOPOBJ_STATIC_POINTER))) 220220497Smarkm { 221220497Smarkm /* Only free if not a pointer into the DSDT */ 222220497Smarkm 223220497Smarkm ACPI_FREE (TargetDesc->String.Pointer); 224220497Smarkm } 225220497Smarkm 226220497Smarkm TargetDesc->String.Pointer = ACPI_ALLOCATE_ZEROED ( 227220497Smarkm (ACPI_SIZE) Length + 1); 228220497Smarkm if (!TargetDesc->String.Pointer) 229220497Smarkm { 230220497Smarkm return_ACPI_STATUS (AE_NO_MEMORY); 231220497Smarkm } 232220497Smarkm 233220497Smarkm TargetDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER; 234220497Smarkm ACPI_MEMCPY (TargetDesc->String.Pointer, Buffer, Length); 235220497Smarkm } 236220497Smarkm 237220497Smarkm /* Set the new target length */ 238220497Smarkm 239220497Smarkm TargetDesc->String.Length = Length; 240220497Smarkm return_ACPI_STATUS (AE_OK); 241220497Smarkm} 242220497Smarkm