1
2
3
4
5
6
7
8
9
10#include <acpi/acpi.h>
11#include "accommon.h"
12#include "acparser.h"
13#include "acdispat.h"
14#include "acinterp.h"
15#include "amlcode.h"
16#include "acnamesp.h"
17
18#define _COMPONENT ACPI_EXECUTER
19ACPI_MODULE_NAME("exoparg1")
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
45
46
47
48
49
50
51
52
53acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state)
54{
55 acpi_status status = AE_OK;
56 union acpi_operand_object *return_desc = NULL;
57
58 ACPI_FUNCTION_TRACE_STR(ex_opcode_0A_0T_1R,
59 acpi_ps_get_opcode_name(walk_state->opcode));
60
61
62
63 switch (walk_state->opcode) {
64 case AML_TIMER_OP:
65
66
67
68 return_desc =
69 acpi_ut_create_integer_object(acpi_os_get_timer());
70 if (!return_desc) {
71 status = AE_NO_MEMORY;
72 goto cleanup;
73 }
74 break;
75
76 default:
77
78 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
79 walk_state->opcode));
80 status = AE_AML_BAD_OPCODE;
81 break;
82 }
83
84cleanup:
85
86
87
88 if ((ACPI_FAILURE(status)) || walk_state->result_obj) {
89 acpi_ut_remove_reference(return_desc);
90 walk_state->result_obj = NULL;
91 } else {
92
93
94 walk_state->result_obj = return_desc;
95 }
96
97 return_ACPI_STATUS(status);
98}
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113acpi_status acpi_ex_opcode_1A_0T_0R(struct acpi_walk_state *walk_state)
114{
115 union acpi_operand_object **operand = &walk_state->operands[0];
116 acpi_status status = AE_OK;
117
118 ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_0T_0R,
119 acpi_ps_get_opcode_name(walk_state->opcode));
120
121
122
123 switch (walk_state->opcode) {
124 case AML_RELEASE_OP:
125
126 status = acpi_ex_release_mutex(operand[0], walk_state);
127 break;
128
129 case AML_RESET_OP:
130
131 status = acpi_ex_system_reset_event(operand[0]);
132 break;
133
134 case AML_SIGNAL_OP:
135
136 status = acpi_ex_system_signal_event(operand[0]);
137 break;
138
139 case AML_SLEEP_OP:
140
141 status = acpi_ex_system_do_sleep(operand[0]->integer.value);
142 break;
143
144 case AML_STALL_OP:
145
146 status =
147 acpi_ex_system_do_stall((u32) operand[0]->integer.value);
148 break;
149
150 case AML_UNLOAD_OP:
151
152 status = acpi_ex_unload_table(operand[0]);
153 break;
154
155 default:
156
157 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
158 walk_state->opcode));
159 status = AE_AML_BAD_OPCODE;
160 break;
161 }
162
163 return_ACPI_STATUS(status);
164}
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179acpi_status acpi_ex_opcode_1A_1T_0R(struct acpi_walk_state *walk_state)
180{
181 acpi_status status = AE_OK;
182 union acpi_operand_object **operand = &walk_state->operands[0];
183
184 ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_1T_0R,
185 acpi_ps_get_opcode_name(walk_state->opcode));
186
187
188
189 switch (walk_state->opcode) {
190 case AML_LOAD_OP:
191
192 status = acpi_ex_load_op(operand[0], operand[1], walk_state);
193 break;
194
195 default:
196
197 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
198 walk_state->opcode));
199 status = AE_AML_BAD_OPCODE;
200 goto cleanup;
201 }
202
203cleanup:
204
205 return_ACPI_STATUS(status);
206}
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state)
222{
223 acpi_status status = AE_OK;
224 union acpi_operand_object **operand = &walk_state->operands[0];
225 union acpi_operand_object *return_desc = NULL;
226 union acpi_operand_object *return_desc2 = NULL;
227 u32 temp32;
228 u32 i;
229 u64 power_of_ten;
230 u64 digit;
231
232 ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_1T_1R,
233 acpi_ps_get_opcode_name(walk_state->opcode));
234
235
236
237 switch (walk_state->opcode) {
238 case AML_BIT_NOT_OP:
239 case AML_FIND_SET_LEFT_BIT_OP:
240 case AML_FIND_SET_RIGHT_BIT_OP:
241 case AML_FROM_BCD_OP:
242 case AML_TO_BCD_OP:
243 case AML_CONDITIONAL_REF_OF_OP:
244
245
246
247 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
248 if (!return_desc) {
249 status = AE_NO_MEMORY;
250 goto cleanup;
251 }
252
253 switch (walk_state->opcode) {
254 case AML_BIT_NOT_OP:
255
256 return_desc->integer.value = ~operand[0]->integer.value;
257 break;
258
259 case AML_FIND_SET_LEFT_BIT_OP:
260
261 return_desc->integer.value = operand[0]->integer.value;
262
263
264
265
266
267 for (temp32 = 0; return_desc->integer.value &&
268 temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
269 return_desc->integer.value >>= 1;
270 }
271
272 return_desc->integer.value = temp32;
273 break;
274
275 case AML_FIND_SET_RIGHT_BIT_OP:
276
277 return_desc->integer.value = operand[0]->integer.value;
278
279
280
281
282
283 for (temp32 = 0; return_desc->integer.value &&
284 temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
285 return_desc->integer.value <<= 1;
286 }
287
288
289
290 return_desc->integer.value =
291 temp32 ==
292 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - temp32;
293 break;
294
295 case AML_FROM_BCD_OP:
296
297
298
299
300
301 power_of_ten = 1;
302 return_desc->integer.value = 0;
303 digit = operand[0]->integer.value;
304
305
306
307 for (i = 0;
308 (i < acpi_gbl_integer_nybble_width) && (digit > 0);
309 i++) {
310
311
312
313 temp32 = ((u32) digit) & 0xF;
314
315
316
317 if (temp32 > 9) {
318 ACPI_ERROR((AE_INFO,
319 "BCD digit too large (not decimal): 0x%X",
320 temp32));
321
322 status = AE_AML_NUMERIC_OVERFLOW;
323 goto cleanup;
324 }
325
326
327
328 return_desc->integer.value +=
329 (((u64) temp32) * power_of_ten);
330
331
332
333 digit >>= 4;
334
335
336
337 power_of_ten *= 10;
338 }
339 break;
340
341 case AML_TO_BCD_OP:
342
343 return_desc->integer.value = 0;
344 digit = operand[0]->integer.value;
345
346
347
348 for (i = 0;
349 (i < acpi_gbl_integer_nybble_width) && (digit > 0);
350 i++) {
351 (void)acpi_ut_short_divide(digit, 10, &digit,
352 &temp32);
353
354
355
356
357
358 return_desc->integer.value |=
359 (((u64) temp32) << ACPI_MUL_4(i));
360 }
361
362
363
364 if (digit > 0) {
365 ACPI_ERROR((AE_INFO,
366 "Integer too large to convert to BCD: 0x%8.8X%8.8X",
367 ACPI_FORMAT_UINT64(operand[0]->
368 integer.value)));
369 status = AE_AML_NUMERIC_OVERFLOW;
370 goto cleanup;
371 }
372 break;
373
374 case AML_CONDITIONAL_REF_OF_OP:
375
376
377
378
379
380 if ((struct acpi_namespace_node *)operand[0] ==
381 acpi_gbl_root_node) {
382
383
384
385
386 return_desc->integer.value = 0;
387 goto cleanup;
388 }
389
390
391
392 status = acpi_ex_get_object_reference(operand[0],
393 &return_desc2,
394 walk_state);
395 if (ACPI_FAILURE(status)) {
396 goto cleanup;
397 }
398
399 status =
400 acpi_ex_store(return_desc2, operand[1], walk_state);
401 acpi_ut_remove_reference(return_desc2);
402
403
404
405 return_desc->integer.value = ACPI_UINT64_MAX;
406 goto cleanup;
407
408 default:
409
410
411
412 break;
413 }
414 break;
415
416 case AML_STORE_OP:
417
418
419
420
421
422 status = acpi_ex_store(operand[0], operand[1], walk_state);
423 if (ACPI_FAILURE(status)) {
424 return_ACPI_STATUS(status);
425 }
426
427
428
429 if (!walk_state->result_obj) {
430
431
432
433
434
435
436 walk_state->result_obj = operand[0];
437 walk_state->operands[0] = NULL;
438 }
439 return_ACPI_STATUS(status);
440
441
442
443
444 case AML_COPY_OBJECT_OP:
445
446 status =
447 acpi_ut_copy_iobject_to_iobject(operand[0], &return_desc,
448 walk_state);
449 break;
450
451 case AML_TO_DECIMAL_STRING_OP:
452
453 status =
454 acpi_ex_convert_to_string(operand[0], &return_desc,
455 ACPI_EXPLICIT_CONVERT_DECIMAL);
456 if (return_desc == operand[0]) {
457
458
459
460 acpi_ut_add_reference(return_desc);
461 }
462 break;
463
464 case AML_TO_HEX_STRING_OP:
465
466 status =
467 acpi_ex_convert_to_string(operand[0], &return_desc,
468 ACPI_EXPLICIT_CONVERT_HEX);
469 if (return_desc == operand[0]) {
470
471
472
473 acpi_ut_add_reference(return_desc);
474 }
475 break;
476
477 case AML_TO_BUFFER_OP:
478
479 status = acpi_ex_convert_to_buffer(operand[0], &return_desc);
480 if (return_desc == operand[0]) {
481
482
483
484 acpi_ut_add_reference(return_desc);
485 }
486 break;
487
488 case AML_TO_INTEGER_OP:
489
490
491
492 status =
493 acpi_ex_convert_to_integer(operand[0], &return_desc, 0);
494 if (return_desc == operand[0]) {
495
496
497
498 acpi_ut_add_reference(return_desc);
499 }
500 break;
501
502 case AML_SHIFT_LEFT_BIT_OP:
503 case AML_SHIFT_RIGHT_BIT_OP:
504
505
506
507 ACPI_ERROR((AE_INFO,
508 "%s is obsolete and not implemented",
509 acpi_ps_get_opcode_name(walk_state->opcode)));
510 status = AE_SUPPORT;
511 goto cleanup;
512
513 default:
514
515 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
516 walk_state->opcode));
517 status = AE_AML_BAD_OPCODE;
518 goto cleanup;
519 }
520
521 if (ACPI_SUCCESS(status)) {
522
523
524
525 status = acpi_ex_store(return_desc, operand[1], walk_state);
526 }
527
528cleanup:
529
530
531
532 if (ACPI_FAILURE(status)) {
533 acpi_ut_remove_reference(return_desc);
534 }
535
536
537
538 else if (!walk_state->result_obj) {
539 walk_state->result_obj = return_desc;
540 }
541
542 return_ACPI_STATUS(status);
543}
544
545
546
547
548
549
550
551
552
553
554
555
556
557acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
558{
559 union acpi_operand_object **operand = &walk_state->operands[0];
560 union acpi_operand_object *temp_desc;
561 union acpi_operand_object *return_desc = NULL;
562 acpi_status status = AE_OK;
563 u32 type;
564 u64 value;
565
566 ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_0T_1R,
567 acpi_ps_get_opcode_name(walk_state->opcode));
568
569
570
571 switch (walk_state->opcode) {
572 case AML_LOGICAL_NOT_OP:
573
574 return_desc = acpi_ut_create_integer_object((u64) 0);
575 if (!return_desc) {
576 status = AE_NO_MEMORY;
577 goto cleanup;
578 }
579
580
581
582
583
584 if (!operand[0]->integer.value) {
585 return_desc->integer.value = ACPI_UINT64_MAX;
586 }
587 break;
588
589 case AML_DECREMENT_OP:
590 case AML_INCREMENT_OP:
591
592
593
594
595 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
596 if (!return_desc) {
597 status = AE_NO_MEMORY;
598 goto cleanup;
599 }
600
601
602
603
604
605 temp_desc = operand[0];
606 if (ACPI_GET_DESCRIPTOR_TYPE(temp_desc) ==
607 ACPI_DESC_TYPE_OPERAND) {
608
609
610
611 acpi_ut_add_reference(temp_desc);
612 }
613
614
615
616
617
618
619
620
621 status = acpi_ex_resolve_operands(AML_LOGICAL_NOT_OP,
622 &temp_desc, walk_state);
623 if (ACPI_FAILURE(status)) {
624 ACPI_EXCEPTION((AE_INFO, status,
625 "While resolving operands for [%s]",
626 acpi_ps_get_opcode_name(walk_state->
627 opcode)));
628
629 goto cleanup;
630 }
631
632
633
634
635
636 if (walk_state->opcode == AML_INCREMENT_OP) {
637 return_desc->integer.value =
638 temp_desc->integer.value + 1;
639 } else {
640 return_desc->integer.value =
641 temp_desc->integer.value - 1;
642 }
643
644
645
646 acpi_ut_remove_reference(temp_desc);
647
648
649
650
651
652 status = acpi_ex_store(return_desc, operand[0], walk_state);
653 break;
654
655 case AML_OBJECT_TYPE_OP:
656
657
658
659
660
661
662
663
664
665 status =
666 acpi_ex_resolve_multiple(walk_state, operand[0], &type,
667 NULL);
668 if (ACPI_FAILURE(status)) {
669 goto cleanup;
670 }
671
672
673
674 return_desc = acpi_ut_create_integer_object((u64) type);
675 if (!return_desc) {
676 status = AE_NO_MEMORY;
677 goto cleanup;
678 }
679 break;
680
681 case AML_SIZE_OF_OP:
682
683
684
685
686
687
688
689 status =
690 acpi_ex_resolve_multiple(walk_state, operand[0], &type,
691 &temp_desc);
692 if (ACPI_FAILURE(status)) {
693 goto cleanup;
694 }
695
696
697
698
699
700
701
702
703
704
705 switch (type) {
706 case ACPI_TYPE_INTEGER:
707
708 value = acpi_gbl_integer_byte_width;
709 break;
710
711 case ACPI_TYPE_STRING:
712
713 value = temp_desc->string.length;
714 break;
715
716 case ACPI_TYPE_BUFFER:
717
718
719
720 status = acpi_ds_get_buffer_arguments(temp_desc);
721 value = temp_desc->buffer.length;
722 break;
723
724 case ACPI_TYPE_PACKAGE:
725
726
727
728 status = acpi_ds_get_package_arguments(temp_desc);
729 value = temp_desc->package.count;
730 break;
731
732 default:
733
734 ACPI_ERROR((AE_INFO,
735 "Operand must be Buffer/Integer/String/Package"
736 " - found type %s",
737 acpi_ut_get_type_name(type)));
738
739 status = AE_AML_OPERAND_TYPE;
740 goto cleanup;
741 }
742
743 if (ACPI_FAILURE(status)) {
744 goto cleanup;
745 }
746
747
748
749
750
751 return_desc = acpi_ut_create_integer_object(value);
752 if (!return_desc) {
753 status = AE_NO_MEMORY;
754 goto cleanup;
755 }
756 break;
757
758 case AML_REF_OF_OP:
759
760 status =
761 acpi_ex_get_object_reference(operand[0], &return_desc,
762 walk_state);
763 if (ACPI_FAILURE(status)) {
764 goto cleanup;
765 }
766 break;
767
768 case AML_DEREF_OF_OP:
769
770
771
772 if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) ==
773 ACPI_DESC_TYPE_NAMED) {
774 temp_desc =
775 acpi_ns_get_attached_object((struct
776 acpi_namespace_node *)
777 operand[0]);
778 if (temp_desc
779 && ((temp_desc->common.type == ACPI_TYPE_STRING)
780 || (temp_desc->common.type ==
781 ACPI_TYPE_LOCAL_REFERENCE))) {
782 operand[0] = temp_desc;
783 acpi_ut_add_reference(temp_desc);
784 } else {
785 status = AE_AML_OPERAND_TYPE;
786 goto cleanup;
787 }
788 } else {
789 switch ((operand[0])->common.type) {
790 case ACPI_TYPE_LOCAL_REFERENCE:
791
792
793
794
795
796 switch (operand[0]->reference.class) {
797 case ACPI_REFCLASS_LOCAL:
798 case ACPI_REFCLASS_ARG:
799
800
801
802 status =
803 acpi_ds_method_data_get_value
804 (operand[0]->reference.class,
805 operand[0]->reference.value,
806 walk_state, &temp_desc);
807 if (ACPI_FAILURE(status)) {
808 goto cleanup;
809 }
810
811
812
813
814
815 acpi_ut_remove_reference(operand[0]);
816 operand[0] = temp_desc;
817 break;
818
819 case ACPI_REFCLASS_REFOF:
820
821
822
823 temp_desc =
824 operand[0]->reference.object;
825 acpi_ut_remove_reference(operand[0]);
826 operand[0] = temp_desc;
827 break;
828
829 default:
830
831
832 break;
833 }
834 break;
835
836 case ACPI_TYPE_STRING:
837
838 break;
839
840 default:
841
842 status = AE_AML_OPERAND_TYPE;
843 goto cleanup;
844 }
845 }
846
847 if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) !=
848 ACPI_DESC_TYPE_NAMED) {
849 if ((operand[0])->common.type == ACPI_TYPE_STRING) {
850
851
852
853
854
855
856
857
858 status =
859 acpi_ns_get_node_unlocked(walk_state->
860 scope_info->scope.
861 node,
862 operand[0]->
863 string.pointer,
864 ACPI_NS_SEARCH_PARENT,
865 ACPI_CAST_INDIRECT_PTR
866 (struct
867 acpi_namespace_node,
868 &return_desc));
869 if (ACPI_FAILURE(status)) {
870 goto cleanup;
871 }
872
873 status =
874 acpi_ex_resolve_node_to_value
875 (ACPI_CAST_INDIRECT_PTR
876 (struct acpi_namespace_node, &return_desc),
877 walk_state);
878 goto cleanup;
879 }
880 }
881
882
883
884 if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) ==
885 ACPI_DESC_TYPE_NAMED) {
886
887
888
889
890
891
892
893 switch (((struct acpi_namespace_node *)operand[0])->
894 type) {
895 case ACPI_TYPE_DEVICE:
896 case ACPI_TYPE_THERMAL:
897
898
899
900 return_desc = operand[0];
901 break;
902
903 default:
904
905
906 return_desc = acpi_ns_get_attached_object((struct acpi_namespace_node *)operand[0]);
907 acpi_ut_add_reference(return_desc);
908 break;
909 }
910 } else {
911
912
913
914
915 switch (operand[0]->reference.class) {
916 case ACPI_REFCLASS_INDEX:
917
918
919
920
921 switch (operand[0]->reference.target_type) {
922 case ACPI_TYPE_BUFFER_FIELD:
923
924 temp_desc =
925 operand[0]->reference.object;
926
927
928
929
930
931
932
933
934
935
936
937
938
939 return_desc =
940 acpi_ut_create_integer_object((u64)
941 temp_desc->buffer.pointer[operand[0]->reference.value]);
942 if (!return_desc) {
943 status = AE_NO_MEMORY;
944 goto cleanup;
945 }
946 break;
947
948 case ACPI_TYPE_PACKAGE:
949
950
951
952
953 return_desc =
954 *(operand[0]->reference.where);
955 if (!return_desc) {
956
957
958
959
960
961 return_ACPI_STATUS
962 (AE_AML_UNINITIALIZED_ELEMENT);
963 }
964
965 acpi_ut_add_reference(return_desc);
966 break;
967
968 default:
969
970 ACPI_ERROR((AE_INFO,
971 "Unknown Index TargetType 0x%X in reference object %p",
972 operand[0]->reference.
973 target_type, operand[0]));
974
975 status = AE_AML_OPERAND_TYPE;
976 goto cleanup;
977 }
978 break;
979
980 case ACPI_REFCLASS_REFOF:
981
982 return_desc = operand[0]->reference.object;
983
984 if (ACPI_GET_DESCRIPTOR_TYPE(return_desc) ==
985 ACPI_DESC_TYPE_NAMED) {
986 return_desc =
987 acpi_ns_get_attached_object((struct
988 acpi_namespace_node
989 *)
990 return_desc);
991 if (!return_desc) {
992 break;
993 }
994
995
996
997
998
999 switch (return_desc->common.type) {
1000 case ACPI_TYPE_BUFFER_FIELD:
1001 case ACPI_TYPE_LOCAL_REGION_FIELD:
1002 case ACPI_TYPE_LOCAL_BANK_FIELD:
1003 case ACPI_TYPE_LOCAL_INDEX_FIELD:
1004
1005 status =
1006 acpi_ex_read_data_from_field
1007 (walk_state, return_desc,
1008 &temp_desc);
1009 if (ACPI_FAILURE(status)) {
1010 goto cleanup;
1011 }
1012
1013 return_desc = temp_desc;
1014 break;
1015
1016 default:
1017
1018
1019
1020 acpi_ut_add_reference
1021 (return_desc);
1022 break;
1023 }
1024 }
1025 break;
1026
1027 default:
1028
1029 ACPI_ERROR((AE_INFO,
1030 "Unknown class in reference(%p) - 0x%2.2X",
1031 operand[0],
1032 operand[0]->reference.class));
1033
1034 status = AE_TYPE;
1035 goto cleanup;
1036 }
1037 }
1038 break;
1039
1040 default:
1041
1042 ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
1043 walk_state->opcode));
1044
1045 status = AE_AML_BAD_OPCODE;
1046 goto cleanup;
1047 }
1048
1049cleanup:
1050
1051
1052
1053 if (ACPI_FAILURE(status)) {
1054 acpi_ut_remove_reference(return_desc);
1055 }
1056
1057
1058
1059 else {
1060 walk_state->result_obj = return_desc;
1061 }
1062
1063 return_ACPI_STATUS(status);
1064}
1065