diff options
| -rw-r--r-- | drivers/acpi/dispatcher/dswexec.c | 3 | ||||
| -rw-r--r-- | drivers/acpi/executer/exconvrt.c | 320 | ||||
| -rw-r--r-- | drivers/acpi/executer/exfldio.c | 2 | ||||
| -rw-r--r-- | drivers/acpi/executer/exmisc.c | 464 | ||||
| -rw-r--r-- | drivers/acpi/executer/exoparg1.c | 22 | ||||
| -rw-r--r-- | drivers/acpi/executer/exoparg2.c | 95 | ||||
| -rw-r--r-- | drivers/acpi/executer/exresop.c | 12 | ||||
| -rw-r--r-- | drivers/acpi/namespace/nsnames.c | 6 | ||||
| -rw-r--r-- | drivers/acpi/parser/psopcode.c | 4 | ||||
| -rw-r--r-- | drivers/acpi/utilities/utalloc.c | 5 | ||||
| -rw-r--r-- | drivers/acpi/utilities/utobject.c | 62 | ||||
| -rw-r--r-- | include/acpi/acconfig.h | 2 | ||||
| -rw-r--r-- | include/acpi/acinterp.h | 32 | ||||
| -rw-r--r-- | include/acpi/acobject.h | 5 | ||||
| -rw-r--r-- | include/acpi/actypes.h | 9 | ||||
| -rw-r--r-- | include/acpi/acutils.h | 4 | ||||
| -rw-r--r-- | include/acpi/amlcode.h | 25 | ||||
| -rw-r--r-- | include/acpi/amlresrc.h | 4 |
18 files changed, 626 insertions, 450 deletions
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index 02872ca223d2..148040c09a75 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c @@ -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)) { diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c index 04c04e4ae39b..8b9df9274f83 100644 --- a/drivers/acpi/executer/exconvrt.c +++ b/drivers/acpi/executer/exconvrt.c @@ -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; diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c index 03ccfb9e10f0..5f8fbdb16e11 100644 --- a/drivers/acpi/executer/exfldio.c +++ b/drivers/acpi/executer/exfldio.c @@ -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); } diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index 961a949e9797..a8aaeafc5e9c 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c @@ -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 @@ cleanup: * 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 @@ cleanup: 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: @@ -451,20 +474,84 @@ 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); } diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c index 8ba1e646974d..33adceb1bf5d 100644 --- a/drivers/acpi/executer/exoparg1.c +++ b/drivers/acpi/executer/exoparg1.c @@ -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; diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c index 0b6f86a91572..2660afa7b4f8 100644 --- a/drivers/acpi/executer/exoparg2.c +++ b/drivers/acpi/executer/exoparg2.c @@ -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; } diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c index d410bd7f1fe3..3f6e6f9f9745 100644 --- a/drivers/acpi/executer/exresop.c +++ b/drivers/acpi/executer/exresop.c @@ -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); } diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c index e0b9663aef80..3f633d97e051 100644 --- a/drivers/acpi/namespace/nsnames.c +++ b/drivers/acpi/namespace/nsnames.c @@ -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 */ } diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c index 30620375bd88..832193b93a78 100644 --- a/drivers/acpi/parser/psopcode.c +++ b/drivers/acpi/parser/psopcode.c @@ -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), diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c index 58ec6733efaa..7fb51f4e9dcb 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/utilities/utalloc.c @@ -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 */ diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index b3b8757c1a20..72b0347d2564 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c @@ -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); @@ -191,6 +190,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 * * PARAMETERS: Object - Object to be validated diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index e4a0f1e6f814..5911d1b3c589 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -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, diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h index a43e91fb972c..f87445f46b54 100644 --- a/include/acpi/acinterp.h +++ b/include/acpi/acinterp.h @@ -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 ( diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h index 0d479722f4aa..09d6a5af268c 100644 --- a/include/acpi/acobject.h +++ b/include/acpi/acobject.h @@ -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 diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 8bee457d81d6..c5bd3036c57a 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -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 diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h index d786ae5ec820..ab3784a0cf58 100644 --- a/include/acpi/acutils.h +++ b/include/acpi/acutils.h @@ -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 diff --git a/include/acpi/amlcode.h b/include/acpi/amlcode.h index 0344b94c863d..1d06e16648cc 100644 --- a/include/acpi/amlcode.h +++ b/include/acpi/amlcode.h @@ -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 */ diff --git a/include/acpi/amlresrc.h b/include/acpi/amlresrc.h index b28b6905b71e..89a52ddae530 100644 --- a/include/acpi/amlresrc.h +++ b/include/acpi/amlresrc.h @@ -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 { |
