1 /******************************************************************************
3 * Module Name: dswload - Dispatcher namespace load callbacks
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
36 #define _COMPONENT ACPI_DISPATCHER
37 MODULE_NAME ("dswload")
40 /*******************************************************************************
42 * FUNCTION: Acpi_ds_init_callbacks
44 * PARAMETERS: Walk_state - Current state of the parse tree walk
45 * Pass_number - 1, 2, or 3
49 * DESCRIPTION: Init walk state callbacks
51 ******************************************************************************/
54 acpi_ds_init_callbacks (
55 acpi_walk_state *walk_state,
59 switch (pass_number) {
61 walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE;
62 walk_state->descending_callback = acpi_ds_load1_begin_op;
63 walk_state->ascending_callback = acpi_ds_load1_end_op;
67 walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE;
68 walk_state->descending_callback = acpi_ds_load2_begin_op;
69 walk_state->ascending_callback = acpi_ds_load2_end_op;
73 walk_state->parse_flags |= ACPI_PARSE_EXECUTE | ACPI_PARSE_DELETE_TREE;
74 walk_state->descending_callback = acpi_ds_exec_begin_op;
75 walk_state->ascending_callback = acpi_ds_exec_end_op;
79 return (AE_BAD_PARAMETER);
87 /*******************************************************************************
89 * FUNCTION: Acpi_ds_load1_begin_op
91 * PARAMETERS: Walk_state - Current state of the parse tree walk
92 * Op - Op that has been just been reached in the
93 * walk; Arguments have not been evaluated yet.
97 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
99 ******************************************************************************/
102 acpi_ds_load1_begin_op (
103 acpi_walk_state *walk_state,
104 acpi_parse_object **out_op)
106 acpi_parse_object *op;
107 acpi_namespace_node *node;
109 acpi_object_type8 data_type;
113 PROC_NAME ("Ds_load1_begin_op");
116 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
119 /* We are only interested in opcodes that have an associated name */
121 if (walk_state->op) {
122 if (!(walk_state->op_info->flags & AML_NAMED)) {
127 /* Check if this object has already been installed in the namespace */
135 path = acpi_ps_get_next_namestring (&walk_state->parser_state);
137 /* Map the raw opcode into an internal object type */
139 data_type = acpi_ds_map_named_opcode_to_data_type (walk_state->opcode);
142 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
143 "State=%p Op=%p Type=%x\n", walk_state, op, data_type));
146 if (walk_state->opcode == AML_SCOPE_OP) {
147 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
148 "State=%p Op=%p Type=%x\n", walk_state, op, data_type));
152 * Enter the named type into the internal namespace. We enter the name
153 * as we go downward in the parse tree. Any necessary subobjects that involve
154 * arguments to the opcode must be created as we go back up the parse tree later.
156 status = acpi_ns_lookup (walk_state->scope_info, path, data_type,
157 IMODE_LOAD_PASS1, NS_NO_UPSEARCH, walk_state, &(node));
159 if (ACPI_FAILURE (status)) {
164 /* Create a new op */
166 op = acpi_ps_alloc_op (walk_state->opcode);
168 return (AE_NO_MEMORY);
174 ((acpi_parse2_object *)op)->name = node->name;
177 * Put the Node in the "op" object that the parser uses, so we
178 * can get it again quickly when this scope is closed
181 acpi_ps_append_arg (acpi_ps_get_parent_scope (&walk_state->parser_state), op);
188 /*******************************************************************************
190 * FUNCTION: Acpi_ds_load1_end_op
192 * PARAMETERS: Walk_state - Current state of the parse tree walk
193 * Op - Op that has been just been completed in the
194 * walk; Arguments have now been evaluated.
198 * DESCRIPTION: Ascending callback used during the loading of the namespace,
199 * both control methods and everything else.
201 ******************************************************************************/
204 acpi_ds_load1_end_op (
205 acpi_walk_state *walk_state)
207 acpi_parse_object *op;
208 acpi_object_type8 data_type;
211 PROC_NAME ("Ds_load1_end_op");
214 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
217 /* We are only interested in opcodes that have an associated name */
219 if (!(walk_state->op_info->flags & AML_NAMED)) {
223 /* Get the type to determine if we should pop the scope */
225 data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode);
227 if (op->opcode == AML_NAME_OP) {
228 /* For Name opcode, check the argument */
231 data_type = acpi_ds_map_opcode_to_data_type (
232 (op->value.arg)->opcode, NULL);
233 ((acpi_namespace_node *)op->node)->type =
238 /* Pop the scope stack */
240 if (acpi_ns_opens_scope (data_type)) {
241 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s): Popping scope for Op %p\n",
242 acpi_ut_get_type_name (data_type), op));
244 acpi_ds_scope_stack_pop (walk_state);
251 /*******************************************************************************
253 * FUNCTION: Acpi_ds_load2_begin_op
255 * PARAMETERS: Walk_state - Current state of the parse tree walk
256 * Op - Op that has been just been reached in the
257 * walk; Arguments have not been evaluated yet.
261 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
263 ******************************************************************************/
266 acpi_ds_load2_begin_op (
267 acpi_walk_state *walk_state,
268 acpi_parse_object **out_op)
270 acpi_parse_object *op;
271 acpi_namespace_node *node;
273 acpi_object_type8 data_type;
274 NATIVE_CHAR *buffer_ptr;
275 void *original = NULL;
278 PROC_NAME ("Ds_load2_begin_op");
281 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
285 /* We only care about Namespace opcodes here */
287 if (!(walk_state->op_info->flags & AML_NSOPCODE) &&
288 walk_state->opcode != AML_INT_NAMEPATH_OP) {
292 /* TBD: [Restructure] Temp! same code as in psparse */
294 if (!(walk_state->op_info->flags & AML_NAMED)) {
299 * Get the name we are going to enter or lookup in the namespace
301 if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
302 /* For Namepath op, get the path string */
304 buffer_ptr = op->value.string;
306 /* No name, just exit */
312 /* Get name from the op */
314 buffer_ptr = (NATIVE_CHAR *) &((acpi_parse2_object *)op)->name;
318 buffer_ptr = acpi_ps_get_next_namestring (&walk_state->parser_state);
322 /* Map the raw opcode into an internal object type */
324 data_type = acpi_ds_map_named_opcode_to_data_type (walk_state->opcode);
326 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
327 "State=%p Op=%p Type=%x\n", walk_state, op, data_type));
330 if (walk_state->opcode == AML_FIELD_OP ||
331 walk_state->opcode == AML_BANK_FIELD_OP ||
332 walk_state->opcode == AML_INDEX_FIELD_OP) {
337 else if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
339 * The Name_path is an object reference to an existing object. Don't enter the
340 * name into the namespace, but look it up for use later
342 status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, data_type,
343 IMODE_EXECUTE, NS_SEARCH_PARENT, walk_state, &(node));
347 if (op && op->node) {
351 if (acpi_ns_opens_scope (data_type)) {
352 status = acpi_ds_scope_stack_push (node, data_type, walk_state);
353 if (ACPI_FAILURE (status)) {
362 * Enter the named type into the internal namespace. We enter the name
363 * as we go downward in the parse tree. Any necessary subobjects that involve
364 * arguments to the opcode must be created as we go back up the parse tree later.
366 status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, data_type,
367 IMODE_EXECUTE, NS_NO_UPSEARCH, walk_state, &(node));
370 if (ACPI_SUCCESS (status)) {
372 /* Create a new op */
374 op = acpi_ps_alloc_op (walk_state->opcode);
376 return (AE_NO_MEMORY);
381 ((acpi_parse2_object *)op)->name = node->name;
386 * Put the Node in the "op" object that the parser uses, so we
387 * can get it again quickly when this scope is closed
392 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "old %p new %p\n", original, node));
394 if (original != node) {
395 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
396 "Lookup match error: old %p new %p\n", original, node));
405 /*******************************************************************************
407 * FUNCTION: Acpi_ds_load2_end_op
409 * PARAMETERS: Walk_state - Current state of the parse tree walk
410 * Op - Op that has been just been completed in the
411 * walk; Arguments have now been evaluated.
415 * DESCRIPTION: Ascending callback used during the loading of the namespace,
416 * both control methods and everything else.
418 ******************************************************************************/
421 acpi_ds_load2_end_op (
422 acpi_walk_state *walk_state)
424 acpi_parse_object *op;
425 acpi_status status = AE_OK;
426 acpi_object_type8 data_type;
427 acpi_namespace_node *node;
428 acpi_parse_object *arg;
429 acpi_namespace_node *new_node;
433 PROC_NAME ("Ds_load2_end_op");
436 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
439 /* Only interested in opcodes that have namespace objects */
441 if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
445 if (op->opcode == AML_SCOPE_OP) {
446 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
447 "Ending scope Op=%p State=%p\n", op, walk_state));
449 if (((acpi_parse2_object *)op)->name == -1) {
450 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unnamed scope! Op=%p State=%p\n",
457 data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode);
460 * Get the Node/name from the earlier lookup
461 * (It was saved in the *op structure)
466 * Put the Node on the object stack (Contains the ACPI Name of
469 walk_state->operands[0] = (void *) node;
470 walk_state->num_operands = 1;
472 /* Pop the scope stack */
474 if (acpi_ns_opens_scope (data_type)) {
476 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
477 acpi_ut_get_type_name (data_type), op));
478 acpi_ds_scope_stack_pop (walk_state);
482 * Named operations are as follows:
487 * AML_CREATEBYTEFIELD
488 * AML_CREATEDWORDFIELD
490 * AML_CREATEQWORDFIELD
491 * AML_CREATEWORDFIELD
509 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
510 "Create-Load [%s] State=%p Op=%p Named_obj=%p\n",
511 acpi_ps_get_opcode_name (op->opcode), walk_state, op, node));
513 /* Decode the opcode */
517 switch (walk_state->op_info->type) {
518 case AML_TYPE_CREATE_FIELD:
521 * Create the field object, but the field buffer and index must
522 * be evaluated later during the execution phase
524 status = acpi_ds_create_buffer_field (op, walk_state);
528 case AML_TYPE_NAMED_FIELD:
531 switch (op->opcode) {
532 case AML_INDEX_FIELD_OP:
534 status = acpi_ds_create_index_field (op, (acpi_handle) arg->node,
539 case AML_BANK_FIELD_OP:
541 status = acpi_ds_create_bank_field (op, arg->node, walk_state);
547 status = acpi_ds_create_field (op, arg->node, walk_state);
553 case AML_TYPE_NAMED_SIMPLE:
555 status = acpi_ds_create_operands (walk_state, arg);
556 if (ACPI_FAILURE (status)) {
560 switch (op->opcode) {
561 case AML_PROCESSOR_OP:
563 status = acpi_ex_create_processor (walk_state);
567 case AML_POWER_RES_OP:
569 status = acpi_ex_create_power_resource (walk_state);
575 status = acpi_ex_create_mutex (walk_state);
581 status = acpi_ex_create_event (walk_state);
585 case AML_DATA_REGION_OP:
587 status = acpi_ex_create_table_region (walk_state);
592 status = acpi_ex_create_alias (walk_state);
603 /* Delete operands */
605 for (i = 1; i < walk_state->num_operands; i++) {
606 acpi_ut_remove_reference (walk_state->operands[i]);
607 walk_state->operands[i] = NULL;
613 case AML_TYPE_NAMED_COMPLEX:
615 switch (op->opcode) {
618 * Method_op Pkg_length Names_string Method_flags Term_list
620 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
621 "LOADING-Method: State=%p Op=%p Named_obj=%p\n",
622 walk_state, op, node));
625 status = acpi_ds_create_operands (walk_state, arg);
626 if (ACPI_FAILURE (status)) {
630 status = acpi_ex_create_method (((acpi_parse2_object *) op)->data,
631 ((acpi_parse2_object *) op)->length,
639 * The Op_region is not fully parsed at this time. Only valid argument is the Space_id.
640 * (We must save the address of the AML of the address and length operands)
642 status = acpi_ex_create_region (((acpi_parse2_object *) op)->data,
643 ((acpi_parse2_object *) op)->length,
644 (ACPI_ADR_SPACE_TYPE) arg->value.integer, walk_state);
650 status = acpi_ds_create_node (walk_state, node, op);
656 case AML_CLASS_INTERNAL:
658 /* case AML_INT_NAMEPATH_OP: */
662 case AML_CLASS_METHOD_CALL:
664 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
665 "RESOLVING-Method_call: State=%p Op=%p Named_obj=%p\n",
666 walk_state, op, node));
669 * Lookup the method name and save the Node
671 status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,
672 ACPI_TYPE_ANY, IMODE_LOAD_PASS2,
673 NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE,
674 walk_state, &(new_node));
675 if (ACPI_SUCCESS (status)) {
676 /* TBD: has name already been resolved by here ??*/
678 /* TBD: [Restructure] Make sure that what we found is indeed a method! */
679 /* We didn't search for a method on purpose, to see if the name would resolve! */
681 /* We could put the returned object (Node) on the object stack for later, but
682 * for now, we will put it in the "op" object that the parser uses, so we
683 * can get it again at the end of this scope
698 /* Remove the Node pushed at the very beginning */
700 walk_state->operands[0] = NULL;
701 walk_state->num_operands = 0;