exstorob.c revision 281075
1/******************************************************************************
2 *
3 * Module Name: exstorob - AML Interpreter object store support, store to object
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, 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#include <contrib/dev/acpica/include/acpi.h>
45#include <contrib/dev/acpica/include/accommon.h>
46#include <contrib/dev/acpica/include/acinterp.h>
47
48
49#define _COMPONENT          ACPI_EXECUTER
50        ACPI_MODULE_NAME    ("exstorob")
51
52
53/*******************************************************************************
54 *
55 * FUNCTION:    AcpiExStoreBufferToBuffer
56 *
57 * PARAMETERS:  SourceDesc          - Source object to copy
58 *              TargetDesc          - Destination object of the copy
59 *
60 * RETURN:      Status
61 *
62 * DESCRIPTION: Copy a buffer object to another buffer object.
63 *
64 ******************************************************************************/
65
66ACPI_STATUS
67AcpiExStoreBufferToBuffer (
68    ACPI_OPERAND_OBJECT     *SourceDesc,
69    ACPI_OPERAND_OBJECT     *TargetDesc)
70{
71    UINT32                  Length;
72    UINT8                   *Buffer;
73
74
75    ACPI_FUNCTION_TRACE_PTR (ExStoreBufferToBuffer, SourceDesc);
76
77
78    /* If Source and Target are the same, just return */
79
80    if (SourceDesc == TargetDesc)
81    {
82        return_ACPI_STATUS (AE_OK);
83    }
84
85    /* We know that SourceDesc is a buffer by now */
86
87    Buffer = ACPI_CAST_PTR (UINT8, SourceDesc->Buffer.Pointer);
88    Length = SourceDesc->Buffer.Length;
89
90    /*
91     * If target is a buffer of length zero or is a static buffer,
92     * allocate a new buffer of the proper length
93     */
94    if ((TargetDesc->Buffer.Length == 0) ||
95        (TargetDesc->Common.Flags & AOPOBJ_STATIC_POINTER))
96    {
97        TargetDesc->Buffer.Pointer = ACPI_ALLOCATE (Length);
98        if (!TargetDesc->Buffer.Pointer)
99        {
100            return_ACPI_STATUS (AE_NO_MEMORY);
101        }
102
103        TargetDesc->Buffer.Length = Length;
104    }
105
106    /* Copy source buffer to target buffer */
107
108    if (Length <= TargetDesc->Buffer.Length)
109    {
110        /* Clear existing buffer and copy in the new one */
111
112        ACPI_MEMSET (TargetDesc->Buffer.Pointer, 0, TargetDesc->Buffer.Length);
113        ACPI_MEMCPY (TargetDesc->Buffer.Pointer, Buffer, Length);
114
115#ifdef ACPI_OBSOLETE_BEHAVIOR
116        /*
117         * NOTE: ACPI versions up to 3.0 specified that the buffer must be
118         * truncated if the string is smaller than the buffer. However, "other"
119         * implementations of ACPI never did this and thus became the defacto
120         * standard. ACPI 3.0A changes this behavior such that the buffer
121         * is no longer truncated.
122         */
123
124        /*
125         * OBSOLETE BEHAVIOR:
126         * If the original source was a string, we must truncate the buffer,
127         * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer
128         * copy must not truncate the original buffer.
129         */
130        if (OriginalSrcType == ACPI_TYPE_STRING)
131        {
132            /* Set the new length of the target */
133
134            TargetDesc->Buffer.Length = Length;
135        }
136#endif
137    }
138    else
139    {
140        /* Truncate the source, copy only what will fit */
141
142        ACPI_MEMCPY (TargetDesc->Buffer.Pointer, Buffer,
143            TargetDesc->Buffer.Length);
144
145        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
146            "Truncating source buffer from %X to %X\n",
147            Length, TargetDesc->Buffer.Length));
148    }
149
150    /* Copy flags */
151
152    TargetDesc->Buffer.Flags = SourceDesc->Buffer.Flags;
153    TargetDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER;
154    return_ACPI_STATUS (AE_OK);
155}
156
157
158/*******************************************************************************
159 *
160 * FUNCTION:    AcpiExStoreStringToString
161 *
162 * PARAMETERS:  SourceDesc          - Source object to copy
163 *              TargetDesc          - Destination object of the copy
164 *
165 * RETURN:      Status
166 *
167 * DESCRIPTION: Copy a String object to another String object
168 *
169 ******************************************************************************/
170
171ACPI_STATUS
172AcpiExStoreStringToString (
173    ACPI_OPERAND_OBJECT     *SourceDesc,
174    ACPI_OPERAND_OBJECT     *TargetDesc)
175{
176    UINT32                  Length;
177    UINT8                   *Buffer;
178
179
180    ACPI_FUNCTION_TRACE_PTR (ExStoreStringToString, SourceDesc);
181
182
183    /* If Source and Target are the same, just return */
184
185    if (SourceDesc == TargetDesc)
186    {
187        return_ACPI_STATUS (AE_OK);
188    }
189
190    /* We know that SourceDesc is a string by now */
191
192    Buffer = ACPI_CAST_PTR (UINT8, SourceDesc->String.Pointer);
193    Length = SourceDesc->String.Length;
194
195    /*
196     * Replace existing string value if it will fit and the string
197     * pointer is not a static pointer (part of an ACPI table)
198     */
199    if ((Length < TargetDesc->String.Length) &&
200       (!(TargetDesc->Common.Flags & AOPOBJ_STATIC_POINTER)))
201    {
202        /*
203         * String will fit in existing non-static buffer.
204         * Clear old string and copy in the new one
205         */
206        ACPI_MEMSET (TargetDesc->String.Pointer, 0,
207            (ACPI_SIZE) TargetDesc->String.Length + 1);
208        ACPI_MEMCPY (TargetDesc->String.Pointer, Buffer, Length);
209    }
210    else
211    {
212        /*
213         * Free the current buffer, then allocate a new buffer
214         * large enough to hold the value
215         */
216        if (TargetDesc->String.Pointer &&
217           (!(TargetDesc->Common.Flags & AOPOBJ_STATIC_POINTER)))
218        {
219            /* Only free if not a pointer into the DSDT */
220
221            ACPI_FREE (TargetDesc->String.Pointer);
222        }
223
224        TargetDesc->String.Pointer = ACPI_ALLOCATE_ZEROED (
225                                        (ACPI_SIZE) Length + 1);
226        if (!TargetDesc->String.Pointer)
227        {
228            return_ACPI_STATUS (AE_NO_MEMORY);
229        }
230
231        TargetDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER;
232        ACPI_MEMCPY (TargetDesc->String.Pointer, Buffer, Length);
233    }
234
235    /* Set the new target length */
236
237    TargetDesc->String.Length = Length;
238    return_ACPI_STATUS (AE_OK);
239}
240