]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/contrib/dev/acpica/components/executer/exstorob.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / contrib / dev / acpica / components / executer / exstorob.c
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
68 ACPI_STATUS
69 AcpiExStoreBufferToBuffer (
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
173 ACPI_STATUS
174 AcpiExStoreStringToString (
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 }