diff options
Diffstat (limited to 'drivers/acpi/acpica/exmisc.c')
| -rw-r--r-- | drivers/acpi/acpica/exmisc.c | 344 |
1 files changed, 31 insertions, 313 deletions
diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index 00bf29877574..07cbac58ed21 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c @@ -1,51 +1,16 @@ +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 /****************************************************************************** * * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2013, Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * Copyright (C) 2000 - 2025, Intel Corp. * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - */ + *****************************************************************************/ #include <acpi/acpi.h> #include "accommon.h" #include "acinterp.h" #include "amlcode.h" -#include "amlresrc.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exmisc") @@ -98,9 +63,9 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, default: - ACPI_ERROR((AE_INFO, "Unknown Reference Class 0x%2.2X", + ACPI_ERROR((AE_INFO, "Invalid Reference Class 0x%2.2X", obj_desc->reference.class)); - return_ACPI_STATUS(AE_AML_INTERNAL); + return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } break; @@ -140,263 +105,6 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, /******************************************************************************* * - * FUNCTION: acpi_ex_concat_template - * - * 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 - * - * DESCRIPTION: Concatenate two resource templates - * - ******************************************************************************/ - -acpi_status -acpi_ex_concat_template(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; - union acpi_operand_object *return_desc; - u8 *new_buf; - u8 *end_tag; - acpi_size length0; - acpi_size length1; - acpi_size new_length; - - ACPI_FUNCTION_TRACE(ex_concat_template); - - /* - * Find the end_tag descriptor in each resource template. - * Note1: returned pointers point TO the end_tag, not past it. - * Note2: zero-length buffers are allowed; treated like one end_tag - */ - - /* Get the length of the first resource template */ - - status = acpi_ut_get_resource_end_tag(operand0, &end_tag); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer); - - /* Get the length of the second resource template */ - - status = acpi_ut_get_resource_end_tag(operand1, &end_tag); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer); - - /* Combine both lengths, minimum size will be 2 for end_tag */ - - new_length = length0 + length1 + sizeof(struct aml_resource_end_tag); - - /* Create a new buffer object for the result (with one end_tag) */ - - return_desc = acpi_ut_create_buffer_object(new_length); - if (!return_desc) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - /* - * Copy the templates to the new buffer, 0 first, then 1 follows. One - * end_tag descriptor is copied from Operand1. - */ - new_buf = return_desc->buffer.pointer; - ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length0); - ACPI_MEMCPY(new_buf + length0, operand1->buffer.pointer, length1); - - /* Insert end_tag and set the checksum to zero, means "ignore checksum" */ - - new_buf[new_length - 1] = 0; - new_buf[new_length - 2] = ACPI_RESOURCE_NAME_END_TAG | 1; - - /* Return the completed resource template */ - - *actual_return_desc = return_desc; - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ex_do_concatenate - * - * 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 - * - * DESCRIPTION: Concatenate two objects OF THE SAME TYPE. - * - ******************************************************************************/ - -acpi_status -acpi_ex_do_concatenate(union acpi_operand_object *operand0, - union acpi_operand_object *operand1, - union acpi_operand_object **actual_return_desc, - struct acpi_walk_state *walk_state) -{ - union acpi_operand_object *local_operand1 = operand1; - union acpi_operand_object *return_desc; - char *new_buf; - acpi_status status; - - 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 (operand0->common.type) { - case ACPI_TYPE_INTEGER: - - status = - acpi_ex_convert_to_integer(operand1, &local_operand1, 16); - break; - - case ACPI_TYPE_STRING: - - status = acpi_ex_convert_to_string(operand1, &local_operand1, - ACPI_IMPLICIT_CONVERT_HEX); - break; - - case ACPI_TYPE_BUFFER: - - status = acpi_ex_convert_to_buffer(operand1, &local_operand1); - break; - - default: - - ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X", - operand0->common.type)); - 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: - * - * 1) Two Integers concatenated to produce a new Buffer - * 2) Two Strings concatenated to produce a new String - * 3) Two Buffers concatenated to produce a new Buffer - */ - switch (operand0->common.type) { - 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_size) - ACPI_MUL_2 - (acpi_gbl_integer_byte_width)); - if (!return_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - new_buf = (char *)return_desc->buffer.pointer; - - /* Copy the first integer, LSB first */ - - ACPI_MEMCPY(new_buf, &operand0->integer.value, - acpi_gbl_integer_byte_width); - - /* 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_string_object(((acpi_size) - operand0->string. - length + - local_operand1-> - string.length)); - if (!return_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - new_buf = return_desc->string.pointer; - - /* Concatenate the strings */ - - 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) - operand0->buffer. - length + - local_operand1-> - buffer.length)); - if (!return_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - new_buf = (char *)return_desc->buffer.pointer; - - /* Concatenate the buffers */ - - 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_ERROR((AE_INFO, "Invalid object type: 0x%X", - operand0->common.type)); - status = AE_AML_INTERNAL; - goto cleanup; - } - - *actual_return_desc = return_desc; - - cleanup: - if (local_operand1 != operand1) { - acpi_ut_remove_reference(local_operand1); - } - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * * FUNCTION: acpi_ex_do_math_op * * PARAMETERS: opcode - AML opcode @@ -507,14 +215,14 @@ acpi_ex_do_logical_numeric_op(u16 opcode, ACPI_FUNCTION_TRACE(ex_do_logical_numeric_op); switch (opcode) { - case AML_LAND_OP: /* LAnd (Integer0, Integer1) */ + case AML_LOGICAL_AND_OP: /* LAnd (Integer0, Integer1) */ if (integer0 && integer1) { local_result = TRUE; } break; - case AML_LOR_OP: /* LOr (Integer0, Integer1) */ + case AML_LOGICAL_OR_OP: /* LOr (Integer0, Integer1) */ if (integer0 || integer1) { local_result = TRUE; @@ -523,6 +231,8 @@ acpi_ex_do_logical_numeric_op(u16 opcode, default: + ACPI_ERROR((AE_INFO, + "Invalid numeric logical opcode: %X", opcode)); status = AE_AML_INTERNAL; break; } @@ -585,14 +295,15 @@ acpi_ex_do_logical_op(u16 opcode, switch (operand0->common.type) { case ACPI_TYPE_INTEGER: - status = - acpi_ex_convert_to_integer(operand1, &local_operand1, 16); + status = acpi_ex_convert_to_integer(operand1, &local_operand1, + ACPI_IMPLICIT_CONVERSION); break; case ACPI_TYPE_STRING: - status = acpi_ex_convert_to_string(operand1, &local_operand1, - ACPI_IMPLICIT_CONVERT_HEX); + status = + acpi_ex_convert_to_string(operand1, &local_operand1, + ACPI_IMPLICIT_CONVERT_HEX); break; case ACPI_TYPE_BUFFER: @@ -602,6 +313,9 @@ acpi_ex_do_logical_op(u16 opcode, default: + ACPI_ERROR((AE_INFO, + "Invalid object type for logical operator: %X", + operand0->common.type)); status = AE_AML_INTERNAL; break; } @@ -622,21 +336,21 @@ acpi_ex_do_logical_op(u16 opcode, integer1 = local_operand1->integer.value; switch (opcode) { - case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */ + case AML_LOGICAL_EQUAL_OP: /* LEqual (Operand0, Operand1) */ if (integer0 == integer1) { local_result = TRUE; } break; - case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */ + case AML_LOGICAL_GREATER_OP: /* LGreater (Operand0, Operand1) */ if (integer0 > integer1) { local_result = TRUE; } break; - case AML_LLESS_OP: /* LLess (Operand0, Operand1) */ + case AML_LOGICAL_LESS_OP: /* LLess (Operand0, Operand1) */ if (integer0 < integer1) { local_result = TRUE; @@ -645,6 +359,8 @@ acpi_ex_do_logical_op(u16 opcode, default: + ACPI_ERROR((AE_INFO, + "Invalid comparison opcode: %X", opcode)); status = AE_AML_INTERNAL; break; } @@ -660,12 +376,12 @@ acpi_ex_do_logical_op(u16 opcode, /* Lexicographic compare: compare the data bytes */ - compare = ACPI_MEMCMP(operand0->buffer.pointer, - local_operand1->buffer.pointer, - (length0 > length1) ? length1 : length0); + compare = memcmp(operand0->buffer.pointer, + local_operand1->buffer.pointer, + (length0 > length1) ? length1 : length0); switch (opcode) { - case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */ + case AML_LOGICAL_EQUAL_OP: /* LEqual (Operand0, Operand1) */ /* Length and all bytes must be equal */ @@ -677,7 +393,7 @@ acpi_ex_do_logical_op(u16 opcode, } break; - case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */ + case AML_LOGICAL_GREATER_OP: /* LGreater (Operand0, Operand1) */ if (compare > 0) { local_result = TRUE; @@ -694,7 +410,7 @@ acpi_ex_do_logical_op(u16 opcode, } break; - case AML_LLESS_OP: /* LLess (Operand0, Operand1) */ + case AML_LOGICAL_LESS_OP: /* LLess (Operand0, Operand1) */ if (compare > 0) { goto cleanup; /* FALSE */ @@ -713,12 +429,14 @@ acpi_ex_do_logical_op(u16 opcode, default: + ACPI_ERROR((AE_INFO, + "Invalid comparison opcode: %X", opcode)); status = AE_AML_INTERNAL; break; } } - cleanup: +cleanup: /* New object was created if implicit conversion performed - delete */ |
