1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acparser.h"
47#include "acdispat.h"
48#include "acnamesp.h"
49
50#define _COMPONENT ACPI_DISPATCHER
51ACPI_MODULE_NAME("dswstate")
52
53
54static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *ws);
55static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *ws);
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70acpi_status
71acpi_ds_result_pop(union acpi_operand_object **object,
72 struct acpi_walk_state *walk_state)
73{
74 u32 index;
75 union acpi_generic_state *state;
76 acpi_status status;
77
78 ACPI_FUNCTION_NAME(ds_result_pop);
79
80 state = walk_state->results;
81
82
83
84 if (state && !walk_state->result_count) {
85 ACPI_ERROR((AE_INFO, "No results on result stack"));
86 return (AE_AML_INTERNAL);
87 }
88
89 if (!state && walk_state->result_count) {
90 ACPI_ERROR((AE_INFO, "No result state for result stack"));
91 return (AE_AML_INTERNAL);
92 }
93
94
95
96 if (!state) {
97 ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p",
98 walk_state));
99 return (AE_AML_NO_RETURN_VALUE);
100 }
101
102
103
104 walk_state->result_count--;
105 index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
106
107 *object = state->results.obj_desc[index];
108 if (!*object) {
109 ACPI_ERROR((AE_INFO,
110 "No result objects on result stack, State=%p",
111 walk_state));
112 return (AE_AML_NO_RETURN_VALUE);
113 }
114
115 state->results.obj_desc[index] = NULL;
116 if (index == 0) {
117 status = acpi_ds_result_stack_pop(walk_state);
118 if (ACPI_FAILURE(status)) {
119 return (status);
120 }
121 }
122
123 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
124 "Obj=%p [%s] Index=%X State=%p Num=%X\n", *object,
125 acpi_ut_get_object_type_name(*object),
126 index, walk_state, walk_state->result_count));
127
128 return (AE_OK);
129}
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144acpi_status
145acpi_ds_result_push(union acpi_operand_object * object,
146 struct acpi_walk_state * walk_state)
147{
148 union acpi_generic_state *state;
149 acpi_status status;
150 u32 index;
151
152 ACPI_FUNCTION_NAME(ds_result_push);
153
154 if (walk_state->result_count > walk_state->result_size) {
155 ACPI_ERROR((AE_INFO, "Result stack is full"));
156 return (AE_AML_INTERNAL);
157 } else if (walk_state->result_count == walk_state->result_size) {
158
159
160
161 status = acpi_ds_result_stack_push(walk_state);
162 if (ACPI_FAILURE(status)) {
163 ACPI_ERROR((AE_INFO,
164 "Failed to extend the result stack"));
165 return (status);
166 }
167 }
168
169 if (!(walk_state->result_count < walk_state->result_size)) {
170 ACPI_ERROR((AE_INFO, "No free elements in result stack"));
171 return (AE_AML_INTERNAL);
172 }
173
174 state = walk_state->results;
175 if (!state) {
176 ACPI_ERROR((AE_INFO, "No result stack frame during push"));
177 return (AE_AML_INTERNAL);
178 }
179
180 if (!object) {
181 ACPI_ERROR((AE_INFO,
182 "Null Object! Obj=%p State=%p Num=%u",
183 object, walk_state, walk_state->result_count));
184 return (AE_BAD_PARAMETER);
185 }
186
187
188
189 index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
190 state->results.obj_desc[index] = object;
191 walk_state->result_count++;
192
193 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
194 object,
195 acpi_ut_get_object_type_name((union
196 acpi_operand_object *)
197 object), walk_state,
198 walk_state->result_count,
199 walk_state->current_result));
200
201 return (AE_OK);
202}
203
204
205
206
207
208
209
210
211
212
213
214
215
216static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *walk_state)
217{
218 union acpi_generic_state *state;
219
220 ACPI_FUNCTION_NAME(ds_result_stack_push);
221
222
223
224 if (((u32) walk_state->result_size + ACPI_RESULTS_FRAME_OBJ_NUM) >
225 ACPI_RESULTS_OBJ_NUM_MAX) {
226 ACPI_ERROR((AE_INFO, "Result stack overflow: State=%p Num=%u",
227 walk_state, walk_state->result_size));
228 return (AE_STACK_OVERFLOW);
229 }
230
231 state = acpi_ut_create_generic_state();
232 if (!state) {
233 return (AE_NO_MEMORY);
234 }
235
236 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT;
237 acpi_ut_push_generic_state(&walk_state->results, state);
238
239
240
241 walk_state->result_size += ACPI_RESULTS_FRAME_OBJ_NUM;
242
243 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n",
244 state, walk_state));
245
246 return (AE_OK);
247}
248
249
250
251
252
253
254
255
256
257
258
259
260
261static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state)
262{
263 union acpi_generic_state *state;
264
265 ACPI_FUNCTION_NAME(ds_result_stack_pop);
266
267
268
269 if (walk_state->results == NULL) {
270 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
271 "Result stack underflow - State=%p\n",
272 walk_state));
273 return (AE_AML_NO_OPERAND);
274 }
275
276 if (walk_state->result_size < ACPI_RESULTS_FRAME_OBJ_NUM) {
277 ACPI_ERROR((AE_INFO, "Insufficient result stack size"));
278 return (AE_AML_INTERNAL);
279 }
280
281 state = acpi_ut_pop_generic_state(&walk_state->results);
282 acpi_ut_delete_generic_state(state);
283
284
285
286 walk_state->result_size -= ACPI_RESULTS_FRAME_OBJ_NUM;
287
288 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
289 "Result=%p RemainingResults=%X State=%p\n",
290 state, walk_state->result_count, walk_state));
291
292 return (AE_OK);
293}
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308acpi_status
309acpi_ds_obj_stack_push(void *object, struct acpi_walk_state * walk_state)
310{
311 ACPI_FUNCTION_NAME(ds_obj_stack_push);
312
313
314
315 if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) {
316 ACPI_ERROR((AE_INFO,
317 "Object stack overflow! Obj=%p State=%p #Ops=%u",
318 object, walk_state, walk_state->num_operands));
319 return (AE_STACK_OVERFLOW);
320 }
321
322
323
324 walk_state->operands[walk_state->operand_index] = object;
325 walk_state->num_operands++;
326
327
328
329 walk_state->operand_index++;
330
331 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
332 object,
333 acpi_ut_get_object_type_name((union
334 acpi_operand_object *)
335 object), walk_state,
336 walk_state->num_operands));
337
338 return (AE_OK);
339}
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355acpi_status
356acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state * walk_state)
357{
358 u32 i;
359
360 ACPI_FUNCTION_NAME(ds_obj_stack_pop);
361
362 for (i = 0; i < pop_count; i++) {
363
364
365
366 if (walk_state->num_operands == 0) {
367 ACPI_ERROR((AE_INFO,
368 "Object stack underflow! Count=%X State=%p #Ops=%u",
369 pop_count, walk_state,
370 walk_state->num_operands));
371 return (AE_STACK_UNDERFLOW);
372 }
373
374
375
376 walk_state->num_operands--;
377 walk_state->operands[walk_state->num_operands] = NULL;
378 }
379
380 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n",
381 pop_count, walk_state, walk_state->num_operands));
382
383 return (AE_OK);
384}
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400void
401acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
402 struct acpi_walk_state *walk_state)
403{
404 s32 i;
405 union acpi_operand_object *obj_desc;
406
407 ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete);
408
409 if (pop_count == 0) {
410 return;
411 }
412
413 for (i = (s32) pop_count - 1; i >= 0; i--) {
414 if (walk_state->num_operands == 0) {
415 return;
416 }
417
418
419
420 walk_state->num_operands--;
421 obj_desc = walk_state->operands[i];
422 if (obj_desc) {
423 acpi_ut_remove_reference(walk_state->operands[i]);
424 walk_state->operands[i] = NULL;
425 }
426 }
427
428 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
429 pop_count, walk_state, walk_state->num_operands));
430}
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state
446 *thread)
447{
448 ACPI_FUNCTION_NAME(ds_get_current_walk_state);
449
450 if (!thread) {
451 return (NULL);
452 }
453
454 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Current WalkState %p\n",
455 thread->walk_state_list));
456
457 return (thread->walk_state_list);
458}
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473void
474acpi_ds_push_walk_state(struct acpi_walk_state *walk_state,
475 struct acpi_thread_state *thread)
476{
477 ACPI_FUNCTION_TRACE(ds_push_walk_state);
478
479 walk_state->next = thread->walk_state_list;
480 thread->walk_state_list = walk_state;
481
482 return_VOID;
483}
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499struct acpi_walk_state *acpi_ds_pop_walk_state(struct acpi_thread_state *thread)
500{
501 struct acpi_walk_state *walk_state;
502
503 ACPI_FUNCTION_TRACE(ds_pop_walk_state);
504
505 walk_state = thread->walk_state_list;
506
507 if (walk_state) {
508
509
510
511 thread->walk_state_list = walk_state->next;
512
513
514
515
516
517
518 }
519
520 return_PTR(walk_state);
521}
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union acpi_parse_object
540 *origin, union acpi_operand_object
541 *method_desc, struct acpi_thread_state
542 *thread)
543{
544 struct acpi_walk_state *walk_state;
545
546 ACPI_FUNCTION_TRACE(ds_create_walk_state);
547
548 walk_state = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_walk_state));
549 if (!walk_state) {
550 return_PTR(NULL);
551 }
552
553 walk_state->descriptor_type = ACPI_DESC_TYPE_WALK;
554 walk_state->method_desc = method_desc;
555 walk_state->owner_id = owner_id;
556 walk_state->origin = origin;
557 walk_state->thread = thread;
558
559 walk_state->parser_state.start_op = origin;
560
561
562
563#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
564 acpi_ds_method_data_init(walk_state);
565#endif
566
567
568
569 if (thread) {
570 acpi_ds_push_walk_state(walk_state, thread);
571 }
572
573 return_PTR(walk_state);
574}
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594acpi_status
595acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
596 union acpi_parse_object *op,
597 struct acpi_namespace_node *method_node,
598 u8 * aml_start,
599 u32 aml_length,
600 struct acpi_evaluate_info *info, u8 pass_number)
601{
602 acpi_status status;
603 struct acpi_parse_state *parser_state = &walk_state->parser_state;
604 union acpi_parse_object *extra_op;
605
606 ACPI_FUNCTION_TRACE(ds_init_aml_walk);
607
608 walk_state->parser_state.aml =
609 walk_state->parser_state.aml_start = aml_start;
610 walk_state->parser_state.aml_end =
611 walk_state->parser_state.pkg_end = aml_start + aml_length;
612
613
614
615 walk_state->next_op = NULL;
616 walk_state->pass_number = pass_number;
617
618 if (info) {
619 walk_state->params = info->parameters;
620 walk_state->caller_return_desc = &info->return_object;
621 }
622
623 status = acpi_ps_init_scope(&walk_state->parser_state, op);
624 if (ACPI_FAILURE(status)) {
625 return_ACPI_STATUS(status);
626 }
627
628 if (method_node) {
629 walk_state->parser_state.start_node = method_node;
630 walk_state->walk_type = ACPI_WALK_METHOD;
631 walk_state->method_node = method_node;
632 walk_state->method_desc =
633 acpi_ns_get_attached_object(method_node);
634
635
636
637 status =
638 acpi_ds_scope_stack_push(method_node, ACPI_TYPE_METHOD,
639 walk_state);
640 if (ACPI_FAILURE(status)) {
641 return_ACPI_STATUS(status);
642 }
643
644
645
646 status = acpi_ds_method_data_init_args(walk_state->params,
647 ACPI_METHOD_NUM_ARGS,
648 walk_state);
649 if (ACPI_FAILURE(status)) {
650 return_ACPI_STATUS(status);
651 }
652 } else {
653
654
655
656
657
658
659 extra_op = parser_state->start_op;
660 while (extra_op && !extra_op->common.node) {
661 extra_op = extra_op->common.parent;
662 }
663
664 if (!extra_op) {
665 parser_state->start_node = NULL;
666 } else {
667 parser_state->start_node = extra_op->common.node;
668 }
669
670 if (parser_state->start_node) {
671
672
673
674 status =
675 acpi_ds_scope_stack_push(parser_state->start_node,
676 parser_state->start_node->
677 type, walk_state);
678 if (ACPI_FAILURE(status)) {
679 return_ACPI_STATUS(status);
680 }
681 }
682 }
683
684 status = acpi_ds_init_callbacks(walk_state, pass_number);
685 return_ACPI_STATUS(status);
686}
687
688
689
690
691
692
693
694
695
696
697
698
699
700void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state)
701{
702 union acpi_generic_state *state;
703
704 ACPI_FUNCTION_TRACE_PTR(ds_delete_walk_state, walk_state);
705
706 if (!walk_state) {
707 return;
708 }
709
710 if (walk_state->descriptor_type != ACPI_DESC_TYPE_WALK) {
711 ACPI_ERROR((AE_INFO, "%p is not a valid walk state",
712 walk_state));
713 return;
714 }
715
716
717
718 if (walk_state->parser_state.scope) {
719 ACPI_ERROR((AE_INFO, "%p walk still has a scope list",
720 walk_state));
721 acpi_ps_cleanup_scope(&walk_state->parser_state);
722 }
723
724
725
726 while (walk_state->control_state) {
727 state = walk_state->control_state;
728 walk_state->control_state = state->common.next;
729
730 acpi_ut_delete_generic_state(state);
731 }
732
733
734
735 while (walk_state->scope_info) {
736 state = walk_state->scope_info;
737 walk_state->scope_info = state->common.next;
738
739 acpi_ut_delete_generic_state(state);
740 }
741
742
743
744 while (walk_state->results) {
745 state = walk_state->results;
746 walk_state->results = state->common.next;
747
748 acpi_ut_delete_generic_state(state);
749 }
750
751 ACPI_FREE(walk_state);
752 return_VOID;
753}
754