Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenexconvrt.c
Go to the documentation of this file.
00001 /****************************************************************************** 00002 * 00003 * Module Name: exconvrt - Object conversion routines 00004 * 00005 *****************************************************************************/ 00006 00007 /****************************************************************************** 00008 * 00009 * 1. Copyright Notice 00010 * 00011 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp. 00012 * All rights reserved. 00013 * 00014 * 2. License 00015 * 00016 * 2.1. This is your license from Intel Corp. under its intellectual property 00017 * rights. You may have additional license terms from the party that provided 00018 * you this software, covering your right to use that party's intellectual 00019 * property rights. 00020 * 00021 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 00022 * copy of the source code appearing in this file ("Covered Code") an 00023 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 00024 * base code distributed originally by Intel ("Original Intel Code") to copy, 00025 * make derivatives, distribute, use and display any portion of the Covered 00026 * Code in any form, with the right to sublicense such rights; and 00027 * 00028 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 00029 * license (with the right to sublicense), under only those claims of Intel 00030 * patents that are infringed by the Original Intel Code, to make, use, sell, 00031 * offer to sell, and import the Covered Code and derivative works thereof 00032 * solely to the minimum extent necessary to exercise the above copyright 00033 * license, and in no event shall the patent license extend to any additions 00034 * to or modifications of the Original Intel Code. No other license or right 00035 * is granted directly or by implication, estoppel or otherwise; 00036 * 00037 * The above copyright and patent license is granted only if the following 00038 * conditions are met: 00039 * 00040 * 3. Conditions 00041 * 00042 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 00043 * Redistribution of source code of any substantial portion of the Covered 00044 * Code or modification with rights to further distribute source must include 00045 * the above Copyright Notice, the above License, this list of Conditions, 00046 * and the following Disclaimer and Export Compliance provision. In addition, 00047 * Licensee must cause all Covered Code to which Licensee contributes to 00048 * contain a file documenting the changes Licensee made to create that Covered 00049 * Code and the date of any change. Licensee must include in that file the 00050 * documentation of any changes made by any predecessor Licensee. Licensee 00051 * must include a prominent statement that the modification is derived, 00052 * directly or indirectly, from Original Intel Code. 00053 * 00054 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 00055 * Redistribution of source code of any substantial portion of the Covered 00056 * Code or modification without rights to further distribute source must 00057 * include the following Disclaimer and Export Compliance provision in the 00058 * documentation and/or other materials provided with distribution. In 00059 * addition, Licensee may not authorize further sublicense of source of any 00060 * portion of the Covered Code, and must include terms to the effect that the 00061 * license from Licensee to its licensee is limited to the intellectual 00062 * property embodied in the software Licensee provides to its licensee, and 00063 * not to intellectual property embodied in modifications its licensee may 00064 * make. 00065 * 00066 * 3.3. Redistribution of Executable. Redistribution in executable form of any 00067 * substantial portion of the Covered Code or modification must reproduce the 00068 * above Copyright Notice, and the following Disclaimer and Export Compliance 00069 * provision in the documentation and/or other materials provided with the 00070 * distribution. 00071 * 00072 * 3.4. Intel retains all right, title, and interest in and to the Original 00073 * Intel Code. 00074 * 00075 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 00076 * Intel shall be used in advertising or otherwise to promote the sale, use or 00077 * other dealings in products derived from or relating to the Covered Code 00078 * without prior written authorization from Intel. 00079 * 00080 * 4. Disclaimer and Export Compliance 00081 * 00082 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 00083 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 00084 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 00085 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 00086 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 00087 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 00088 * PARTICULAR PURPOSE. 00089 * 00090 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 00091 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 00092 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 00093 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 00094 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 00095 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 00096 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 00097 * LIMITED REMEDY. 00098 * 00099 * 4.3. Licensee shall not export, either directly or indirectly, any of this 00100 * software or system incorporating such software without first obtaining any 00101 * required license or other approval from the U. S. Department of Commerce or 00102 * any other agency or department of the United States Government. In the 00103 * event Licensee exports any such software from the United States or 00104 * re-exports any such software from a foreign destination, Licensee shall 00105 * ensure that the distribution and export/re-export of the software is in 00106 * compliance with all laws, regulations, orders, or other restrictions of the 00107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 00108 * any of its subsidiaries will export/re-export any technical data, process, 00109 * software, or service, directly or indirectly, to any country for which the 00110 * United States government or any agency thereof requires an export license, 00111 * other governmental approval, or letter of assurance, without first obtaining 00112 * such license, approval or letter. 00113 * 00114 *****************************************************************************/ 00115 00116 00117 #define __EXCONVRT_C__ 00118 00119 #include "acpi.h" 00120 #include "accommon.h" 00121 #include "acinterp.h" 00122 #include "amlcode.h" 00123 00124 00125 #define _COMPONENT ACPI_EXECUTER 00126 ACPI_MODULE_NAME ("exconvrt") 00127 00128 /* Local prototypes */ 00129 00130 static UINT32 00131 AcpiExConvertToAscii ( 00132 UINT64 Integer, 00133 UINT16 Base, 00134 UINT8 *String, 00135 UINT8 MaxLength); 00136 00137 00138 /******************************************************************************* 00139 * 00140 * FUNCTION: AcpiExConvertToInteger 00141 * 00142 * PARAMETERS: ObjDesc - Object to be converted. Must be an 00143 * Integer, Buffer, or String 00144 * ResultDesc - Where the new Integer object is returned 00145 * Flags - Used for string conversion 00146 * 00147 * RETURN: Status 00148 * 00149 * DESCRIPTION: Convert an ACPI Object to an integer. 00150 * 00151 ******************************************************************************/ 00152 00153 ACPI_STATUS 00154 AcpiExConvertToInteger ( 00155 ACPI_OPERAND_OBJECT *ObjDesc, 00156 ACPI_OPERAND_OBJECT **ResultDesc, 00157 UINT32 Flags) 00158 { 00159 ACPI_OPERAND_OBJECT *ReturnDesc; 00160 UINT8 *Pointer; 00161 UINT64 Result; 00162 UINT32 i; 00163 UINT32 Count; 00164 ACPI_STATUS Status; 00165 00166 00167 ACPI_FUNCTION_TRACE_PTR (ExConvertToInteger, ObjDesc); 00168 00169 00170 switch (ObjDesc->Common.Type) 00171 { 00172 case ACPI_TYPE_INTEGER: 00173 00174 /* No conversion necessary */ 00175 00176 *ResultDesc = ObjDesc; 00177 return_ACPI_STATUS (AE_OK); 00178 00179 case ACPI_TYPE_BUFFER: 00180 case ACPI_TYPE_STRING: 00181 00182 /* Note: Takes advantage of common buffer/string fields */ 00183 00184 Pointer = ObjDesc->Buffer.Pointer; 00185 Count = ObjDesc->Buffer.Length; 00186 break; 00187 00188 default: 00189 return_ACPI_STATUS (AE_TYPE); 00190 } 00191 00192 /* 00193 * Convert the buffer/string to an integer. Note that both buffers and 00194 * strings are treated as raw data - we don't convert ascii to hex for 00195 * strings. 00196 * 00197 * There are two terminating conditions for the loop: 00198 * 1) The size of an integer has been reached, or 00199 * 2) The end of the buffer or string has been reached 00200 */ 00201 Result = 0; 00202 00203 /* String conversion is different than Buffer conversion */ 00204 00205 switch (ObjDesc->Common.Type) 00206 { 00207 case ACPI_TYPE_STRING: 00208 00209 /* 00210 * Convert string to an integer - for most cases, the string must be 00211 * hexadecimal as per the ACPI specification. The only exception (as 00212 * of ACPI 3.0) is that the ToInteger() operator allows both decimal 00213 * and hexadecimal strings (hex prefixed with "0x"). 00214 */ 00215 Status = AcpiUtStrtoul64 ((char *) Pointer, Flags, &Result); 00216 if (ACPI_FAILURE (Status)) 00217 { 00218 return_ACPI_STATUS (Status); 00219 } 00220 break; 00221 00222 00223 case ACPI_TYPE_BUFFER: 00224 00225 /* Check for zero-length buffer */ 00226 00227 if (!Count) 00228 { 00229 return_ACPI_STATUS (AE_AML_BUFFER_LIMIT); 00230 } 00231 00232 /* Transfer no more than an integer's worth of data */ 00233 00234 if (Count > AcpiGbl_IntegerByteWidth) 00235 { 00236 Count = AcpiGbl_IntegerByteWidth; 00237 } 00238 00239 /* 00240 * Convert buffer to an integer - we simply grab enough raw data 00241 * from the buffer to fill an integer 00242 */ 00243 for (i = 0; i < Count; i++) 00244 { 00245 /* 00246 * Get next byte and shift it into the Result. 00247 * Little endian is used, meaning that the first byte of the buffer 00248 * is the LSB of the integer 00249 */ 00250 Result |= (((UINT64) Pointer[i]) << (i * 8)); 00251 } 00252 break; 00253 00254 00255 default: 00256 00257 /* No other types can get here */ 00258 break; 00259 } 00260 00261 /* Create a new integer */ 00262 00263 ReturnDesc = AcpiUtCreateIntegerObject (Result); 00264 if (!ReturnDesc) 00265 { 00266 return_ACPI_STATUS (AE_NO_MEMORY); 00267 } 00268 00269 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 00270 ACPI_FORMAT_UINT64 (Result))); 00271 00272 /* Save the Result */ 00273 00274 AcpiExTruncateFor32bitTable (ReturnDesc); 00275 *ResultDesc = ReturnDesc; 00276 return_ACPI_STATUS (AE_OK); 00277 } 00278 00279 00280 /******************************************************************************* 00281 * 00282 * FUNCTION: AcpiExConvertToBuffer 00283 * 00284 * PARAMETERS: ObjDesc - Object to be converted. Must be an 00285 * Integer, Buffer, or String 00286 * ResultDesc - Where the new buffer object is returned 00287 * 00288 * RETURN: Status 00289 * 00290 * DESCRIPTION: Convert an ACPI Object to a Buffer 00291 * 00292 ******************************************************************************/ 00293 00294 ACPI_STATUS 00295 AcpiExConvertToBuffer ( 00296 ACPI_OPERAND_OBJECT *ObjDesc, 00297 ACPI_OPERAND_OBJECT **ResultDesc) 00298 { 00299 ACPI_OPERAND_OBJECT *ReturnDesc; 00300 UINT8 *NewBuf; 00301 00302 00303 ACPI_FUNCTION_TRACE_PTR (ExConvertToBuffer, ObjDesc); 00304 00305 00306 switch (ObjDesc->Common.Type) 00307 { 00308 case ACPI_TYPE_BUFFER: 00309 00310 /* No conversion necessary */ 00311 00312 *ResultDesc = ObjDesc; 00313 return_ACPI_STATUS (AE_OK); 00314 00315 00316 case ACPI_TYPE_INTEGER: 00317 00318 /* 00319 * Create a new Buffer object. 00320 * Need enough space for one integer 00321 */ 00322 ReturnDesc = AcpiUtCreateBufferObject (AcpiGbl_IntegerByteWidth); 00323 if (!ReturnDesc) 00324 { 00325 return_ACPI_STATUS (AE_NO_MEMORY); 00326 } 00327 00328 /* Copy the integer to the buffer, LSB first */ 00329 00330 NewBuf = ReturnDesc->Buffer.Pointer; 00331 ACPI_MEMCPY (NewBuf, 00332 &ObjDesc->Integer.Value, 00333 AcpiGbl_IntegerByteWidth); 00334 break; 00335 00336 00337 case ACPI_TYPE_STRING: 00338 00339 /* 00340 * Create a new Buffer object 00341 * Size will be the string length 00342 * 00343 * NOTE: Add one to the string length to include the null terminator. 00344 * The ACPI spec is unclear on this subject, but there is existing 00345 * ASL/AML code that depends on the null being transferred to the new 00346 * buffer. 00347 */ 00348 ReturnDesc = AcpiUtCreateBufferObject ( 00349 (ACPI_SIZE) ObjDesc->String.Length + 1); 00350 if (!ReturnDesc) 00351 { 00352 return_ACPI_STATUS (AE_NO_MEMORY); 00353 } 00354 00355 /* Copy the string to the buffer */ 00356 00357 NewBuf = ReturnDesc->Buffer.Pointer; 00358 ACPI_STRNCPY ((char *) NewBuf, (char *) ObjDesc->String.Pointer, 00359 ObjDesc->String.Length); 00360 break; 00361 00362 00363 default: 00364 return_ACPI_STATUS (AE_TYPE); 00365 } 00366 00367 /* Mark buffer initialized */ 00368 00369 ReturnDesc->Common.Flags |= AOPOBJ_DATA_VALID; 00370 *ResultDesc = ReturnDesc; 00371 return_ACPI_STATUS (AE_OK); 00372 } 00373 00374 00375 /******************************************************************************* 00376 * 00377 * FUNCTION: AcpiExConvertToAscii 00378 * 00379 * PARAMETERS: Integer - Value to be converted 00380 * Base - ACPI_STRING_DECIMAL or ACPI_STRING_HEX 00381 * String - Where the string is returned 00382 * DataWidth - Size of data item to be converted, in bytes 00383 * 00384 * RETURN: Actual string length 00385 * 00386 * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string 00387 * 00388 ******************************************************************************/ 00389 00390 static UINT32 00391 AcpiExConvertToAscii ( 00392 UINT64 Integer, 00393 UINT16 Base, 00394 UINT8 *String, 00395 UINT8 DataWidth) 00396 { 00397 UINT64 Digit; 00398 UINT32 i; 00399 UINT32 j; 00400 UINT32 k = 0; 00401 UINT32 HexLength; 00402 UINT32 DecimalLength; 00403 UINT32 Remainder; 00404 BOOLEAN SupressZeros; 00405 00406 00407 ACPI_FUNCTION_ENTRY (); 00408 00409 00410 switch (Base) 00411 { 00412 case 10: 00413 00414 /* Setup max length for the decimal number */ 00415 00416 switch (DataWidth) 00417 { 00418 case 1: 00419 DecimalLength = ACPI_MAX8_DECIMAL_DIGITS; 00420 break; 00421 00422 case 4: 00423 DecimalLength = ACPI_MAX32_DECIMAL_DIGITS; 00424 break; 00425 00426 case 8: 00427 default: 00428 DecimalLength = ACPI_MAX64_DECIMAL_DIGITS; 00429 break; 00430 } 00431 00432 SupressZeros = TRUE; /* No leading zeros */ 00433 Remainder = 0; 00434 00435 for (i = DecimalLength; i > 0; i--) 00436 { 00437 /* Divide by nth factor of 10 */ 00438 00439 Digit = Integer; 00440 for (j = 0; j < i; j++) 00441 { 00442 (void) AcpiUtShortDivide (Digit, 10, &Digit, &Remainder); 00443 } 00444 00445 /* Handle leading zeros */ 00446 00447 if (Remainder != 0) 00448 { 00449 SupressZeros = FALSE; 00450 } 00451 00452 if (!SupressZeros) 00453 { 00454 String[k] = (UINT8) (ACPI_ASCII_ZERO + Remainder); 00455 k++; 00456 } 00457 } 00458 break; 00459 00460 case 16: 00461 00462 /* HexLength: 2 ascii hex chars per data byte */ 00463 00464 HexLength = ACPI_MUL_2 (DataWidth); 00465 for (i = 0, j = (HexLength-1); i < HexLength; i++, j--) 00466 { 00467 /* Get one hex digit, most significant digits first */ 00468 00469 String[k] = (UINT8) AcpiUtHexToAsciiChar (Integer, ACPI_MUL_4 (j)); 00470 k++; 00471 } 00472 break; 00473 00474 default: 00475 return (0); 00476 } 00477 00478 /* 00479 * Since leading zeros are suppressed, we must check for the case where 00480 * the integer equals 0 00481 * 00482 * Finally, null terminate the string and return the length 00483 */ 00484 if (!k) 00485 { 00486 String [0] = ACPI_ASCII_ZERO; 00487 k = 1; 00488 } 00489 00490 String [k] = 0; 00491 return ((UINT32) k); 00492 } 00493 00494 00495 /******************************************************************************* 00496 * 00497 * FUNCTION: AcpiExConvertToString 00498 * 00499 * PARAMETERS: ObjDesc - Object to be converted. Must be an 00500 * Integer, Buffer, or String 00501 * ResultDesc - Where the string object is returned 00502 * Type - String flags (base and conversion type) 00503 * 00504 * RETURN: Status 00505 * 00506 * DESCRIPTION: Convert an ACPI Object to a string 00507 * 00508 ******************************************************************************/ 00509 00510 ACPI_STATUS 00511 AcpiExConvertToString ( 00512 ACPI_OPERAND_OBJECT *ObjDesc, 00513 ACPI_OPERAND_OBJECT **ResultDesc, 00514 UINT32 Type) 00515 { 00516 ACPI_OPERAND_OBJECT *ReturnDesc; 00517 UINT8 *NewBuf; 00518 UINT32 i; 00519 UINT32 StringLength = 0; 00520 UINT16 Base = 16; 00521 UINT8 Separator = ','; 00522 00523 00524 ACPI_FUNCTION_TRACE_PTR (ExConvertToString, ObjDesc); 00525 00526 00527 switch (ObjDesc->Common.Type) 00528 { 00529 case ACPI_TYPE_STRING: 00530 00531 /* No conversion necessary */ 00532 00533 *ResultDesc = ObjDesc; 00534 return_ACPI_STATUS (AE_OK); 00535 00536 00537 case ACPI_TYPE_INTEGER: 00538 00539 switch (Type) 00540 { 00541 case ACPI_EXPLICIT_CONVERT_DECIMAL: 00542 00543 /* Make room for maximum decimal number */ 00544 00545 StringLength = ACPI_MAX_DECIMAL_DIGITS; 00546 Base = 10; 00547 break; 00548 00549 default: 00550 00551 /* Two hex string characters for each integer byte */ 00552 00553 StringLength = ACPI_MUL_2 (AcpiGbl_IntegerByteWidth); 00554 break; 00555 } 00556 00557 /* 00558 * Create a new String 00559 * Need enough space for one ASCII integer (plus null terminator) 00560 */ 00561 ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength); 00562 if (!ReturnDesc) 00563 { 00564 return_ACPI_STATUS (AE_NO_MEMORY); 00565 } 00566 00567 NewBuf = ReturnDesc->Buffer.Pointer; 00568 00569 /* Convert integer to string */ 00570 00571 StringLength = AcpiExConvertToAscii (ObjDesc->Integer.Value, Base, 00572 NewBuf, AcpiGbl_IntegerByteWidth); 00573 00574 /* Null terminate at the correct place */ 00575 00576 ReturnDesc->String.Length = StringLength; 00577 NewBuf [StringLength] = 0; 00578 break; 00579 00580 00581 case ACPI_TYPE_BUFFER: 00582 00583 /* Setup string length, base, and separator */ 00584 00585 switch (Type) 00586 { 00587 case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by ToDecimalString */ 00588 /* 00589 * From ACPI: "If Data is a buffer, it is converted to a string of 00590 * decimal values separated by commas." 00591 */ 00592 Base = 10; 00593 00594 /* 00595 * Calculate the final string length. Individual string values 00596 * are variable length (include separator for each) 00597 */ 00598 for (i = 0; i < ObjDesc->Buffer.Length; i++) 00599 { 00600 if (ObjDesc->Buffer.Pointer[i] >= 100) 00601 { 00602 StringLength += 4; 00603 } 00604 else if (ObjDesc->Buffer.Pointer[i] >= 10) 00605 { 00606 StringLength += 3; 00607 } 00608 else 00609 { 00610 StringLength += 2; 00611 } 00612 } 00613 break; 00614 00615 case ACPI_IMPLICIT_CONVERT_HEX: 00616 /* 00617 * From the ACPI spec: 00618 *"The entire contents of the buffer are converted to a string of 00619 * two-character hexadecimal numbers, each separated by a space." 00620 */ 00621 Separator = ' '; 00622 StringLength = (ObjDesc->Buffer.Length * 3); 00623 break; 00624 00625 case ACPI_EXPLICIT_CONVERT_HEX: /* Used by ToHexString */ 00626 /* 00627 * From ACPI: "If Data is a buffer, it is converted to a string of 00628 * hexadecimal values separated by commas." 00629 */ 00630 StringLength = (ObjDesc->Buffer.Length * 3); 00631 break; 00632 00633 default: 00634 return_ACPI_STATUS (AE_BAD_PARAMETER); 00635 } 00636 00637 /* 00638 * Create a new string object and string buffer 00639 * (-1 because of extra separator included in StringLength from above) 00640 * Allow creation of zero-length strings from zero-length buffers. 00641 */ 00642 if (StringLength) 00643 { 00644 StringLength--; 00645 } 00646 00647 ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength); 00648 if (!ReturnDesc) 00649 { 00650 return_ACPI_STATUS (AE_NO_MEMORY); 00651 } 00652 00653 NewBuf = ReturnDesc->Buffer.Pointer; 00654 00655 /* 00656 * Convert buffer bytes to hex or decimal values 00657 * (separated by commas or spaces) 00658 */ 00659 for (i = 0; i < ObjDesc->Buffer.Length; i++) 00660 { 00661 NewBuf += AcpiExConvertToAscii ( 00662 (UINT64) ObjDesc->Buffer.Pointer[i], Base, 00663 NewBuf, 1); 00664 *NewBuf++ = Separator; /* each separated by a comma or space */ 00665 } 00666 00667 /* 00668 * Null terminate the string 00669 * (overwrites final comma/space from above) 00670 */ 00671 if (ObjDesc->Buffer.Length) 00672 { 00673 NewBuf--; 00674 } 00675 *NewBuf = 0; 00676 break; 00677 00678 default: 00679 return_ACPI_STATUS (AE_TYPE); 00680 } 00681 00682 *ResultDesc = ReturnDesc; 00683 return_ACPI_STATUS (AE_OK); 00684 } 00685 00686 00687 /******************************************************************************* 00688 * 00689 * FUNCTION: AcpiExConvertToTargetType 00690 * 00691 * PARAMETERS: DestinationType - Current type of the destination 00692 * SourceDesc - Source object to be converted. 00693 * ResultDesc - Where the converted object is returned 00694 * WalkState - Current method state 00695 * 00696 * RETURN: Status 00697 * 00698 * DESCRIPTION: Implements "implicit conversion" rules for storing an object. 00699 * 00700 ******************************************************************************/ 00701 00702 ACPI_STATUS 00703 AcpiExConvertToTargetType ( 00704 ACPI_OBJECT_TYPE DestinationType, 00705 ACPI_OPERAND_OBJECT *SourceDesc, 00706 ACPI_OPERAND_OBJECT **ResultDesc, 00707 ACPI_WALK_STATE *WalkState) 00708 { 00709 ACPI_STATUS Status = AE_OK; 00710 00711 00712 ACPI_FUNCTION_TRACE (ExConvertToTargetType); 00713 00714 00715 /* Default behavior */ 00716 00717 *ResultDesc = SourceDesc; 00718 00719 /* 00720 * If required by the target, 00721 * perform implicit conversion on the source before we store it. 00722 */ 00723 switch (GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs)) 00724 { 00725 case ARGI_SIMPLE_TARGET: 00726 case ARGI_FIXED_TARGET: 00727 case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */ 00728 00729 switch (DestinationType) 00730 { 00731 case ACPI_TYPE_LOCAL_REGION_FIELD: 00732 /* 00733 * Named field can always handle conversions 00734 */ 00735 break; 00736 00737 default: 00738 /* No conversion allowed for these types */ 00739 00740 if (DestinationType != SourceDesc->Common.Type) 00741 { 00742 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 00743 "Explicit operator, will store (%s) over existing type (%s)\n", 00744 AcpiUtGetObjectTypeName (SourceDesc), 00745 AcpiUtGetTypeName (DestinationType))); 00746 Status = AE_TYPE; 00747 } 00748 } 00749 break; 00750 00751 00752 case ARGI_TARGETREF: 00753 00754 switch (DestinationType) 00755 { 00756 case ACPI_TYPE_INTEGER: 00757 case ACPI_TYPE_BUFFER_FIELD: 00758 case ACPI_TYPE_LOCAL_BANK_FIELD: 00759 case ACPI_TYPE_LOCAL_INDEX_FIELD: 00760 /* 00761 * These types require an Integer operand. We can convert 00762 * a Buffer or a String to an Integer if necessary. 00763 */ 00764 Status = AcpiExConvertToInteger (SourceDesc, ResultDesc, 00765 16); 00766 break; 00767 00768 00769 case ACPI_TYPE_STRING: 00770 /* 00771 * The operand must be a String. We can convert an 00772 * Integer or Buffer if necessary 00773 */ 00774 Status = AcpiExConvertToString (SourceDesc, ResultDesc, 00775 ACPI_IMPLICIT_CONVERT_HEX); 00776 break; 00777 00778 00779 case ACPI_TYPE_BUFFER: 00780 /* 00781 * The operand must be a Buffer. We can convert an 00782 * Integer or String if necessary 00783 */ 00784 Status = AcpiExConvertToBuffer (SourceDesc, ResultDesc); 00785 break; 00786 00787 00788 default: 00789 ACPI_ERROR ((AE_INFO, "Bad destination type during conversion: 0x%X", 00790 DestinationType)); 00791 Status = AE_AML_INTERNAL; 00792 break; 00793 } 00794 break; 00795 00796 00797 case ARGI_REFERENCE: 00798 /* 00799 * CreateXxxxField cases - we are storing the field object into the name 00800 */ 00801 break; 00802 00803 00804 default: 00805 ACPI_ERROR ((AE_INFO, 00806 "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s", 00807 GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs), 00808 WalkState->Opcode, AcpiUtGetTypeName (DestinationType))); 00809 Status = AE_AML_INTERNAL; 00810 } 00811 00812 /* 00813 * Source-to-Target conversion semantics: 00814 * 00815 * If conversion to the target type cannot be performed, then simply 00816 * overwrite the target with the new object and type. 00817 */ 00818 if (Status == AE_TYPE) 00819 { 00820 Status = AE_OK; 00821 } 00822 00823 return_ACPI_STATUS (Status); 00824 } 00825 00826 Generated on Sun May 27 2012 04:27:16 for ReactOS by
1.7.6.1
|