171867Smsmith/****************************************************************************** 271867Smsmith * 377424Smsmith * Module Name: exconvrt - Object conversion routines 471867Smsmith * 571867Smsmith *****************************************************************************/ 671867Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 971867Smsmith * All rights reserved. 1071867Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2571867Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2971867Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4371867Smsmith 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 47193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 4871867Smsmith 4971867Smsmith 5077424Smsmith#define _COMPONENT ACPI_EXECUTER 5191116Smsmith ACPI_MODULE_NAME ("exconvrt") 5271867Smsmith 53151937Sjkim/* Local prototypes */ 5471867Smsmith 55151937Sjkimstatic UINT32 56151937SjkimAcpiExConvertToAscii ( 57202771Sjkim UINT64 Integer, 58151937Sjkim UINT16 Base, 59151937Sjkim UINT8 *String, 60151937Sjkim UINT8 MaxLength); 61151937Sjkim 62151937Sjkim 6371867Smsmith/******************************************************************************* 6471867Smsmith * 6577424Smsmith * FUNCTION: AcpiExConvertToInteger 6671867Smsmith * 67193267Sjkim * PARAMETERS: ObjDesc - Object to be converted. Must be an 6871867Smsmith * Integer, Buffer, or String 69126372Snjl * ResultDesc - Where the new Integer object is returned 70138287Smarks * Flags - Used for string conversion 7171867Smsmith * 7271867Smsmith * RETURN: Status 7371867Smsmith * 7471867Smsmith * DESCRIPTION: Convert an ACPI Object to an integer. 7571867Smsmith * 7671867Smsmith ******************************************************************************/ 7771867Smsmith 7871867SmsmithACPI_STATUS 7977424SmsmithAcpiExConvertToInteger ( 8080062Smsmith ACPI_OPERAND_OBJECT *ObjDesc, 8180062Smsmith ACPI_OPERAND_OBJECT **ResultDesc, 82138287Smarks UINT32 Flags) 8371867Smsmith{ 84138287Smarks ACPI_OPERAND_OBJECT *ReturnDesc; 85138287Smarks UINT8 *Pointer; 86202771Sjkim UINT64 Result; 8771867Smsmith UINT32 i; 8871867Smsmith UINT32 Count; 8999679Siwasaki ACPI_STATUS Status; 9071867Smsmith 9171867Smsmith 92167802Sjkim ACPI_FUNCTION_TRACE_PTR (ExConvertToInteger, ObjDesc); 9383174Smsmith 9483174Smsmith 95193267Sjkim switch (ObjDesc->Common.Type) 9671867Smsmith { 9771867Smsmith case ACPI_TYPE_INTEGER: 98138287Smarks 99138287Smarks /* No conversion necessary */ 100138287Smarks 10180062Smsmith *ResultDesc = ObjDesc; 10291116Smsmith return_ACPI_STATUS (AE_OK); 10371867Smsmith 104138287Smarks case ACPI_TYPE_BUFFER: 10571867Smsmith case ACPI_TYPE_STRING: 10671867Smsmith 107138287Smarks /* Note: Takes advantage of common buffer/string fields */ 108138287Smarks 10999679Siwasaki Pointer = ObjDesc->Buffer.Pointer; 11080062Smsmith Count = ObjDesc->Buffer.Length; 11171867Smsmith break; 11271867Smsmith 11371867Smsmith default: 114250838Sjkim 11591116Smsmith return_ACPI_STATUS (AE_TYPE); 11671867Smsmith } 11771867Smsmith 11871867Smsmith /* 119193267Sjkim * Convert the buffer/string to an integer. Note that both buffers and 12071867Smsmith * strings are treated as raw data - we don't convert ascii to hex for 12171867Smsmith * strings. 12271867Smsmith * 12371867Smsmith * There are two terminating conditions for the loop: 12471867Smsmith * 1) The size of an integer has been reached, or 12571867Smsmith * 2) The end of the buffer or string has been reached 12671867Smsmith */ 12771867Smsmith Result = 0; 12871867Smsmith 129151937Sjkim /* String conversion is different than Buffer conversion */ 130151937Sjkim 131193267Sjkim switch (ObjDesc->Common.Type) 13271867Smsmith { 13371867Smsmith case ACPI_TYPE_STRING: 13471867Smsmith /* 135138287Smarks * Convert string to an integer - for most cases, the string must be 136193267Sjkim * hexadecimal as per the ACPI specification. The only exception (as 137138287Smarks * of ACPI 3.0) is that the ToInteger() operator allows both decimal 138138287Smarks * and hexadecimal strings (hex prefixed with "0x"). 13971867Smsmith */ 140306536Sjkim Status = AcpiUtStrtoul64 ((char *) Pointer, Flags, 141306536Sjkim AcpiGbl_IntegerByteWidth, &Result); 14299679Siwasaki if (ACPI_FAILURE (Status)) 14399679Siwasaki { 14499679Siwasaki return_ACPI_STATUS (Status); 14599679Siwasaki } 14671867Smsmith break; 14771867Smsmith 14871867Smsmith case ACPI_TYPE_BUFFER: 14971867Smsmith 150151937Sjkim /* Check for zero-length buffer */ 151151937Sjkim 152151937Sjkim if (!Count) 153151937Sjkim { 154151937Sjkim return_ACPI_STATUS (AE_AML_BUFFER_LIMIT); 155151937Sjkim } 156151937Sjkim 157138287Smarks /* Transfer no more than an integer's worth of data */ 158138287Smarks 159138287Smarks if (Count > AcpiGbl_IntegerByteWidth) 160138287Smarks { 161138287Smarks Count = AcpiGbl_IntegerByteWidth; 162138287Smarks } 163138287Smarks 16471867Smsmith /* 165138287Smarks * Convert buffer to an integer - we simply grab enough raw data 166138287Smarks * from the buffer to fill an integer 16771867Smsmith */ 16871867Smsmith for (i = 0; i < Count; i++) 16971867Smsmith { 17071867Smsmith /* 17171867Smsmith * Get next byte and shift it into the Result. 17271867Smsmith * Little endian is used, meaning that the first byte of the buffer 17371867Smsmith * is the LSB of the integer 17471867Smsmith */ 175202771Sjkim Result |= (((UINT64) Pointer[i]) << (i * 8)); 17671867Smsmith } 17771867Smsmith break; 17899679Siwasaki 17999679Siwasaki default: 180193267Sjkim 18199679Siwasaki /* No other types can get here */ 182250838Sjkim 18399679Siwasaki break; 18471867Smsmith } 18571867Smsmith 186151937Sjkim /* Create a new integer */ 187151937Sjkim 188199337Sjkim ReturnDesc = AcpiUtCreateIntegerObject (Result); 189138287Smarks if (!ReturnDesc) 19099679Siwasaki { 19199679Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 19299679Siwasaki } 19399679Siwasaki 194167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 195167802Sjkim ACPI_FORMAT_UINT64 (Result))); 196167802Sjkim 197107325Siwasaki /* Save the Result */ 19871867Smsmith 199245582Sjkim (void) AcpiExTruncateFor32bitTable (ReturnDesc); 200138287Smarks *ResultDesc = ReturnDesc; 20191116Smsmith return_ACPI_STATUS (AE_OK); 20271867Smsmith} 20371867Smsmith 20471867Smsmith 20571867Smsmith/******************************************************************************* 20671867Smsmith * 20777424Smsmith * FUNCTION: AcpiExConvertToBuffer 20871867Smsmith * 209193267Sjkim * PARAMETERS: ObjDesc - Object to be converted. Must be an 21071867Smsmith * Integer, Buffer, or String 211126372Snjl * ResultDesc - Where the new buffer object is returned 21271867Smsmith * 21371867Smsmith * RETURN: Status 21471867Smsmith * 215104470Siwasaki * DESCRIPTION: Convert an ACPI Object to a Buffer 21671867Smsmith * 21771867Smsmith ******************************************************************************/ 21871867Smsmith 21971867SmsmithACPI_STATUS 22077424SmsmithAcpiExConvertToBuffer ( 22180062Smsmith ACPI_OPERAND_OBJECT *ObjDesc, 222138287Smarks ACPI_OPERAND_OBJECT **ResultDesc) 22371867Smsmith{ 224138287Smarks ACPI_OPERAND_OBJECT *ReturnDesc; 22571867Smsmith UINT8 *NewBuf; 22671867Smsmith 22771867Smsmith 228167802Sjkim ACPI_FUNCTION_TRACE_PTR (ExConvertToBuffer, ObjDesc); 22983174Smsmith 23083174Smsmith 231193267Sjkim switch (ObjDesc->Common.Type) 23271867Smsmith { 233107325Siwasaki case ACPI_TYPE_BUFFER: 234107325Siwasaki 235107325Siwasaki /* No conversion necessary */ 236107325Siwasaki 237107325Siwasaki *ResultDesc = ObjDesc; 238107325Siwasaki return_ACPI_STATUS (AE_OK); 239107325Siwasaki 240107325Siwasaki 24171867Smsmith case ACPI_TYPE_INTEGER: 24271867Smsmith /* 243107325Siwasaki * Create a new Buffer object. 244114237Snjl * Need enough space for one integer 24571867Smsmith */ 246138287Smarks ReturnDesc = AcpiUtCreateBufferObject (AcpiGbl_IntegerByteWidth); 247138287Smarks if (!ReturnDesc) 24871867Smsmith { 24991116Smsmith return_ACPI_STATUS (AE_NO_MEMORY); 25071867Smsmith } 25171867Smsmith 252138287Smarks /* Copy the integer to the buffer, LSB first */ 25371867Smsmith 254138287Smarks NewBuf = ReturnDesc->Buffer.Pointer; 255306536Sjkim memcpy (NewBuf, &ObjDesc->Integer.Value, AcpiGbl_IntegerByteWidth); 25671867Smsmith break; 25771867Smsmith 25871867Smsmith case ACPI_TYPE_STRING: 259104470Siwasaki /* 260104470Siwasaki * Create a new Buffer object 261107325Siwasaki * Size will be the string length 262151937Sjkim * 263151937Sjkim * NOTE: Add one to the string length to include the null terminator. 264151937Sjkim * The ACPI spec is unclear on this subject, but there is existing 265151937Sjkim * ASL/AML code that depends on the null being transferred to the new 266151937Sjkim * buffer. 267104470Siwasaki */ 268306536Sjkim ReturnDesc = AcpiUtCreateBufferObject ((ACPI_SIZE) 269306536Sjkim ObjDesc->String.Length + 1); 270138287Smarks if (!ReturnDesc) 271104470Siwasaki { 272104470Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 273104470Siwasaki } 274104470Siwasaki 275107325Siwasaki /* Copy the string to the buffer */ 276104470Siwasaki 277138287Smarks NewBuf = ReturnDesc->Buffer.Pointer; 278306536Sjkim strncpy ((char *) NewBuf, (char *) ObjDesc->String.Pointer, 279107325Siwasaki ObjDesc->String.Length); 28071867Smsmith break; 28171867Smsmith 282250838Sjkim default: 28371867Smsmith 28491116Smsmith return_ACPI_STATUS (AE_TYPE); 28591116Smsmith } 28671867Smsmith 28799146Siwasaki /* Mark buffer initialized */ 28899146Siwasaki 289138287Smarks ReturnDesc->Common.Flags |= AOPOBJ_DATA_VALID; 290138287Smarks *ResultDesc = ReturnDesc; 29191116Smsmith return_ACPI_STATUS (AE_OK); 29271867Smsmith} 29371867Smsmith 29471867Smsmith 29571867Smsmith/******************************************************************************* 29671867Smsmith * 297138287Smarks * FUNCTION: AcpiExConvertToAscii 29882367Smsmith * 299104470Siwasaki * PARAMETERS: Integer - Value to be converted 300138287Smarks * Base - ACPI_STRING_DECIMAL or ACPI_STRING_HEX 301104470Siwasaki * String - Where the string is returned 302138287Smarks * DataWidth - Size of data item to be converted, in bytes 30382367Smsmith * 30482367Smsmith * RETURN: Actual string length 30582367Smsmith * 306104470Siwasaki * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string 30782367Smsmith * 30882367Smsmith ******************************************************************************/ 30982367Smsmith 310151937Sjkimstatic UINT32 31182367SmsmithAcpiExConvertToAscii ( 312202771Sjkim UINT64 Integer, 313138287Smarks UINT16 Base, 314114237Snjl UINT8 *String, 315114237Snjl UINT8 DataWidth) 31682367Smsmith{ 317202771Sjkim UINT64 Digit; 318193267Sjkim UINT32 i; 319193267Sjkim UINT32 j; 320193267Sjkim UINT32 k = 0; 321193267Sjkim UINT32 HexLength; 322193267Sjkim UINT32 DecimalLength; 32384491Smsmith UINT32 Remainder; 324138287Smarks BOOLEAN SupressZeros; 32582367Smsmith 32682367Smsmith 32791116Smsmith ACPI_FUNCTION_ENTRY (); 32882367Smsmith 329126372Snjl 33082367Smsmith switch (Base) 33182367Smsmith { 33282367Smsmith case 10: 33382367Smsmith 334138287Smarks /* Setup max length for the decimal number */ 335138287Smarks 336138287Smarks switch (DataWidth) 337138287Smarks { 338138287Smarks case 1: 339250838Sjkim 340138287Smarks DecimalLength = ACPI_MAX8_DECIMAL_DIGITS; 341138287Smarks break; 342138287Smarks 343138287Smarks case 4: 344250838Sjkim 345138287Smarks DecimalLength = ACPI_MAX32_DECIMAL_DIGITS; 346138287Smarks break; 347138287Smarks 348138287Smarks case 8: 349138287Smarks default: 350250838Sjkim 351138287Smarks DecimalLength = ACPI_MAX64_DECIMAL_DIGITS; 352138287Smarks break; 353138287Smarks } 354138287Smarks 355138287Smarks SupressZeros = TRUE; /* No leading zeros */ 35684491Smsmith Remainder = 0; 357138287Smarks 358138287Smarks for (i = DecimalLength; i > 0; i--) 35982367Smsmith { 36082367Smsmith /* Divide by nth factor of 10 */ 36182367Smsmith 36282367Smsmith Digit = Integer; 363126372Snjl for (j = 0; j < i; j++) 36482367Smsmith { 365138287Smarks (void) AcpiUtShortDivide (Digit, 10, &Digit, &Remainder); 36682367Smsmith } 36782367Smsmith 368138287Smarks /* Handle leading zeros */ 36982367Smsmith 370126372Snjl if (Remainder != 0) 37182367Smsmith { 372138287Smarks SupressZeros = FALSE; 37382367Smsmith } 37482367Smsmith 375138287Smarks if (!SupressZeros) 37682367Smsmith { 37791116Smsmith String[k] = (UINT8) (ACPI_ASCII_ZERO + Remainder); 37882367Smsmith k++; 37982367Smsmith } 38082367Smsmith } 38182367Smsmith break; 38282367Smsmith 38382367Smsmith case 16: 38482367Smsmith 385151937Sjkim /* HexLength: 2 ascii hex chars per data byte */ 38682367Smsmith 387193267Sjkim HexLength = ACPI_MUL_2 (DataWidth); 388138287Smarks for (i = 0, j = (HexLength-1); i < HexLength; i++, j--) 38982367Smsmith { 390138287Smarks /* Get one hex digit, most significant digits first */ 39182367Smsmith 392306536Sjkim String[k] = (UINT8) 393306536Sjkim AcpiUtHexToAsciiChar (Integer, ACPI_MUL_4 (j)); 394138287Smarks k++; 39582367Smsmith } 39682367Smsmith break; 39782367Smsmith 39882367Smsmith default: 399138287Smarks return (0); 40082367Smsmith } 40182367Smsmith 40282367Smsmith /* 403193267Sjkim * Since leading zeros are suppressed, we must check for the case where 404126372Snjl * the integer equals 0 40582367Smsmith * 40682367Smsmith * Finally, null terminate the string and return the length 40782367Smsmith */ 40882367Smsmith if (!k) 40982367Smsmith { 41091116Smsmith String [0] = ACPI_ASCII_ZERO; 41182367Smsmith k = 1; 41282367Smsmith } 413114237Snjl 41482367Smsmith String [k] = 0; 415138287Smarks return ((UINT32) k); 41682367Smsmith} 41782367Smsmith 41882367Smsmith 41982367Smsmith/******************************************************************************* 42082367Smsmith * 42177424Smsmith * FUNCTION: AcpiExConvertToString 42271867Smsmith * 423193267Sjkim * PARAMETERS: ObjDesc - Object to be converted. Must be an 424138287Smarks * Integer, Buffer, or String 425126372Snjl * ResultDesc - Where the string object is returned 426138287Smarks * Type - String flags (base and conversion type) 42771867Smsmith * 42871867Smsmith * RETURN: Status 42971867Smsmith * 43071867Smsmith * DESCRIPTION: Convert an ACPI Object to a string 43171867Smsmith * 43271867Smsmith ******************************************************************************/ 43371867Smsmith 43471867SmsmithACPI_STATUS 43577424SmsmithAcpiExConvertToString ( 43680062Smsmith ACPI_OPERAND_OBJECT *ObjDesc, 43780062Smsmith ACPI_OPERAND_OBJECT **ResultDesc, 438138287Smarks UINT32 Type) 43971867Smsmith{ 440138287Smarks ACPI_OPERAND_OBJECT *ReturnDesc; 44171867Smsmith UINT8 *NewBuf; 442151937Sjkim UINT32 i; 443138287Smarks UINT32 StringLength = 0; 444138287Smarks UINT16 Base = 16; 445138287Smarks UINT8 Separator = ','; 44671867Smsmith 44771867Smsmith 448167802Sjkim ACPI_FUNCTION_TRACE_PTR (ExConvertToString, ObjDesc); 44980062Smsmith 45083174Smsmith 451193267Sjkim switch (ObjDesc->Common.Type) 45271867Smsmith { 453107325Siwasaki case ACPI_TYPE_STRING: 454107325Siwasaki 455138287Smarks /* No conversion necessary */ 456107325Siwasaki 457138287Smarks *ResultDesc = ObjDesc; 458138287Smarks return_ACPI_STATUS (AE_OK); 459107325Siwasaki 46071867Smsmith case ACPI_TYPE_INTEGER: 46171867Smsmith 462138287Smarks switch (Type) 46382367Smsmith { 464138287Smarks case ACPI_EXPLICIT_CONVERT_DECIMAL: 465138287Smarks 466138287Smarks /* Make room for maximum decimal number */ 467138287Smarks 46882367Smsmith StringLength = ACPI_MAX_DECIMAL_DIGITS; 469138287Smarks Base = 10; 470138287Smarks break; 471138287Smarks 472138287Smarks default: 473138287Smarks 474138287Smarks /* Two hex string characters for each integer byte */ 475138287Smarks 476138287Smarks StringLength = ACPI_MUL_2 (AcpiGbl_IntegerByteWidth); 477138287Smarks break; 47882367Smsmith } 47982367Smsmith 48082367Smsmith /* 48182367Smsmith * Create a new String 482138287Smarks * Need enough space for one ASCII integer (plus null terminator) 48382367Smsmith */ 484138287Smarks ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength); 485138287Smarks if (!ReturnDesc) 48682367Smsmith { 48791116Smsmith return_ACPI_STATUS (AE_NO_MEMORY); 48882367Smsmith } 48982367Smsmith 490138287Smarks NewBuf = ReturnDesc->Buffer.Pointer; 49171867Smsmith 492138287Smarks /* Convert integer to string */ 49371867Smsmith 494306536Sjkim StringLength = AcpiExConvertToAscii ( 495306536Sjkim ObjDesc->Integer.Value, Base, NewBuf, AcpiGbl_IntegerByteWidth); 49671867Smsmith 49780062Smsmith /* Null terminate at the correct place */ 49871867Smsmith 499138287Smarks ReturnDesc->String.Length = StringLength; 500138287Smarks NewBuf [StringLength] = 0; 50180062Smsmith break; 50271867Smsmith 50371867Smsmith case ACPI_TYPE_BUFFER: 50471867Smsmith 505151937Sjkim /* Setup string length, base, and separator */ 506151937Sjkim 507138287Smarks switch (Type) 50882367Smsmith { 509151937Sjkim case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by ToDecimalString */ 510138287Smarks /* 511138287Smarks * From ACPI: "If Data is a buffer, it is converted to a string of 512138287Smarks * decimal values separated by commas." 513138287Smarks */ 514138287Smarks Base = 10; 515114237Snjl 516151937Sjkim /* 517193267Sjkim * Calculate the final string length. Individual string values 518151937Sjkim * are variable length (include separator for each) 519151937Sjkim */ 520151937Sjkim for (i = 0; i < ObjDesc->Buffer.Length; i++) 521151937Sjkim { 522151937Sjkim if (ObjDesc->Buffer.Pointer[i] >= 100) 523151937Sjkim { 524151937Sjkim StringLength += 4; 525151937Sjkim } 526151937Sjkim else if (ObjDesc->Buffer.Pointer[i] >= 10) 527151937Sjkim { 528151937Sjkim StringLength += 3; 529151937Sjkim } 530151937Sjkim else 531151937Sjkim { 532151937Sjkim StringLength += 2; 533151937Sjkim } 534151937Sjkim } 535151937Sjkim break; 536138287Smarks 537138287Smarks case ACPI_IMPLICIT_CONVERT_HEX: 538138287Smarks /* 539138287Smarks * From the ACPI spec: 540138287Smarks *"The entire contents of the buffer are converted to a string of 541138287Smarks * two-character hexadecimal numbers, each separated by a space." 542138287Smarks */ 543151937Sjkim Separator = ' '; 544151937Sjkim StringLength = (ObjDesc->Buffer.Length * 3); 545151937Sjkim break; 54680062Smsmith 547151937Sjkim case ACPI_EXPLICIT_CONVERT_HEX: /* Used by ToHexString */ 548138287Smarks /* 549138287Smarks * From ACPI: "If Data is a buffer, it is converted to a string of 550138287Smarks * hexadecimal values separated by commas." 551138287Smarks */ 552151937Sjkim StringLength = (ObjDesc->Buffer.Length * 3); 553151937Sjkim break; 55471867Smsmith 555151937Sjkim default: 556151937Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 557151937Sjkim } 55871867Smsmith 559151937Sjkim /* 560167802Sjkim * Create a new string object and string buffer 561151937Sjkim * (-1 because of extra separator included in StringLength from above) 562193267Sjkim * Allow creation of zero-length strings from zero-length buffers. 563151937Sjkim */ 564193267Sjkim if (StringLength) 565193267Sjkim { 566193267Sjkim StringLength--; 567193267Sjkim } 568193267Sjkim 569193267Sjkim ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength); 570151937Sjkim if (!ReturnDesc) 571151937Sjkim { 572151937Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 573151937Sjkim } 57471867Smsmith 575151937Sjkim NewBuf = ReturnDesc->Buffer.Pointer; 57682367Smsmith 577151937Sjkim /* 578151937Sjkim * Convert buffer bytes to hex or decimal values 579151937Sjkim * (separated by commas or spaces) 580151937Sjkim */ 581151937Sjkim for (i = 0; i < ObjDesc->Buffer.Length; i++) 582151937Sjkim { 583151937Sjkim NewBuf += AcpiExConvertToAscii ( 584306536Sjkim (UINT64) ObjDesc->Buffer.Pointer[i], Base, NewBuf, 1); 585151937Sjkim *NewBuf++ = Separator; /* each separated by a comma or space */ 586151937Sjkim } 58771867Smsmith 588151937Sjkim /* 589151937Sjkim * Null terminate the string 590151937Sjkim * (overwrites final comma/space from above) 591151937Sjkim */ 592193267Sjkim if (ObjDesc->Buffer.Length) 593193267Sjkim { 594193267Sjkim NewBuf--; 595193267Sjkim } 596151937Sjkim *NewBuf = 0; 59771867Smsmith break; 59871867Smsmith 599107325Siwasaki default: 600250838Sjkim 601107325Siwasaki return_ACPI_STATUS (AE_TYPE); 602107325Siwasaki } 60380062Smsmith 604138287Smarks *ResultDesc = ReturnDesc; 60591116Smsmith return_ACPI_STATUS (AE_OK); 60671867Smsmith} 60771867Smsmith 60871867Smsmith 60977424Smsmith/******************************************************************************* 61077424Smsmith * 61177424Smsmith * FUNCTION: AcpiExConvertToTargetType 61277424Smsmith * 61391116Smsmith * PARAMETERS: DestinationType - Current type of the destination 61491116Smsmith * SourceDesc - Source object to be converted. 615126372Snjl * ResultDesc - Where the converted object is returned 61691116Smsmith * WalkState - Current method state 61777424Smsmith * 61877424Smsmith * RETURN: Status 61977424Smsmith * 62091116Smsmith * DESCRIPTION: Implements "implicit conversion" rules for storing an object. 62177424Smsmith * 62277424Smsmith ******************************************************************************/ 62377424Smsmith 62477424SmsmithACPI_STATUS 62577424SmsmithAcpiExConvertToTargetType ( 62691116Smsmith ACPI_OBJECT_TYPE DestinationType, 62791116Smsmith ACPI_OPERAND_OBJECT *SourceDesc, 62891116Smsmith ACPI_OPERAND_OBJECT **ResultDesc, 62977424Smsmith ACPI_WALK_STATE *WalkState) 63077424Smsmith{ 63177424Smsmith ACPI_STATUS Status = AE_OK; 63277424Smsmith 63377424Smsmith 634167802Sjkim ACPI_FUNCTION_TRACE (ExConvertToTargetType); 63577424Smsmith 63677424Smsmith 63791116Smsmith /* Default behavior */ 63891116Smsmith 63991116Smsmith *ResultDesc = SourceDesc; 64091116Smsmith 64177424Smsmith /* 64277424Smsmith * If required by the target, 64377424Smsmith * perform implicit conversion on the source before we store it. 64477424Smsmith */ 64577424Smsmith switch (GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs)) 64677424Smsmith { 64777424Smsmith case ARGI_SIMPLE_TARGET: 64877424Smsmith case ARGI_FIXED_TARGET: 64977424Smsmith case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */ 65077424Smsmith 65177424Smsmith switch (DestinationType) 65277424Smsmith { 653107325Siwasaki case ACPI_TYPE_LOCAL_REGION_FIELD: 65477424Smsmith /* 65577424Smsmith * Named field can always handle conversions 65677424Smsmith */ 65777424Smsmith break; 65877424Smsmith 65977424Smsmith default: 660250838Sjkim 66177424Smsmith /* No conversion allowed for these types */ 66277424Smsmith 663193267Sjkim if (DestinationType != SourceDesc->Common.Type) 66477424Smsmith { 665104470Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 666104470Siwasaki "Explicit operator, will store (%s) over existing type (%s)\n", 66799679Siwasaki AcpiUtGetObjectTypeName (SourceDesc), 66877424Smsmith AcpiUtGetTypeName (DestinationType))); 66977424Smsmith Status = AE_TYPE; 67077424Smsmith } 67177424Smsmith } 67277424Smsmith break; 67377424Smsmith 67477424Smsmith case ARGI_TARGETREF: 675306536Sjkim case ARGI_STORE_TARGET: 67677424Smsmith 67777424Smsmith switch (DestinationType) 67877424Smsmith { 67977424Smsmith case ACPI_TYPE_INTEGER: 68077424Smsmith case ACPI_TYPE_BUFFER_FIELD: 681107325Siwasaki case ACPI_TYPE_LOCAL_BANK_FIELD: 682107325Siwasaki case ACPI_TYPE_LOCAL_INDEX_FIELD: 68377424Smsmith /* 684193267Sjkim * These types require an Integer operand. We can convert 68577424Smsmith * a Buffer or a String to an Integer if necessary. 68677424Smsmith */ 687306536Sjkim Status = AcpiExConvertToInteger (SourceDesc, ResultDesc, 16); 68877424Smsmith break; 68977424Smsmith 69077424Smsmith case ACPI_TYPE_STRING: 69177424Smsmith /* 692193267Sjkim * The operand must be a String. We can convert an 69377424Smsmith * Integer or Buffer if necessary 69477424Smsmith */ 695138287Smarks Status = AcpiExConvertToString (SourceDesc, ResultDesc, 696306536Sjkim ACPI_IMPLICIT_CONVERT_HEX); 69777424Smsmith break; 69877424Smsmith 69977424Smsmith case ACPI_TYPE_BUFFER: 70077424Smsmith /* 701193267Sjkim * The operand must be a Buffer. We can convert an 70291116Smsmith * Integer or String if necessary 70377424Smsmith */ 704138287Smarks Status = AcpiExConvertToBuffer (SourceDesc, ResultDesc); 70577424Smsmith break; 70699679Siwasaki 707250838Sjkim default: 70899679Siwasaki 709306536Sjkim ACPI_ERROR ((AE_INFO, 710306536Sjkim "Bad destination type during conversion: 0x%X", 711126372Snjl DestinationType)); 71299679Siwasaki Status = AE_AML_INTERNAL; 71399679Siwasaki break; 71477424Smsmith } 71577424Smsmith break; 71677424Smsmith 71777424Smsmith case ARGI_REFERENCE: 71877424Smsmith /* 71977424Smsmith * CreateXxxxField cases - we are storing the field object into the name 72077424Smsmith */ 72177424Smsmith break; 72277424Smsmith 723250838Sjkim default: 72477424Smsmith 725167802Sjkim ACPI_ERROR ((AE_INFO, 726204773Sjkim "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s", 72777424Smsmith GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs), 728167802Sjkim WalkState->Opcode, AcpiUtGetTypeName (DestinationType))); 72977424Smsmith Status = AE_AML_INTERNAL; 73077424Smsmith } 73177424Smsmith 73277424Smsmith /* 73377424Smsmith * Source-to-Target conversion semantics: 73477424Smsmith * 73577424Smsmith * If conversion to the target type cannot be performed, then simply 73677424Smsmith * overwrite the target with the new object and type. 73777424Smsmith */ 73877424Smsmith if (Status == AE_TYPE) 73977424Smsmith { 74077424Smsmith Status = AE_OK; 74177424Smsmith } 74277424Smsmith 74377424Smsmith return_ACPI_STATUS (Status); 74477424Smsmith} 745