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 - 2023, 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  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include "acpi.h"
153 #include "accommon.h"
154 #include "acparser.h"
155 #include "acdispat.h"
156 #include "acinterp.h"
157 #include "amlcode.h"
158 #include "acnamesp.h"
159 
160 
161 #define _COMPONENT          ACPI_EXECUTER
162         ACPI_MODULE_NAME    ("exoparg1")
163 
164 
165 /*!
166  * Naming convention for AML interpreter execution routines.
167  *
168  * The routines that begin execution of AML opcodes are named with a common
169  * convention based upon the number of arguments, the number of target operands,
170  * and whether or not a value is returned:
171  *
172  *      AcpiExOpcode_xA_yT_zR
173  *
174  * Where:
175  *
176  * xA - ARGUMENTS:    The number of arguments (input operands) that are
177  *                    required for this opcode type (0 through 6 args).
178  * yT - TARGETS:      The number of targets (output operands) that are required
179  *                    for this opcode type (0, 1, or 2 targets).
180  * zR - RETURN VALUE: Indicates whether this opcode type returns a value
181  *                    as the function return (0 or 1).
182  *
183  * The AcpiExOpcode* functions are called via the Dispatcher component with
184  * fully resolved operands.
185 !*/
186 
187 /*******************************************************************************
188  *
189  * FUNCTION:    AcpiExOpcode_0A_0T_1R
190  *
191  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
192  *
193  * RETURN:      Status
194  *
195  * DESCRIPTION: Execute operator with no operands, one return value
196  *
197  ******************************************************************************/
198 
199 ACPI_STATUS
AcpiExOpcode_0A_0T_1R(ACPI_WALK_STATE * WalkState)200 AcpiExOpcode_0A_0T_1R (
201     ACPI_WALK_STATE         *WalkState)
202 {
203     ACPI_STATUS             Status = AE_OK;
204     ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
205 
206 
207     ACPI_FUNCTION_TRACE_STR (ExOpcode_0A_0T_1R,
208         AcpiPsGetOpcodeName (WalkState->Opcode));
209 
210 
211     /* Examine the AML opcode */
212 
213     switch (WalkState->Opcode)
214     {
215     case AML_TIMER_OP:      /*  Timer () */
216 
217         /* Create a return object of type Integer */
218 
219         ReturnDesc = AcpiUtCreateIntegerObject (AcpiOsGetTimer ());
220         if (!ReturnDesc)
221         {
222             Status = AE_NO_MEMORY;
223             goto Cleanup;
224         }
225         break;
226 
227     default:                /*  Unknown opcode  */
228 
229         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
230             WalkState->Opcode));
231         Status = AE_AML_BAD_OPCODE;
232         break;
233     }
234 
235 Cleanup:
236 
237     /* Delete return object on error */
238 
239     if ((ACPI_FAILURE (Status)) || WalkState->ResultObj)
240     {
241         AcpiUtRemoveReference (ReturnDesc);
242         WalkState->ResultObj = NULL;
243     }
244     else
245     {
246         /* Save the return value */
247 
248         WalkState->ResultObj = ReturnDesc;
249     }
250 
251     return_ACPI_STATUS (Status);
252 }
253 
254 
255 /*******************************************************************************
256  *
257  * FUNCTION:    AcpiExOpcode_1A_0T_0R
258  *
259  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
260  *
261  * RETURN:      Status
262  *
263  * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
264  *              object stack
265  *
266  ******************************************************************************/
267 
268 ACPI_STATUS
AcpiExOpcode_1A_0T_0R(ACPI_WALK_STATE * WalkState)269 AcpiExOpcode_1A_0T_0R (
270     ACPI_WALK_STATE         *WalkState)
271 {
272     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
273     ACPI_STATUS             Status = AE_OK;
274 
275 
276     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_0R,
277         AcpiPsGetOpcodeName (WalkState->Opcode));
278 
279 
280     /* Examine the AML opcode */
281 
282     switch (WalkState->Opcode)
283     {
284     case AML_RELEASE_OP:    /*  Release (MutexObject) */
285 
286         Status = AcpiExReleaseMutex (Operand[0], WalkState);
287         break;
288 
289     case AML_RESET_OP:      /*  Reset (EventObject) */
290 
291         Status = AcpiExSystemResetEvent (Operand[0]);
292         break;
293 
294     case AML_SIGNAL_OP:     /*  Signal (EventObject) */
295 
296         Status = AcpiExSystemSignalEvent (Operand[0]);
297         break;
298 
299     case AML_SLEEP_OP:      /*  Sleep (MsecTime) */
300 
301         Status = AcpiExSystemDoSleep (Operand[0]->Integer.Value);
302         break;
303 
304     case AML_STALL_OP:      /*  Stall (UsecTime) */
305 
306         Status = AcpiExSystemDoStall ((UINT32) Operand[0]->Integer.Value);
307         break;
308 
309     case AML_UNLOAD_OP:     /*  Unload (Handle) */
310 
311         Status = AcpiExUnloadTable (Operand[0]);
312         break;
313 
314     default:                /*  Unknown opcode  */
315 
316         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
317             WalkState->Opcode));
318         Status = AE_AML_BAD_OPCODE;
319         break;
320     }
321 
322     return_ACPI_STATUS (Status);
323 }
324 
325 
326 #ifdef _OBSOLETE_CODE /* Was originally used for Load() operator */
327 /*******************************************************************************
328  *
329  * FUNCTION:    AcpiExOpcode_1A_1T_0R
330  *
331  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
332  *
333  * RETURN:      Status
334  *
335  * DESCRIPTION: Execute opcode with one argument, one target, and no
336  *              return value.
337  *
338  ******************************************************************************/
339 
340 ACPI_STATUS
AcpiExOpcode_1A_1T_0R(ACPI_WALK_STATE * WalkState)341 AcpiExOpcode_1A_1T_0R (
342     ACPI_WALK_STATE         *WalkState)
343 {
344     ACPI_STATUS             Status = AE_OK;
345     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
346 
347 
348     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_0R,
349         AcpiPsGetOpcodeName (WalkState->Opcode));
350 
351 
352     /* Examine the AML opcode */
353 
354     switch (WalkState->Opcode)
355     {
356 #ifdef _OBSOLETE_CODE
357     case AML_LOAD_OP:
358 
359         Status = AcpiExLoadOp (Operand[0], Operand[1], WalkState);
360         break;
361 #endif
362 
363     default:                        /* Unknown opcode */
364 
365         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
366             WalkState->Opcode));
367         Status = AE_AML_BAD_OPCODE;
368         goto Cleanup;
369     }
370 
371 
372 Cleanup:
373 
374     return_ACPI_STATUS (Status);
375 }
376 #endif
377 
378 /*******************************************************************************
379  *
380  * FUNCTION:    AcpiExOpcode_1A_1T_1R
381  *
382  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
383  *
384  * RETURN:      Status
385  *
386  * DESCRIPTION: Execute opcode with one argument, one target, and a
387  *              return value.
388  *              January 2022: Added Load operator, with new ACPI 6.4
389  *              semantics.
390  *
391  ******************************************************************************/
392 
393 ACPI_STATUS
AcpiExOpcode_1A_1T_1R(ACPI_WALK_STATE * WalkState)394 AcpiExOpcode_1A_1T_1R (
395     ACPI_WALK_STATE         *WalkState)
396 {
397     ACPI_STATUS             Status = AE_OK;
398     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
399     ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
400     ACPI_OPERAND_OBJECT     *ReturnDesc2 = NULL;
401     UINT32                  Temp32;
402     UINT32                  i;
403     UINT64                  PowerOfTen;
404     UINT64                  Digit;
405 
406 
407     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_1R,
408         AcpiPsGetOpcodeName (WalkState->Opcode));
409 
410 
411     /* Examine the AML opcode */
412 
413     switch (WalkState->Opcode)
414     {
415     case AML_BIT_NOT_OP:
416     case AML_FIND_SET_LEFT_BIT_OP:
417     case AML_FIND_SET_RIGHT_BIT_OP:
418     case AML_FROM_BCD_OP:
419     case AML_LOAD_OP:
420     case AML_TO_BCD_OP:
421     case AML_CONDITIONAL_REF_OF_OP:
422 
423         /* Create a return object of type Integer for these opcodes */
424 
425         ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
426         if (!ReturnDesc)
427         {
428             Status = AE_NO_MEMORY;
429             goto Cleanup;
430         }
431 
432         switch (WalkState->Opcode)
433         {
434         case AML_BIT_NOT_OP:            /* Not (Operand, Result)  */
435 
436             ReturnDesc->Integer.Value = ~Operand[0]->Integer.Value;
437             break;
438 
439         case AML_FIND_SET_LEFT_BIT_OP:  /* FindSetLeftBit (Operand, Result) */
440 
441             ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
442 
443             /*
444              * Acpi specification describes Integer type as a little
445              * endian unsigned value, so this boundary condition is valid.
446              */
447             for (Temp32 = 0; ReturnDesc->Integer.Value &&
448                     Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
449             {
450                 ReturnDesc->Integer.Value >>= 1;
451             }
452 
453             ReturnDesc->Integer.Value = Temp32;
454             break;
455 
456         case AML_FIND_SET_RIGHT_BIT_OP: /* FindSetRightBit (Operand, Result) */
457 
458             ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
459 
460             /*
461              * The Acpi specification describes Integer type as a little
462              * endian unsigned value, so this boundary condition is valid.
463              */
464             for (Temp32 = 0; ReturnDesc->Integer.Value &&
465                      Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
466             {
467                 ReturnDesc->Integer.Value <<= 1;
468             }
469 
470             /* Since the bit position is one-based, subtract from 33 (65) */
471 
472             ReturnDesc->Integer.Value =
473                 Temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - Temp32;
474             break;
475 
476         case AML_FROM_BCD_OP:           /* FromBcd (BCDValue, Result)  */
477             /*
478              * The 64-bit ACPI integer can hold 16 4-bit BCD characters
479              * (if table is 32-bit, integer can hold 8 BCD characters)
480              * Convert each 4-bit BCD value
481              */
482             PowerOfTen = 1;
483             ReturnDesc->Integer.Value = 0;
484             Digit = Operand[0]->Integer.Value;
485 
486             /* Convert each BCD digit (each is one nybble wide) */
487 
488             for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
489             {
490                 /* Get the least significant 4-bit BCD digit */
491 
492                 Temp32 = ((UINT32) Digit) & 0xF;
493 
494                 /* Check the range of the digit */
495 
496                 if (Temp32 > 9)
497                 {
498                     ACPI_ERROR ((AE_INFO,
499                         "BCD digit too large (not decimal): 0x%X",
500                         Temp32));
501 
502                     Status = AE_AML_NUMERIC_OVERFLOW;
503                     goto Cleanup;
504                 }
505 
506                 /* Sum the digit into the result with the current power of 10 */
507 
508                 ReturnDesc->Integer.Value +=
509                     (((UINT64) Temp32) * PowerOfTen);
510 
511                 /* Shift to next BCD digit */
512 
513                 Digit >>= 4;
514 
515                 /* Next power of 10 */
516 
517                 PowerOfTen *= 10;
518             }
519             break;
520 
521         case AML_LOAD_OP:               /* Result1 = Load (Operand[0], Result1) */
522 
523             ReturnDesc->Integer.Value = 0;
524             Status = AcpiExLoadOp (Operand[0], ReturnDesc, WalkState);
525             if (ACPI_SUCCESS (Status))
526             {
527                 /* Return -1 (non-zero) indicates success */
528 
529                 ReturnDesc->Integer.Value = 0xFFFFFFFFFFFFFFFF;
530             }
531             break;
532 
533         case AML_TO_BCD_OP:             /* ToBcd (Operand, Result)  */
534 
535             ReturnDesc->Integer.Value = 0;
536             Digit = Operand[0]->Integer.Value;
537 
538             /* Each BCD digit is one nybble wide */
539 
540             for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
541             {
542                 (void) AcpiUtShortDivide (Digit, 10, &Digit, &Temp32);
543 
544                 /*
545                  * Insert the BCD digit that resides in the
546                  * remainder from above
547                  */
548                 ReturnDesc->Integer.Value |=
549                     (((UINT64) Temp32) << ACPI_MUL_4 (i));
550             }
551 
552             /* Overflow if there is any data left in Digit */
553 
554             if (Digit > 0)
555             {
556                 ACPI_ERROR ((AE_INFO,
557                     "Integer too large to convert to BCD: 0x%8.8X%8.8X",
558                     ACPI_FORMAT_UINT64 (Operand[0]->Integer.Value)));
559                 Status = AE_AML_NUMERIC_OVERFLOW;
560                 goto Cleanup;
561             }
562             break;
563 
564         case AML_CONDITIONAL_REF_OF_OP:     /* CondRefOf (SourceObject, Result)  */
565             /*
566              * This op is a little strange because the internal return value is
567              * different than the return value stored in the result descriptor
568              * (There are really two return values)
569              */
570             if ((ACPI_NAMESPACE_NODE *) Operand[0] == AcpiGbl_RootNode)
571             {
572                 /*
573                  * This means that the object does not exist in the namespace,
574                  * return FALSE
575                  */
576                 ReturnDesc->Integer.Value = 0;
577                 goto Cleanup;
578             }
579 
580             /* Get the object reference, store it, and remove our reference */
581 
582             Status = AcpiExGetObjectReference (Operand[0],
583                 &ReturnDesc2, WalkState);
584             if (ACPI_FAILURE (Status))
585             {
586                 goto Cleanup;
587             }
588 
589             Status = AcpiExStore (ReturnDesc2, Operand[1], WalkState);
590             AcpiUtRemoveReference (ReturnDesc2);
591 
592             /* The object exists in the namespace, return TRUE */
593 
594             ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
595             goto Cleanup;
596 
597 
598         default:
599 
600             /* No other opcodes get here */
601 
602             break;
603         }
604         break;
605 
606     case AML_STORE_OP:              /* Store (Source, Target) */
607         /*
608          * A store operand is typically a number, string, buffer or lvalue
609          * Be careful about deleting the source object,
610          * since the object itself may have been stored.
611          */
612         Status = AcpiExStore (Operand[0], Operand[1], WalkState);
613         if (ACPI_FAILURE (Status))
614         {
615             return_ACPI_STATUS (Status);
616         }
617 
618         /* It is possible that the Store already produced a return object */
619 
620         if (!WalkState->ResultObj)
621         {
622             /*
623              * Normally, we would remove a reference on the Operand[0]
624              * parameter; But since it is being used as the internal return
625              * object (meaning we would normally increment it), the two
626              * cancel out, and we simply don't do anything.
627              */
628             WalkState->ResultObj = Operand[0];
629             WalkState->Operands[0] = NULL;  /* Prevent deletion */
630         }
631         return_ACPI_STATUS (Status);
632 
633     /*
634      * ACPI 2.0 Opcodes
635      */
636     case AML_COPY_OBJECT_OP:        /* CopyObject (Source, Target) */
637 
638         Status = AcpiUtCopyIobjectToIobject (
639             Operand[0], &ReturnDesc, WalkState);
640         break;
641 
642     case AML_TO_DECIMAL_STRING_OP:  /* ToDecimalString (Data, Result) */
643 
644         Status = AcpiExConvertToString (
645             Operand[0], &ReturnDesc, ACPI_EXPLICIT_CONVERT_DECIMAL);
646         if (ReturnDesc == Operand[0])
647         {
648             /* No conversion performed, add ref to handle return value */
649 
650             AcpiUtAddReference (ReturnDesc);
651         }
652         break;
653 
654     case AML_TO_HEX_STRING_OP:      /* ToHexString (Data, Result) */
655 
656         Status = AcpiExConvertToString (
657             Operand[0], &ReturnDesc, ACPI_EXPLICIT_CONVERT_HEX);
658         if (ReturnDesc == Operand[0])
659         {
660             /* No conversion performed, add ref to handle return value */
661 
662             AcpiUtAddReference (ReturnDesc);
663         }
664         break;
665 
666     case AML_TO_BUFFER_OP:          /* ToBuffer (Data, Result) */
667 
668         Status = AcpiExConvertToBuffer (Operand[0], &ReturnDesc);
669         if (ReturnDesc == Operand[0])
670         {
671             /* No conversion performed, add ref to handle return value */
672 
673             AcpiUtAddReference (ReturnDesc);
674         }
675         break;
676 
677     case AML_TO_INTEGER_OP:         /* ToInteger (Data, Result) */
678 
679         /* Perform "explicit" conversion */
680 
681         Status = AcpiExConvertToInteger (Operand[0], &ReturnDesc, 0);
682         if (ReturnDesc == Operand[0])
683         {
684             /* No conversion performed, add ref to handle return value */
685 
686             AcpiUtAddReference (ReturnDesc);
687         }
688         break;
689 
690     case AML_SHIFT_LEFT_BIT_OP:     /* ShiftLeftBit (Source, BitNum)  */
691     case AML_SHIFT_RIGHT_BIT_OP:    /* ShiftRightBit (Source, BitNum) */
692 
693         /* These are two obsolete opcodes */
694 
695         ACPI_ERROR ((AE_INFO,
696             "%s is obsolete and not implemented",
697             AcpiPsGetOpcodeName (WalkState->Opcode)));
698         Status = AE_SUPPORT;
699         goto Cleanup;
700 
701     default:                        /* Unknown opcode */
702 
703         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
704             WalkState->Opcode));
705         Status = AE_AML_BAD_OPCODE;
706         goto Cleanup;
707     }
708 
709     if (ACPI_SUCCESS (Status))
710     {
711         /* Store the return value computed above into the target object */
712 
713         Status = AcpiExStore (ReturnDesc, Operand[1], WalkState);
714     }
715 
716 
717 Cleanup:
718 
719     /* Delete return object on error */
720 
721     if (ACPI_FAILURE (Status))
722     {
723         AcpiUtRemoveReference (ReturnDesc);
724     }
725 
726     /* Save return object on success */
727 
728     else if (!WalkState->ResultObj)
729     {
730         WalkState->ResultObj = ReturnDesc;
731     }
732 
733     return_ACPI_STATUS (Status);
734 }
735 
736 
737 /*******************************************************************************
738  *
739  * FUNCTION:    AcpiExOpcode_1A_0T_1R
740  *
741  * PARAMETERS:  WalkState           - Current state (contains AML opcode)
742  *
743  * RETURN:      Status
744  *
745  * DESCRIPTION: Execute opcode with one argument, no target, and a return value
746  *
747  ******************************************************************************/
748 
749 ACPI_STATUS
AcpiExOpcode_1A_0T_1R(ACPI_WALK_STATE * WalkState)750 AcpiExOpcode_1A_0T_1R (
751     ACPI_WALK_STATE         *WalkState)
752 {
753     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
754     ACPI_OPERAND_OBJECT     *TempDesc;
755     ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
756     ACPI_STATUS             Status = AE_OK;
757     UINT32                  Type;
758     UINT64                  Value;
759 
760 
761     ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_1R,
762         AcpiPsGetOpcodeName (WalkState->Opcode));
763 
764 
765     /* Examine the AML opcode */
766 
767     switch (WalkState->Opcode)
768     {
769     case AML_LOGICAL_NOT_OP:        /* LNot (Operand) */
770 
771         ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) 0);
772         if (!ReturnDesc)
773         {
774             Status = AE_NO_MEMORY;
775             goto Cleanup;
776         }
777 
778         /*
779          * Set result to ONES (TRUE) if Value == 0. Note:
780          * ReturnDesc->Integer.Value is initially == 0 (FALSE) from above.
781          */
782         if (!Operand[0]->Integer.Value)
783         {
784             ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
785         }
786         break;
787 
788     case AML_DECREMENT_OP:          /* Decrement (Operand)  */
789     case AML_INCREMENT_OP:          /* Increment (Operand)  */
790         /*
791          * Create a new integer. Can't just get the base integer and
792          * increment it because it may be an Arg or Field.
793          */
794         ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
795         if (!ReturnDesc)
796         {
797             Status = AE_NO_MEMORY;
798             goto Cleanup;
799         }
800 
801         /*
802          * Since we are expecting a Reference operand, it can be either a
803          * NS Node or an internal object.
804          */
805         TempDesc = Operand[0];
806         if (ACPI_GET_DESCRIPTOR_TYPE (TempDesc) == ACPI_DESC_TYPE_OPERAND)
807         {
808             /* Internal reference object - prevent deletion */
809 
810             AcpiUtAddReference (TempDesc);
811         }
812 
813         /*
814          * Convert the Reference operand to an Integer (This removes a
815          * reference on the Operand[0] object)
816          *
817          * NOTE:  We use LNOT_OP here in order to force resolution of the
818          * reference operand to an actual integer.
819          */
820         Status = AcpiExResolveOperands (AML_LOGICAL_NOT_OP,
821             &TempDesc, WalkState);
822         if (ACPI_FAILURE (Status))
823         {
824             ACPI_EXCEPTION ((AE_INFO, Status,
825                 "While resolving operands for [%s]",
826                 AcpiPsGetOpcodeName (WalkState->Opcode)));
827 
828             goto Cleanup;
829         }
830 
831         /*
832          * TempDesc is now guaranteed to be an Integer object --
833          * Perform the actual increment or decrement
834          */
835         if (WalkState->Opcode == AML_INCREMENT_OP)
836         {
837             ReturnDesc->Integer.Value = TempDesc->Integer.Value + 1;
838         }
839         else
840         {
841             ReturnDesc->Integer.Value = TempDesc->Integer.Value - 1;
842         }
843 
844         /* Finished with this Integer object */
845 
846         AcpiUtRemoveReference (TempDesc);
847 
848         /*
849          * Store the result back (indirectly) through the original
850          * Reference object
851          */
852         Status = AcpiExStore (ReturnDesc, Operand[0], WalkState);
853         break;
854 
855     case AML_OBJECT_TYPE_OP:            /* ObjectType (SourceObject) */
856         /*
857          * Note: The operand is not resolved at this point because we want to
858          * get the associated object, not its value. For example, we don't
859          * want to resolve a FieldUnit to its value, we want the actual
860          * FieldUnit object.
861          */
862 
863         /* Get the type of the base object */
864 
865         Status = AcpiExResolveMultiple (WalkState, Operand[0], &Type, NULL);
866         if (ACPI_FAILURE (Status))
867         {
868             goto Cleanup;
869         }
870 
871         /* Allocate a descriptor to hold the type. */
872 
873         ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) Type);
874         if (!ReturnDesc)
875         {
876             Status = AE_NO_MEMORY;
877             goto Cleanup;
878         }
879         break;
880 
881     case AML_SIZE_OF_OP:            /* SizeOf (SourceObject)  */
882         /*
883          * Note: The operand is not resolved at this point because we want to
884          * get the associated object, not its value.
885          */
886 
887         /* Get the base object */
888 
889         Status = AcpiExResolveMultiple (
890             WalkState, Operand[0], &Type, &TempDesc);
891         if (ACPI_FAILURE (Status))
892         {
893             goto Cleanup;
894         }
895 
896         /*
897          * The type of the base object must be integer, buffer, string, or
898          * package. All others are not supported.
899          *
900          * NOTE: Integer is not specifically supported by the ACPI spec,
901          * but is supported implicitly via implicit operand conversion.
902          * rather than bother with conversion, we just use the byte width
903          * global (4 or 8 bytes).
904          */
905         switch (Type)
906         {
907         case ACPI_TYPE_INTEGER:
908 
909             Value = AcpiGbl_IntegerByteWidth;
910             break;
911 
912         case ACPI_TYPE_STRING:
913 
914             Value = TempDesc->String.Length;
915             break;
916 
917         case ACPI_TYPE_BUFFER:
918 
919             /* Buffer arguments may not be evaluated at this point */
920 
921             Status = AcpiDsGetBufferArguments (TempDesc);
922             Value = TempDesc->Buffer.Length;
923             break;
924 
925         case ACPI_TYPE_PACKAGE:
926 
927             /* Package arguments may not be evaluated at this point */
928 
929             Status = AcpiDsGetPackageArguments (TempDesc);
930             Value = TempDesc->Package.Count;
931             break;
932 
933         default:
934 
935             ACPI_ERROR ((AE_INFO,
936                 "Operand must be Buffer/Integer/String/Package"
937                 " - found type %s",
938                 AcpiUtGetTypeName (Type)));
939 
940             Status = AE_AML_OPERAND_TYPE;
941             goto Cleanup;
942         }
943 
944         if (ACPI_FAILURE (Status))
945         {
946             goto Cleanup;
947         }
948 
949         /*
950          * Now that we have the size of the object, create a result
951          * object to hold the value
952          */
953         ReturnDesc = AcpiUtCreateIntegerObject (Value);
954         if (!ReturnDesc)
955         {
956             Status = AE_NO_MEMORY;
957             goto Cleanup;
958         }
959         break;
960 
961 
962     case AML_REF_OF_OP:             /* RefOf (SourceObject) */
963 
964         Status = AcpiExGetObjectReference (
965             Operand[0], &ReturnDesc, WalkState);
966         if (ACPI_FAILURE (Status))
967         {
968             goto Cleanup;
969         }
970         break;
971 
972 
973     case AML_DEREF_OF_OP:           /* DerefOf (ObjReference | String) */
974 
975         /* Check for a method local or argument, or standalone String */
976 
977         if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED)
978         {
979             TempDesc = AcpiNsGetAttachedObject (
980                 (ACPI_NAMESPACE_NODE *) Operand[0]);
981             if (TempDesc &&
982                  ((TempDesc->Common.Type == ACPI_TYPE_STRING) ||
983                   (TempDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)))
984             {
985                 Operand[0] = TempDesc;
986                 AcpiUtAddReference (TempDesc);
987             }
988             else
989             {
990                 Status = AE_AML_OPERAND_TYPE;
991                 goto Cleanup;
992             }
993         }
994         else
995         {
996             switch ((Operand[0])->Common.Type)
997             {
998             case ACPI_TYPE_LOCAL_REFERENCE:
999                 /*
1000                  * This is a DerefOf (LocalX | ArgX)
1001                  *
1002                  * Must resolve/dereference the local/arg reference first
1003                  */
1004                 switch (Operand[0]->Reference.Class)
1005                 {
1006                 case ACPI_REFCLASS_LOCAL:
1007                 case ACPI_REFCLASS_ARG:
1008 
1009                     /* Set Operand[0] to the value of the local/arg */
1010 
1011                     Status = AcpiDsMethodDataGetValue (
1012                         Operand[0]->Reference.Class,
1013                         Operand[0]->Reference.Value,
1014                         WalkState, &TempDesc);
1015                     if (ACPI_FAILURE (Status))
1016                     {
1017                         goto Cleanup;
1018                     }
1019 
1020                     /*
1021                      * Delete our reference to the input object and
1022                      * point to the object just retrieved
1023                      */
1024                     AcpiUtRemoveReference (Operand[0]);
1025                     Operand[0] = TempDesc;
1026                     break;
1027 
1028                 case ACPI_REFCLASS_REFOF:
1029 
1030                     /* Get the object to which the reference refers */
1031 
1032                     TempDesc = Operand[0]->Reference.Object;
1033                     AcpiUtRemoveReference (Operand[0]);
1034                     Operand[0] = TempDesc;
1035                     break;
1036 
1037                 default:
1038 
1039                     /* Must be an Index op - handled below */
1040                     break;
1041                 }
1042                 break;
1043 
1044             case ACPI_TYPE_STRING:
1045 
1046                 break;
1047 
1048             default:
1049 
1050                 Status = AE_AML_OPERAND_TYPE;
1051                 goto Cleanup;
1052             }
1053         }
1054 
1055         if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) != ACPI_DESC_TYPE_NAMED)
1056         {
1057             if ((Operand[0])->Common.Type == ACPI_TYPE_STRING)
1058             {
1059                 /*
1060                  * This is a DerefOf (String). The string is a reference
1061                  * to a named ACPI object.
1062                  *
1063                  * 1) Find the owning Node
1064                  * 2) Dereference the node to an actual object. Could be a
1065                  *    Field, so we need to resolve the node to a value.
1066                  */
1067                 Status = AcpiNsGetNodeUnlocked (WalkState->ScopeInfo->Scope.Node,
1068                     Operand[0]->String.Pointer,
1069                     ACPI_NS_SEARCH_PARENT,
1070                     ACPI_CAST_INDIRECT_PTR (
1071                         ACPI_NAMESPACE_NODE, &ReturnDesc));
1072                 if (ACPI_FAILURE (Status))
1073                 {
1074                     goto Cleanup;
1075                 }
1076 
1077                 Status = AcpiExResolveNodeToValue (
1078                     ACPI_CAST_INDIRECT_PTR (
1079                         ACPI_NAMESPACE_NODE, &ReturnDesc),
1080                     WalkState);
1081                 goto Cleanup;
1082             }
1083         }
1084 
1085         /* Operand[0] may have changed from the code above */
1086 
1087         if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED)
1088         {
1089             /*
1090              * This is a DerefOf (ObjectReference)
1091              * Get the actual object from the Node (This is the dereference).
1092              * This case may only happen when a LocalX or ArgX is
1093              * dereferenced above, or for references to device and
1094              * thermal objects.
1095              */
1096             switch (((ACPI_NAMESPACE_NODE *) Operand[0])->Type)
1097             {
1098             case ACPI_TYPE_DEVICE:
1099             case ACPI_TYPE_THERMAL:
1100 
1101                 /* These types have no node subobject, return the NS node */
1102 
1103                 ReturnDesc = Operand[0];
1104                 break;
1105 
1106             default:
1107                 /* For most types, get the object attached to the node */
1108 
1109                 ReturnDesc = AcpiNsGetAttachedObject (
1110                     (ACPI_NAMESPACE_NODE *) Operand[0]);
1111                 AcpiUtAddReference (ReturnDesc);
1112                 break;
1113             }
1114         }
1115         else
1116         {
1117             /*
1118              * This must be a reference object produced by either the
1119              * Index() or RefOf() operator
1120              */
1121             switch (Operand[0]->Reference.Class)
1122             {
1123             case ACPI_REFCLASS_INDEX:
1124                 /*
1125                  * The target type for the Index operator must be
1126                  * either a Buffer or a Package
1127                  */
1128                 switch (Operand[0]->Reference.TargetType)
1129                 {
1130                 case ACPI_TYPE_BUFFER_FIELD:
1131 
1132                     TempDesc = Operand[0]->Reference.Object;
1133 
1134                     /*
1135                      * Create a new object that contains one element of the
1136                      * buffer -- the element pointed to by the index.
1137                      *
1138                      * NOTE: index into a buffer is NOT a pointer to a
1139                      * sub-buffer of the main buffer, it is only a pointer to a
1140                      * single element (byte) of the buffer!
1141                      *
1142                      * Since we are returning the value of the buffer at the
1143                      * indexed location, we don't need to add an additional
1144                      * reference to the buffer itself.
1145                      */
1146                     ReturnDesc = AcpiUtCreateIntegerObject ((UINT64)
1147                         TempDesc->Buffer.Pointer[Operand[0]->Reference.Value]);
1148                     if (!ReturnDesc)
1149                     {
1150                         Status = AE_NO_MEMORY;
1151                         goto Cleanup;
1152                     }
1153                     break;
1154 
1155                 case ACPI_TYPE_PACKAGE:
1156                     /*
1157                      * Return the referenced element of the package. We must
1158                      * add another reference to the referenced object, however.
1159                      */
1160                     ReturnDesc = *(Operand[0]->Reference.Where);
1161                     if (!ReturnDesc)
1162                     {
1163                         /*
1164                          * Element is NULL, do not allow the dereference.
1165                          * This provides compatibility with other ACPI
1166                          * implementations.
1167                          */
1168                         return_ACPI_STATUS (AE_AML_UNINITIALIZED_ELEMENT);
1169                     }
1170 
1171                     AcpiUtAddReference (ReturnDesc);
1172                     break;
1173 
1174                 default:
1175 
1176                     ACPI_ERROR ((AE_INFO,
1177                         "Unknown Index TargetType 0x%X in reference object %p",
1178                         Operand[0]->Reference.TargetType, Operand[0]));
1179 
1180                     Status = AE_AML_OPERAND_TYPE;
1181                     goto Cleanup;
1182                 }
1183                 break;
1184 
1185             case ACPI_REFCLASS_REFOF:
1186 
1187                 ReturnDesc = Operand[0]->Reference.Object;
1188 
1189                 if (ACPI_GET_DESCRIPTOR_TYPE (ReturnDesc) ==
1190                     ACPI_DESC_TYPE_NAMED)
1191                 {
1192                     ReturnDesc = AcpiNsGetAttachedObject (
1193                         (ACPI_NAMESPACE_NODE *) ReturnDesc);
1194                     if (!ReturnDesc)
1195                     {
1196                         break;
1197                     }
1198 
1199                    /*
1200                     * June 2013:
1201                     * BufferFields/FieldUnits require additional resolution
1202                     */
1203                     switch (ReturnDesc->Common.Type)
1204                     {
1205                     case ACPI_TYPE_BUFFER_FIELD:
1206                     case ACPI_TYPE_LOCAL_REGION_FIELD:
1207                     case ACPI_TYPE_LOCAL_BANK_FIELD:
1208                     case ACPI_TYPE_LOCAL_INDEX_FIELD:
1209 
1210                         Status = AcpiExReadDataFromField (
1211                             WalkState, ReturnDesc, &TempDesc);
1212                         if (ACPI_FAILURE (Status))
1213                         {
1214                             return_ACPI_STATUS (Status);
1215                         }
1216 
1217                         ReturnDesc = TempDesc;
1218                         break;
1219 
1220                     default:
1221 
1222                         /* Add another reference to the object */
1223 
1224                         AcpiUtAddReference (ReturnDesc);
1225                         break;
1226                     }
1227                 }
1228                 break;
1229 
1230             default:
1231 
1232                 ACPI_ERROR ((AE_INFO,
1233                     "Unknown class in reference(%p) - 0x%2.2X",
1234                     Operand[0], Operand[0]->Reference.Class));
1235 
1236                 Status = AE_TYPE;
1237                 goto Cleanup;
1238             }
1239         }
1240         break;
1241 
1242     default:
1243 
1244         ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
1245             WalkState->Opcode));
1246 
1247         Status = AE_AML_BAD_OPCODE;
1248         goto Cleanup;
1249     }
1250 
1251 
1252 Cleanup:
1253 
1254     /* Delete return object on error */
1255 
1256     if (ACPI_FAILURE (Status))
1257     {
1258         AcpiUtRemoveReference (ReturnDesc);
1259     }
1260 
1261     /* Save return object on success */
1262 
1263     else
1264     {
1265         WalkState->ResultObj = ReturnDesc;
1266     }
1267 
1268     return_ACPI_STATUS (Status);
1269 }
1270