diff options
Diffstat (limited to 'sys/contrib/dev/acpica/exconvrt.c')
-rw-r--r-- | sys/contrib/dev/acpica/exconvrt.c | 402 |
1 files changed, 182 insertions, 220 deletions
diff --git a/sys/contrib/dev/acpica/exconvrt.c b/sys/contrib/dev/acpica/exconvrt.c index 42ca183..fd3854a 100644 --- a/sys/contrib/dev/acpica/exconvrt.c +++ b/sys/contrib/dev/acpica/exconvrt.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: exconvrt - Object conversion routines - * $Revision: 53 $ + * $Revision: 59 $ * *****************************************************************************/ @@ -133,7 +133,7 @@ * PARAMETERS: ObjDesc - Object to be converted. Must be an * Integer, Buffer, or String * ResultDesc - Where the new Integer object is returned - * WalkState - Current method state + * Flags - Used for string conversion * * RETURN: Status * @@ -145,13 +145,13 @@ ACPI_STATUS AcpiExConvertToInteger ( ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ResultDesc, - ACPI_WALK_STATE *WalkState) + UINT32 Flags) { - UINT32 i; - ACPI_OPERAND_OBJECT *RetDesc; - UINT32 Count; + ACPI_OPERAND_OBJECT *ReturnDesc; UINT8 *Pointer; ACPI_INTEGER Result; + UINT32 i; + UINT32 Count; ACPI_STATUS Status; @@ -161,15 +161,17 @@ AcpiExConvertToInteger ( switch (ACPI_GET_OBJECT_TYPE (ObjDesc)) { case ACPI_TYPE_INTEGER: + + /* No conversion necessary */ + *ResultDesc = ObjDesc; return_ACPI_STATUS (AE_OK); + case ACPI_TYPE_BUFFER: case ACPI_TYPE_STRING: - Pointer = (UINT8 *) ObjDesc->String.Pointer; - Count = ObjDesc->String.Length; - break; - case ACPI_TYPE_BUFFER: + /* Note: Takes advantage of common buffer/string fields */ + Pointer = ObjDesc->Buffer.Pointer; Count = ObjDesc->Buffer.Length; break; @@ -189,13 +191,6 @@ AcpiExConvertToInteger ( */ Result = 0; - /* Transfer no more than an integer's worth of data */ - - if (Count > AcpiGbl_IntegerByteWidth) - { - Count = AcpiGbl_IntegerByteWidth; - } - /* * String conversion is different than Buffer conversion */ @@ -204,10 +199,12 @@ AcpiExConvertToInteger ( case ACPI_TYPE_STRING: /* - * Convert string to an integer - * String must be hexadecimal as per the ACPI specification + * Convert string to an integer - for most cases, the string must be + * hexadecimal as per the ACPI specification. The only exception (as + * of ACPI 3.0) is that the ToInteger() operator allows both decimal + * and hexadecimal strings (hex prefixed with "0x"). */ - Status = AcpiUtStrtoul64 ((char *) Pointer, 16, &Result); + Status = AcpiUtStrtoul64 ((char *) Pointer, Flags, &Result); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); @@ -217,9 +214,16 @@ AcpiExConvertToInteger ( case ACPI_TYPE_BUFFER: + /* Transfer no more than an integer's worth of data */ + + if (Count > AcpiGbl_IntegerByteWidth) + { + Count = AcpiGbl_IntegerByteWidth; + } + /* - * Buffer conversion - we simply grab enough raw data from the - * buffer to fill an integer + * Convert buffer to an integer - we simply grab enough raw data + * from the buffer to fill an integer */ for (i = 0; i < Count; i++) { @@ -241,30 +245,17 @@ AcpiExConvertToInteger ( /* * Create a new integer */ - RetDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); - if (!RetDesc) + ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + if (!ReturnDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Save the Result */ - RetDesc->Integer.Value = Result; - - /* - * If we are about to overwrite the original object on the operand stack, - * we must remove a reference on the original object because we are - * essentially removing it from the stack. - */ - if (*ResultDesc == ObjDesc) - { - if (WalkState->Opcode != AML_STORE_OP) - { - AcpiUtRemoveReference (ObjDesc); - } - } - - *ResultDesc = RetDesc; + ReturnDesc->Integer.Value = Result; + AcpiExTruncateFor32bitTable (ReturnDesc); + *ResultDesc = ReturnDesc; return_ACPI_STATUS (AE_OK); } @@ -276,7 +267,6 @@ AcpiExConvertToInteger ( * PARAMETERS: ObjDesc - Object to be converted. Must be an * Integer, Buffer, or String * ResultDesc - Where the new buffer object is returned - * WalkState - Current method state * * RETURN: Status * @@ -287,11 +277,9 @@ AcpiExConvertToInteger ( ACPI_STATUS AcpiExConvertToBuffer ( ACPI_OPERAND_OBJECT *ObjDesc, - ACPI_OPERAND_OBJECT **ResultDesc, - ACPI_WALK_STATE *WalkState) + ACPI_OPERAND_OBJECT **ResultDesc) { - ACPI_OPERAND_OBJECT *RetDesc; - UINT32 i; + ACPI_OPERAND_OBJECT *ReturnDesc; UINT8 *NewBuf; @@ -314,19 +302,18 @@ AcpiExConvertToBuffer ( * Create a new Buffer object. * Need enough space for one integer */ - RetDesc = AcpiUtCreateBufferObject (AcpiGbl_IntegerByteWidth); - if (!RetDesc) + ReturnDesc = AcpiUtCreateBufferObject (AcpiGbl_IntegerByteWidth); + if (!ReturnDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } - /* Copy the integer to the buffer */ + /* Copy the integer to the buffer, LSB first */ - NewBuf = RetDesc->Buffer.Pointer; - for (i = 0; i < AcpiGbl_IntegerByteWidth; i++) - { - NewBuf[i] = (UINT8) (ObjDesc->Integer.Value >> (i * 8)); - } + NewBuf = ReturnDesc->Buffer.Pointer; + ACPI_MEMCPY (NewBuf, + &ObjDesc->Integer.Value, + AcpiGbl_IntegerByteWidth); break; @@ -336,15 +323,15 @@ AcpiExConvertToBuffer ( * Create a new Buffer object * Size will be the string length */ - RetDesc = AcpiUtCreateBufferObject ((ACPI_SIZE) ObjDesc->String.Length); - if (!RetDesc) + ReturnDesc = AcpiUtCreateBufferObject ((ACPI_SIZE) ObjDesc->String.Length); + if (!ReturnDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Copy the string to the buffer */ - NewBuf = RetDesc->Buffer.Pointer; + NewBuf = ReturnDesc->Buffer.Pointer; ACPI_STRNCPY ((char *) NewBuf, (char *) ObjDesc->String.Pointer, ObjDesc->String.Length); break; @@ -356,34 +343,20 @@ AcpiExConvertToBuffer ( /* Mark buffer initialized */ - RetDesc->Common.Flags |= AOPOBJ_DATA_VALID; - - /* - * If we are about to overwrite the original object on the operand stack, - * we must remove a reference on the original object because we are - * essentially removing it from the stack. - */ - if (*ResultDesc == ObjDesc) - { - if (WalkState->Opcode != AML_STORE_OP) - { - AcpiUtRemoveReference (ObjDesc); - } - } - - *ResultDesc = RetDesc; + ReturnDesc->Common.Flags |= AOPOBJ_DATA_VALID; + *ResultDesc = ReturnDesc; return_ACPI_STATUS (AE_OK); } /******************************************************************************* * - * FUNCTION: AcpiExConvertAscii + * FUNCTION: AcpiExConvertToAscii * * PARAMETERS: Integer - Value to be converted - * Base - 10 or 16 + * Base - ACPI_STRING_DECIMAL or ACPI_STRING_HEX * String - Where the string is returned - * DataWidth - Size of data item to be converted + * DataWidth - Size of data item to be converted, in bytes * * RETURN: Actual string length * @@ -394,57 +367,66 @@ AcpiExConvertToBuffer ( UINT32 AcpiExConvertToAscii ( ACPI_INTEGER Integer, - UINT32 Base, + UINT16 Base, UINT8 *String, UINT8 DataWidth) { - UINT32 i; - UINT32 j; - UINT32 k = 0; - char HexDigit; ACPI_INTEGER Digit; + ACPI_NATIVE_UINT i; + ACPI_NATIVE_UINT j; + ACPI_NATIVE_UINT k = 0; + ACPI_NATIVE_UINT HexLength; + ACPI_NATIVE_UINT DecimalLength; UINT32 Remainder; - UINT32 Length; - BOOLEAN LeadingZero; + BOOLEAN SupressZeros; ACPI_FUNCTION_ENTRY (); - if (DataWidth < sizeof (ACPI_INTEGER)) - { - LeadingZero = FALSE; - Length = DataWidth; - } - else - { - LeadingZero = TRUE; - Length = sizeof (ACPI_INTEGER); - } - switch (Base) { case 10: + /* Setup max length for the decimal number */ + + switch (DataWidth) + { + case 1: + DecimalLength = ACPI_MAX8_DECIMAL_DIGITS; + break; + + case 4: + DecimalLength = ACPI_MAX32_DECIMAL_DIGITS; + break; + + case 8: + default: + DecimalLength = ACPI_MAX64_DECIMAL_DIGITS; + break; + } + + SupressZeros = TRUE; /* No leading zeros */ Remainder = 0; - for (i = ACPI_MAX_DECIMAL_DIGITS; i > 0; i--) + + for (i = DecimalLength; i > 0; i--) { /* Divide by nth factor of 10 */ Digit = Integer; for (j = 0; j < i; j++) { - (void) AcpiUtShortDivide (&Digit, 10, &Digit, &Remainder); + (void) AcpiUtShortDivide (Digit, 10, &Digit, &Remainder); } - /* Create the decimal digit */ + /* Handle leading zeros */ if (Remainder != 0) { - LeadingZero = FALSE; + SupressZeros = FALSE; } - if (!LeadingZero) + if (!SupressZeros) { String[k] = (UINT8) (ACPI_ASCII_ZERO + Remainder); k++; @@ -452,31 +434,21 @@ AcpiExConvertToAscii ( } break; - case 16: - /* Copy the integer to the buffer */ + HexLength = ACPI_MUL_2 (DataWidth); /* 2 ascii hex chars per data byte */ - for (i = 0, j = ((Length * 2) -1); i < (Length * 2); i++, j--) + for (i = 0, j = (HexLength-1); i < HexLength; i++, j--) { + /* Get one hex digit, most significant digits first */ - HexDigit = AcpiUtHexToAsciiChar (Integer, (j * 4)); - if (HexDigit != ACPI_ASCII_ZERO) - { - LeadingZero = FALSE; - } - - if (!LeadingZero) - { - String[k] = (UINT8) HexDigit; - k++; - } + String[k] = (UINT8) AcpiUtHexToAsciiChar (Integer, ACPI_MUL_4 (j)); + k++; } break; - default: - break; + return (0); } /* @@ -492,7 +464,7 @@ AcpiExConvertToAscii ( } String [k] = 0; - return (k); + return ((UINT32) k); } @@ -501,11 +473,9 @@ AcpiExConvertToAscii ( * FUNCTION: AcpiExConvertToString * * PARAMETERS: ObjDesc - Object to be converted. Must be an - * Integer, Buffer, or String + * Integer, Buffer, or String * ResultDesc - Where the string object is returned - * Base - 10 or 16 - * MaxLength - Max length of the returned string - * WalkState - Current method state + * Type - String flags (base and conversion type) * * RETURN: Status * @@ -517,15 +487,14 @@ ACPI_STATUS AcpiExConvertToString ( ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ResultDesc, - UINT32 Base, - UINT32 MaxLength, - ACPI_WALK_STATE *WalkState) + UINT32 Type) { - ACPI_OPERAND_OBJECT *RetDesc; + ACPI_OPERAND_OBJECT *ReturnDesc; UINT8 *NewBuf; - UINT8 *Pointer; - UINT32 StringLength; + UINT32 StringLength = 0; + UINT16 Base = 16; UINT32 i; + UINT8 Separator = ','; ACPI_FUNCTION_TRACE_PTR ("ExConvertToString", ObjDesc); @@ -535,146 +504,137 @@ AcpiExConvertToString ( { case ACPI_TYPE_STRING: - if (MaxLength >= ObjDesc->String.Length) - { - *ResultDesc = ObjDesc; - return_ACPI_STATUS (AE_OK); - } - else - { - /* Must copy the string first and then truncate it */ + /* No conversion necessary */ - return_ACPI_STATUS (AE_NOT_IMPLEMENTED); - } + *ResultDesc = ObjDesc; + return_ACPI_STATUS (AE_OK); case ACPI_TYPE_INTEGER: - StringLength = AcpiGbl_IntegerByteWidth * 2; - if (Base == 10) + switch (Type) { + case ACPI_EXPLICIT_CONVERT_DECIMAL: + + /* Make room for maximum decimal number */ + StringLength = ACPI_MAX_DECIMAL_DIGITS; + Base = 10; + break; + + default: + + /* Two hex string characters for each integer byte */ + + StringLength = ACPI_MUL_2 (AcpiGbl_IntegerByteWidth); + break; } /* * Create a new String + * Need enough space for one ASCII integer (plus null terminator) */ - RetDesc = AcpiUtCreateInternalObject (ACPI_TYPE_STRING); - if (!RetDesc) + ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength); + if (!ReturnDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } - /* Need enough space for one ASCII integer plus null terminator */ - - NewBuf = ACPI_MEM_CALLOCATE ((ACPI_SIZE) StringLength + 1); - if (!NewBuf) - { - ACPI_REPORT_ERROR - (("ExConvertToString: Buffer allocation failure\n")); - AcpiUtRemoveReference (RetDesc); - return_ACPI_STATUS (AE_NO_MEMORY); - } + NewBuf = ReturnDesc->Buffer.Pointer; - /* Convert */ + /* Convert integer to string */ - i = AcpiExConvertToAscii (ObjDesc->Integer.Value, Base, NewBuf, sizeof (ACPI_INTEGER)); + StringLength = AcpiExConvertToAscii (ObjDesc->Integer.Value, Base, + NewBuf, AcpiGbl_IntegerByteWidth); /* Null terminate at the correct place */ - if (MaxLength < i) - { - NewBuf[MaxLength] = 0; - RetDesc->String.Length = MaxLength; - } - else - { - NewBuf [i] = 0; - RetDesc->String.Length = i; - } - - RetDesc->Buffer.Pointer = NewBuf; + ReturnDesc->String.Length = StringLength; + NewBuf [StringLength] = 0; break; case ACPI_TYPE_BUFFER: - /* Find the string length */ - - Pointer = ObjDesc->Buffer.Pointer; - for (StringLength = 0; StringLength < ObjDesc->Buffer.Length; StringLength++) + switch (Type) { - /* Exit on null terminator */ + case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by ToDecimalString operator */ + /* + * From ACPI: "If Data is a buffer, it is converted to a string of + * decimal values separated by commas." + */ + Base = 10; + StringLength = ObjDesc->Buffer.Length; /* 4 chars for each decimal */ - if (!Pointer[StringLength]) + /*lint -fallthrough */ + + case ACPI_IMPLICIT_CONVERT_HEX: + /* + * From the ACPI spec: + *"The entire contents of the buffer are converted to a string of + * two-character hexadecimal numbers, each separated by a space." + */ + if (Type == ACPI_IMPLICIT_CONVERT_HEX) { - break; + Separator = ' '; } - } - if (MaxLength > ACPI_MAX_STRING_CONVERSION) - { - if (StringLength > ACPI_MAX_STRING_CONVERSION) + /*lint -fallthrough */ + + case ACPI_EXPLICIT_CONVERT_HEX: /* Used by ToHexString operator */ + /* + * From ACPI: "If Data is a buffer, it is converted to a string of + * hexadecimal values separated by commas." + */ + StringLength += (ObjDesc->Buffer.Length * 3); + if (StringLength > ACPI_MAX_STRING_CONVERSION) /* ACPI limit */ { return_ACPI_STATUS (AE_AML_STRING_LIMIT); } - } - /* - * Create a new string object - */ - RetDesc = AcpiUtCreateInternalObject (ACPI_TYPE_STRING); - if (!RetDesc) - { - return_ACPI_STATUS (AE_NO_MEMORY); - } + /* Create a new string object and string buffer */ - /* String length is the lesser of the Max or the actual length */ + ReturnDesc = AcpiUtCreateStringObject ((ACPI_SIZE) StringLength -1); + if (!ReturnDesc) + { + return_ACPI_STATUS (AE_NO_MEMORY); + } - if (MaxLength < StringLength) - { - StringLength = MaxLength; - } + NewBuf = ReturnDesc->Buffer.Pointer; - NewBuf = ACPI_MEM_CALLOCATE ((ACPI_SIZE) StringLength + 1); - if (!NewBuf) - { - ACPI_REPORT_ERROR - (("ExConvertToString: Buffer allocation failure\n")); - AcpiUtRemoveReference (RetDesc); - return_ACPI_STATUS (AE_NO_MEMORY); - } + /* + * Convert buffer bytes to hex or decimal values + * (separated by commas) + */ + for (i = 0; i < ObjDesc->Buffer.Length; i++) + { + NewBuf += AcpiExConvertToAscii ( + (ACPI_INTEGER) ObjDesc->Buffer.Pointer[i], Base, + NewBuf, 1); + *NewBuf++ = Separator; /* each separated by a comma or space */ + } - /* Copy the appropriate number of buffer characters */ + /* Null terminate the string (overwrites final comma from above) */ - ACPI_MEMCPY (NewBuf, Pointer, StringLength); + NewBuf--; + *NewBuf = 0; - /* Null terminate */ + /* Recalculate length */ - NewBuf [StringLength] = 0; - RetDesc->Buffer.Pointer = NewBuf; - RetDesc->String.Length = StringLength; - break; + ReturnDesc->String.Length = (UINT32) + ACPI_STRLEN (ReturnDesc->String.Pointer); + break; + default: + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + break; default: return_ACPI_STATUS (AE_TYPE); } - /* - * If we are about to overwrite the original object on the operand stack, - * we must remove a reference on the original object because we are - * essentially removing it from the stack. - */ - if (*ResultDesc == ObjDesc) - { - if (WalkState->Opcode != AML_STORE_OP) - { - AcpiUtRemoveReference (ObjDesc); - } - } - - *ResultDesc = RetDesc; + *ResultDesc = ReturnDesc; return_ACPI_STATUS (AE_OK); } @@ -756,7 +716,8 @@ AcpiExConvertToTargetType ( * These types require an Integer operand. We can convert * a Buffer or a String to an Integer if necessary. */ - Status = AcpiExConvertToInteger (SourceDesc, ResultDesc, WalkState); + Status = AcpiExConvertToInteger (SourceDesc, ResultDesc, + 16); break; @@ -766,7 +727,8 @@ AcpiExConvertToTargetType ( * The operand must be a String. We can convert an * Integer or Buffer if necessary */ - Status = AcpiExConvertToString (SourceDesc, ResultDesc, 16, ACPI_UINT32_MAX, WalkState); + Status = AcpiExConvertToString (SourceDesc, ResultDesc, + ACPI_IMPLICIT_CONVERT_HEX); break; @@ -776,7 +738,7 @@ AcpiExConvertToTargetType ( * The operand must be a Buffer. We can convert an * Integer or String if necessary */ - Status = AcpiExConvertToBuffer (SourceDesc, ResultDesc, WalkState); + Status = AcpiExConvertToBuffer (SourceDesc, ResultDesc); break; |