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