Merge trunk HEAD (r46369)
[reactos.git] / reactos / drivers / bus / acpi / executer / amdyadic.c
1 /******************************************************************************
2 *
3 * Module Name: amdyadic - ACPI AML (p-code) execution for dyadic operators
4 * $Revision: 1.1 $
5 *
6 *****************************************************************************/
7
8 /*
9 * Copyright (C) 2000, 2001 R. Byron Moore
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26
27 #include <acpi.h>
28
29
30
31 #define _COMPONENT ACPI_EXECUTER
32 MODULE_NAME ("amdyadic")
33
34
35 /*******************************************************************************
36 *
37 * FUNCTION: Acpi_aml_do_concatenate
38 *
39 * PARAMETERS: *Obj_desc - Object to be converted. Must be an
40 * Integer, Buffer, or String
41 *
42 * RETURN: Status
43 *
44 * DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
45 *
46 ******************************************************************************/
47
48 ACPI_STATUS
49 acpi_aml_do_concatenate (
50 ACPI_OPERAND_OBJECT *obj_desc,
51 ACPI_OPERAND_OBJECT *obj_desc2,
52 ACPI_OPERAND_OBJECT **actual_ret_desc,
53 ACPI_WALK_STATE *walk_state)
54 {
55 ACPI_STATUS status;
56 u32 i;
57 ACPI_INTEGER this_integer;
58 ACPI_OPERAND_OBJECT *ret_desc;
59 NATIVE_CHAR *new_buf;
60 u32 integer_size = sizeof (ACPI_INTEGER);
61
62
63 /*
64 * There are three cases to handle:
65 * 1) Two Integers concatenated to produce a buffer
66 * 2) Two Strings concatenated to produce a string
67 * 3) Two Buffers concatenated to produce a buffer
68 */
69 switch (obj_desc->common.type) {
70 case ACPI_TYPE_INTEGER:
71
72 /* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
73
74 if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
75 /*
76 * We are running a method that exists in a 32-bit ACPI table.
77 * Truncate the value to 32 bits by zeroing out the upper
78 * 32-bit field
79 */
80 integer_size = sizeof (u32);
81 }
82
83 /* Result of two integers is a buffer */
84
85 ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_BUFFER);
86 if (!ret_desc) {
87 return (AE_NO_MEMORY);
88 }
89
90 /* Need enough space for two integers */
91
92 ret_desc->buffer.length = integer_size * 2;
93 new_buf = acpi_cm_callocate (ret_desc->buffer.length);
94 if (!new_buf) {
95 REPORT_ERROR
96 (("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n"));
97 status = AE_NO_MEMORY;
98 goto cleanup;
99 }
100
101 ret_desc->buffer.pointer = (u8 *) new_buf;
102
103 /* Convert the first integer */
104
105 this_integer = obj_desc->integer.value;
106 for (i = 0; i < integer_size; i++) {
107 new_buf[i] = (u8) this_integer;
108 this_integer >>= 8;
109 }
110
111 /* Convert the second integer */
112
113 this_integer = obj_desc2->integer.value;
114 for (; i < (integer_size * 2); i++) {
115 new_buf[i] = (u8) this_integer;
116 this_integer >>= 8;
117 }
118
119 break;
120
121
122 case ACPI_TYPE_STRING:
123
124 ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_STRING);
125 if (!ret_desc) {
126 return (AE_NO_MEMORY);
127 }
128
129 /* Operand1 is string */
130
131 new_buf = acpi_cm_allocate (obj_desc->string.length +
132 obj_desc2->string.length + 1);
133 if (!new_buf) {
134 REPORT_ERROR
135 (("Aml_exec_dyadic2_r/Concat_op: String allocation failure\n"));
136 status = AE_NO_MEMORY;
137 goto cleanup;
138 }
139
140 STRCPY (new_buf, obj_desc->string.pointer);
141 STRCPY (new_buf + obj_desc->string.length,
142 obj_desc2->string.pointer);
143
144 /* Point the return object to the new string */
145
146 ret_desc->string.pointer = new_buf;
147 ret_desc->string.length = obj_desc->string.length +=
148 obj_desc2->string.length;
149 break;
150
151
152 case ACPI_TYPE_BUFFER:
153
154 /* Operand1 is a buffer */
155
156 ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_BUFFER);
157 if (!ret_desc) {
158 return (AE_NO_MEMORY);
159 }
160
161 new_buf = acpi_cm_allocate (obj_desc->buffer.length +
162 obj_desc2->buffer.length);
163 if (!new_buf) {
164 REPORT_ERROR
165 (("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n"));
166 status = AE_NO_MEMORY;
167 goto cleanup;
168 }
169
170 MEMCPY (new_buf, obj_desc->buffer.pointer,
171 obj_desc->buffer.length);
172 MEMCPY (new_buf + obj_desc->buffer.length, obj_desc2->buffer.pointer,
173 obj_desc2->buffer.length);
174
175 /*
176 * Point the return object to the new buffer
177 */
178
179 ret_desc->buffer.pointer = (u8 *) new_buf;
180 ret_desc->buffer.length = obj_desc->buffer.length +
181 obj_desc2->buffer.length;
182 break;
183
184 default:
185 status = AE_AML_INTERNAL;
186 ret_desc = NULL;
187 }
188
189
190 *actual_ret_desc = ret_desc;
191 return (AE_OK);
192
193
194 cleanup:
195
196 acpi_cm_remove_reference (ret_desc);
197 return (status);
198 }
199
200
201 /*******************************************************************************
202 *
203 * FUNCTION: Acpi_aml_exec_dyadic1
204 *
205 * PARAMETERS: Opcode - The opcode to be executed
206 *
207 * RETURN: Status
208 *
209 * DESCRIPTION: Execute Type 1 dyadic operator with numeric operands:
210 * Notify_op
211 *
212 * ALLOCATION: Deletes both operands
213 *
214 ******************************************************************************/
215
216 ACPI_STATUS
217 acpi_aml_exec_dyadic1 (
218 u16 opcode,
219 ACPI_WALK_STATE *walk_state)
220 {
221 ACPI_OPERAND_OBJECT *obj_desc = NULL;
222 ACPI_OPERAND_OBJECT *val_desc = NULL;
223 ACPI_NAMESPACE_NODE *node;
224 ACPI_STATUS status = AE_OK;
225
226
227 /* Resolve all operands */
228
229 status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
230 /* Get the operands */
231
232 status |= acpi_ds_obj_stack_pop_object (&val_desc, walk_state);
233 status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
234 if (ACPI_FAILURE (status)) {
235 /* Invalid parameters on object stack */
236
237 goto cleanup;
238 }
239
240
241 /* Examine the opcode */
242
243 switch (opcode) {
244
245 /* Def_notify := Notify_op Notify_object Notify_value */
246
247 case AML_NOTIFY_OP:
248
249 /* The Obj_desc is actually an Node */
250
251 node = (ACPI_NAMESPACE_NODE *) obj_desc;
252 obj_desc = NULL;
253
254 /* Object must be a device or thermal zone */
255
256 if (node && val_desc) {
257 switch (node->type) {
258 case ACPI_TYPE_DEVICE:
259 case ACPI_TYPE_THERMAL:
260
261 /*
262 * Dispatch the notify to the appropriate handler
263 * NOTE: the request is queued for execution after this method
264 * completes. The notify handlers are NOT invoked synchronously
265 * from this thread -- because handlers may in turn run other
266 * control methods.
267 */
268
269 status = acpi_ev_queue_notify_request (node,
270 (u32) val_desc->integer.value);
271 break;
272
273 default:
274 status = AE_AML_OPERAND_TYPE;
275 break;
276 }
277 }
278 break;
279
280 default:
281
282 REPORT_ERROR (("Acpi_aml_exec_dyadic1: Unknown dyadic opcode %X\n",
283 opcode));
284 status = AE_AML_BAD_OPCODE;
285 }
286
287
288 cleanup:
289
290 /* Always delete both operands */
291
292 acpi_cm_remove_reference (val_desc);
293 acpi_cm_remove_reference (obj_desc);
294
295
296 return (status);
297 }
298
299
300 /*******************************************************************************
301 *
302 * FUNCTION: Acpi_aml_exec_dyadic2_r
303 *
304 * PARAMETERS: Opcode - The opcode to be executed
305 *
306 * RETURN: Status
307 *
308 * DESCRIPTION: Execute Type 2 dyadic operator with numeric operands and
309 * one or two result operands.
310 *
311 * ALLOCATION: Deletes one operand descriptor -- other remains on stack
312 *
313 ******************************************************************************/
314
315 ACPI_STATUS
316 acpi_aml_exec_dyadic2_r (
317 u16 opcode,
318 ACPI_WALK_STATE *walk_state,
319 ACPI_OPERAND_OBJECT **return_desc)
320 {
321 ACPI_OPERAND_OBJECT *obj_desc = NULL;
322 ACPI_OPERAND_OBJECT *obj_desc2 = NULL;
323 ACPI_OPERAND_OBJECT *res_desc = NULL;
324 ACPI_OPERAND_OBJECT *res_desc2 = NULL;
325 ACPI_OPERAND_OBJECT *ret_desc = NULL;
326 ACPI_OPERAND_OBJECT *ret_desc2 = NULL;
327 ACPI_STATUS status = AE_OK;
328 u32 num_operands = 3;
329
330
331 /* Resolve all operands */
332
333 status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
334 /* Get all operands */
335
336 if (AML_DIVIDE_OP == opcode) {
337 num_operands = 4;
338 status |= acpi_ds_obj_stack_pop_object (&res_desc2, walk_state);
339 }
340
341 status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state);
342 status |= acpi_ds_obj_stack_pop_object (&obj_desc2, walk_state);
343 status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
344 if (ACPI_FAILURE (status)) {
345 goto cleanup;
346 }
347
348
349 /* Create an internal return object if necessary */
350
351 switch (opcode) {
352 case AML_ADD_OP:
353 case AML_BIT_AND_OP:
354 case AML_BIT_NAND_OP:
355 case AML_BIT_OR_OP:
356 case AML_BIT_NOR_OP:
357 case AML_BIT_XOR_OP:
358 case AML_DIVIDE_OP:
359 case AML_MULTIPLY_OP:
360 case AML_SHIFT_LEFT_OP:
361 case AML_SHIFT_RIGHT_OP:
362 case AML_SUBTRACT_OP:
363
364 ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
365 if (!ret_desc) {
366 status = AE_NO_MEMORY;
367 goto cleanup;
368 }
369
370 break;
371 }
372
373
374 /*
375 * Execute the opcode
376 */
377
378 switch (opcode) {
379
380 /* Def_add := Add_op Operand1 Operand2 Result */
381
382 case AML_ADD_OP:
383
384 ret_desc->integer.value = obj_desc->integer.value +
385 obj_desc2->integer.value;
386 break;
387
388
389 /* Def_and := And_op Operand1 Operand2 Result */
390
391 case AML_BIT_AND_OP:
392
393 ret_desc->integer.value = obj_desc->integer.value &
394 obj_desc2->integer.value;
395 break;
396
397
398 /* Def_nAnd := NAnd_op Operand1 Operand2 Result */
399
400 case AML_BIT_NAND_OP:
401
402 ret_desc->integer.value = ~(obj_desc->integer.value &
403 obj_desc2->integer.value);
404 break;
405
406
407 /* Def_or := Or_op Operand1 Operand2 Result */
408
409 case AML_BIT_OR_OP:
410
411 ret_desc->integer.value = obj_desc->integer.value |
412 obj_desc2->integer.value;
413 break;
414
415
416 /* Def_nOr := NOr_op Operand1 Operand2 Result */
417
418 case AML_BIT_NOR_OP:
419
420 ret_desc->integer.value = ~(obj_desc->integer.value |
421 obj_desc2->integer.value);
422 break;
423
424
425 /* Def_xOr := XOr_op Operand1 Operand2 Result */
426
427 case AML_BIT_XOR_OP:
428
429 ret_desc->integer.value = obj_desc->integer.value ^
430 obj_desc2->integer.value;
431 break;
432
433
434 /* Def_divide := Divide_op Dividend Divisor Remainder Quotient */
435
436 case AML_DIVIDE_OP:
437
438 if (!obj_desc2->integer.value) {
439 REPORT_ERROR
440 (("Aml_exec_dyadic2_r/Divide_op: Divide by zero\n"));
441
442 status = AE_AML_DIVIDE_BY_ZERO;
443 goto cleanup;
444 }
445
446 ret_desc2 = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
447 if (!ret_desc2) {
448 status = AE_NO_MEMORY;
449 goto cleanup;
450 }
451
452 /* Remainder (modulo) */
453
454 ret_desc->integer.value = ACPI_MODULO (obj_desc->integer.value,
455 obj_desc2->integer.value);
456
457 /* Result (what we used to call the quotient) */
458
459 ret_desc2->integer.value = ACPI_DIVIDE (obj_desc->integer.value,
460 obj_desc2->integer.value);
461 break;
462
463
464 /* Def_multiply := Multiply_op Operand1 Operand2 Result */
465
466 case AML_MULTIPLY_OP:
467
468 ret_desc->integer.value = obj_desc->integer.value *
469 obj_desc2->integer.value;
470 break;
471
472
473 /* Def_shift_left := Shift_left_op Operand Shift_count Result */
474
475 case AML_SHIFT_LEFT_OP:
476
477 ret_desc->integer.value = obj_desc->integer.value <<
478 obj_desc2->integer.value;
479 break;
480
481
482 /* Def_shift_right := Shift_right_op Operand Shift_count Result */
483
484 case AML_SHIFT_RIGHT_OP:
485
486 ret_desc->integer.value = obj_desc->integer.value >>
487 obj_desc2->integer.value;
488 break;
489
490
491 /* Def_subtract := Subtract_op Operand1 Operand2 Result */
492
493 case AML_SUBTRACT_OP:
494
495 ret_desc->integer.value = obj_desc->integer.value -
496 obj_desc2->integer.value;
497 break;
498
499
500 /* Def_concat := Concat_op Data1 Data2 Result */
501
502 case AML_CONCAT_OP:
503
504
505 /*
506 * Convert the second operand if necessary. The first operand
507 * determines the type of the second operand, (See the Data Types
508 * section of the ACPI specification.) Both object types are
509 * guaranteed to be either Integer/String/Buffer by the operand
510 * resolution mechanism above.
511 */
512
513 switch (obj_desc->common.type) {
514 case ACPI_TYPE_INTEGER:
515 status = acpi_aml_convert_to_integer (&obj_desc2, walk_state);
516 break;
517
518 case ACPI_TYPE_STRING:
519 status = acpi_aml_convert_to_string (&obj_desc2, walk_state);
520 break;
521
522 case ACPI_TYPE_BUFFER:
523 status = acpi_aml_convert_to_buffer (&obj_desc2, walk_state);
524 break;
525
526 default:
527 status = AE_AML_INTERNAL;
528 }
529
530 if (ACPI_FAILURE (status)) {
531 goto cleanup;
532 }
533
534
535 /*
536 * Both operands are now known to be the same object type
537 * (Both are Integer, String, or Buffer), and we can now perform the
538 * concatenation.
539 */
540 status = acpi_aml_do_concatenate (obj_desc, obj_desc2, &ret_desc, walk_state);
541 if (ACPI_FAILURE (status)) {
542 goto cleanup;
543 }
544 break;
545
546
547 default:
548
549 REPORT_ERROR (("Acpi_aml_exec_dyadic2_r: Unknown dyadic opcode %X\n",
550 opcode));
551 status = AE_AML_BAD_OPCODE;
552 goto cleanup;
553 }
554
555
556 /*
557 * Store the result of the operation (which is now in Obj_desc) into
558 * the result descriptor, or the location pointed to by the result
559 * descriptor (Res_desc).
560 */
561
562 status = acpi_aml_exec_store (ret_desc, res_desc, walk_state);
563 if (ACPI_FAILURE (status)) {
564 goto cleanup;
565 }
566
567 if (AML_DIVIDE_OP == opcode) {
568 status = acpi_aml_exec_store (ret_desc2, res_desc2, walk_state);
569
570 /*
571 * Since the remainder is not returned, remove a reference to
572 * the object we created earlier
573 */
574
575 acpi_cm_remove_reference (ret_desc2);
576 }
577
578
579 cleanup:
580
581 /* Always delete the operands */
582
583 acpi_cm_remove_reference (obj_desc);
584 acpi_cm_remove_reference (obj_desc2);
585
586
587 /* Delete return object on error */
588
589 if (ACPI_FAILURE (status)) {
590 /* On failure, delete the result ops */
591
592 acpi_cm_remove_reference (res_desc);
593 acpi_cm_remove_reference (res_desc2);
594
595 if (ret_desc) {
596 /* And delete the internal return object */
597
598 acpi_cm_remove_reference (ret_desc);
599 ret_desc = NULL;
600 }
601 }
602
603 /* Set the return object and exit */
604
605 *return_desc = ret_desc;
606 return (status);
607 }
608
609
610 /*******************************************************************************
611 *
612 * FUNCTION: Acpi_aml_exec_dyadic2_s
613 *
614 * PARAMETERS: Opcode - The opcode to be executed
615 *
616 * RETURN: Status
617 *
618 * DESCRIPTION: Execute Type 2 dyadic synchronization operator
619 *
620 * ALLOCATION: Deletes one operand descriptor -- other remains on stack
621 *
622 ******************************************************************************/
623
624 ACPI_STATUS
625 acpi_aml_exec_dyadic2_s (
626 u16 opcode,
627 ACPI_WALK_STATE *walk_state,
628 ACPI_OPERAND_OBJECT **return_desc)
629 {
630 ACPI_OPERAND_OBJECT *obj_desc;
631 ACPI_OPERAND_OBJECT *time_desc;
632 ACPI_OPERAND_OBJECT *ret_desc = NULL;
633 ACPI_STATUS status;
634
635
636 /* Resolve all operands */
637
638 status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
639 /* Get all operands */
640
641 status |= acpi_ds_obj_stack_pop_object (&time_desc, walk_state);
642 status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
643 if (ACPI_FAILURE (status)) {
644 /* Invalid parameters on object stack */
645
646 goto cleanup;
647 }
648
649
650 /* Create the internal return object */
651
652 ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
653 if (!ret_desc) {
654 status = AE_NO_MEMORY;
655 goto cleanup;
656 }
657
658 /* Default return value is FALSE, operation did not time out */
659
660 ret_desc->integer.value = 0;
661
662
663 /* Examine the opcode */
664
665 switch (opcode) {
666
667 /* Def_acquire := Acquire_op Mutex_object Timeout */
668
669 case AML_ACQUIRE_OP:
670
671 status = acpi_aml_acquire_mutex (time_desc, obj_desc, walk_state);
672 break;
673
674
675 /* Def_wait := Wait_op Acpi_event_object Timeout */
676
677 case AML_WAIT_OP:
678
679 status = acpi_aml_system_wait_event (time_desc, obj_desc);
680 break;
681
682
683 default:
684
685 REPORT_ERROR (("Acpi_aml_exec_dyadic2_s: Unknown dyadic synchronization opcode %X\n", opcode));
686 status = AE_AML_BAD_OPCODE;
687 goto cleanup;
688 }
689
690
691 /*
692 * Return a boolean indicating if operation timed out
693 * (TRUE) or not (FALSE)
694 */
695
696 if (status == AE_TIME) {
697 ret_desc->integer.value = ACPI_INTEGER_MAX; /* TRUE, op timed out */
698 status = AE_OK;
699 }
700
701
702 cleanup:
703
704 /* Delete params */
705
706 acpi_cm_remove_reference (time_desc);
707 acpi_cm_remove_reference (obj_desc);
708
709 /* Delete return object on error */
710
711 if (ACPI_FAILURE (status) &&
712 (ret_desc)) {
713 acpi_cm_remove_reference (ret_desc);
714 ret_desc = NULL;
715 }
716
717
718 /* Set the return object and exit */
719
720 *return_desc = ret_desc;
721 return (status);
722 }
723
724
725 /*******************************************************************************
726 *
727 * FUNCTION: Acpi_aml_exec_dyadic2
728 *
729 * PARAMETERS: Opcode - The opcode to be executed
730 *
731 * RETURN: Status
732 *
733 * DESCRIPTION: Execute Type 2 dyadic operator with numeric operands and
734 * no result operands
735 *
736 * ALLOCATION: Deletes one operand descriptor -- other remains on stack
737 * containing result value
738 *
739 ******************************************************************************/
740
741 ACPI_STATUS
742 acpi_aml_exec_dyadic2 (
743 u16 opcode,
744 ACPI_WALK_STATE *walk_state,
745 ACPI_OPERAND_OBJECT **return_desc)
746 {
747 ACPI_OPERAND_OBJECT *obj_desc;
748 ACPI_OPERAND_OBJECT *obj_desc2;
749 ACPI_OPERAND_OBJECT *ret_desc = NULL;
750 ACPI_STATUS status;
751 u8 lboolean;
752
753
754 /* Resolve all operands */
755
756 status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
757 /* Get all operands */
758
759 status |= acpi_ds_obj_stack_pop_object (&obj_desc2, walk_state);
760 status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
761 if (ACPI_FAILURE (status)) {
762 /* Invalid parameters on object stack */
763
764 goto cleanup;
765 }
766
767
768 /* Create the internal return object */
769
770 ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
771 if (!ret_desc) {
772 status = AE_NO_MEMORY;
773 goto cleanup;
774 }
775
776 /*
777 * Execute the Opcode
778 */
779
780 lboolean = FALSE;
781 switch (opcode) {
782
783 /* Def_lAnd := LAnd_op Operand1 Operand2 */
784
785 case AML_LAND_OP:
786
787 lboolean = (u8) (obj_desc->integer.value &&
788 obj_desc2->integer.value);
789 break;
790
791
792 /* Def_lEqual := LEqual_op Operand1 Operand2 */
793
794 case AML_LEQUAL_OP:
795
796 lboolean = (u8) (obj_desc->integer.value ==
797 obj_desc2->integer.value);
798 break;
799
800
801 /* Def_lGreater := LGreater_op Operand1 Operand2 */
802
803 case AML_LGREATER_OP:
804
805 lboolean = (u8) (obj_desc->integer.value >
806 obj_desc2->integer.value);
807 break;
808
809
810 /* Def_lLess := LLess_op Operand1 Operand2 */
811
812 case AML_LLESS_OP:
813
814 lboolean = (u8) (obj_desc->integer.value <
815 obj_desc2->integer.value);
816 break;
817
818
819 /* Def_lOr := LOr_op Operand1 Operand2 */
820
821 case AML_LOR_OP:
822
823 lboolean = (u8) (obj_desc->integer.value ||
824 obj_desc2->integer.value);
825 break;
826
827
828 default:
829
830 REPORT_ERROR (("Acpi_aml_exec_dyadic2: Unknown dyadic opcode %X\n", opcode));
831 status = AE_AML_BAD_OPCODE;
832 goto cleanup;
833 break;
834 }
835
836
837 /* Set return value to logical TRUE (all ones) or FALSE (zero) */
838
839 if (lboolean) {
840 ret_desc->integer.value = ACPI_INTEGER_MAX;
841 }
842 else {
843 ret_desc->integer.value = 0;
844 }
845
846
847 cleanup:
848
849 /* Always delete operands */
850
851 acpi_cm_remove_reference (obj_desc);
852 acpi_cm_remove_reference (obj_desc2);
853
854
855 /* Delete return object on error */
856
857 if (ACPI_FAILURE (status) &&
858 (ret_desc)) {
859 acpi_cm_remove_reference (ret_desc);
860 ret_desc = NULL;
861 }
862
863
864 /* Set the return object and exit */
865
866 *return_desc = ret_desc;
867 return (status);
868 }
869
870