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 "amlcode.h"
48#include "acdispat.h"
49#include "acnamesp.h"
50#include "acinterp.h"
51
52#define _COMPONENT ACPI_DISPATCHER
53ACPI_MODULE_NAME("dsobject")
54
55
56static acpi_status
57acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
58 union acpi_parse_object *op,
59 union acpi_operand_object **obj_desc_ptr);
60
61#ifndef ACPI_NO_METHOD_EXECUTION
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77static acpi_status
78acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
79 union acpi_parse_object *op,
80 union acpi_operand_object **obj_desc_ptr)
81{
82 union acpi_operand_object *obj_desc;
83 acpi_status status;
84
85 ACPI_FUNCTION_TRACE(ds_build_internal_object);
86
87 *obj_desc_ptr = NULL;
88 if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
89
90
91
92
93
94 if (!op->common.node) {
95 status = acpi_ns_lookup(walk_state->scope_info,
96 op->common.value.string,
97 ACPI_TYPE_ANY,
98 ACPI_IMODE_EXECUTE,
99 ACPI_NS_SEARCH_PARENT |
100 ACPI_NS_DONT_OPEN_SCOPE, NULL,
101 ACPI_CAST_INDIRECT_PTR(struct
102 acpi_namespace_node,
103 &(op->
104 common.
105 node)));
106 if (ACPI_FAILURE(status)) {
107
108
109
110 if ((status == AE_NOT_FOUND)
111 && (acpi_gbl_enable_interpreter_slack)
112 &&
113 ((op->common.parent->common.aml_opcode ==
114 AML_PACKAGE_OP)
115 || (op->common.parent->common.aml_opcode ==
116 AML_VAR_PACKAGE_OP))) {
117
118
119
120
121
122
123
124
125
126 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
127 "Ignoring unresolved reference in package [%4.4s]\n",
128 walk_state->
129 scope_info->scope.
130 node->name.ascii));
131
132 return_ACPI_STATUS(AE_OK);
133 } else {
134 ACPI_ERROR_NAMESPACE(op->common.value.
135 string, status);
136 }
137
138 return_ACPI_STATUS(status);
139 }
140 }
141
142
143
144 if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
145 (op->common.parent->common.aml_opcode ==
146 AML_VAR_PACKAGE_OP)) {
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161 obj_desc =
162 ACPI_CAST_PTR(union acpi_operand_object,
163 op->common.node);
164
165 status =
166 acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
167 (struct
168 acpi_namespace_node,
169 &obj_desc),
170 walk_state);
171 if (ACPI_FAILURE(status)) {
172 return_ACPI_STATUS(status);
173 }
174
175 switch (op->common.node->type) {
176
177
178
179
180
181
182 case ACPI_TYPE_DEVICE:
183 case ACPI_TYPE_THERMAL:
184
185 acpi_ut_add_reference(op->common.node->object);
186
187
188
189
190
191
192 case ACPI_TYPE_MUTEX:
193 case ACPI_TYPE_METHOD:
194 case ACPI_TYPE_POWER:
195 case ACPI_TYPE_PROCESSOR:
196 case ACPI_TYPE_EVENT:
197 case ACPI_TYPE_REGION:
198
199
200 break;
201
202 default:
203
204
205
206
207 goto exit;
208 }
209 }
210 }
211
212
213
214 obj_desc = acpi_ut_create_internal_object((acpi_ps_get_opcode_info
215 (op->common.aml_opcode))->
216 object_type);
217 if (!obj_desc) {
218 return_ACPI_STATUS(AE_NO_MEMORY);
219 }
220
221 status =
222 acpi_ds_init_object_from_op(walk_state, op, op->common.aml_opcode,
223 &obj_desc);
224 if (ACPI_FAILURE(status)) {
225 acpi_ut_remove_reference(obj_desc);
226 return_ACPI_STATUS(status);
227 }
228
229 exit:
230 *obj_desc_ptr = obj_desc;
231 return_ACPI_STATUS(status);
232}
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250acpi_status
251acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,
252 union acpi_parse_object *op,
253 u32 buffer_length,
254 union acpi_operand_object **obj_desc_ptr)
255{
256 union acpi_parse_object *arg;
257 union acpi_operand_object *obj_desc;
258 union acpi_parse_object *byte_list;
259 u32 byte_list_length = 0;
260
261 ACPI_FUNCTION_TRACE(ds_build_internal_buffer_obj);
262
263
264
265
266
267
268 obj_desc = *obj_desc_ptr;
269 if (!obj_desc) {
270
271
272
273 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
274 *obj_desc_ptr = obj_desc;
275 if (!obj_desc) {
276 return_ACPI_STATUS(AE_NO_MEMORY);
277 }
278 }
279
280
281
282
283
284
285 arg = op->common.value.arg;
286
287 byte_list = arg->named.next;
288 if (byte_list) {
289 if (byte_list->common.aml_opcode != AML_INT_BYTELIST_OP) {
290 ACPI_ERROR((AE_INFO,
291 "Expecting bytelist, got AML opcode %X in op %p",
292 byte_list->common.aml_opcode, byte_list));
293
294 acpi_ut_remove_reference(obj_desc);
295 return (AE_TYPE);
296 }
297
298 byte_list_length = (u32) byte_list->common.value.integer;
299 }
300
301
302
303
304
305
306 obj_desc->buffer.length = buffer_length;
307 if (byte_list_length > buffer_length) {
308 obj_desc->buffer.length = byte_list_length;
309 }
310
311
312
313 if (obj_desc->buffer.length == 0) {
314 obj_desc->buffer.pointer = NULL;
315 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
316 "Buffer defined with zero length in AML, creating\n"));
317 } else {
318 obj_desc->buffer.pointer =
319 ACPI_ALLOCATE_ZEROED(obj_desc->buffer.length);
320 if (!obj_desc->buffer.pointer) {
321 acpi_ut_delete_object_desc(obj_desc);
322 return_ACPI_STATUS(AE_NO_MEMORY);
323 }
324
325
326
327 if (byte_list) {
328 ACPI_MEMCPY(obj_desc->buffer.pointer,
329 byte_list->named.data, byte_list_length);
330 }
331 }
332
333 obj_desc->buffer.flags |= AOPOBJ_DATA_VALID;
334 op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc);
335 return_ACPI_STATUS(AE_OK);
336}
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367acpi_status
368acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
369 union acpi_parse_object *op,
370 u32 element_count,
371 union acpi_operand_object **obj_desc_ptr)
372{
373 union acpi_parse_object *arg;
374 union acpi_parse_object *parent;
375 union acpi_operand_object *obj_desc = NULL;
376 acpi_status status = AE_OK;
377 unsigned i;
378 u16 index;
379 u16 reference_count;
380
381 ACPI_FUNCTION_TRACE(ds_build_internal_package_obj);
382
383
384
385 parent = op->common.parent;
386 while ((parent->common.aml_opcode == AML_PACKAGE_OP) ||
387 (parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
388 parent = parent->common.parent;
389 }
390
391
392
393
394
395 obj_desc = *obj_desc_ptr;
396 if (!obj_desc) {
397 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
398 *obj_desc_ptr = obj_desc;
399 if (!obj_desc) {
400 return_ACPI_STATUS(AE_NO_MEMORY);
401 }
402
403 obj_desc->package.node = parent->common.node;
404 }
405
406
407
408
409
410
411 obj_desc->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
412 element_count +
413 1) * sizeof(void *));
414
415 if (!obj_desc->package.elements) {
416 acpi_ut_delete_object_desc(obj_desc);
417 return_ACPI_STATUS(AE_NO_MEMORY);
418 }
419
420 obj_desc->package.count = element_count;
421
422
423
424
425
426
427
428 arg = op->common.value.arg;
429 arg = arg->common.next;
430 for (i = 0; arg && (i < element_count); i++) {
431 if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
432 if (arg->common.node->type == ACPI_TYPE_METHOD) {
433
434
435
436
437 arg->common.aml_opcode = AML_INT_NAMEPATH_OP;
438 status =
439 acpi_ds_build_internal_object(walk_state,
440 arg,
441 &obj_desc->
442 package.
443 elements[i]);
444 } else {
445
446
447 obj_desc->package.elements[i] =
448 ACPI_CAST_PTR(union acpi_operand_object,
449 arg->common.node);
450 }
451 } else {
452 status = acpi_ds_build_internal_object(walk_state, arg,
453 &obj_desc->
454 package.
455 elements[i]);
456 }
457
458 if (*obj_desc_ptr) {
459
460
461
462 reference_count =
463 (*obj_desc_ptr)->common.reference_count;
464 if (reference_count > 1) {
465
466
467
468 for (index = 0; index < (reference_count - 1);
469 index++) {
470 acpi_ut_add_reference((obj_desc->
471 package.
472 elements[i]));
473 }
474 }
475 }
476
477 arg = arg->common.next;
478 }
479
480
481
482 if (arg) {
483
484
485
486
487
488
489
490
491
492
493
494 while (arg) {
495
496
497
498
499 if (arg->common.node) {
500 acpi_ut_remove_reference(ACPI_CAST_PTR
501 (union
502 acpi_operand_object,
503 arg->common.node));
504 arg->common.node = NULL;
505 }
506
507
508
509 i++;
510 arg = arg->common.next;
511 }
512
513 ACPI_WARNING((AE_INFO,
514 "Package List length (0x%X) larger than NumElements count (0x%X), truncated\n",
515 i, element_count));
516 } else if (i < element_count) {
517
518
519
520
521 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
522 "Package List length (0x%X) smaller than NumElements count (0x%X), padded with null elements\n",
523 i, element_count));
524 }
525
526 obj_desc->package.flags |= AOPOBJ_DATA_VALID;
527 op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc);
528 return_ACPI_STATUS(status);
529}
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545acpi_status
546acpi_ds_create_node(struct acpi_walk_state *walk_state,
547 struct acpi_namespace_node *node,
548 union acpi_parse_object *op)
549{
550 acpi_status status;
551 union acpi_operand_object *obj_desc;
552
553 ACPI_FUNCTION_TRACE_PTR(ds_create_node, op);
554
555
556
557
558
559
560 if (acpi_ns_get_attached_object(node)) {
561 return_ACPI_STATUS(AE_OK);
562 }
563
564 if (!op->common.value.arg) {
565
566
567
568 return_ACPI_STATUS(AE_OK);
569 }
570
571
572
573 status = acpi_ds_build_internal_object(walk_state, op->common.value.arg,
574 &obj_desc);
575 if (ACPI_FAILURE(status)) {
576 return_ACPI_STATUS(status);
577 }
578
579
580
581 node->type = obj_desc->common.type;
582
583
584
585 status = acpi_ns_attach_object(node, obj_desc, node->type);
586
587
588
589 acpi_ut_remove_reference(obj_desc);
590 return_ACPI_STATUS(status);
591}
592
593#endif
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612acpi_status
613acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
614 union acpi_parse_object *op,
615 u16 opcode,
616 union acpi_operand_object **ret_obj_desc)
617{
618 const struct acpi_opcode_info *op_info;
619 union acpi_operand_object *obj_desc;
620 acpi_status status = AE_OK;
621
622 ACPI_FUNCTION_TRACE(ds_init_object_from_op);
623
624 obj_desc = *ret_obj_desc;
625 op_info = acpi_ps_get_opcode_info(opcode);
626 if (op_info->class == AML_CLASS_UNKNOWN) {
627
628
629
630 return_ACPI_STATUS(AE_TYPE);
631 }
632
633
634
635 switch (obj_desc->common.type) {
636 case ACPI_TYPE_BUFFER:
637
638
639
640
641 obj_desc->buffer.node =
642 ACPI_CAST_PTR(struct acpi_namespace_node,
643 walk_state->operands[0]);
644 obj_desc->buffer.aml_start = op->named.data;
645 obj_desc->buffer.aml_length = op->named.length;
646 break;
647
648 case ACPI_TYPE_PACKAGE:
649
650
651
652
653 obj_desc->package.node =
654 ACPI_CAST_PTR(struct acpi_namespace_node,
655 walk_state->operands[0]);
656 obj_desc->package.aml_start = op->named.data;
657 obj_desc->package.aml_length = op->named.length;
658 break;
659
660 case ACPI_TYPE_INTEGER:
661
662 switch (op_info->type) {
663 case AML_TYPE_CONSTANT:
664
665
666
667
668
669
670
671
672 obj_desc->common.flags = AOPOBJ_AML_CONSTANT;
673
674 switch (opcode) {
675 case AML_ZERO_OP:
676
677 obj_desc->integer.value = 0;
678 break;
679
680 case AML_ONE_OP:
681
682 obj_desc->integer.value = 1;
683 break;
684
685 case AML_ONES_OP:
686
687 obj_desc->integer.value = ACPI_INTEGER_MAX;
688
689
690
691#ifndef ACPI_NO_METHOD_EXECUTION
692 acpi_ex_truncate_for32bit_table(obj_desc);
693#endif
694 break;
695
696 case AML_REVISION_OP:
697
698 obj_desc->integer.value = ACPI_CA_VERSION;
699 break;
700
701 default:
702
703 ACPI_ERROR((AE_INFO,
704 "Unknown constant opcode %X",
705 opcode));
706 status = AE_AML_OPERAND_TYPE;
707 break;
708 }
709 break;
710
711 case AML_TYPE_LITERAL:
712
713 obj_desc->integer.value = op->common.value.integer;
714#ifndef ACPI_NO_METHOD_EXECUTION
715 acpi_ex_truncate_for32bit_table(obj_desc);
716#endif
717 break;
718
719 default:
720 ACPI_ERROR((AE_INFO, "Unknown Integer type %X",
721 op_info->type));
722 status = AE_AML_OPERAND_TYPE;
723 break;
724 }
725 break;
726
727 case ACPI_TYPE_STRING:
728
729 obj_desc->string.pointer = op->common.value.string;
730 obj_desc->string.length =
731 (u32) ACPI_STRLEN(op->common.value.string);
732
733
734
735
736
737 obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
738 break;
739
740 case ACPI_TYPE_METHOD:
741 break;
742
743 case ACPI_TYPE_LOCAL_REFERENCE:
744
745 switch (op_info->type) {
746 case AML_TYPE_LOCAL_VARIABLE:
747
748
749
750 obj_desc->reference.value =
751 ((u32)opcode) - AML_LOCAL_OP;
752 obj_desc->reference.class = ACPI_REFCLASS_LOCAL;
753
754#ifndef ACPI_NO_METHOD_EXECUTION
755 status =
756 acpi_ds_method_data_get_node(ACPI_REFCLASS_LOCAL,
757 obj_desc->reference.
758 value, walk_state,
759 ACPI_CAST_INDIRECT_PTR
760 (struct
761 acpi_namespace_node,
762 &obj_desc->reference.
763 object));
764#endif
765 break;
766
767 case AML_TYPE_METHOD_ARGUMENT:
768
769
770
771 obj_desc->reference.value = ((u32)opcode) - AML_ARG_OP;
772 obj_desc->reference.class = ACPI_REFCLASS_ARG;
773
774#ifndef ACPI_NO_METHOD_EXECUTION
775 status = acpi_ds_method_data_get_node(ACPI_REFCLASS_ARG,
776 obj_desc->
777 reference.value,
778 walk_state,
779 ACPI_CAST_INDIRECT_PTR
780 (struct
781 acpi_namespace_node,
782 &obj_desc->
783 reference.
784 object));
785#endif
786 break;
787
788 default:
789
790 switch (op->common.aml_opcode) {
791 case AML_INT_NAMEPATH_OP:
792
793
794
795 obj_desc->reference.node = op->common.node;
796 obj_desc->reference.object =
797 op->common.node->object;
798 obj_desc->reference.class = ACPI_REFCLASS_NAME;
799 break;
800
801 case AML_DEBUG_OP:
802
803 obj_desc->reference.class = ACPI_REFCLASS_DEBUG;
804 break;
805
806 default:
807
808 ACPI_ERROR((AE_INFO,
809 "Unimplemented reference type for AML opcode: %4.4X",
810 opcode));
811 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
812 }
813 break;
814 }
815 break;
816
817 default:
818
819 ACPI_ERROR((AE_INFO, "Unimplemented data type: %X",
820 obj_desc->common.type));
821
822 status = AE_AML_OPERAND_TYPE;
823 break;
824 }
825
826 return_ACPI_STATUS(status);
827}
828