1 /******************************************************************************
3 * Module Name: dsobject - Dispatcher object management routines
6 *****************************************************************************/
9 * Copyright (C) 2000, 2001 R. Byron Moore
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #define _COMPONENT ACPI_DISPATCHER
35 MODULE_NAME ("dsobject")
38 /*******************************************************************************
40 * FUNCTION: Acpi_ds_init_one_object
42 * PARAMETERS: Obj_handle - Node
43 * Level - Current nesting level
44 * Context - Points to a init info struct
45 * Return_value - Not used
49 * DESCRIPTION: Callback from Acpi_walk_namespace. Invoked for every object
50 * within the namespace.
52 * Currently, the only objects that require initialization are:
56 ******************************************************************************/
59 acpi_ds_init_one_object (
60 acpi_handle obj_handle,
65 acpi_object_type8 type;
67 acpi_init_walk_info *info = (acpi_init_walk_info *) context;
71 PROC_NAME ("Ds_init_one_object");
75 table_revision = info->table_desc->pointer->revision;
78 * We are only interested in objects owned by the table that
81 if (((acpi_namespace_node *) obj_handle)->owner_id !=
82 info->table_desc->table_id) {
87 /* And even then, we are only interested in a few object types */
89 type = acpi_ns_get_type (obj_handle);
93 case ACPI_TYPE_REGION:
95 acpi_ds_initialize_region (obj_handle);
97 info->op_region_count++;
101 case ACPI_TYPE_METHOD:
103 info->method_count++;
105 if (!(acpi_dbg_level & ACPI_LV_INIT)) {
106 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "."));
110 * Set the execution data width (32 or 64) based upon the
111 * revision number of the parent ACPI table.
113 if (table_revision == 1) {
114 ((acpi_namespace_node *)obj_handle)->flags |= ANOBJ_DATA_WIDTH_32;
118 * Always parse methods to detect errors, we may delete
119 * the parse tree below
121 status = acpi_ds_parse_method (obj_handle);
122 if (ACPI_FAILURE (status)) {
123 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Method %p [%4.4s] - parse failure, %s\n",
124 obj_handle, (char*)&((acpi_namespace_node *)obj_handle)->name,
125 acpi_format_exception (status)));
127 /* This parse failed, but we will continue parsing more methods */
133 * Delete the parse tree. We simple re-parse the method
134 * for every execution since there isn't much overhead
136 acpi_ns_delete_namespace_subtree (obj_handle);
144 * We ignore errors from above, and always return OK, since
145 * we don't want to abort the walk on a single error.
151 /*******************************************************************************
153 * FUNCTION: Acpi_ds_initialize_objects
159 * DESCRIPTION: Walk the entire namespace and perform any necessary
160 * initialization on the objects found therein
162 ******************************************************************************/
165 acpi_ds_initialize_objects (
166 acpi_table_desc *table_desc,
167 acpi_namespace_node *start_node)
170 acpi_init_walk_info info;
173 FUNCTION_TRACE ("Ds_initialize_objects");
176 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
177 "**** Starting initialization of namespace objects ****\n"));
178 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "Parsing Methods:"));
181 info.method_count = 0;
182 info.op_region_count = 0;
183 info.object_count = 0;
184 info.table_desc = table_desc;
187 /* Walk entire namespace from the supplied root */
189 status = acpi_walk_namespace (ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
190 acpi_ds_init_one_object, &info, NULL);
191 if (ACPI_FAILURE (status)) {
192 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Walk_namespace failed! %x\n", status));
195 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK,
196 "\n%d Control Methods found and parsed (%d nodes total)\n",
197 info.method_count, info.object_count));
198 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
199 "%d Control Methods found\n", info.method_count));
200 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
201 "%d Op Regions found\n", info.op_region_count));
203 return_ACPI_STATUS (AE_OK);
207 /*****************************************************************************
209 * FUNCTION: Acpi_ds_init_object_from_op
211 * PARAMETERS: Op - Parser op used to init the internal object
212 * Opcode - AML opcode associated with the object
213 * Obj_desc - Namespace object to be initialized
217 * DESCRIPTION: Initialize a namespace object from a parser Op and its
218 * associated arguments. The namespace object is a more compact
219 * representation of the Op and its arguments.
221 ****************************************************************************/
224 acpi_ds_init_object_from_op (
225 acpi_walk_state *walk_state,
226 acpi_parse_object *op,
228 acpi_operand_object **ret_obj_desc)
231 acpi_parse_object *arg;
232 acpi_parse2_object *byte_list;
233 acpi_operand_object *arg_desc;
234 const acpi_opcode_info *op_info;
235 acpi_operand_object *obj_desc;
238 PROC_NAME ("Ds_init_object_from_op");
241 obj_desc = *ret_obj_desc;
242 op_info = acpi_ps_get_opcode_info (opcode);
243 if (op_info->class == AML_CLASS_UNKNOWN) {
250 /* Get and prepare the first argument */
252 switch (obj_desc->common.type) {
253 case ACPI_TYPE_BUFFER:
255 /* First arg is a number */
257 acpi_ds_create_operand (walk_state, op->value.arg, 0);
258 arg_desc = walk_state->operands [walk_state->num_operands - 1];
259 acpi_ds_obj_stack_pop (1, walk_state);
261 /* Resolve the object (could be an arg or local) */
263 status = acpi_ex_resolve_to_value (&arg_desc, walk_state);
264 if (ACPI_FAILURE (status)) {
265 acpi_ut_remove_reference (arg_desc);
269 /* We are expecting a number */
271 if (arg_desc->common.type != ACPI_TYPE_INTEGER) {
272 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
273 "Expecting number, got obj: %p type %X\n",
274 arg_desc, arg_desc->common.type));
275 acpi_ut_remove_reference (arg_desc);
279 /* Get the value, delete the internal object */
281 obj_desc->buffer.length = (u32) arg_desc->integer.value;
282 acpi_ut_remove_reference (arg_desc);
284 /* Allocate the buffer */
286 if (obj_desc->buffer.length == 0) {
287 obj_desc->buffer.pointer = NULL;
288 REPORT_WARNING (("Buffer created with zero length in AML\n"));
293 obj_desc->buffer.pointer = ACPI_MEM_CALLOCATE (
294 obj_desc->buffer.length);
296 if (!obj_desc->buffer.pointer) {
297 return (AE_NO_MEMORY);
302 * Second arg is the buffer data (optional) Byte_list can be either
303 * individual bytes or a string initializer.
305 arg = op->value.arg; /* skip first arg */
307 byte_list = (acpi_parse2_object *) arg->next;
309 if (byte_list->opcode != AML_INT_BYTELIST_OP) {
310 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Expecting bytelist, got: %p\n",
315 MEMCPY (obj_desc->buffer.pointer, byte_list->data,
316 obj_desc->buffer.length);
322 case ACPI_TYPE_PACKAGE:
325 * When called, an internal package object has already been built and
326 * is pointed to by Obj_desc. Acpi_ds_build_internal_object builds another
327 * internal package object, so remove reference to the original so
328 * that it is deleted. Error checking is done within the remove
329 * reference function.
331 acpi_ut_remove_reference (obj_desc);
332 status = acpi_ds_build_internal_object (walk_state, op, ret_obj_desc);
335 case ACPI_TYPE_INTEGER:
336 obj_desc->integer.value = op->value.integer;
340 case ACPI_TYPE_STRING:
341 obj_desc->string.pointer = op->value.string;
342 obj_desc->string.length = STRLEN (op->value.string);
345 * The string is contained in the ACPI table, don't ever try
348 obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
352 case ACPI_TYPE_METHOD:
356 case INTERNAL_TYPE_REFERENCE:
358 switch (op_info->type) {
359 case AML_TYPE_LOCAL_VARIABLE:
361 /* Split the opcode into a base opcode + offset */
363 obj_desc->reference.opcode = AML_LOCAL_OP;
364 obj_desc->reference.offset = opcode - AML_LOCAL_OP;
368 case AML_TYPE_METHOD_ARGUMENT:
370 /* Split the opcode into a base opcode + offset */
372 obj_desc->reference.opcode = AML_ARG_OP;
373 obj_desc->reference.offset = opcode - AML_ARG_OP;
377 default: /* Constants, Literals, etc.. */
379 if (op->opcode == AML_INT_NAMEPATH_OP) {
380 /* Node was saved in Op */
382 obj_desc->reference.node = op->node;
385 obj_desc->reference.opcode = opcode;
394 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unimplemented data type: %x\n",
395 obj_desc->common.type));
404 /*****************************************************************************
406 * FUNCTION: Acpi_ds_build_internal_simple_obj
408 * PARAMETERS: Op - Parser object to be translated
409 * Obj_desc_ptr - Where the ACPI internal object is returned
413 * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
414 * Simple objects are any objects other than a package object!
416 ****************************************************************************/
419 acpi_ds_build_internal_simple_obj (
420 acpi_walk_state *walk_state,
421 acpi_parse_object *op,
422 acpi_operand_object **obj_desc_ptr)
424 acpi_operand_object *obj_desc;
425 acpi_object_type8 type;
431 FUNCTION_TRACE ("Ds_build_internal_simple_obj");
434 if (op->opcode == AML_INT_NAMEPATH_OP) {
436 * This is an object reference. If The name was
437 * previously looked up in the NS, it is stored in this op.
438 * Otherwise, go ahead and look it up now
441 status = acpi_ns_lookup (walk_state->scope_info,
442 op->value.string, ACPI_TYPE_ANY,
444 NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE,
446 (acpi_namespace_node **)&(op->node));
448 if (ACPI_FAILURE (status)) {
449 if (status == AE_NOT_FOUND) {
451 acpi_ns_externalize_name (ACPI_UINT32_MAX, op->value.string, &length, &name);
454 REPORT_WARNING (("Reference %s at AML %X not found\n",
455 name, op->aml_offset));
456 ACPI_MEM_FREE (name);
460 REPORT_WARNING (("Reference %s at AML %X not found\n",
461 op->value.string, op->aml_offset));
464 *obj_desc_ptr = NULL;
468 return_ACPI_STATUS (status);
474 * The reference will be a Reference
475 * TBD: [Restructure] unless we really need a separate
476 * type of INTERNAL_TYPE_REFERENCE change
477 * Acpi_ds_map_opcode_to_data_type to handle this case
479 type = INTERNAL_TYPE_REFERENCE;
482 type = acpi_ds_map_opcode_to_data_type (op->opcode, NULL);
486 /* Create and init the internal ACPI object */
488 obj_desc = acpi_ut_create_internal_object (type);
490 return_ACPI_STATUS (AE_NO_MEMORY);
493 status = acpi_ds_init_object_from_op (walk_state, op, op->opcode, &obj_desc);
494 if (ACPI_FAILURE (status)) {
495 acpi_ut_remove_reference (obj_desc);
496 return_ACPI_STATUS (status);
499 *obj_desc_ptr = obj_desc;
501 return_ACPI_STATUS (AE_OK);
505 /*****************************************************************************
507 * FUNCTION: Acpi_ds_build_internal_package_obj
509 * PARAMETERS: Op - Parser object to be translated
510 * Obj_desc_ptr - Where the ACPI internal object is returned
514 * DESCRIPTION: Translate a parser Op package object to the equivalent
517 ****************************************************************************/
520 acpi_ds_build_internal_package_obj (
521 acpi_walk_state *walk_state,
522 acpi_parse_object *op,
523 acpi_operand_object **obj_desc_ptr)
525 acpi_parse_object *arg;
526 acpi_operand_object *obj_desc;
527 acpi_status status = AE_OK;
530 FUNCTION_TRACE ("Ds_build_internal_package_obj");
533 obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE);
534 *obj_desc_ptr = obj_desc;
536 return_ACPI_STATUS (AE_NO_MEMORY);
539 if (op->opcode == AML_VAR_PACKAGE_OP) {
541 * Variable length package parameters are evaluated JIT
543 return_ACPI_STATUS (AE_OK);
546 /* The first argument must be the package length */
549 obj_desc->package.count = arg->value.integer32;
552 * Allocate the array of pointers (ptrs to the
553 * individual objects) Add an extra pointer slot so
554 * that the list is always null terminated.
556 obj_desc->package.elements = ACPI_MEM_CALLOCATE (
557 (obj_desc->package.count + 1) * sizeof (void *));
559 if (!obj_desc->package.elements) {
560 acpi_ut_delete_object_desc (obj_desc);
561 return_ACPI_STATUS (AE_NO_MEMORY);
564 obj_desc->package.next_element = obj_desc->package.elements;
567 * Now init the elements of the package
571 if (arg->opcode == AML_PACKAGE_OP) {
572 status = acpi_ds_build_internal_package_obj (walk_state, arg,
573 obj_desc->package.next_element);
577 status = acpi_ds_build_internal_simple_obj (walk_state, arg,
578 obj_desc->package.next_element);
581 obj_desc->package.next_element++;
585 obj_desc->package.flags |= AOPOBJ_DATA_VALID;
586 return_ACPI_STATUS (status);
590 /*****************************************************************************
592 * FUNCTION: Acpi_ds_build_internal_object
594 * PARAMETERS: Op - Parser object to be translated
595 * Obj_desc_ptr - Where the ACPI internal object is returned
599 * DESCRIPTION: Translate a parser Op object to the equivalent namespace
602 ****************************************************************************/
605 acpi_ds_build_internal_object (
606 acpi_walk_state *walk_state,
607 acpi_parse_object *op,
608 acpi_operand_object **obj_desc_ptr)
613 switch (op->opcode) {
615 case AML_VAR_PACKAGE_OP:
617 status = acpi_ds_build_internal_package_obj (walk_state, op, obj_desc_ptr);
623 status = acpi_ds_build_internal_simple_obj (walk_state, op, obj_desc_ptr);
631 /*****************************************************************************
633 * FUNCTION: Acpi_ds_create_node
635 * PARAMETERS: Op - Parser object to be translated
636 * Obj_desc_ptr - Where the ACPI internal object is returned
642 ****************************************************************************/
645 acpi_ds_create_node (
646 acpi_walk_state *walk_state,
647 acpi_namespace_node *node,
648 acpi_parse_object *op)
651 acpi_operand_object *obj_desc;
654 FUNCTION_TRACE_PTR ("Ds_create_node", op);
658 * Because of the execution pass through the non-control-method
659 * parts of the table, we can arrive here twice. Only init
660 * the named object node the first time through
663 return_ACPI_STATUS (AE_OK);
666 if (!op->value.arg) {
667 /* No arguments, there is nothing to do */
669 return_ACPI_STATUS (AE_OK);
672 /* Build an internal object for the argument(s) */
674 status = acpi_ds_build_internal_object (walk_state, op->value.arg, &obj_desc);
675 if (ACPI_FAILURE (status)) {
676 return_ACPI_STATUS (status);
679 /* Re-type the object according to it's argument */
681 node->type = obj_desc->common.type;
685 status = acpi_ns_attach_object (node, obj_desc, (u8) node->type);
687 /* Remove local reference to the object */
689 acpi_ut_remove_reference (obj_desc);
690 return_ACPI_STATUS (status);