1 | /****************************************************************************** |
2 | * |
3 | * Module Name: exconvrt - Object conversion routines |
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 "acinterp.h" |
47 | #include "amlcode.h" |
48 | |
49 | |
50 | #define _COMPONENT ACPI_EXECUTER |
51 | ACPI_MODULE_NAME ("exconvrt" ) |
52 | |
53 | /* Local prototypes */ |
54 | |
55 | static UINT32 |
56 | AcpiExConvertToAscii ( |
57 | UINT64 Integer, |
58 | UINT16 Base, |
59 | UINT8 *String, |
60 | UINT8 MaxLength); |
61 | |
62 | |
63 | /******************************************************************************* |
64 | * |
65 | * FUNCTION: AcpiExConvertToInteger |
66 | * |
67 | * PARAMETERS: ObjDesc - Object to be converted. Must be an |
68 | * Integer, Buffer, or String |
69 | * ResultDesc - Where the new Integer object is returned |
70 | * Flags - Used for string conversion |
71 | * |
72 | * RETURN: Status |
73 | * |
74 | * DESCRIPTION: Convert an ACPI Object to an integer. |
75 | * |
76 | ******************************************************************************/ |
77 | |
78 | ACPI_STATUS |
79 | AcpiExConvertToInteger ( |
80 | ACPI_OPERAND_OBJECT *ObjDesc, |
81 | ACPI_OPERAND_OBJECT **ResultDesc, |
82 | UINT32 Flags) |
83 | { |
84 | ACPI_OPERAND_OBJECT *ReturnDesc; |
85 | UINT8 *Pointer; |
86 | UINT64 Result; |
87 | UINT32 i; |
88 | UINT32 Count; |
89 | ACPI_STATUS Status; |
90 | |
91 | |
92 | ACPI_FUNCTION_TRACE_PTR (ExConvertToInteger, ObjDesc); |
93 | |
94 | |
95 | switch (ObjDesc->Common.Type) |
96 | { |
97 | case ACPI_TYPE_INTEGER: |
98 | |
99 | /* No conversion necessary */ |
100 | |
101 | *ResultDesc = ObjDesc; |
102 | return_ACPI_STATUS (AE_OK); |
103 | |
104 | case ACPI_TYPE_BUFFER: |
105 | case ACPI_TYPE_STRING: |
106 | |
107 | /* Note: Takes advantage of common buffer/string fields */ |
108 | |
109 | Pointer = ObjDesc->Buffer.Pointer; |
110 | Count = ObjDesc->Buffer.Length; |
111 | break; |
112 | |
113 | default: |
114 | |
115 | return_ACPI_STATUS (AE_TYPE); |
116 | } |
117 | |
118 | /* |
119 | * Convert the buffer/string to an integer. Note that both buffers and |
120 | * strings are treated as raw data - we don't convert ascii to hex for |
121 | * strings. |
122 | * |
123 | * There are two terminating conditions for the loop: |
124 | * 1) The size of an integer has been reached, or |
125 | * 2) The end of the buffer or string has been reached |
126 | */ |
127 | Result = 0; |
128 | |
129 | /* String conversion is different than Buffer conversion */ |
130 | |
131 | switch (ObjDesc->Common.Type) |
132 | { |
133 | case ACPI_TYPE_STRING: |
134 | /* |
135 | * Convert string to an integer - for most cases, the string must be |
136 | * hexadecimal as per the ACPI specification. The only exception (as |
137 | * of ACPI 3.0) is that the ToInteger() operator allows both decimal |
138 | * and hexadecimal strings (hex prefixed with "0x"). |
139 | */ |
140 | Status = AcpiUtStrtoul64 (ACPI_CAST_PTR (char, Pointer), |
141 | (AcpiGbl_IntegerByteWidth | Flags), &Result); |
142 | if (ACPI_FAILURE (Status)) |
143 | { |
144 | return_ACPI_STATUS (Status); |
145 | } |
146 | break; |
147 | |
148 | case ACPI_TYPE_BUFFER: |
149 | |
150 | /* Check for zero-length buffer */ |
151 | |
152 | if (!Count) |
153 | { |
154 | return_ACPI_STATUS (AE_AML_BUFFER_LIMIT); |
155 | } |
156 | |
157 | /* Transfer no more than an integer's worth of data */ |
158 | |
159 | if (Count > AcpiGbl_IntegerByteWidth) |
160 | { |
161 | Count = AcpiGbl_IntegerByteWidth; |
162 | } |
163 | |
164 | /* |
165 | * Convert buffer to an integer - we simply grab enough raw data |
166 | * from the buffer to fill an integer |
167 | */ |
168 | for (i = 0; i < Count; i++) |
169 | { |
170 | /* |
171 | * Get next byte and shift it into the Result. |
172 | * Little endian is used, meaning that the first byte of the buffer |
173 | * is the LSB of the integer |
174 | */ |
175 | Result |= (((UINT64) Pointer[i]) << (i * 8)); |
176 | } |
177 | break; |
178 | |
179 | default: |
180 | |
181 | /* No other types can get here */ |
182 | |
183 | break; |
184 | } |
185 | |
186 | /* Create a new integer */ |
187 | |
188 | ReturnDesc = AcpiUtCreateIntegerObject (Result); |
189 | if (!ReturnDesc) |
190 | { |
191 | return_ACPI_STATUS (AE_NO_MEMORY); |
192 | } |
193 | |
194 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n" , |
195 | ACPI_FORMAT_UINT64 (Result))); |
196 | |
197 | /* Save the Result */ |
198 | |
199 | (void) AcpiExTruncateFor32bitTable (ReturnDesc); |
200 | *ResultDesc = ReturnDesc; |
201 | return_ACPI_STATUS (AE_OK); |
202 | } |
203 | |
204 | |
205 | /******************************************************************************* |
206 | * |
207 | * FUNCTION: AcpiExConvertToBuffer |
208 | * |
209 | * PARAMETERS: ObjDesc - Object to be converted. Must be an |
210 | * Integer, Buffer, or String |
211 | * ResultDesc - Where the new buffer object is returned |
212 | * |
213 | * RETURN: Status |
214 | * |
215 | * DESCRIPTION: Convert an ACPI Object to a Buffer |
216 | * |
217 | ******************************************************************************/ |
218 | |
219 | ACPI_STATUS |
220 | AcpiExConvertToBuffer ( |
221 | ACPI_OPERAND_OBJECT *ObjDesc, |
222 | ACPI_OPERAND_OBJECT **ResultDesc) |
223 | { |
224 | ACPI_OPERAND_OBJECT *ReturnDesc; |
225 | UINT8 *NewBuf; |
226 | |
227 | |
228 | ACPI_FUNCTION_TRACE_PTR (ExConvertToBuffer, ObjDesc); |
229 | |
230 | |
231 | switch (ObjDesc->Common.Type) |
232 | { |
233 | case ACPI_TYPE_BUFFER: |
234 | |
235 | /* No conversion necessary */ |
236 | |
237 | *ResultDesc = ObjDesc; |
238 | return_ACPI_STATUS (AE_OK); |
239 | |
240 | |
241 | case ACPI_TYPE_INTEGER: |
242 | /* |
243 | * Create a new Buffer object. |
244 | * Need enough space for one integer |
245 | */ |
246 | ReturnDesc = AcpiUtCreateBufferObject (AcpiGbl_IntegerByteWidth); |
247 | if (!ReturnDesc) |
248 | { |
249 | return_ACPI_STATUS (AE_NO_MEMORY); |
250 | } |
251 | |
252 | /* Copy the integer to the buffer, LSB first */ |
253 | |
254 | NewBuf = ReturnDesc->Buffer.Pointer; |
255 | memcpy (NewBuf, &ObjDesc->Integer.Value, AcpiGbl_IntegerByteWidth); |
256 | break; |
257 | |
258 | case ACPI_TYPE_STRING: |
259 | /* |
260 | * Create a new Buffer object |
261 | * Size will be the string length |
262 | * |
263 | * NOTE: Add one to the string length to include the null terminator. |
264 | * The ACPI spec is unclear on this subject, but there is existing |
265 | * ASL/AML code that depends on the null being transferred to the new |
266 | * buffer. |
267 | */ |
268 | ReturnDesc = AcpiUtCreateBufferObject ((ACPI_SIZE) |
269 | ObjDesc->String.Length + 1); |
270 | if (!ReturnDesc) |
271 | { |
272 | return_ACPI_STATUS (AE_NO_MEMORY); |
273 | } |
274 | |
275 | /* Copy the string to the buffer */ |
276 | |
277 | NewBuf = ReturnDesc->Buffer.Pointer; |
278 | strncpy ((char *) NewBuf, (char *) ObjDesc->String.Pointer, |
279 | ObjDesc->String.Length); |
280 | break; |
281 | |
282 | default: |
283 | |
284 | return_ACPI_STATUS (AE_TYPE); |
285 | } |
286 | |
287 | /* Mark buffer initialized */ |
288 | |
289 | ReturnDesc->Common.Flags |= AOPOBJ_DATA_VALID; |
290 | *ResultDesc = ReturnDesc; |
291 | return_ACPI_STATUS (AE_OK); |
292 | } |
293 | |
294 | |
295 | /******************************************************************************* |
296 | * |
297 | * FUNCTION: AcpiExConvertToAscii |
298 | * |
299 | * PARAMETERS: Integer - Value to be converted |
300 | * Base - ACPI_STRING_DECIMAL or ACPI_STRING_HEX |
301 | * String - Where the string is returned |
302 | * DataWidth - Size of data item to be converted, in bytes |
303 | * |
304 | * RETURN: Actual string length |
305 | * |
306 | * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string |
307 | * |
308 | ******************************************************************************/ |
309 | |
310 | static UINT32 |
311 | AcpiExConvertToAscii ( |
312 | UINT64 Integer, |
313 | UINT16 Base, |
314 | UINT8 *String, |
315 | UINT8 DataWidth) |
316 | { |
317 | UINT64 Digit; |
318 | UINT32 i; |
319 | UINT32 j; |
320 | UINT32 k = 0; |
321 | UINT32 HexLength; |
322 | UINT32 DecimalLength; |
323 | UINT32 Remainder; |
324 | BOOLEAN SupressZeros; |
325 | |
326 | |
327 | ACPI_FUNCTION_ENTRY (); |
328 | |
329 | |
330 | switch (Base) |
331 | { |
332 | case 10: |
333 | |
334 | /* Setup max length for the decimal number */ |
335 | |
336 | switch (DataWidth) |
337 | { |
338 | case 1: |
339 | |
340 | DecimalLength = ACPI_MAX8_DECIMAL_DIGITS; |
341 | break; |
342 | |
343 | case 4: |
344 | |
345 | DecimalLength = ACPI_MAX32_DECIMAL_DIGITS; |
346 | break; |
347 | |
348 | case 8: |
349 | default: |
350 | |
351 | DecimalLength = ACPI_MAX64_DECIMAL_DIGITS; |
352 | break; |
353 | } |
354 | |
355 | SupressZeros = TRUE; /* No leading zeros */ |
356 | Remainder = 0; |
357 | |
358 | for (i = DecimalLength; i > 0; i--) |
359 | { |
360 | /* Divide by nth factor of 10 */ |
361 | |
362 | Digit = Integer; |
363 | for (j = 0; j < i; j++) |
364 | { |
365 | (void) AcpiUtShortDivide (Digit, 10, &Digit, &Remainder); |
366 | } |
367 | |
368 | /* Handle leading zeros */ |
369 | |
370 | if (Remainder != 0) |
371 | { |
372 | SupressZeros = FALSE; |
373 | } |
374 | |
375 | if (!SupressZeros) |
376 | { |
377 | String[k] = (UINT8) (ACPI_ASCII_ZERO + Remainder); |
378 | k++; |
379 | } |
380 | } |
381 | break; |
382 | |
383 | case 16: |
384 | |
385 | /* HexLength: 2 ascii hex chars per data byte */ |
386 | |
387 | HexLength = ACPI_MUL_2 (DataWidth); |
388 | for (i = 0, j = (HexLength-1); i < HexLength; i++, j--) |
389 | { |
390 | /* Get one hex digit, most significant digits first */ |
391 | |
392 | String[k] = (UINT8) |
393 | AcpiUtHexToAsciiChar (Integer, ACPI_MUL_4 (j)); |
394 | k++; |
395 | } |
396 | break; |
397 | |
398 | default: |
399 | return (0); |
400 | } |
401 | |
402 | /* |
403 | * Since leading zeros are suppressed, we must check for the case where |
404 | * the integer equals 0 |
405 | * |
406 | * Finally, null terminate the string and return the length |
407 | */ |
408 | if (!k) |
409 | { |
410 | String [0] = ACPI_ASCII_ZERO; |
411 | k = 1; |
412 | } |
413 | |
414 | String [k] = 0; |
415 | return ((UINT32) k); |
416 | } |
417 | |
418 | |
419 | /******************************************************************************* |
420 | * |
421 | * FUNCTION: AcpiExConvertToString |
422 | * |
423 | * PARAMETERS: ObjDesc - Object to be converted. Must be an |
424 | * Integer, Buffer, or String |
425 | * ResultDesc - Where the string object is returned |
426 | * Type - String flags (base and conversion type) |
427 | * |
428 | * RETURN: Status |
429 | * |
430 | * DESCRIPTION: Convert an ACPI Object to a string |
431 | * |
432 | ******************************************************************************/ |
433 | |
434 | ACPI_STATUS |
435 | AcpiExConvertToString ( |
436 | ACPI_OPERAND_OBJECT *ObjDesc, |
437 | ACPI_OPERAND_OBJECT **ResultDesc, |
438 | UINT32 Type) |
439 | { |
440 | ACPI_OPERAND_OBJECT *ReturnDesc; |
441 | UINT8 *NewBuf; |
442 | UINT32 i; |
443 | UINT32 StringLength = 0; |
444 | UINT16 Base = 16; |
445 | UINT8 Separator = ','; |
446 | |
447 | |
448 | ACPI_FUNCTION_TRACE_PTR (ExConvertToString, ObjDesc); |
449 | |
450 | |
451 | switch (ObjDesc->Common.Type) |
452 | { |
453 | case ACPI_TYPE_STRING: |
454 | |
455 | /* No conversion necessary */ |
456 | |
457 | *ResultDesc = ObjDesc; |
458 | return_ACPI_STATUS (AE_OK); |
459 | |
460 | case ACPI_TYPE_INTEGER: |
461 | |
462 | switch (Type) |
463 | { |
464 | case ACPI_EXPLICIT_CONVERT_DECIMAL: |
465 | |
466 | /* Make room for maximum decimal number */ |
467 | |
468 | StringLength = ACPI_MAX_DECIMAL_DIGITS; |
469 | Base = 10; |
470 | break; |
471 | |
472 | default: |
473 | |
474 | /* Two hex string characters for each integer byte */ |
475 | |
476 | StringLength = ACPI_MUL_2 (AcpiGbl_IntegerByteWidth); |
477 | break; |
478 | } |
479 | |
480 | /* |
481 | * Create a new String |
482 | * Need enough space for one ASCII integer (plus null terminator) |
483 | */ |
484 | ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength); |
485 | if (!ReturnDesc) |
486 | { |
487 | return_ACPI_STATUS (AE_NO_MEMORY); |
488 | } |
489 | |
490 | NewBuf = ReturnDesc->Buffer.Pointer; |
491 | |
492 | /* Convert integer to string */ |
493 | |
494 | StringLength = AcpiExConvertToAscii ( |
495 | ObjDesc->Integer.Value, Base, NewBuf, AcpiGbl_IntegerByteWidth); |
496 | |
497 | /* Null terminate at the correct place */ |
498 | |
499 | ReturnDesc->String.Length = StringLength; |
500 | NewBuf [StringLength] = 0; |
501 | break; |
502 | |
503 | case ACPI_TYPE_BUFFER: |
504 | |
505 | /* Setup string length, base, and separator */ |
506 | |
507 | switch (Type) |
508 | { |
509 | case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by ToDecimalString */ |
510 | /* |
511 | * From ACPI: "If Data is a buffer, it is converted to a string of |
512 | * decimal values separated by commas." |
513 | */ |
514 | Base = 10; |
515 | |
516 | /* |
517 | * Calculate the final string length. Individual string values |
518 | * are variable length (include separator for each) |
519 | */ |
520 | for (i = 0; i < ObjDesc->Buffer.Length; i++) |
521 | { |
522 | if (ObjDesc->Buffer.Pointer[i] >= 100) |
523 | { |
524 | StringLength += 4; |
525 | } |
526 | else if (ObjDesc->Buffer.Pointer[i] >= 10) |
527 | { |
528 | StringLength += 3; |
529 | } |
530 | else |
531 | { |
532 | StringLength += 2; |
533 | } |
534 | } |
535 | break; |
536 | |
537 | case ACPI_IMPLICIT_CONVERT_HEX: |
538 | /* |
539 | * From the ACPI spec: |
540 | *"The entire contents of the buffer are converted to a string of |
541 | * two-character hexadecimal numbers, each separated by a space." |
542 | */ |
543 | Separator = ' '; |
544 | StringLength = (ObjDesc->Buffer.Length * 3); |
545 | break; |
546 | |
547 | case ACPI_EXPLICIT_CONVERT_HEX: /* Used by ToHexString */ |
548 | /* |
549 | * From ACPI: "If Data is a buffer, it is converted to a string of |
550 | * hexadecimal values separated by commas." |
551 | */ |
552 | StringLength = (ObjDesc->Buffer.Length * 3); |
553 | break; |
554 | |
555 | default: |
556 | return_ACPI_STATUS (AE_BAD_PARAMETER); |
557 | } |
558 | |
559 | /* |
560 | * Create a new string object and string buffer |
561 | * (-1 because of extra separator included in StringLength from above) |
562 | * Allow creation of zero-length strings from zero-length buffers. |
563 | */ |
564 | if (StringLength) |
565 | { |
566 | StringLength--; |
567 | } |
568 | |
569 | ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength); |
570 | if (!ReturnDesc) |
571 | { |
572 | return_ACPI_STATUS (AE_NO_MEMORY); |
573 | } |
574 | |
575 | NewBuf = ReturnDesc->Buffer.Pointer; |
576 | |
577 | /* |
578 | * Convert buffer bytes to hex or decimal values |
579 | * (separated by commas or spaces) |
580 | */ |
581 | for (i = 0; i < ObjDesc->Buffer.Length; i++) |
582 | { |
583 | NewBuf += AcpiExConvertToAscii ( |
584 | (UINT64) ObjDesc->Buffer.Pointer[i], Base, NewBuf, 1); |
585 | *NewBuf++ = Separator; /* each separated by a comma or space */ |
586 | } |
587 | |
588 | /* |
589 | * Null terminate the string |
590 | * (overwrites final comma/space from above) |
591 | */ |
592 | if (ObjDesc->Buffer.Length) |
593 | { |
594 | NewBuf--; |
595 | } |
596 | *NewBuf = 0; |
597 | break; |
598 | |
599 | default: |
600 | |
601 | return_ACPI_STATUS (AE_TYPE); |
602 | } |
603 | |
604 | *ResultDesc = ReturnDesc; |
605 | return_ACPI_STATUS (AE_OK); |
606 | } |
607 | |
608 | |
609 | /******************************************************************************* |
610 | * |
611 | * FUNCTION: AcpiExConvertToTargetType |
612 | * |
613 | * PARAMETERS: DestinationType - Current type of the destination |
614 | * SourceDesc - Source object to be converted. |
615 | * ResultDesc - Where the converted object is returned |
616 | * WalkState - Current method state |
617 | * |
618 | * RETURN: Status |
619 | * |
620 | * DESCRIPTION: Implements "implicit conversion" rules for storing an object. |
621 | * |
622 | ******************************************************************************/ |
623 | |
624 | ACPI_STATUS |
625 | AcpiExConvertToTargetType ( |
626 | ACPI_OBJECT_TYPE DestinationType, |
627 | ACPI_OPERAND_OBJECT *SourceDesc, |
628 | ACPI_OPERAND_OBJECT **ResultDesc, |
629 | ACPI_WALK_STATE *WalkState) |
630 | { |
631 | ACPI_STATUS Status = AE_OK; |
632 | |
633 | |
634 | ACPI_FUNCTION_TRACE (ExConvertToTargetType); |
635 | |
636 | |
637 | /* Default behavior */ |
638 | |
639 | *ResultDesc = SourceDesc; |
640 | |
641 | /* |
642 | * If required by the target, |
643 | * perform implicit conversion on the source before we store it. |
644 | */ |
645 | switch (GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs)) |
646 | { |
647 | case ARGI_SIMPLE_TARGET: |
648 | case ARGI_FIXED_TARGET: |
649 | case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */ |
650 | |
651 | switch (DestinationType) |
652 | { |
653 | case ACPI_TYPE_LOCAL_REGION_FIELD: |
654 | /* |
655 | * Named field can always handle conversions |
656 | */ |
657 | break; |
658 | |
659 | default: |
660 | |
661 | /* No conversion allowed for these types */ |
662 | |
663 | if (DestinationType != SourceDesc->Common.Type) |
664 | { |
665 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, |
666 | "Explicit operator, will store (%s) over existing type (%s)\n" , |
667 | AcpiUtGetObjectTypeName (SourceDesc), |
668 | AcpiUtGetTypeName (DestinationType))); |
669 | Status = AE_TYPE; |
670 | } |
671 | } |
672 | break; |
673 | |
674 | case ARGI_TARGETREF: |
675 | case ARGI_STORE_TARGET: |
676 | |
677 | switch (DestinationType) |
678 | { |
679 | case ACPI_TYPE_INTEGER: |
680 | case ACPI_TYPE_BUFFER_FIELD: |
681 | case ACPI_TYPE_LOCAL_BANK_FIELD: |
682 | case ACPI_TYPE_LOCAL_INDEX_FIELD: |
683 | /* |
684 | * These types require an Integer operand. We can convert |
685 | * a Buffer or a String to an Integer if necessary. |
686 | */ |
687 | Status = AcpiExConvertToInteger (SourceDesc, ResultDesc, |
688 | ACPI_STRTOUL_BASE16); |
689 | break; |
690 | |
691 | case ACPI_TYPE_STRING: |
692 | /* |
693 | * The operand must be a String. We can convert an |
694 | * Integer or Buffer if necessary |
695 | */ |
696 | Status = AcpiExConvertToString (SourceDesc, ResultDesc, |
697 | ACPI_IMPLICIT_CONVERT_HEX); |
698 | break; |
699 | |
700 | case ACPI_TYPE_BUFFER: |
701 | /* |
702 | * The operand must be a Buffer. We can convert an |
703 | * Integer or String if necessary |
704 | */ |
705 | Status = AcpiExConvertToBuffer (SourceDesc, ResultDesc); |
706 | break; |
707 | |
708 | default: |
709 | |
710 | ACPI_ERROR ((AE_INFO, |
711 | "Bad destination type during conversion: 0x%X" , |
712 | DestinationType)); |
713 | Status = AE_AML_INTERNAL; |
714 | break; |
715 | } |
716 | break; |
717 | |
718 | case ARGI_REFERENCE: |
719 | /* |
720 | * CreateXxxxField cases - we are storing the field object into the name |
721 | */ |
722 | break; |
723 | |
724 | default: |
725 | |
726 | ACPI_ERROR ((AE_INFO, |
727 | "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s" , |
728 | GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs), |
729 | WalkState->Opcode, AcpiUtGetTypeName (DestinationType))); |
730 | Status = AE_AML_INTERNAL; |
731 | } |
732 | |
733 | /* |
734 | * Source-to-Target conversion semantics: |
735 | * |
736 | * If conversion to the target type cannot be performed, then simply |
737 | * overwrite the target with the new object and type. |
738 | */ |
739 | if (Status == AE_TYPE) |
740 | { |
741 | Status = AE_OK; |
742 | } |
743 | |
744 | return_ACPI_STATUS (Status); |
745 | } |
746 | |