Commit 8d7b2d68 authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] ACPICA 20040827 update from Bob Moore

Signed-off-by: default avatarLen Brown <len.brown@intel.com>

Implemented support for implicit object conversion in
the non-numeric logical operators (LEqual, LGreater,
LGreaterEqual, LLess, LLessEqual, and LNotEqual.) Any
combination of Integers/Strings/Buffers may now be used;
the second operand is implicitly converted on the fly to
match the type of the first operand.  For example:

LEqual (Source1, Source2)

Source1 and Source2 must each evaluate to an integer, a
string, or a buffer. The data type of Source1 dictates the
required type of Source2.  Source2 is implicitly converted
if necessary to match the type of Source1.

Updated and corrected the behavior of the string
conversion support.  The rules concerning conversion of
buffers to strings (according to the ACPI specification)
are as follows:

ToDecimalString - explicit byte-wise conversion of buffer
to string of decimal values (0-255) separated by commas.

ToHexString - explicit byte-wise conversion of buffer to
string of hex values (0-FF) separated by commas.

ToString - explicit byte-wise conversion of buffer to
string.  Byte-by-byte copy with no transform except NULL
terminated.  Any other implicit buffer-to-string conversion

byte-wise conversion of buffer to string of hex values
(0-FF) separated by spaces.

