exstorob.c revision 272461
1/******************************************************************************
2 *
3 * Module Name: exstorob - AML Interpreter object store support, store to object
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2013, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#define __EXSTOROB_C__
45
46#include <contrib/dev/acpica/include/acpi.h>
47#include <contrib/dev/acpica/include/accommon.h>
48#include <contrib/dev/acpica/include/acinterp.h>
49
50
51#define _COMPONENT          ACPI_EXECUTER
52        ACPI_MODULE_NAME    ("exstorob")
53
54
55/*******************************************************************************
56 *
57 * FUNCTION:    AcpiExStoreBufferToBuffer
58 *
59 * PARAMETERS:  SourceDesc          - Source object to copy
60 *              TargetDesc          - Destination object of the copy
61 *
62 * RETURN:      Status
63 *
64 * DESCRIPTION: Copy a buffer object to another buffer object.
65 *
66 ******************************************************************************/
67
68ACPI_STATUS
69AcpiExStoreBufferToBuffer (
70    ACPI_OPERAND_OBJECT     *SourceDesc,
71    ACPI_OPERAND_OBJECT     *TargetDesc)
72{
73    UINT32                  Length;
74    UINT8                   *Buffer;
75
76
77    ACPI_FUNCTION_TRACE_PTR (ExStoreBufferToBuffer, SourceDesc);
78
79
80    /* If Source and Target are the same, just return */
81
82    if (SourceDesc == TargetDesc)
83    {
84        return_ACPI_STATUS (AE_OK);
85    }
86
87    /* We know that SourceDesc is a buffer by now */
88
89    Buffer = ACPI_CAST_PTR (UINT8, SourceDesc->Buffer.Pointer);
90    Length = SourceDesc->Buffer.Length;
91
92    /*
93     * If target is a buffer of length zero or is a static buffer,
94     * allocate a new buffer of the proper length
95     */
96    if ((TargetDesc->Buffer.Length == 0) ||
97        (TargetDesc->Common.Flags & AOPOBJ_STATIC_POINTER))
98    {
99        TargetDesc->Buffer.Pointer = ACPI_ALLOCATE (Length);
100        if (!TargetDesc->Buffer.Pointer)
101        {
102            return_ACPI_STATUS (AE_NO_MEMORY);
103        }
104
105        TargetDesc->Buffer.Length = Length;
106    }
107
108    /* Copy source buffer to target buffer */
109
110    if (Length <= TargetDesc->Buffer.Length)
111    {
112        /* Clear existing buffer and copy in the new one */
113
114        ACPI_MEMSET (TargetDesc->Buffer.Pointer, 0, TargetDesc->Buffer.Length);
115        ACPI_MEMCPY (TargetDesc->Buffer.Pointer, Buffer, Length);
116
117#ifdef ACPI_OBSOLETE_BEHAVIOR
118        /*
119         * NOTE: ACPI versions up to 3.0 specified that the buffer must be
120         * truncated if the string is smaller than the buffer. However, "other"
121         * implementations of ACPI never did this and thus became the defacto
122         * standard. ACPI 3.0A changes this behavior such that the buffer
123         * is no longer truncated.
124         */
125
126        /*
127         * OBSOLETE BEHAVIOR:
128         * If the original source was a string, we must truncate the buffer,
129         * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer
130         * copy must not truncate the original buffer.
131         */
132        if (OriginalSrcType == ACPI_TYPE_STRING)
133        {
134            /* Set the new length of the target */
135
136            TargetDesc->Buffer.Length = Length;
137        }
138#endif
139    }
140    else
141    {
142        /* Truncate the source, copy only what will fit */
143
144        ACPI_MEMCPY (TargetDesc->Buffer.Pointer, Buffer,
145            TargetDesc->Buffer.Length);
146
147        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
148            "Truncating source buffer from %X to %X\n",
149            Length, TargetDesc->Buffer.Length));
150    }
151
152    /* Copy flags */
153
154    TargetDesc->Buffer.Flags = SourceDesc->Buffer.Flags;
155    TargetDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER;
156    return_ACPI_STATUS (AE_OK);
157}
158
159
160/*******************************************************************************
161 *
162 * FUNCTION:    AcpiExStoreStringToString
163 *
164 * PARAMETERS:  SourceDesc          - Source object to copy
165 *              TargetDesc          - Destination object of the copy
166 *
167 * RETURN:      Status
168 *
169 * DESCRIPTION: Copy a String object to another String object
170 *
171 ******************************************************************************/
172
173ACPI_STATUS
174AcpiExStoreStringToString (
175    ACPI_OPERAND_OBJECT     *SourceDesc,
176    ACPI_OPERAND_OBJECT     *TargetDesc)
177{
178    UINT32                  Length;
179    UINT8                   *Buffer;
180
181
182    ACPI_FUNCTION_TRACE_PTR (ExStoreStringToString, SourceDesc);
183
184
185    /* If Source and Target are the same, just return */
186
187    if (SourceDesc == TargetDesc)
188    {
189        return_ACPI_STATUS (AE_OK);
190    }
191
192    /* We know that SourceDesc is a string by now */
193
194    Buffer = ACPI_CAST_PTR (UINT8, SourceDesc->String.Pointer);
195    Length = SourceDesc->String.Length;
196
197    /*
198     * Replace existing string value if it will fit and the string
199     * pointer is not a static pointer (part of an ACPI table)
200     */
201    if ((Length < TargetDesc->String.Length) &&
202       (!(TargetDesc->Common.Flags & AOPOBJ_STATIC_POINTER)))
203    {
204        /*
205         * String will fit in existing non-static buffer.
206         * Clear old string and copy in the new one
207         */
208        ACPI_MEMSET (TargetDesc->String.Pointer, 0,
209            (ACPI_SIZE) TargetDesc->String.Length + 1);
210        ACPI_MEMCPY (TargetDesc->String.Pointer, Buffer, Length);
211    }
212    else
213    {
214        /*
215         * Free the current buffer, then allocate a new buffer
216         * large enough to hold the value
217         */
218        if (TargetDesc->String.Pointer &&
219           (!(TargetDesc->Common.Flags & AOPOBJ_STATIC_POINTER)))
220        {
221            /* Only free if not a pointer into the DSDT */
222
223            ACPI_FREE (TargetDesc->String.Pointer);
224        }
225
226        TargetDesc->String.Pointer = ACPI_ALLOCATE_ZEROED (
227                                        (ACPI_SIZE) Length + 1);
228        if (!TargetDesc->String.Pointer)
229        {
230            return_ACPI_STATUS (AE_NO_MEMORY);
231        }
232
233        TargetDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER;
234        ACPI_MEMCPY (TargetDesc->String.Pointer, Buffer, Length);
235    }
236
237    /* Set the new target length */
238
239    TargetDesc->String.Length = Length;
240    return_ACPI_STATUS (AE_OK);
241}
242