File: /usr/src/linux/drivers/acpi/dispatcher/dswload.c
1 /******************************************************************************
2 *
3 * Module Name: dswload - Dispatcher namespace load callbacks
4 * $Revision: 44 $
5 *
6 *****************************************************************************/
7
8 /*
9 * Copyright (C) 2000, 2001 R. Byron Moore
10 *
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.
15 *
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.
20 *
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
24 */
25
26
27 #include "acpi.h"
28 #include "acparser.h"
29 #include "amlcode.h"
30 #include "acdispat.h"
31 #include "acinterp.h"
32 #include "acnamesp.h"
33 #include "acevents.h"
34
35
36 #define _COMPONENT ACPI_DISPATCHER
37 MODULE_NAME ("dswload")
38
39
40 /*******************************************************************************
41 *
42 * FUNCTION: Acpi_ds_load1_begin_op
43 *
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.
47 *
48 * RETURN: Status
49 *
50 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
51 *
52 ******************************************************************************/
53
54 acpi_status
55 acpi_ds_load1_begin_op (
56 u16 opcode,
57 acpi_parse_object *op,
58 acpi_walk_state *walk_state,
59 acpi_parse_object **out_op)
60 {
61 acpi_namespace_node *node;
62 acpi_status status;
63 acpi_object_type8 data_type;
64 NATIVE_CHAR *path;
65 const acpi_opcode_info *op_info;
66
67
68 PROC_NAME ("Ds_load1_begin_op");
69 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
70
71
72 /* We are only interested in opcodes that have an associated name */
73
74 op_info = acpi_ps_get_opcode_info (opcode);
75 if (!(op_info->flags & AML_NAMED)) {
76 *out_op = op;
77 return (AE_OK);
78 }
79
80 /* Check if this object has already been installed in the namespace */
81
82 if (op && op->node) {
83 *out_op = op;
84 return (AE_OK);
85 }
86
87 path = acpi_ps_get_next_namestring (walk_state->parser_state);
88
89 /* Map the raw opcode into an internal object type */
90
91 data_type = acpi_ds_map_named_opcode_to_data_type (opcode);
92
93
94 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
95 "State=%p Op=%p Type=%x\n", walk_state, op, data_type));
96
97
98 if (opcode == AML_SCOPE_OP) {
99 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
100 "State=%p Op=%p Type=%x\n", walk_state, op, data_type));
101 }
102
103 /*
104 * Enter the named type into the internal namespace. We enter the name
105 * as we go downward in the parse tree. Any necessary subobjects that involve
106 * arguments to the opcode must be created as we go back up the parse tree later.
107 */
108 status = acpi_ns_lookup (walk_state->scope_info, path, data_type,
109 IMODE_LOAD_PASS1, NS_NO_UPSEARCH, walk_state, &(node));
110
111 if (ACPI_FAILURE (status)) {
112 return (status);
113 }
114
115 if (!op) {
116 /* Create a new op */
117
118 op = acpi_ps_alloc_op (opcode);
119 if (!op) {
120 return (AE_NO_MEMORY);
121 }
122 }
123
124 /* Initialize */
125
126 ((acpi_parse2_object *)op)->name = node->name;
127
128 /*
129 * Put the Node in the "op" object that the parser uses, so we
130 * can get it again quickly when this scope is closed
131 */
132 op->node = node;
133 acpi_ps_append_arg (acpi_ps_get_parent_scope (walk_state->parser_state), op);
134
135 *out_op = op;
136 return (status);
137 }
138
139
140 /*******************************************************************************
141 *
142 * FUNCTION: Acpi_ds_load1_end_op
143 *
144 * PARAMETERS: Walk_state - Current state of the parse tree walk
145 * Op - Op that has been just been completed in the
146 * walk; Arguments have now been evaluated.
147 *
148 * RETURN: Status
149 *
150 * DESCRIPTION: Ascending callback used during the loading of the namespace,
151 * both control methods and everything else.
152 *
153 ******************************************************************************/
154
155 acpi_status
156 acpi_ds_load1_end_op (
157 acpi_walk_state *walk_state,
158 acpi_parse_object *op)
159 {
160 acpi_object_type8 data_type;
161 const acpi_opcode_info *op_info;
162
163
164 PROC_NAME ("Ds_load1_end_op");
165 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
166
167
168 /* We are only interested in opcodes that have an associated name */
169
170 op_info = acpi_ps_get_opcode_info (op->opcode);
171 if (!(op_info->flags & AML_NAMED)) {
172 return (AE_OK);
173 }
174
175 /* Get the type to determine if we should pop the scope */
176
177 data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode);
178
179 if (op->opcode == AML_NAME_OP) {
180 /* For Name opcode, check the argument */
181
182 if (op->value.arg) {
183 data_type = acpi_ds_map_opcode_to_data_type (
184 (op->value.arg)->opcode, NULL);
185 ((acpi_namespace_node *)op->node)->type =
186 (u8) data_type;
187 }
188 }
189
190 /* Pop the scope stack */
191
192 if (acpi_ns_opens_scope (data_type)) {
193 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s): Popping scope for Op %p\n",
194 acpi_ut_get_type_name (data_type), op));
195
196 acpi_ds_scope_stack_pop (walk_state);
197 }
198
199 return (AE_OK);
200 }
201
202
203 /*******************************************************************************
204 *
205 * FUNCTION: Acpi_ds_load2_begin_op
206 *
207 * PARAMETERS: Walk_state - Current state of the parse tree walk
208 * Op - Op that has been just been reached in the
209 * walk; Arguments have not been evaluated yet.
210 *
211 * RETURN: Status
212 *
213 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
214 *
215 ******************************************************************************/
216
217 acpi_status
218 acpi_ds_load2_begin_op (
219 u16 opcode,
220 acpi_parse_object *op,
221 acpi_walk_state *walk_state,
222 acpi_parse_object **out_op)
223 {
224 acpi_namespace_node *node;
225 acpi_status status;
226 acpi_object_type8 data_type;
227 NATIVE_CHAR *buffer_ptr;
228 void *original = NULL;
229 const acpi_opcode_info *op_info;
230
231
232 PROC_NAME ("Ds_load2_begin_op");
233 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
234
235
236 /* We only care about Namespace opcodes here */
237
238 op_info = acpi_ps_get_opcode_info (opcode);
239 if (!(op_info->flags & AML_NSOPCODE) &&
240 opcode != AML_INT_NAMEPATH_OP) {
241 return (AE_OK);
242 }
243
244 /* TBD: [Restructure] Temp! same code as in psparse */
245
246 if (!(op_info->flags & AML_NAMED)) {
247 return (AE_OK);
248 }
249
250 if (op) {
251 /*
252 * Get the name we are going to enter or lookup in the namespace
253 */
254 if (opcode == AML_INT_NAMEPATH_OP) {
255 /* For Namepath op, get the path string */
256
257 buffer_ptr = op->value.string;
258 if (!buffer_ptr) {
259 /* No name, just exit */
260
261 return (AE_OK);
262 }
263 }
264
265 else {
266 /* Get name from the op */
267
268 buffer_ptr = (NATIVE_CHAR *) &((acpi_parse2_object *)op)->name;
269 }
270 }
271
272 else {
273 buffer_ptr = acpi_ps_get_next_namestring (walk_state->parser_state);
274 }
275
276
277 /* Map the raw opcode into an internal object type */
278
279 data_type = acpi_ds_map_named_opcode_to_data_type (opcode);
280
281 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
282 "State=%p Op=%p Type=%x\n", walk_state, op, data_type));
283
284
285 if (opcode == AML_FIELD_OP ||
286 opcode == AML_BANK_FIELD_OP ||
287 opcode == AML_INDEX_FIELD_OP) {
288 node = NULL;
289 status = AE_OK;
290 }
291
292 else if (opcode == AML_INT_NAMEPATH_OP) {
293 /*
294 * The Name_path is an object reference to an existing object. Don't enter the
295 * name into the namespace, but look it up for use later
296 */
297 status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, data_type,
298 IMODE_EXECUTE, NS_SEARCH_PARENT, walk_state, &(node));
299 }
300
301 else {
302 if (op && op->node) {
303 original = op->node;
304 node = op->node;
305
306 if (acpi_ns_opens_scope (data_type)) {
307 status = acpi_ds_scope_stack_push (node, data_type, walk_state);
308 if (ACPI_FAILURE (status)) {
309 return (status);
310 }
311
312 }
313 return (AE_OK);
314 }
315
316 /*
317 * Enter the named type into the internal namespace. We enter the name
318 * as we go downward in the parse tree. Any necessary subobjects that involve
319 * arguments to the opcode must be created as we go back up the parse tree later.
320 */
321 status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, data_type,
322 IMODE_EXECUTE, NS_NO_UPSEARCH, walk_state, &(node));
323 }
324
325 if (ACPI_SUCCESS (status)) {
326 if (!op) {
327 /* Create a new op */
328
329 op = acpi_ps_alloc_op (opcode);
330 if (!op) {
331 return (AE_NO_MEMORY);
332 }
333
334 /* Initialize */
335
336 ((acpi_parse2_object *)op)->name = node->name;
337 *out_op = op;
338 }
339
340 /*
341 * Put the Node in the "op" object that the parser uses, so we
342 * can get it again quickly when this scope is closed
343 */
344 op->node = node;
345
346 if (original) {
347 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "old %p new %p\n", original, node));
348
349 if (original != node) {
350 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
351 "Lookup match error: old %p new %p\n", original, node));
352 }
353 }
354 }
355
356 return (status);
357 }
358
359
360 /*******************************************************************************
361 *
362 * FUNCTION: Acpi_ds_load2_end_op
363 *
364 * PARAMETERS: Walk_state - Current state of the parse tree walk
365 * Op - Op that has been just been completed in the
366 * walk; Arguments have now been evaluated.
367 *
368 * RETURN: Status
369 *
370 * DESCRIPTION: Ascending callback used during the loading of the namespace,
371 * both control methods and everything else.
372 *
373 ******************************************************************************/
374
375 acpi_status
376 acpi_ds_load2_end_op (
377 acpi_walk_state *walk_state,
378 acpi_parse_object *op)
379 {
380 acpi_status status = AE_OK;
381 acpi_object_type8 data_type;
382 acpi_namespace_node *node;
383 acpi_parse_object *arg;
384 acpi_namespace_node *new_node;
385 const acpi_opcode_info *op_info;
386
387
388 PROC_NAME ("Ds_load2_end_op");
389 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
390
391
392 /* Only interested in opcodes that have namespace objects */
393
394 op_info = acpi_ps_get_opcode_info (op->opcode);
395 if (!(op_info->flags & AML_NSOBJECT)) {
396 return (AE_OK);
397 }
398
399 if (op->opcode == AML_SCOPE_OP) {
400 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
401 "Ending scope Op=%p State=%p\n", op, walk_state));
402
403 if (((acpi_parse2_object *)op)->name == -1) {
404 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unnamed scope! Op=%p State=%p\n",
405 op, walk_state));
406 return (AE_OK);
407 }
408 }
409
410
411 data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode);
412
413 /*
414 * Get the Node/name from the earlier lookup
415 * (It was saved in the *op structure)
416 */
417 node = op->node;
418
419 /*
420 * Put the Node on the object stack (Contains the ACPI Name of
421 * this object)
422 */
423 walk_state->operands[0] = (void *) node;
424 walk_state->num_operands = 1;
425
426 /* Pop the scope stack */
427
428 if (acpi_ns_opens_scope (data_type)) {
429
430 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
431 acpi_ut_get_type_name (data_type), op));
432 acpi_ds_scope_stack_pop (walk_state);
433 }
434
435 /*
436 * Named operations are as follows:
437 *
438 * AML_SCOPE
439 * AML_DEVICE
440 * AML_THERMALZONE
441 * AML_METHOD
442 * AML_POWERRES
443 * AML_PROCESSOR
444 * AML_FIELD
445 * AML_INDEXFIELD
446 * AML_BANKFIELD
447 * AML_NAMEDFIELD
448 * AML_NAME
449 * AML_ALIAS
450 * AML_MUTEX
451 * AML_EVENT
452 * AML_OPREGION
453 * AML_CREATEFIELD
454 * AML_CREATEBITFIELD
455 * AML_CREATEBYTEFIELD
456 * AML_CREATEWORDFIELD
457 * AML_CREATEDWORDFIELD
458 * AML_CREATEQWORDFIELD
459 * AML_METHODCALL
460 */
461
462
463 /* Decode the opcode */
464
465 arg = op->value.arg;
466
467 switch (op->opcode) {
468
469 case AML_CREATE_FIELD_OP:
470 case AML_CREATE_BIT_FIELD_OP:
471 case AML_CREATE_BYTE_FIELD_OP:
472 case AML_CREATE_WORD_FIELD_OP:
473 case AML_CREATE_DWORD_FIELD_OP:
474 case AML_CREATE_QWORD_FIELD_OP:
475
476 /*
477 * Create the field object, but the field buffer and index must
478 * be evaluated later during the execution phase
479 */
480 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
481 "Create_xxx_field: State=%p Op=%p Named_obj=%p\n",
482 walk_state, op, node));
483
484 /* Get the Name_string argument */
485
486 if (op->opcode == AML_CREATE_FIELD_OP) {
487 arg = acpi_ps_get_arg (op, 3);
488 }
489 else {
490 /* Create Bit/Byte/Word/Dword field */
491
492 arg = acpi_ps_get_arg (op, 2);
493 }
494
495 if (!arg) {
496 status = AE_AML_NO_OPERAND;
497 goto cleanup;
498 }
499
500 /*
501 * Enter the Name_string into the namespace
502 */
503 status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,
504 INTERNAL_TYPE_DEF_ANY, IMODE_LOAD_PASS1,
505 NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
506 walk_state, &(new_node));
507 if (ACPI_FAILURE (status)) {
508 goto cleanup;
509 }
510
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
514 */
515 op->node = new_node;
516
517 /*
518 * If there is no object attached to the node, this node was just created and
519 * we need to create the field object. Otherwise, this was a lookup of an
520 * existing node and we don't want to create the field object again.
521 */
522 if (!new_node->object) {
523 /*
524 * The Field definition is not fully parsed at this time.
525 * (We must save the address of the AML for the buffer and index operands)
526 */
527 status = acpi_ex_create_buffer_field (((acpi_parse2_object *) op)->data,
528 ((acpi_parse2_object *) op)->length,
529 new_node, walk_state);
530 }
531 break;
532
533
534 case AML_INT_METHODCALL_OP:
535
536 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
537 "RESOLVING-Method_call: State=%p Op=%p Named_obj=%p\n",
538 walk_state, op, node));
539
540 /*
541 * Lookup the method name and save the Node
542 */
543 status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,
544 ACPI_TYPE_ANY, IMODE_LOAD_PASS2,
545 NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE,
546 walk_state, &(new_node));
547 if (ACPI_SUCCESS (status)) {
548 /* TBD: has name already been resolved by here ??*/
549
550 /* TBD: [Restructure] Make sure that what we found is indeed a method! */
551 /* We didn't search for a method on purpose, to see if the name would resolve! */
552
553 /* We could put the returned object (Node) on the object stack for later, but
554 * for now, we will put it in the "op" object that the parser uses, so we
555 * can get it again at the end of this scope
556 */
557 op->node = new_node;
558 }
559
560
561 break;
562
563
564 case AML_PROCESSOR_OP:
565
566 /* Nothing to do other than enter object into namespace */
567
568 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
569 "LOADING-Processor: State=%p Op=%p Named_obj=%p\n",
570 walk_state, op, node));
571
572 status = acpi_ex_create_processor (op, node);
573 if (ACPI_FAILURE (status)) {
574 goto cleanup;
575 }
576
577 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
578 "Completed Processor Init, Op=%p State=%p entry=%p\n",
579 op, walk_state, node));
580 break;
581
582
583 case AML_POWER_RES_OP:
584
585 /* Nothing to do other than enter object into namespace */
586
587 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
588 "LOADING-Power_resource: State=%p Op=%p Named_obj=%p\n",
589 walk_state, op, node));
590
591 status = acpi_ex_create_power_resource (op, node);
592 if (ACPI_FAILURE (status)) {
593 goto cleanup;
594 }
595
596 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
597 "Completed Power_resource Init, Op=%p State=%p entry=%p\n",
598 op, walk_state, node));
599 break;
600
601
602 case AML_THERMAL_ZONE_OP:
603
604 /* Nothing to do other than enter object into namespace */
605
606 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
607 "LOADING-Thermal_zone: State=%p Op=%p Named_obj=%p\n",
608 walk_state, op, node));
609 break;
610
611
612 case AML_FIELD_OP:
613
614 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
615 "LOADING-Field: State=%p Op=%p Named_obj=%p\n",
616 walk_state, op, node));
617
618 arg = op->value.arg;
619
620 status = acpi_ds_create_field (op, arg->node, walk_state);
621 break;
622
623
624 case AML_INDEX_FIELD_OP:
625
626 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
627 "LOADING-Index_field: State=%p Op=%p Named_obj=%p\n",
628 walk_state, op, node));
629
630 arg = op->value.arg;
631
632 status = acpi_ds_create_index_field (op, (acpi_handle) arg->node,
633 walk_state);
634 break;
635
636
637 case AML_BANK_FIELD_OP:
638
639 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
640 "LOADING-Bank_field: State=%p Op=%p Named_obj=%p\n",
641 walk_state, op, node));
642
643 arg = op->value.arg;
644 status = acpi_ds_create_bank_field (op, arg->node, walk_state);
645 break;
646
647
648 /*
649 * Method_op Pkg_length Names_string Method_flags Term_list
650 */
651 case AML_METHOD_OP:
652
653 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
654 "LOADING-Method: State=%p Op=%p Named_obj=%p\n",
655 walk_state, op, node));
656
657 if (!node->object) {
658 status = acpi_ex_create_method (((acpi_parse2_object *) op)->data,
659 ((acpi_parse2_object *) op)->length,
660 arg->value.integer32, node);
661 }
662 break;
663
664
665 case AML_MUTEX_OP:
666
667 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
668 "LOADING-Mutex: Op=%p State=%p\n", op, walk_state));
669
670 status = acpi_ds_create_operands (walk_state, arg);
671 if (ACPI_FAILURE (status)) {
672 goto cleanup;
673 }
674
675 status = acpi_ex_create_mutex (walk_state);
676 break;
677
678
679 case AML_EVENT_OP:
680
681 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
682 "LOADING-Event: Op=%p State=%p\n", op, walk_state));
683
684 status = acpi_ds_create_operands (walk_state, arg);
685 if (ACPI_FAILURE (status)) {
686 goto cleanup;
687 }
688
689 status = acpi_ex_create_event (walk_state);
690 break;
691
692
693 case AML_REGION_OP:
694
695 if (node->object) {
696 break;
697 }
698
699 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
700 "LOADING-Opregion: Op=%p State=%p Named_obj=%p\n",
701 op, walk_state, node));
702
703 /*
704 * The Op_region is not fully parsed at this time. Only valid argument is the Space_id.
705 * (We must save the address of the AML of the address and length operands)
706 */
707 status = acpi_ex_create_region (((acpi_parse2_object *) op)->data,
708 ((acpi_parse2_object *) op)->length,
709 (ACPI_ADR_SPACE_TYPE) arg->value.integer, walk_state);
710
711 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
712 "Completed Op_region Init, Op=%p State=%p entry=%p\n",
713 op, walk_state, node));
714 break;
715
716
717 /* Namespace Modifier Opcodes */
718
719 case AML_ALIAS_OP:
720
721 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
722 "LOADING-Alias: Op=%p State=%p\n", op, walk_state));
723
724 status = acpi_ds_create_operands (walk_state, arg);
725 if (ACPI_FAILURE (status)) {
726 goto cleanup;
727 }
728
729 status = acpi_ex_create_alias (walk_state);
730 break;
731
732
733 case AML_NAME_OP:
734
735 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
736 "LOADING-Name: Op=%p State=%p\n", op, walk_state));
737
738 /*
739 * Because of the execution pass through the non-control-method
740 * parts of the table, we can arrive here twice. Only init
741 * the named object node the first time through
742 */
743 if (!node->object) {
744 status = acpi_ds_create_node (walk_state, node, op);
745 }
746
747 break;
748
749
750 case AML_INT_NAMEPATH_OP:
751
752 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
753 "LOADING-Name_path object: State=%p Op=%p Named_obj=%p\n",
754 walk_state, op, node));
755 break;
756
757
758 default:
759 break;
760 }
761
762
763 cleanup:
764
765 /* Remove the Node pushed at the very beginning */
766
767 acpi_ds_obj_stack_pop (1, walk_state);
768 return (status);
769 }
770
771
772