Fixed a problem in acpi_ns_get_pathname_length where the
returned length was one byte too short in the case of a
node in the root scope.  This could cause a fault during
debug output.
parent 66f57430
......@@ -639,7 +639,8 @@ acpi_ds_exec_end_op (
* conditional predicate
*/
if ((walk_state->control_state) &&
if ((ACPI_SUCCESS (status)) &&
(walk_state->control_state) &&
(walk_state->control_state->common.state ==
ACPI_CONTROL_PREDICATE_EXECUTING) &&
(walk_state->control_state->control.predicate_op == op)) {
......
......@@ -58,7 +58,7 @@
* PARAMETERS: obj_desc - Object to be converted. Must be an
* Integer, Buffer, or String
* result_desc - Where the new Integer object is returned
* walk_state - Current method state
* Opcode - AML opcode
*
* RETURN: Status
*
......@@ -70,13 +70,13 @@ acpi_status
acpi_ex_convert_to_integer (
union acpi_operand_object *obj_desc,
union acpi_operand_object **result_desc,
struct acpi_walk_state *walk_state)
u16 opcode)
{
u32 i;
union acpi_operand_object *ret_desc;
u32 count;
union acpi_operand_object *return_desc;
u8 *pointer;
acpi_integer result;
u32 i;
u32 count;
acpi_status status;
......@@ -85,15 +85,17 @@ acpi_ex_convert_to_integer (
switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
case ACPI_TYPE_INTEGER:
/* No conversion necessary */
*result_desc = obj_desc;
return_ACPI_STATUS (AE_OK);
case ACPI_TYPE_BUFFER:
case ACPI_TYPE_STRING:
pointer = (u8 *) obj_desc->string.pointer;
count = obj_desc->string.length;
break;
case ACPI_TYPE_BUFFER:
/* Note: Takes advantage of common buffer/string fields */
pointer = obj_desc->buffer.pointer;
count = obj_desc->buffer.length;
break;
......@@ -126,8 +128,8 @@ acpi_ex_convert_to_integer (
case ACPI_TYPE_STRING:
/*
* Convert string to an integer
* String must be hexadecimal as per the ACPI specification
* Convert string to an integer - the string must be hexadecimal
* as per the ACPI specification
*/
status = acpi_ut_strtoul64 ((char *) pointer, 16, &result);
if (ACPI_FAILURE (status)) {
......@@ -139,8 +141,8 @@ acpi_ex_convert_to_integer (
case ACPI_TYPE_BUFFER:
/*
* 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++) {
/*
......@@ -161,14 +163,14 @@ acpi_ex_convert_to_integer (
/*
* Create a new integer
*/
ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
if (!ret_desc) {
return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Save the Result */
ret_desc->integer.value = result;
return_desc->integer.value = result;
/*
* If we are about to overwrite the original object on the operand stack,
......@@ -176,12 +178,12 @@ acpi_ex_convert_to_integer (
* essentially removing it from the stack.
*/
if (*result_desc == obj_desc) {
if (walk_state->opcode != AML_STORE_OP) {
if (opcode != AML_STORE_OP) {
acpi_ut_remove_reference (obj_desc);
}
}
*result_desc = ret_desc;
*result_desc = return_desc;
return_ACPI_STATUS (AE_OK);
}
......@@ -193,7 +195,7 @@ acpi_ex_convert_to_integer (
* PARAMETERS: obj_desc - Object to be converted. Must be an
* Integer, Buffer, or String
* result_desc - Where the new buffer object is returned
* walk_state - Current method state
* Opcode - AML opcode
*
* RETURN: Status
*
......@@ -205,10 +207,9 @@ acpi_status
acpi_ex_convert_to_buffer (
union acpi_operand_object *obj_desc,
union acpi_operand_object **result_desc,
struct acpi_walk_state *walk_state)
u16 opcode)
{
union acpi_operand_object *ret_desc;
u32 i;
union acpi_operand_object *return_desc;
u8 *new_buf;
......@@ -230,17 +231,17 @@ acpi_ex_convert_to_buffer (
* Create a new Buffer object.
* Need enough space for one integer
*/
ret_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width);
if (!ret_desc) {
return_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width);
if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Copy the integer to the buffer */
/* Copy the integer to the buffer, LSB first */
new_buf = ret_desc->buffer.pointer;
for (i = 0; i < acpi_gbl_integer_byte_width; i++) {
new_buf[i] = (u8) (obj_desc->integer.value >> (i * 8));
}
new_buf = return_desc->buffer.pointer;
ACPI_MEMCPY (new_buf,
&obj_desc->integer.value,
acpi_gbl_integer_byte_width);
break;
......@@ -250,14 +251,14 @@ acpi_ex_convert_to_buffer (
* Create a new Buffer object
* Size will be the string length
*/
ret_desc = acpi_ut_create_buffer_object ((acpi_size) obj_desc->string.length);
if (!ret_desc) {
return_desc = acpi_ut_create_buffer_object ((acpi_size) obj_desc->string.length);
if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Copy the string to the buffer */
new_buf = ret_desc->buffer.pointer;
new_buf = return_desc->buffer.pointer;
ACPI_STRNCPY ((char *) new_buf, (char *) obj_desc->string.pointer,
obj_desc->string.length);
break;
......@@ -269,7 +270,7 @@ acpi_ex_convert_to_buffer (
/* Mark buffer initialized */
ret_desc->common.flags |= AOPOBJ_DATA_VALID;
return_desc->common.flags |= AOPOBJ_DATA_VALID;
/*
* If we are about to overwrite the original object on the operand stack,
......@@ -277,24 +278,24 @@ acpi_ex_convert_to_buffer (
* essentially removing it from the stack.
*/
if (*result_desc == obj_desc) {
if (walk_state->opcode != AML_STORE_OP) {
if (opcode != AML_STORE_OP) {
acpi_ut_remove_reference (obj_desc);
}
}
*result_desc = ret_desc;
*result_desc = return_desc;
return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: acpi_ex_convert_ascii
* FUNCTION: acpi_ex_convert_to_ascii
*
* PARAMETERS: Integer - Value to be converted
* Base - 10 or 16
* Base - ACPI_STRING_DECIMAL or ACPI_STRING_HEX
* String - Where the string is returned
* data_width - Size of data item to be converted
* data_width - Size of data item to be converted, in bytes
*
* RETURN: Actual string length
*
......@@ -305,37 +306,47 @@ acpi_ex_convert_to_buffer (
u32
acpi_ex_convert_to_ascii (
acpi_integer integer,
u32 base,
u16 base,
u8 *string,
u8 data_width)
{
u32 i;
u32 j;
u32 k = 0;
char hex_digit;
acpi_integer digit;
acpi_native_uint i;
acpi_native_uint j;
acpi_native_uint k = 0;
acpi_native_uint hex_length;
acpi_native_uint decimal_length;
u32 remainder;
u32 length;
u8 leading_zero;
u8 supress_zeros;
ACPI_FUNCTION_ENTRY ();
if (data_width < sizeof (acpi_integer)) {
leading_zero = FALSE;
length = data_width;
}
else {
leading_zero = TRUE;
length = sizeof (acpi_integer);
}
switch (base) {
case 10:
/* Setup max length for the decimal number */
switch (data_width) {
case 1:
decimal_length = ACPI_MAX8_DECIMAL_DIGITS;
break;
case 4:
decimal_length = ACPI_MAX32_DECIMAL_DIGITS;
break;
case 8:
default:
decimal_length = ACPI_MAX64_DECIMAL_DIGITS;
break;
}
supress_zeros = TRUE; /* No leading zeros */
remainder = 0;
for (i = ACPI_MAX_DECIMAL_DIGITS; i > 0; i--) {
for (i = decimal_length; i > 0; i--) {
/* Divide by nth factor of 10 */
digit = integer;
......@@ -343,41 +354,33 @@ acpi_ex_convert_to_ascii (
(void) acpi_ut_short_divide (&digit, 10, &digit, &remainder);
}
/* Create the decimal digit */
/* Handle leading zeros */
if (remainder != 0) {
leading_zero = FALSE;
supress_zeros = FALSE;
}
if (!leading_zero) {
if (!supress_zeros) {
string[k] = (u8) (ACPI_ASCII_ZERO + remainder);
k++;
}
}
break;
case 16:
/* Copy the integer to the buffer */
hex_length = ACPI_MUL_2 (data_width); /* 2 ascii hex chars per data byte */
for (i = 0, j = ((length * 2) -1); i < (length * 2); i++, j--) {
hex_digit = acpi_ut_hex_to_ascii_char (integer, (j * 4));
if (hex_digit != ACPI_ASCII_ZERO) {
leading_zero = FALSE;
}
for (i = 0, j = (hex_length-1); i < hex_length; i++, j--) {
/* Get one hex digit, most significant digits first */
if (!leading_zero) {
string[k] = (u8) hex_digit;
k++;
}
string[k] = (u8) acpi_ut_hex_to_ascii_char (integer, ACPI_MUL_4 (j));
k++;
}
break;
default:
break;
return (0);
}
/*
......@@ -392,7 +395,7 @@ acpi_ex_convert_to_ascii (
}
string [k] = 0;
return (k);
return ((u32) k);
}
......@@ -401,11 +404,10 @@ acpi_ex_convert_to_ascii (
* FUNCTION: acpi_ex_convert_to_string
*
* PARAMETERS: obj_desc - Object to be converted. Must be an
* Integer, Buffer, or String
* Integer, Buffer, or String
* result_desc - Where the string object is returned
* Base - 10 or 16
* max_length - Max length of the returned string
* walk_state - Current method state
* Type - String flags (base and conversion type)
* Opcode - AML opcode
*
* RETURN: Status
*
......@@ -417,15 +419,15 @@ acpi_status
acpi_ex_convert_to_string (
union acpi_operand_object *obj_desc,
union acpi_operand_object **result_desc,
u32 base,
u32 max_length,
struct acpi_walk_state *walk_state)
u32 type,
u16 opcode)
{
union acpi_operand_object *ret_desc;
union acpi_operand_object *return_desc;
u8 *new_buf;
u8 *pointer;
u32 string_length;
u32 string_length = 0;
u16 base = 16;
u32 i;
u8 separator = ',';
ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_string", obj_desc);
......@@ -434,114 +436,117 @@ acpi_ex_convert_to_string (
switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
case ACPI_TYPE_STRING:
if (max_length >= obj_desc->string.length) {
*result_desc = obj_desc;
return_ACPI_STATUS (AE_OK);
}
else {
/* Must copy the string first and then truncate it */
/* No conversion necessary */
return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
}
*result_desc = obj_desc;
return_ACPI_STATUS (AE_OK);
case ACPI_TYPE_INTEGER:
string_length = acpi_gbl_integer_byte_width * 2;
if (base == 10) {
switch (type) {
case ACPI_EXPLICIT_CONVERT_DECIMAL:
/* Make room for maximum decimal number */
string_length = ACPI_MAX_DECIMAL_DIGITS;
base = 10;
break;
default:
/* Two hex string characters for each integer byte */
string_length = ACPI_MUL_2 (acpi_gbl_integer_byte_width);
break;
}
/*
* Create a new String
* Need enough space for one ASCII integer plus null terminator
*/
ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
if (!ret_desc) {
return_desc = acpi_ut_create_string_object ((acpi_size) string_length + 1);
if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Need enough space for one ASCII integer plus null terminator */
new_buf = return_desc->buffer.pointer;
new_buf = ACPI_MEM_CALLOCATE ((acpi_size) string_length + 1);
if (!new_buf) {
ACPI_REPORT_ERROR
(("ex_convert_to_string: Buffer allocation failure\n"));
acpi_ut_remove_reference (ret_desc);
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Convert */
/* Convert integer to string */
i = acpi_ex_convert_to_ascii (obj_desc->integer.value, base, new_buf, sizeof (acpi_integer));
string_length = acpi_ex_convert_to_ascii (obj_desc->integer.value, base,
new_buf, acpi_gbl_integer_byte_width);
/* Null terminate at the correct place */
if (max_length < i) {
new_buf[max_length] = 0;
ret_desc->string.length = max_length;
}
else {
new_buf [i] = 0;
ret_desc->string.length = i;
}
ret_desc->buffer.pointer = new_buf;
new_buf [string_length] = 0;
break;
case ACPI_TYPE_BUFFER:
/* Find the string length */
switch (type) {
case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by to_decimal_string operator */
/*
* From ACPI: "If Data is a buffer, it is converted to a string of
* decimal values separated by commas."
*/
base = 10;
string_length = obj_desc->buffer.length; /* 4 chars for each decimal */
pointer = obj_desc->buffer.pointer;
for (string_length = 0; string_length < obj_desc->buffer.length; string_length++) {
/* Exit on null terminator */
/*lint -fallthrough */
if (!pointer[string_length]) {
break;
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) {
separator = ' ';
}
}
if (max_length > ACPI_MAX_STRING_CONVERSION) {
if (string_length > ACPI_MAX_STRING_CONVERSION) {
/*lint -fallthrough */
case ACPI_EXPLICIT_CONVERT_HEX: /* Used by to_hex_string operator */
/*
* From ACPI: "If Data is a buffer, it is converted to a string of
* hexadecimal values separated by commas."
*/
string_length += (obj_desc->buffer.length * 3);
if (string_length > ACPI_MAX_STRING_CONVERSION) /* ACPI limit */ {
return_ACPI_STATUS (AE_AML_STRING_LIMIT);
}
}
/*
* Create a new string object
*/
ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
if (!ret_desc) {
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 */
return_desc = acpi_ut_create_string_object ((acpi_size) string_length);
if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
if (max_length < string_length) {
string_length = max_length;
}
new_buf = return_desc->buffer.pointer;
new_buf = ACPI_MEM_CALLOCATE ((acpi_size) string_length + 1);
if (!new_buf) {
ACPI_REPORT_ERROR
(("ex_convert_to_string: Buffer allocation failure\n"));
acpi_ut_remove_reference (ret_desc);
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Convert buffer bytes to hex or decimal values (separated by commas) */
/* Copy the appropriate number of buffer characters */
for (i = 0; i < obj_desc->buffer.length; i++) {
new_buf += acpi_ex_convert_to_ascii (
(acpi_integer) obj_desc->buffer.pointer[i], base,
new_buf, 1);
*new_buf++ = separator; /* each separated by a comma or space */
}
ACPI_MEMCPY (new_buf, pointer, string_length);
/* Null terminate the string (overwrites final comma from above) */
/* Null terminate */
new_buf--;
*new_buf = 0;
break;
new_buf [string_length] = 0;
ret_desc->buffer.pointer = new_buf;
ret_desc->string.length = string_length;
default:
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
break;
default:
return_ACPI_STATUS (AE_TYPE);
}
......@@ -552,12 +557,12 @@ acpi_ex_convert_to_string (
* essentially removing it from the stack.
*/
if (*result_desc == obj_desc) {
if (walk_state->opcode != AML_STORE_OP) {
if (opcode != AML_STORE_OP) {
acpi_ut_remove_reference (obj_desc);
}
}
*result_desc = ret_desc;
*result_desc = return_desc;
return_ACPI_STATUS (AE_OK);
}
......@@ -635,7 +640,8 @@ acpi_ex_convert_to_target_type (
* These types require an Integer operand. We can convert
* a Buffer or a String to an Integer if necessary.
*/
status = acpi_ex_convert_to_integer (source_desc, result_desc, walk_state);
status = acpi_ex_convert_to_integer (source_desc, result_desc,
walk_state->opcode);
break;
......@@ -645,7 +651,8 @@ acpi_ex_convert_to_target_type (
* The operand must be a String. We can convert an
* Integer or Buffer if necessary
*/
status = acpi_ex_convert_to_string (source_desc, result_desc, 16, ACPI_UINT32_MAX, walk_state);
status = acpi_ex_convert_to_string (source_desc, result_desc,
ACPI_IMPLICIT_CONVERT_HEX, walk_state->opcode);
break;
......@@ -655,7 +662,8 @@ acpi_ex_convert_to_target_type (
* The operand must be a Buffer. We can convert an
* Integer or String if necessary
*/
status = acpi_ex_convert_to_buffer (source_desc, result_desc, walk_state);
status = acpi_ex_convert_to_buffer (source_desc, result_desc,
walk_state->opcode);
break;
......
......@@ -139,7 +139,7 @@ acpi_ex_setup_region (
if (ACPI_ROUND_UP (rgn_desc->region.length,
obj_desc->common_field.access_byte_width) >=
(obj_desc->common_field.base_byte_offset +
obj_desc->common_field.access_byte_width +
(acpi_native_uint) obj_desc->common_field.access_byte_width +
field_datum_byte_offset)) {
return_ACPI_STATUS (AE_OK);
}
......
......@@ -149,8 +149,9 @@ acpi_ex_get_object_reference (
*
* FUNCTION: acpi_ex_concat_template
*
* PARAMETERS: *obj_desc - Object to be converted. Must be an
* Integer, Buffer, or String
* PARAMETERS: Operand0 - First source object
* Operand1 - Second source object
* actual_return_desc - Where to place the return object
* walk_state - Current walk state
*
* RETURN: Status
......@@ -161,8 +162,8 @@ acpi_ex_get_object_reference (
acpi_status
acpi_ex_concat_template (
union acpi_operand_object *obj_desc1,
union acpi_operand_object *obj_desc2,
union acpi_operand_object *operand0,
union acpi_operand_object *operand1,
union acpi_operand_object **actual_return_desc,
struct acpi_walk_state *walk_state)
{
......@@ -179,16 +180,16 @@ acpi_ex_concat_template (
/* Find the end_tags in each resource template */
end_tag1 = acpi_ut_get_resource_end_tag (obj_desc1);
end_tag2 = acpi_ut_get_resource_end_tag (obj_desc2);
end_tag1 = acpi_ut_get_resource_end_tag (operand0);
end_tag2 = acpi_ut_get_resource_end_tag (operand1);
if (!end_tag1 || !end_tag2) {
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
/* Compute the length of each part */
length1 = ACPI_PTR_DIFF (end_tag1, obj_desc1->buffer.pointer);
length2 = ACPI_PTR_DIFF (end_tag2, obj_desc2->buffer.pointer) +
length1 = ACPI_PTR_DIFF (end_tag1, operand0->buffer.pointer);
length2 = ACPI_PTR_DIFF (end_tag2, operand1->buffer.pointer) +
2; /* Size of END_TAG */
/* Create a new buffer object for the result */
......@@ -201,8 +202,8 @@ acpi_ex_concat_template (
/* Copy the templates to the new descriptor */
new_buf = return_desc->buffer.pointer;
ACPI_MEMCPY (new_buf, obj_desc1->buffer.pointer, length1);
ACPI_MEMCPY (new_buf + length1, obj_desc2->buffer.pointer, length2);
ACPI_MEMCPY (new_buf, operand0->buffer.pointer, length1);
ACPI_MEMCPY (new_buf + length1, operand1->buffer.pointer, length2);
/* Compute the new checksum */
......@@ -221,8 +222,8 @@ acpi_ex_concat_template (
*
* FUNCTION: acpi_ex_do_concatenate
*
* PARAMETERS: obj_desc1 - First source object
* obj_desc2 - Second source object
* PARAMETERS: Operand0 - First source object
* Operand1 - Second source object
* actual_return_desc - Where to place the return object
* walk_state - Current walk state
*
......@@ -234,20 +235,58 @@ acpi_ex_concat_template (
acpi_status
acpi_ex_do_concatenate (
union acpi_operand_object *obj_desc1,
union acpi_operand_object *obj_desc2,
union acpi_operand_object *operand0,
union acpi_operand_object *operand1,
union acpi_operand_object **actual_return_desc,
struct acpi_walk_state *walk_state)
{
acpi_status status;
u32 i;
acpi_integer this_integer;
union acpi_operand_object *local_operand1 = operand1;
union acpi_operand_object *return_desc;
char *new_buf;
acpi_status status;
ACPI_FUNCTION_ENTRY ();
ACPI_FUNCTION_TRACE ("ex_do_concatenate");
/*
* Convert the second operand if necessary. The first operand
* determines the type of the second operand, (See the Data Types
* section of the ACPI specification.) Both object types are
* guaranteed to be either Integer/String/Buffer by the operand
* resolution mechanism.
*/
switch (ACPI_GET_OBJECT_TYPE (operand0)) {
case ACPI_TYPE_INTEGER:
status = acpi_ex_convert_to_integer (operand1, &local_operand1,
walk_state->opcode);
break;
case ACPI_TYPE_STRING:
status = acpi_ex_convert_to_string (operand1, &local_operand1,
ACPI_IMPLICIT_CONVERT_HEX, walk_state->opcode);
break;
case ACPI_TYPE_BUFFER:
status = acpi_ex_convert_to_buffer (operand1, &local_operand1,
walk_state->opcode);
break;
default:
ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n",
ACPI_GET_OBJECT_TYPE (operand0)));
status = AE_AML_INTERNAL;
}
if (ACPI_FAILURE (status)) {
goto cleanup;
}
/*
* Both operands are now known to be the same object type
* (Both are Integer, String, or Buffer), and we can now perform the
* concatenation.
*/
/*
* There are three cases to handle:
......@@ -256,113 +295,97 @@ acpi_ex_do_concatenate (
* 2) Two Strings concatenated to produce a new String
* 3) Two Buffers concatenated to produce a new Buffer
*/
switch (ACPI_GET_OBJECT_TYPE (obj_desc1)) {
switch (ACPI_GET_OBJECT_TYPE (operand0)) {
case ACPI_TYPE_INTEGER:
/* Result of two Integers is a Buffer */
/* Need enough buffer space for two integers */
return_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width * 2);
return_desc = acpi_ut_create_buffer_object (
ACPI_MUL_2 (acpi_gbl_integer_byte_width));
if (!return_desc) {
return (AE_NO_MEMORY);
status = AE_NO_MEMORY;
goto cleanup;
}
new_buf = (char *) return_desc->buffer.pointer;
/* Convert the first integer */
this_integer = obj_desc1->integer.value;
for (i = 0; i < acpi_gbl_integer_byte_width; i++) {
new_buf[i] = (char) this_integer;
this_integer >>= 8;
}
/* Copy the first integer, LSB first */
/* Convert the second integer */
ACPI_MEMCPY (new_buf,
&operand0->integer.value,
acpi_gbl_integer_byte_width);
this_integer = obj_desc2->integer.value;
for (; i < (ACPI_MUL_2 (acpi_gbl_integer_byte_width)); i++) {
new_buf[i] = (char) this_integer;
this_integer >>= 8;
}
/* Copy the second integer (LSB first) after the first */
ACPI_MEMCPY (new_buf + acpi_gbl_integer_byte_width,
&local_operand1->integer.value,
acpi_gbl_integer_byte_width);
break;
case ACPI_TYPE_STRING:
/* Result of two Strings is a String */
return_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
return_desc = acpi_ut_create_string_object (
(acpi_size) operand0->string.length +
(acpi_size) local_operand1->string.length + 1);
if (!return_desc) {
return (AE_NO_MEMORY);
}
/* Operand0 is string */
new_buf = ACPI_MEM_CALLOCATE ((acpi_size) obj_desc1->string.length +
(acpi_size) obj_desc2->string.length + 1);
if (!new_buf) {
ACPI_REPORT_ERROR
(("ex_do_concatenate: String allocation failure\n"));
status = AE_NO_MEMORY;
goto cleanup;
}
/* Concatenate the strings */
ACPI_STRCPY (new_buf, obj_desc1->string.pointer);
ACPI_STRCPY (new_buf + obj_desc1->string.length,
obj_desc2->string.pointer);
new_buf = return_desc->string.pointer;
/* Complete the String object initialization */
/* Concatenate the strings */
return_desc->string.pointer = new_buf;
return_desc->string.length = obj_desc1->string.length +
obj_desc2->string.length;
ACPI_STRCPY (new_buf,
operand0->string.pointer);
ACPI_STRCPY (new_buf + operand0->string.length,
local_operand1->string.pointer);
break;
case ACPI_TYPE_BUFFER:
/* Result of two Buffers is a Buffer */
return_desc = acpi_ut_create_buffer_object (
(acpi_size) obj_desc1->buffer.length +
(acpi_size) obj_desc2->buffer.length);
(acpi_size) operand0->buffer.length +
(acpi_size) local_operand1->buffer.length);
if (!return_desc) {
return (AE_NO_MEMORY);
status = AE_NO_MEMORY;
goto cleanup;
}
new_buf = (char *) return_desc->buffer.pointer;
/* Concatenate the buffers */
ACPI_MEMCPY (new_buf, obj_desc1->buffer.pointer,
obj_desc1->buffer.length);
ACPI_MEMCPY (new_buf + obj_desc1->buffer.length, obj_desc2->buffer.pointer,
obj_desc2->buffer.length);
ACPI_MEMCPY (new_buf,
operand0->buffer.pointer,
operand0->buffer.length);
ACPI_MEMCPY (new_buf + operand0->buffer.length,
local_operand1->buffer.pointer,
local_operand1->buffer.length);
break;
default:
/* Invalid object type, should not happen here */
ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n",
ACPI_GET_OBJECT_TYPE (obj_desc1)));
status = AE_AML_INTERNAL;
return_desc = NULL;
ACPI_REPORT_ERROR (("Concatenate - Invalid object type: %X\n",
ACPI_GET_OBJECT_TYPE (operand0)));
status =AE_AML_INTERNAL;
goto cleanup;
}
*actual_return_desc = return_desc;
return (AE_OK);
cleanup:
acpi_ut_remove_reference (return_desc);
return (status);
if (local_operand1 != operand1) {
acpi_ut_remove_reference (local_operand1);
}
return_ACPI_STATUS (AE_OK);
}
......@@ -371,8 +394,8 @@ acpi_ex_do_concatenate (
* FUNCTION: acpi_ex_do_math_op
*
* PARAMETERS: Opcode - AML opcode
* Operand0 - Integer operand #0
* Operand1 - Integer operand #1
* Integer0 - Integer operand #0
* Integer1 - Integer operand #1
*
* RETURN: Integer result of the operation
*
......@@ -385,62 +408,62 @@ acpi_ex_do_concatenate (
acpi_integer
acpi_ex_do_math_op (
u16 opcode,
acpi_integer operand0,
acpi_integer operand1)
acpi_integer integer0,
acpi_integer integer1)
{
ACPI_FUNCTION_ENTRY ();
switch (opcode) {
case AML_ADD_OP: /* Add (Operand0, Operand1, Result) */
case AML_ADD_OP: /* Add (Integer0, Integer1, Result) */
return (operand0 + operand1);
return (integer0 + integer1);
case AML_BIT_AND_OP: /* And (Operand0, Operand1, Result) */
case AML_BIT_AND_OP: /* And (Integer0, Integer1, Result) */
return (operand0 & operand1);
return (integer0 & integer1);
case AML_BIT_NAND_OP: /* NAnd (Operand0, Operand1, Result) */
case AML_BIT_NAND_OP: /* NAnd (Integer0, Integer1, Result) */
return (~(operand0 & operand1));
return (~(integer0 & integer1));
case AML_BIT_OR_OP: /* Or (Operand0, Operand1, Result) */
case AML_BIT_OR_OP: /* Or (Integer0, Integer1, Result) */
return (operand0 | operand1);
return (integer0 | integer1);
case AML_BIT_NOR_OP: /* NOr (Operand0, Operand1, Result) */
case AML_BIT_NOR_OP: /* NOr (Integer0, Integer1, Result) */
return (~(operand0 | operand1));
return (~(integer0 | integer1));
case AML_BIT_XOR_OP: /* XOr (Operand0, Operand1, Result) */
case AML_BIT_XOR_OP: /* XOr (Integer0, Integer1, Result) */
return (operand0 ^ operand1);
return (integer0 ^ integer1);
case AML_MULTIPLY_OP: /* Multiply (Operand0, Operand1, Result) */
case AML_MULTIPLY_OP: /* Multiply (Integer0, Integer1, Result) */
return (operand0 * operand1);
return (integer0 * integer1);
case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */
return (operand0 << operand1);
return (integer0 << integer1);
case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */
return (operand0 >> operand1);
return (integer0 >> integer1);
case AML_SUBTRACT_OP: /* Subtract (Operand0, Operand1, Result) */
case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */
return (operand0 - operand1);
return (integer0 - integer1);
default:
......@@ -449,22 +472,86 @@ acpi_ex_do_math_op (
}
/*******************************************************************************
*
* FUNCTION: acpi_ex_do_logical_numeric_op
*
* PARAMETERS: Opcode - AML opcode
* Integer0 - Integer operand #0
* Integer1 - Integer operand #1
* logical_result - TRUE/FALSE result of the operation
*
* RETURN: Status
*
* DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric
* operators (LAnd and LOr), both operands must be integers.
*
* Note: cleanest machine code seems to be produced by the code
* below, rather than using statements of the form:
* Result = (Integer0 && Integer1);
*
******************************************************************************/
acpi_status
acpi_ex_do_logical_numeric_op (
u16 opcode,
acpi_integer integer0,
acpi_integer integer1,
u8 *logical_result)
{
acpi_status status = AE_OK;
u8 local_result = FALSE;
ACPI_FUNCTION_TRACE ("ex_do_logical_numeric_op");
switch (opcode) {
case AML_LAND_OP: /* LAnd (Integer0, Integer1) */
if (integer0 && integer1) {
local_result = TRUE;
}
break;
case AML_LOR_OP: /* LOr (Integer0, Integer1) */
if (integer0 || integer1) {
local_result = TRUE;
}
break;
default:
status = AE_AML_INTERNAL;
break;
}
/* Return the logical result and status */
*logical_result = local_result;
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: acpi_ex_do_logical_op
*
* PARAMETERS: Opcode - AML opcode
* obj_desc0 - operand #0
* obj_desc1 - operand #1
* Operand0 - operand #0
* Operand1 - operand #1
* logical_result - TRUE/FALSE result of the operation
*
* RETURN: TRUE/FALSE result of the operation
* RETURN: Status
*
* DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the
* functions here is to prevent a lot of pointer dereferencing
* to obtain the operands and to simplify the generation of the
* logical value. Both operands must already be validated as
* 1) Both the same type, and
* 2) Either Integer, Buffer, or String type.
* logical value. For the Numeric operators (LAnd and LOr), both
* operands must be integers. For the other logical operators,
* operands can be any combination of Integer/String/Buffer. The
* first operand determines the type to which the second operand
* will be converted.
*
* Note: cleanest machine code seems to be produced by the code
* below, rather than using statements of the form:
......@@ -472,143 +559,174 @@ acpi_ex_do_math_op (
*
******************************************************************************/
u8
acpi_status
acpi_ex_do_logical_op (
u16 opcode,
union acpi_operand_object *obj_desc0,
union acpi_operand_object *obj_desc1)
union acpi_operand_object *operand0,
union acpi_operand_object *operand1,
u8 *logical_result)
{
acpi_integer operand0;
acpi_integer operand1;
u8 *ptr0;
u8 *ptr1;
union acpi_operand_object *local_operand1 = operand1;
acpi_integer integer0;
acpi_integer integer1;
u32 length0;
u32 length1;
u32 i;
acpi_status status = AE_OK;
u8 local_result = FALSE;
int compare;
ACPI_FUNCTION_ENTRY ();
ACPI_FUNCTION_TRACE ("ex_do_logical_op");
if (ACPI_GET_OBJECT_TYPE (obj_desc0) == ACPI_TYPE_INTEGER) {
/* Both operands are of type integer */
/*
* Convert the second operand if necessary. The first operand
* determines the type of the second operand, (See the Data Types
* section of the ACPI 3.0+ specification.) Both object types are
* guaranteed to be either Integer/String/Buffer by the operand
* resolution mechanism.
*/
switch (ACPI_GET_OBJECT_TYPE (operand0)) {
case ACPI_TYPE_INTEGER:
status = acpi_ex_convert_to_integer (operand1, &local_operand1, opcode);
break;
operand0 = obj_desc0->integer.value;
operand1 = obj_desc1->integer.value;
case ACPI_TYPE_STRING:
status = acpi_ex_convert_to_string (operand1, &local_operand1,
ACPI_IMPLICIT_CONVERT_HEX, opcode);
break;
switch (opcode) {
case AML_LAND_OP: /* LAnd (Operand0, Operand1) */
case ACPI_TYPE_BUFFER:
status = acpi_ex_convert_to_buffer (operand1, &local_operand1, opcode);
break;
if (operand0 && operand1) {
return (TRUE);
}
break;
default:
status = AE_AML_INTERNAL;
break;
}
if (ACPI_FAILURE (status)) {
goto cleanup;
}
/*
* Two cases: 1) Both Integers, 2) Both Strings or Buffers
*/
if (ACPI_GET_OBJECT_TYPE (operand0) == ACPI_TYPE_INTEGER) {
/*
* 1) Both operands are of type integer
* Note: local_operand1 may have changed above
*/
integer0 = operand0->integer.value;
integer1 = local_operand1->integer.value;
switch (opcode) {
case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
if (operand0 == operand1) {
return (TRUE);
if (integer0 == integer1) {
local_result = TRUE;
}
break;
case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
if (operand0 > operand1) {
return (TRUE);
if (integer0 > integer1) {
local_result = TRUE;
}
break;
case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
if (operand0 < operand1) {
return (TRUE);
}
break;
case AML_LOR_OP: /* LOr (Operand0, Operand1) */
if (operand0 || operand1) {
return (TRUE);
if (integer0 < integer1) {
local_result = TRUE;
}
break;
default:
status = AE_AML_INTERNAL;
break;
}
}
else {
/*
* Case for Buffer/String objects.
* NOTE: takes advantage of common Buffer/String object fields
* 2) Both operands are Strings or both are Buffers
* Note: Code below takes advantage of common Buffer/String
* object fields. local_operand1 may have changed above
*/
length0 = obj_desc0->buffer.length;
ptr0 = obj_desc0->buffer.pointer;
length0 = operand0->buffer.length;
length1 = local_operand1->buffer.length;
length1 = obj_desc1->buffer.length;
ptr1 = obj_desc1->buffer.pointer;
/* Lexicographic compare: compare the data bytes */
compare = ACPI_STRNCMP ((const char * ) operand0->buffer.pointer,
(const char * ) local_operand1->buffer.pointer,
(length0 > length1) ? length1 : length0);
switch (opcode) {
case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
/* Length and all bytes must be equal */
if (length0 != length1) {
return (FALSE);
}
if ((length0 == length1) &&
(compare == 0)) {
/* Length and all bytes match ==> TRUE */
for (i = 0; i < length0; i++) {
if (ptr0[i] != ptr1[i]) {
return (FALSE);
}
local_result = TRUE;
}
return (TRUE);
break;
case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
/* Lexicographic compare: Scan the 1-to-1 data */
for (i = 0; (i < length0) && (i < length1); i++) {
if (ptr0[i] > ptr1[i]) {
return (TRUE);
}
if (compare > 0) {
local_result = TRUE;
goto cleanup; /* TRUE */
}
if (compare < 0) {
goto cleanup; /* FALSE */
}
/* Bytes match, now check lengths */
/* Bytes match (to shortest length), compare lengths */
if (length0 > length1) {
return (TRUE);
local_result = TRUE;
}
/* Length0 <= Length1 */
return (FALSE);
break;
case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
/* Lexicographic compare: Scan the 1-to-1 data */
for (i = 0; (i < length0) && (i < length1); i++) {
if (ptr0[i] < ptr1[i]) {
return (TRUE);
}
if (compare > 0) {
goto cleanup; /* FALSE */
}
if (compare < 0) {
local_result = TRUE;
goto cleanup; /* TRUE */
}
/* Bytes match, now check lengths */
/* Bytes match (to shortest length), compare lengths */
if (length0 < length1) {
return (TRUE);
local_result = TRUE;
}
/* Length0 >= Length1 */
return (FALSE);
break;
default:
status = AE_AML_INTERNAL;
break;
}
}
return (FALSE);
cleanup:
/* New object was created if implicit conversion performed - delete */
if (local_operand1 != operand1) {
acpi_ut_remove_reference (local_operand1);
}
/* Return the logical result and status */
*logical_result = local_result;
return_ACPI_STATUS (status);
}
......@@ -344,7 +344,7 @@ acpi_ex_opcode_1A_1T_1R (
/* Insert the BCD digit that resides in the remainder from above */
return_desc->integer.value |= (((acpi_integer) temp32) << (i * 4));
return_desc->integer.value |= (((acpi_integer) temp32) << ACPI_MUL_4 (i));
}
/* Overflow if there is any data left in Digit */
......@@ -429,31 +429,36 @@ acpi_ex_opcode_1A_1T_1R (
*/
case AML_COPY_OP: /* Copy (Source, Target) */
status = acpi_ut_copy_iobject_to_iobject (operand[0], &return_desc, walk_state);
status = acpi_ut_copy_iobject_to_iobject (operand[0], &return_desc,
walk_state);
break;
case AML_TO_DECSTRING_OP: /* to_decimal_string (Data, Result) */
status = acpi_ex_convert_to_string (operand[0], &return_desc, 10, ACPI_UINT32_MAX, walk_state);
status = acpi_ex_convert_to_string (operand[0], &return_desc,
ACPI_EXPLICIT_CONVERT_DECIMAL, walk_state->opcode);
break;
case AML_TO_HEXSTRING_OP: /* to_hex_string (Data, Result) */
status = acpi_ex_convert_to_string (operand[0], &return_desc, 16, ACPI_UINT32_MAX, walk_state);
status = acpi_ex_convert_to_string (operand[0], &return_desc,
ACPI_EXPLICIT_CONVERT_HEX, walk_state->opcode);
break;
case AML_TO_BUFFER_OP: /* to_buffer (Data, Result) */
status = acpi_ex_convert_to_buffer (operand[0], &return_desc, walk_state);
status = acpi_ex_convert_to_buffer (operand[0], &return_desc,
walk_state->opcode);
break;
case AML_TO_INTEGER_OP: /* to_integer (Data, Result) */
status = acpi_ex_convert_to_integer (operand[0], &return_desc, walk_state);
status = acpi_ex_convert_to_integer (operand[0], &return_desc,
walk_state->opcode);
break;
......@@ -463,8 +468,9 @@ acpi_ex_opcode_1A_1T_1R (
/*
* These are two obsolete opcodes
*/
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s is obsolete and not implemented\n",
acpi_ps_get_opcode_name (walk_state->opcode)));
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"%s is obsolete and not implemented\n",
acpi_ps_get_opcode_name (walk_state->opcode)));
status = AE_SUPPORT;
goto cleanup;
......
......@@ -292,7 +292,6 @@ acpi_ex_opcode_2A_1T_1R (
{
union acpi_operand_object **operand = &walk_state->operands[0];
union acpi_operand_object *return_desc = NULL;
union acpi_operand_object *temp_desc = NULL;
u32 index;
acpi_status status = AE_OK;
acpi_size length;
......@@ -331,52 +330,15 @@ acpi_ex_opcode_2A_1T_1R (
/* return_desc will contain the remainder */
status = acpi_ut_divide (&operand[0]->integer.value, &operand[1]->integer.value,
status = acpi_ut_divide (&operand[0]->integer.value,
&operand[1]->integer.value,
NULL, &return_desc->integer.value);
break;
case AML_CONCAT_OP: /* Concatenate (Data1, Data2, Result) */
/*
* Convert the second operand if necessary. The first operand
* determines the type of the second operand, (See the Data Types
* section of the ACPI specification.) Both object types are
* guaranteed to be either Integer/String/Buffer by the operand
* resolution mechanism above.
*/
switch (ACPI_GET_OBJECT_TYPE (operand[0])) {
case ACPI_TYPE_INTEGER:
status = acpi_ex_convert_to_integer (operand[1], &temp_desc, walk_state);
break;
case ACPI_TYPE_STRING:
status = acpi_ex_convert_to_string (operand[1], &temp_desc, 16, ACPI_UINT32_MAX, walk_state);
break;
case ACPI_TYPE_BUFFER:
status = acpi_ex_convert_to_buffer (operand[1], &temp_desc, walk_state);
break;
default:
ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n",
ACPI_GET_OBJECT_TYPE (operand[0])));
status = AE_AML_INTERNAL;
}
if (ACPI_FAILURE (status)) {
goto cleanup;
}
/*
* Both operands are now known to be the same object type
* (Both are Integer, String, or Buffer), and we can now perform the
* concatenation.
*/
status = acpi_ex_do_concatenate (operand[0], temp_desc, &return_desc, walk_state);
if (temp_desc != operand[1]) {
acpi_ut_remove_reference (temp_desc);
}
status = acpi_ex_do_concatenate (operand[0], operand[1], &return_desc, walk_state);
break;
......@@ -407,35 +369,25 @@ acpi_ex_opcode_2A_1T_1R (
goto cleanup;
}
/* Create the internal return object */
/* Allocate a new string (Length + 1 for null terminator) */
return_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
return_desc = acpi_ut_create_string_object (length + 1);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
}
/* Allocate a new string buffer (Length + 1 for null terminator) */
return_desc->string.pointer = ACPI_MEM_CALLOCATE (length + 1);
if (!return_desc->string.pointer) {
status = AE_NO_MEMORY;
goto cleanup;
}
/* Copy the raw buffer data with no transform */
ACPI_MEMCPY (return_desc->string.pointer, operand[0]->buffer.pointer, length);
/* Copy the raw buffer data with no transform. NULL terminated already. */
/* Set the string length */
return_desc->string.length = (u32) length;
ACPI_MEMCPY (return_desc->string.pointer,
operand[0]->buffer.pointer, length);
break;
case AML_CONCAT_RES_OP: /* concatenate_res_template (Buffer, Buffer, Result) (ACPI 2.0) */
status = acpi_ex_concat_template (operand[0], operand[1], &return_desc, walk_state);
status = acpi_ex_concat_template (operand[0], operand[1],
&return_desc, walk_state);
break;
......@@ -458,7 +410,8 @@ acpi_ex_opcode_2A_1T_1R (
/* Object to be indexed is a Package */
if (index >= operand[0]->package.count) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value (%X) beyond package end (%X)\n",
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Index value (%X) beyond package end (%X)\n",
index, operand[0]->package.count));
status = AE_AML_PACKAGE_LIMIT;
goto cleanup;
......@@ -472,7 +425,8 @@ acpi_ex_opcode_2A_1T_1R (
/* Object to be indexed is a Buffer */
if (index >= operand[0]->buffer.length) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value (%X) beyond end of buffer (%X)\n",
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Index value (%X) beyond end of buffer (%X)\n",
index, operand[0]->buffer.length));
status = AE_AML_BUFFER_LIMIT;
goto cleanup;
......@@ -572,18 +526,15 @@ acpi_ex_opcode_2A_0T_1R (
/*
* Execute the Opcode
*/
if (walk_state->op_info->flags & AML_LOGICAL) /* logical_op (Operand0, Operand1) */ {
/* Both operands must be of the same type */
if (ACPI_GET_OBJECT_TYPE (operand[0]) !=
ACPI_GET_OBJECT_TYPE (operand[1])) {
status = AE_AML_OPERAND_TYPE;
goto cleanup;
}
logical_result = acpi_ex_do_logical_op (walk_state->opcode,
operand[0],
operand[1]);
if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) /* logical_op (Operand0, Operand1) */ {
status = acpi_ex_do_logical_numeric_op (walk_state->opcode,
operand[0]->integer.value, operand[1]->integer.value,
&logical_result);
goto store_logical_result;
}
else if (walk_state->op_info->flags & AML_LOGICAL) /* logical_op (Operand0, Operand1) */ {
status = acpi_ex_do_logical_op (walk_state->opcode, operand[0],
operand[1], &logical_result);
goto store_logical_result;
}
......
......@@ -398,7 +398,8 @@ acpi_ex_resolve_operands (
* But we can implicitly convert from a STRING or BUFFER
* Aka - "Implicit Source Operand Conversion"
*/
status = acpi_ex_convert_to_integer (obj_desc, stack_ptr, walk_state);
status = acpi_ex_convert_to_integer (obj_desc, stack_ptr,
walk_state->opcode);
if (ACPI_FAILURE (status)) {
if (status == AE_TYPE) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
......@@ -420,7 +421,8 @@ acpi_ex_resolve_operands (
* But we can implicitly convert from a STRING or INTEGER
* Aka - "Implicit Source Operand Conversion"
*/
status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr, walk_state);
status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr,
walk_state->opcode);
if (ACPI_FAILURE (status)) {
if (status == AE_TYPE) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
......@@ -442,7 +444,8 @@ acpi_ex_resolve_operands (
* But we can implicitly convert from a BUFFER or INTEGER
* Aka - "Implicit Source Operand Conversion"
*/
status = acpi_ex_convert_to_string (obj_desc, stack_ptr, 16, ACPI_UINT32_MAX, walk_state);
status = acpi_ex_convert_to_string (obj_desc, stack_ptr,
ACPI_IMPLICIT_CONVERT_HEX, walk_state->opcode);
if (ACPI_FAILURE (status)) {
if (status == AE_TYPE) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
......@@ -494,7 +497,8 @@ acpi_ex_resolve_operands (
/* Highest priority conversion is to type Buffer */
status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr, walk_state);
status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr,
walk_state->opcode);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
......
......@@ -202,7 +202,11 @@ acpi_ns_get_pathname_length (
next_node = acpi_ns_get_parent_node (next_node);
}
return (size + 1);
if (!size) {
size = 1; /* Root node case */
}
return (size + 1); /* +1 for null string terminator */
}
......
......@@ -527,8 +527,8 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] =
/* 35 */ ACPI_OP ("CreateByteField", ARGP_CREATE_BYTE_FIELD_OP, ARGI_CREATE_BYTE_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
/* 36 */ ACPI_OP ("CreateBitField", ARGP_CREATE_BIT_FIELD_OP, ARGI_CREATE_BIT_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
/* 37 */ ACPI_OP ("ObjectType", ARGP_TYPE_OP, ARGI_TYPE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R),
/* 38 */ ACPI_OP ("LAnd", ARGP_LAND_OP, ARGI_LAND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
/* 39 */ ACPI_OP ("LOr", ARGP_LOR_OP, ARGI_LOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
/* 38 */ ACPI_OP ("LAnd", ARGP_LAND_OP, ARGI_LAND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
/* 39 */ ACPI_OP ("LOr", ARGP_LOR_OP, ARGI_LOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
/* 3A */ ACPI_OP ("LNot", ARGP_LNOT_OP, ARGI_LNOT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
/* 3B */ ACPI_OP ("LEqual", ARGP_LEQUAL_OP, ARGI_LEQUAL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
/* 3C */ ACPI_OP ("LGreater", ARGP_LGREATER_OP, ARGI_LGREATER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
......
......@@ -472,7 +472,7 @@ acpi_ut_allocate_and_track (
acpi_status status;
allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_block), component,
allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_header), component,
module, line);
if (!allocation) {
return (NULL);
......@@ -518,7 +518,7 @@ acpi_ut_callocate_and_track (
acpi_status status;
allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_block), component,
allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_header), component,
module, line);
if (!allocation) {
/* Report allocation error */
......@@ -712,6 +712,7 @@ acpi_ut_track_allocation (
allocation->line = line;
ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME);
allocation->module[ACPI_MAX_MODULE_NAME-1] = 0;
/* Insert at list head */
......
......@@ -155,9 +155,8 @@ acpi_ut_create_buffer_object (
ACPI_FUNCTION_TRACE_U32 ("ut_create_buffer_object", buffer_size);
/*
* Create a new Buffer object
*/
/* Create a new Buffer object */
buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
if (!buffer_desc) {
return_PTR (NULL);
......@@ -189,6 +188,63 @@ acpi_ut_create_buffer_object (
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_create_string_object
*
* PARAMETERS: string_size - Size of string to be created, plus one
* for the NULL terminater. Actual sting
* length will be this size minus one.
*
* RETURN: Pointer to a new String object
*
* DESCRIPTION: Create a fully initialized string object
*
******************************************************************************/
union acpi_operand_object *
acpi_ut_create_string_object (
acpi_size string_size)
{
union acpi_operand_object *string_desc;
char *string = NULL;
ACPI_FUNCTION_TRACE_U32 ("ut_create_string_object", string_size);
/* Create a new String object */
string_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
if (!string_desc) {
return_PTR (NULL);
}
/* Create an actual string only if size > 0 */
if (string_size > 0) {
/* Allocate the actual string */
string = ACPI_MEM_CALLOCATE (string_size);
if (!string) {
ACPI_REPORT_ERROR (("create_string: could not allocate size %X\n",
(u32) string_size));
acpi_ut_remove_reference (string_desc);
return_PTR (NULL);
}
}
/* Complete string object initialization */
string_desc->string.pointer = string;
string_desc->string.length = (u32) string_size - 1;
/* Return the new string descriptor */
return_PTR (string_desc);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_valid_internal_object
......
......@@ -64,7 +64,7 @@
/* Version string */
#define ACPI_CA_VERSION 0x20040816
#define ACPI_CA_VERSION 0x20040827
/*
* OS name, used for the _OS object. The _OS object is essentially obsolete,
......
......@@ -83,21 +83,27 @@ acpi_status
acpi_ex_convert_to_integer (
union acpi_operand_object *obj_desc,
union acpi_operand_object **result_desc,
struct acpi_walk_state *walk_state);
u16 opcode);
acpi_status
acpi_ex_convert_to_buffer (
union acpi_operand_object *obj_desc,
union acpi_operand_object **result_desc,
struct acpi_walk_state *walk_state);
u16 opcode);
acpi_status
acpi_ex_convert_to_string (
union acpi_operand_object *obj_desc,
union acpi_operand_object **result_desc,
u32 base,
u32 max_length,
struct acpi_walk_state *walk_state);
u32 type,
u16 opcode);
/* Types for String conversion */
#define ACPI_EXPLICIT_BYTE_COPY 0x00000000
#define ACPI_EXPLICIT_CONVERT_HEX 0x00000001
#define ACPI_IMPLICIT_CONVERT_HEX 0x00000002
#define ACPI_EXPLICIT_CONVERT_DECIMAL 0x00000003
acpi_status
acpi_ex_convert_to_target_type (
......@@ -109,7 +115,7 @@ acpi_ex_convert_to_target_type (
u32
acpi_ex_convert_to_ascii (
acpi_integer integer,
u32 base,
u16 base,
u8 *string,
u8 max_length);
......@@ -243,11 +249,19 @@ acpi_ex_do_concatenate (
union acpi_operand_object **actual_return_desc,
struct acpi_walk_state *walk_state);
u8
acpi_status
acpi_ex_do_logical_numeric_op (
u16 opcode,
acpi_integer integer0,
acpi_integer integer1,
u8 *logical_result);
acpi_status
acpi_ex_do_logical_op (
u16 opcode,
union acpi_operand_object *obj_desc,
union acpi_operand_object *obj_desc2);
union acpi_operand_object *operand0,
union acpi_operand_object *operand1,
u8 *logical_result);
acpi_integer
acpi_ex_do_math_op (
......
......@@ -135,7 +135,10 @@ struct acpi_object_integer
acpi_integer value;
};
/*
* Note: The String and Buffer object must be identical through the Pointer
* element. There is code that depends on this.
*/
struct acpi_object_string /* Null terminated, ASCII characters only */
{
ACPI_OBJECT_COMMON_HEADER
......
......@@ -303,7 +303,7 @@ struct uint32_struct
typedef u32 acpi_integer;
#define ACPI_INTEGER_MAX ACPI_UINT32_MAX
#define ACPI_INTEGER_BIT_SIZE 32
#define ACPI_MAX_DECIMAL_DIGITS 10
#define ACPI_MAX_DECIMAL_DIGITS 10 /* 2^32 = 4,294,967,296 */
#define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 32-bit divide */
......@@ -315,13 +315,18 @@ typedef u32 acpi_integer;
typedef u64 acpi_integer;
#define ACPI_INTEGER_MAX ACPI_UINT64_MAX
#define ACPI_INTEGER_BIT_SIZE 64
#define ACPI_MAX_DECIMAL_DIGITS 19
#define ACPI_MAX_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */
#if ACPI_MACHINE_WIDTH == 64
#define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 64-bit divide */
#endif
#endif
#define ACPI_MAX64_DECIMAL_DIGITS 20
#define ACPI_MAX32_DECIMAL_DIGITS 10
#define ACPI_MAX16_DECIMAL_DIGITS 5
#define ACPI_MAX8_DECIMAL_DIGITS 3
/*
* Constants with special meanings
......
......@@ -577,6 +577,10 @@ union acpi_operand_object *
acpi_ut_create_buffer_object (
acpi_size buffer_size);
union acpi_operand_object *
acpi_ut_create_string_object (
acpi_size string_size);
/*
* ut_ref_cnt - Object reference count management
......
......@@ -305,19 +305,20 @@
/* Opcode flags */
#define AML_HAS_ARGS 0x0800
#define AML_HAS_TARGET 0x0400
#define AML_HAS_RETVAL 0x0200
#define AML_NSOBJECT 0x0100
#define AML_NSOPCODE 0x0080
#define AML_NSNODE 0x0040
#define AML_NAMED 0x0020
#define AML_DEFER 0x0010
#define AML_FIELD 0x0008
#define AML_CREATE 0x0004
#define AML_MATH 0x0002
#define AML_LOGICAL 0x0001
#define AML_CONSTANT 0x1000
#define AML_LOGICAL_NUMERIC 0x0002
#define AML_MATH 0x0004
#define AML_CREATE 0x0008
#define AML_FIELD 0x0010
#define AML_DEFER 0x0020
#define AML_NAMED 0x0040
#define AML_NSNODE 0x0080
#define AML_NSOPCODE 0x0100
#define AML_NSOBJECT 0x0200
#define AML_HAS_RETVAL 0x0400
#define AML_HAS_TARGET 0x0800
#define AML_HAS_ARGS 0x1000
#define AML_CONSTANT 0x2000
/* Convenient flag groupings */
......
......@@ -99,7 +99,7 @@ struct asl_resource_node
/*
* Resource descriptors defined in the ACPI specification.
*
* Alignment must be BYTE because these descriptors
* Packing/alignment must be BYTE because these descriptors
* are used to overlay the AML byte stream.
*/
#pragma pack(1)
......@@ -297,7 +297,7 @@ struct asl_general_register_desc
#pragma pack()
/* Union of all resource descriptors, sow we can allocate the worst case */
/* Union of all resource descriptors, so we can allocate the worst case */
union asl_resource_desc
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment