patch-2.4.22 linux-2.4.22/drivers/acpi/dispatcher/dsobject.c
Next file: linux-2.4.22/drivers/acpi/dispatcher/dsopcode.c
Previous file: linux-2.4.22/drivers/acpi/dispatcher/dsmthdat.c
Back to the patch index
Back to the overall index
- Lines: 1116
- Date:
2003-08-25 04:44:41.000000000 -0700
- Orig file:
linux-2.4.21/drivers/acpi/dispatcher/dsobject.c
- Orig date:
2001-10-24 14:06:22.000000000 -0700
diff -urN linux-2.4.21/drivers/acpi/dispatcher/dsobject.c linux-2.4.22/drivers/acpi/dispatcher/dsobject.c
@@ -1,692 +1,612 @@
/******************************************************************************
*
* Module Name: dsobject - Dispatcher object management routines
- * $Revision: 81 $
*
*****************************************************************************/
/*
- * Copyright (C) 2000, 2001 R. Byron Moore
+ * Copyright (C) 2000 - 2003, R. Byron Moore
+ * All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * 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.h"
-#include "acparser.h"
-#include "amlcode.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acinterp.h>
#define _COMPONENT ACPI_DISPATCHER
- MODULE_NAME ("dsobject")
+ ACPI_MODULE_NAME ("dsobject")
-/*******************************************************************************
+#ifndef ACPI_NO_METHOD_EXECUTION
+/*****************************************************************************
*
- * FUNCTION: Acpi_ds_init_one_object
+ * FUNCTION: acpi_ds_build_internal_object
*
- * PARAMETERS: Obj_handle - Node
- * Level - Current nesting level
- * Context - Points to a init info struct
- * Return_value - Not used
+ * PARAMETERS: walk_state - Current walk state
+ * Op - Parser object to be translated
+ * obj_desc_ptr - Where the ACPI internal object is returned
*
* RETURN: Status
*
- * DESCRIPTION: Callback from Acpi_walk_namespace. Invoked for every object
- * within the namespace.
- *
- * Currently, the only objects that require initialization are:
- * 1) Methods
- * 2) Op Regions
+ * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
+ * Simple objects are any objects other than a package object!
*
- ******************************************************************************/
+ ****************************************************************************/
acpi_status
-acpi_ds_init_one_object (
- acpi_handle obj_handle,
- u32 level,
- void *context,
- void **return_value)
+acpi_ds_build_internal_object (
+ struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ union acpi_operand_object **obj_desc_ptr)
{
- acpi_object_type8 type;
- acpi_status status;
- acpi_init_walk_info *info = (acpi_init_walk_info *) context;
- u8 table_revision;
-
-
- PROC_NAME ("Ds_init_one_object");
-
-
- info->object_count++;
- table_revision = info->table_desc->pointer->revision;
-
- /*
- * We are only interested in objects owned by the table that
- * was just loaded
- */
- if (((acpi_namespace_node *) obj_handle)->owner_id !=
- info->table_desc->table_id) {
- return (AE_OK);
- }
-
-
- /* And even then, we are only interested in a few object types */
-
- type = acpi_ns_get_type (obj_handle);
-
- switch (type) {
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
- case ACPI_TYPE_REGION:
- acpi_ds_initialize_region (obj_handle);
+ ACPI_FUNCTION_TRACE ("ds_build_internal_object");
- info->op_region_count++;
- break;
-
-
- case ACPI_TYPE_METHOD:
-
- info->method_count++;
-
- if (!(acpi_dbg_level & ACPI_LV_INIT)) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "."));
- }
-
- /*
- * Set the execution data width (32 or 64) based upon the
- * revision number of the parent ACPI table.
- */
- if (table_revision == 1) {
- ((acpi_namespace_node *)obj_handle)->flags |= ANOBJ_DATA_WIDTH_32;
- }
+ *obj_desc_ptr = NULL;
+ if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
/*
- * Always parse methods to detect errors, we may delete
- * the parse tree below
+ * 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
*/
- status = acpi_ds_parse_method (obj_handle);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Method %p [%4.4s] - parse failure, %s\n",
- obj_handle, (char*)&((acpi_namespace_node *)obj_handle)->name,
- acpi_format_exception (status)));
+ 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));
- /* This parse failed, but we will continue parsing more methods */
-
- break;
+ if (ACPI_FAILURE (status)) {
+ ACPI_REPORT_NSERROR (op->common.value.string, status);
+ return_ACPI_STATUS (status);
+ }
}
-
- /*
- * Delete the parse tree. We simple re-parse the method
- * for every execution since there isn't much overhead
- */
- acpi_ns_delete_namespace_subtree (obj_handle);
- break;
-
- default:
- break;
}
- /*
- * We ignore errors from above, and always return OK, since
- * we don't want to abort the walk on a single error.
- */
- return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_ds_initialize_objects
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: Walk the entire namespace and perform any necessary
- * initialization on the objects found therein
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ds_initialize_objects (
- acpi_table_desc *table_desc,
- acpi_namespace_node *start_node)
-{
- acpi_status status;
- acpi_init_walk_info info;
-
-
- FUNCTION_TRACE ("Ds_initialize_objects");
-
-
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "**** Starting initialization of namespace objects ****\n"));
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "Parsing Methods:"));
-
-
- info.method_count = 0;
- info.op_region_count = 0;
- info.object_count = 0;
- info.table_desc = table_desc;
-
+ /* Create and init the internal ACPI object */
- /* Walk entire namespace from the supplied root */
+ 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_walk_namespace (ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
- acpi_ds_init_one_object, &info, NULL);
+ status = acpi_ds_init_object_from_op (walk_state, op, op->common.aml_opcode, &obj_desc);
if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Walk_namespace failed! %x\n", status));
+ acpi_ut_remove_reference (obj_desc);
+ return_ACPI_STATUS (status);
}
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK,
- "\n%d Control Methods found and parsed (%d nodes total)\n",
- info.method_count, info.object_count));
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "%d Control Methods found\n", info.method_count));
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "%d Op Regions found\n", info.op_region_count));
-
+ *obj_desc_ptr = obj_desc;
return_ACPI_STATUS (AE_OK);
}
/*****************************************************************************
*
- * FUNCTION: Acpi_ds_init_object_from_op
+ * FUNCTION: acpi_ds_build_internal_buffer_obj
*
- * PARAMETERS: Op - Parser op used to init the internal object
- * Opcode - AML opcode associated with the object
- * Obj_desc - Namespace object to be initialized
+ * PARAMETERS: walk_state - Current walk state
+ * Op - Parser object to be translated
+ * buffer_length - Length of the buffer
+ * obj_desc_ptr - Where the ACPI internal object is returned
*
* RETURN: Status
*
- * DESCRIPTION: Initialize a namespace object from a parser Op and its
- * associated arguments. The namespace object is a more compact
- * representation of the Op and its arguments.
+ * DESCRIPTION: Translate a parser Op package object to the equivalent
+ * namespace object
*
****************************************************************************/
acpi_status
-acpi_ds_init_object_from_op (
- acpi_walk_state *walk_state,
- acpi_parse_object *op,
- u16 opcode,
- acpi_operand_object **ret_obj_desc)
+acpi_ds_build_internal_buffer_obj (
+ struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ u32 buffer_length,
+ union acpi_operand_object **obj_desc_ptr)
{
- acpi_status status;
- acpi_parse_object *arg;
- acpi_parse2_object *byte_list;
- acpi_operand_object *arg_desc;
- const acpi_opcode_info *op_info;
- acpi_operand_object *obj_desc;
-
+ union acpi_parse_object *arg;
+ union acpi_operand_object *obj_desc;
+ union acpi_parse_object *byte_list;
+ u32 byte_list_length = 0;
- PROC_NAME ("Ds_init_object_from_op");
+ ACPI_FUNCTION_TRACE ("ds_build_internal_buffer_obj");
- obj_desc = *ret_obj_desc;
- op_info = acpi_ps_get_opcode_info (opcode);
- if (op_info->class == AML_CLASS_UNKNOWN) {
- /* Unknown opcode */
- return (AE_TYPE);
+ obj_desc = *obj_desc_ptr;
+ if (obj_desc) {
+ /*
+ * We are evaluating a Named buffer object "Name (xxxx, Buffer)".
+ * The buffer object already exists (from the NS node)
+ */
}
+ else {
+ /* Create a new buffer object */
-
- /* Get and prepare the first argument */
-
- switch (obj_desc->common.type) {
- case ACPI_TYPE_BUFFER:
-
- /* First arg is a number */
-
- acpi_ds_create_operand (walk_state, op->value.arg, 0);
- arg_desc = walk_state->operands [walk_state->num_operands - 1];
- acpi_ds_obj_stack_pop (1, walk_state);
-
- /* Resolve the object (could be an arg or local) */
-
- status = acpi_ex_resolve_to_value (&arg_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- acpi_ut_remove_reference (arg_desc);
- return (status);
+ obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
+ *obj_desc_ptr = obj_desc;
+ if (!obj_desc) {
+ return_ACPI_STATUS (AE_NO_MEMORY);
}
+ }
- /* We are expecting a number */
+ /*
+ * Second arg is the buffer data (optional) byte_list can be either
+ * individual bytes or a string initializer. In either case, a
+ * byte_list appears in the AML.
+ */
+ arg = op->common.value.arg; /* skip first arg */
- if (arg_desc->common.type != ACPI_TYPE_INTEGER) {
+ byte_list = arg->named.next;
+ if (byte_list) {
+ if (byte_list->common.aml_opcode != AML_INT_BYTELIST_OP) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Expecting number, got obj: %p type %X\n",
- arg_desc, arg_desc->common.type));
- acpi_ut_remove_reference (arg_desc);
+ "Expecting bytelist, got AML opcode %X in op %p\n",
+ byte_list->common.aml_opcode, byte_list));
+
+ acpi_ut_remove_reference (obj_desc);
return (AE_TYPE);
}
- /* Get the value, delete the internal object */
+ byte_list_length = (u32) byte_list->common.value.integer;
+ }
- obj_desc->buffer.length = (u32) arg_desc->integer.value;
- acpi_ut_remove_reference (arg_desc);
+ /*
+ * The buffer length (number of bytes) will be the larger of:
+ * 1) The specified buffer length and
+ * 2) The length of the initializer byte list
+ */
+ obj_desc->buffer.length = buffer_length;
+ if (byte_list_length > buffer_length) {
+ obj_desc->buffer.length = byte_list_length;
+ }
- /* Allocate the buffer */
+ /* Allocate the buffer */
- if (obj_desc->buffer.length == 0) {
- obj_desc->buffer.pointer = NULL;
- REPORT_WARNING (("Buffer created with zero length in AML\n"));
- break;
+ if (obj_desc->buffer.length == 0) {
+ obj_desc->buffer.pointer = NULL;
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Buffer defined with zero length in AML, creating\n"));
+ }
+ else {
+ obj_desc->buffer.pointer = ACPI_MEM_CALLOCATE (
+ obj_desc->buffer.length);
+ if (!obj_desc->buffer.pointer) {
+ acpi_ut_delete_object_desc (obj_desc);
+ return_ACPI_STATUS (AE_NO_MEMORY);
}
- else {
- obj_desc->buffer.pointer = ACPI_MEM_CALLOCATE (
- obj_desc->buffer.length);
+ /* Initialize buffer from the byte_list (if present) */
- if (!obj_desc->buffer.pointer) {
- return (AE_NO_MEMORY);
- }
+ if (byte_list) {
+ ACPI_MEMCPY (obj_desc->buffer.pointer, byte_list->named.data,
+ byte_list_length);
}
+ }
- /*
- * Second arg is the buffer data (optional) Byte_list can be either
- * individual bytes or a string initializer.
- */
- arg = op->value.arg; /* skip first arg */
-
- byte_list = (acpi_parse2_object *) arg->next;
- if (byte_list) {
- if (byte_list->opcode != AML_INT_BYTELIST_OP) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Expecting bytelist, got: %p\n",
- byte_list));
- return (AE_TYPE);
- }
+ obj_desc->buffer.flags |= AOPOBJ_DATA_VALID;
+ op->common.node = (struct acpi_namespace_node *) obj_desc;
+ return_ACPI_STATUS (AE_OK);
+}
- MEMCPY (obj_desc->buffer.pointer, byte_list->data,
- obj_desc->buffer.length);
- }
- break;
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_ds_build_internal_package_obj
+ *
+ * PARAMETERS: walk_state - Current walk state
+ * Op - Parser object to be translated
+ * package_length - Number of elements in the package
+ * obj_desc_ptr - Where the ACPI internal object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Translate a parser Op package object to the equivalent
+ * namespace object
+ *
+ ****************************************************************************/
+acpi_status
+acpi_ds_build_internal_package_obj (
+ struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ u32 package_length,
+ union acpi_operand_object **obj_desc_ptr)
+{
+ union acpi_parse_object *arg;
+ union acpi_parse_object *parent;
+ union acpi_operand_object *obj_desc = NULL;
+ u32 package_list_length;
+ acpi_status status = AE_OK;
+ u32 i;
- case ACPI_TYPE_PACKAGE:
- /*
- * When called, an internal package object has already been built and
- * is pointed to by Obj_desc. Acpi_ds_build_internal_object builds another
- * internal package object, so remove reference to the original so
- * that it is deleted. Error checking is done within the remove
- * reference function.
- */
- acpi_ut_remove_reference (obj_desc);
- status = acpi_ds_build_internal_object (walk_state, op, ret_obj_desc);
- break;
+ ACPI_FUNCTION_TRACE ("ds_build_internal_package_obj");
- case ACPI_TYPE_INTEGER:
- obj_desc->integer.value = op->value.integer;
- break;
+ /* Find the parent of a possibly nested package */
- case ACPI_TYPE_STRING:
- obj_desc->string.pointer = op->value.string;
- obj_desc->string.length = STRLEN (op->value.string);
+ parent = op->common.parent;
+ while ((parent->common.aml_opcode == AML_PACKAGE_OP) ||
+ (parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
+ parent = parent->common.parent;
+ }
+ obj_desc = *obj_desc_ptr;
+ if (obj_desc) {
/*
- * The string is contained in the ACPI table, don't ever try
- * to delete it
+ * We are evaluating a Named package object "Name (xxxx, Package)".
+ * Get the existing package object from the NS node
*/
- obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
- break;
-
-
- case ACPI_TYPE_METHOD:
- break;
-
-
- case INTERNAL_TYPE_REFERENCE:
-
- switch (op_info->type) {
- case AML_TYPE_LOCAL_VARIABLE:
-
- /* Split the opcode into a base opcode + offset */
-
- obj_desc->reference.opcode = AML_LOCAL_OP;
- obj_desc->reference.offset = opcode - AML_LOCAL_OP;
- break;
+ }
+ else {
+ obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE);
+ *obj_desc_ptr = obj_desc;
+ if (!obj_desc) {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+ obj_desc->package.node = parent->common.node;
+ }
- case AML_TYPE_METHOD_ARGUMENT:
+ obj_desc->package.count = package_length;
- /* Split the opcode into a base opcode + offset */
+ /* Count the number of items in the package list */
- obj_desc->reference.opcode = AML_ARG_OP;
- obj_desc->reference.offset = opcode - AML_ARG_OP;
- break;
+ package_list_length = 0;
+ arg = op->common.value.arg;
+ arg = arg->common.next;
+ while (arg) {
+ package_list_length++;
+ arg = arg->common.next;
+ }
+ /*
+ * The package length (number of elements) will be the greater
+ * of the specified length and the length of the initializer list
+ */
+ if (package_list_length > package_length) {
+ obj_desc->package.count = package_list_length;
+ }
- default: /* Constants, Literals, etc.. */
+ /*
+ * Allocate the pointer array (array of pointers to the
+ * individual objects). Add an extra pointer slot so
+ * that the list is always null terminated.
+ */
+ obj_desc->package.elements = ACPI_MEM_CALLOCATE (
+ ((acpi_size) obj_desc->package.count + 1) * sizeof (void *));
- if (op->opcode == AML_INT_NAMEPATH_OP) {
- /* Node was saved in Op */
+ if (!obj_desc->package.elements) {
+ acpi_ut_delete_object_desc (obj_desc);
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
- obj_desc->reference.node = op->node;
- }
+ /*
+ * Now init the elements of the package
+ */
+ i = 0;
+ arg = op->common.value.arg;
+ arg = arg->common.next;
+ while (arg) {
+ if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
+ /* Object (package or buffer) is already built */
- obj_desc->reference.opcode = opcode;
- break;
+ obj_desc->package.elements[i] = ACPI_CAST_PTR (union acpi_operand_object, arg->common.node);
+ }
+ else {
+ status = acpi_ds_build_internal_object (walk_state, arg,
+ &obj_desc->package.elements[i]);
}
- break;
-
-
- default:
-
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unimplemented data type: %x\n",
- obj_desc->common.type));
-
- break;
+ i++;
+ arg = arg->common.next;
}
- return (AE_OK);
+ obj_desc->package.flags |= AOPOBJ_DATA_VALID;
+ op->common.node = (struct acpi_namespace_node *) obj_desc;
+ return_ACPI_STATUS (status);
}
/*****************************************************************************
*
- * FUNCTION: Acpi_ds_build_internal_simple_obj
+ * FUNCTION: acpi_ds_create_node
*
- * PARAMETERS: Op - Parser object to be translated
- * Obj_desc_ptr - Where the ACPI internal object is returned
+ * PARAMETERS: walk_state - Current walk state
+ * Node - NS Node to be initialized
+ * Op - Parser object to be translated
*
* RETURN: Status
*
- * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
- * Simple objects are any objects other than a package object!
+ * DESCRIPTION: Create the object to be associated with a namespace node
*
****************************************************************************/
-static acpi_status
-acpi_ds_build_internal_simple_obj (
- acpi_walk_state *walk_state,
- acpi_parse_object *op,
- acpi_operand_object **obj_desc_ptr)
+acpi_status
+acpi_ds_create_node (
+ struct acpi_walk_state *walk_state,
+ struct acpi_namespace_node *node,
+ union acpi_parse_object *op)
{
- acpi_operand_object *obj_desc;
- acpi_object_type8 type;
- acpi_status status;
- u32 length;
- char *name;
+ acpi_status status;
+ union acpi_operand_object *obj_desc;
- FUNCTION_TRACE ("Ds_build_internal_simple_obj");
-
-
- if (op->opcode == AML_INT_NAMEPATH_OP) {
- /*
- * This is an object reference. If The name was
- * previously looked up in the NS, it is stored in this op.
- * Otherwise, go ahead and look it up now
- */
- if (!op->node) {
- status = acpi_ns_lookup (walk_state->scope_info,
- op->value.string, ACPI_TYPE_ANY,
- IMODE_EXECUTE,
- NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE,
- NULL,
- (acpi_namespace_node **)&(op->node));
+ ACPI_FUNCTION_TRACE_PTR ("ds_create_node", op);
- if (ACPI_FAILURE (status)) {
- if (status == AE_NOT_FOUND) {
- name = NULL;
- acpi_ns_externalize_name (ACPI_UINT32_MAX, op->value.string, &length, &name);
-
- if (name) {
- REPORT_WARNING (("Reference %s at AML %X not found\n",
- name, op->aml_offset));
- ACPI_MEM_FREE (name);
- }
-
- else {
- REPORT_WARNING (("Reference %s at AML %X not found\n",
- op->value.string, op->aml_offset));
- }
-
- *obj_desc_ptr = NULL;
- }
-
- else {
- return_ACPI_STATUS (status);
- }
- }
- }
- /*
- * The reference will be a Reference
- * TBD: [Restructure] unless we really need a separate
- * type of INTERNAL_TYPE_REFERENCE change
- * Acpi_ds_map_opcode_to_data_type to handle this case
- */
- type = INTERNAL_TYPE_REFERENCE;
- }
- else {
- type = acpi_ds_map_opcode_to_data_type (op->opcode, NULL);
+ /*
+ * Because of the execution pass through the non-control-method
+ * parts of the table, we can arrive here twice. Only init
+ * the named object node the first time through
+ */
+ if (acpi_ns_get_attached_object (node)) {
+ return_ACPI_STATUS (AE_OK);
}
+ if (!op->common.value.arg) {
+ /* No arguments, there is nothing to do */
- /* Create and init the internal ACPI object */
-
- obj_desc = acpi_ut_create_internal_object (type);
- if (!obj_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_ACPI_STATUS (AE_OK);
}
- status = acpi_ds_init_object_from_op (walk_state, op, op->opcode, &obj_desc);
+ /* Build an internal object for the argument(s) */
+
+ status = acpi_ds_build_internal_object (walk_state, op->common.value.arg, &obj_desc);
if (ACPI_FAILURE (status)) {
- acpi_ut_remove_reference (obj_desc);
return_ACPI_STATUS (status);
}
- *obj_desc_ptr = obj_desc;
+ /* Re-type the object according to its argument */
- return_ACPI_STATUS (AE_OK);
+ node->type = ACPI_GET_OBJECT_TYPE (obj_desc);
+
+ /* Attach obj to node */
+
+ status = acpi_ns_attach_object (node, obj_desc, node->type);
+
+ /* Remove local reference to the object */
+
+ acpi_ut_remove_reference (obj_desc);
+ return_ACPI_STATUS (status);
}
+#endif /* ACPI_NO_METHOD_EXECUTION */
+
/*****************************************************************************
*
- * FUNCTION: Acpi_ds_build_internal_package_obj
+ * FUNCTION: acpi_ds_init_object_from_op
*
- * PARAMETERS: Op - Parser object to be translated
- * Obj_desc_ptr - Where the ACPI internal object is returned
+ * PARAMETERS: walk_state - Current walk state
+ * Op - Parser op used to init the internal object
+ * Opcode - AML opcode associated with the object
+ * ret_obj_desc - Namespace object to be initialized
*
* RETURN: Status
*
- * DESCRIPTION: Translate a parser Op package object to the equivalent
- * namespace object
+ * DESCRIPTION: Initialize a namespace object from a parser Op and its
+ * associated arguments. The namespace object is a more compact
+ * representation of the Op and its arguments.
*
****************************************************************************/
acpi_status
-acpi_ds_build_internal_package_obj (
- acpi_walk_state *walk_state,
- acpi_parse_object *op,
- acpi_operand_object **obj_desc_ptr)
+acpi_ds_init_object_from_op (
+ struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ u16 opcode,
+ union acpi_operand_object **ret_obj_desc)
{
- acpi_parse_object *arg;
- acpi_operand_object *obj_desc;
- acpi_status status = AE_OK;
+ const struct acpi_opcode_info *op_info;
+ union acpi_operand_object *obj_desc;
+ acpi_status status = AE_OK;
- FUNCTION_TRACE ("Ds_build_internal_package_obj");
+ ACPI_FUNCTION_TRACE ("ds_init_object_from_op");
- obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE);
- *obj_desc_ptr = obj_desc;
- if (!obj_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
+ obj_desc = *ret_obj_desc;
+ op_info = acpi_ps_get_opcode_info (opcode);
+ if (op_info->class == AML_CLASS_UNKNOWN) {
+ /* Unknown opcode */
+
+ return_ACPI_STATUS (AE_TYPE);
}
- if (op->opcode == AML_VAR_PACKAGE_OP) {
+ /* Perform per-object initialization */
+
+ switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ case ACPI_TYPE_BUFFER:
+
/*
- * Variable length package parameters are evaluated JIT
+ * Defer evaluation of Buffer term_arg operand
*/
- return_ACPI_STATUS (AE_OK);
- }
+ obj_desc->buffer.node = (struct acpi_namespace_node *) walk_state->operands[0];
+ obj_desc->buffer.aml_start = op->named.data;
+ obj_desc->buffer.aml_length = op->named.length;
+ break;
- /* The first argument must be the package length */
- arg = op->value.arg;
- obj_desc->package.count = arg->value.integer32;
+ case ACPI_TYPE_PACKAGE:
- /*
- * Allocate the array of pointers (ptrs to the
- * individual objects) Add an extra pointer slot so
- * that the list is always null terminated.
- */
- obj_desc->package.elements = ACPI_MEM_CALLOCATE (
- (obj_desc->package.count + 1) * sizeof (void *));
+ /*
+ * Defer evaluation of Package term_arg operand
+ */
+ obj_desc->package.node = (struct acpi_namespace_node *) walk_state->operands[0];
+ obj_desc->package.aml_start = op->named.data;
+ obj_desc->package.aml_length = op->named.length;
+ break;
- if (!obj_desc->package.elements) {
- acpi_ut_delete_object_desc (obj_desc);
- return_ACPI_STATUS (AE_NO_MEMORY);
- }
- obj_desc->package.next_element = obj_desc->package.elements;
+ case ACPI_TYPE_INTEGER:
- /*
- * Now init the elements of the package
- */
- arg = arg->next;
- while (arg) {
- if (arg->opcode == AML_PACKAGE_OP) {
- status = acpi_ds_build_internal_package_obj (walk_state, arg,
- obj_desc->package.next_element);
- }
+ switch (op_info->type) {
+ case AML_TYPE_CONSTANT:
+ /*
+ * Resolve AML Constants here - AND ONLY HERE!
+ * All constants are integers.
+ * We mark the integer with a flag that indicates that it started life
+ * as a constant -- so that stores to constants will perform as expected (noop).
+ * (zero_op is used as a placeholder for optional target operands.)
+ */
+ obj_desc->common.flags = AOPOBJ_AML_CONSTANT;
- else {
- status = acpi_ds_build_internal_simple_obj (walk_state, arg,
- obj_desc->package.next_element);
- }
+ switch (opcode) {
+ case AML_ZERO_OP:
- obj_desc->package.next_element++;
- arg = arg->next;
- }
+ obj_desc->integer.value = 0;
+ break;
- obj_desc->package.flags |= AOPOBJ_DATA_VALID;
- return_ACPI_STATUS (status);
-}
+ case AML_ONE_OP:
+ obj_desc->integer.value = 1;
+ break;
-/*****************************************************************************
- *
- * FUNCTION: Acpi_ds_build_internal_object
- *
- * PARAMETERS: Op - Parser object to be translated
- * Obj_desc_ptr - Where the ACPI internal object is returned
- *
- * RETURN: Status
- *
- * DESCRIPTION: Translate a parser Op object to the equivalent namespace
- * object
- *
- ****************************************************************************/
+ case AML_ONES_OP:
+
+ obj_desc->integer.value = ACPI_INTEGER_MAX;
+
+ /* Truncate value if we are executing from a 32-bit ACPI table */
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+ acpi_ex_truncate_for32bit_table (obj_desc);
+#endif
+ break;
+
+ case AML_REVISION_OP:
+
+ obj_desc->integer.value = ACPI_CA_SUPPORT_LEVEL;
+ break;
+
+ default:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown constant opcode %X\n", opcode));
+ status = AE_AML_OPERAND_TYPE;
+ break;
+ }
+ break;
-acpi_status
-acpi_ds_build_internal_object (
- acpi_walk_state *walk_state,
- acpi_parse_object *op,
- acpi_operand_object **obj_desc_ptr)
-{
- acpi_status status;
+ case AML_TYPE_LITERAL:
+
+ obj_desc->integer.value = op->common.value.integer;
+ break;
- switch (op->opcode) {
- case AML_PACKAGE_OP:
- case AML_VAR_PACKAGE_OP:
- status = acpi_ds_build_internal_package_obj (walk_state, op, obj_desc_ptr);
+ default:
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Integer type %X\n", op_info->type));
+ status = AE_AML_OPERAND_TYPE;
+ break;
+ }
break;
- default:
+ case ACPI_TYPE_STRING:
- status = acpi_ds_build_internal_simple_obj (walk_state, op, obj_desc_ptr);
+ obj_desc->string.pointer = op->common.value.string;
+ obj_desc->string.length = (u32) ACPI_STRLEN (op->common.value.string);
+
+ /*
+ * The string is contained in the ACPI table, don't ever try
+ * to delete it
+ */
+ obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
break;
- }
- return (status);
-}
+ case ACPI_TYPE_METHOD:
+ break;
-/*****************************************************************************
- *
- * FUNCTION: Acpi_ds_create_node
- *
- * PARAMETERS: Op - Parser object to be translated
- * Obj_desc_ptr - Where the ACPI internal object is returned
- *
- * RETURN: Status
- *
- * DESCRIPTION:
- *
- ****************************************************************************/
-acpi_status
-acpi_ds_create_node (
- acpi_walk_state *walk_state,
- acpi_namespace_node *node,
- acpi_parse_object *op)
-{
- acpi_status status;
- acpi_operand_object *obj_desc;
+ case ACPI_TYPE_LOCAL_REFERENCE:
+ switch (op_info->type) {
+ case AML_TYPE_LOCAL_VARIABLE:
- FUNCTION_TRACE_PTR ("Ds_create_node", op);
+ /* Split the opcode into a base opcode + offset */
+ obj_desc->reference.opcode = AML_LOCAL_OP;
+ obj_desc->reference.offset = opcode - AML_LOCAL_OP;
- /*
- * Because of the execution pass through the non-control-method
- * parts of the table, we can arrive here twice. Only init
- * the named object node the first time through
- */
- if (node->object) {
- return_ACPI_STATUS (AE_OK);
- }
+#ifndef ACPI_NO_METHOD_EXECUTION
+ status = acpi_ds_method_data_get_node (AML_LOCAL_OP, obj_desc->reference.offset,
+ walk_state, (struct acpi_namespace_node **) &obj_desc->reference.object);
+#endif
+ break;
- if (!op->value.arg) {
- /* No arguments, there is nothing to do */
- return_ACPI_STATUS (AE_OK);
- }
+ case AML_TYPE_METHOD_ARGUMENT:
- /* Build an internal object for the argument(s) */
+ /* Split the opcode into a base opcode + offset */
- status = acpi_ds_build_internal_object (walk_state, op->value.arg, &obj_desc);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
- }
+ obj_desc->reference.opcode = AML_ARG_OP;
+ obj_desc->reference.offset = opcode - AML_ARG_OP;
+ break;
- /* Re-type the object according to it's argument */
+ default: /* Other literals, etc.. */
- node->type = obj_desc->common.type;
+ if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
+ /* Node was saved in Op */
- /* Init obj */
+ obj_desc->reference.node = op->common.node;
+ }
- status = acpi_ns_attach_object (node, obj_desc, (u8) node->type);
+ obj_desc->reference.opcode = opcode;
+ break;
+ }
+ break;
- /* Remove local reference to the object */
- acpi_ut_remove_reference (obj_desc);
+ default:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unimplemented data type: %X\n",
+ ACPI_GET_OBJECT_TYPE (obj_desc)));
+
+ status = AE_AML_OPERAND_TYPE;
+ break;
+ }
+
return_ACPI_STATUS (status);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)