1 | /****************************************************************************** |
2 | * |
3 | * Module Name: exstoren - AML Interpreter object store support, |
4 | * Store to Node (namespace object) |
5 | * |
6 | *****************************************************************************/ |
7 | |
8 | /* |
9 | * Copyright (C) 2000 - 2016, Intel Corp. |
10 | * All rights reserved. |
11 | * |
12 | * Redistribution and use in source and binary forms, with or without |
13 | * modification, are permitted provided that the following conditions |
14 | * are met: |
15 | * 1. Redistributions of source code must retain the above copyright |
16 | * notice, this list of conditions, and the following disclaimer, |
17 | * without modification. |
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer |
19 | * substantially similar to the "NO WARRANTY" disclaimer below |
20 | * ("Disclaimer") and any redistribution must be conditioned upon |
21 | * including a substantially similar Disclaimer requirement for further |
22 | * binary redistribution. |
23 | * 3. Neither the names of the above-listed copyright holders nor the names |
24 | * of any contributors may be used to endorse or promote products derived |
25 | * from this software without specific prior written permission. |
26 | * |
27 | * Alternatively, this software may be distributed under the terms of the |
28 | * GNU General Public License ("GPL") version 2 as published by the Free |
29 | * Software Foundation. |
30 | * |
31 | * NO WARRANTY |
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR |
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
42 | * POSSIBILITY OF SUCH DAMAGES. |
43 | */ |
44 | |
45 | #include "acpi.h" |
46 | #include "accommon.h" |
47 | #include "acinterp.h" |
48 | #include "amlcode.h" |
49 | |
50 | |
51 | #define _COMPONENT ACPI_EXECUTER |
52 | ACPI_MODULE_NAME ("exstoren" ) |
53 | |
54 | |
55 | /******************************************************************************* |
56 | * |
57 | * FUNCTION: AcpiExResolveObject |
58 | * |
59 | * PARAMETERS: SourceDescPtr - Pointer to the source object |
60 | * TargetType - Current type of the target |
61 | * WalkState - Current walk state |
62 | * |
63 | * RETURN: Status, resolved object in SourceDescPtr. |
64 | * |
65 | * DESCRIPTION: Resolve an object. If the object is a reference, dereference |
66 | * it and return the actual object in the SourceDescPtr. |
67 | * |
68 | ******************************************************************************/ |
69 | |
70 | ACPI_STATUS |
71 | AcpiExResolveObject ( |
72 | ACPI_OPERAND_OBJECT **SourceDescPtr, |
73 | ACPI_OBJECT_TYPE TargetType, |
74 | ACPI_WALK_STATE *WalkState) |
75 | { |
76 | ACPI_OPERAND_OBJECT *SourceDesc = *SourceDescPtr; |
77 | ACPI_STATUS Status = AE_OK; |
78 | |
79 | |
80 | ACPI_FUNCTION_TRACE (ExResolveObject); |
81 | |
82 | |
83 | /* Ensure we have a Target that can be stored to */ |
84 | |
85 | switch (TargetType) |
86 | { |
87 | case ACPI_TYPE_BUFFER_FIELD: |
88 | case ACPI_TYPE_LOCAL_REGION_FIELD: |
89 | case ACPI_TYPE_LOCAL_BANK_FIELD: |
90 | case ACPI_TYPE_LOCAL_INDEX_FIELD: |
91 | /* |
92 | * These cases all require only Integers or values that |
93 | * can be converted to Integers (Strings or Buffers) |
94 | */ |
95 | case ACPI_TYPE_INTEGER: |
96 | case ACPI_TYPE_STRING: |
97 | case ACPI_TYPE_BUFFER: |
98 | /* |
99 | * Stores into a Field/Region or into a Integer/Buffer/String |
100 | * are all essentially the same. This case handles the |
101 | * "interchangeable" types Integer, String, and Buffer. |
102 | */ |
103 | if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) |
104 | { |
105 | /* Resolve a reference object first */ |
106 | |
107 | Status = AcpiExResolveToValue (SourceDescPtr, WalkState); |
108 | if (ACPI_FAILURE (Status)) |
109 | { |
110 | break; |
111 | } |
112 | } |
113 | |
114 | /* For CopyObject, no further validation necessary */ |
115 | |
116 | if (WalkState->Opcode == AML_COPY_OP) |
117 | { |
118 | break; |
119 | } |
120 | |
121 | /* Must have a Integer, Buffer, or String */ |
122 | |
123 | if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER) && |
124 | (SourceDesc->Common.Type != ACPI_TYPE_BUFFER) && |
125 | (SourceDesc->Common.Type != ACPI_TYPE_STRING) && |
126 | !((SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && |
127 | (SourceDesc->Reference.Class== ACPI_REFCLASS_TABLE))) |
128 | { |
129 | /* Conversion successful but still not a valid type */ |
130 | |
131 | ACPI_ERROR ((AE_INFO, |
132 | "Cannot assign type [%s] to [%s] (must be type Int/Str/Buf)" , |
133 | AcpiUtGetObjectTypeName (SourceDesc), |
134 | AcpiUtGetTypeName (TargetType))); |
135 | |
136 | Status = AE_AML_OPERAND_TYPE; |
137 | } |
138 | break; |
139 | |
140 | case ACPI_TYPE_LOCAL_ALIAS: |
141 | case ACPI_TYPE_LOCAL_METHOD_ALIAS: |
142 | /* |
143 | * All aliases should have been resolved earlier, during the |
144 | * operand resolution phase. |
145 | */ |
146 | ACPI_ERROR ((AE_INFO, "Store into an unresolved Alias object" )); |
147 | Status = AE_AML_INTERNAL; |
148 | break; |
149 | |
150 | case ACPI_TYPE_PACKAGE: |
151 | default: |
152 | /* |
153 | * All other types than Alias and the various Fields come here, |
154 | * including the untyped case - ACPI_TYPE_ANY. |
155 | */ |
156 | break; |
157 | } |
158 | |
159 | return_ACPI_STATUS (Status); |
160 | } |
161 | |
162 | |
163 | /******************************************************************************* |
164 | * |
165 | * FUNCTION: AcpiExStoreObjectToObject |
166 | * |
167 | * PARAMETERS: SourceDesc - Object to store |
168 | * DestDesc - Object to receive a copy of the source |
169 | * NewDesc - New object if DestDesc is obsoleted |
170 | * WalkState - Current walk state |
171 | * |
172 | * RETURN: Status |
173 | * |
174 | * DESCRIPTION: "Store" an object to another object. This may include |
175 | * converting the source type to the target type (implicit |
176 | * conversion), and a copy of the value of the source to |
177 | * the target. |
178 | * |
179 | * The Assignment of an object to another (not named) object |
180 | * is handled here. |
181 | * The Source passed in will replace the current value (if any) |
182 | * with the input value. |
183 | * |
184 | * When storing into an object the data is converted to the |
185 | * target object type then stored in the object. This means |
186 | * that the target object type (for an initialized target) will |
187 | * not be changed by a store operation. |
188 | * |
189 | * This module allows destination types of Number, String, |
190 | * Buffer, and Package. |
191 | * |
192 | * Assumes parameters are already validated. NOTE: SourceDesc |
193 | * resolution (from a reference object) must be performed by |
194 | * the caller if necessary. |
195 | * |
196 | ******************************************************************************/ |
197 | |
198 | ACPI_STATUS |
199 | AcpiExStoreObjectToObject ( |
200 | ACPI_OPERAND_OBJECT *SourceDesc, |
201 | ACPI_OPERAND_OBJECT *DestDesc, |
202 | ACPI_OPERAND_OBJECT **NewDesc, |
203 | ACPI_WALK_STATE *WalkState) |
204 | { |
205 | ACPI_OPERAND_OBJECT *ActualSrcDesc; |
206 | ACPI_STATUS Status = AE_OK; |
207 | |
208 | |
209 | ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToObject, SourceDesc); |
210 | |
211 | |
212 | ActualSrcDesc = SourceDesc; |
213 | if (!DestDesc) |
214 | { |
215 | /* |
216 | * There is no destination object (An uninitialized node or |
217 | * package element), so we can simply copy the source object |
218 | * creating a new destination object |
219 | */ |
220 | Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, NewDesc, WalkState); |
221 | return_ACPI_STATUS (Status); |
222 | } |
223 | |
224 | if (SourceDesc->Common.Type != DestDesc->Common.Type) |
225 | { |
226 | /* |
227 | * The source type does not match the type of the destination. |
228 | * Perform the "implicit conversion" of the source to the current type |
229 | * of the target as per the ACPI specification. |
230 | * |
231 | * If no conversion performed, ActualSrcDesc = SourceDesc. |
232 | * Otherwise, ActualSrcDesc is a temporary object to hold the |
233 | * converted object. |
234 | */ |
235 | Status = AcpiExConvertToTargetType (DestDesc->Common.Type, |
236 | SourceDesc, &ActualSrcDesc, WalkState); |
237 | if (ACPI_FAILURE (Status)) |
238 | { |
239 | return_ACPI_STATUS (Status); |
240 | } |
241 | |
242 | if (SourceDesc == ActualSrcDesc) |
243 | { |
244 | /* |
245 | * No conversion was performed. Return the SourceDesc as the |
246 | * new object. |
247 | */ |
248 | *NewDesc = SourceDesc; |
249 | return_ACPI_STATUS (AE_OK); |
250 | } |
251 | } |
252 | |
253 | /* |
254 | * We now have two objects of identical types, and we can perform a |
255 | * copy of the *value* of the source object. |
256 | */ |
257 | switch (DestDesc->Common.Type) |
258 | { |
259 | case ACPI_TYPE_INTEGER: |
260 | |
261 | DestDesc->Integer.Value = ActualSrcDesc->Integer.Value; |
262 | |
263 | /* Truncate value if we are executing from a 32-bit ACPI table */ |
264 | |
265 | (void) AcpiExTruncateFor32bitTable (DestDesc); |
266 | break; |
267 | |
268 | case ACPI_TYPE_STRING: |
269 | |
270 | Status = AcpiExStoreStringToString (ActualSrcDesc, DestDesc); |
271 | break; |
272 | |
273 | case ACPI_TYPE_BUFFER: |
274 | |
275 | Status = AcpiExStoreBufferToBuffer (ActualSrcDesc, DestDesc); |
276 | break; |
277 | |
278 | case ACPI_TYPE_PACKAGE: |
279 | |
280 | Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, &DestDesc, |
281 | WalkState); |
282 | break; |
283 | |
284 | default: |
285 | /* |
286 | * All other types come here. |
287 | */ |
288 | ACPI_WARNING ((AE_INFO, "Store into type [%s] not implemented" , |
289 | AcpiUtGetObjectTypeName (DestDesc))); |
290 | |
291 | Status = AE_NOT_IMPLEMENTED; |
292 | break; |
293 | } |
294 | |
295 | if (ActualSrcDesc != SourceDesc) |
296 | { |
297 | /* Delete the intermediate (temporary) source object */ |
298 | |
299 | AcpiUtRemoveReference (ActualSrcDesc); |
300 | } |
301 | |
302 | *NewDesc = DestDesc; |
303 | return_ACPI_STATUS (Status); |
304 | } |
305 | |