1
2
3
4
5
6
7
8
9
10#include <acpi/acpi.h>
11#include "accommon.h"
12#include "acparser.h"
13#include "amlcode.h"
14#include "acdispat.h"
15#include "acinterp.h"
16#include "acnamesp.h"
17#include "acevents.h"
18#ifdef ACPI_EXEC_APP
19#include "aecommon.h"
20#endif
21
22#define _COMPONENT ACPI_DISPATCHER
23ACPI_MODULE_NAME("dswload2")
24
25
26
27
28
29
30
31
32
33
34
35
36
37acpi_status
38acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
39 union acpi_parse_object **out_op)
40{
41 union acpi_parse_object *op;
42 struct acpi_namespace_node *node;
43 acpi_status status;
44 acpi_object_type object_type;
45 char *buffer_ptr;
46 u32 flags;
47
48 ACPI_FUNCTION_TRACE(ds_load2_begin_op);
49
50 op = walk_state->op;
51 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
52 walk_state));
53
54 if (op) {
55 if ((walk_state->control_state) &&
56 (walk_state->control_state->common.state ==
57 ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
58
59
60
61 status = acpi_ds_exec_begin_op(walk_state, out_op);
62 return_ACPI_STATUS(status);
63 }
64
65
66
67 if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&
68 (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
69 (!(walk_state->op_info->flags & AML_NAMED))) {
70 return_ACPI_STATUS(AE_OK);
71 }
72
73
74
75 if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
76
77
78
79 buffer_ptr = op->common.value.string;
80 if (!buffer_ptr) {
81
82
83
84 return_ACPI_STATUS(AE_OK);
85 }
86 } else {
87
88
89 buffer_ptr = ACPI_CAST_PTR(char, &op->named.name);
90 }
91 } else {
92
93
94 buffer_ptr =
95 acpi_ps_get_next_namestring(&walk_state->parser_state);
96 }
97
98
99
100 object_type = walk_state->op_info->object_type;
101
102 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
103 "State=%p Op=%p Type=%X\n", walk_state, op,
104 object_type));
105
106 switch (walk_state->opcode) {
107 case AML_FIELD_OP:
108 case AML_BANK_FIELD_OP:
109 case AML_INDEX_FIELD_OP:
110
111 node = NULL;
112 status = AE_OK;
113 break;
114
115 case AML_INT_NAMEPATH_OP:
116
117
118
119
120
121 status =
122 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
123 object_type, ACPI_IMODE_EXECUTE,
124 ACPI_NS_SEARCH_PARENT, walk_state, &(node));
125 break;
126
127 case AML_SCOPE_OP:
128
129
130
131 if (op && (op->named.node == acpi_gbl_root_node)) {
132 node = op->named.node;
133
134 status =
135 acpi_ds_scope_stack_push(node, object_type,
136 walk_state);
137 if (ACPI_FAILURE(status)) {
138 return_ACPI_STATUS(status);
139 }
140 } else {
141
142
143
144
145
146 status =
147 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
148 object_type, ACPI_IMODE_EXECUTE,
149 ACPI_NS_SEARCH_PARENT, walk_state,
150 &(node));
151 if (ACPI_FAILURE(status)) {
152#ifdef ACPI_ASL_COMPILER
153 if (status == AE_NOT_FOUND) {
154 status = AE_OK;
155 } else {
156 ACPI_ERROR_NAMESPACE(walk_state->
157 scope_info,
158 buffer_ptr,
159 status);
160 }
161#else
162 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
163 buffer_ptr, status);
164#endif
165 return_ACPI_STATUS(status);
166 }
167 }
168
169
170
171
172
173 switch (node->type) {
174 case ACPI_TYPE_ANY:
175 case ACPI_TYPE_LOCAL_SCOPE:
176 case ACPI_TYPE_DEVICE:
177 case ACPI_TYPE_POWER:
178 case ACPI_TYPE_PROCESSOR:
179 case ACPI_TYPE_THERMAL:
180
181
182 break;
183
184 case ACPI_TYPE_INTEGER:
185 case ACPI_TYPE_STRING:
186 case ACPI_TYPE_BUFFER:
187
188
189
190
191
192
193
194
195 ACPI_WARNING((AE_INFO,
196 "Type override - [%4.4s] had invalid type (%s) "
197 "for Scope operator, changed to type ANY",
198 acpi_ut_get_node_name(node),
199 acpi_ut_get_type_name(node->type)));
200
201 node->type = ACPI_TYPE_ANY;
202 walk_state->scope_info->common.value = ACPI_TYPE_ANY;
203 break;
204
205 case ACPI_TYPE_METHOD:
206
207
208
209
210
211 if ((node == acpi_gbl_root_node) &&
212 (walk_state->
213 parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
214 break;
215 }
216
217 ACPI_FALLTHROUGH;
218
219 default:
220
221
222
223 ACPI_ERROR((AE_INFO,
224 "Invalid type (%s) for target of "
225 "Scope operator [%4.4s] (Cannot override)",
226 acpi_ut_get_type_name(node->type),
227 acpi_ut_get_node_name(node)));
228
229 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
230 }
231 break;
232
233 default:
234
235
236
237 if (op && op->common.node) {
238
239
240
241 node = op->common.node;
242
243 if (acpi_ns_opens_scope(object_type)) {
244 status =
245 acpi_ds_scope_stack_push(node, object_type,
246 walk_state);
247 if (ACPI_FAILURE(status)) {
248 return_ACPI_STATUS(status);
249 }
250 }
251
252 return_ACPI_STATUS(AE_OK);
253 }
254
255
256
257
258
259
260
261
262
263 if (walk_state->deferred_node) {
264
265
266
267 node = walk_state->deferred_node;
268 status = AE_OK;
269 break;
270 }
271
272 flags = ACPI_NS_NO_UPSEARCH;
273 if (walk_state->pass_number == ACPI_IMODE_EXECUTE) {
274
275
276
277 flags |= ACPI_NS_ERROR_IF_FOUND;
278
279 if (!
280 (walk_state->
281 parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
282 flags |= ACPI_NS_TEMPORARY;
283 }
284 }
285#ifdef ACPI_ASL_COMPILER
286
287
288
289
290
291
292
293
294
295
296
297 if (walk_state->opcode == AML_EXTERNAL_OP) {
298 flags |= ACPI_NS_DONT_OPEN_SCOPE;
299 }
300#endif
301
302
303
304
305
306 if (walk_state->op_info->flags & AML_NAMED) {
307 flags |= ACPI_NS_PREFIX_MUST_EXIST;
308 }
309
310
311
312 status =
313 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
314 object_type, ACPI_IMODE_LOAD_PASS2, flags,
315 walk_state, &node);
316
317 if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) {
318 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
319 "***New Node [%4.4s] %p is temporary\n",
320 acpi_ut_get_node_name(node), node));
321 }
322 break;
323 }
324
325 if (ACPI_FAILURE(status)) {
326 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
327 buffer_ptr, status);
328 return_ACPI_STATUS(status);
329 }
330
331 if (!op) {
332
333
334
335 op = acpi_ps_alloc_op(walk_state->opcode, walk_state->aml);
336 if (!op) {
337 return_ACPI_STATUS(AE_NO_MEMORY);
338 }
339
340
341
342 if (node) {
343 op->named.name = node->name.integer;
344 }
345 *out_op = op;
346 }
347
348
349
350
351
352 op->common.node = node;
353 return_ACPI_STATUS(status);
354}
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
370{
371 union acpi_parse_object *op;
372 acpi_status status = AE_OK;
373 acpi_object_type object_type;
374 struct acpi_namespace_node *node;
375 union acpi_parse_object *arg;
376 struct acpi_namespace_node *new_node;
377 u32 i;
378 u8 region_space;
379#ifdef ACPI_EXEC_APP
380 union acpi_operand_object *obj_desc;
381 char *namepath;
382#endif
383
384 ACPI_FUNCTION_TRACE(ds_load2_end_op);
385
386 op = walk_state->op;
387 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
388 walk_state->op_info->name, op, walk_state));
389
390
391
392 if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
393 return_ACPI_STATUS(AE_OK);
394 }
395
396 if (op->common.aml_opcode == AML_SCOPE_OP) {
397 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
398 "Ending scope Op=%p State=%p\n", op,
399 walk_state));
400 }
401
402 object_type = walk_state->op_info->object_type;
403
404
405
406
407
408 node = op->common.node;
409
410
411
412
413
414 walk_state->operands[0] = (void *)node;
415 walk_state->num_operands = 1;
416
417
418
419 if (acpi_ns_opens_scope(object_type) &&
420 (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
421 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
422 "(%s) Popping scope for Op %p\n",
423 acpi_ut_get_type_name(object_type), op));
424
425 status = acpi_ds_scope_stack_pop(walk_state);
426 if (ACPI_FAILURE(status)) {
427 goto cleanup;
428 }
429 }
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
460 "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
461 acpi_ps_get_opcode_name(op->common.aml_opcode),
462 walk_state, op, node));
463
464
465
466 arg = op->common.value.arg;
467
468 switch (walk_state->op_info->type) {
469
470 case AML_TYPE_CREATE_FIELD:
471
472
473
474
475 status = acpi_ds_create_buffer_field(op, walk_state);
476 if (ACPI_FAILURE(status)) {
477 ACPI_EXCEPTION((AE_INFO, status,
478 "CreateBufferField failure"));
479 goto cleanup;
480 }
481 break;
482
483 case AML_TYPE_NAMED_FIELD:
484
485
486
487 if (walk_state->method_node) {
488 status = acpi_ds_init_field_objects(op, walk_state);
489 }
490
491 switch (op->common.aml_opcode) {
492 case AML_INDEX_FIELD_OP:
493
494 status =
495 acpi_ds_create_index_field(op,
496 (acpi_handle)arg->common.
497 node, walk_state);
498 break;
499
500 case AML_BANK_FIELD_OP:
501
502 status =
503 acpi_ds_create_bank_field(op, arg->common.node,
504 walk_state);
505 break;
506
507 case AML_FIELD_OP:
508
509 status =
510 acpi_ds_create_field(op, arg->common.node,
511 walk_state);
512 break;
513
514 default:
515
516
517 break;
518 }
519 break;
520
521 case AML_TYPE_NAMED_SIMPLE:
522
523 status = acpi_ds_create_operands(walk_state, arg);
524 if (ACPI_FAILURE(status)) {
525 goto cleanup;
526 }
527
528 switch (op->common.aml_opcode) {
529 case AML_PROCESSOR_OP:
530
531 status = acpi_ex_create_processor(walk_state);
532 break;
533
534 case AML_POWER_RESOURCE_OP:
535
536 status = acpi_ex_create_power_resource(walk_state);
537 break;
538
539 case AML_MUTEX_OP:
540
541 status = acpi_ex_create_mutex(walk_state);
542 break;
543
544 case AML_EVENT_OP:
545
546 status = acpi_ex_create_event(walk_state);
547 break;
548
549 case AML_ALIAS_OP:
550
551 status = acpi_ex_create_alias(walk_state);
552 break;
553
554 default:
555
556
557
558 status = AE_OK;
559 goto cleanup;
560 }
561
562
563
564 for (i = 1; i < walk_state->num_operands; i++) {
565 acpi_ut_remove_reference(walk_state->operands[i]);
566 walk_state->operands[i] = NULL;
567 }
568
569 break;
570
571 case AML_TYPE_NAMED_COMPLEX:
572
573 switch (op->common.aml_opcode) {
574 case AML_REGION_OP:
575 case AML_DATA_REGION_OP:
576
577 if (op->common.aml_opcode == AML_REGION_OP) {
578 region_space = (acpi_adr_space_type)
579 ((op->common.value.arg)->common.value.
580 integer);
581 } else {
582 region_space = ACPI_ADR_SPACE_DATA_TABLE;
583 }
584
585
586
587
588
589
590
591
592
593
594
595
596
597 if (walk_state->method_node) {
598
599
600
601
602 status = acpi_ex_create_region(op->named.data,
603 op->named.length,
604 region_space,
605 walk_state);
606 if (ACPI_FAILURE(status)) {
607 return_ACPI_STATUS(status);
608 }
609 }
610
611 status =
612 acpi_ev_initialize_region
613 (acpi_ns_get_attached_object(node));
614 break;
615
616 case AML_NAME_OP:
617
618 status = acpi_ds_create_node(walk_state, node, op);
619 if (ACPI_FAILURE(status)) {
620 goto cleanup;
621 }
622#ifdef ACPI_EXEC_APP
623
624
625
626
627 namepath = acpi_ns_get_external_pathname(node);
628 status = ae_lookup_init_file_entry(namepath, &obj_desc);
629 if (ACPI_SUCCESS(status)) {
630
631
632
633 if (node->object) {
634 acpi_ns_detach_object(node);
635 }
636 acpi_ns_attach_object(node, obj_desc,
637 obj_desc->common.type);
638 }
639 ACPI_FREE(namepath);
640 status = AE_OK;
641#endif
642 break;
643
644 case AML_METHOD_OP:
645
646
647
648
649
650
651
652
653 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
654 "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
655 walk_state, op, op->named.node));
656
657 if (!acpi_ns_get_attached_object(op->named.node)) {
658 walk_state->operands[0] =
659 ACPI_CAST_PTR(void, op->named.node);
660 walk_state->num_operands = 1;
661
662 status =
663 acpi_ds_create_operands(walk_state,
664 op->common.value.
665 arg);
666 if (ACPI_SUCCESS(status)) {
667 status =
668 acpi_ex_create_method(op->named.
669 data,
670 op->named.
671 length,
672 walk_state);
673 }
674
675 walk_state->operands[0] = NULL;
676 walk_state->num_operands = 0;
677
678 if (ACPI_FAILURE(status)) {
679 return_ACPI_STATUS(status);
680 }
681 }
682 break;
683
684 default:
685
686
687 break;
688 }
689 break;
690
691 case AML_CLASS_INTERNAL:
692
693
694 break;
695
696 case AML_CLASS_METHOD_CALL:
697
698 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
699 "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
700 walk_state, op, node));
701
702
703
704
705 status =
706 acpi_ns_lookup(walk_state->scope_info,
707 arg->common.value.string, ACPI_TYPE_ANY,
708 ACPI_IMODE_LOAD_PASS2,
709 ACPI_NS_SEARCH_PARENT |
710 ACPI_NS_DONT_OPEN_SCOPE, walk_state,
711 &(new_node));
712 if (ACPI_SUCCESS(status)) {
713
714
715
716
717
718 if (new_node->type != ACPI_TYPE_METHOD) {
719 status = AE_AML_OPERAND_TYPE;
720 }
721
722
723
724
725
726 op->common.node = new_node;
727 } else {
728 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
729 arg->common.value.string, status);
730 }
731 break;
732
733 default:
734
735 break;
736 }
737
738cleanup:
739
740
741
742 walk_state->operands[0] = NULL;
743 walk_state->num_operands = 0;
744 return_ACPI_STATUS(status);
745}
746