1 | /****************************************************************************** |
2 | * |
3 | * Module Name: exstore - AML Interpreter object store support |
4 | * |
5 | *****************************************************************************/ |
6 | |
7 | /* |
8 | * Copyright (C) 2000 - 2016, 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 "acpi.h" |
45 | #include "accommon.h" |
46 | #include "acdispat.h" |
47 | #include "acinterp.h" |
48 | #include "amlcode.h" |
49 | #include "acnamesp.h" |
50 | |
51 | |
52 | #define _COMPONENT ACPI_EXECUTER |
53 | ACPI_MODULE_NAME ("exstore" ) |
54 | |
55 | /* Local prototypes */ |
56 | |
57 | static ACPI_STATUS |
58 | AcpiExStoreObjectToIndex ( |
59 | ACPI_OPERAND_OBJECT *ValDesc, |
60 | ACPI_OPERAND_OBJECT *DestDesc, |
61 | ACPI_WALK_STATE *WalkState); |
62 | |
63 | static ACPI_STATUS |
64 | AcpiExStoreDirectToNode ( |
65 | ACPI_OPERAND_OBJECT *SourceDesc, |
66 | ACPI_NAMESPACE_NODE *Node, |
67 | ACPI_WALK_STATE *WalkState); |
68 | |
69 | |
70 | /******************************************************************************* |
71 | * |
72 | * FUNCTION: AcpiExStore |
73 | * |
74 | * PARAMETERS: *SourceDesc - Value to be stored |
75 | * *DestDesc - Where to store it. Must be an NS node |
76 | * or ACPI_OPERAND_OBJECT of type |
77 | * Reference; |
78 | * WalkState - Current walk state |
79 | * |
80 | * RETURN: Status |
81 | * |
82 | * DESCRIPTION: Store the value described by SourceDesc into the location |
83 | * described by DestDesc. Called by various interpreter |
84 | * functions to store the result of an operation into |
85 | * the destination operand -- not just simply the actual "Store" |
86 | * ASL operator. |
87 | * |
88 | ******************************************************************************/ |
89 | |
90 | ACPI_STATUS |
91 | AcpiExStore ( |
92 | ACPI_OPERAND_OBJECT *SourceDesc, |
93 | ACPI_OPERAND_OBJECT *DestDesc, |
94 | ACPI_WALK_STATE *WalkState) |
95 | { |
96 | ACPI_STATUS Status = AE_OK; |
97 | ACPI_OPERAND_OBJECT *RefDesc = DestDesc; |
98 | |
99 | |
100 | ACPI_FUNCTION_TRACE_PTR (ExStore, DestDesc); |
101 | |
102 | |
103 | /* Validate parameters */ |
104 | |
105 | if (!SourceDesc || !DestDesc) |
106 | { |
107 | ACPI_ERROR ((AE_INFO, "Null parameter" )); |
108 | return_ACPI_STATUS (AE_AML_NO_OPERAND); |
109 | } |
110 | |
111 | /* DestDesc can be either a namespace node or an ACPI object */ |
112 | |
113 | if (ACPI_GET_DESCRIPTOR_TYPE (DestDesc) == ACPI_DESC_TYPE_NAMED) |
114 | { |
115 | /* |
116 | * Dest is a namespace node, |
117 | * Storing an object into a Named node. |
118 | */ |
119 | Status = AcpiExStoreObjectToNode (SourceDesc, |
120 | (ACPI_NAMESPACE_NODE *) DestDesc, WalkState, |
121 | ACPI_IMPLICIT_CONVERSION); |
122 | |
123 | return_ACPI_STATUS (Status); |
124 | } |
125 | |
126 | /* Destination object must be a Reference or a Constant object */ |
127 | |
128 | switch (DestDesc->Common.Type) |
129 | { |
130 | case ACPI_TYPE_LOCAL_REFERENCE: |
131 | |
132 | break; |
133 | |
134 | case ACPI_TYPE_INTEGER: |
135 | |
136 | /* Allow stores to Constants -- a Noop as per ACPI spec */ |
137 | |
138 | if (DestDesc->Common.Flags & AOPOBJ_AML_CONSTANT) |
139 | { |
140 | return_ACPI_STATUS (AE_OK); |
141 | } |
142 | |
143 | /*lint -fallthrough */ |
144 | |
145 | default: |
146 | |
147 | /* Destination is not a Reference object */ |
148 | |
149 | ACPI_ERROR ((AE_INFO, |
150 | "Target is not a Reference or Constant object - [%s] %p" , |
151 | AcpiUtGetObjectTypeName (DestDesc), DestDesc)); |
152 | |
153 | return_ACPI_STATUS (AE_AML_OPERAND_TYPE); |
154 | } |
155 | |
156 | /* |
157 | * Examine the Reference class. These cases are handled: |
158 | * |
159 | * 1) Store to Name (Change the object associated with a name) |
160 | * 2) Store to an indexed area of a Buffer or Package |
161 | * 3) Store to a Method Local or Arg |
162 | * 4) Store to the debug object |
163 | */ |
164 | switch (RefDesc->Reference.Class) |
165 | { |
166 | case ACPI_REFCLASS_REFOF: |
167 | |
168 | /* Storing an object into a Name "container" */ |
169 | |
170 | Status = AcpiExStoreObjectToNode (SourceDesc, |
171 | RefDesc->Reference.Object, |
172 | WalkState, ACPI_IMPLICIT_CONVERSION); |
173 | break; |
174 | |
175 | case ACPI_REFCLASS_INDEX: |
176 | |
177 | /* Storing to an Index (pointer into a packager or buffer) */ |
178 | |
179 | Status = AcpiExStoreObjectToIndex (SourceDesc, RefDesc, WalkState); |
180 | break; |
181 | |
182 | case ACPI_REFCLASS_LOCAL: |
183 | case ACPI_REFCLASS_ARG: |
184 | |
185 | /* Store to a method local/arg */ |
186 | |
187 | Status = AcpiDsStoreObjectToLocal (RefDesc->Reference.Class, |
188 | RefDesc->Reference.Value, SourceDesc, WalkState); |
189 | break; |
190 | |
191 | case ACPI_REFCLASS_DEBUG: |
192 | /* |
193 | * Storing to the Debug object causes the value stored to be |
194 | * displayed and otherwise has no effect -- see ACPI Specification |
195 | */ |
196 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, |
197 | "**** Write to Debug Object: Object %p [%s] ****:\n\n" , |
198 | SourceDesc, AcpiUtGetObjectTypeName (SourceDesc))); |
199 | |
200 | ACPI_DEBUG_OBJECT (SourceDesc, 0, 0); |
201 | break; |
202 | |
203 | default: |
204 | |
205 | ACPI_ERROR ((AE_INFO, "Unknown Reference Class 0x%2.2X" , |
206 | RefDesc->Reference.Class)); |
207 | ACPI_DUMP_ENTRY (RefDesc, ACPI_LV_INFO); |
208 | |
209 | Status = AE_AML_INTERNAL; |
210 | break; |
211 | } |
212 | |
213 | return_ACPI_STATUS (Status); |
214 | } |
215 | |
216 | |
217 | /******************************************************************************* |
218 | * |
219 | * FUNCTION: AcpiExStoreObjectToIndex |
220 | * |
221 | * PARAMETERS: *SourceDesc - Value to be stored |
222 | * *DestDesc - Named object to receive the value |
223 | * WalkState - Current walk state |
224 | * |
225 | * RETURN: Status |
226 | * |
227 | * DESCRIPTION: Store the object to indexed Buffer or Package element |
228 | * |
229 | ******************************************************************************/ |
230 | |
231 | static ACPI_STATUS |
232 | AcpiExStoreObjectToIndex ( |
233 | ACPI_OPERAND_OBJECT *SourceDesc, |
234 | ACPI_OPERAND_OBJECT *IndexDesc, |
235 | ACPI_WALK_STATE *WalkState) |
236 | { |
237 | ACPI_STATUS Status = AE_OK; |
238 | ACPI_OPERAND_OBJECT *ObjDesc; |
239 | ACPI_OPERAND_OBJECT *NewDesc; |
240 | UINT8 Value = 0; |
241 | UINT32 i; |
242 | |
243 | |
244 | ACPI_FUNCTION_TRACE (ExStoreObjectToIndex); |
245 | |
246 | |
247 | /* |
248 | * Destination must be a reference pointer, and |
249 | * must point to either a buffer or a package |
250 | */ |
251 | switch (IndexDesc->Reference.TargetType) |
252 | { |
253 | case ACPI_TYPE_PACKAGE: |
254 | /* |
255 | * Storing to a package element. Copy the object and replace |
256 | * any existing object with the new object. No implicit |
257 | * conversion is performed. |
258 | * |
259 | * The object at *(IndexDesc->Reference.Where) is the |
260 | * element within the package that is to be modified. |
261 | * The parent package object is at IndexDesc->Reference.Object |
262 | */ |
263 | ObjDesc = *(IndexDesc->Reference.Where); |
264 | |
265 | if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE && |
266 | SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE) |
267 | { |
268 | /* This is a DDBHandle, just add a reference to it */ |
269 | |
270 | AcpiUtAddReference (SourceDesc); |
271 | NewDesc = SourceDesc; |
272 | } |
273 | else |
274 | { |
275 | /* Normal object, copy it */ |
276 | |
277 | Status = AcpiUtCopyIobjectToIobject ( |
278 | SourceDesc, &NewDesc, WalkState); |
279 | if (ACPI_FAILURE (Status)) |
280 | { |
281 | return_ACPI_STATUS (Status); |
282 | } |
283 | } |
284 | |
285 | if (ObjDesc) |
286 | { |
287 | /* Decrement reference count by the ref count of the parent package */ |
288 | |
289 | for (i = 0; |
290 | i < ((ACPI_OPERAND_OBJECT *) |
291 | IndexDesc->Reference.Object)->Common.ReferenceCount; |
292 | i++) |
293 | { |
294 | AcpiUtRemoveReference (ObjDesc); |
295 | } |
296 | } |
297 | |
298 | *(IndexDesc->Reference.Where) = NewDesc; |
299 | |
300 | /* Increment ref count by the ref count of the parent package-1 */ |
301 | |
302 | for (i = 1; |
303 | i < ((ACPI_OPERAND_OBJECT *) |
304 | IndexDesc->Reference.Object)->Common.ReferenceCount; |
305 | i++) |
306 | { |
307 | AcpiUtAddReference (NewDesc); |
308 | } |
309 | |
310 | break; |
311 | |
312 | case ACPI_TYPE_BUFFER_FIELD: |
313 | /* |
314 | * Store into a Buffer or String (not actually a real BufferField) |
315 | * at a location defined by an Index. |
316 | * |
317 | * The first 8-bit element of the source object is written to the |
318 | * 8-bit Buffer location defined by the Index destination object, |
319 | * according to the ACPI 2.0 specification. |
320 | */ |
321 | |
322 | /* |
323 | * Make sure the target is a Buffer or String. An error should |
324 | * not happen here, since the ReferenceObject was constructed |
325 | * by the INDEX_OP code. |
326 | */ |
327 | ObjDesc = IndexDesc->Reference.Object; |
328 | if ((ObjDesc->Common.Type != ACPI_TYPE_BUFFER) && |
329 | (ObjDesc->Common.Type != ACPI_TYPE_STRING)) |
330 | { |
331 | return_ACPI_STATUS (AE_AML_OPERAND_TYPE); |
332 | } |
333 | |
334 | /* |
335 | * The assignment of the individual elements will be slightly |
336 | * different for each source type. |
337 | */ |
338 | switch (SourceDesc->Common.Type) |
339 | { |
340 | case ACPI_TYPE_INTEGER: |
341 | |
342 | /* Use the least-significant byte of the integer */ |
343 | |
344 | Value = (UINT8) (SourceDesc->Integer.Value); |
345 | break; |
346 | |
347 | case ACPI_TYPE_BUFFER: |
348 | case ACPI_TYPE_STRING: |
349 | |
350 | /* Note: Takes advantage of common string/buffer fields */ |
351 | |
352 | Value = SourceDesc->Buffer.Pointer[0]; |
353 | break; |
354 | |
355 | default: |
356 | |
357 | /* All other types are invalid */ |
358 | |
359 | ACPI_ERROR ((AE_INFO, |
360 | "Source must be type [Integer/Buffer/String], found [%s]" , |
361 | AcpiUtGetObjectTypeName (SourceDesc))); |
362 | return_ACPI_STATUS (AE_AML_OPERAND_TYPE); |
363 | } |
364 | |
365 | /* Store the source value into the target buffer byte */ |
366 | |
367 | ObjDesc->Buffer.Pointer[IndexDesc->Reference.Value] = Value; |
368 | break; |
369 | |
370 | default: |
371 | ACPI_ERROR ((AE_INFO, |
372 | "Target is not of type [Package/BufferField]" )); |
373 | Status = AE_AML_TARGET_TYPE; |
374 | break; |
375 | } |
376 | |
377 | return_ACPI_STATUS (Status); |
378 | } |
379 | |
380 | |
381 | /******************************************************************************* |
382 | * |
383 | * FUNCTION: AcpiExStoreObjectToNode |
384 | * |
385 | * PARAMETERS: SourceDesc - Value to be stored |
386 | * Node - Named object to receive the value |
387 | * WalkState - Current walk state |
388 | * ImplicitConversion - Perform implicit conversion (yes/no) |
389 | * |
390 | * RETURN: Status |
391 | * |
392 | * DESCRIPTION: Store the object to the named object. |
393 | * |
394 | * The assignment of an object to a named object is handled here. |
395 | * The value passed in will replace the current value (if any) |
396 | * with the input value. |
397 | * |
398 | * When storing into an object the data is converted to the |
399 | * target object type then stored in the object. This means |
400 | * that the target object type (for an initialized target) will |
401 | * not be changed by a store operation. A CopyObject can change |
402 | * the target type, however. |
403 | * |
404 | * The ImplicitConversion flag is set to NO/FALSE only when |
405 | * storing to an ArgX -- as per the rules of the ACPI spec. |
406 | * |
407 | * Assumes parameters are already validated. |
408 | * |
409 | ******************************************************************************/ |
410 | |
411 | ACPI_STATUS |
412 | AcpiExStoreObjectToNode ( |
413 | ACPI_OPERAND_OBJECT *SourceDesc, |
414 | ACPI_NAMESPACE_NODE *Node, |
415 | ACPI_WALK_STATE *WalkState, |
416 | UINT8 ImplicitConversion) |
417 | { |
418 | ACPI_STATUS Status = AE_OK; |
419 | ACPI_OPERAND_OBJECT *TargetDesc; |
420 | ACPI_OPERAND_OBJECT *NewDesc; |
421 | ACPI_OBJECT_TYPE TargetType; |
422 | |
423 | |
424 | ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToNode, SourceDesc); |
425 | |
426 | |
427 | /* Get current type of the node, and object attached to Node */ |
428 | |
429 | TargetType = AcpiNsGetType (Node); |
430 | TargetDesc = AcpiNsGetAttachedObject (Node); |
431 | |
432 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p [%s] to node %p [%s]\n" , |
433 | SourceDesc, AcpiUtGetObjectTypeName (SourceDesc), |
434 | Node, AcpiUtGetTypeName (TargetType))); |
435 | |
436 | /* Only limited target types possible for everything except CopyObject */ |
437 | |
438 | if (WalkState->Opcode != AML_COPY_OP) |
439 | { |
440 | /* |
441 | * Only CopyObject allows all object types to be overwritten. For |
442 | * TargetRef(s), there are restrictions on the object types that |
443 | * are allowed. |
444 | * |
445 | * Allowable operations/typing for Store: |
446 | * |
447 | * 1) Simple Store |
448 | * Integer --> Integer (Named/Local/Arg) |
449 | * String --> String (Named/Local/Arg) |
450 | * Buffer --> Buffer (Named/Local/Arg) |
451 | * Package --> Package (Named/Local/Arg) |
452 | * |
453 | * 2) Store with implicit conversion |
454 | * Integer --> String or Buffer (Named) |
455 | * String --> Integer or Buffer (Named) |
456 | * Buffer --> Integer or String (Named) |
457 | */ |
458 | switch (TargetType) |
459 | { |
460 | case ACPI_TYPE_PACKAGE: |
461 | /* |
462 | * Here, can only store a package to an existing package. |
463 | * Storing a package to a Local/Arg is OK, and handled |
464 | * elsewhere. |
465 | */ |
466 | if (WalkState->Opcode == AML_STORE_OP) |
467 | { |
468 | if (SourceDesc->Common.Type != ACPI_TYPE_PACKAGE) |
469 | { |
470 | ACPI_ERROR ((AE_INFO, |
471 | "Cannot assign type [%s] to [Package] " |
472 | "(source must be type Pkg)" , |
473 | AcpiUtGetObjectTypeName (SourceDesc))); |
474 | |
475 | return_ACPI_STATUS (AE_AML_TARGET_TYPE); |
476 | } |
477 | break; |
478 | } |
479 | |
480 | /* Fallthrough */ |
481 | |
482 | case ACPI_TYPE_DEVICE: |
483 | case ACPI_TYPE_EVENT: |
484 | case ACPI_TYPE_MUTEX: |
485 | case ACPI_TYPE_REGION: |
486 | case ACPI_TYPE_POWER: |
487 | case ACPI_TYPE_PROCESSOR: |
488 | case ACPI_TYPE_THERMAL: |
489 | |
490 | ACPI_ERROR ((AE_INFO, |
491 | "Target must be [Buffer/Integer/String/Reference]" |
492 | ", found [%s] (%4.4s)" , |
493 | AcpiUtGetTypeName (Node->Type), Node->Name.Ascii)); |
494 | |
495 | return_ACPI_STATUS (AE_AML_TARGET_TYPE); |
496 | |
497 | default: |
498 | break; |
499 | } |
500 | } |
501 | |
502 | /* |
503 | * Resolve the source object to an actual value |
504 | * (If it is a reference object) |
505 | */ |
506 | Status = AcpiExResolveObject (&SourceDesc, TargetType, WalkState); |
507 | if (ACPI_FAILURE (Status)) |
508 | { |
509 | return_ACPI_STATUS (Status); |
510 | } |
511 | |
512 | /* Do the actual store operation */ |
513 | |
514 | switch (TargetType) |
515 | { |
516 | /* |
517 | * The simple data types all support implicit source operand |
518 | * conversion before the store. |
519 | */ |
520 | case ACPI_TYPE_INTEGER: |
521 | case ACPI_TYPE_STRING: |
522 | case ACPI_TYPE_BUFFER: |
523 | |
524 | if ((WalkState->Opcode == AML_COPY_OP) || |
525 | !ImplicitConversion) |
526 | { |
527 | /* |
528 | * However, CopyObject and Stores to ArgX do not perform |
529 | * an implicit conversion, as per the ACPI specification. |
530 | * A direct store is performed instead. |
531 | */ |
532 | Status = AcpiExStoreDirectToNode (SourceDesc, Node, WalkState); |
533 | break; |
534 | } |
535 | |
536 | /* Store with implicit source operand conversion support */ |
537 | |
538 | Status = AcpiExStoreObjectToObject (SourceDesc, TargetDesc, |
539 | &NewDesc, WalkState); |
540 | if (ACPI_FAILURE (Status)) |
541 | { |
542 | return_ACPI_STATUS (Status); |
543 | } |
544 | |
545 | if (NewDesc != TargetDesc) |
546 | { |
547 | /* |
548 | * Store the new NewDesc as the new value of the Name, and set |
549 | * the Name's type to that of the value being stored in it. |
550 | * SourceDesc reference count is incremented by AttachObject. |
551 | * |
552 | * Note: This may change the type of the node if an explicit |
553 | * store has been performed such that the node/object type |
554 | * has been changed. |
555 | */ |
556 | Status = AcpiNsAttachObject ( |
557 | Node, NewDesc, NewDesc->Common.Type); |
558 | |
559 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, |
560 | "Store type [%s] into [%s] via Convert/Attach\n" , |
561 | AcpiUtGetObjectTypeName (SourceDesc), |
562 | AcpiUtGetObjectTypeName (NewDesc))); |
563 | } |
564 | break; |
565 | |
566 | case ACPI_TYPE_BUFFER_FIELD: |
567 | case ACPI_TYPE_LOCAL_REGION_FIELD: |
568 | case ACPI_TYPE_LOCAL_BANK_FIELD: |
569 | case ACPI_TYPE_LOCAL_INDEX_FIELD: |
570 | /* |
571 | * For all fields, always write the source data to the target |
572 | * field. Any required implicit source operand conversion is |
573 | * performed in the function below as necessary. Note, field |
574 | * objects must retain their original type permanently. |
575 | */ |
576 | Status = AcpiExWriteDataToField (SourceDesc, TargetDesc, |
577 | &WalkState->ResultObj); |
578 | break; |
579 | |
580 | default: |
581 | /* |
582 | * CopyObject operator: No conversions for all other types. |
583 | * Instead, directly store a copy of the source object. |
584 | * |
585 | * This is the ACPI spec-defined behavior for the CopyObject |
586 | * operator. (Note, for this default case, all normal |
587 | * Store/Target operations exited above with an error). |
588 | */ |
589 | Status = AcpiExStoreDirectToNode (SourceDesc, Node, WalkState); |
590 | break; |
591 | } |
592 | |
593 | return_ACPI_STATUS (Status); |
594 | } |
595 | |
596 | |
597 | /******************************************************************************* |
598 | * |
599 | * FUNCTION: AcpiExStoreDirectToNode |
600 | * |
601 | * PARAMETERS: SourceDesc - Value to be stored |
602 | * Node - Named object to receive the value |
603 | * WalkState - Current walk state |
604 | * |
605 | * RETURN: Status |
606 | * |
607 | * DESCRIPTION: "Store" an object directly to a node. This involves a copy |
608 | * and an attach. |
609 | * |
610 | ******************************************************************************/ |
611 | |
612 | static ACPI_STATUS |
613 | AcpiExStoreDirectToNode ( |
614 | ACPI_OPERAND_OBJECT *SourceDesc, |
615 | ACPI_NAMESPACE_NODE *Node, |
616 | ACPI_WALK_STATE *WalkState) |
617 | { |
618 | ACPI_STATUS Status; |
619 | ACPI_OPERAND_OBJECT *NewDesc; |
620 | |
621 | |
622 | ACPI_FUNCTION_TRACE (ExStoreDirectToNode); |
623 | |
624 | |
625 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, |
626 | "Storing [%s] (%p) directly into node [%s] (%p)" |
627 | " with no implicit conversion\n" , |
628 | AcpiUtGetObjectTypeName (SourceDesc), SourceDesc, |
629 | AcpiUtGetTypeName (Node->Type), Node)); |
630 | |
631 | /* Copy the source object to a new object */ |
632 | |
633 | Status = AcpiUtCopyIobjectToIobject (SourceDesc, &NewDesc, WalkState); |
634 | if (ACPI_FAILURE (Status)) |
635 | { |
636 | return_ACPI_STATUS (Status); |
637 | } |
638 | |
639 | /* Attach the new object to the node */ |
640 | |
641 | Status = AcpiNsAttachObject (Node, NewDesc, NewDesc->Common.Type); |
642 | AcpiUtRemoveReference (NewDesc); |
643 | return_ACPI_STATUS (Status); |
644 | } |
645 | |