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_load1_begin_op
44 * PARAMETERS: Walk_state - Current state of the parse tree walk
45 * Op - Op that has been just been reached in the
46 * walk; Arguments have not been evaluated yet.
50 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
52 ******************************************************************************/
55 acpi_ds_load1_begin_op (
57 ACPI_PARSE_OBJECT *op,
58 ACPI_WALK_STATE *walk_state,
59 ACPI_PARSE_OBJECT **out_op)
61 ACPI_NAMESPACE_NODE *node;
63 OBJECT_TYPE_INTERNAL data_type;
67 /* We are only interested in opcodes that have an associated name */
69 if (!acpi_ps_is_named_op (opcode)) {
75 /* Check if this object has already been installed in the namespace */
82 path = acpi_ps_get_next_namestring (walk_state->parser_state);
84 /* Map the raw opcode into an internal object type */
86 data_type = acpi_ds_map_named_opcode_to_data_type (opcode);
91 * Enter the named type into the internal namespace. We enter the name
92 * as we go downward in the parse tree. Any necessary subobjects that involve
93 * arguments to the opcode must be created as we go back up the parse tree later.
95 status = acpi_ns_lookup (walk_state->scope_info, path,
96 data_type, IMODE_LOAD_PASS1,
97 NS_NO_UPSEARCH, walk_state, &(node));
99 if (ACPI_FAILURE (status)) {
104 /* Create a new op */
106 op = acpi_ps_alloc_op (opcode);
108 return (AE_NO_MEMORY);
114 ((ACPI_PARSE2_OBJECT *)op)->name = node->name;
117 * Put the Node in the "op" object that the parser uses, so we
118 * can get it again quickly when this scope is closed
123 acpi_ps_append_arg (acpi_ps_get_parent_scope (walk_state->parser_state), op);
131 /*******************************************************************************
133 * FUNCTION: Acpi_ds_load1_end_op
135 * PARAMETERS: Walk_state - Current state of the parse tree walk
136 * Op - Op that has been just been completed in the
137 * walk; Arguments have now been evaluated.
141 * DESCRIPTION: Ascending callback used during the loading of the namespace,
142 * both control methods and everything else.
144 ******************************************************************************/
147 acpi_ds_load1_end_op (
148 ACPI_WALK_STATE *walk_state,
149 ACPI_PARSE_OBJECT *op)
151 OBJECT_TYPE_INTERNAL data_type;
154 /* We are only interested in opcodes that have an associated name */
156 if (!acpi_ps_is_named_op (op->opcode)) {
161 /* Get the type to determine if we should pop the scope */
163 data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode);
165 if (op->opcode == AML_NAME_OP) {
166 /* For Name opcode, check the argument */
169 data_type = acpi_ds_map_opcode_to_data_type (
170 (op->value.arg)->opcode, NULL);
171 ((ACPI_NAMESPACE_NODE *)op->node)->type =
177 /* Pop the scope stack */
179 if (acpi_ns_opens_scope (data_type)) {
181 acpi_ds_scope_stack_pop (walk_state);
189 /*******************************************************************************
191 * FUNCTION: Acpi_ds_load2_begin_op
193 * PARAMETERS: Walk_state - Current state of the parse tree walk
194 * Op - Op that has been just been reached in the
195 * walk; Arguments have not been evaluated yet.
199 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
201 ******************************************************************************/
204 acpi_ds_load2_begin_op (
206 ACPI_PARSE_OBJECT *op,
207 ACPI_WALK_STATE *walk_state,
208 ACPI_PARSE_OBJECT **out_op)
210 ACPI_NAMESPACE_NODE *node;
212 OBJECT_TYPE_INTERNAL data_type;
213 NATIVE_CHAR *buffer_ptr;
214 void *original = NULL;
217 /* We only care about Namespace opcodes here */
219 if (!acpi_ps_is_namespace_op (opcode) &&
220 opcode != AML_NAMEPATH_OP) {
225 /* Temp! same code as in psparse */
227 if (!acpi_ps_is_named_op (opcode)) {
233 * Get the name we are going to enter or lookup in the namespace
235 if (opcode == AML_NAMEPATH_OP) {
236 /* For Namepath op, get the path string */
238 buffer_ptr = op->value.string;
240 /* No name, just exit */
247 /* Get name from the op */
249 buffer_ptr = (NATIVE_CHAR *) &((ACPI_PARSE2_OBJECT *)op)->name;
254 buffer_ptr = acpi_ps_get_next_namestring (walk_state->parser_state);
258 /* Map the raw opcode into an internal object type */
260 data_type = acpi_ds_map_named_opcode_to_data_type (opcode);
263 if (opcode == AML_DEF_FIELD_OP ||
264 opcode == AML_BANK_FIELD_OP ||
265 opcode == AML_INDEX_FIELD_OP) {
270 else if (opcode == AML_NAMEPATH_OP) {
272 * The Name_path is an object reference to an existing object. Don't enter the
273 * name into the namespace, but look it up for use later
275 status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr,
276 data_type, IMODE_EXECUTE,
277 NS_SEARCH_PARENT, walk_state,
282 if (op && op->node) {
286 if (acpi_ns_opens_scope (data_type)) {
287 status = acpi_ds_scope_stack_push (node,
290 if (ACPI_FAILURE (status)) {
299 * Enter the named type into the internal namespace. We enter the name
300 * as we go downward in the parse tree. Any necessary subobjects that involve
301 * arguments to the opcode must be created as we go back up the parse tree later.
303 status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr,
304 data_type, IMODE_EXECUTE,
305 NS_NO_UPSEARCH, walk_state,
309 if (ACPI_SUCCESS (status)) {
311 /* Create a new op */
313 op = acpi_ps_alloc_op (opcode);
315 return (AE_NO_MEMORY);
320 ((ACPI_PARSE2_OBJECT *)op)->name = node->name;
326 * Put the Node in the "op" object that the parser uses, so we
327 * can get it again quickly when this scope is closed
338 /*******************************************************************************
340 * FUNCTION: Acpi_ds_load2_end_op
342 * PARAMETERS: Walk_state - Current state of the parse tree walk
343 * Op - Op that has been just been completed in the
344 * walk; Arguments have now been evaluated.
348 * DESCRIPTION: Ascending callback used during the loading of the namespace,
349 * both control methods and everything else.
351 ******************************************************************************/
354 acpi_ds_load2_end_op (
355 ACPI_WALK_STATE *walk_state,
356 ACPI_PARSE_OBJECT *op)
358 ACPI_STATUS status = AE_OK;
359 OBJECT_TYPE_INTERNAL data_type;
360 ACPI_NAMESPACE_NODE *node;
361 ACPI_PARSE_OBJECT *arg;
362 ACPI_NAMESPACE_NODE *new_node;
365 if (!acpi_ps_is_namespace_object_op (op->opcode)) {
369 if (op->opcode == AML_SCOPE_OP) {
370 if (((ACPI_PARSE2_OBJECT *)op)->name == -1) {
376 data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode);
379 * Get the Node/name from the earlier lookup
380 * (It was saved in the *op structure)
385 * Put the Node on the object stack (Contains the ACPI Name of
389 walk_state->operands[0] = (void *) node;
390 walk_state->num_operands = 1;
392 /* Pop the scope stack */
394 if (acpi_ns_opens_scope (data_type)) {
396 acpi_ds_scope_stack_pop (walk_state);
401 * Named operations are as follows:
420 * AML_CREATEBYTEFIELD
421 * AML_CREATEWORDFIELD
422 * AML_CREATEDWORDFIELD
427 /* Decode the opcode */
431 switch (op->opcode) {
433 case AML_CREATE_FIELD_OP:
434 case AML_BIT_FIELD_OP:
435 case AML_BYTE_FIELD_OP:
436 case AML_WORD_FIELD_OP:
437 case AML_DWORD_FIELD_OP:
440 * Create the field object, but the field buffer and index must
441 * be evaluated later during the execution phase
444 /* Get the Name_string argument */
446 if (op->opcode == AML_CREATE_FIELD_OP) {
447 arg = acpi_ps_get_arg (op, 3);
450 /* Create Bit/Byte/Word/Dword field */
452 arg = acpi_ps_get_arg (op, 2);
456 * Enter the Name_string into the namespace
459 status = acpi_ns_lookup (walk_state->scope_info,
461 INTERNAL_TYPE_DEF_ANY,
463 NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
464 walk_state, &(new_node));
466 if (ACPI_SUCCESS (status)) {
467 /* We could put the returned object (Node) on the object stack for later, but
468 * for now, we will put it in the "op" object that the parser uses, so we
469 * can get it again at the end of this scope
474 * If there is no object attached to the node, this node was just created and
475 * we need to create the field object. Otherwise, this was a lookup of an
476 * existing node and we don't want to create the field object again.
478 if (!new_node->object) {
480 * The Field definition is not fully parsed at this time.
481 * (We must save the address of the AML for the buffer and index operands)
483 status = acpi_aml_exec_create_field (((ACPI_PARSE2_OBJECT *) op)->data,
484 ((ACPI_PARSE2_OBJECT *) op)->length,
485 new_node, walk_state);
493 case AML_METHODCALL_OP:
496 * Lookup the method name and save the Node
499 status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,
500 ACPI_TYPE_ANY, IMODE_LOAD_PASS2,
501 NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE,
502 walk_state, &(new_node));
504 if (ACPI_SUCCESS (status)) {
506 /* has name already been resolved by here ??*/
508 /* TBD: [Restructure] Make sure that what we found is indeed a method! */
509 /* We didn't search for a method on purpose, to see if the name would resolve! */
511 /* We could put the returned object (Node) on the object stack for later, but
512 * for now, we will put it in the "op" object that the parser uses, so we
513 * can get it again at the end of this scope
522 case AML_PROCESSOR_OP:
524 /* Nothing to do other than enter object into namespace */
526 status = acpi_aml_exec_create_processor (op, (ACPI_HANDLE) node);
527 if (ACPI_FAILURE (status)) {
534 case AML_POWER_RES_OP:
536 /* Nothing to do other than enter object into namespace */
538 status = acpi_aml_exec_create_power_resource (op, (ACPI_HANDLE) node);
539 if (ACPI_FAILURE (status)) {
546 case AML_THERMAL_ZONE_OP:
548 /* Nothing to do other than enter object into namespace */
553 case AML_DEF_FIELD_OP:
557 status = acpi_ds_create_field (op, arg->node, walk_state);
561 case AML_INDEX_FIELD_OP:
565 status = acpi_ds_create_index_field (op, (ACPI_HANDLE) arg->node,
570 case AML_BANK_FIELD_OP:
573 status = acpi_ds_create_bank_field (op, arg->node, walk_state);
578 * Method_op Pkg_length Names_string Method_flags Term_list
583 status = acpi_aml_exec_create_method (((ACPI_PARSE2_OBJECT *) op)->data,
584 ((ACPI_PARSE2_OBJECT *) op)->length,
585 arg->value.integer, (ACPI_HANDLE) node);
593 status = acpi_ds_create_operands (walk_state, arg);
594 if (ACPI_FAILURE (status)) {
598 status = acpi_aml_exec_create_mutex (walk_state);
604 status = acpi_ds_create_operands (walk_state, arg);
605 if (ACPI_FAILURE (status)) {
609 status = acpi_aml_exec_create_event (walk_state);
621 * The Op_region is not fully parsed at this time. Only valid argument is the Space_id.
622 * (We must save the address of the AML of the address and length operands)
625 status = acpi_aml_exec_create_region (((ACPI_PARSE2_OBJECT *) op)->data,
626 ((ACPI_PARSE2_OBJECT *) op)->length,
627 (ACPI_ADDRESS_SPACE_TYPE) arg->value.integer,
633 /* Namespace Modifier Opcodes */
637 status = acpi_ds_create_operands (walk_state, arg);
638 if (ACPI_FAILURE (status)) {
642 status = acpi_aml_exec_create_alias (walk_state);
649 * Because of the execution pass through the non-control-method
650 * parts of the table, we can arrive here twice. Only init
651 * the named object node the first time through
655 status = acpi_ds_create_node (walk_state, node, op);
661 case AML_NAMEPATH_OP:
673 /* Remove the Node pushed at the very beginning */
675 acpi_ds_obj_stack_pop (1, walk_state);