|
||||
Warning, cross-references for /kernel/drivers/acpica/exconvrt.c need to be fixed.
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 - 2009, 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 0117 #define __EXCONVRT_C__ 0118 0119 #include "acpi.h" 0120 #include "accommon.h" 0121 #include "acinterp.h" 0122 #include "amlcode.h" 0123 0124 0125 #define _COMPONENT ACPI_EXECUTER 0126 ACPI_MODULE_NAME ("exconvrt") 0127 0128 /* Local prototypes */ 0129 0130 static UINT32 0131 AcpiExConvertToAscii ( 0132 ACPI_INTEGER Integer, 0133 UINT16 Base, 0134 UINT8 *String, 0135 UINT8 MaxLength); 0136 0137 0138 /******************************************************************************* 0139 * 0140 * FUNCTION: AcpiExConvertToInteger 0141 * 0142 * PARAMETERS: ObjDesc - Object to be converted. Must be an 0143 * Integer, Buffer, or String 0144 * ResultDesc - Where the new Integer object is returned 0145 * Flags - Used for string conversion 0146 * 0147 * RETURN: Status 0148 * 0149 * DESCRIPTION: Convert an ACPI Object to an integer. 0150 * 0151 ******************************************************************************/ 0152 0153 ACPI_STATUS 0154 AcpiExConvertToInteger ( 0155 ACPI_OPERAND_OBJECT *ObjDesc, 0156 ACPI_OPERAND_OBJECT **ResultDesc, 0157 UINT32 Flags) 0158 { 0159 ACPI_OPERAND_OBJECT *ReturnDesc; 0160 UINT8 *Pointer; 0161 ACPI_INTEGER Result; 0162 UINT32 i; 0163 UINT32 Count; 0164 ACPI_STATUS Status; 0165 0166 0167 ACPI_FUNCTION_TRACE_PTR (ExConvertToInteger, ObjDesc); 0168 0169 0170 switch (ObjDesc->Common.Type) 0171 { 0172 case ACPI_TYPE_INTEGER: 0173 0174 /* No conversion necessary */ 0175 0176 *ResultDesc = ObjDesc; 0177 return_ACPI_STATUS (AE_OK); 0178 0179 case ACPI_TYPE_BUFFER: 0180 case ACPI_TYPE_STRING: 0181 0182 /* Note: Takes advantage of common buffer/string fields */ 0183 0184 Pointer = ObjDesc->Buffer.Pointer; 0185 Count = ObjDesc->Buffer.Length; 0186 break; 0187 0188 default: 0189 return_ACPI_STATUS (AE_TYPE); 0190 } 0191 0192 /* 0193 * Convert the buffer/string to an integer. Note that both buffers and 0194 * strings are treated as raw data - we don't convert ascii to hex for 0195 * strings. 0196 * 0197 * There are two terminating conditions for the loop: 0198 * 1) The size of an integer has been reached, or 0199 * 2) The end of the buffer or string has been reached 0200 */ 0201 Result = 0; 0202 0203 /* String conversion is different than Buffer conversion */ 0204 0205 switch (ObjDesc->Common.Type) 0206 { 0207 case ACPI_TYPE_STRING: 0208 0209 /* 0210 * Convert string to an integer - for most cases, the string must be 0211 * hexadecimal as per the ACPI specification. The only exception (as 0212 * of ACPI 3.0) is that the ToInteger() operator allows both decimal 0213 * and hexadecimal strings (hex prefixed with "0x"). 0214 */ 0215 Status = AcpiUtStrtoul64 ((char *) Pointer, Flags, &Result); 0216 if (ACPI_FAILURE (Status)) 0217 { 0218 return_ACPI_STATUS (Status); 0219 } 0220 break; 0221 0222 0223 case ACPI_TYPE_BUFFER: 0224 0225 /* Check for zero-length buffer */ 0226 0227 if (!Count) 0228 { 0229 return_ACPI_STATUS (AE_AML_BUFFER_LIMIT); 0230 } 0231 0232 /* Transfer no more than an integer's worth of data */ 0233 0234 if (Count > AcpiGbl_IntegerByteWidth) 0235 { 0236 Count = AcpiGbl_IntegerByteWidth; 0237 } 0238 0239 /* 0240 * Convert buffer to an integer - we simply grab enough raw data 0241 * from the buffer to fill an integer 0242 */ 0243 for (i = 0; i < Count; i++) 0244 { 0245 /* 0246 * Get next byte and shift it into the Result. 0247 * Little endian is used, meaning that the first byte of the buffer 0248 * is the LSB of the integer 0249 */ 0250 Result |= (((ACPI_INTEGER) Pointer[i]) << (i * 8)); 0251 } 0252 break; 0253 0254 0255 default: 0256 0257 /* No other types can get here */ 0258 break; 0259 } 0260 0261 /* Create a new integer */ 0262 0263 ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 0264 if (!ReturnDesc) 0265 { 0266 return_ACPI_STATUS (AE_NO_MEMORY); 0267 } 0268 0269 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 0270 ACPI_FORMAT_UINT64 (Result))); 0271 0272 /* Save the Result */ 0273 0274 ReturnDesc->Integer.Value = Result; 0275 AcpiExTruncateFor32bitTable (ReturnDesc); 0276 *ResultDesc = ReturnDesc; 0277 return_ACPI_STATUS (AE_OK); 0278 } 0279 0280 0281 /******************************************************************************* 0282 * 0283 * FUNCTION: AcpiExConvertToBuffer 0284 * 0285 * PARAMETERS: ObjDesc - Object to be converted. Must be an 0286 * Integer, Buffer, or String 0287 * ResultDesc - Where the new buffer object is returned 0288 * 0289 * RETURN: Status 0290 * 0291 * DESCRIPTION: Convert an ACPI Object to a Buffer 0292 * 0293 ******************************************************************************/ 0294 0295 ACPI_STATUS 0296 AcpiExConvertToBuffer ( 0297 ACPI_OPERAND_OBJECT *ObjDesc, 0298 ACPI_OPERAND_OBJECT **ResultDesc) 0299 { 0300 ACPI_OPERAND_OBJECT *ReturnDesc; 0301 UINT8 *NewBuf; 0302 0303 0304 ACPI_FUNCTION_TRACE_PTR (ExConvertToBuffer, ObjDesc); 0305 0306 0307 switch (ObjDesc->Common.Type) 0308 { 0309 case ACPI_TYPE_BUFFER: 0310 0311 /* No conversion necessary */ 0312 0313 *ResultDesc = ObjDesc; 0314 return_ACPI_STATUS (AE_OK); 0315 0316 0317 case ACPI_TYPE_INTEGER: 0318 0319 /* 0320 * Create a new Buffer object. 0321 * Need enough space for one integer 0322 */ 0323 ReturnDesc = AcpiUtCreateBufferObject (AcpiGbl_IntegerByteWidth); 0324 if (!ReturnDesc) 0325 { 0326 return_ACPI_STATUS (AE_NO_MEMORY); 0327 } 0328 0329 /* Copy the integer to the buffer, LSB first */ 0330 0331 NewBuf = ReturnDesc->Buffer.Pointer; 0332 ACPI_MEMCPY (NewBuf, 0333 &ObjDesc->Integer.Value, 0334 AcpiGbl_IntegerByteWidth); 0335 break; 0336 0337 0338 case ACPI_TYPE_STRING: 0339 0340 /* 0341 * Create a new Buffer object 0342 * Size will be the string length 0343 * 0344 * NOTE: Add one to the string length to include the null terminator. 0345 * The ACPI spec is unclear on this subject, but there is existing 0346 * ASL/AML code that depends on the null being transferred to the new 0347 * buffer. 0348 */ 0349 ReturnDesc = AcpiUtCreateBufferObject ( 0350 (ACPI_SIZE) ObjDesc->String.Length + 1); 0351 if (!ReturnDesc) 0352 { 0353 return_ACPI_STATUS (AE_NO_MEMORY); 0354 } 0355 0356 /* Copy the string to the buffer */ 0357 0358 NewBuf = ReturnDesc->Buffer.Pointer; 0359 ACPI_STRNCPY ((char *) NewBuf, (char *) ObjDesc->String.Pointer, 0360 ObjDesc->String.Length); 0361 break; 0362 0363 0364 default: 0365 return_ACPI_STATUS (AE_TYPE); 0366 } 0367 0368 /* Mark buffer initialized */ 0369 0370 ReturnDesc->Common.Flags |= AOPOBJ_DATA_VALID; 0371 *ResultDesc = ReturnDesc; 0372 return_ACPI_STATUS (AE_OK); 0373 } 0374 0375 0376 /******************************************************************************* 0377 * 0378 * FUNCTION: AcpiExConvertToAscii 0379 * 0380 * PARAMETERS: Integer - Value to be converted 0381 * Base - ACPI_STRING_DECIMAL or ACPI_STRING_HEX 0382 * String - Where the string is returned 0383 * DataWidth - Size of data item to be converted, in bytes 0384 * 0385 * RETURN: Actual string length 0386 * 0387 * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string 0388 * 0389 ******************************************************************************/ 0390 0391 static UINT32 0392 AcpiExConvertToAscii ( 0393 ACPI_INTEGER Integer, 0394 UINT16 Base, 0395 UINT8 *String, 0396 UINT8 DataWidth) 0397 { 0398 ACPI_INTEGER Digit; 0399 UINT32 i; 0400 UINT32 j; 0401 UINT32 k = 0; 0402 UINT32 HexLength; 0403 UINT32 DecimalLength; 0404 UINT32 Remainder; 0405 BOOLEAN SupressZeros; 0406 0407 0408 ACPI_FUNCTION_ENTRY (); 0409 0410 0411 switch (Base) 0412 { 0413 case 10: 0414 0415 /* Setup max length for the decimal number */ 0416 0417 switch (DataWidth) 0418 { 0419 case 1: 0420 DecimalLength = ACPI_MAX8_DECIMAL_DIGITS; 0421 break; 0422 0423 case 4: 0424 DecimalLength = ACPI_MAX32_DECIMAL_DIGITS; 0425 break; 0426 0427 case 8: 0428 default: 0429 DecimalLength = ACPI_MAX64_DECIMAL_DIGITS; 0430 break; 0431 } 0432 0433 SupressZeros = TRUE; /* No leading zeros */ 0434 Remainder = 0; 0435 0436 for (i = DecimalLength; i > 0; i--) 0437 { 0438 /* Divide by nth factor of 10 */ 0439 0440 Digit = Integer; 0441 for (j = 0; j < i; j++) 0442 { 0443 (void) AcpiUtShortDivide (Digit, 10, &Digit, &Remainder); 0444 } 0445 0446 /* Handle leading zeros */ 0447 0448 if (Remainder != 0) 0449 { 0450 SupressZeros = FALSE; 0451 } 0452 0453 if (!SupressZeros) 0454 { 0455 String[k] = (UINT8) (ACPI_ASCII_ZERO + Remainder); 0456 k++; 0457 } 0458 } 0459 break; 0460 0461 case 16: 0462 0463 /* HexLength: 2 ascii hex chars per data byte */ 0464 0465 HexLength = ACPI_MUL_2 (DataWidth); 0466 for (i = 0, j = (HexLength-1); i < HexLength; i++, j--) 0467 { 0468 /* Get one hex digit, most significant digits first */ 0469 0470 String[k] = (UINT8) AcpiUtHexToAsciiChar (Integer, ACPI_MUL_4 (j)); 0471 k++; 0472 } 0473 break; 0474 0475 default: 0476 return (0); 0477 } 0478 0479 /* 0480 * Since leading zeros are suppressed, we must check for the case where 0481 * the integer equals 0 0482 * 0483 * Finally, null terminate the string and return the length 0484 */ 0485 if (!k) 0486 { 0487 String [0] = ACPI_ASCII_ZERO; 0488 k = 1; 0489 } 0490 0491 String [k] = 0; 0492 return ((UINT32) k); 0493 } 0494 0495 0496 /******************************************************************************* 0497 * 0498 * FUNCTION: AcpiExConvertToString 0499 * 0500 * PARAMETERS: ObjDesc - Object to be converted. Must be an 0501 * Integer, Buffer, or String 0502 * ResultDesc - Where the string object is returned 0503 * Type - String flags (base and conversion type) 0504 * 0505 * RETURN: Status 0506 * 0507 * DESCRIPTION: Convert an ACPI Object to a string 0508 * 0509 ******************************************************************************/ 0510 0511 ACPI_STATUS 0512 AcpiExConvertToString ( 0513 ACPI_OPERAND_OBJECT *ObjDesc, 0514 ACPI_OPERAND_OBJECT **ResultDesc, 0515 UINT32 Type) 0516 { 0517 ACPI_OPERAND_OBJECT *ReturnDesc; 0518 UINT8 *NewBuf; 0519 UINT32 i; 0520 UINT32 StringLength = 0; 0521 UINT16 Base = 16; 0522 UINT8 Separator = ','; 0523 0524 0525 ACPI_FUNCTION_TRACE_PTR (ExConvertToString, ObjDesc); 0526 0527 0528 switch (ObjDesc->Common.Type) 0529 { 0530 case ACPI_TYPE_STRING: 0531 0532 /* No conversion necessary */ 0533 0534 *ResultDesc = ObjDesc; 0535 return_ACPI_STATUS (AE_OK); 0536 0537 0538 case ACPI_TYPE_INTEGER: 0539 0540 switch (Type) 0541 { 0542 case ACPI_EXPLICIT_CONVERT_DECIMAL: 0543 0544 /* Make room for maximum decimal number */ 0545 0546 StringLength = ACPI_MAX_DECIMAL_DIGITS; 0547 Base = 10; 0548 break; 0549 0550 default: 0551 0552 /* Two hex string characters for each integer byte */ 0553 0554 StringLength = ACPI_MUL_2 (AcpiGbl_IntegerByteWidth); 0555 break; 0556 } 0557 0558 /* 0559 * Create a new String 0560 * Need enough space for one ASCII integer (plus null terminator) 0561 */ 0562 ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength); 0563 if (!ReturnDesc) 0564 { 0565 return_ACPI_STATUS (AE_NO_MEMORY); 0566 } 0567 0568 NewBuf = ReturnDesc->Buffer.Pointer; 0569 0570 /* Convert integer to string */ 0571 0572 StringLength = AcpiExConvertToAscii (ObjDesc->Integer.Value, Base, 0573 NewBuf, AcpiGbl_IntegerByteWidth); 0574 0575 /* Null terminate at the correct place */ 0576 0577 ReturnDesc->String.Length = StringLength; 0578 NewBuf [StringLength] = 0; 0579 break; 0580 0581 0582 case ACPI_TYPE_BUFFER: 0583 0584 /* Setup string length, base, and separator */ 0585 0586 switch (Type) 0587 { 0588 case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by ToDecimalString */ 0589 /* 0590 * From ACPI: "If Data is a buffer, it is converted to a string of 0591 * decimal values separated by commas." 0592 */ 0593 Base = 10; 0594 0595 /* 0596 * Calculate the final string length. Individual string values 0597 * are variable length (include separator for each) 0598 */ 0599 for (i = 0; i < ObjDesc->Buffer.Length; i++) 0600 { 0601 if (ObjDesc->Buffer.Pointer[i] >= 100) 0602 { 0603 StringLength += 4; 0604 } 0605 else if (ObjDesc->Buffer.Pointer[i] >= 10) 0606 { 0607 StringLength += 3; 0608 } 0609 else 0610 { 0611 StringLength += 2; 0612 } 0613 } 0614 break; 0615 0616 case ACPI_IMPLICIT_CONVERT_HEX: 0617 /* 0618 * From the ACPI spec: 0619 *"The entire contents of the buffer are converted to a string of 0620 * two-character hexadecimal numbers, each separated by a space." 0621 */ 0622 Separator = ' '; 0623 StringLength = (ObjDesc->Buffer.Length * 3); 0624 break; 0625 0626 case ACPI_EXPLICIT_CONVERT_HEX: /* Used by ToHexString */ 0627 /* 0628 * From ACPI: "If Data is a buffer, it is converted to a string of 0629 * hexadecimal values separated by commas." 0630 */ 0631 StringLength = (ObjDesc->Buffer.Length * 3); 0632 break; 0633 0634 default: 0635 return_ACPI_STATUS (AE_BAD_PARAMETER); 0636 } 0637 0638 /* 0639 * Create a new string object and string buffer 0640 * (-1 because of extra separator included in StringLength from above) 0641 * Allow creation of zero-length strings from zero-length buffers. 0642 */ 0643 if (StringLength) 0644 { 0645 StringLength--; 0646 } 0647 0648 ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength); 0649 if (!ReturnDesc) 0650 { 0651 return_ACPI_STATUS (AE_NO_MEMORY); 0652 } 0653 0654 NewBuf = ReturnDesc->Buffer.Pointer; 0655 0656 /* 0657 * Convert buffer bytes to hex or decimal values 0658 * (separated by commas or spaces) 0659 */ 0660 for (i = 0; i < ObjDesc->Buffer.Length; i++) 0661 { 0662 NewBuf += AcpiExConvertToAscii ( 0663 (ACPI_INTEGER) ObjDesc->Buffer.Pointer[i], Base, 0664 NewBuf, 1); 0665 *NewBuf++ = Separator; /* each separated by a comma or space */ 0666 } 0667 0668 /* 0669 * Null terminate the string 0670 * (overwrites final comma/space from above) 0671 */ 0672 if (ObjDesc->Buffer.Length) 0673 { 0674 NewBuf--; 0675 } 0676 *NewBuf = 0; 0677 break; 0678 0679 default: 0680 return_ACPI_STATUS (AE_TYPE); 0681 } 0682 0683 *ResultDesc = ReturnDesc; 0684 return_ACPI_STATUS (AE_OK); 0685 } 0686 0687 0688 /******************************************************************************* 0689 * 0690 * FUNCTION: AcpiExConvertToTargetType 0691 * 0692 * PARAMETERS: DestinationType - Current type of the destination 0693 * SourceDesc - Source object to be converted. 0694 * ResultDesc - Where the converted object is returned 0695 * WalkState - Current method state 0696 * 0697 * RETURN: Status 0698 * 0699 * DESCRIPTION: Implements "implicit conversion" rules for storing an object. 0700 * 0701 ******************************************************************************/ 0702 0703 ACPI_STATUS 0704 AcpiExConvertToTargetType ( 0705 ACPI_OBJECT_TYPE DestinationType, 0706 ACPI_OPERAND_OBJECT *SourceDesc, 0707 ACPI_OPERAND_OBJECT **ResultDesc, 0708 ACPI_WALK_STATE *WalkState) 0709 { 0710 ACPI_STATUS Status = AE_OK; 0711 0712 0713 ACPI_FUNCTION_TRACE (ExConvertToTargetType); 0714 0715 0716 /* Default behavior */ 0717 0718 *ResultDesc = SourceDesc; 0719 0720 /* 0721 * If required by the target, 0722 * perform implicit conversion on the source before we store it. 0723 */ 0724 switch (GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs)) 0725 { 0726 case ARGI_SIMPLE_TARGET: 0727 case ARGI_FIXED_TARGET: 0728 case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */ 0729 0730 switch (DestinationType) 0731 { 0732 case ACPI_TYPE_LOCAL_REGION_FIELD: 0733 /* 0734 * Named field can always handle conversions 0735 */ 0736 break; 0737 0738 default: 0739 /* No conversion allowed for these types */ 0740 0741 if (DestinationType != SourceDesc->Common.Type) 0742 { 0743 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 0744 "Explicit operator, will store (%s) over existing type (%s)\n", 0745 AcpiUtGetObjectTypeName (SourceDesc), 0746 AcpiUtGetTypeName (DestinationType))); 0747 Status = AE_TYPE; 0748 } 0749 } 0750 break; 0751 0752 0753 case ARGI_TARGETREF: 0754 0755 switch (DestinationType) 0756 { 0757 case ACPI_TYPE_INTEGER: 0758 case ACPI_TYPE_BUFFER_FIELD: 0759 case ACPI_TYPE_LOCAL_BANK_FIELD: 0760 case ACPI_TYPE_LOCAL_INDEX_FIELD: 0761 /* 0762 * These types require an Integer operand. We can convert 0763 * a Buffer or a String to an Integer if necessary. 0764 */ 0765 Status = AcpiExConvertToInteger (SourceDesc, ResultDesc, 0766 16); 0767 break; 0768 0769 0770 case ACPI_TYPE_STRING: 0771 /* 0772 * The operand must be a String. We can convert an 0773 * Integer or Buffer if necessary 0774 */ 0775 Status = AcpiExConvertToString (SourceDesc, ResultDesc, 0776 ACPI_IMPLICIT_CONVERT_HEX); 0777 break; 0778 0779 0780 case ACPI_TYPE_BUFFER: 0781 /* 0782 * The operand must be a Buffer. We can convert an 0783 * Integer or String if necessary 0784 */ 0785 Status = AcpiExConvertToBuffer (SourceDesc, ResultDesc); 0786 break; 0787 0788 0789 default: 0790 ACPI_ERROR ((AE_INFO, "Bad destination type during conversion: %X", 0791 DestinationType)); 0792 Status = AE_AML_INTERNAL; 0793 break; 0794 } 0795 break; 0796 0797 0798 case ARGI_REFERENCE: 0799 /* 0800 * CreateXxxxField cases - we are storing the field object into the name 0801 */ 0802 break; 0803 0804 0805 default: 0806 ACPI_ERROR ((AE_INFO, 0807 "Unknown Target type ID 0x%X AmlOpcode %X DestType %s", 0808 GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs), 0809 WalkState->Opcode, AcpiUtGetTypeName (DestinationType))); 0810 Status = AE_AML_INTERNAL; 0811 } 0812 0813 /* 0814 * Source-to-Target conversion semantics: 0815 * 0816 * If conversion to the target type cannot be performed, then simply 0817 * overwrite the target with the new object and type. 0818 */ 0819 if (Status == AE_TYPE) 0820 { 0821 Status = AE_OK; 0822 } 0823 0824 return_ACPI_STATUS (Status); 0825 } 0826 0827
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 1.2.0 LXR engine. |