struct acpi_namespace_node *acpi_db_local_ns_lookup(char *name) { char *internal_path; acpi_status status; struct acpi_namespace_node *node = NULL; acpi_db_prep_namestring(name); /* Build an internal namestring */ status = acpi_ns_internalize_name(name, &internal_path); if (ACPI_FAILURE(status)) { acpi_os_printf("Invalid namestring: %s\n", name); return (NULL); } /* * Lookup the name. * (Uses root node as the search starting point) */ status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &node); if (ACPI_FAILURE(status)) { acpi_os_printf("Could not locate name: %s, %s\n", name, acpi_format_exception(status)); } ACPI_FREE(internal_path); return (node); }
acpi_status acpi_ns_evaluate_by_name ( NATIVE_CHAR *pathname, acpi_operand_object **params, acpi_operand_object **return_object) { acpi_status status; acpi_namespace_node *node = NULL; NATIVE_CHAR *internal_path = NULL; FUNCTION_TRACE ("Ns_evaluate_by_name"); /* Build an internal name string for the method */ status = acpi_ns_internalize_name (pathname, &internal_path); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); /* Lookup the name in the namespace */ status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY, IMODE_EXECUTE, NS_NO_UPSEARCH, NULL, &node); acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Object at [%s] was not found, status=%.4X\n", pathname, status)); goto cleanup; } /* * Now that we have a handle to the object, we can attempt * to evaluate it. */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s [%p] Value %p\n", pathname, node, node->object)); status = acpi_ns_evaluate_by_handle (node, params, return_object); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "*** Completed eval of object %s ***\n", pathname)); cleanup: /* Cleanup */ if (internal_path) { ACPI_MEM_FREE (internal_path); } return_ACPI_STATUS (status); }
acpi_status acpi_ns_get_node ( NATIVE_CHAR *pathname, acpi_namespace_node *start_node, acpi_namespace_node **return_node) { acpi_generic_state scope_info; acpi_status status; NATIVE_CHAR *internal_path = NULL; FUNCTION_TRACE_PTR ("Ns_get_node", pathname); /* Ensure that the namespace has been initialized */ if (!acpi_gbl_root_node) { return_ACPI_STATUS (AE_NO_NAMESPACE); } if (!pathname) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Convert path to internal representation */ status = acpi_ns_internalize_name (pathname, &internal_path); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); /* Setup lookup scope (search starting point) */ scope_info.scope.node = start_node; /* Lookup the name in the namespace */ status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY, IMODE_EXECUTE, NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE, NULL, return_node); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s, %s\n", internal_path, acpi_format_exception (status))); } acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); /* Cleanup */ ACPI_MEM_FREE (internal_path); return_ACPI_STATUS (status); }
acpi_status acpi_ps_display_object_pathname ( acpi_walk_state *walk_state, acpi_parse_object *op) { acpi_status status; acpi_namespace_node *node; NATIVE_CHAR buffer[MAX_SHOW_ENTRY]; u32 buffer_size = MAX_SHOW_ENTRY; u32 debug_level; /* Save current debug level so we don't get extraneous debug output */ debug_level = acpi_dbg_level; acpi_dbg_level = 0; /* Just get the Node out of the Op object */ node = op->node; if (!node) { /* Node not defined in this scope, look it up */ status = acpi_ns_lookup (walk_state->scope_info, op->value.string, ACPI_TYPE_ANY, IMODE_EXECUTE, NS_SEARCH_PARENT, walk_state, &(node)); if (ACPI_FAILURE (status)) { /* * We can't get the pathname since the object * is not in the namespace. This can happen during single * stepping where a dynamic named object is *about* to be created. */ acpi_os_printf (" [Path not found]"); goto exit; } /* Save it for next time. */ op->node = node; } /* Convert Named_desc/handle to a full pathname */ status = acpi_ns_handle_to_pathname (node, &buffer_size, buffer); if (ACPI_FAILURE (status)) { acpi_os_printf ("****Could not get pathname****)"); goto exit; } acpi_os_printf (" (Path %s)", buffer); exit: /* Restore the debug level */ acpi_dbg_level = debug_level; return (status); }
acpi_status acpi_ns_evaluate_by_name(char *pathname, struct acpi_parameter_info *info) { acpi_status status; char *internal_path = NULL; ACPI_FUNCTION_TRACE("ns_evaluate_by_name"); /* Build an internal name string for the method */ status = acpi_ns_internalize_name(pathname, &internal_path); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { goto cleanup; } /* Lookup the name in the namespace */ status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, &info->node); (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Object at [%s] was not found, status=%.4X\n", pathname, status)); goto cleanup; } /* * Now that we have a handle to the object, we can attempt to evaluate it. */ ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", pathname, info->node, acpi_ns_get_attached_object(info->node))); status = acpi_ns_evaluate_by_handle(info); ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n", pathname)); cleanup: /* Cleanup */ if (internal_path) { ACPI_MEM_FREE(internal_path); } return_ACPI_STATUS(status); }
acpi_status acpi_ns_get_node_by_path ( char *pathname, struct acpi_namespace_node *start_node, u32 flags, struct acpi_namespace_node **return_node) { union acpi_generic_state scope_info; acpi_status status; char *internal_path = NULL; ACPI_FUNCTION_TRACE_PTR ("ns_get_node_by_path", pathname); if (pathname) { /* Convert path to internal representation */ status = acpi_ns_internalize_name (pathname, &internal_path); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } } /* Must lock namespace during lookup */ status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { goto cleanup; } /* Setup lookup scope (search starting point) */ scope_info.scope.node = start_node; /* Lookup the name in the namespace */ status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL, return_node); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s, %s\n", internal_path, acpi_format_exception (status))); } (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); cleanup: /* Cleanup */ if (internal_path) { ACPI_MEM_FREE (internal_path); } return_ACPI_STATUS (status); }
acpi_status acpi_ns_get_node_unlocked(struct acpi_namespace_node *prefix_node, const char *pathname, u32 flags, struct acpi_namespace_node **return_node) { union acpi_generic_state scope_info; acpi_status status; char *internal_path; ACPI_FUNCTION_TRACE_PTR(ns_get_node_unlocked, ACPI_CAST_PTR(char, pathname)); /* Simplest case is a null pathname */ if (!pathname) { *return_node = prefix_node; if (!prefix_node) { *return_node = acpi_gbl_root_node; } return_ACPI_STATUS(AE_OK); } /* Quick check for a reference to the root */ if (ACPI_IS_ROOT_PREFIX(pathname[0]) && (!pathname[1])) { *return_node = acpi_gbl_root_node; return_ACPI_STATUS(AE_OK); } /* Convert path to internal representation */ status = acpi_ns_internalize_name(pathname, &internal_path); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Setup lookup scope (search starting point) */ scope_info.scope.node = prefix_node; /* Lookup the name in the namespace */ status = acpi_ns_lookup(&scope_info, internal_path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL, return_node); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s, %s\n", pathname, acpi_format_exception(status))); } ACPI_FREE(internal_path); return_ACPI_STATUS(status); }
ACPI_STATUS acpi_ns_evaluate_by_name ( NATIVE_CHAR *pathname, ACPI_OPERAND_OBJECT **params, ACPI_OPERAND_OBJECT **return_object) { ACPI_STATUS status; ACPI_NAMESPACE_NODE *node = NULL; NATIVE_CHAR *internal_path = NULL; /* Build an internal name string for the method */ status = acpi_ns_internalize_name (pathname, &internal_path); if (ACPI_FAILURE (status)) { return (status); } acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); /* Lookup the name in the namespace */ status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY, IMODE_EXECUTE, NS_NO_UPSEARCH, NULL, &node); acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { goto cleanup; } /* * Now that we have a handle to the object, we can attempt * to evaluate it. */ status = acpi_ns_evaluate_by_handle (node, params, return_object); cleanup: /* Cleanup */ if (internal_path) { acpi_cm_free (internal_path); } return (status); }
acpi_status acpi_ds_build_internal_object ( struct acpi_walk_state *walk_state, union acpi_parse_object *op, union acpi_operand_object **obj_desc_ptr) { union acpi_operand_object *obj_desc; acpi_status status; ACPI_FUNCTION_TRACE ("ds_build_internal_object"); *obj_desc_ptr = NULL; if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) { /* * This is an named object reference. If this name was * previously looked up in the namespace, it was stored in this op. * Otherwise, go ahead and look it up now */ if (!op->common.node) { status = acpi_ns_lookup (walk_state->scope_info, op->common.value.string, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, (struct acpi_namespace_node **) &(op->common.node)); if (ACPI_FAILURE (status)) { ACPI_REPORT_NSERROR (op->common.value.string, status); return_ACPI_STATUS (status); } } } /* Create and init the internal ACPI object */ obj_desc = acpi_ut_create_internal_object ((acpi_ps_get_opcode_info (op->common.aml_opcode))->object_type); if (!obj_desc) { return_ACPI_STATUS (AE_NO_MEMORY); } status = acpi_ds_init_object_from_op (walk_state, op, op->common.aml_opcode, &obj_desc); if (ACPI_FAILURE (status)) { acpi_ut_remove_reference (obj_desc); return_ACPI_STATUS (status); } *obj_desc_ptr = obj_desc; return_ACPI_STATUS (AE_OK); }
static acpi_status acpi_ds_create_external_region(acpi_status lookup_status, union acpi_parse_object *op, char *path, struct acpi_walk_state *walk_state, struct acpi_namespace_node **node) { acpi_status status; union acpi_operand_object *obj_desc; if (lookup_status != AE_NOT_FOUND) { return (lookup_status); } /* * Table disassembly: * operation_region not found. Generate an External for it, and * insert the name into the namespace. */ acpi_dm_add_to_external_list(op, path, ACPI_TYPE_REGION, 0); status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION, ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, walk_state, node); if (ACPI_FAILURE(status)) { return (status); } /* Must create and install a region object for the new node */ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION); if (!obj_desc) { return (AE_NO_MEMORY); } obj_desc->region.node = *node; status = acpi_ns_attach_object(*node, obj_desc, ACPI_TYPE_REGION); return (status); }
acpi_namespace_node * acpi_db_local_ns_lookup ( NATIVE_CHAR *name) { NATIVE_CHAR *internal_path; acpi_status status; acpi_namespace_node *node = NULL; acpi_db_prep_namestring (name); /* Build an internal namestring */ status = acpi_ns_internalize_name (name, &internal_path); if (ACPI_FAILURE (status)) { acpi_os_printf ("Invalid namestring: %s\n", name); return (NULL); } /* Lookup the name */ /* TBD: [Investigate] what scope do we use? */ /* Use the root scope for the start of the search */ status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY, IMODE_EXECUTE, NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE, NULL, &node); if (ACPI_FAILURE (status)) { acpi_os_printf ("Could not locate name: %s %s\n", name, acpi_format_exception (status)); } ACPI_MEM_FREE (internal_path); return (node); }
ACPI_STATUS acpi_ns_evaluate_relative ( ACPI_NAMESPACE_NODE *handle, NATIVE_CHAR *pathname, ACPI_OPERAND_OBJECT **params, ACPI_OPERAND_OBJECT **return_object) { ACPI_NAMESPACE_NODE *prefix_node; ACPI_STATUS status; ACPI_NAMESPACE_NODE *node = NULL; NATIVE_CHAR *internal_path = NULL; ACPI_GENERIC_STATE scope_info; /* * Must have a valid object handle */ if (!handle) { return (AE_BAD_PARAMETER); } /* Build an internal name string for the method */ status = acpi_ns_internalize_name (pathname, &internal_path); if (ACPI_FAILURE (status)) { return (status); } /* Get the prefix handle and Node */ acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); prefix_node = acpi_ns_convert_handle_to_entry (handle); if (!prefix_node) { acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); status = AE_BAD_PARAMETER; goto cleanup; } /* Lookup the name in the namespace */ scope_info.scope.node = prefix_node; status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY, IMODE_EXECUTE, NS_NO_UPSEARCH, NULL, &node); acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { goto cleanup; } /* * Now that we have a handle to the object, we can attempt * to evaluate it. */ status = acpi_ns_evaluate_by_handle (node, params, return_object); cleanup: /* Cleanup */ acpi_cm_free (internal_path); return (status); }
static acpi_status acpi_ds_get_field_names(struct acpi_create_field_info *info, struct acpi_walk_state *walk_state, union acpi_parse_object *arg) { acpi_status status; u64 position; union acpi_parse_object *child; ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info); /* First field starts at bit zero */ info->field_bit_position = 0; /* Process all elements in the field list (of parse nodes) */ while (arg) { /* * Four types of field elements are handled: * 1) name - Enters a new named field into the namespace * 2) offset - specifies a bit offset * 3) access_as - changes the access mode/attributes * 4) connection - Associate a resource template with the field */ switch (arg->common.aml_opcode) { case AML_INT_RESERVEDFIELD_OP: position = (u64) info->field_bit_position + (u64) arg->common.value.size; if (position > ACPI_UINT32_MAX) { ACPI_ERROR((AE_INFO, "Bit offset within field too large (> 0xFFFFFFFF)")); return_ACPI_STATUS(AE_SUPPORT); } info->field_bit_position = (u32) position; break; case AML_INT_ACCESSFIELD_OP: case AML_INT_EXTACCESSFIELD_OP: /* * Get new access_type, access_attribute, and access_length fields * -- to be used for all field units that follow, until the * end-of-field or another access_as keyword is encountered. * NOTE. These three bytes are encoded in the integer value * of the parseop for convenience. * * In field_flags, preserve the flag bits other than the * ACCESS_TYPE bits. */ /* access_type (byte_acc, word_acc, etc.) */ info->field_flags = (u8) ((info-> field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) | ((u8)((u32)(arg->common.value.integer & 0x07)))); /* access_attribute (attrib_quick, attrib_byte, etc.) */ info->attribute = (u8)((arg->common.value.integer >> 8) & 0xFF); /* access_length (for serial/buffer protocols) */ info->access_length = (u8)((arg->common.value.integer >> 16) & 0xFF); break; case AML_INT_CONNECTION_OP: /* * Clear any previous connection. New connection is used for all * fields that follow, similar to access_as */ info->resource_buffer = NULL; info->connection_node = NULL; info->pin_number_index = 0; /* * A Connection() is either an actual resource descriptor (buffer) * or a named reference to a resource template */ child = arg->common.value.arg; if (child->common.aml_opcode == AML_INT_BYTELIST_OP) { info->resource_buffer = child->named.data; info->resource_length = (u16)child->named.value.integer; } else { /* Lookup the Connection() namepath, it should already exist */ status = acpi_ns_lookup(walk_state->scope_info, child->common.value. name, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE, walk_state, &info->connection_node); if (ACPI_FAILURE(status)) { ACPI_ERROR_NAMESPACE(child->common. value.name, status); return_ACPI_STATUS(status); } } break; case AML_INT_NAMEDFIELD_OP: /* Lookup the name, it should already exist */ status = acpi_ns_lookup(walk_state->scope_info, (char *)&arg->named.name, info->field_type, ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE, walk_state, &info->field_node); if (ACPI_FAILURE(status)) { ACPI_ERROR_NAMESPACE((char *)&arg->named.name, status); return_ACPI_STATUS(status); } else { arg->common.node = info->field_node; info->field_bit_length = arg->common.value.size; /* * If there is no object attached to the node, this node was * just created and we need to create the field object. * Otherwise, this was a lookup of an existing node and we * don't want to create the field object again. */ if (!acpi_ns_get_attached_object (info->field_node)) { status = acpi_ex_prep_field_value(info); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } } } /* Keep track of bit position for the next field */ position = (u64) info->field_bit_position + (u64) arg->common.value.size; if (position > ACPI_UINT32_MAX) { ACPI_ERROR((AE_INFO, "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)", ACPI_CAST_PTR(char, &info->field_node-> name))); return_ACPI_STATUS(AE_SUPPORT); } info->field_bit_position += info->field_bit_length; info->pin_number_index++; /* Index relative to previous Connection() */ break; default: ACPI_ERROR((AE_INFO, "Invalid opcode in field list: 0x%X", arg->common.aml_opcode)); return_ACPI_STATUS(AE_AML_BAD_OPCODE); } arg = arg->common.next; }
acpi_status acpi_ds_create_buffer_field(union acpi_parse_object *op, struct acpi_walk_state *walk_state) { union acpi_parse_object *arg; struct acpi_namespace_node *node; acpi_status status; union acpi_operand_object *obj_desc; union acpi_operand_object *second_desc = NULL; u32 flags; ACPI_FUNCTION_TRACE(ds_create_buffer_field); /* * Get the name_string argument (name of the new buffer_field) */ if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { /* For create_field, name is the 4th argument */ arg = acpi_ps_get_arg(op, 3); } else { /* For all other create_XXXField operators, name is the 3rd argument */ arg = acpi_ps_get_arg(op, 2); } if (!arg) { return_ACPI_STATUS(AE_AML_NO_OPERAND); } if (walk_state->deferred_node) { node = walk_state->deferred_node; status = AE_OK; } else { /* Execute flag should always be set when this function is entered */ if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) { return_ACPI_STATUS(AE_AML_INTERNAL); } /* Creating new namespace node, should not already exist */ flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND; /* * Mark node temporary if we are executing a normal control * method. (Don't mark if this is a module-level code method) */ if (walk_state->method_node && !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) { flags |= ACPI_NS_TEMPORARY; } /* Enter the name_string into the namespace */ status = acpi_ns_lookup(walk_state->scope_info, arg->common.value.string, ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1, flags, walk_state, &node); if (ACPI_FAILURE(status)) { ACPI_ERROR_NAMESPACE(arg->common.value.string, status); return_ACPI_STATUS(status); } } /* * We could put the returned object (Node) on the object stack for later, * but for now, we will put it in the "op" object that the parser uses, * so we can get it again at the end of this scope. */ op->common.node = node; /* * If there is no object attached to the node, this node was just created * and we need to create the field object. Otherwise, this was a lookup * of an existing node and we don't want to create the field object again. */ obj_desc = acpi_ns_get_attached_object(node); if (obj_desc) { return_ACPI_STATUS(AE_OK); } /* * The Field definition is not fully parsed at this time. * (We must save the address of the AML for the buffer and index operands) */ /* Create the buffer field object */ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD); if (!obj_desc) { status = AE_NO_MEMORY; goto cleanup; } /* * Remember location in AML stream of the field unit opcode and operands -- * since the buffer and index operands must be evaluated. */ second_desc = obj_desc->common.next_object; second_desc->extra.aml_start = op->named.data; second_desc->extra.aml_length = op->named.length; obj_desc->buffer_field.node = node; /* Attach constructed field descriptors to parent node */ status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD); if (ACPI_FAILURE(status)) { goto cleanup; } cleanup: /* Remove local reference to the object */ acpi_ut_remove_reference(obj_desc); return_ACPI_STATUS(status); }
acpi_status acpi_ds_load2_end_op ( acpi_walk_state *walk_state) { acpi_parse_object *op; acpi_status status = AE_OK; acpi_object_type8 data_type; acpi_namespace_node *node; acpi_parse_object *arg; acpi_namespace_node *new_node; u32 i; PROC_NAME ("Ds_load2_end_op"); op = walk_state->op; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); /* Only interested in opcodes that have namespace objects */ if (!(walk_state->op_info->flags & AML_NSOBJECT)) { return (AE_OK); } if (op->opcode == AML_SCOPE_OP) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Ending scope Op=%p State=%p\n", op, walk_state)); if (((acpi_parse2_object *)op)->name == -1) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unnamed scope! Op=%p State=%p\n", op, walk_state)); return (AE_OK); } } data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode); /* * Get the Node/name from the earlier lookup * (It was saved in the *op structure) */ node = op->node; /* * Put the Node on the object stack (Contains the ACPI Name of * this object) */ walk_state->operands[0] = (void *) node; walk_state->num_operands = 1; /* Pop the scope stack */ if (acpi_ns_opens_scope (data_type)) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n", acpi_ut_get_type_name (data_type), op)); acpi_ds_scope_stack_pop (walk_state); } /* * Named operations are as follows: * * AML_ALIAS * AML_BANKFIELD * AML_CREATEBITFIELD * AML_CREATEBYTEFIELD * AML_CREATEDWORDFIELD * AML_CREATEFIELD * AML_CREATEQWORDFIELD * AML_CREATEWORDFIELD * AML_DATA_REGION * AML_DEVICE * AML_EVENT * AML_FIELD * AML_INDEXFIELD * AML_METHOD * AML_METHODCALL * AML_MUTEX * AML_NAME * AML_NAMEDFIELD * AML_OPREGION * AML_POWERRES * AML_PROCESSOR * AML_SCOPE * AML_THERMALZONE */ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Create-Load [%s] State=%p Op=%p Named_obj=%p\n", acpi_ps_get_opcode_name (op->opcode), walk_state, op, node)); /* Decode the opcode */ arg = op->value.arg; switch (walk_state->op_info->type) { case AML_TYPE_CREATE_FIELD: /* * Create the field object, but the field buffer and index must * be evaluated later during the execution phase */ status = acpi_ds_create_buffer_field (op, walk_state); break; case AML_TYPE_NAMED_FIELD: arg = op->value.arg; switch (op->opcode) { case AML_INDEX_FIELD_OP: status = acpi_ds_create_index_field (op, (acpi_handle) arg->node, walk_state); break; case AML_BANK_FIELD_OP: status = acpi_ds_create_bank_field (op, arg->node, walk_state); break; case AML_FIELD_OP: status = acpi_ds_create_field (op, arg->node, walk_state); break; } break; case AML_TYPE_NAMED_SIMPLE: status = acpi_ds_create_operands (walk_state, arg); if (ACPI_FAILURE (status)) { goto cleanup; } switch (op->opcode) { case AML_PROCESSOR_OP: status = acpi_ex_create_processor (walk_state); break; case AML_POWER_RES_OP: status = acpi_ex_create_power_resource (walk_state); break; case AML_MUTEX_OP: status = acpi_ex_create_mutex (walk_state); break; case AML_EVENT_OP: status = acpi_ex_create_event (walk_state); break; case AML_DATA_REGION_OP: status = acpi_ex_create_table_region (walk_state); break; case AML_ALIAS_OP: status = acpi_ex_create_alias (walk_state); break; default: /* Unknown opcode */ status = AE_OK; goto cleanup; break; } /* Delete operands */ for (i = 1; i < walk_state->num_operands; i++) { acpi_ut_remove_reference (walk_state->operands[i]); walk_state->operands[i] = NULL; } break; case AML_TYPE_NAMED_COMPLEX: switch (op->opcode) { case AML_METHOD_OP: /* * Method_op Pkg_length Names_string Method_flags Term_list */ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "LOADING-Method: State=%p Op=%p Named_obj=%p\n", walk_state, op, node)); if (!node->object) { status = acpi_ds_create_operands (walk_state, arg); if (ACPI_FAILURE (status)) { goto cleanup; } status = acpi_ex_create_method (((acpi_parse2_object *) op)->data, ((acpi_parse2_object *) op)->length, walk_state); } break; case AML_REGION_OP: /* * The Op_region is not fully parsed at this time. Only valid argument is the Space_id. * (We must save the address of the AML of the address and length operands) */ status = acpi_ex_create_region (((acpi_parse2_object *) op)->data, ((acpi_parse2_object *) op)->length, (ACPI_ADR_SPACE_TYPE) arg->value.integer, walk_state); break; case AML_NAME_OP: status = acpi_ds_create_node (walk_state, node, op); break; } break; case AML_CLASS_INTERNAL: /* case AML_INT_NAMEPATH_OP: */ break; case AML_CLASS_METHOD_CALL: ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "RESOLVING-Method_call: State=%p Op=%p Named_obj=%p\n", walk_state, op, node)); /* * Lookup the method name and save the Node */ status = acpi_ns_lookup (walk_state->scope_info, arg->value.string, ACPI_TYPE_ANY, IMODE_LOAD_PASS2, NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE, walk_state, &(new_node)); if (ACPI_SUCCESS (status)) { /* TBD: has name already been resolved by here ??*/ /* TBD: [Restructure] Make sure that what we found is indeed a method! */ /* We didn't search for a method on purpose, to see if the name would resolve! */ /* We could put the returned object (Node) on the object stack for later, but * for now, we will put it in the "op" object that the parser uses, so we * can get it again at the end of this scope */ op->node = new_node; } break; default: break; } cleanup: /* Remove the Node pushed at the very beginning */ walk_state->operands[0] = NULL; walk_state->num_operands = 0; return (status); }
acpi_status acpi_ns_evaluate_relative ( acpi_namespace_node *handle, NATIVE_CHAR *pathname, acpi_operand_object **params, acpi_operand_object **return_object) { acpi_namespace_node *prefix_node; acpi_status status; acpi_namespace_node *node = NULL; NATIVE_CHAR *internal_path = NULL; acpi_generic_state scope_info; FUNCTION_TRACE ("Ns_evaluate_relative"); /* * Must have a valid object handle */ if (!handle) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Build an internal name string for the method */ status = acpi_ns_internalize_name (pathname, &internal_path); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Get the prefix handle and Node */ acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); prefix_node = acpi_ns_map_handle_to_node (handle); if (!prefix_node) { acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); status = AE_BAD_PARAMETER; goto cleanup; } /* Lookup the name in the namespace */ scope_info.scope.node = prefix_node; status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY, IMODE_EXECUTE, NS_NO_UPSEARCH, NULL, &node); acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Object [%s] not found [%s]\n", pathname, acpi_format_exception (status))); goto cleanup; } /* * Now that we have a handle to the object, we can attempt * to evaluate it. */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s [%p] Value %p\n", pathname, node, node->object)); status = acpi_ns_evaluate_by_handle (node, params, return_object); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "*** Completed eval of object %s ***\n", pathname)); cleanup: ACPI_MEM_FREE (internal_path); return_ACPI_STATUS (status); }
acpi_status acpi_ds_load1_begin_op ( acpi_walk_state *walk_state, acpi_parse_object **out_op) { acpi_parse_object *op; acpi_namespace_node *node; acpi_status status; acpi_object_type8 data_type; NATIVE_CHAR *path; PROC_NAME ("Ds_load1_begin_op"); op = walk_state->op; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); /* We are only interested in opcodes that have an associated name */ if (walk_state->op) { if (!(walk_state->op_info->flags & AML_NAMED)) { *out_op = op; return (AE_OK); } /* Check if this object has already been installed in the namespace */ if (op->node) { *out_op = op; return (AE_OK); } } path = acpi_ps_get_next_namestring (&walk_state->parser_state); /* Map the raw opcode into an internal object type */ data_type = acpi_ds_map_named_opcode_to_data_type (walk_state->opcode); ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "State=%p Op=%p Type=%x\n", walk_state, op, data_type)); if (walk_state->opcode == AML_SCOPE_OP) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "State=%p Op=%p Type=%x\n", walk_state, op, data_type)); } /* * Enter the named type into the internal namespace. We enter the name * as we go downward in the parse tree. Any necessary subobjects that involve * arguments to the opcode must be created as we go back up the parse tree later. */ status = acpi_ns_lookup (walk_state->scope_info, path, data_type, IMODE_LOAD_PASS1, NS_NO_UPSEARCH, walk_state, &(node)); if (ACPI_FAILURE (status)) { return (status); } if (!op) { /* Create a new op */ op = acpi_ps_alloc_op (walk_state->opcode); if (!op) { return (AE_NO_MEMORY); } } /* Initialize */ ((acpi_parse2_object *)op)->name = node->name; /* * Put the Node in the "op" object that the parser uses, so we * can get it again quickly when this scope is closed */ op->node = node; acpi_ps_append_arg (acpi_ps_get_parent_scope (&walk_state->parser_state), op); *out_op = op; return (status); }
acpi_status acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, struct acpi_parse_state *parser_state, union acpi_parse_object *arg, u8 method_call) { char *path; union acpi_parse_object *name_op; acpi_status status = AE_OK; union acpi_operand_object *method_desc; struct acpi_namespace_node *node; union acpi_generic_state scope_info; ACPI_FUNCTION_TRACE("ps_get_next_namepath"); path = acpi_ps_get_next_namestring(parser_state); /* Null path case is allowed */ if (path) { /* * Lookup the name in the internal namespace */ scope_info.scope.node = NULL; node = parser_state->start_node; if (node) { scope_info.scope.node = node; } /* * Lookup object. We don't want to add anything new to the namespace * here, however. So we use MODE_EXECUTE. Allow searching of the * parent tree, but don't open a new scope -- we just want to lookup the * object (MUST BE mode EXECUTE to perform upsearch) */ status = acpi_ns_lookup(&scope_info, path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &node); if (ACPI_SUCCESS(status) && method_call) { if (node->type == ACPI_TYPE_METHOD) { /* This name is actually a control method invocation */ method_desc = acpi_ns_get_attached_object(node); ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Control Method - %p Desc %p Path=%p\n", node, method_desc, path)); name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP); if (!name_op) { return_ACPI_STATUS(AE_NO_MEMORY); } /* Change arg into a METHOD CALL and attach name to it */ acpi_ps_init_op(arg, AML_INT_METHODCALL_OP); name_op->common.value.name = path; /* Point METHODCALL/NAME to the METHOD Node */ name_op->common.node = node; acpi_ps_append_arg(arg, name_op); if (!method_desc) { ACPI_REPORT_ERROR(("ps_get_next_namepath: Control Method %p has no attached object\n", node)); return_ACPI_STATUS(AE_AML_INTERNAL); } ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Control Method - %p Args %X\n", node, method_desc->method. param_count)); /* Get the number of arguments to expect */ walk_state->arg_count = method_desc->method.param_count; return_ACPI_STATUS(AE_OK); } /* * Else this is normal named object reference. * Just init the NAMEPATH object with the pathname. * (See code below) */ } if (ACPI_FAILURE(status)) { /* * 1) Any error other than NOT_FOUND is always severe * 2) NOT_FOUND is only important if we are executing a method. * 3) If executing a cond_ref_of opcode, NOT_FOUND is ok. */ if ((((walk_state-> parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) && (status == AE_NOT_FOUND) && (walk_state->op->common.aml_opcode != AML_COND_REF_OF_OP)) || (status != AE_NOT_FOUND)) { ACPI_REPORT_NSERROR(path, status); acpi_os_printf ("search_node %p start_node %p return_node %p\n", scope_info.scope.node, parser_state->start_node, node); } else { /* * We got a NOT_FOUND during table load or we encountered * a cond_ref_of(x) where the target does not exist. * Either case is ok */ status = AE_OK; } } } /* * Regardless of success/failure above, * Just initialize the Op with the pathname. */ acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); arg->common.value.name = path; return_ACPI_STATUS(status); }
ACPI_STATUS acpi_ns_root_initialize (void) { ACPI_STATUS status = AE_OK; PREDEFINED_NAMES *init_val = NULL; ACPI_NAMESPACE_NODE *new_node; ACPI_OPERAND_OBJECT *obj_desc; acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); /* * The global root ptr is initially NULL, so a non-NULL value indicates * that Acpi_ns_root_initialize() has already been called; just return. */ if (acpi_gbl_root_node) { status = AE_OK; goto unlock_and_exit; } /* * Tell the rest of the subsystem that the root is initialized * (This is OK because the namespace is locked) */ acpi_gbl_root_node = &acpi_gbl_root_node_struct; /* Enter the pre-defined names in the name table */ for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) { status = acpi_ns_lookup (NULL, init_val->name, (OBJECT_TYPE_INTERNAL) init_val->type, IMODE_LOAD_PASS2, NS_NO_UPSEARCH, NULL, &new_node); /* * Name entered successfully. * If entry in Pre_defined_names[] specifies an * initial value, create the initial value. */ if (init_val->val) { /* * Entry requests an initial value, allocate a * descriptor for it. */ obj_desc = acpi_cm_create_internal_object ( (OBJECT_TYPE_INTERNAL) init_val->type); if (!obj_desc) { status = AE_NO_MEMORY; goto unlock_and_exit; } /* * Convert value string from table entry to * internal representation. Only types actually * used for initial values are implemented here. */ switch (init_val->type) { case ACPI_TYPE_NUMBER: obj_desc->number.value = (ACPI_INTEGER) STRTOUL (init_val->val, NULL, 10); break; case ACPI_TYPE_STRING: obj_desc->string.length = (u16) STRLEN (init_val->val); /* * Allocate a buffer for the string. All * String.Pointers must be allocated buffers! * (makes deletion simpler) */ obj_desc->string.pointer = acpi_cm_allocate ( (obj_desc->string.length + 1)); if (!obj_desc->string.pointer) { acpi_cm_remove_reference (obj_desc); status = AE_NO_MEMORY; goto unlock_and_exit; } STRCPY (obj_desc->string.pointer, init_val->val); break; case ACPI_TYPE_MUTEX: obj_desc->mutex.sync_level = (u16) STRTOUL (init_val->val, NULL, 10); if (STRCMP (init_val->name, "_GL_") == 0) { /* * Create a counting semaphore for the * global lock */ status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 1, &obj_desc->mutex.semaphore); if (ACPI_FAILURE (status)) { goto unlock_and_exit; } /* * We just created the mutex for the * global lock, save it */ acpi_gbl_global_lock_semaphore = obj_desc->mutex.semaphore; } else { /* Create a mutex */ status = acpi_os_create_semaphore (1, 1, &obj_desc->mutex.semaphore); if (ACPI_FAILURE (status)) { goto unlock_and_exit; } } break; default: REPORT_ERROR (("Unsupported initial type value %X\n", init_val->type)); acpi_cm_remove_reference (obj_desc); obj_desc = NULL; continue; } /* Store pointer to value descriptor in the Node */ acpi_ns_attach_object (new_node, obj_desc, obj_desc->common.type); } } unlock_and_exit: acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); return (status); }
acpi_status acpi_ns_root_initialize(void) { acpi_status status; const struct acpi_predefined_names *init_val = NULL; struct acpi_namespace_node *new_node; union acpi_operand_object *obj_desc; acpi_string val = NULL; ACPI_FUNCTION_TRACE(ns_root_initialize); status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } if (acpi_gbl_root_node) { status = AE_OK; goto unlock_and_exit; } acpi_gbl_root_node = &acpi_gbl_root_node_struct; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Entering predefined entries into namespace\n")); for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) { if (!ACPI_STRCMP(init_val->name, "_OSI") && !acpi_gbl_create_osi_method) { continue; } status = acpi_ns_lookup(NULL, init_val->name, init_val->type, ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, NULL, &new_node); if (ACPI_FAILURE(status) || (!new_node)) { ACPI_EXCEPTION((AE_INFO, status, "Could not create predefined name %s", init_val->name)); } if (init_val->val) { status = acpi_os_predefined_override(init_val, &val); if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not override predefined %s", init_val->name)); } if (!val) { val = init_val->val; } obj_desc = acpi_ut_create_internal_object(init_val->type); if (!obj_desc) { status = AE_NO_MEMORY; goto unlock_and_exit; } switch (init_val->type) { case ACPI_TYPE_METHOD: obj_desc->method.param_count = (u8) ACPI_TO_INTEGER(val); obj_desc->common.flags |= AOPOBJ_DATA_VALID; #if defined (ACPI_ASL_COMPILER) new_node->value = obj_desc->method.param_count; #else obj_desc->method.info_flags = ACPI_METHOD_INTERNAL_ONLY; obj_desc->method.dispatch.implementation = acpi_ut_osi_implementation; #endif break; case ACPI_TYPE_INTEGER: obj_desc->integer.value = ACPI_TO_INTEGER(val); break; case ACPI_TYPE_STRING: obj_desc->string.length = (u32) ACPI_STRLEN(val); obj_desc->string.pointer = val; obj_desc->common.flags |= AOPOBJ_STATIC_POINTER; break; case ACPI_TYPE_MUTEX: obj_desc->mutex.node = new_node; obj_desc->mutex.sync_level = (u8) (ACPI_TO_INTEGER(val) - 1); status = acpi_os_create_mutex(&obj_desc->mutex. os_mutex); if (ACPI_FAILURE(status)) { acpi_ut_remove_reference(obj_desc); goto unlock_and_exit; } if (ACPI_STRCMP(init_val->name, "_GL_") == 0) { acpi_gbl_global_lock_mutex = obj_desc; status = acpi_os_create_semaphore(1, 0, &acpi_gbl_global_lock_semaphore); if (ACPI_FAILURE(status)) { acpi_ut_remove_reference (obj_desc); goto unlock_and_exit; } } break; default: ACPI_ERROR((AE_INFO, "Unsupported initial type value 0x%X", init_val->type)); acpi_ut_remove_reference(obj_desc); obj_desc = NULL; continue; } status = acpi_ns_attach_object(new_node, obj_desc, obj_desc->common.type); acpi_ut_remove_reference(obj_desc); } } unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (ACPI_SUCCESS(status)) { status = acpi_ns_get_node(NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH, &acpi_gbl_fadt_gpe_device); } return_ACPI_STATUS(status); }
acpi_status acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, union acpi_parse_object ** out_op) { union acpi_parse_object *op; struct acpi_namespace_node *node; acpi_status status; acpi_object_type object_type; char *path; u32 flags; ACPI_FUNCTION_TRACE(ds_load1_begin_op); op = walk_state->op; ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); /* We are only interested in opcodes that have an associated name */ if (op) { if (!(walk_state->op_info->flags & AML_NAMED)) { *out_op = op; return_ACPI_STATUS(AE_OK); } /* Check if this object has already been installed in the namespace */ if (op->common.node) { *out_op = op; return_ACPI_STATUS(AE_OK); } } path = acpi_ps_get_next_namestring(&walk_state->parser_state); /* Map the raw opcode into an internal object type */ object_type = walk_state->op_info->object_type; ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "State=%p Op=%p [%s]\n", walk_state, op, acpi_ut_get_type_name(object_type))); switch (walk_state->opcode) { case AML_SCOPE_OP: /* * The target name of the Scope() operator must exist at this point so * that we can actually open the scope to enter new names underneath it. * Allow search-to-root for single namesegs. */ status = acpi_ns_lookup(walk_state->scope_info, path, object_type, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node)); #ifdef ACPI_ASL_COMPILER if (status == AE_NOT_FOUND) { /* * Table disassembly: * Target of Scope() not found. Generate an External for it, and * insert the name into the namespace. */ acpi_dm_add_to_external_list(path, ACPI_TYPE_DEVICE, 0); status = acpi_ns_lookup(walk_state->scope_info, path, object_type, ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, walk_state, &node); } #endif if (ACPI_FAILURE(status)) { ACPI_ERROR_NAMESPACE(path, status); return_ACPI_STATUS(status); } /* * Check to make sure that the target is * one of the opcodes that actually opens a scope */ switch (node->type) { case ACPI_TYPE_ANY: case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ case ACPI_TYPE_DEVICE: case ACPI_TYPE_POWER: case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_THERMAL: /* These are acceptable types */ break; case ACPI_TYPE_INTEGER: case ACPI_TYPE_STRING: case ACPI_TYPE_BUFFER: /* * These types we will allow, but we will change the type. This * enables some existing code of the form: * * Name (DEB, 0) * Scope (DEB) { ... } * * Note: silently change the type here. On the second pass, we will report * a warning */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n", path, acpi_ut_get_type_name(node->type))); node->type = ACPI_TYPE_ANY; walk_state->scope_info->common.value = ACPI_TYPE_ANY; break; default: /* All other types are an error */ ACPI_ERROR((AE_INFO, "Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)", acpi_ut_get_type_name(node->type), path)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } break; default: /* * For all other named opcodes, we will enter the name into * the namespace. * * Setup the search flags. * Since we are entering a name into the namespace, we do not want to * enable the search-to-root upsearch. * * There are only two conditions where it is acceptable that the name * already exists: * 1) the Scope() operator can reopen a scoping object that was * previously defined (Scope, Method, Device, etc.) * 2) Whenever we are parsing a deferred opcode (op_region, Buffer, * buffer_field, or Package), the name of the object is already * in the namespace. */ if (walk_state->deferred_node) { /* This name is already in the namespace, get the node */ node = walk_state->deferred_node; status = AE_OK; break; } /* * If we are executing a method, do not create any namespace objects * during the load phase, only during execution. */ if (walk_state->method_node) { node = NULL; status = AE_OK; break; } flags = ACPI_NS_NO_UPSEARCH; if ((walk_state->opcode != AML_SCOPE_OP) && (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) { flags |= ACPI_NS_ERROR_IF_FOUND; ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n", acpi_ut_get_type_name(object_type))); } else { ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[%s] Both Find or Create allowed\n", acpi_ut_get_type_name(object_type))); } /* * Enter the named type into the internal namespace. We enter the name * as we go downward in the parse tree. Any necessary subobjects that * involve arguments to the opcode must be created as we go back up the * parse tree later. */ status = acpi_ns_lookup(walk_state->scope_info, path, object_type, ACPI_IMODE_LOAD_PASS1, flags, walk_state, &node); if (ACPI_FAILURE(status)) { if (status == AE_ALREADY_EXISTS) { /* The name already exists in this scope */ if (node->flags & ANOBJ_IS_EXTERNAL) { /* * Allow one create on an object or segment that was * previously declared External */ node->flags &= ~ANOBJ_IS_EXTERNAL; node->type = (u8) object_type; /* Just retyped a node, probably will need to open a scope */ if (acpi_ns_opens_scope(object_type)) { status = acpi_ds_scope_stack_push (node, object_type, walk_state); if (ACPI_FAILURE(status)) { return_ACPI_STATUS (status); } } status = AE_OK; } } if (ACPI_FAILURE(status)) { ACPI_ERROR_NAMESPACE(path, status); return_ACPI_STATUS(status); } } break; } /* Common exit */ if (!op) { /* Create a new op */ op = acpi_ps_alloc_op(walk_state->opcode); if (!op) { return_ACPI_STATUS(AE_NO_MEMORY); } } /* Initialize the op */ #if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)) op->named.path = ACPI_CAST_PTR(u8, path); #endif if (node) { /* * Put the Node in the "op" object that the parser uses, so we * can get it again quickly when this scope is closed */ op->common.node = node; op->named.name = node->name.integer; } acpi_ps_append_arg(acpi_ps_get_parent_scope(&walk_state->parser_state), op); *out_op = op; return_ACPI_STATUS(status); }
/******************************************************************************* * * FUNCTION: acpi_ns_root_initialize * * PARAMETERS: None * * RETURN: Status * * DESCRIPTION: Allocate and initialize the default root named objects * * MUTEX: Locks namespace for entire execution * ******************************************************************************/ acpi_status acpi_ns_root_initialize(void) { acpi_status status; const struct acpi_predefined_names *init_val = NULL; struct acpi_namespace_node *new_node; union acpi_operand_object *obj_desc; acpi_string val = NULL; ACPI_FUNCTION_TRACE(ns_root_initialize); status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* * The global root ptr is initially NULL, so a non-NULL value indicates * that acpi_ns_root_initialize() has already been called; just return. */ if (acpi_gbl_root_node) { status = AE_OK; goto unlock_and_exit; } /* * Tell the rest of the subsystem that the root is initialized * (This is OK because the namespace is locked) */ acpi_gbl_root_node = &acpi_gbl_root_node_struct; /* Enter the pre-defined names in the name table */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Entering predefined entries into namespace\n")); for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) { /* _OSI is optional for now, will be permanent later */ if (!ACPI_STRCMP(init_val->name, "_OSI") && !acpi_gbl_create_osi_method) { continue; } status = acpi_ns_lookup(NULL, init_val->name, init_val->type, ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, NULL, &new_node); if (ACPI_FAILURE(status) || (!new_node)) { /* Must be on same line for code converter */ ACPI_EXCEPTION((AE_INFO, status, "Could not create predefined name %s", init_val->name)); } /* * Name entered successfully. * If entry in pre_defined_names[] specifies an * initial value, create the initial value. */ if (init_val->val) { status = acpi_os_predefined_override(init_val, &val); if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not override predefined %s", init_val->name)); } if (!val) { val = init_val->val; } /* * Entry requests an initial value, allocate a * descriptor for it. */ obj_desc = acpi_ut_create_internal_object(init_val->type); if (!obj_desc) { status = AE_NO_MEMORY; goto unlock_and_exit; } /* * Convert value string from table entry to * internal representation. Only types actually * used for initial values are implemented here. */ switch (init_val->type) { case ACPI_TYPE_METHOD: obj_desc->method.param_count = (u8) ACPI_TO_INTEGER(val); obj_desc->common.flags |= AOPOBJ_DATA_VALID; #if defined (ACPI_ASL_COMPILER) /* Save the parameter count for the i_aSL compiler */ new_node->value = obj_desc->method.param_count; #else /* Mark this as a very SPECIAL method */ obj_desc->method.method_flags = AML_METHOD_INTERNAL_ONLY; obj_desc->method.implementation = acpi_ut_osi_implementation; #endif break; case ACPI_TYPE_INTEGER: obj_desc->integer.value = ACPI_TO_INTEGER(val); break; case ACPI_TYPE_STRING: /* * Build an object around the static string */ obj_desc->string.length = (u32) ACPI_STRLEN(val); obj_desc->string.pointer = val; obj_desc->common.flags |= AOPOBJ_STATIC_POINTER; break; case ACPI_TYPE_MUTEX: obj_desc->mutex.node = new_node; obj_desc->mutex.sync_level = (u8) (ACPI_TO_INTEGER(val) - 1); /* Create a mutex */ status = acpi_os_create_mutex(&obj_desc->mutex. os_mutex); if (ACPI_FAILURE(status)) { acpi_ut_remove_reference(obj_desc); goto unlock_and_exit; } /* Special case for ACPI Global Lock */ if (ACPI_STRCMP(init_val->name, "_GL_") == 0) { acpi_gbl_global_lock_mutex = obj_desc; /* Create additional counting semaphore for global lock */ status = acpi_os_create_semaphore(1, 0, &acpi_gbl_global_lock_semaphore); if (ACPI_FAILURE(status)) { acpi_ut_remove_reference (obj_desc); goto unlock_and_exit; } } break; default: ACPI_ERROR((AE_INFO, "Unsupported initial type value %X", init_val->type)); acpi_ut_remove_reference(obj_desc); obj_desc = NULL; continue; } /* Store pointer to value descriptor in the Node */ status = acpi_ns_attach_object(new_node, obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc)); /* Remove local reference to the object */ acpi_ut_remove_reference(obj_desc); } } unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); /* Save a handle to "_GPE", it is always present */ if (ACPI_SUCCESS(status)) { status = acpi_ns_get_node(NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH, &acpi_gbl_fadt_gpe_device); } return_ACPI_STATUS(status); }
acpi_status acpi_ds_load2_begin_op ( acpi_walk_state *walk_state, acpi_parse_object **out_op) { acpi_parse_object *op; acpi_namespace_node *node; acpi_status status; acpi_object_type8 data_type; NATIVE_CHAR *buffer_ptr; void *original = NULL; PROC_NAME ("Ds_load2_begin_op"); op = walk_state->op; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); if (op) { /* We only care about Namespace opcodes here */ if (!(walk_state->op_info->flags & AML_NSOPCODE) && walk_state->opcode != AML_INT_NAMEPATH_OP) { return (AE_OK); } /* TBD: [Restructure] Temp! same code as in psparse */ if (!(walk_state->op_info->flags & AML_NAMED)) { return (AE_OK); } /* * Get the name we are going to enter or lookup in the namespace */ if (walk_state->opcode == AML_INT_NAMEPATH_OP) { /* For Namepath op, get the path string */ buffer_ptr = op->value.string; if (!buffer_ptr) { /* No name, just exit */ return (AE_OK); } } else { /* Get name from the op */ buffer_ptr = (NATIVE_CHAR *) &((acpi_parse2_object *)op)->name; } } else { buffer_ptr = acpi_ps_get_next_namestring (&walk_state->parser_state); } /* Map the raw opcode into an internal object type */ data_type = acpi_ds_map_named_opcode_to_data_type (walk_state->opcode); ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "State=%p Op=%p Type=%x\n", walk_state, op, data_type)); if (walk_state->opcode == AML_FIELD_OP || walk_state->opcode == AML_BANK_FIELD_OP || walk_state->opcode == AML_INDEX_FIELD_OP) { node = NULL; status = AE_OK; } else if (walk_state->opcode == AML_INT_NAMEPATH_OP) { /* * The Name_path is an object reference to an existing object. Don't enter the * name into the namespace, but look it up for use later */ status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, data_type, IMODE_EXECUTE, NS_SEARCH_PARENT, walk_state, &(node)); } else { if (op && op->node) { original = op->node; node = op->node; if (acpi_ns_opens_scope (data_type)) { status = acpi_ds_scope_stack_push (node, data_type, walk_state); if (ACPI_FAILURE (status)) { return (status); } } return (AE_OK); } /* * Enter the named type into the internal namespace. We enter the name * as we go downward in the parse tree. Any necessary subobjects that involve * arguments to the opcode must be created as we go back up the parse tree later. */ status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, data_type, IMODE_EXECUTE, NS_NO_UPSEARCH, walk_state, &(node)); } if (ACPI_SUCCESS (status)) { if (!op) { /* Create a new op */ op = acpi_ps_alloc_op (walk_state->opcode); if (!op) { return (AE_NO_MEMORY); } /* Initialize */ ((acpi_parse2_object *)op)->name = node->name; *out_op = op; } /* * Put the Node in the "op" object that the parser uses, so we * can get it again quickly when this scope is closed */ op->node = node; if (original) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "old %p new %p\n", original, node)); if (original != node) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Lookup match error: old %p new %p\n", original, node)); } } } return (status); }
acpi_status acpi_ns_evaluate_relative(char *pathname, struct acpi_parameter_info *info) { acpi_status status; struct acpi_namespace_node *node = NULL; union acpi_generic_state *scope_info; char *internal_path = NULL; ACPI_FUNCTION_TRACE("ns_evaluate_relative"); /* * Must have a valid object handle */ if (!info || !info->node) { return_ACPI_STATUS(AE_BAD_PARAMETER); } /* Build an internal name string for the method */ status = acpi_ns_internalize_name(pathname, &internal_path); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } scope_info = acpi_ut_create_generic_state(); if (!scope_info) { goto cleanup1; } /* Get the prefix handle and Node */ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { goto cleanup; } info->node = acpi_ns_map_handle_to_node(info->node); if (!info->node) { (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); status = AE_BAD_PARAMETER; goto cleanup; } /* Lookup the name in the namespace */ scope_info->scope.node = info->node; status = acpi_ns_lookup(scope_info, internal_path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, &node); (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Object [%s] not found [%s]\n", pathname, acpi_format_exception(status))); goto cleanup; } /* * Now that we have a handle to the object, we can attempt to evaluate it. */ ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", pathname, node, acpi_ns_get_attached_object(node))); info->node = node; status = acpi_ns_evaluate_by_handle(info); ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n", pathname)); cleanup: acpi_ut_delete_generic_state(scope_info); cleanup1: ACPI_MEM_FREE(internal_path); return_ACPI_STATUS(status); }
void acpi_ps_get_next_namepath ( ACPI_PARSE_STATE *parser_state, ACPI_PARSE_OBJECT *arg, u32 *arg_count, u8 method_call) { NATIVE_CHAR *path; ACPI_PARSE_OBJECT *name_op; ACPI_STATUS status; ACPI_NAMESPACE_NODE *method_node = NULL; ACPI_NAMESPACE_NODE *node; ACPI_GENERIC_STATE scope_info; path = acpi_ps_get_next_namestring (parser_state); if (!path || !method_call) { /* Null name case, create a null namepath object */ acpi_ps_init_op (arg, AML_NAMEPATH_OP); arg->value.name = path; return; } if (method_call) { /* * Lookup the name in the internal namespace */ scope_info.scope.node = NULL; node = parser_state->start_node; if (node) { scope_info.scope.node = node; } /* * Lookup object. We don't want to add anything new to the namespace * here, however. So we use MODE_EXECUTE. Allow searching of the * parent tree, but don't open a new scope -- we just want to lookup the * object (MUST BE mode EXECUTE to perform upsearch) */ status = acpi_ns_lookup (&scope_info, path, ACPI_TYPE_ANY, IMODE_EXECUTE, NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE, NULL, &node); if (ACPI_SUCCESS (status)) { if (node->type == ACPI_TYPE_METHOD) { method_node = node; name_op = acpi_ps_alloc_op (AML_NAMEPATH_OP); if (name_op) { /* Change arg into a METHOD CALL and attach name to it */ acpi_ps_init_op (arg, AML_METHODCALL_OP); name_op->value.name = path; /* Point METHODCALL/NAME to the METHOD Node */ name_op->node = method_node; acpi_ps_append_arg (arg, name_op); if (!(ACPI_OPERAND_OBJECT *) method_node->object) { return; } *arg_count = ((ACPI_OPERAND_OBJECT *) method_node->object)->method.param_count; } return; } /* * Else this is normal named object reference. * Just init the NAMEPATH object with the pathname. * (See code below) */ } } /* * Either we didn't find the object in the namespace, or the object is * something other than a control method. Just initialize the Op with the * pathname. */ acpi_ps_init_op (arg, AML_NAMEPATH_OP); arg->value.name = path; return; }