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
29 #define _COMPONENT ACPI_DISPATCHER
30 MODULE_NAME ("dswload")
33 /*******************************************************************************
35 * FUNCTION: Acpi_ds_load1_begin_op
37 * PARAMETERS: Walk_state - Current state of the parse tree walk
38 * Op - Op that has been just been reached in the
39 * walk; Arguments have not been evaluated yet.
43 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
45 ******************************************************************************/
48 acpi_ds_load1_begin_op (
50 ACPI_PARSE_OBJECT
*op
,
51 ACPI_WALK_STATE
*walk_state
,
52 ACPI_PARSE_OBJECT
**out_op
)
54 ACPI_NAMESPACE_NODE
*node
;
56 OBJECT_TYPE_INTERNAL data_type
;
60 /* We are only interested in opcodes that have an associated name */
62 if (!acpi_ps_is_named_op (opcode
)) {
68 /* Check if this object has already been installed in the namespace */
75 path
= acpi_ps_get_next_namestring (walk_state
->parser_state
);
77 /* Map the raw opcode into an internal object type */
79 data_type
= acpi_ds_map_named_opcode_to_data_type (opcode
);
84 * Enter the named type into the internal namespace. We enter the name
85 * as we go downward in the parse tree. Any necessary subobjects that involve
86 * arguments to the opcode must be created as we go back up the parse tree later.
88 status
= acpi_ns_lookup (walk_state
->scope_info
, path
,
89 data_type
, IMODE_LOAD_PASS1
,
90 NS_NO_UPSEARCH
, walk_state
, &(node
));
92 if (ACPI_FAILURE (status
)) {
99 op
= acpi_ps_alloc_op (opcode
);
101 return (AE_NO_MEMORY
);
107 ((ACPI_PARSE2_OBJECT
*)op
)->name
= node
->name
;
110 * Put the Node in the "op" object that the parser uses, so we
111 * can get it again quickly when this scope is closed
116 acpi_ps_append_arg (acpi_ps_get_parent_scope (walk_state
->parser_state
), op
);
124 /*******************************************************************************
126 * FUNCTION: Acpi_ds_load1_end_op
128 * PARAMETERS: Walk_state - Current state of the parse tree walk
129 * Op - Op that has been just been completed in the
130 * walk; Arguments have now been evaluated.
134 * DESCRIPTION: Ascending callback used during the loading of the namespace,
135 * both control methods and everything else.
137 ******************************************************************************/
140 acpi_ds_load1_end_op (
141 ACPI_WALK_STATE
*walk_state
,
142 ACPI_PARSE_OBJECT
*op
)
144 OBJECT_TYPE_INTERNAL data_type
;
147 /* We are only interested in opcodes that have an associated name */
149 if (!acpi_ps_is_named_op (op
->opcode
)) {
154 /* Get the type to determine if we should pop the scope */
156 data_type
= acpi_ds_map_named_opcode_to_data_type (op
->opcode
);
158 if (op
->opcode
== AML_NAME_OP
) {
159 /* For Name opcode, check the argument */
162 data_type
= acpi_ds_map_opcode_to_data_type (
163 (op
->value
.arg
)->opcode
, NULL
);
164 ((ACPI_NAMESPACE_NODE
*)op
->node
)->type
=
170 /* Pop the scope stack */
172 if (acpi_ns_opens_scope (data_type
)) {
174 acpi_ds_scope_stack_pop (walk_state
);
182 /*******************************************************************************
184 * FUNCTION: Acpi_ds_load2_begin_op
186 * PARAMETERS: Walk_state - Current state of the parse tree walk
187 * Op - Op that has been just been reached in the
188 * walk; Arguments have not been evaluated yet.
192 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
194 ******************************************************************************/
197 acpi_ds_load2_begin_op (
199 ACPI_PARSE_OBJECT
*op
,
200 ACPI_WALK_STATE
*walk_state
,
201 ACPI_PARSE_OBJECT
**out_op
)
203 ACPI_NAMESPACE_NODE
*node
;
205 OBJECT_TYPE_INTERNAL data_type
;
206 NATIVE_CHAR
*buffer_ptr
;
207 void *original
= NULL
;
210 /* We only care about Namespace opcodes here */
212 if (!acpi_ps_is_namespace_op (opcode
) &&
213 opcode
!= AML_NAMEPATH_OP
) {
218 /* Temp! same code as in psparse */
220 if (!acpi_ps_is_named_op (opcode
)) {
226 * Get the name we are going to enter or lookup in the namespace
228 if (opcode
== AML_NAMEPATH_OP
) {
229 /* For Namepath op, get the path string */
231 buffer_ptr
= op
->value
.string
;
233 /* No name, just exit */
240 /* Get name from the op */
242 buffer_ptr
= (NATIVE_CHAR
*) &((ACPI_PARSE2_OBJECT
*)op
)->name
;
247 buffer_ptr
= acpi_ps_get_next_namestring (walk_state
->parser_state
);
251 /* Map the raw opcode into an internal object type */
253 data_type
= acpi_ds_map_named_opcode_to_data_type (opcode
);
256 if (opcode
== AML_DEF_FIELD_OP
||
257 opcode
== AML_BANK_FIELD_OP
||
258 opcode
== AML_INDEX_FIELD_OP
) {
263 else if (opcode
== AML_NAMEPATH_OP
) {
265 * The Name_path is an object reference to an existing object. Don't enter the
266 * name into the namespace, but look it up for use later
268 status
= acpi_ns_lookup (walk_state
->scope_info
, buffer_ptr
,
269 data_type
, IMODE_EXECUTE
,
270 NS_SEARCH_PARENT
, walk_state
,
275 if (op
&& op
->node
) {
279 if (acpi_ns_opens_scope (data_type
)) {
280 status
= acpi_ds_scope_stack_push (node
,
283 if (ACPI_FAILURE (status
)) {
292 * Enter the named type into the internal namespace. We enter the name
293 * as we go downward in the parse tree. Any necessary subobjects that involve
294 * arguments to the opcode must be created as we go back up the parse tree later.
296 status
= acpi_ns_lookup (walk_state
->scope_info
, buffer_ptr
,
297 data_type
, IMODE_EXECUTE
,
298 NS_NO_UPSEARCH
, walk_state
,
302 if (ACPI_SUCCESS (status
)) {
304 /* Create a new op */
306 op
= acpi_ps_alloc_op (opcode
);
308 return (AE_NO_MEMORY
);
313 ((ACPI_PARSE2_OBJECT
*)op
)->name
= node
->name
;
319 * Put the Node in the "op" object that the parser uses, so we
320 * can get it again quickly when this scope is closed
331 /*******************************************************************************
333 * FUNCTION: Acpi_ds_load2_end_op
335 * PARAMETERS: Walk_state - Current state of the parse tree walk
336 * Op - Op that has been just been completed in the
337 * walk; Arguments have now been evaluated.
341 * DESCRIPTION: Ascending callback used during the loading of the namespace,
342 * both control methods and everything else.
344 ******************************************************************************/
347 acpi_ds_load2_end_op (
348 ACPI_WALK_STATE
*walk_state
,
349 ACPI_PARSE_OBJECT
*op
)
351 ACPI_STATUS status
= AE_OK
;
352 OBJECT_TYPE_INTERNAL data_type
;
353 ACPI_NAMESPACE_NODE
*node
;
354 ACPI_PARSE_OBJECT
*arg
;
355 ACPI_NAMESPACE_NODE
*new_node
;
358 if (!acpi_ps_is_namespace_object_op (op
->opcode
)) {
362 if (op
->opcode
== AML_SCOPE_OP
) {
363 if (((ACPI_PARSE2_OBJECT
*)op
)->name
== -1) {
369 data_type
= acpi_ds_map_named_opcode_to_data_type (op
->opcode
);
372 * Get the Node/name from the earlier lookup
373 * (It was saved in the *op structure)
378 * Put the Node on the object stack (Contains the ACPI Name of
382 walk_state
->operands
[0] = (void *) node
;
383 walk_state
->num_operands
= 1;
385 /* Pop the scope stack */
387 if (acpi_ns_opens_scope (data_type
)) {
389 acpi_ds_scope_stack_pop (walk_state
);
394 * Named operations are as follows:
413 * AML_CREATEBYTEFIELD
414 * AML_CREATEWORDFIELD
415 * AML_CREATEDWORDFIELD
420 /* Decode the opcode */
424 switch (op
->opcode
) {
426 case AML_CREATE_FIELD_OP
:
427 case AML_BIT_FIELD_OP
:
428 case AML_BYTE_FIELD_OP
:
429 case AML_WORD_FIELD_OP
:
430 case AML_DWORD_FIELD_OP
:
433 * Create the field object, but the field buffer and index must
434 * be evaluated later during the execution phase
437 /* Get the Name_string argument */
439 if (op
->opcode
== AML_CREATE_FIELD_OP
) {
440 arg
= acpi_ps_get_arg (op
, 3);
443 /* Create Bit/Byte/Word/Dword field */
445 arg
= acpi_ps_get_arg (op
, 2);
449 * Enter the Name_string into the namespace
452 status
= acpi_ns_lookup (walk_state
->scope_info
,
454 INTERNAL_TYPE_DEF_ANY
,
456 NS_NO_UPSEARCH
| NS_DONT_OPEN_SCOPE
,
457 walk_state
, &(new_node
));
459 if (ACPI_SUCCESS (status
)) {
460 /* We could put the returned object (Node) on the object stack for later, but
461 * for now, we will put it in the "op" object that the parser uses, so we
462 * can get it again at the end of this scope
467 * If there is no object attached to the node, this node was just created and
468 * we need to create the field object. Otherwise, this was a lookup of an
469 * existing node and we don't want to create the field object again.
471 if (!new_node
->object
) {
473 * The Field definition is not fully parsed at this time.
474 * (We must save the address of the AML for the buffer and index operands)
476 status
= acpi_aml_exec_create_field (((ACPI_PARSE2_OBJECT
*) op
)->data
,
477 ((ACPI_PARSE2_OBJECT
*) op
)->length
,
478 new_node
, walk_state
);
486 case AML_METHODCALL_OP
:
489 * Lookup the method name and save the Node
492 status
= acpi_ns_lookup (walk_state
->scope_info
, arg
->value
.string
,
493 ACPI_TYPE_ANY
, IMODE_LOAD_PASS2
,
494 NS_SEARCH_PARENT
| NS_DONT_OPEN_SCOPE
,
495 walk_state
, &(new_node
));
497 if (ACPI_SUCCESS (status
)) {
499 /* has name already been resolved by here ??*/
501 /* TBD: [Restructure] Make sure that what we found is indeed a method! */
502 /* We didn't search for a method on purpose, to see if the name would resolve! */
504 /* We could put the returned object (Node) on the object stack for later, but
505 * for now, we will put it in the "op" object that the parser uses, so we
506 * can get it again at the end of this scope
515 case AML_PROCESSOR_OP
:
517 /* Nothing to do other than enter object into namespace */
519 status
= acpi_aml_exec_create_processor (op
, (ACPI_HANDLE
) node
);
520 if (ACPI_FAILURE (status
)) {
527 case AML_POWER_RES_OP
:
529 /* Nothing to do other than enter object into namespace */
531 status
= acpi_aml_exec_create_power_resource (op
, (ACPI_HANDLE
) node
);
532 if (ACPI_FAILURE (status
)) {
539 case AML_THERMAL_ZONE_OP
:
541 /* Nothing to do other than enter object into namespace */
546 case AML_DEF_FIELD_OP
:
550 status
= acpi_ds_create_field (op
, arg
->node
, walk_state
);
554 case AML_INDEX_FIELD_OP
:
558 status
= acpi_ds_create_index_field (op
, (ACPI_HANDLE
) arg
->node
,
563 case AML_BANK_FIELD_OP
:
566 status
= acpi_ds_create_bank_field (op
, arg
->node
, walk_state
);
571 * Method_op Pkg_length Names_string Method_flags Term_list
576 status
= acpi_aml_exec_create_method (((ACPI_PARSE2_OBJECT
*) op
)->data
,
577 ((ACPI_PARSE2_OBJECT
*) op
)->length
,
578 arg
->value
.integer
, (ACPI_HANDLE
) node
);
586 status
= acpi_ds_create_operands (walk_state
, arg
);
587 if (ACPI_FAILURE (status
)) {
591 status
= acpi_aml_exec_create_mutex (walk_state
);
597 status
= acpi_ds_create_operands (walk_state
, arg
);
598 if (ACPI_FAILURE (status
)) {
602 status
= acpi_aml_exec_create_event (walk_state
);
614 * The Op_region is not fully parsed at this time. Only valid argument is the Space_id.
615 * (We must save the address of the AML of the address and length operands)
618 status
= acpi_aml_exec_create_region (((ACPI_PARSE2_OBJECT
*) op
)->data
,
619 ((ACPI_PARSE2_OBJECT
*) op
)->length
,
620 (ACPI_ADDRESS_SPACE_TYPE
) arg
->value
.integer
,
626 /* Namespace Modifier Opcodes */
630 status
= acpi_ds_create_operands (walk_state
, arg
);
631 if (ACPI_FAILURE (status
)) {
635 status
= acpi_aml_exec_create_alias (walk_state
);
642 * Because of the execution pass through the non-control-method
643 * parts of the table, we can arrive here twice. Only init
644 * the named object node the first time through
648 status
= acpi_ds_create_node (walk_state
, node
, op
);
654 case AML_NAMEPATH_OP
:
666 /* Remove the Node pushed at the very beginning */
668 acpi_ds_obj_stack_pop (1, walk_state
);