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