167754Smsmith/****************************************************************************** 267754Smsmith * 3306536Sjkim * Module Name: exstorob - AML object store support, store to object 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 4767754Smsmith 4867754Smsmith 4977424Smsmith#define _COMPONENT ACPI_EXECUTER 5091116Smsmith ACPI_MODULE_NAME ("exstorob") 5167754Smsmith 5267754Smsmith 5367754Smsmith/******************************************************************************* 5467754Smsmith * 5591116Smsmith * FUNCTION: AcpiExStoreBufferToBuffer 5667754Smsmith * 5771867Smsmith * PARAMETERS: SourceDesc - Source object to copy 5871867Smsmith * TargetDesc - Destination object of the copy 5967754Smsmith * 6067754Smsmith * RETURN: Status 6167754Smsmith * 6271867Smsmith * DESCRIPTION: Copy a buffer object to another buffer object. 6367754Smsmith * 6471867Smsmith ******************************************************************************/ 6571867Smsmith 6671867SmsmithACPI_STATUS 6791116SmsmithAcpiExStoreBufferToBuffer ( 6871867Smsmith ACPI_OPERAND_OBJECT *SourceDesc, 6971867Smsmith ACPI_OPERAND_OBJECT *TargetDesc) 7071867Smsmith{ 7171867Smsmith UINT32 Length; 7271867Smsmith UINT8 *Buffer; 7377424Smsmith 7477424Smsmith 75167802Sjkim ACPI_FUNCTION_TRACE_PTR (ExStoreBufferToBuffer, SourceDesc); 7682367Smsmith 7783174Smsmith 78197104Sjkim /* If Source and Target are the same, just return */ 79197104Sjkim 80197104Sjkim if (SourceDesc == TargetDesc) 81197104Sjkim { 82197104Sjkim return_ACPI_STATUS (AE_OK); 83197104Sjkim } 84197104Sjkim 85151937Sjkim /* We know that SourceDesc is a buffer by now */ 86151937Sjkim 87167802Sjkim Buffer = ACPI_CAST_PTR (UINT8, SourceDesc->Buffer.Pointer); 8871867Smsmith Length = SourceDesc->Buffer.Length; 8971867Smsmith 9071867Smsmith /* 91114237Snjl * If target is a buffer of length zero or is a static buffer, 92114237Snjl * allocate a new buffer of the proper length 9373561Smsmith */ 94114237Snjl if ((TargetDesc->Buffer.Length == 0) || 95114237Snjl (TargetDesc->Common.Flags & AOPOBJ_STATIC_POINTER)) 9673561Smsmith { 97167802Sjkim TargetDesc->Buffer.Pointer = ACPI_ALLOCATE (Length); 9873561Smsmith if (!TargetDesc->Buffer.Pointer) 9973561Smsmith { 100114237Snjl return_ACPI_STATUS (AE_NO_MEMORY); 10173561Smsmith } 10273561Smsmith 10373561Smsmith TargetDesc->Buffer.Length = Length; 10473561Smsmith } 10577424Smsmith 106151937Sjkim /* Copy source buffer to target buffer */ 107151937Sjkim 10871867Smsmith if (Length <= TargetDesc->Buffer.Length) 10971867Smsmith { 11071867Smsmith /* Clear existing buffer and copy in the new one */ 11171867Smsmith 112306536Sjkim memset (TargetDesc->Buffer.Pointer, 0, TargetDesc->Buffer.Length); 113306536Sjkim memcpy (TargetDesc->Buffer.Pointer, Buffer, Length); 114151937Sjkim 115151937Sjkim#ifdef ACPI_OBSOLETE_BEHAVIOR 116151937Sjkim /* 117151937Sjkim * NOTE: ACPI versions up to 3.0 specified that the buffer must be 118241973Sjkim * truncated if the string is smaller than the buffer. However, "other" 119151937Sjkim * implementations of ACPI never did this and thus became the defacto 120151937Sjkim * standard. ACPI 3.0A changes this behavior such that the buffer 121151937Sjkim * is no longer truncated. 122151937Sjkim */ 123151937Sjkim 124151937Sjkim /* 125151937Sjkim * OBSOLETE BEHAVIOR: 126151937Sjkim * If the original source was a string, we must truncate the buffer, 127241973Sjkim * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer 128151937Sjkim * copy must not truncate the original buffer. 129151937Sjkim */ 130151937Sjkim if (OriginalSrcType == ACPI_TYPE_STRING) 131151937Sjkim { 132151937Sjkim /* Set the new length of the target */ 133151937Sjkim 134151937Sjkim TargetDesc->Buffer.Length = Length; 135151937Sjkim } 136151937Sjkim#endif 13771867Smsmith } 13877424Smsmith else 13971867Smsmith { 140151937Sjkim /* Truncate the source, copy only what will fit */ 14171867Smsmith 142306536Sjkim memcpy (TargetDesc->Buffer.Pointer, Buffer, 143151937Sjkim TargetDesc->Buffer.Length); 144151937Sjkim 14582367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 146151937Sjkim "Truncating source buffer from %X to %X\n", 14771867Smsmith Length, TargetDesc->Buffer.Length)); 14871867Smsmith } 14971867Smsmith 15099146Siwasaki /* Copy flags */ 15199146Siwasaki 15299146Siwasaki TargetDesc->Buffer.Flags = SourceDesc->Buffer.Flags; 153151937Sjkim TargetDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER; 154114237Snjl return_ACPI_STATUS (AE_OK); 15571867Smsmith} 15671867Smsmith 15771867Smsmith 15871867Smsmith/******************************************************************************* 15967754Smsmith * 16091116Smsmith * FUNCTION: AcpiExStoreStringToString 16167754Smsmith * 16271867Smsmith * PARAMETERS: SourceDesc - Source object to copy 16371867Smsmith * TargetDesc - Destination object of the copy 16467754Smsmith * 16571867Smsmith * RETURN: Status 16671867Smsmith * 16771867Smsmith * DESCRIPTION: Copy a String object to another String object 16871867Smsmith * 16967754Smsmith ******************************************************************************/ 17067754Smsmith 17167754SmsmithACPI_STATUS 17291116SmsmithAcpiExStoreStringToString ( 17371867Smsmith ACPI_OPERAND_OBJECT *SourceDesc, 17471867Smsmith ACPI_OPERAND_OBJECT *TargetDesc) 17567754Smsmith{ 17671867Smsmith UINT32 Length; 17771867Smsmith UINT8 *Buffer; 17867754Smsmith 17967754Smsmith 180167802Sjkim ACPI_FUNCTION_TRACE_PTR (ExStoreStringToString, SourceDesc); 18183174Smsmith 18283174Smsmith 183197104Sjkim /* If Source and Target are the same, just return */ 184197104Sjkim 185197104Sjkim if (SourceDesc == TargetDesc) 186197104Sjkim { 187197104Sjkim return_ACPI_STATUS (AE_OK); 188197104Sjkim } 189197104Sjkim 190151937Sjkim /* We know that SourceDesc is a string by now */ 191151937Sjkim 192167802Sjkim Buffer = ACPI_CAST_PTR (UINT8, SourceDesc->String.Pointer); 19371867Smsmith Length = SourceDesc->String.Length; 19467754Smsmith 19567754Smsmith /* 196114237Snjl * Replace existing string value if it will fit and the string 197114237Snjl * pointer is not a static pointer (part of an ACPI table) 19867754Smsmith */ 199114237Snjl if ((Length < TargetDesc->String.Length) && 200114237Snjl (!(TargetDesc->Common.Flags & AOPOBJ_STATIC_POINTER))) 20167754Smsmith { 202114237Snjl /* 203114237Snjl * String will fit in existing non-static buffer. 204114237Snjl * Clear old string and copy in the new one 205104470Siwasaki */ 206306536Sjkim memset (TargetDesc->String.Pointer, 0, 207151937Sjkim (ACPI_SIZE) TargetDesc->String.Length + 1); 208306536Sjkim memcpy (TargetDesc->String.Pointer, Buffer, Length); 20971867Smsmith } 21071867Smsmith else 21171867Smsmith { 21267754Smsmith /* 213104470Siwasaki * Free the current buffer, then allocate a new buffer 21471867Smsmith * large enough to hold the value 21567754Smsmith */ 21671867Smsmith if (TargetDesc->String.Pointer && 21782367Smsmith (!(TargetDesc->Common.Flags & AOPOBJ_STATIC_POINTER))) 21867754Smsmith { 219151937Sjkim /* Only free if not a pointer into the DSDT */ 220151937Sjkim 221167802Sjkim ACPI_FREE (TargetDesc->String.Pointer); 22267754Smsmith } 22367754Smsmith 224306536Sjkim TargetDesc->String.Pointer = 225306536Sjkim ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) Length + 1); 226306536Sjkim 22771867Smsmith if (!TargetDesc->String.Pointer) 22867754Smsmith { 229114237Snjl return_ACPI_STATUS (AE_NO_MEMORY); 23067754Smsmith } 23183174Smsmith 232114237Snjl TargetDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER; 233306536Sjkim memcpy (TargetDesc->String.Pointer, Buffer, Length); 23471867Smsmith } 23567754Smsmith 236104470Siwasaki /* Set the new target length */ 237104470Siwasaki 238104470Siwasaki TargetDesc->String.Length = Length; 239114237Snjl return_ACPI_STATUS (AE_OK); 24071867Smsmith} 241