/******************************************************************************1*2* Module Name: dsargs - Support for execution of dynamic arguments for static3* objects (regions, fields, buffer fields, etc.)4*5*****************************************************************************/67/*8* Copyright (C) 2000 - 2011, Intel Corp.9* All rights reserved.10*11* Redistribution and use in source and binary forms, with or without12* modification, are permitted provided that the following conditions13* are met:14* 1. Redistributions of source code must retain the above copyright15* notice, this list of conditions, and the following disclaimer,16* without modification.17* 2. Redistributions in binary form must reproduce at minimum a disclaimer18* substantially similar to the "NO WARRANTY" disclaimer below19* ("Disclaimer") and any redistribution must be conditioned upon20* including a substantially similar Disclaimer requirement for further21* binary redistribution.22* 3. Neither the names of the above-listed copyright holders nor the names23* of any contributors may be used to endorse or promote products derived24* from this software without specific prior written permission.25*26* Alternatively, this software may be distributed under the terms of the27* GNU General Public License ("GPL") version 2 as published by the Free28* Software Foundation.29*30* NO WARRANTY31* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS32* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT33* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR34* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT35* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL36* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS37* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)38* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,39* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING40* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE41* POSSIBILITY OF SUCH DAMAGES.42*/4344#include <acpi/acpi.h>45#include "accommon.h"46#include "acparser.h"47#include "amlcode.h"48#include "acdispat.h"49#include "acnamesp.h"5051#define _COMPONENT ACPI_DISPATCHER52ACPI_MODULE_NAME("dsargs")5354/* Local prototypes */55static acpi_status56acpi_ds_execute_arguments(struct acpi_namespace_node *node,57struct acpi_namespace_node *scope_node,58u32 aml_length, u8 *aml_start);5960/*******************************************************************************61*62* FUNCTION: acpi_ds_execute_arguments63*64* PARAMETERS: Node - Object NS node65* scope_node - Parent NS node66* aml_length - Length of executable AML67* aml_start - Pointer to the AML68*69* RETURN: Status.70*71* DESCRIPTION: Late (deferred) execution of region or field arguments72*73******************************************************************************/7475static acpi_status76acpi_ds_execute_arguments(struct acpi_namespace_node *node,77struct acpi_namespace_node *scope_node,78u32 aml_length, u8 *aml_start)79{80acpi_status status;81union acpi_parse_object *op;82struct acpi_walk_state *walk_state;8384ACPI_FUNCTION_TRACE(ds_execute_arguments);8586/* Allocate a new parser op to be the root of the parsed tree */8788op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);89if (!op) {90return_ACPI_STATUS(AE_NO_MEMORY);91}9293/* Save the Node for use in acpi_ps_parse_aml */9495op->common.node = scope_node;9697/* Create and initialize a new parser state */9899walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);100if (!walk_state) {101status = AE_NO_MEMORY;102goto cleanup;103}104105status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,106aml_length, NULL, ACPI_IMODE_LOAD_PASS1);107if (ACPI_FAILURE(status)) {108acpi_ds_delete_walk_state(walk_state);109goto cleanup;110}111112/* Mark this parse as a deferred opcode */113114walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;115walk_state->deferred_node = node;116117/* Pass1: Parse the entire declaration */118119status = acpi_ps_parse_aml(walk_state);120if (ACPI_FAILURE(status)) {121goto cleanup;122}123124/* Get and init the Op created above */125126op->common.node = node;127acpi_ps_delete_parse_tree(op);128129/* Evaluate the deferred arguments */130131op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);132if (!op) {133return_ACPI_STATUS(AE_NO_MEMORY);134}135136op->common.node = scope_node;137138/* Create and initialize a new parser state */139140walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);141if (!walk_state) {142status = AE_NO_MEMORY;143goto cleanup;144}145146/* Execute the opcode and arguments */147148status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,149aml_length, NULL, ACPI_IMODE_EXECUTE);150if (ACPI_FAILURE(status)) {151acpi_ds_delete_walk_state(walk_state);152goto cleanup;153}154155/* Mark this execution as a deferred opcode */156157walk_state->deferred_node = node;158status = acpi_ps_parse_aml(walk_state);159160cleanup:161acpi_ps_delete_parse_tree(op);162return_ACPI_STATUS(status);163}164165/*******************************************************************************166*167* FUNCTION: acpi_ds_get_buffer_field_arguments168*169* PARAMETERS: obj_desc - A valid buffer_field object170*171* RETURN: Status.172*173* DESCRIPTION: Get buffer_field Buffer and Index. This implements the late174* evaluation of these field attributes.175*176******************************************************************************/177178acpi_status179acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)180{181union acpi_operand_object *extra_desc;182struct acpi_namespace_node *node;183acpi_status status;184185ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc);186187if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {188return_ACPI_STATUS(AE_OK);189}190191/* Get the AML pointer (method object) and buffer_field node */192193extra_desc = acpi_ns_get_secondary_object(obj_desc);194node = obj_desc->buffer_field.node;195196ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_BUFFER_FIELD,197node, NULL));198199ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",200acpi_ut_get_node_name(node)));201202/* Execute the AML code for the term_arg arguments */203204status = acpi_ds_execute_arguments(node, node->parent,205extra_desc->extra.aml_length,206extra_desc->extra.aml_start);207return_ACPI_STATUS(status);208}209210/*******************************************************************************211*212* FUNCTION: acpi_ds_get_bank_field_arguments213*214* PARAMETERS: obj_desc - A valid bank_field object215*216* RETURN: Status.217*218* DESCRIPTION: Get bank_field bank_value. This implements the late219* evaluation of these field attributes.220*221******************************************************************************/222223acpi_status224acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)225{226union acpi_operand_object *extra_desc;227struct acpi_namespace_node *node;228acpi_status status;229230ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc);231232if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {233return_ACPI_STATUS(AE_OK);234}235236/* Get the AML pointer (method object) and bank_field node */237238extra_desc = acpi_ns_get_secondary_object(obj_desc);239node = obj_desc->bank_field.node;240241ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname242(ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL));243244ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",245acpi_ut_get_node_name(node)));246247/* Execute the AML code for the term_arg arguments */248249status = acpi_ds_execute_arguments(node, node->parent,250extra_desc->extra.aml_length,251extra_desc->extra.aml_start);252return_ACPI_STATUS(status);253}254255/*******************************************************************************256*257* FUNCTION: acpi_ds_get_buffer_arguments258*259* PARAMETERS: obj_desc - A valid Buffer object260*261* RETURN: Status.262*263* DESCRIPTION: Get Buffer length and initializer byte list. This implements264* the late evaluation of these attributes.265*266******************************************************************************/267268acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc)269{270struct acpi_namespace_node *node;271acpi_status status;272273ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc);274275if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {276return_ACPI_STATUS(AE_OK);277}278279/* Get the Buffer node */280281node = obj_desc->buffer.node;282if (!node) {283ACPI_ERROR((AE_INFO,284"No pointer back to namespace node in buffer object %p",285obj_desc));286return_ACPI_STATUS(AE_AML_INTERNAL);287}288289ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n"));290291/* Execute the AML code for the term_arg arguments */292293status = acpi_ds_execute_arguments(node, node,294obj_desc->buffer.aml_length,295obj_desc->buffer.aml_start);296return_ACPI_STATUS(status);297}298299/*******************************************************************************300*301* FUNCTION: acpi_ds_get_package_arguments302*303* PARAMETERS: obj_desc - A valid Package object304*305* RETURN: Status.306*307* DESCRIPTION: Get Package length and initializer byte list. This implements308* the late evaluation of these attributes.309*310******************************************************************************/311312acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc)313{314struct acpi_namespace_node *node;315acpi_status status;316317ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc);318319if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {320return_ACPI_STATUS(AE_OK);321}322323/* Get the Package node */324325node = obj_desc->package.node;326if (!node) {327ACPI_ERROR((AE_INFO,328"No pointer back to namespace node in package %p",329obj_desc));330return_ACPI_STATUS(AE_AML_INTERNAL);331}332333ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Arg Init\n"));334335/* Execute the AML code for the term_arg arguments */336337status = acpi_ds_execute_arguments(node, node,338obj_desc->package.aml_length,339obj_desc->package.aml_start);340return_ACPI_STATUS(status);341}342343/*******************************************************************************344*345* FUNCTION: acpi_ds_get_region_arguments346*347* PARAMETERS: obj_desc - A valid region object348*349* RETURN: Status.350*351* DESCRIPTION: Get region address and length. This implements the late352* evaluation of these region attributes.353*354******************************************************************************/355356acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)357{358struct acpi_namespace_node *node;359acpi_status status;360union acpi_operand_object *extra_desc;361362ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc);363364if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {365return_ACPI_STATUS(AE_OK);366}367368extra_desc = acpi_ns_get_secondary_object(obj_desc);369if (!extra_desc) {370return_ACPI_STATUS(AE_NOT_EXIST);371}372373/* Get the Region node */374375node = obj_desc->region.node;376377ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname378(ACPI_TYPE_REGION, node, NULL));379380ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",381acpi_ut_get_node_name(node),382extra_desc->extra.aml_start));383384/* Execute the argument AML */385386status = acpi_ds_execute_arguments(node, node->parent,387extra_desc->extra.aml_length,388extra_desc->extra.aml_start);389return_ACPI_STATUS(status);390}391392393