/******************************************************************************1*2* Module Name: dswload2 - Dispatcher second pass namespace load callbacks3*4*****************************************************************************/56/*7* Copyright (C) 2000 - 2011, Intel Corp.8* All rights reserved.9*10* Redistribution and use in source and binary forms, with or without11* modification, are permitted provided that the following conditions12* are met:13* 1. Redistributions of source code must retain the above copyright14* notice, this list of conditions, and the following disclaimer,15* without modification.16* 2. Redistributions in binary form must reproduce at minimum a disclaimer17* substantially similar to the "NO WARRANTY" disclaimer below18* ("Disclaimer") and any redistribution must be conditioned upon19* including a substantially similar Disclaimer requirement for further20* binary redistribution.21* 3. Neither the names of the above-listed copyright holders nor the names22* of any contributors may be used to endorse or promote products derived23* from this software without specific prior written permission.24*25* Alternatively, this software may be distributed under the terms of the26* GNU General Public License ("GPL") version 2 as published by the Free27* Software Foundation.28*29* NO WARRANTY30* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS31* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT32* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR33* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT34* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL35* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS36* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)37* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,38* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING39* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE40* POSSIBILITY OF SUCH DAMAGES.41*/4243#include <acpi/acpi.h>44#include "accommon.h"45#include "acparser.h"46#include "amlcode.h"47#include "acdispat.h"48#include "acinterp.h"49#include "acnamesp.h"50#include "acevents.h"5152#define _COMPONENT ACPI_DISPATCHER53ACPI_MODULE_NAME("dswload2")5455/*******************************************************************************56*57* FUNCTION: acpi_ds_load2_begin_op58*59* PARAMETERS: walk_state - Current state of the parse tree walk60* out_op - Wher to return op if a new one is created61*62* RETURN: Status63*64* DESCRIPTION: Descending callback used during the loading of ACPI tables.65*66******************************************************************************/67acpi_status68acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,69union acpi_parse_object **out_op)70{71union acpi_parse_object *op;72struct acpi_namespace_node *node;73acpi_status status;74acpi_object_type object_type;75char *buffer_ptr;76u32 flags;7778ACPI_FUNCTION_TRACE(ds_load2_begin_op);7980op = walk_state->op;81ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,82walk_state));8384if (op) {85if ((walk_state->control_state) &&86(walk_state->control_state->common.state ==87ACPI_CONTROL_CONDITIONAL_EXECUTING)) {8889/* We are executing a while loop outside of a method */9091status = acpi_ds_exec_begin_op(walk_state, out_op);92return_ACPI_STATUS(status);93}9495/* We only care about Namespace opcodes here */9697if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&98(walk_state->opcode != AML_INT_NAMEPATH_OP)) ||99(!(walk_state->op_info->flags & AML_NAMED))) {100return_ACPI_STATUS(AE_OK);101}102103/* Get the name we are going to enter or lookup in the namespace */104105if (walk_state->opcode == AML_INT_NAMEPATH_OP) {106107/* For Namepath op, get the path string */108109buffer_ptr = op->common.value.string;110if (!buffer_ptr) {111112/* No name, just exit */113114return_ACPI_STATUS(AE_OK);115}116} else {117/* Get name from the op */118119buffer_ptr = ACPI_CAST_PTR(char, &op->named.name);120}121} else {122/* Get the namestring from the raw AML */123124buffer_ptr =125acpi_ps_get_next_namestring(&walk_state->parser_state);126}127128/* Map the opcode into an internal object type */129130object_type = walk_state->op_info->object_type;131132ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,133"State=%p Op=%p Type=%X\n", walk_state, op,134object_type));135136switch (walk_state->opcode) {137case AML_FIELD_OP:138case AML_BANK_FIELD_OP:139case AML_INDEX_FIELD_OP:140141node = NULL;142status = AE_OK;143break;144145case AML_INT_NAMEPATH_OP:146/*147* The name_path is an object reference to an existing object.148* Don't enter the name into the namespace, but look it up149* for use later.150*/151status =152acpi_ns_lookup(walk_state->scope_info, buffer_ptr,153object_type, ACPI_IMODE_EXECUTE,154ACPI_NS_SEARCH_PARENT, walk_state, &(node));155break;156157case AML_SCOPE_OP:158159/* Special case for Scope(\) -> refers to the Root node */160161if (op && (op->named.node == acpi_gbl_root_node)) {162node = op->named.node;163164status =165acpi_ds_scope_stack_push(node, object_type,166walk_state);167if (ACPI_FAILURE(status)) {168return_ACPI_STATUS(status);169}170} else {171/*172* The Path is an object reference to an existing object.173* Don't enter the name into the namespace, but look it up174* for use later.175*/176status =177acpi_ns_lookup(walk_state->scope_info, buffer_ptr,178object_type, ACPI_IMODE_EXECUTE,179ACPI_NS_SEARCH_PARENT, walk_state,180&(node));181if (ACPI_FAILURE(status)) {182#ifdef ACPI_ASL_COMPILER183if (status == AE_NOT_FOUND) {184status = AE_OK;185} else {186ACPI_ERROR_NAMESPACE(buffer_ptr,187status);188}189#else190ACPI_ERROR_NAMESPACE(buffer_ptr, status);191#endif192return_ACPI_STATUS(status);193}194}195196/*197* We must check to make sure that the target is198* one of the opcodes that actually opens a scope199*/200switch (node->type) {201case ACPI_TYPE_ANY:202case ACPI_TYPE_LOCAL_SCOPE: /* Scope */203case ACPI_TYPE_DEVICE:204case ACPI_TYPE_POWER:205case ACPI_TYPE_PROCESSOR:206case ACPI_TYPE_THERMAL:207208/* These are acceptable types */209break;210211case ACPI_TYPE_INTEGER:212case ACPI_TYPE_STRING:213case ACPI_TYPE_BUFFER:214215/*216* These types we will allow, but we will change the type.217* This enables some existing code of the form:218*219* Name (DEB, 0)220* Scope (DEB) { ... }221*/222ACPI_WARNING((AE_INFO,223"Type override - [%4.4s] had invalid type (%s) "224"for Scope operator, changed to type ANY\n",225acpi_ut_get_node_name(node),226acpi_ut_get_type_name(node->type)));227228node->type = ACPI_TYPE_ANY;229walk_state->scope_info->common.value = ACPI_TYPE_ANY;230break;231232default:233234/* All other types are an error */235236ACPI_ERROR((AE_INFO,237"Invalid type (%s) for target of "238"Scope operator [%4.4s] (Cannot override)",239acpi_ut_get_type_name(node->type),240acpi_ut_get_node_name(node)));241242return (AE_AML_OPERAND_TYPE);243}244break;245246default:247248/* All other opcodes */249250if (op && op->common.node) {251252/* This op/node was previously entered into the namespace */253254node = op->common.node;255256if (acpi_ns_opens_scope(object_type)) {257status =258acpi_ds_scope_stack_push(node, object_type,259walk_state);260if (ACPI_FAILURE(status)) {261return_ACPI_STATUS(status);262}263}264265return_ACPI_STATUS(AE_OK);266}267268/*269* Enter the named type into the internal namespace. We enter the name270* as we go downward in the parse tree. Any necessary subobjects that271* involve arguments to the opcode must be created as we go back up the272* parse tree later.273*274* Note: Name may already exist if we are executing a deferred opcode.275*/276if (walk_state->deferred_node) {277278/* This name is already in the namespace, get the node */279280node = walk_state->deferred_node;281status = AE_OK;282break;283}284285flags = ACPI_NS_NO_UPSEARCH;286if (walk_state->pass_number == ACPI_IMODE_EXECUTE) {287288/* Execution mode, node cannot already exist, node is temporary */289290flags |= ACPI_NS_ERROR_IF_FOUND;291292if (!293(walk_state->294parse_flags & ACPI_PARSE_MODULE_LEVEL)) {295flags |= ACPI_NS_TEMPORARY;296}297}298299/* Add new entry or lookup existing entry */300301status =302acpi_ns_lookup(walk_state->scope_info, buffer_ptr,303object_type, ACPI_IMODE_LOAD_PASS2, flags,304walk_state, &node);305306if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) {307ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,308"***New Node [%4.4s] %p is temporary\n",309acpi_ut_get_node_name(node), node));310}311break;312}313314if (ACPI_FAILURE(status)) {315ACPI_ERROR_NAMESPACE(buffer_ptr, status);316return_ACPI_STATUS(status);317}318319if (!op) {320321/* Create a new op */322323op = acpi_ps_alloc_op(walk_state->opcode);324if (!op) {325return_ACPI_STATUS(AE_NO_MEMORY);326}327328/* Initialize the new op */329330if (node) {331op->named.name = node->name.integer;332}333*out_op = op;334}335336/*337* Put the Node in the "op" object that the parser uses, so we338* can get it again quickly when this scope is closed339*/340op->common.node = node;341return_ACPI_STATUS(status);342}343344/*******************************************************************************345*346* FUNCTION: acpi_ds_load2_end_op347*348* PARAMETERS: walk_state - Current state of the parse tree walk349*350* RETURN: Status351*352* DESCRIPTION: Ascending callback used during the loading of the namespace,353* both control methods and everything else.354*355******************************************************************************/356357acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)358{359union acpi_parse_object *op;360acpi_status status = AE_OK;361acpi_object_type object_type;362struct acpi_namespace_node *node;363union acpi_parse_object *arg;364struct acpi_namespace_node *new_node;365#ifndef ACPI_NO_METHOD_EXECUTION366u32 i;367u8 region_space;368#endif369370ACPI_FUNCTION_TRACE(ds_load2_end_op);371372op = walk_state->op;373ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",374walk_state->op_info->name, op, walk_state));375376/* Check if opcode had an associated namespace object */377378if (!(walk_state->op_info->flags & AML_NSOBJECT)) {379return_ACPI_STATUS(AE_OK);380}381382if (op->common.aml_opcode == AML_SCOPE_OP) {383ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,384"Ending scope Op=%p State=%p\n", op,385walk_state));386}387388object_type = walk_state->op_info->object_type;389390/*391* Get the Node/name from the earlier lookup392* (It was saved in the *op structure)393*/394node = op->common.node;395396/*397* Put the Node on the object stack (Contains the ACPI Name of398* this object)399*/400walk_state->operands[0] = (void *)node;401walk_state->num_operands = 1;402403/* Pop the scope stack */404405if (acpi_ns_opens_scope(object_type) &&406(op->common.aml_opcode != AML_INT_METHODCALL_OP)) {407ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,408"(%s) Popping scope for Op %p\n",409acpi_ut_get_type_name(object_type), op));410411status = acpi_ds_scope_stack_pop(walk_state);412if (ACPI_FAILURE(status)) {413goto cleanup;414}415}416417/*418* Named operations are as follows:419*420* AML_ALIAS421* AML_BANKFIELD422* AML_CREATEBITFIELD423* AML_CREATEBYTEFIELD424* AML_CREATEDWORDFIELD425* AML_CREATEFIELD426* AML_CREATEQWORDFIELD427* AML_CREATEWORDFIELD428* AML_DATA_REGION429* AML_DEVICE430* AML_EVENT431* AML_FIELD432* AML_INDEXFIELD433* AML_METHOD434* AML_METHODCALL435* AML_MUTEX436* AML_NAME437* AML_NAMEDFIELD438* AML_OPREGION439* AML_POWERRES440* AML_PROCESSOR441* AML_SCOPE442* AML_THERMALZONE443*/444445ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,446"Create-Load [%s] State=%p Op=%p NamedObj=%p\n",447acpi_ps_get_opcode_name(op->common.aml_opcode),448walk_state, op, node));449450/* Decode the opcode */451452arg = op->common.value.arg;453454switch (walk_state->op_info->type) {455#ifndef ACPI_NO_METHOD_EXECUTION456457case AML_TYPE_CREATE_FIELD:458/*459* Create the field object, but the field buffer and index must460* be evaluated later during the execution phase461*/462status = acpi_ds_create_buffer_field(op, walk_state);463break;464465case AML_TYPE_NAMED_FIELD:466/*467* If we are executing a method, initialize the field468*/469if (walk_state->method_node) {470status = acpi_ds_init_field_objects(op, walk_state);471}472473switch (op->common.aml_opcode) {474case AML_INDEX_FIELD_OP:475476status =477acpi_ds_create_index_field(op,478(acpi_handle) arg->479common.node, walk_state);480break;481482case AML_BANK_FIELD_OP:483484status =485acpi_ds_create_bank_field(op, arg->common.node,486walk_state);487break;488489case AML_FIELD_OP:490491status =492acpi_ds_create_field(op, arg->common.node,493walk_state);494break;495496default:497/* All NAMED_FIELD opcodes must be handled above */498break;499}500break;501502case AML_TYPE_NAMED_SIMPLE:503504status = acpi_ds_create_operands(walk_state, arg);505if (ACPI_FAILURE(status)) {506goto cleanup;507}508509switch (op->common.aml_opcode) {510case AML_PROCESSOR_OP:511512status = acpi_ex_create_processor(walk_state);513break;514515case AML_POWER_RES_OP:516517status = acpi_ex_create_power_resource(walk_state);518break;519520case AML_MUTEX_OP:521522status = acpi_ex_create_mutex(walk_state);523break;524525case AML_EVENT_OP:526527status = acpi_ex_create_event(walk_state);528break;529530case AML_ALIAS_OP:531532status = acpi_ex_create_alias(walk_state);533break;534535default:536/* Unknown opcode */537538status = AE_OK;539goto cleanup;540}541542/* Delete operands */543544for (i = 1; i < walk_state->num_operands; i++) {545acpi_ut_remove_reference(walk_state->operands[i]);546walk_state->operands[i] = NULL;547}548549break;550#endif /* ACPI_NO_METHOD_EXECUTION */551552case AML_TYPE_NAMED_COMPLEX:553554switch (op->common.aml_opcode) {555#ifndef ACPI_NO_METHOD_EXECUTION556case AML_REGION_OP:557case AML_DATA_REGION_OP:558559if (op->common.aml_opcode == AML_REGION_OP) {560region_space = (acpi_adr_space_type)561((op->common.value.arg)->common.value.562integer);563} else {564region_space = ACPI_ADR_SPACE_DATA_TABLE;565}566567/*568* The op_region is not fully parsed at this time. The only valid569* argument is the space_id. (We must save the address of the570* AML of the address and length operands)571*572* If we have a valid region, initialize it. The namespace is573* unlocked at this point.574*575* Need to unlock interpreter if it is locked (if we are running576* a control method), in order to allow _REG methods to be run577* during acpi_ev_initialize_region.578*/579if (walk_state->method_node) {580/*581* Executing a method: initialize the region and unlock582* the interpreter583*/584status =585acpi_ex_create_region(op->named.data,586op->named.length,587region_space,588walk_state);589if (ACPI_FAILURE(status)) {590return (status);591}592593acpi_ex_exit_interpreter();594}595596status =597acpi_ev_initialize_region598(acpi_ns_get_attached_object(node), FALSE);599if (walk_state->method_node) {600acpi_ex_enter_interpreter();601}602603if (ACPI_FAILURE(status)) {604/*605* If AE_NOT_EXIST is returned, it is not fatal606* because many regions get created before a handler607* is installed for said region.608*/609if (AE_NOT_EXIST == status) {610status = AE_OK;611}612}613break;614615case AML_NAME_OP:616617status = acpi_ds_create_node(walk_state, node, op);618break;619620case AML_METHOD_OP:621/*622* method_op pkg_length name_string method_flags term_list623*624* Note: We must create the method node/object pair as soon as we625* see the method declaration. This allows later pass1 parsing626* of invocations of the method (need to know the number of627* arguments.)628*/629ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,630"LOADING-Method: State=%p Op=%p NamedObj=%p\n",631walk_state, op, op->named.node));632633if (!acpi_ns_get_attached_object(op->named.node)) {634walk_state->operands[0] =635ACPI_CAST_PTR(void, op->named.node);636walk_state->num_operands = 1;637638status =639acpi_ds_create_operands(walk_state,640op->common.value.641arg);642if (ACPI_SUCCESS(status)) {643status =644acpi_ex_create_method(op->named.645data,646op->named.647length,648walk_state);649}650walk_state->operands[0] = NULL;651walk_state->num_operands = 0;652653if (ACPI_FAILURE(status)) {654return_ACPI_STATUS(status);655}656}657break;658659#endif /* ACPI_NO_METHOD_EXECUTION */660661default:662/* All NAMED_COMPLEX opcodes must be handled above */663break;664}665break;666667case AML_CLASS_INTERNAL:668669/* case AML_INT_NAMEPATH_OP: */670break;671672case AML_CLASS_METHOD_CALL:673674ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,675"RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",676walk_state, op, node));677678/*679* Lookup the method name and save the Node680*/681status =682acpi_ns_lookup(walk_state->scope_info,683arg->common.value.string, ACPI_TYPE_ANY,684ACPI_IMODE_LOAD_PASS2,685ACPI_NS_SEARCH_PARENT |686ACPI_NS_DONT_OPEN_SCOPE, walk_state,687&(new_node));688if (ACPI_SUCCESS(status)) {689/*690* Make sure that what we found is indeed a method691* We didn't search for a method on purpose, to see if the name692* would resolve693*/694if (new_node->type != ACPI_TYPE_METHOD) {695status = AE_AML_OPERAND_TYPE;696}697698/* We could put the returned object (Node) on the object stack for699* later, but for now, we will put it in the "op" object that the700* parser uses, so we can get it again at the end of this scope701*/702op->common.node = new_node;703} else {704ACPI_ERROR_NAMESPACE(arg->common.value.string, status);705}706break;707708default:709break;710}711712cleanup:713714/* Remove the Node pushed at the very beginning */715716walk_state->operands[0] = NULL;717walk_state->num_operands = 0;718return_ACPI_STATUS(status);719}720721722