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 ACPI_MEMCPY(obj_desc->buffer.pointer,
343 byte_list->named.data, 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 = acpi_ds_build_internal_object(walk_state, arg,
467 &obj_desc->
468 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((AE_INFO,
528 "Actual Package length (%u) is larger than 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 count (%u), padded with null elements\n",
537 i, element_count));
538 }
539
540 obj_desc->package.flags |= AOPOBJ_DATA_VALID;
541 op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc);
542 return_ACPI_STATUS(status);
543}
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559acpi_status
560acpi_ds_create_node(struct acpi_walk_state *walk_state,
561 struct acpi_namespace_node *node,
562 union acpi_parse_object *op)
563{
564 acpi_status status;
565 union acpi_operand_object *obj_desc;
566
567 ACPI_FUNCTION_TRACE_PTR(ds_create_node, op);
568
569
570
571
572
573
574 if (acpi_ns_get_attached_object(node)) {
575 return_ACPI_STATUS(AE_OK);
576 }
577
578 if (!op->common.value.arg) {
579
580
581
582 return_ACPI_STATUS(AE_OK);
583 }
584
585
586
587 status = acpi_ds_build_internal_object(walk_state, op->common.value.arg,
588 &obj_desc);
589 if (ACPI_FAILURE(status)) {
590 return_ACPI_STATUS(status);
591 }
592
593
594
595 node->type = obj_desc->common.type;
596
597
598
599 status = acpi_ns_attach_object(node, obj_desc, node->type);
600
601
602
603 acpi_ut_remove_reference(obj_desc);
604 return_ACPI_STATUS(status);
605}
606
607#endif
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626acpi_status
627acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
628 union acpi_parse_object *op,
629 u16 opcode,
630 union acpi_operand_object **ret_obj_desc)
631{
632 const struct acpi_opcode_info *op_info;
633 union acpi_operand_object *obj_desc;
634 acpi_status status = AE_OK;
635
636 ACPI_FUNCTION_TRACE(ds_init_object_from_op);
637
638 obj_desc = *ret_obj_desc;
639 op_info = acpi_ps_get_opcode_info(opcode);
640 if (op_info->class == AML_CLASS_UNKNOWN) {
641
642
643
644 return_ACPI_STATUS(AE_TYPE);
645 }
646
647
648
649 switch (obj_desc->common.type) {
650 case ACPI_TYPE_BUFFER:
651
652
653
654 obj_desc->buffer.node =
655 ACPI_CAST_PTR(struct acpi_namespace_node,
656 walk_state->operands[0]);
657 obj_desc->buffer.aml_start = op->named.data;
658 obj_desc->buffer.aml_length = op->named.length;
659 break;
660
661 case ACPI_TYPE_PACKAGE:
662
663
664
665 obj_desc->package.node =
666 ACPI_CAST_PTR(struct acpi_namespace_node,
667 walk_state->operands[0]);
668 obj_desc->package.aml_start = op->named.data;
669 obj_desc->package.aml_length = op->named.length;
670 break;
671
672 case ACPI_TYPE_INTEGER:
673
674 switch (op_info->type) {
675 case AML_TYPE_CONSTANT:
676
677
678
679
680
681
682
683
684 obj_desc->common.flags = AOPOBJ_AML_CONSTANT;
685
686 switch (opcode) {
687 case AML_ZERO_OP:
688
689 obj_desc->integer.value = 0;
690 break;
691
692 case AML_ONE_OP:
693
694 obj_desc->integer.value = 1;
695 break;
696
697 case AML_ONES_OP:
698
699 obj_desc->integer.value = ACPI_UINT64_MAX;
700
701
702
703#ifndef ACPI_NO_METHOD_EXECUTION
704 (void)acpi_ex_truncate_for32bit_table(obj_desc);
705#endif
706 break;
707
708 case AML_REVISION_OP:
709
710 obj_desc->integer.value = ACPI_CA_VERSION;
711 break;
712
713 default:
714
715 ACPI_ERROR((AE_INFO,
716 "Unknown constant opcode 0x%X",
717 opcode));
718 status = AE_AML_OPERAND_TYPE;
719 break;
720 }
721 break;
722
723 case AML_TYPE_LITERAL:
724
725 obj_desc->integer.value = op->common.value.integer;
726
727#ifndef ACPI_NO_METHOD_EXECUTION
728 if (acpi_ex_truncate_for32bit_table(obj_desc)) {
729
730
731
732 ACPI_WARNING((AE_INFO,
733 "Truncated 64-bit constant found in 32-bit table: %8.8X%8.8X => %8.8X",
734 ACPI_FORMAT_UINT64(op->common.
735 value.integer),
736 (u32)obj_desc->integer.value));
737 }
738#endif
739 break;
740
741 default:
742
743 ACPI_ERROR((AE_INFO, "Unknown Integer type 0x%X",
744 op_info->type));
745 status = AE_AML_OPERAND_TYPE;
746 break;
747 }
748 break;
749
750 case ACPI_TYPE_STRING:
751
752 obj_desc->string.pointer = op->common.value.string;
753 obj_desc->string.length =
754 (u32) ACPI_STRLEN(op->common.value.string);
755
756
757
758
759
760 obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
761 break;
762
763 case ACPI_TYPE_METHOD:
764 break;
765
766 case ACPI_TYPE_LOCAL_REFERENCE:
767
768 switch (op_info->type) {
769 case AML_TYPE_LOCAL_VARIABLE:
770
771
772
773 obj_desc->reference.value =
774 ((u32)opcode) - AML_LOCAL_OP;
775 obj_desc->reference.class = ACPI_REFCLASS_LOCAL;
776
777#ifndef ACPI_NO_METHOD_EXECUTION
778 status =
779 acpi_ds_method_data_get_node(ACPI_REFCLASS_LOCAL,
780 obj_desc->reference.
781 value, walk_state,
782 ACPI_CAST_INDIRECT_PTR
783 (struct
784 acpi_namespace_node,
785 &obj_desc->reference.
786 object));
787#endif
788 break;
789
790 case AML_TYPE_METHOD_ARGUMENT:
791
792
793
794 obj_desc->reference.value = ((u32)opcode) - AML_ARG_OP;
795 obj_desc->reference.class = ACPI_REFCLASS_ARG;
796
797#ifndef ACPI_NO_METHOD_EXECUTION
798 status = acpi_ds_method_data_get_node(ACPI_REFCLASS_ARG,
799 obj_desc->
800 reference.value,
801 walk_state,
802 ACPI_CAST_INDIRECT_PTR
803 (struct
804 acpi_namespace_node,
805 &obj_desc->
806 reference.
807 object));
808#endif
809 break;
810
811 default:
812
813 switch (op->common.aml_opcode) {
814 case AML_INT_NAMEPATH_OP:
815
816
817
818 obj_desc->reference.node = op->common.node;
819 obj_desc->reference.object =
820 op->common.node->object;
821 obj_desc->reference.class = ACPI_REFCLASS_NAME;
822 break;
823
824 case AML_DEBUG_OP:
825
826 obj_desc->reference.class = ACPI_REFCLASS_DEBUG;
827 break;
828
829 default:
830
831 ACPI_ERROR((AE_INFO,
832 "Unimplemented reference type for AML opcode: 0x%4.4X",
833 opcode));
834 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
835 }
836 break;
837 }
838 break;
839
840 default:
841
842 ACPI_ERROR((AE_INFO, "Unimplemented data type: 0x%X",
843 obj_desc->common.type));
844
845 status = AE_AML_OPERAND_TYPE;
846 break;
847 }
848
849 return_ACPI_STATUS(status);
850}
851