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