![]() |
|
|||
File indexing completed on 2025-05-11 08:24:02
0001 /****************************************************************************** 0002 * 0003 * Module Name: exconvrt - Object conversion routines 0004 * 0005 *****************************************************************************/ 0006 0007 /****************************************************************************** 0008 * 0009 * 1. Copyright Notice 0010 * 0011 * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp. 0012 * All rights reserved. 0013 * 0014 * 2. License 0015 * 0016 * 2.1. This is your license from Intel Corp. under its intellectual property 0017 * rights. You may have additional license terms from the party that provided 0018 * you this software, covering your right to use that party's intellectual 0019 * property rights. 0020 * 0021 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 0022 * copy of the source code appearing in this file ("Covered Code") an 0023 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 0024 * base code distributed originally by Intel ("Original Intel Code") to copy, 0025 * make derivatives, distribute, use and display any portion of the Covered 0026 * Code in any form, with the right to sublicense such rights; and 0027 * 0028 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 0029 * license (with the right to sublicense), under only those claims of Intel 0030 * patents that are infringed by the Original Intel Code, to make, use, sell, 0031 * offer to sell, and import the Covered Code and derivative works thereof 0032 * solely to the minimum extent necessary to exercise the above copyright 0033 * license, and in no event shall the patent license extend to any additions 0034 * to or modifications of the Original Intel Code. No other license or right 0035 * is granted directly or by implication, estoppel or otherwise; 0036 * 0037 * The above copyright and patent license is granted only if the following 0038 * conditions are met: 0039 * 0040 * 3. Conditions 0041 * 0042 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 0043 * Redistribution of source code of any substantial portion of the Covered 0044 * Code or modification with rights to further distribute source must include 0045 * the above Copyright Notice, the above License, this list of Conditions, 0046 * and the following Disclaimer and Export Compliance provision. In addition, 0047 * Licensee must cause all Covered Code to which Licensee contributes to 0048 * contain a file documenting the changes Licensee made to create that Covered 0049 * Code and the date of any change. Licensee must include in that file the 0050 * documentation of any changes made by any predecessor Licensee. Licensee 0051 * must include a prominent statement that the modification is derived, 0052 * directly or indirectly, from Original Intel Code. 0053 * 0054 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 0055 * Redistribution of source code of any substantial portion of the Covered 0056 * Code or modification without rights to further distribute source must 0057 * include the following Disclaimer and Export Compliance provision in the 0058 * documentation and/or other materials provided with distribution. In 0059 * addition, Licensee may not authorize further sublicense of source of any 0060 * portion of the Covered Code, and must include terms to the effect that the 0061 * license from Licensee to its licensee is limited to the intellectual 0062 * property embodied in the software Licensee provides to its licensee, and 0063 * not to intellectual property embodied in modifications its licensee may 0064 * make. 0065 * 0066 * 3.3. Redistribution of Executable. Redistribution in executable form of any 0067 * substantial portion of the Covered Code or modification must reproduce the 0068 * above Copyright Notice, and the following Disclaimer and Export Compliance 0069 * provision in the documentation and/or other materials provided with the 0070 * distribution. 0071 * 0072 * 3.4. Intel retains all right, title, and interest in and to the Original 0073 * Intel Code. 0074 * 0075 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 0076 * Intel shall be used in advertising or otherwise to promote the sale, use or 0077 * other dealings in products derived from or relating to the Covered Code 0078 * without prior written authorization from Intel. 0079 * 0080 * 4. Disclaimer and Export Compliance 0081 * 0082 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 0083 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 0084 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 0085 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 0086 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 0087 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 0088 * PARTICULAR PURPOSE. 0089 * 0090 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 0091 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 0092 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 0093 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 0094 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 0095 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 0096 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 0097 * LIMITED REMEDY. 0098 * 0099 * 4.3. Licensee shall not export, either directly or indirectly, any of this 0100 * software or system incorporating such software without first obtaining any 0101 * required license or other approval from the U. S. Department of Commerce or 0102 * any other agency or department of the United States Government. In the 0103 * event Licensee exports any such software from the United States or 0104 * re-exports any such software from a foreign destination, Licensee shall 0105 * ensure that the distribution and export/re-export of the software is in 0106 * compliance with all laws, regulations, orders, or other restrictions of the 0107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 0108 * any of its subsidiaries will export/re-export any technical data, process, 0109 * software, or service, directly or indirectly, to any country for which the 0110 * United States government or any agency thereof requires an export license, 0111 * other governmental approval, or letter of assurance, without first obtaining 0112 * such license, approval or letter. 0113 * 0114 ***************************************************************************** 0115 * 0116 * Alternatively, you may choose to be licensed under the terms of the 0117 * following license: 0118 * 0119 * Redistribution and use in source and binary forms, with or without 0120 * modification, are permitted provided that the following conditions 0121 * are met: 0122 * 1. Redistributions of source code must retain the above copyright 0123 * notice, this list of conditions, and the following disclaimer, 0124 * without modification. 0125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 0126 * substantially similar to the "NO WARRANTY" disclaimer below 0127 * ("Disclaimer") and any redistribution must be conditioned upon 0128 * including a substantially similar Disclaimer requirement for further 0129 * binary redistribution. 0130 * 3. Neither the names of the above-listed copyright holders nor the names 0131 * of any contributors may be used to endorse or promote products derived 0132 * from this software without specific prior written permission. 0133 * 0134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 0135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 0136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 0137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 0138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 0139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 0140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0145 * 0146 * Alternatively, you may choose to be licensed under the terms of the 0147 * GNU General Public License ("GPL") version 2 as published by the Free 0148 * Software Foundation. 0149 * 0150 *****************************************************************************/ 0151 0152 #include "acpi.h" 0153 #include "accommon.h" 0154 #include "acinterp.h" 0155 #include "amlcode.h" 0156 0157 0158 #define _COMPONENT ACPI_EXECUTER 0159 ACPI_MODULE_NAME ("exconvrt") 0160 0161 /* Local prototypes */ 0162 0163 static UINT32 0164 AcpiExConvertToAscii ( 0165 UINT64 Integer, 0166 UINT16 Base, 0167 UINT8 *String, 0168 UINT8 MaxLength, 0169 BOOLEAN LeadingZeros); 0170 0171 0172 /******************************************************************************* 0173 * 0174 * FUNCTION: AcpiExConvertToInteger 0175 * 0176 * PARAMETERS: ObjDesc - Object to be converted. Must be an 0177 * Integer, Buffer, or String 0178 * ResultDesc - Where the new Integer object is returned 0179 * ImplicitConversion - Used for string conversion 0180 * 0181 * RETURN: Status 0182 * 0183 * DESCRIPTION: Convert an ACPI Object to an integer. 0184 * 0185 ******************************************************************************/ 0186 0187 ACPI_STATUS 0188 AcpiExConvertToInteger ( 0189 ACPI_OPERAND_OBJECT *ObjDesc, 0190 ACPI_OPERAND_OBJECT **ResultDesc, 0191 UINT32 ImplicitConversion) 0192 { 0193 ACPI_OPERAND_OBJECT *ReturnDesc; 0194 UINT8 *Pointer; 0195 UINT64 Result; 0196 UINT32 i; 0197 UINT32 Count; 0198 0199 0200 ACPI_FUNCTION_TRACE_PTR (ExConvertToInteger, ObjDesc); 0201 0202 0203 switch (ObjDesc->Common.Type) 0204 { 0205 case ACPI_TYPE_INTEGER: 0206 0207 /* No conversion necessary */ 0208 0209 *ResultDesc = ObjDesc; 0210 return_ACPI_STATUS (AE_OK); 0211 0212 case ACPI_TYPE_BUFFER: 0213 case ACPI_TYPE_STRING: 0214 0215 /* Note: Takes advantage of common buffer/string fields */ 0216 0217 Pointer = ObjDesc->Buffer.Pointer; 0218 Count = ObjDesc->Buffer.Length; 0219 break; 0220 0221 default: 0222 0223 return_ACPI_STATUS (AE_TYPE); 0224 } 0225 0226 /* 0227 * Convert the buffer/string to an integer. Note that both buffers and 0228 * strings are treated as raw data - we don't convert ascii to hex for 0229 * strings. 0230 * 0231 * There are two terminating conditions for the loop: 0232 * 1) The size of an integer has been reached, or 0233 * 2) The end of the buffer or string has been reached 0234 */ 0235 Result = 0; 0236 0237 /* String conversion is different than Buffer conversion */ 0238 0239 switch (ObjDesc->Common.Type) 0240 { 0241 case ACPI_TYPE_STRING: 0242 /* 0243 * Convert string to an integer - for most cases, the string must be 0244 * hexadecimal as per the ACPI specification. The only exception (as 0245 * of ACPI 3.0) is that the ToInteger() operator allows both decimal 0246 * and hexadecimal strings (hex prefixed with "0x"). 0247 * 0248 * Explicit conversion is used only by ToInteger. 0249 * All other string-to-integer conversions are implicit conversions. 0250 */ 0251 if (ImplicitConversion) 0252 { 0253 Result = AcpiUtImplicitStrtoul64 (ACPI_CAST_PTR (char, Pointer)); 0254 } 0255 else 0256 { 0257 Result = AcpiUtExplicitStrtoul64 (ACPI_CAST_PTR (char, Pointer)); 0258 } 0259 break; 0260 0261 case ACPI_TYPE_BUFFER: 0262 0263 /* Check for zero-length buffer */ 0264 0265 if (!Count) 0266 { 0267 return_ACPI_STATUS (AE_AML_BUFFER_LIMIT); 0268 } 0269 0270 /* Transfer no more than an integer's worth of data */ 0271 0272 if (Count > AcpiGbl_IntegerByteWidth) 0273 { 0274 Count = AcpiGbl_IntegerByteWidth; 0275 } 0276 0277 /* 0278 * Convert buffer to an integer - we simply grab enough raw data 0279 * from the buffer to fill an integer 0280 */ 0281 for (i = 0; i < Count; i++) 0282 { 0283 /* 0284 * Get next byte and shift it into the Result. 0285 * Little endian is used, meaning that the first byte of the buffer 0286 * is the LSB of the integer 0287 */ 0288 Result |= (((UINT64) Pointer[i]) << (i * 8)); 0289 } 0290 break; 0291 0292 default: 0293 0294 /* No other types can get here */ 0295 0296 break; 0297 } 0298 0299 /* Create a new integer */ 0300 0301 ReturnDesc = AcpiUtCreateIntegerObject (Result); 0302 if (!ReturnDesc) 0303 { 0304 return_ACPI_STATUS (AE_NO_MEMORY); 0305 } 0306 0307 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 0308 ACPI_FORMAT_UINT64 (Result))); 0309 0310 /* Save the Result */ 0311 0312 (void) AcpiExTruncateFor32bitTable (ReturnDesc); 0313 *ResultDesc = ReturnDesc; 0314 return_ACPI_STATUS (AE_OK); 0315 } 0316 0317 0318 /******************************************************************************* 0319 * 0320 * FUNCTION: AcpiExConvertToBuffer 0321 * 0322 * PARAMETERS: ObjDesc - Object to be converted. Must be an 0323 * Integer, Buffer, or String 0324 * ResultDesc - Where the new buffer object is returned 0325 * 0326 * RETURN: Status 0327 * 0328 * DESCRIPTION: Convert an ACPI Object to a Buffer 0329 * 0330 ******************************************************************************/ 0331 0332 ACPI_STATUS 0333 AcpiExConvertToBuffer ( 0334 ACPI_OPERAND_OBJECT *ObjDesc, 0335 ACPI_OPERAND_OBJECT **ResultDesc) 0336 { 0337 ACPI_OPERAND_OBJECT *ReturnDesc; 0338 UINT8 *NewBuf; 0339 0340 0341 ACPI_FUNCTION_TRACE_PTR (ExConvertToBuffer, ObjDesc); 0342 0343 0344 switch (ObjDesc->Common.Type) 0345 { 0346 case ACPI_TYPE_BUFFER: 0347 0348 /* No conversion necessary */ 0349 0350 *ResultDesc = ObjDesc; 0351 return_ACPI_STATUS (AE_OK); 0352 0353 0354 case ACPI_TYPE_INTEGER: 0355 /* 0356 * Create a new Buffer object. 0357 * Need enough space for one integer 0358 */ 0359 ReturnDesc = AcpiUtCreateBufferObject (AcpiGbl_IntegerByteWidth); 0360 if (!ReturnDesc) 0361 { 0362 return_ACPI_STATUS (AE_NO_MEMORY); 0363 } 0364 0365 /* Copy the integer to the buffer, LSB first */ 0366 0367 NewBuf = ReturnDesc->Buffer.Pointer; 0368 memcpy (NewBuf, &ObjDesc->Integer.Value, AcpiGbl_IntegerByteWidth); 0369 break; 0370 0371 case ACPI_TYPE_STRING: 0372 /* 0373 * Create a new Buffer object 0374 * Size will be the string length 0375 * 0376 * NOTE: Add one to the string length to include the null terminator. 0377 * The ACPI spec is unclear on this subject, but there is existing 0378 * ASL/AML code that depends on the null being transferred to the new 0379 * buffer. 0380 */ 0381 ReturnDesc = AcpiUtCreateBufferObject ((ACPI_SIZE) 0382 ObjDesc->String.Length + 1); 0383 if (!ReturnDesc) 0384 { 0385 return_ACPI_STATUS (AE_NO_MEMORY); 0386 } 0387 0388 /* Copy the string to the buffer */ 0389 0390 NewBuf = ReturnDesc->Buffer.Pointer; 0391 strncpy ((char *) NewBuf, (char *) ObjDesc->String.Pointer, 0392 ObjDesc->String.Length); 0393 break; 0394 0395 default: 0396 0397 return_ACPI_STATUS (AE_TYPE); 0398 } 0399 0400 /* Mark buffer initialized */ 0401 0402 ReturnDesc->Common.Flags |= AOPOBJ_DATA_VALID; 0403 *ResultDesc = ReturnDesc; 0404 return_ACPI_STATUS (AE_OK); 0405 } 0406 0407 0408 /******************************************************************************* 0409 * 0410 * FUNCTION: AcpiExConvertToAscii 0411 * 0412 * PARAMETERS: Integer - Value to be converted 0413 * Base - ACPI_STRING_DECIMAL or ACPI_STRING_HEX 0414 * String - Where the string is returned 0415 * DataWidth - Size of data item to be converted, in bytes 0416 * LeadingZeros - Allow leading zeros 0417 * 0418 * RETURN: Actual string length 0419 * 0420 * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string 0421 * 0422 ******************************************************************************/ 0423 0424 static UINT32 0425 AcpiExConvertToAscii ( 0426 UINT64 Integer, 0427 UINT16 Base, 0428 UINT8 *String, 0429 UINT8 DataWidth, 0430 BOOLEAN LeadingZeros) 0431 { 0432 UINT64 Digit; 0433 UINT32 i; 0434 UINT32 j; 0435 UINT32 k = 0; 0436 UINT32 HexLength; 0437 UINT32 DecimalLength; 0438 UINT32 Remainder; 0439 BOOLEAN SupressZeros = !LeadingZeros; 0440 UINT8 HexChar; 0441 0442 0443 ACPI_FUNCTION_ENTRY (); 0444 0445 0446 switch (Base) 0447 { 0448 case 10: 0449 0450 /* Setup max length for the decimal number */ 0451 0452 switch (DataWidth) 0453 { 0454 case 1: 0455 0456 DecimalLength = ACPI_MAX8_DECIMAL_DIGITS; 0457 break; 0458 0459 case 4: 0460 0461 DecimalLength = ACPI_MAX32_DECIMAL_DIGITS; 0462 break; 0463 0464 case 8: 0465 default: 0466 0467 DecimalLength = ACPI_MAX64_DECIMAL_DIGITS; 0468 break; 0469 } 0470 0471 Remainder = 0; 0472 0473 for (i = DecimalLength; i > 0; i--) 0474 { 0475 /* Divide by nth factor of 10 */ 0476 0477 Digit = Integer; 0478 for (j = 0; j < i; j++) 0479 { 0480 (void) AcpiUtShortDivide (Digit, 10, &Digit, &Remainder); 0481 } 0482 0483 /* Handle leading zeros */ 0484 0485 if (Remainder != 0) 0486 { 0487 SupressZeros = FALSE; 0488 } 0489 0490 if (!SupressZeros) 0491 { 0492 String[k] = (UINT8) (ACPI_ASCII_ZERO + Remainder); 0493 k++; 0494 } 0495 } 0496 break; 0497 0498 case 16: 0499 0500 /* HexLength: 2 ascii hex chars per data byte */ 0501 0502 HexLength = (DataWidth * 2); 0503 for (i = 0, j = (HexLength-1); i < HexLength; i++, j--) 0504 { 0505 /* Get one hex digit, most significant digits first */ 0506 0507 HexChar = (UINT8) 0508 AcpiUtHexToAsciiChar (Integer, ACPI_MUL_4 (j)); 0509 0510 /* Supress leading zeros until the first non-zero character */ 0511 0512 if (HexChar == ACPI_ASCII_ZERO && SupressZeros) 0513 { 0514 continue; 0515 } 0516 0517 SupressZeros = FALSE; 0518 String[k] = HexChar; 0519 k++; 0520 } 0521 break; 0522 0523 default: 0524 return (0); 0525 } 0526 0527 /* 0528 * Since leading zeros are suppressed, we must check for the case where 0529 * the integer equals 0 0530 * 0531 * Finally, null terminate the string and return the length 0532 */ 0533 if (!k) 0534 { 0535 String [0] = ACPI_ASCII_ZERO; 0536 k = 1; 0537 } 0538 0539 String [k] = 0; 0540 return ((UINT32) k); 0541 } 0542 0543 0544 /******************************************************************************* 0545 * 0546 * FUNCTION: AcpiExConvertToString 0547 * 0548 * PARAMETERS: ObjDesc - Object to be converted. Must be an 0549 * Integer, Buffer, or String 0550 * ResultDesc - Where the string object is returned 0551 * Type - String flags (base and conversion type) 0552 * 0553 * RETURN: Status 0554 * 0555 * DESCRIPTION: Convert an ACPI Object to a string. Supports both implicit 0556 * and explicit conversions and related rules. 0557 * 0558 ******************************************************************************/ 0559 0560 ACPI_STATUS 0561 AcpiExConvertToString ( 0562 ACPI_OPERAND_OBJECT *ObjDesc, 0563 ACPI_OPERAND_OBJECT **ResultDesc, 0564 UINT32 Type) 0565 { 0566 ACPI_OPERAND_OBJECT *ReturnDesc; 0567 UINT8 *NewBuf; 0568 UINT32 i; 0569 UINT32 StringLength = 0; 0570 UINT16 Base = 16; 0571 UINT8 Separator = ','; 0572 BOOLEAN LeadingZeros; 0573 0574 0575 ACPI_FUNCTION_TRACE_PTR (ExConvertToString, ObjDesc); 0576 0577 0578 switch (ObjDesc->Common.Type) 0579 { 0580 case ACPI_TYPE_STRING: 0581 0582 /* No conversion necessary */ 0583 0584 *ResultDesc = ObjDesc; 0585 return_ACPI_STATUS (AE_OK); 0586 0587 case ACPI_TYPE_INTEGER: 0588 0589 switch (Type) 0590 { 0591 case ACPI_EXPLICIT_CONVERT_DECIMAL: 0592 /* 0593 * From ToDecimalString, integer source. 0594 * 0595 * Make room for the maximum decimal number size 0596 */ 0597 StringLength = ACPI_MAX_DECIMAL_DIGITS; 0598 LeadingZeros = FALSE; 0599 Base = 10; 0600 break; 0601 0602 case ACPI_EXPLICIT_CONVERT_HEX: 0603 /* 0604 * From ToHexString. 0605 * 0606 * Supress leading zeros and append "0x" 0607 */ 0608 StringLength = ACPI_MUL_2 (AcpiGbl_IntegerByteWidth) + 2; 0609 LeadingZeros = FALSE; 0610 break; 0611 default: 0612 0613 /* Two hex string characters for each integer byte */ 0614 0615 StringLength = ACPI_MUL_2 (AcpiGbl_IntegerByteWidth); 0616 LeadingZeros = TRUE; 0617 break; 0618 } 0619 0620 /* 0621 * Create a new String 0622 * Need enough space for one ASCII integer (plus null terminator) 0623 */ 0624 ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength); 0625 if (!ReturnDesc) 0626 { 0627 return_ACPI_STATUS (AE_NO_MEMORY); 0628 } 0629 0630 NewBuf = ReturnDesc->Buffer.Pointer; 0631 if (Type == ACPI_EXPLICIT_CONVERT_HEX) 0632 { 0633 /* Append "0x" prefix for explicit hex conversion */ 0634 0635 *NewBuf++ = '0'; 0636 *NewBuf++ = 'x'; 0637 } 0638 0639 /* Convert integer to string */ 0640 0641 StringLength = AcpiExConvertToAscii ( 0642 ObjDesc->Integer.Value, Base, NewBuf, AcpiGbl_IntegerByteWidth, LeadingZeros); 0643 0644 /* Null terminate at the correct place */ 0645 0646 ReturnDesc->String.Length = StringLength; 0647 if (Type == ACPI_EXPLICIT_CONVERT_HEX) 0648 { 0649 /* Take "0x" prefix into account */ 0650 0651 ReturnDesc->String.Length += 2; 0652 } 0653 0654 NewBuf [StringLength] = 0; 0655 break; 0656 0657 case ACPI_TYPE_BUFFER: 0658 0659 /* Setup string length, base, and separator */ 0660 0661 switch (Type) 0662 { 0663 case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by ToDecimalString */ 0664 /* 0665 * Explicit conversion from the ToDecimalString ASL operator. 0666 * 0667 * From ACPI: "If the input is a buffer, it is converted to a 0668 * a string of decimal values separated by commas." 0669 */ 0670 LeadingZeros = FALSE; 0671 Base = 10; 0672 0673 /* 0674 * Calculate the final string length. Individual string values 0675 * are variable length (include separator for each) 0676 */ 0677 for (i = 0; i < ObjDesc->Buffer.Length; i++) 0678 { 0679 if (ObjDesc->Buffer.Pointer[i] >= 100) 0680 { 0681 StringLength += 4; 0682 } 0683 else if (ObjDesc->Buffer.Pointer[i] >= 10) 0684 { 0685 StringLength += 3; 0686 } 0687 else 0688 { 0689 StringLength += 2; 0690 } 0691 } 0692 break; 0693 0694 case ACPI_IMPLICIT_CONVERT_HEX: 0695 /* 0696 * Implicit buffer-to-string conversion 0697 * 0698 * From the ACPI spec: 0699 * "The entire contents of the buffer are converted to a string of 0700 * two-character hexadecimal numbers, each separated by a space." 0701 * 0702 * Each hex number is prefixed with 0x (11/2018) 0703 */ 0704 LeadingZeros = TRUE; 0705 Separator = ' '; 0706 StringLength = (ObjDesc->Buffer.Length * 5); 0707 break; 0708 0709 case ACPI_EXPLICIT_CONVERT_HEX: 0710 /* 0711 * Explicit conversion from the ToHexString ASL operator. 0712 * 0713 * From ACPI: "If Data is a buffer, it is converted to a string of 0714 * hexadecimal values separated by commas." 0715 * 0716 * Each hex number is prefixed with 0x (11/2018) 0717 */ 0718 LeadingZeros = TRUE; 0719 Separator = ','; 0720 StringLength = (ObjDesc->Buffer.Length * 5); 0721 break; 0722 0723 default: 0724 return_ACPI_STATUS (AE_BAD_PARAMETER); 0725 } 0726 0727 /* 0728 * Create a new string object and string buffer 0729 * (-1 because of extra separator included in StringLength from above) 0730 * Allow creation of zero-length strings from zero-length buffers. 0731 */ 0732 if (StringLength) 0733 { 0734 StringLength--; 0735 } 0736 0737 ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength); 0738 if (!ReturnDesc) 0739 { 0740 return_ACPI_STATUS (AE_NO_MEMORY); 0741 } 0742 0743 NewBuf = ReturnDesc->Buffer.Pointer; 0744 0745 /* 0746 * Convert buffer bytes to hex or decimal values 0747 * (separated by commas or spaces) 0748 */ 0749 for (i = 0; i < ObjDesc->Buffer.Length; i++) 0750 { 0751 if (Base == 16) 0752 { 0753 /* Emit 0x prefix for explicit/implicit hex conversion */ 0754 0755 *NewBuf++ = '0'; 0756 *NewBuf++ = 'x'; 0757 } 0758 0759 NewBuf += AcpiExConvertToAscii ( 0760 (UINT64) ObjDesc->Buffer.Pointer[i], Base, NewBuf, 1, LeadingZeros); 0761 0762 /* Each digit is separated by either a comma or space */ 0763 0764 *NewBuf++ = Separator; 0765 } 0766 0767 /* 0768 * Null terminate the string 0769 * (overwrites final comma/space from above) 0770 */ 0771 if (ObjDesc->Buffer.Length) 0772 { 0773 NewBuf--; 0774 } 0775 *NewBuf = 0; 0776 break; 0777 0778 default: 0779 0780 return_ACPI_STATUS (AE_TYPE); 0781 } 0782 0783 *ResultDesc = ReturnDesc; 0784 return_ACPI_STATUS (AE_OK); 0785 } 0786 0787 0788 /******************************************************************************* 0789 * 0790 * FUNCTION: AcpiExConvertToTargetType 0791 * 0792 * PARAMETERS: DestinationType - Current type of the destination 0793 * SourceDesc - Source object to be converted. 0794 * ResultDesc - Where the converted object is returned 0795 * WalkState - Current method state 0796 * 0797 * RETURN: Status 0798 * 0799 * DESCRIPTION: Implements "implicit conversion" rules for storing an object. 0800 * 0801 ******************************************************************************/ 0802 0803 ACPI_STATUS 0804 AcpiExConvertToTargetType ( 0805 ACPI_OBJECT_TYPE DestinationType, 0806 ACPI_OPERAND_OBJECT *SourceDesc, 0807 ACPI_OPERAND_OBJECT **ResultDesc, 0808 ACPI_WALK_STATE *WalkState) 0809 { 0810 ACPI_STATUS Status = AE_OK; 0811 0812 0813 ACPI_FUNCTION_TRACE (ExConvertToTargetType); 0814 0815 0816 /* Default behavior */ 0817 0818 *ResultDesc = SourceDesc; 0819 0820 /* 0821 * If required by the target, 0822 * perform implicit conversion on the source before we store it. 0823 */ 0824 switch (GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs)) 0825 { 0826 case ARGI_SIMPLE_TARGET: 0827 case ARGI_FIXED_TARGET: 0828 case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */ 0829 0830 switch (DestinationType) 0831 { 0832 case ACPI_TYPE_LOCAL_REGION_FIELD: 0833 /* 0834 * Named field can always handle conversions 0835 */ 0836 break; 0837 0838 default: 0839 0840 /* No conversion allowed for these types */ 0841 0842 if (DestinationType != SourceDesc->Common.Type) 0843 { 0844 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 0845 "Explicit operator, will store (%s) over existing type (%s)\n", 0846 AcpiUtGetObjectTypeName (SourceDesc), 0847 AcpiUtGetTypeName (DestinationType))); 0848 Status = AE_TYPE; 0849 } 0850 } 0851 break; 0852 0853 case ARGI_TARGETREF: 0854 case ARGI_STORE_TARGET: 0855 0856 switch (DestinationType) 0857 { 0858 case ACPI_TYPE_INTEGER: 0859 case ACPI_TYPE_BUFFER_FIELD: 0860 case ACPI_TYPE_LOCAL_BANK_FIELD: 0861 case ACPI_TYPE_LOCAL_INDEX_FIELD: 0862 /* 0863 * These types require an Integer operand. We can convert 0864 * a Buffer or a String to an Integer if necessary. 0865 */ 0866 Status = AcpiExConvertToInteger (SourceDesc, ResultDesc, 0867 ACPI_IMPLICIT_CONVERSION); 0868 break; 0869 0870 case ACPI_TYPE_STRING: 0871 /* 0872 * The operand must be a String. We can convert an 0873 * Integer or Buffer if necessary 0874 */ 0875 Status = AcpiExConvertToString (SourceDesc, ResultDesc, 0876 ACPI_IMPLICIT_CONVERT_HEX); 0877 break; 0878 0879 case ACPI_TYPE_BUFFER: 0880 /* 0881 * The operand must be a Buffer. We can convert an 0882 * Integer or String if necessary 0883 */ 0884 Status = AcpiExConvertToBuffer (SourceDesc, ResultDesc); 0885 break; 0886 0887 default: 0888 0889 ACPI_ERROR ((AE_INFO, 0890 "Bad destination type during conversion: 0x%X", 0891 DestinationType)); 0892 Status = AE_AML_INTERNAL; 0893 break; 0894 } 0895 break; 0896 0897 case ARGI_REFERENCE: 0898 /* 0899 * CreateXxxxField cases - we are storing the field object into the name 0900 */ 0901 break; 0902 0903 default: 0904 0905 ACPI_ERROR ((AE_INFO, 0906 "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s", 0907 GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs), 0908 WalkState->Opcode, AcpiUtGetTypeName (DestinationType))); 0909 Status = AE_AML_INTERNAL; 0910 } 0911 0912 /* 0913 * Source-to-Target conversion semantics: 0914 * 0915 * If conversion to the target type cannot be performed, then simply 0916 * overwrite the target with the new object and type. 0917 */ 0918 if (Status == AE_TYPE) 0919 { 0920 Status = AE_OK; 0921 } 0922 0923 return_ACPI_STATUS (Status); 0924 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |