diff options
author | Len Brown <len.brown@intel.com> | 2009-01-09 00:13:17 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-01-09 03:30:47 -0500 |
commit | 95b482a8d31116f3f5c2a5089569393234d06385 (patch) | |
tree | f32aec8673a285a9d188948be97af3034ee06e93 /drivers/acpi/dispatcher/dsopcode.c | |
parent | 6620e0c49f577454b772fb381543d60ae53eb885 (diff) |
ACPICA: create acpica/ directory
also, delete sleep/ and delete ACPI_CFLAGS from Makefile
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/dispatcher/dsopcode.c')
-rw-r--r-- | drivers/acpi/dispatcher/dsopcode.c | 1469 |
1 files changed, 0 insertions, 1469 deletions
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c deleted file mode 100644 index cb8a0d3109f..00000000000 --- a/drivers/acpi/dispatcher/dsopcode.c +++ /dev/null @@ -1,1469 +0,0 @@ -/****************************************************************************** - * - * Module Name: dsopcode - Dispatcher Op Region support and handling of - * "control" opcodes - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2008, 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. - * - * 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 <acpi/accommon.h> -#include <acpi/acparser.h> -#include <acpi/amlcode.h> -#include <acpi/acdispat.h> -#include <acpi/acinterp.h> -#include <acpi/acnamesp.h> -#include <acpi/acevents.h> -#include <acpi/actables.h> - -#define _COMPONENT ACPI_DISPATCHER -ACPI_MODULE_NAME("dsopcode") - -/* Local prototypes */ -static acpi_status -acpi_ds_execute_arguments(struct acpi_namespace_node *node, - struct acpi_namespace_node *scope_node, - u32 aml_length, u8 * aml_start); - -static acpi_status -acpi_ds_init_buffer_field(u16 aml_opcode, - union acpi_operand_object *obj_desc, - union acpi_operand_object *buffer_desc, - union acpi_operand_object *offset_desc, - union acpi_operand_object *length_desc, - union acpi_operand_object *result_desc); - -/******************************************************************************* - * - * FUNCTION: acpi_ds_execute_arguments - * - * PARAMETERS: Node - Object NS node - * scope_node - Parent NS node - * aml_length - Length of executable AML - * aml_start - Pointer to the AML - * - * RETURN: Status. - * - * DESCRIPTION: Late (deferred) execution of region or field arguments - * - ******************************************************************************/ - -static acpi_status -acpi_ds_execute_arguments(struct acpi_namespace_node *node, - struct acpi_namespace_node *scope_node, - u32 aml_length, u8 * aml_start) -{ - acpi_status status; - union acpi_parse_object *op; - struct acpi_walk_state *walk_state; - - ACPI_FUNCTION_TRACE(ds_execute_arguments); - - /* - * Allocate a new parser op to be the root of the parsed tree - */ - op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP); - if (!op) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - /* Save the Node for use in acpi_ps_parse_aml */ - - op->common.node = scope_node; - - /* Create and initialize a new parser state */ - - walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL); - if (!walk_state) { - status = AE_NO_MEMORY; - goto cleanup; - } - - status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, - aml_length, NULL, ACPI_IMODE_LOAD_PASS1); - if (ACPI_FAILURE(status)) { - acpi_ds_delete_walk_state(walk_state); - goto cleanup; - } - - /* Mark this parse as a deferred opcode */ - - walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP; - walk_state->deferred_node = node; - - /* Pass1: Parse the entire declaration */ - - status = acpi_ps_parse_aml(walk_state); - if (ACPI_FAILURE(status)) { - goto cleanup; - } - - /* Get and init the Op created above */ - - op->common.node = node; - acpi_ps_delete_parse_tree(op); - - /* Evaluate the deferred arguments */ - - op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP); - if (!op) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - op->common.node = scope_node; - - /* Create and initialize a new parser state */ - - walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL); - if (!walk_state) { - status = AE_NO_MEMORY; - goto cleanup; - } - - /* Execute the opcode and arguments */ - - status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, - aml_length, NULL, ACPI_IMODE_EXECUTE); - if (ACPI_FAILURE(status)) { - acpi_ds_delete_walk_state(walk_state); - goto cleanup; - } - - /* Mark this execution as a deferred opcode */ - - walk_state->deferred_node = node; - status = acpi_ps_parse_aml(walk_state); - - cleanup: - acpi_ps_delete_parse_tree(op); - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ds_get_buffer_field_arguments - * - * PARAMETERS: obj_desc - A valid buffer_field object - * - * RETURN: Status. - * - * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late - * evaluation of these field attributes. - * - ******************************************************************************/ - -acpi_status -acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc) -{ - union acpi_operand_object *extra_desc; - struct acpi_namespace_node *node; - acpi_status status; - - ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc); - - if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { - return_ACPI_STATUS(AE_OK); - } - - /* Get the AML pointer (method object) and buffer_field node */ - - extra_desc = acpi_ns_get_secondary_object(obj_desc); - node = obj_desc->buffer_field.node; - - ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname - (ACPI_TYPE_BUFFER_FIELD, node, NULL)); - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n", - acpi_ut_get_node_name(node))); - - /* Execute the AML code for the term_arg arguments */ - - status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), - extra_desc->extra.aml_length, - extra_desc->extra.aml_start); - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ds_get_bank_field_arguments - * - * PARAMETERS: obj_desc - A valid bank_field object - * - * RETURN: Status. - * - * DESCRIPTION: Get bank_field bank_value. This implements the late - * evaluation of these field attributes. - * - ******************************************************************************/ - -acpi_status -acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc) -{ - union acpi_operand_object *extra_desc; - struct acpi_namespace_node *node; - acpi_status status; - - ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc); - - if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { - return_ACPI_STATUS(AE_OK); - } - - /* Get the AML pointer (method object) and bank_field node */ - - extra_desc = acpi_ns_get_secondary_object(obj_desc); - node = obj_desc->bank_field.node; - - ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname - (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL)); - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n", - acpi_ut_get_node_name(node))); - - /* Execute the AML code for the term_arg arguments */ - - status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), - extra_desc->extra.aml_length, - extra_desc->extra.aml_start); - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ds_get_buffer_arguments - * - * PARAMETERS: obj_desc - A valid Buffer object - * - * RETURN: Status. - * - * DESCRIPTION: Get Buffer length and initializer byte list. This implements - * the late evaluation of these attributes. - * - ******************************************************************************/ - -acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc) -{ - struct acpi_namespace_node *node; - acpi_status status; - - ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc); - - if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { - return_ACPI_STATUS(AE_OK); - } - - /* Get the Buffer node */ - - node = obj_desc->buffer.node; - if (!node) { - ACPI_ERROR((AE_INFO, - "No pointer back to NS node in buffer obj %p", - obj_desc)); - return_ACPI_STATUS(AE_AML_INTERNAL); - } - - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n")); - - /* Execute the AML code for the term_arg arguments */ - - status = acpi_ds_execute_arguments(node, node, - obj_desc->buffer.aml_length, - obj_desc->buffer.aml_start); - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ds_get_package_arguments - * - * PARAMETERS: obj_desc - A valid Package object - * - * RETURN: Status. - * - * DESCRIPTION: Get Package length and initializer byte list. This implements - * the late evaluation of these attributes. - * - ******************************************************************************/ - -acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc) -{ - struct acpi_namespace_node *node; - acpi_status status; - - ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc); - - if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { - return_ACPI_STATUS(AE_OK); - } - - /* Get the Package node */ - - node = obj_desc->package.node; - if (!node) { - ACPI_ERROR((AE_INFO, - "No pointer back to NS node in package %p", - obj_desc)); - return_ACPI_STATUS(AE_AML_INTERNAL); - } - - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Arg Init\n")); - - /* Execute the AML code for the term_arg arguments */ - - status = acpi_ds_execute_arguments(node, node, - obj_desc->package.aml_length, - obj_desc->package.aml_start); - return_ACPI_STATUS(status); -} - -/***************************************************************************** - * - * FUNCTION: acpi_ds_get_region_arguments - * - * PARAMETERS: obj_desc - A valid region object - * - * RETURN: Status. - * - * DESCRIPTION: Get region address and length. This implements the late - * evaluation of these region attributes. - * - ****************************************************************************/ - -acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc) -{ - struct acpi_namespace_node *node; - acpi_status status; - union acpi_operand_object *extra_desc; - - ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc); - - if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { - return_ACPI_STATUS(AE_OK); - } - - extra_desc = acpi_ns_get_secondary_object(obj_desc); - if (!extra_desc) { - return_ACPI_STATUS(AE_NOT_EXIST); - } - - /* Get the Region node */ - - node = obj_desc->region.node; - - ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname - (ACPI_TYPE_REGION, node, NULL)); - - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n", - acpi_ut_get_node_name(node), - extra_desc->extra.aml_start)); - - /* Execute the argument AML */ - - status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), - extra_desc->extra.aml_length, - extra_desc->extra.aml_start); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Validate the region address/length via the host OS */ - - status = acpi_os_validate_address(obj_desc->region.space_id, - obj_desc->region.address, - (acpi_size) obj_desc->region.length, - acpi_ut_get_node_name(node)); - - if (ACPI_FAILURE(status)) { - /* - * Invalid address/length. We will emit an error message and mark - * the region as invalid, so that it will cause an additional error if - * it is ever used. Then return AE_OK. - */ - ACPI_EXCEPTION((AE_INFO, status, - "During address validation of OpRegion [%4.4s]", - node->name.ascii)); - obj_desc->common.flags |= AOPOBJ_INVALID; - status = AE_OK; - } - - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ds_initialize_region - * - * PARAMETERS: obj_handle - Region namespace node - * - * RETURN: Status - * - * DESCRIPTION: Front end to ev_initialize_region - * - ******************************************************************************/ - -acpi_status acpi_ds_initialize_region(acpi_handle obj_handle) -{ - union acpi_operand_object *obj_desc; - acpi_status status; - - obj_desc = acpi_ns_get_attached_object(obj_handle); - - /* Namespace is NOT locked */ - - status = acpi_ev_initialize_region(obj_desc, FALSE); - return (status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ds_init_buffer_field - * - * PARAMETERS: aml_opcode - create_xxx_field - * obj_desc - buffer_field object - * buffer_desc - Host Buffer - * offset_desc - Offset into buffer - * length_desc - Length of field (CREATE_FIELD_OP only) - * result_desc - Where to store the result - * - * RETURN: Status - * - * DESCRIPTION: Perform actual initialization of a buffer field - * - ******************************************************************************/ - -static acpi_status -acpi_ds_init_buffer_field(u16 aml_opcode, - union acpi_operand_object *obj_desc, - union acpi_operand_object *buffer_desc, - union acpi_operand_object *offset_desc, - union acpi_operand_object *length_desc, - union acpi_operand_object *result_desc) -{ - u32 offset; - u32 bit_offset; - u32 bit_count; - u8 field_flags; - acpi_status status; - - ACPI_FUNCTION_TRACE_PTR(ds_init_buffer_field, obj_desc); - - /* Host object must be a Buffer */ - - if (ACPI_GET_OBJECT_TYPE(buffer_desc) != ACPI_TYPE_BUFFER) { - ACPI_ERROR((AE_INFO, - "Target of Create Field is not a Buffer object - %s", - acpi_ut_get_object_type_name(buffer_desc))); - - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - - /* - * The last parameter to all of these opcodes (result_desc) started - * out as a name_string, and should therefore now be a NS node - * after resolution in acpi_ex_resolve_operands(). - */ - if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) { - ACPI_ERROR((AE_INFO, - "(%s) destination not a NS Node [%s]", - acpi_ps_get_opcode_name(aml_opcode), - acpi_ut_get_descriptor_name(result_desc))); - - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - - offset = (u32) offset_desc->integer.value; - - /* - * Setup the Bit offsets and counts, according to the opcode - */ - switch (aml_opcode) { - case AML_CREATE_FIELD_OP: - - /* Offset is in bits, count is in bits */ - - field_flags = AML_FIELD_ACCESS_BYTE; - bit_offset = offset; - bit_count = (u32) length_desc->integer.value; - - /* Must have a valid (>0) bit count */ - - if (bit_count == 0) { - ACPI_ERROR((AE_INFO, - "Attempt to CreateField of length zero")); - status = AE_AML_OPERAND_VALUE; - goto cleanup; - } - break; - - case AML_CREATE_BIT_FIELD_OP: - - /* Offset is in bits, Field is one bit */ - - bit_offset = offset; - bit_count = 1; - field_flags = AML_FIELD_ACCESS_BYTE; - break; - - case AML_CREATE_BYTE_FIELD_OP: - - /* Offset is in bytes, field is one byte */ - - bit_offset = 8 * offset; - bit_count = 8; - field_flags = AML_FIELD_ACCESS_BYTE; - break; - - case AML_CREATE_WORD_FIELD_OP: - - /* Offset is in bytes, field is one word */ - - bit_offset = 8 * offset; - bit_count = 16; - field_flags = AML_FIELD_ACCESS_WORD; - break; - - case AML_CREATE_DWORD_FIELD_OP: - - /* Offset is in bytes, field is one dword */ - - bit_offset = 8 * offset; - bit_count = 32; - field_flags = AML_FIELD_ACCESS_DWORD; - break; - - case AML_CREATE_QWORD_FIELD_OP: - - /* Offset is in bytes, field is one qword */ - - bit_offset = 8 * offset; - bit_count = 64; - field_flags = AML_FIELD_ACCESS_QWORD; - break; - - default: - - ACPI_ERROR((AE_INFO, - "Unknown field creation opcode %02x", aml_opcode)); - status = AE_AML_BAD_OPCODE; - goto cleanup; - } - - /* Entire field must fit within the current length of the buffer */ - - if ((bit_offset + bit_count) > (8 * (u32) buffer_desc->buffer.length)) { - ACPI_ERROR((AE_INFO, - "Field [%4.4s] at %d exceeds Buffer [%4.4s] size %d (bits)", - acpi_ut_get_node_name(result_desc), - bit_offset + bit_count, - acpi_ut_get_node_name(buffer_desc->buffer.node), - 8 * (u32) buffer_desc->buffer.length)); - status = AE_AML_BUFFER_LIMIT; - goto cleanup; - } - - /* - * Initialize areas of the field object that are common to all fields - * For field_flags, use LOCK_RULE = 0 (NO_LOCK), - * UPDATE_RULE = 0 (UPDATE_PRESERVE) - */ - status = acpi_ex_prep_common_field_object(obj_desc, field_flags, 0, - bit_offset, bit_count); - if (ACPI_FAILURE(status)) { - goto cleanup; - } - - obj_desc->buffer_field.buffer_obj = buffer_desc; - - /* Reference count for buffer_desc inherits obj_desc count */ - - buffer_desc->common.reference_count = (u16) - (buffer_desc->common.reference_count + - obj_desc->common.reference_count); - - cleanup: - - /* Always delete the operands */ - - acpi_ut_remove_reference(offset_desc); - acpi_ut_remove_reference(buffer_desc); - - if (aml_opcode == AML_CREATE_FIELD_OP) { - acpi_ut_remove_reference(length_desc); - } - - /* On failure, delete the result descriptor */ - - if (ACPI_FAILURE(status)) { - acpi_ut_remove_reference(result_desc); /* Result descriptor */ - } else { - /* Now the address and length are valid for this buffer_field */ - - obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID; - } - - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ds_eval_buffer_field_operands - * - * PARAMETERS: walk_state - Current walk - * Op - A valid buffer_field Op object - * - * RETURN: Status - * - * DESCRIPTION: Get buffer_field Buffer and Index - * Called from acpi_ds_exec_end_op during buffer_field parse tree walk - * - ******************************************************************************/ - -acpi_status -acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state, - union acpi_parse_object *op) -{ - acpi_status status; - union acpi_operand_object *obj_desc; - struct acpi_namespace_node *node; - union acpi_parse_object *next_op; - - ACPI_FUNCTION_TRACE_PTR(ds_eval_buffer_field_operands, op); - - /* - * This is where we evaluate the address and length fields of the - * create_xxx_field declaration - */ - node = op->common.node; - - /* next_op points to the op that holds the Buffer */ - - next_op = op->common.value.arg; - - /* Evaluate/create the address and length operands */ - - status = acpi_ds_create_operands(walk_state, next_op); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - obj_desc = acpi_ns_get_attached_object(node); - if (!obj_desc) { - return_ACPI_STATUS(AE_NOT_EXIST); - } - - /* Resolve the operands */ - - status = acpi_ex_resolve_operands(op->common.aml_opcode, - ACPI_WALK_OPERANDS, walk_state); - if (ACPI_FAILURE(status)) { - ACPI_ERROR((AE_INFO, "(%s) bad operand(s) (%X)", - acpi_ps_get_opcode_name(op->common.aml_opcode), - status)); - - return_ACPI_STATUS(status); - } - - /* Initialize the Buffer Field */ - - if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { - - /* NOTE: Slightly different operands for this opcode */ - - status = - acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc, - walk_state->operands[0], - walk_state->operands[1], - walk_state->operands[2], - walk_state->operands[3]); - } else { - /* All other, create_xxx_field opcodes */ - - status = - acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc, - walk_state->operands[0], - walk_state->operands[1], NULL, - walk_state->operands[2]); - } - - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ds_eval_region_operands - * - * PARAMETERS: walk_state - Current walk - * Op - A valid region Op object - * - * RETURN: Status - * - * DESCRIPTION: Get region address and length - * Called from acpi_ds_exec_end_op during op_region parse tree walk - * - ******************************************************************************/ - -acpi_status -acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, - union acpi_parse_object *op) -{ - acpi_status status; - union acpi_operand_object *obj_desc; - union acpi_operand_object *operand_desc; - struct acpi_namespace_node *node; - union acpi_parse_object *next_op; - - ACPI_FUNCTION_TRACE_PTR(ds_eval_region_operands, op); - - /* - * This is where we evaluate the address and length fields of the - * op_region declaration - */ - node = op->common.node; - - /* next_op points to the op that holds the space_iD */ - - next_op = op->common.value.arg; - - /* next_op points to address op */ - - next_op = next_op->common.next; - - /* Evaluate/create the address and length operands */ - - status = acpi_ds_create_operands(walk_state, next_op); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Resolve the length and address operands to numbers */ - - status = acpi_ex_resolve_operands(op->common.aml_opcode, - ACPI_WALK_OPERANDS, walk_state); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - obj_desc = acpi_ns_get_attached_object(node); - if (!obj_desc) { - return_ACPI_STATUS(AE_NOT_EXIST); - } - - /* - * Get the length operand and save it - * (at Top of stack) - */ - operand_desc = walk_state->operands[walk_state->num_operands - 1]; - - obj_desc->region.length = (u32) operand_desc->integer.value; - acpi_ut_remove_reference(operand_desc); - - /* - * Get the address and save it - * (at top of stack - 1) - */ - operand_desc = walk_state->operands[walk_state->num_operands - 2]; - - obj_desc->region.address = (acpi_physical_address) - operand_desc->integer.value; - acpi_ut_remove_reference(operand_desc); - - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", - obj_desc, - ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address), - obj_desc->region.length)); - - /* Now the address and length are valid for this opregion */ - - obj_desc->region.flags |= AOPOBJ_DATA_VALID; - - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ds_eval_table_region_operands - * - * PARAMETERS: walk_state - Current walk - * Op - A valid region Op object - * - * RETURN: Status - * - * DESCRIPTION: Get region address and length - * Called from acpi_ds_exec_end_op during data_table_region parse tree walk - * - ******************************************************************************/ - -acpi_status -acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, - union acpi_parse_object *op) -{ - acpi_status status; - union acpi_operand_object *obj_desc; - union acpi_operand_object **operand; - struct acpi_namespace_node *node; - union acpi_parse_object *next_op; - u32 table_index; - struct acpi_table_header *table; - - ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op); - - /* - * This is where we evaluate the signature_string and oem_iDString - * and oem_table_iDString of the data_table_region declaration - */ - node = op->common.node; - - /* next_op points to signature_string op */ - - next_op = op->common.value.arg; - - /* - * Evaluate/create the signature_string and oem_iDString - * and oem_table_iDString operands - */ - status = acpi_ds_create_operands(walk_state, next_op); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Resolve the signature_string and oem_iDString - * and oem_table_iDString operands - */ - status = acpi_ex_resolve_operands(op->common.aml_opcode, - ACPI_WALK_OPERANDS, walk_state); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - operand = &walk_state->operands[0]; - - /* Find the ACPI table */ - - status = acpi_tb_find_table(operand[0]->string.pointer, - operand[1]->string.pointer, - operand[2]->string.pointer, &table_index); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - acpi_ut_remove_reference(operand[0]); - acpi_ut_remove_reference(operand[1]); - acpi_ut_remove_reference(operand[2]); - - status = acpi_get_table_by_index(table_index, &table); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - obj_desc = acpi_ns_get_attached_object(node); - if (!obj_desc) { - return_ACPI_STATUS(AE_NOT_EXIST); - } - - obj_desc->region.address = - (acpi_physical_address) ACPI_TO_INTEGER(table); - obj_desc->region.length = table->length; - - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", - obj_desc, - ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address), - obj_desc->region.length)); - - /* Now the address and length are valid for this opregion */ - - obj_desc->region.flags |= AOPOBJ_DATA_VALID; - - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ds_eval_data_object_operands - * - * PARAMETERS: walk_state - Current walk - * Op - A valid data_object Op object - * obj_desc - data_object - * - * RETURN: Status - * - * DESCRIPTION: Get the operands and complete the following data object types: - * Buffer, Package. - * - ******************************************************************************/ - -acpi_status -acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, - union acpi_parse_object *op, - union acpi_operand_object *obj_desc) -{ - acpi_status status; - union acpi_operand_object *arg_desc; - u32 length; - - ACPI_FUNCTION_TRACE(ds_eval_data_object_operands); - - /* The first operand (for all of these data objects) is the length */ - - /* - * Set proper index into operand stack for acpi_ds_obj_stack_push - * invoked inside acpi_ds_create_operand. - */ - walk_state->operand_index = walk_state->num_operands; - - status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - status = acpi_ex_resolve_operands(walk_state->opcode, - &(walk_state-> - operands[walk_state->num_operands - - 1]), walk_state); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Extract length operand */ - - arg_desc = walk_state->operands[walk_state->num_operands - 1]; - length = (u32) arg_desc->integer.value; - - /* Cleanup for length operand */ - - status = acpi_ds_obj_stack_pop(1, walk_state); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - acpi_ut_remove_reference(arg_desc); - - /* - * Create the actual data object - */ - switch (op->common.aml_opcode) { - case AML_BUFFER_OP: - - status = - acpi_ds_build_internal_buffer_obj(walk_state, op, length, - &obj_desc); - break; - - case AML_PACKAGE_OP: - case AML_VAR_PACKAGE_OP: - - status = - acpi_ds_build_internal_package_obj(walk_state, op, length, - &obj_desc); - break; - - default: - return_ACPI_STATUS(AE_AML_BAD_OPCODE); - } - - if (ACPI_SUCCESS(status)) { - /* - * Return the object in the walk_state, unless the parent is a package - - * in this case, the return object will be stored in the parse tree - * for the package. - */ - if ((!op->common.parent) || - ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) && - (op->common.parent->common.aml_opcode != - AML_VAR_PACKAGE_OP) - && (op->common.parent->common.aml_opcode != AML_NAME_OP))) { - walk_state->result_obj = obj_desc; - } - } - - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ds_eval_bank_field_operands - * - * PARAMETERS: walk_state - Current walk - * Op - A valid bank_field Op object - * - * RETURN: Status - * - * DESCRIPTION: Get bank_field bank_value - * Called from acpi_ds_exec_end_op during bank_field parse tree walk - * - ******************************************************************************/ - -acpi_status -acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state, - union acpi_parse_object *op) -{ - acpi_status status; - union acpi_operand_object *obj_desc; - union acpi_operand_object *operand_desc; - struct acpi_namespace_node *node; - union acpi_parse_object *next_op; - union acpi_parse_object *arg; - - ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op); - - /* - * This is where we evaluate the bank_value field of the - * bank_field declaration - */ - - /* next_op points to the op that holds the Region */ - - next_op = op->common.value.arg; - - /* next_op points to the op that holds the Bank Register */ - - next_op = next_op->common.next; - - /* next_op points to the op that holds the Bank Value */ - - next_op = next_op->common.next; - - /* - * Set proper index into operand stack for acpi_ds_obj_stack_push - * invoked inside acpi_ds_create_operand. - * - * We use walk_state->Operands[0] to store the evaluated bank_value - */ - walk_state->operand_index = 0; - - status = acpi_ds_create_operand(walk_state, next_op, 0); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, - acpi_ps_get_opcode_name(op->common.aml_opcode), 1); - /* - * Get the bank_value operand and save it - * (at Top of stack) - */ - operand_desc = walk_state->operands[0]; - - /* Arg points to the start Bank Field */ - - arg = acpi_ps_get_arg(op, 4); - while (arg) { - - /* Ignore OFFSET and ACCESSAS terms here */ - - if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { - node = arg->common.node; - - obj_desc = acpi_ns_get_attached_object(node); - if (!obj_desc) { - return_ACPI_STATUS(AE_NOT_EXIST); - } - - obj_desc->bank_field.value = - (u32) operand_desc->integer.value; - } - - /* Move to next field in the list */ - - arg = arg->common.next; - } - - acpi_ut_remove_reference(operand_desc); - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ds_exec_begin_control_op - * - * PARAMETERS: walk_list - The list that owns the walk stack - * Op - The control Op - * - * RETURN: Status - * - * DESCRIPTION: Handles all control ops encountered during control method - * execution. - * - ******************************************************************************/ - -acpi_status -acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state, - union acpi_parse_object *op) -{ - acpi_status status = AE_OK; - union acpi_generic_state *control_state; - - ACPI_FUNCTION_NAME(ds_exec_begin_control_op); - - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op, - op->common.aml_opcode, walk_state)); - - switch (op->common.aml_opcode) { - case AML_WHILE_OP: - - /* - * If this is an additional iteration of a while loop, continue. - * There is no need to allocate a new control state. - */ - if (walk_state->control_state) { - if (walk_state->control_state->control.aml_predicate_start - == (walk_state->parser_state.aml - 1)) { - - /* Reset the state to start-of-loop */ - - walk_state->control_state->common.state = - ACPI_CONTROL_CONDITIONAL_EXECUTING; - break; - } - } - - /*lint -fallthrough */ - - case AML_IF_OP: - - /* - * IF/WHILE: Create a new control state to manage these - * constructs. We need to manage these as a stack, in order - * to handle nesting. - */ - control_state = acpi_ut_create_control_state(); - if (!control_state) { - status = AE_NO_MEMORY; - break; - } - /* - * Save a pointer to the predicate for multiple executions - * of a loop - */ - control_state->control.aml_predicate_start = - walk_state->parser_state.aml - 1; - control_state->control.package_end = - walk_state->parser_state.pkg_end; - control_state->control.opcode = op->common.aml_opcode; - - /* Push the control state on this walk's control stack */ - - acpi_ut_push_generic_state(&walk_state->control_state, - control_state); - break; - - case AML_ELSE_OP: - - /* Predicate is in the state object */ - /* If predicate is true, the IF was executed, ignore ELSE part */ - - if (walk_state->last_predicate) { - status = AE_CTRL_TRUE; - } - - break; - - case AML_RETURN_OP: - - break; - - default: - break; - } - - return (status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ds_exec_end_control_op - * - * PARAMETERS: walk_list - The list that owns the walk stack - * Op - The control Op - * - * RETURN: Status - * - * DESCRIPTION: Handles all control ops encountered during control method - * execution. - * - ******************************************************************************/ - -acpi_status -acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, - union acpi_parse_object * op) -{ - acpi_status status = AE_OK; - union acpi_generic_state *control_state; - - ACPI_FUNCTION_NAME(ds_exec_end_control_op); - - switch (op->common.aml_opcode) { - case AML_IF_OP: - - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op)); - - /* - * Save the result of the predicate in case there is an - * ELSE to come - */ - walk_state->last_predicate = - (u8) walk_state->control_state->common.value; - - /* - * Pop the control state that was created at the start - * of the IF and free it - */ - control_state = - acpi_ut_pop_generic_state(&walk_state->control_state); - acpi_ut_delete_generic_state(control_state); - break; - - case AML_ELSE_OP: - - break; - - case AML_WHILE_OP: - - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op)); - - control_state = walk_state->control_state; - if (control_state->common.value) { - - /* Predicate was true, the body of the loop was just executed */ - - /* - * This loop counter mechanism allows the interpreter to escape - * possibly infinite loops. This can occur in poorly written AML - * when the hardware does not respond within a while loop and the - * loop does not implement a timeout. - */ - control_state->control.loop_count++; - if (control_state->control.loop_count > - ACPI_MAX_LOOP_ITERATIONS) { - status = AE_AML_INFINITE_LOOP; - break; - } - - /* - * Go back and evaluate the predicate and maybe execute the loop - * another time - */ - status = AE_CTRL_PENDING; - walk_state->aml_last_while = - control_state->control.aml_predicate_start; - break; - } - - /* Predicate was false, terminate this while loop */ - - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "[WHILE_OP] termination! Op=%p\n", op)); - - /* Pop this control state and free it */ - - control_state = - acpi_ut_pop_generic_state(&walk_state->control_state); - acpi_ut_delete_generic_state(control_state); - break; - - case AML_RETURN_OP: - - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "[RETURN_OP] Op=%p Arg=%p\n", op, - op->common.value.arg)); - - /* - * One optional operand -- the return value - * It can be either an immediate operand or a result that - * has been bubbled up the tree - */ - if (op->common.value.arg) { - - /* Since we have a real Return(), delete any implicit return */ - - acpi_ds_clear_implicit_return(walk_state); - - /* Return statement has an immediate operand */ - - status = - acpi_ds_create_operands(walk_state, - op->common.value.arg); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* - * If value being returned is a Reference (such as - * an arg or local), resolve it now because it may - * cease to exist at the end of the method. - */ - status = - acpi_ex_resolve_to_value(&walk_state->operands[0], - walk_state); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* - * Get the return value and save as the last result - * value. This is the only place where walk_state->return_desc - * is set to anything other than zero! - */ - walk_state->return_desc = walk_state->operands[0]; - } else if (walk_state->result_count) { - - /* Since we have a real Return(), delete any implicit return */ - - acpi_ds_clear_implicit_return(walk_state); - - /* - * The return value has come from a previous calculation. - * - * If value being returned is a Reference (such as - * an arg or local), resolve it now because it may - * cease to exist at the end of the method. - * - * Allow references created by the Index operator to return unchanged. - */ - if ((ACPI_GET_DESCRIPTOR_TYPE - (walk_state->results->results.obj_desc[0]) == - ACPI_DESC_TYPE_OPERAND) - && - (ACPI_GET_OBJECT_TYPE - (walk_state->results->results.obj_desc[0]) == - ACPI_TYPE_LOCAL_REFERENCE) - && ((walk_state->results->results.obj_desc[0])-> - reference.class != ACPI_REFCLASS_INDEX)) { - status = - acpi_ex_resolve_to_value(&walk_state-> - results->results. - obj_desc[0], - walk_state); - if (ACPI_FAILURE(status)) { - return (status); - } - } - - walk_state->return_desc = - walk_state->results->results.obj_desc[0]; - } else { - /* No return operand */ - - if (walk_state->num_operands) { - acpi_ut_remove_reference(walk_state-> - operands[0]); - } - - walk_state->operands[0] = NULL; - walk_state->num_operands = 0; - walk_state->return_desc = NULL; - } - - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "Completed RETURN_OP State=%p, RetVal=%p\n", - walk_state, walk_state->return_desc)); - - /* End the control method execution right now */ - - status = AE_CTRL_TERMINATE; - break; - - case AML_NOOP_OP: - - /* Just do nothing! */ - break; - - case AML_BREAK_POINT_OP: - - /* Call up to the OS service layer to handle this */ - - status = - acpi_os_signal(ACPI_SIGNAL_BREAKPOINT, - "Executed AML Breakpoint opcode"); - - /* If and when it returns, all done. */ - - break; - - case AML_BREAK_OP: - case AML_CONTINUE_OP: /* ACPI 2.0 */ - - /* Pop and delete control states until we find a while */ - - while (walk_state->control_state && - (walk_state->control_state->control.opcode != - AML_WHILE_OP)) { - control_state = - acpi_ut_pop_generic_state(&walk_state-> - control_state); - acpi_ut_delete_generic_state(control_state); - } - - /* No while found? */ - - if (!walk_state->control_state) { - return (AE_AML_NO_WHILE); - } - - /* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */ - - walk_state->aml_last_while = - walk_state->control_state->control.package_end; - - /* Return status depending on opcode */ - - if (op->common.aml_opcode == AML_BREAK_OP) { - status = AE_CTRL_BREAK; - } else { - status = AE_CTRL_CONTINUE; - } - break; - - default: - - ACPI_ERROR((AE_INFO, "Unknown control opcode=%X Op=%p", - op->common.aml_opcode, op)); - - status = AE_AML_BAD_OPCODE; - break; - } - - return (status); -} |