xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/executer/exoparg1.c (revision ca8ed5ea660fb6275799a3b7f138b201c41a667b)
1 /******************************************************************************
2  *
3  * Module Name: exoparg1 - AML execution - opcodes with 1 argument
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2014, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115 
116 #define __EXOPARG1_C__
117 
118 #include "acpi.h"
119 #include "accommon.h"
120 #include "acparser.h"
121 #include "acdispat.h"
122 #include "acinterp.h"
123 #include "amlcode.h"
124 #include "acnamesp.h"
125 
126 
127 #define _COMPONENT          ACPI_EXECUTER
128         ACPI_MODULE_NAME    ("exoparg1")
129 
130 
131 /*!
132  * Naming convention for AML interpreter execution routines.
133  *
134  * The routines that begin execution of AML opcodes are named with a common
135  * convention based upon the number of arguments, the number of target operands,
136  * and whether or not a value is returned:
137  *
138  *      AcpiExOpcode_xA_yT_zR
139  *
140  * Where:
141  *
142  * xA - ARGUMENTS:    The number of arguments (input operands) that are
143  *                    required for this opcode type (0 through 6 args).
144  * yT - TARGETS:      The number of targets (output operands) that are required
145  *                    for this opcode type (0, 1, or 2 targets).
146  * zR - RETURN VALUE: Indicates whether this opcode type returns a value
147  *                    as the function return (0 or 1).
148  *
149  * The AcpiExOpcode* functions are called via the Dispatcher component with
150  * fully resolved operands.
151 !*/
152 
153 /*******************************************************************************
154  *
155  * FUNCTION:    AcpiExOpcode_0A_0T_1R
156  *
157  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
158  *
159  * RETURN:      Status
160  *
161  * DESCRIPTION: Execute operator with no operands, one return value
162  *
163  ******************************************************************************/
164 
165 ACPI_STATUS
166 AcpiExOpcode_0A_0T_1R (
167     ACPI_WALK_STATE         *WalkState)
168 {
169     ACPI_STATUS             Status = AE_OK;
170     ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
171 
172 
173     ACPI_FUNCTION_TRACE_STR (ExOpcode_0A_0T_1R,
174         AcpiPsGetOpcodeName (WalkState->Opcode));
175 
176 
177     /* Examine the AML opcode */
178 
179     switch (WalkState->Opcode)
180     {
181     case AML_TIMER_OP:      /*  Timer () */
182 
183         /* Create a return object of type Integer */
184 
185         ReturnDesc = AcpiUtCreateIntegerObject (AcpiOsGetTimer ());
186         if (!ReturnDesc)
187         {
188             Status = AE_NO_MEMORY;
189             goto Cleanup;
190         }
191         break;
192 
193     default:                /*  Unknown opcode  */
194 
195         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
196             WalkState->Opcode));
197         Status = AE_AML_BAD_OPCODE;
198         break;
199     }
200 
201 Cleanup:
202 
203     /* Delete return object on error */
204 
205     if ((ACPI_FAILURE (Status)) || WalkState->ResultObj)
206     {
207         AcpiUtRemoveReference (ReturnDesc);
208         WalkState->ResultObj = NULL;
209     }
210     else
211     {
212         /* Save the return value */
213 
214         WalkState->ResultObj = ReturnDesc;
215     }
216 
217     return_ACPI_STATUS (Status);
218 }
219 
220 
221 /*******************************************************************************
222  *
223  * FUNCTION:    AcpiExOpcode_1A_0T_0R
224  *
225  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
226  *
227  * RETURN:      Status
228  *
229  * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
230  *              object stack
231  *
232  ******************************************************************************/
233 
234 ACPI_STATUS
235 AcpiExOpcode_1A_0T_0R (
236     ACPI_WALK_STATE         *WalkState)
237 {
238     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
239     ACPI_STATUS             Status = AE_OK;
240 
241 
242     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_0R,
243         AcpiPsGetOpcodeName (WalkState->Opcode));
244 
245 
246     /* Examine the AML opcode */
247 
248     switch (WalkState->Opcode)
249     {
250     case AML_RELEASE_OP:    /*  Release (MutexObject) */
251 
252         Status = AcpiExReleaseMutex (Operand[0], WalkState);
253         break;
254 
255     case AML_RESET_OP:      /*  Reset (EventObject) */
256 
257         Status = AcpiExSystemResetEvent (Operand[0]);
258         break;
259 
260     case AML_SIGNAL_OP:     /*  Signal (EventObject) */
261 
262         Status = AcpiExSystemSignalEvent (Operand[0]);
263         break;
264 
265     case AML_SLEEP_OP:      /*  Sleep (MsecTime) */
266 
267         Status = AcpiExSystemDoSleep (Operand[0]->Integer.Value);
268         break;
269 
270     case AML_STALL_OP:      /*  Stall (UsecTime) */
271 
272         Status = AcpiExSystemDoStall ((UINT32) Operand[0]->Integer.Value);
273         break;
274 
275     case AML_UNLOAD_OP:     /*  Unload (Handle) */
276 
277         Status = AcpiExUnloadTable (Operand[0]);
278         break;
279 
280     default:                /*  Unknown opcode  */
281 
282         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
283             WalkState->Opcode));
284         Status = AE_AML_BAD_OPCODE;
285         break;
286     }
287 
288     return_ACPI_STATUS (Status);
289 }
290 
291 
292 /*******************************************************************************
293  *
294  * FUNCTION:    AcpiExOpcode_1A_1T_0R
295  *
296  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
297  *
298  * RETURN:      Status
299  *
300  * DESCRIPTION: Execute opcode with one argument, one target, and no
301  *              return value.
302  *
303  ******************************************************************************/
304 
305 ACPI_STATUS
306 AcpiExOpcode_1A_1T_0R (
307     ACPI_WALK_STATE         *WalkState)
308 {
309     ACPI_STATUS             Status = AE_OK;
310     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
311 
312 
313     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_0R,
314         AcpiPsGetOpcodeName (WalkState->Opcode));
315 
316 
317     /* Examine the AML opcode */
318 
319     switch (WalkState->Opcode)
320     {
321     case AML_LOAD_OP:
322 
323         Status = AcpiExLoadOp (Operand[0], Operand[1], WalkState);
324         break;
325 
326     default:                        /* Unknown opcode */
327 
328         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
329             WalkState->Opcode));
330         Status = AE_AML_BAD_OPCODE;
331         goto Cleanup;
332     }
333 
334 
335 Cleanup:
336 
337     return_ACPI_STATUS (Status);
338 }
339 
340 
341 /*******************************************************************************
342  *
343  * FUNCTION:    AcpiExOpcode_1A_1T_1R
344  *
345  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
346  *
347  * RETURN:      Status
348  *
349  * DESCRIPTION: Execute opcode with one argument, one target, and a
350  *              return value.
351  *
352  ******************************************************************************/
353 
354 ACPI_STATUS
355 AcpiExOpcode_1A_1T_1R (
356     ACPI_WALK_STATE         *WalkState)
357 {
358     ACPI_STATUS             Status = AE_OK;
359     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
360     ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
361     ACPI_OPERAND_OBJECT     *ReturnDesc2 = NULL;
362     UINT32                  Temp32;
363     UINT32                  i;
364     UINT64                  PowerOfTen;
365     UINT64                  Digit;
366 
367 
368     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_1R,
369         AcpiPsGetOpcodeName (WalkState->Opcode));
370 
371 
372     /* Examine the AML opcode */
373 
374     switch (WalkState->Opcode)
375     {
376     case AML_BIT_NOT_OP:
377     case AML_FIND_SET_LEFT_BIT_OP:
378     case AML_FIND_SET_RIGHT_BIT_OP:
379     case AML_FROM_BCD_OP:
380     case AML_TO_BCD_OP:
381     case AML_COND_REF_OF_OP:
382 
383         /* Create a return object of type Integer for these opcodes */
384 
385         ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
386         if (!ReturnDesc)
387         {
388             Status = AE_NO_MEMORY;
389             goto Cleanup;
390         }
391 
392         switch (WalkState->Opcode)
393         {
394         case AML_BIT_NOT_OP:            /* Not (Operand, Result)  */
395 
396             ReturnDesc->Integer.Value = ~Operand[0]->Integer.Value;
397             break;
398 
399         case AML_FIND_SET_LEFT_BIT_OP:  /* FindSetLeftBit (Operand, Result) */
400 
401             ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
402 
403             /*
404              * Acpi specification describes Integer type as a little
405              * endian unsigned value, so this boundary condition is valid.
406              */
407             for (Temp32 = 0; ReturnDesc->Integer.Value &&
408                              Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
409             {
410                 ReturnDesc->Integer.Value >>= 1;
411             }
412 
413             ReturnDesc->Integer.Value = Temp32;
414             break;
415 
416         case AML_FIND_SET_RIGHT_BIT_OP: /* FindSetRightBit (Operand, Result) */
417 
418             ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
419 
420             /*
421              * The Acpi specification describes Integer type as a little
422              * endian unsigned value, so this boundary condition is valid.
423              */
424             for (Temp32 = 0; ReturnDesc->Integer.Value &&
425                              Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
426             {
427                 ReturnDesc->Integer.Value <<= 1;
428             }
429 
430             /* Since the bit position is one-based, subtract from 33 (65) */
431 
432             ReturnDesc->Integer.Value =
433                 Temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - Temp32;
434             break;
435 
436         case AML_FROM_BCD_OP:           /* FromBcd (BCDValue, Result)  */
437             /*
438              * The 64-bit ACPI integer can hold 16 4-bit BCD characters
439              * (if table is 32-bit, integer can hold 8 BCD characters)
440              * Convert each 4-bit BCD value
441              */
442             PowerOfTen = 1;
443             ReturnDesc->Integer.Value = 0;
444             Digit = Operand[0]->Integer.Value;
445 
446             /* Convert each BCD digit (each is one nybble wide) */
447 
448             for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
449             {
450                 /* Get the least significant 4-bit BCD digit */
451 
452                 Temp32 = ((UINT32) Digit) & 0xF;
453 
454                 /* Check the range of the digit */
455 
456                 if (Temp32 > 9)
457                 {
458                     ACPI_ERROR ((AE_INFO,
459                         "BCD digit too large (not decimal): 0x%X",
460                         Temp32));
461 
462                     Status = AE_AML_NUMERIC_OVERFLOW;
463                     goto Cleanup;
464                 }
465 
466                 /* Sum the digit into the result with the current power of 10 */
467 
468                 ReturnDesc->Integer.Value +=
469                     (((UINT64) Temp32) * PowerOfTen);
470 
471                 /* Shift to next BCD digit */
472 
473                 Digit >>= 4;
474 
475                 /* Next power of 10 */
476 
477                 PowerOfTen *= 10;
478             }
479             break;
480 
481         case AML_TO_BCD_OP:             /* ToBcd (Operand, Result)  */
482 
483             ReturnDesc->Integer.Value = 0;
484             Digit = Operand[0]->Integer.Value;
485 
486             /* Each BCD digit is one nybble wide */
487 
488             for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
489             {
490                 (void) AcpiUtShortDivide (Digit, 10, &Digit, &Temp32);
491 
492                 /*
493                  * Insert the BCD digit that resides in the
494                  * remainder from above
495                  */
496                 ReturnDesc->Integer.Value |=
497                     (((UINT64) Temp32) << ACPI_MUL_4 (i));
498             }
499 
500             /* Overflow if there is any data left in Digit */
501 
502             if (Digit > 0)
503             {
504                 ACPI_ERROR ((AE_INFO,
505                     "Integer too large to convert to BCD: 0x%8.8X%8.8X",
506                     ACPI_FORMAT_UINT64 (Operand[0]->Integer.Value)));
507                 Status = AE_AML_NUMERIC_OVERFLOW;
508                 goto Cleanup;
509             }
510             break;
511 
512         case AML_COND_REF_OF_OP:        /* CondRefOf (SourceObject, Result)  */
513             /*
514              * This op is a little strange because the internal return value is
515              * different than the return value stored in the result descriptor
516              * (There are really two return values)
517              */
518             if ((ACPI_NAMESPACE_NODE *) Operand[0] == AcpiGbl_RootNode)
519             {
520                 /*
521                  * This means that the object does not exist in the namespace,
522                  * return FALSE
523                  */
524                 ReturnDesc->Integer.Value = 0;
525                 goto Cleanup;
526             }
527 
528             /* Get the object reference, store it, and remove our reference */
529 
530             Status = AcpiExGetObjectReference (Operand[0],
531                         &ReturnDesc2, WalkState);
532             if (ACPI_FAILURE (Status))
533             {
534                 goto Cleanup;
535             }
536 
537             Status = AcpiExStore (ReturnDesc2, Operand[1], WalkState);
538             AcpiUtRemoveReference (ReturnDesc2);
539 
540             /* The object exists in the namespace, return TRUE */
541 
542             ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
543             goto Cleanup;
544 
545 
546         default:
547 
548             /* No other opcodes get here */
549 
550             break;
551         }
552         break;
553 
554     case AML_STORE_OP:              /* Store (Source, Target) */
555         /*
556          * A store operand is typically a number, string, buffer or lvalue
557          * Be careful about deleting the source object,
558          * since the object itself may have been stored.
559          */
560         Status = AcpiExStore (Operand[0], Operand[1], WalkState);
561         if (ACPI_FAILURE (Status))
562         {
563             return_ACPI_STATUS (Status);
564         }
565 
566         /* It is possible that the Store already produced a return object */
567 
568         if (!WalkState->ResultObj)
569         {
570             /*
571              * Normally, we would remove a reference on the Operand[0]
572              * parameter; But since it is being used as the internal return
573              * object (meaning we would normally increment it), the two
574              * cancel out, and we simply don't do anything.
575              */
576             WalkState->ResultObj = Operand[0];
577             WalkState->Operands[0] = NULL;  /* Prevent deletion */
578         }
579         return_ACPI_STATUS (Status);
580 
581     /*
582      * ACPI 2.0 Opcodes
583      */
584     case AML_COPY_OP:               /* Copy (Source, Target) */
585 
586         Status = AcpiUtCopyIobjectToIobject (Operand[0], &ReturnDesc,
587                     WalkState);
588         break;
589 
590     case AML_TO_DECSTRING_OP:       /* ToDecimalString (Data, Result) */
591 
592         Status = AcpiExConvertToString (Operand[0], &ReturnDesc,
593                     ACPI_EXPLICIT_CONVERT_DECIMAL);
594         if (ReturnDesc == Operand[0])
595         {
596             /* No conversion performed, add ref to handle return value */
597             AcpiUtAddReference (ReturnDesc);
598         }
599         break;
600 
601     case AML_TO_HEXSTRING_OP:       /* ToHexString (Data, Result) */
602 
603         Status = AcpiExConvertToString (Operand[0], &ReturnDesc,
604                     ACPI_EXPLICIT_CONVERT_HEX);
605         if (ReturnDesc == Operand[0])
606         {
607             /* No conversion performed, add ref to handle return value */
608             AcpiUtAddReference (ReturnDesc);
609         }
610         break;
611 
612     case AML_TO_BUFFER_OP:          /* ToBuffer (Data, Result) */
613 
614         Status = AcpiExConvertToBuffer (Operand[0], &ReturnDesc);
615         if (ReturnDesc == Operand[0])
616         {
617             /* No conversion performed, add ref to handle return value */
618             AcpiUtAddReference (ReturnDesc);
619         }
620         break;
621 
622     case AML_TO_INTEGER_OP:         /* ToInteger (Data, Result) */
623 
624         Status = AcpiExConvertToInteger (Operand[0], &ReturnDesc,
625                     ACPI_ANY_BASE);
626         if (ReturnDesc == Operand[0])
627         {
628             /* No conversion performed, add ref to handle return value */
629             AcpiUtAddReference (ReturnDesc);
630         }
631         break;
632 
633     case AML_SHIFT_LEFT_BIT_OP:     /* ShiftLeftBit (Source, BitNum)  */
634     case AML_SHIFT_RIGHT_BIT_OP:    /* ShiftRightBit (Source, BitNum) */
635 
636         /* These are two obsolete opcodes */
637 
638         ACPI_ERROR ((AE_INFO,
639             "%s is obsolete and not implemented",
640             AcpiPsGetOpcodeName (WalkState->Opcode)));
641         Status = AE_SUPPORT;
642         goto Cleanup;
643 
644     default:                        /* Unknown opcode */
645 
646         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
647             WalkState->Opcode));
648         Status = AE_AML_BAD_OPCODE;
649         goto Cleanup;
650     }
651 
652     if (ACPI_SUCCESS (Status))
653     {
654         /* Store the return value computed above into the target object */
655 
656         Status = AcpiExStore (ReturnDesc, Operand[1], WalkState);
657     }
658 
659 
660 Cleanup:
661 
662     /* Delete return object on error */
663 
664     if (ACPI_FAILURE (Status))
665     {
666         AcpiUtRemoveReference (ReturnDesc);
667     }
668 
669     /* Save return object on success */
670 
671     else if (!WalkState->ResultObj)
672     {
673         WalkState->ResultObj = ReturnDesc;
674     }
675 
676     return_ACPI_STATUS (Status);
677 }
678 
679 
680 /*******************************************************************************
681  *
682  * FUNCTION:    AcpiExOpcode_1A_0T_1R
683  *
684  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
685  *
686  * RETURN:      Status
687  *
688  * DESCRIPTION: Execute opcode with one argument, no target, and a return value
689  *
690  ******************************************************************************/
691 
692 ACPI_STATUS
693 AcpiExOpcode_1A_0T_1R (
694     ACPI_WALK_STATE         *WalkState)
695 {
696     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
697     ACPI_OPERAND_OBJECT     *TempDesc;
698     ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
699     ACPI_STATUS             Status = AE_OK;
700     UINT32                  Type;
701     UINT64                  Value;
702 
703 
704     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_1R,
705         AcpiPsGetOpcodeName (WalkState->Opcode));
706 
707 
708     /* Examine the AML opcode */
709 
710     switch (WalkState->Opcode)
711     {
712     case AML_LNOT_OP:               /* LNot (Operand) */
713 
714         ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) 0);
715         if (!ReturnDesc)
716         {
717             Status = AE_NO_MEMORY;
718             goto Cleanup;
719         }
720 
721         /*
722          * Set result to ONES (TRUE) if Value == 0. Note:
723          * ReturnDesc->Integer.Value is initially == 0 (FALSE) from above.
724          */
725         if (!Operand[0]->Integer.Value)
726         {
727             ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
728         }
729         break;
730 
731     case AML_DECREMENT_OP:          /* Decrement (Operand)  */
732     case AML_INCREMENT_OP:          /* Increment (Operand)  */
733         /*
734          * Create a new integer. Can't just get the base integer and
735          * increment it because it may be an Arg or Field.
736          */
737         ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
738         if (!ReturnDesc)
739         {
740             Status = AE_NO_MEMORY;
741             goto Cleanup;
742         }
743 
744         /*
745          * Since we are expecting a Reference operand, it can be either a
746          * NS Node or an internal object.
747          */
748         TempDesc = Operand[0];
749         if (ACPI_GET_DESCRIPTOR_TYPE (TempDesc) == ACPI_DESC_TYPE_OPERAND)
750         {
751             /* Internal reference object - prevent deletion */
752 
753             AcpiUtAddReference (TempDesc);
754         }
755 
756         /*
757          * Convert the Reference operand to an Integer (This removes a
758          * reference on the Operand[0] object)
759          *
760          * NOTE:  We use LNOT_OP here in order to force resolution of the
761          * reference operand to an actual integer.
762          */
763         Status = AcpiExResolveOperands (AML_LNOT_OP, &TempDesc, WalkState);
764         if (ACPI_FAILURE (Status))
765         {
766             ACPI_EXCEPTION ((AE_INFO, Status,
767                 "While resolving operands for [%s]",
768                 AcpiPsGetOpcodeName (WalkState->Opcode)));
769 
770             goto Cleanup;
771         }
772 
773         /*
774          * TempDesc is now guaranteed to be an Integer object --
775          * Perform the actual increment or decrement
776          */
777         if (WalkState->Opcode == AML_INCREMENT_OP)
778         {
779             ReturnDesc->Integer.Value = TempDesc->Integer.Value +1;
780         }
781         else
782         {
783             ReturnDesc->Integer.Value = TempDesc->Integer.Value -1;
784         }
785 
786         /* Finished with this Integer object */
787 
788         AcpiUtRemoveReference (TempDesc);
789 
790         /*
791          * Store the result back (indirectly) through the original
792          * Reference object
793          */
794         Status = AcpiExStore (ReturnDesc, Operand[0], WalkState);
795         break;
796 
797     case AML_TYPE_OP:               /* ObjectType (SourceObject) */
798         /*
799          * Note: The operand is not resolved at this point because we want to
800          * get the associated object, not its value. For example, we don't
801          * want to resolve a FieldUnit to its value, we want the actual
802          * FieldUnit object.
803          */
804 
805         /* Get the type of the base object */
806 
807         Status = AcpiExResolveMultiple (WalkState, Operand[0], &Type, NULL);
808         if (ACPI_FAILURE (Status))
809         {
810             goto Cleanup;
811         }
812 
813         /* Allocate a descriptor to hold the type. */
814 
815         ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) Type);
816         if (!ReturnDesc)
817         {
818             Status = AE_NO_MEMORY;
819             goto Cleanup;
820         }
821         break;
822 
823     case AML_SIZE_OF_OP:            /* SizeOf (SourceObject)  */
824         /*
825          * Note: The operand is not resolved at this point because we want to
826          * get the associated object, not its value.
827          */
828 
829         /* Get the base object */
830 
831         Status = AcpiExResolveMultiple (WalkState,
832                     Operand[0], &Type, &TempDesc);
833         if (ACPI_FAILURE (Status))
834         {
835             goto Cleanup;
836         }
837 
838         /*
839          * The type of the base object must be integer, buffer, string, or
840          * package. All others are not supported.
841          *
842          * NOTE: Integer is not specifically supported by the ACPI spec,
843          * but is supported implicitly via implicit operand conversion.
844          * rather than bother with conversion, we just use the byte width
845          * global (4 or 8 bytes).
846          */
847         switch (Type)
848         {
849         case ACPI_TYPE_INTEGER:
850 
851             Value = AcpiGbl_IntegerByteWidth;
852             break;
853 
854         case ACPI_TYPE_STRING:
855 
856             Value = TempDesc->String.Length;
857             break;
858 
859         case ACPI_TYPE_BUFFER:
860 
861             /* Buffer arguments may not be evaluated at this point */
862 
863             Status = AcpiDsGetBufferArguments (TempDesc);
864             Value = TempDesc->Buffer.Length;
865             break;
866 
867         case ACPI_TYPE_PACKAGE:
868 
869             /* Package arguments may not be evaluated at this point */
870 
871             Status = AcpiDsGetPackageArguments (TempDesc);
872             Value = TempDesc->Package.Count;
873             break;
874 
875         default:
876 
877             ACPI_ERROR ((AE_INFO,
878                 "Operand must be Buffer/Integer/String/Package - found type %s",
879                 AcpiUtGetTypeName (Type)));
880             Status = AE_AML_OPERAND_TYPE;
881             goto Cleanup;
882         }
883 
884         if (ACPI_FAILURE (Status))
885         {
886             goto Cleanup;
887         }
888 
889         /*
890          * Now that we have the size of the object, create a result
891          * object to hold the value
892          */
893         ReturnDesc = AcpiUtCreateIntegerObject (Value);
894         if (!ReturnDesc)
895         {
896             Status = AE_NO_MEMORY;
897             goto Cleanup;
898         }
899         break;
900 
901 
902     case AML_REF_OF_OP:             /* RefOf (SourceObject) */
903 
904         Status = AcpiExGetObjectReference (Operand[0], &ReturnDesc, WalkState);
905         if (ACPI_FAILURE (Status))
906         {
907             goto Cleanup;
908         }
909         break;
910 
911 
912     case AML_DEREF_OF_OP:           /* DerefOf (ObjReference | String) */
913 
914         /* Check for a method local or argument, or standalone String */
915 
916         if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED)
917         {
918             TempDesc = AcpiNsGetAttachedObject (
919                            (ACPI_NAMESPACE_NODE *) Operand[0]);
920             if (TempDesc &&
921                  ((TempDesc->Common.Type == ACPI_TYPE_STRING) ||
922                   (TempDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)))
923             {
924                 Operand[0] = TempDesc;
925                 AcpiUtAddReference (TempDesc);
926             }
927             else
928             {
929                 Status = AE_AML_OPERAND_TYPE;
930                 goto Cleanup;
931             }
932         }
933         else
934         {
935             switch ((Operand[0])->Common.Type)
936             {
937             case ACPI_TYPE_LOCAL_REFERENCE:
938                 /*
939                  * This is a DerefOf (LocalX | ArgX)
940                  *
941                  * Must resolve/dereference the local/arg reference first
942                  */
943                 switch (Operand[0]->Reference.Class)
944                 {
945                 case ACPI_REFCLASS_LOCAL:
946                 case ACPI_REFCLASS_ARG:
947 
948                     /* Set Operand[0] to the value of the local/arg */
949 
950                     Status = AcpiDsMethodDataGetValue (
951                                 Operand[0]->Reference.Class,
952                                 Operand[0]->Reference.Value,
953                                 WalkState, &TempDesc);
954                     if (ACPI_FAILURE (Status))
955                     {
956                         goto Cleanup;
957                     }
958 
959                     /*
960                      * Delete our reference to the input object and
961                      * point to the object just retrieved
962                      */
963                     AcpiUtRemoveReference (Operand[0]);
964                     Operand[0] = TempDesc;
965                     break;
966 
967                 case ACPI_REFCLASS_REFOF:
968 
969                     /* Get the object to which the reference refers */
970 
971                     TempDesc = Operand[0]->Reference.Object;
972                     AcpiUtRemoveReference (Operand[0]);
973                     Operand[0] = TempDesc;
974                     break;
975 
976                 default:
977 
978                     /* Must be an Index op - handled below */
979                     break;
980                 }
981                 break;
982 
983             case ACPI_TYPE_STRING:
984 
985                 break;
986 
987             default:
988 
989                 Status = AE_AML_OPERAND_TYPE;
990                 goto Cleanup;
991             }
992         }
993 
994         if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) != ACPI_DESC_TYPE_NAMED)
995         {
996             if ((Operand[0])->Common.Type == ACPI_TYPE_STRING)
997             {
998                 /*
999                  * This is a DerefOf (String). The string is a reference
1000                  * to a named ACPI object.
1001                  *
1002                  * 1) Find the owning Node
1003                  * 2) Dereference the node to an actual object. Could be a
1004                  *    Field, so we need to resolve the node to a value.
1005                  */
1006                 Status = AcpiNsGetNode (WalkState->ScopeInfo->Scope.Node,
1007                             Operand[0]->String.Pointer,
1008                             ACPI_NS_SEARCH_PARENT,
1009                             ACPI_CAST_INDIRECT_PTR (
1010                                 ACPI_NAMESPACE_NODE, &ReturnDesc));
1011                 if (ACPI_FAILURE (Status))
1012                 {
1013                     goto Cleanup;
1014                 }
1015 
1016                 Status = AcpiExResolveNodeToValue (
1017                             ACPI_CAST_INDIRECT_PTR (
1018                                 ACPI_NAMESPACE_NODE, &ReturnDesc),
1019                             WalkState);
1020                 goto Cleanup;
1021             }
1022         }
1023 
1024         /* Operand[0] may have changed from the code above */
1025 
1026         if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED)
1027         {
1028             /*
1029              * This is a DerefOf (ObjectReference)
1030              * Get the actual object from the Node (This is the dereference).
1031              * This case may only happen when a LocalX or ArgX is
1032              * dereferenced above.
1033              */
1034             ReturnDesc = AcpiNsGetAttachedObject (
1035                             (ACPI_NAMESPACE_NODE *) Operand[0]);
1036             AcpiUtAddReference (ReturnDesc);
1037         }
1038         else
1039         {
1040             /*
1041              * This must be a reference object produced by either the
1042              * Index() or RefOf() operator
1043              */
1044             switch (Operand[0]->Reference.Class)
1045             {
1046             case ACPI_REFCLASS_INDEX:
1047                 /*
1048                  * The target type for the Index operator must be
1049                  * either a Buffer or a Package
1050                  */
1051                 switch (Operand[0]->Reference.TargetType)
1052                 {
1053                 case ACPI_TYPE_BUFFER_FIELD:
1054 
1055                     TempDesc = Operand[0]->Reference.Object;
1056 
1057                     /*
1058                      * Create a new object that contains one element of the
1059                      * buffer -- the element pointed to by the index.
1060                      *
1061                      * NOTE: index into a buffer is NOT a pointer to a
1062                      * sub-buffer of the main buffer, it is only a pointer to a
1063                      * single element (byte) of the buffer!
1064                      *
1065                      * Since we are returning the value of the buffer at the
1066                      * indexed location, we don't need to add an additional
1067                      * reference to the buffer itself.
1068                      */
1069                     ReturnDesc = AcpiUtCreateIntegerObject ((UINT64)
1070                         TempDesc->Buffer.Pointer[Operand[0]->Reference.Value]);
1071                     if (!ReturnDesc)
1072                     {
1073                         Status = AE_NO_MEMORY;
1074                         goto Cleanup;
1075                     }
1076                     break;
1077 
1078                 case ACPI_TYPE_PACKAGE:
1079                     /*
1080                      * Return the referenced element of the package. We must
1081                      * add another reference to the referenced object, however.
1082                      */
1083                     ReturnDesc = *(Operand[0]->Reference.Where);
1084                     if (!ReturnDesc)
1085                     {
1086                         /*
1087                          * Element is NULL, do not allow the dereference.
1088                          * This provides compatibility with other ACPI
1089                          * implementations.
1090                          */
1091                         return_ACPI_STATUS (AE_AML_UNINITIALIZED_ELEMENT);
1092                     }
1093 
1094                     AcpiUtAddReference (ReturnDesc);
1095                     break;
1096 
1097                 default:
1098 
1099                     ACPI_ERROR ((AE_INFO,
1100                         "Unknown Index TargetType 0x%X in reference object %p",
1101                         Operand[0]->Reference.TargetType, Operand[0]));
1102                     Status = AE_AML_OPERAND_TYPE;
1103                     goto Cleanup;
1104                 }
1105                 break;
1106 
1107             case ACPI_REFCLASS_REFOF:
1108 
1109                 ReturnDesc = Operand[0]->Reference.Object;
1110 
1111                 if (ACPI_GET_DESCRIPTOR_TYPE (ReturnDesc) ==
1112                     ACPI_DESC_TYPE_NAMED)
1113                 {
1114                     ReturnDesc = AcpiNsGetAttachedObject (
1115                         (ACPI_NAMESPACE_NODE *) ReturnDesc);
1116                     if (!ReturnDesc)
1117                     {
1118                         break;
1119                     }
1120 
1121                    /*
1122                     * June 2013:
1123                     * BufferFields/FieldUnits require additional resolution
1124                     */
1125                     switch (ReturnDesc->Common.Type)
1126                     {
1127                     case ACPI_TYPE_BUFFER_FIELD:
1128                     case ACPI_TYPE_LOCAL_REGION_FIELD:
1129                     case ACPI_TYPE_LOCAL_BANK_FIELD:
1130                     case ACPI_TYPE_LOCAL_INDEX_FIELD:
1131 
1132                         Status = AcpiExReadDataFromField (WalkState,
1133                             ReturnDesc, &TempDesc);
1134                         if (ACPI_FAILURE (Status))
1135                         {
1136                             goto Cleanup;
1137                         }
1138 
1139                         ReturnDesc = TempDesc;
1140                         break;
1141 
1142                     default:
1143 
1144                         /* Add another reference to the object */
1145 
1146                         AcpiUtAddReference (ReturnDesc);
1147                         break;
1148                     }
1149                 }
1150                 break;
1151 
1152             default:
1153 
1154                 ACPI_ERROR ((AE_INFO,
1155                     "Unknown class in reference(%p) - 0x%2.2X",
1156                     Operand[0], Operand[0]->Reference.Class));
1157 
1158                 Status = AE_TYPE;
1159                 goto Cleanup;
1160             }
1161         }
1162         break;
1163 
1164     default:
1165 
1166         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
1167             WalkState->Opcode));
1168         Status = AE_AML_BAD_OPCODE;
1169         goto Cleanup;
1170     }
1171 
1172 
1173 Cleanup:
1174 
1175     /* Delete return object on error */
1176 
1177     if (ACPI_FAILURE (Status))
1178     {
1179         AcpiUtRemoveReference (ReturnDesc);
1180     }
1181 
1182     /* Save return object on success */
1183 
1184     else
1185     {
1186         WalkState->ResultObj = ReturnDesc;
1187     }
1188 
1189     return_ACPI_STATUS (Status);
1190 }
1191