1 | // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 |
2 | /****************************************************************************** |
3 | * |
4 | * Module Name: dswload2 - Dispatcher second pass namespace load callbacks |
5 | * |
6 | * Copyright (C) 2000 - 2023, Intel Corp. |
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 |
23 | ACPI_MODULE_NAME("dswload2" ) |
24 | |
25 | /******************************************************************************* |
26 | * |
27 | * FUNCTION: acpi_ds_load2_begin_op |
28 | * |
29 | * PARAMETERS: walk_state - Current state of the parse tree walk |
30 | * out_op - Where to return op if a new one is created |
31 | * |
32 | * RETURN: Status |
33 | * |
34 | * DESCRIPTION: Descending callback used during the loading of ACPI tables. |
35 | * |
36 | ******************************************************************************/ |
37 | acpi_status |
38 | acpi_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 | /* We are executing a while loop outside of a method */ |
60 | |
61 | status = acpi_ds_exec_begin_op(walk_state, out_op); |
62 | return_ACPI_STATUS(status); |
63 | } |
64 | |
65 | /* We only care about Namespace opcodes here */ |
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 | /* Get the name we are going to enter or lookup in the namespace */ |
74 | |
75 | if (walk_state->opcode == AML_INT_NAMEPATH_OP) { |
76 | |
77 | /* For Namepath op, get the path string */ |
78 | |
79 | buffer_ptr = op->common.value.string; |
80 | if (!buffer_ptr) { |
81 | |
82 | /* No name, just exit */ |
83 | |
84 | return_ACPI_STATUS(AE_OK); |
85 | } |
86 | } else { |
87 | /* Get name from the op */ |
88 | |
89 | buffer_ptr = ACPI_CAST_PTR(char, &op->named.name); |
90 | } |
91 | } else { |
92 | /* Get the namestring from the raw AML */ |
93 | |
94 | buffer_ptr = |
95 | acpi_ps_get_next_namestring(parser_state: &walk_state->parser_state); |
96 | } |
97 | |
98 | /* Map the opcode into an internal object type */ |
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 | * The name_path is an object reference to an existing object. |
118 | * Don't enter the name into the namespace, but look it up |
119 | * for use later. |
120 | */ |
121 | status = |
122 | acpi_ns_lookup(scope_info: walk_state->scope_info, name: buffer_ptr, |
123 | type: object_type, interpreter_mode: ACPI_IMODE_EXECUTE, |
124 | ACPI_NS_SEARCH_PARENT, walk_state, ret_node: &(node)); |
125 | break; |
126 | |
127 | case AML_SCOPE_OP: |
128 | |
129 | /* Special case for Scope(\) -> refers to the Root node */ |
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, type: object_type, |
136 | walk_state); |
137 | if (ACPI_FAILURE(status)) { |
138 | return_ACPI_STATUS(status); |
139 | } |
140 | } else { |
141 | /* |
142 | * The Path is an object reference to an existing object. |
143 | * Don't enter the name into the namespace, but look it up |
144 | * for use later. |
145 | */ |
146 | status = |
147 | acpi_ns_lookup(scope_info: walk_state->scope_info, name: buffer_ptr, |
148 | type: object_type, interpreter_mode: ACPI_IMODE_EXECUTE, |
149 | ACPI_NS_SEARCH_PARENT, walk_state, |
150 | ret_node: &(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 | * We must check to make sure that the target is |
171 | * one of the opcodes that actually opens a scope |
172 | */ |
173 | switch (node->type) { |
174 | case ACPI_TYPE_ANY: |
175 | case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ |
176 | case ACPI_TYPE_DEVICE: |
177 | case ACPI_TYPE_POWER: |
178 | case ACPI_TYPE_PROCESSOR: |
179 | case ACPI_TYPE_THERMAL: |
180 | |
181 | /* These are acceptable types */ |
182 | break; |
183 | |
184 | case ACPI_TYPE_INTEGER: |
185 | case ACPI_TYPE_STRING: |
186 | case ACPI_TYPE_BUFFER: |
187 | |
188 | /* |
189 | * These types we will allow, but we will change the type. |
190 | * This enables some existing code of the form: |
191 | * |
192 | * Name (DEB, 0) |
193 | * Scope (DEB) { ... } |
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 | * Allow scope change to root during execution of module-level |
209 | * code. Root is typed METHOD during this time. |
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 | /* All other types are an error */ |
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 | /* All other opcodes */ |
236 | |
237 | if (op && op->common.node) { |
238 | |
239 | /* This op/node was previously entered into the namespace */ |
240 | |
241 | node = op->common.node; |
242 | |
243 | if (acpi_ns_opens_scope(type: object_type)) { |
244 | status = |
245 | acpi_ds_scope_stack_push(node, type: 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 | * Enter the named type into the internal namespace. We enter the name |
257 | * as we go downward in the parse tree. Any necessary subobjects that |
258 | * involve arguments to the opcode must be created as we go back up the |
259 | * parse tree later. |
260 | * |
261 | * Note: Name may already exist if we are executing a deferred opcode. |
262 | */ |
263 | if (walk_state->deferred_node) { |
264 | |
265 | /* This name is already in the namespace, get the node */ |
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 | /* Execution mode, node cannot already exist, node is temporary */ |
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 | * Do not open a scope for AML_EXTERNAL_OP |
289 | * acpi_ns_lookup can open a new scope based on the object type |
290 | * of this op. AML_EXTERNAL_OP is a declaration rather than a |
291 | * definition. In the case that this external is a method object, |
292 | * acpi_ns_lookup will open a new scope. However, an AML_EXTERNAL_OP |
293 | * associated with the ACPI_TYPE_METHOD is a declaration, rather than |
294 | * a definition. Flags is set to avoid opening a scope for any |
295 | * AML_EXTERNAL_OP. |
296 | */ |
297 | if (walk_state->opcode == AML_EXTERNAL_OP) { |
298 | flags |= ACPI_NS_DONT_OPEN_SCOPE; |
299 | } |
300 | #endif |
301 | |
302 | /* |
303 | * For name creation opcodes, the full namepath prefix must |
304 | * exist, except for the final (new) nameseg. |
305 | */ |
306 | if (walk_state->op_info->flags & AML_NAMED) { |
307 | flags |= ACPI_NS_PREFIX_MUST_EXIST; |
308 | } |
309 | |
310 | /* Add new entry or lookup existing entry */ |
311 | |
312 | status = |
313 | acpi_ns_lookup(scope_info: walk_state->scope_info, name: buffer_ptr, |
314 | type: object_type, interpreter_mode: ACPI_IMODE_LOAD_PASS2, flags, |
315 | walk_state, ret_node: &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 | /* Create a new op */ |
334 | |
335 | op = acpi_ps_alloc_op(opcode: walk_state->opcode, aml: walk_state->aml); |
336 | if (!op) { |
337 | return_ACPI_STATUS(AE_NO_MEMORY); |
338 | } |
339 | |
340 | /* Initialize the new op */ |
341 | |
342 | if (node) { |
343 | op->named.name = node->name.integer; |
344 | } |
345 | *out_op = op; |
346 | } |
347 | |
348 | /* |
349 | * Put the Node in the "op" object that the parser uses, so we |
350 | * can get it again quickly when this scope is closed |
351 | */ |
352 | op->common.node = node; |
353 | return_ACPI_STATUS(status); |
354 | } |
355 | |
356 | /******************************************************************************* |
357 | * |
358 | * FUNCTION: acpi_ds_load2_end_op |
359 | * |
360 | * PARAMETERS: walk_state - Current state of the parse tree walk |
361 | * |
362 | * RETURN: Status |
363 | * |
364 | * DESCRIPTION: Ascending callback used during the loading of the namespace, |
365 | * both control methods and everything else. |
366 | * |
367 | ******************************************************************************/ |
368 | |
369 | acpi_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 | /* Check if opcode had an associated namespace object */ |
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 | * Get the Node/name from the earlier lookup |
406 | * (It was saved in the *op structure) |
407 | */ |
408 | node = op->common.node; |
409 | |
410 | /* |
411 | * Put the Node on the object stack (Contains the ACPI Name of |
412 | * this object) |
413 | */ |
414 | walk_state->operands[0] = (void *)node; |
415 | walk_state->num_operands = 1; |
416 | |
417 | /* Pop the scope stack */ |
418 | |
419 | if (acpi_ns_opens_scope(type: 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 | * Named operations are as follows: |
433 | * |
434 | * AML_ALIAS |
435 | * AML_BANKFIELD |
436 | * AML_CREATEBITFIELD |
437 | * AML_CREATEBYTEFIELD |
438 | * AML_CREATEDWORDFIELD |
439 | * AML_CREATEFIELD |
440 | * AML_CREATEQWORDFIELD |
441 | * AML_CREATEWORDFIELD |
442 | * AML_DATA_REGION |
443 | * AML_DEVICE |
444 | * AML_EVENT |
445 | * AML_FIELD |
446 | * AML_INDEXFIELD |
447 | * AML_METHOD |
448 | * AML_METHODCALL |
449 | * AML_MUTEX |
450 | * AML_NAME |
451 | * AML_NAMEDFIELD |
452 | * AML_OPREGION |
453 | * AML_POWERRES |
454 | * AML_PROCESSOR |
455 | * AML_SCOPE |
456 | * AML_THERMALZONE |
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 | /* Decode the opcode */ |
465 | |
466 | arg = op->common.value.arg; |
467 | |
468 | switch (walk_state->op_info->type) { |
469 | |
470 | case AML_TYPE_CREATE_FIELD: |
471 | /* |
472 | * Create the field object, but the field buffer and index must |
473 | * be evaluated later during the execution phase |
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 | * If we are executing a method, initialize the field |
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 | region_node: (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, region_node: arg->common.node, |
504 | walk_state); |
505 | break; |
506 | |
507 | case AML_FIELD_OP: |
508 | |
509 | status = |
510 | acpi_ds_create_field(op, region_node: arg->common.node, |
511 | walk_state); |
512 | break; |
513 | |
514 | default: |
515 | |
516 | /* All NAMED_FIELD opcodes must be handled above */ |
517 | break; |
518 | } |
519 | break; |
520 | |
521 | case AML_TYPE_NAMED_SIMPLE: |
522 | |
523 | status = acpi_ds_create_operands(walk_state, first_arg: 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 | /* Unknown opcode */ |
557 | |
558 | status = AE_OK; |
559 | goto cleanup; |
560 | } |
561 | |
562 | /* Delete operands */ |
563 | |
564 | for (i = 1; i < walk_state->num_operands; i++) { |
565 | acpi_ut_remove_reference(object: 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 | * The op_region is not fully parsed at this time. The only valid |
587 | * argument is the space_id. (We must save the address of the |
588 | * AML of the address and length operands) |
589 | * |
590 | * If we have a valid region, initialize it. The namespace is |
591 | * unlocked at this point. |
592 | * |
593 | * Need to unlock interpreter if it is locked (if we are running |
594 | * a control method), in order to allow _REG methods to be run |
595 | * during acpi_ev_initialize_region. |
596 | */ |
597 | if (walk_state->method_node) { |
598 | /* |
599 | * Executing a method: initialize the region and unlock |
600 | * the interpreter |
601 | */ |
602 | status = acpi_ex_create_region(aml_start: op->named.data, |
603 | aml_length: 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 | (region_obj: 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 | * acpi_exec support for namespace initialization file (initialize |
625 | * Name opcodes in this code.) |
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 | /* Detach any existing object, attach new object */ |
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 | * method_op pkg_length name_string method_flags term_list |
647 | * |
648 | * Note: We must create the method node/object pair as soon as we |
649 | * see the method declaration. This allows later pass1 parsing |
650 | * of invocations of the method (need to know the number of |
651 | * arguments.) |
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(node: 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 | first_arg: op->common.value. |
665 | arg); |
666 | if (ACPI_SUCCESS(status)) { |
667 | status = |
668 | acpi_ex_create_method(aml_start: op->named. |
669 | data, |
670 | aml_length: 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 | /* All NAMED_COMPLEX opcodes must be handled above */ |
687 | break; |
688 | } |
689 | break; |
690 | |
691 | case AML_CLASS_INTERNAL: |
692 | |
693 | /* case AML_INT_NAMEPATH_OP: */ |
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 | * Lookup the method name and save the Node |
704 | */ |
705 | status = |
706 | acpi_ns_lookup(scope_info: walk_state->scope_info, |
707 | name: arg->common.value.string, ACPI_TYPE_ANY, |
708 | interpreter_mode: ACPI_IMODE_LOAD_PASS2, |
709 | ACPI_NS_SEARCH_PARENT | |
710 | ACPI_NS_DONT_OPEN_SCOPE, walk_state, |
711 | ret_node: &(new_node)); |
712 | if (ACPI_SUCCESS(status)) { |
713 | /* |
714 | * Make sure that what we found is indeed a method |
715 | * We didn't search for a method on purpose, to see if the name |
716 | * would resolve |
717 | */ |
718 | if (new_node->type != ACPI_TYPE_METHOD) { |
719 | status = AE_AML_OPERAND_TYPE; |
720 | } |
721 | |
722 | /* We could put the returned object (Node) on the object stack for |
723 | * later, but for now, we will put it in the "op" object that the |
724 | * parser uses, so we can get it again at the end of this scope |
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 | |
738 | cleanup: |
739 | |
740 | /* Remove the Node pushed at the very beginning */ |
741 | |
742 | walk_state->operands[0] = NULL; |
743 | walk_state->num_operands = 0; |
744 | return_ACPI_STATUS(status); |
745 | } |
746 | |