185754Smsmith/******************************************************************************
285754Smsmith *
385754Smsmith * Module Name: exoparg1 - AML execution - opcodes with 1 argument
485754Smsmith *
585754Smsmith *****************************************************************************/
685754Smsmith
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
985754Smsmith * All rights reserved.
1085754Smsmith *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
2585754Smsmith *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
2985754Smsmith *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
4385754Smsmith
44193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
45193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
46193341Sjkim#include <contrib/dev/acpica/include/acparser.h>
47193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
48193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
49193341Sjkim#include <contrib/dev/acpica/include/amlcode.h>
50193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
5185754Smsmith
5285754Smsmith
5385754Smsmith#define _COMPONENT          ACPI_EXECUTER
5491116Smsmith        ACPI_MODULE_NAME    ("exoparg1")
5585754Smsmith
5685754Smsmith
5785754Smsmith/*!
5885754Smsmith * Naming convention for AML interpreter execution routines.
5985754Smsmith *
6085754Smsmith * The routines that begin execution of AML opcodes are named with a common
6185754Smsmith * convention based upon the number of arguments, the number of target operands,
6285754Smsmith * and whether or not a value is returned:
6385754Smsmith *
6485754Smsmith *      AcpiExOpcode_xA_yT_zR
6585754Smsmith *
6687031Smsmith * Where:
6785754Smsmith *
6887031Smsmith * xA - ARGUMENTS:    The number of arguments (input operands) that are
69138287Smarks *                    required for this opcode type (0 through 6 args).
7087031Smsmith * yT - TARGETS:      The number of targets (output operands) that are required
7185754Smsmith *                    for this opcode type (0, 1, or 2 targets).
7287031Smsmith * zR - RETURN VALUE: Indicates whether this opcode type returns a value
7385754Smsmith *                    as the function return (0 or 1).
7485754Smsmith *
7587031Smsmith * The AcpiExOpcode* functions are called via the Dispatcher component with
7685754Smsmith * fully resolved operands.
7785754Smsmith!*/
7885754Smsmith
7985754Smsmith/*******************************************************************************
8085754Smsmith *
81138287Smarks * FUNCTION:    AcpiExOpcode_0A_0T_1R
82138287Smarks *
83138287Smarks * PARAMETERS:  WalkState           - Current state (contains AML opcode)
84138287Smarks *
85138287Smarks * RETURN:      Status
86138287Smarks *
87138287Smarks * DESCRIPTION: Execute operator with no operands, one return value
88138287Smarks *
89138287Smarks ******************************************************************************/
90138287Smarks
91138287SmarksACPI_STATUS
92138287SmarksAcpiExOpcode_0A_0T_1R (
93138287Smarks    ACPI_WALK_STATE         *WalkState)
94138287Smarks{
95138287Smarks    ACPI_STATUS             Status = AE_OK;
96138287Smarks    ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
97138287Smarks
98138287Smarks
99167802Sjkim    ACPI_FUNCTION_TRACE_STR (ExOpcode_0A_0T_1R,
100151937Sjkim        AcpiPsGetOpcodeName (WalkState->Opcode));
101138287Smarks
102138287Smarks
103138287Smarks    /* Examine the AML opcode */
104138287Smarks
105138287Smarks    switch (WalkState->Opcode)
106138287Smarks    {
107138287Smarks    case AML_TIMER_OP:      /*  Timer () */
108138287Smarks
109138287Smarks        /* Create a return object of type Integer */
110138287Smarks
111199337Sjkim        ReturnDesc = AcpiUtCreateIntegerObject (AcpiOsGetTimer ());
112138287Smarks        if (!ReturnDesc)
113138287Smarks        {
114138287Smarks            Status = AE_NO_MEMORY;
115138287Smarks            goto Cleanup;
116138287Smarks        }
117138287Smarks        break;
118138287Smarks
119138287Smarks    default:                /*  Unknown opcode  */
120138287Smarks
121204773Sjkim        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
122138287Smarks            WalkState->Opcode));
123138287Smarks        Status = AE_AML_BAD_OPCODE;
124138287Smarks        break;
125138287Smarks    }
126138287Smarks
127138287SmarksCleanup:
128138287Smarks
129138287Smarks    /* Delete return object on error */
130138287Smarks
131151937Sjkim    if ((ACPI_FAILURE (Status)) || WalkState->ResultObj)
132138287Smarks    {
133138287Smarks        AcpiUtRemoveReference (ReturnDesc);
134167802Sjkim        WalkState->ResultObj = NULL;
135138287Smarks    }
136151937Sjkim    else
137151937Sjkim    {
138151937Sjkim        /* Save the return value */
139138287Smarks
140151937Sjkim        WalkState->ResultObj = ReturnDesc;
141151937Sjkim    }
142151937Sjkim
143138287Smarks    return_ACPI_STATUS (Status);
144138287Smarks}
145138287Smarks
146138287Smarks
147138287Smarks/*******************************************************************************
148138287Smarks *
14985754Smsmith * FUNCTION:    AcpiExOpcode_1A_0T_0R
15085754Smsmith *
15185754Smsmith * PARAMETERS:  WalkState           - Current state (contains AML opcode)
15285754Smsmith *
15385754Smsmith * RETURN:      Status
15485754Smsmith *
15585754Smsmith * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
15685754Smsmith *              object stack
15785754Smsmith *
15885754Smsmith ******************************************************************************/
15985754Smsmith
16085754SmsmithACPI_STATUS
16185754SmsmithAcpiExOpcode_1A_0T_0R (
16285754Smsmith    ACPI_WALK_STATE         *WalkState)
16385754Smsmith{
16485754Smsmith    ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
16585754Smsmith    ACPI_STATUS             Status = AE_OK;
16685754Smsmith
16785754Smsmith
168167802Sjkim    ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_0R,
169151937Sjkim        AcpiPsGetOpcodeName (WalkState->Opcode));
17085754Smsmith
17185754Smsmith
17287031Smsmith    /* Examine the AML opcode */
17385754Smsmith
17487031Smsmith    switch (WalkState->Opcode)
17585754Smsmith    {
17685754Smsmith    case AML_RELEASE_OP:    /*  Release (MutexObject) */
17785754Smsmith
17885754Smsmith        Status = AcpiExReleaseMutex (Operand[0], WalkState);
17985754Smsmith        break;
18085754Smsmith
18185754Smsmith    case AML_RESET_OP:      /*  Reset (EventObject) */
18285754Smsmith
18385754Smsmith        Status = AcpiExSystemResetEvent (Operand[0]);
18485754Smsmith        break;
18585754Smsmith
18685754Smsmith    case AML_SIGNAL_OP:     /*  Signal (EventObject) */
18785754Smsmith
18885754Smsmith        Status = AcpiExSystemSignalEvent (Operand[0]);
18985754Smsmith        break;
19085754Smsmith
19185754Smsmith    case AML_SLEEP_OP:      /*  Sleep (MsecTime) */
19285754Smsmith
193207344Sjkim        Status = AcpiExSystemDoSleep (Operand[0]->Integer.Value);
19485754Smsmith        break;
19585754Smsmith
19685754Smsmith    case AML_STALL_OP:      /*  Stall (UsecTime) */
19785754Smsmith
19891116Smsmith        Status = AcpiExSystemDoStall ((UINT32) Operand[0]->Integer.Value);
19985754Smsmith        break;
20085754Smsmith
20185754Smsmith    case AML_UNLOAD_OP:     /*  Unload (Handle) */
20285754Smsmith
20385754Smsmith        Status = AcpiExUnloadTable (Operand[0]);
20485754Smsmith        break;
20585754Smsmith
20685754Smsmith    default:                /*  Unknown opcode  */
20785754Smsmith
208204773Sjkim        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
20985754Smsmith            WalkState->Opcode));
21085754Smsmith        Status = AE_AML_BAD_OPCODE;
21185754Smsmith        break;
21285754Smsmith    }
21385754Smsmith
21485754Smsmith    return_ACPI_STATUS (Status);
21585754Smsmith}
21685754Smsmith
21785754Smsmith
21885754Smsmith/*******************************************************************************
21985754Smsmith *
22085754Smsmith * FUNCTION:    AcpiExOpcode_1A_1T_0R
22185754Smsmith *
22285754Smsmith * PARAMETERS:  WalkState           - Current state (contains AML opcode)
22385754Smsmith *
22485754Smsmith * RETURN:      Status
22585754Smsmith *
22685754Smsmith * DESCRIPTION: Execute opcode with one argument, one target, and no
22785754Smsmith *              return value.
22885754Smsmith *
22985754Smsmith ******************************************************************************/
23085754Smsmith
23185754SmsmithACPI_STATUS
23285754SmsmithAcpiExOpcode_1A_1T_0R (
23385754Smsmith    ACPI_WALK_STATE         *WalkState)
23485754Smsmith{
23585754Smsmith    ACPI_STATUS             Status = AE_OK;
23685754Smsmith    ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
23785754Smsmith
23885754Smsmith
239167802Sjkim    ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_0R,
240151937Sjkim        AcpiPsGetOpcodeName (WalkState->Opcode));
24185754Smsmith
24285754Smsmith
24387031Smsmith    /* Examine the AML opcode */
24487031Smsmith
24585754Smsmith    switch (WalkState->Opcode)
24685754Smsmith    {
24785754Smsmith    case AML_LOAD_OP:
24885754Smsmith
24991116Smsmith        Status = AcpiExLoadOp (Operand[0], Operand[1], WalkState);
25085754Smsmith        break;
25185754Smsmith
25285754Smsmith    default:                        /* Unknown opcode */
25385754Smsmith
254204773Sjkim        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
25585754Smsmith            WalkState->Opcode));
25685754Smsmith        Status = AE_AML_BAD_OPCODE;
25785754Smsmith        goto Cleanup;
25885754Smsmith    }
25985754Smsmith
26085754Smsmith
26185754SmsmithCleanup:
26285754Smsmith
26385754Smsmith    return_ACPI_STATUS (Status);
26485754Smsmith}
26585754Smsmith
26685754Smsmith
26785754Smsmith/*******************************************************************************
26885754Smsmith *
26985754Smsmith * FUNCTION:    AcpiExOpcode_1A_1T_1R
27085754Smsmith *
27185754Smsmith * PARAMETERS:  WalkState           - Current state (contains AML opcode)
27285754Smsmith *
27385754Smsmith * RETURN:      Status
27485754Smsmith *
27585754Smsmith * DESCRIPTION: Execute opcode with one argument, one target, and a
27685754Smsmith *              return value.
27785754Smsmith *
27885754Smsmith ******************************************************************************/
27985754Smsmith
28085754SmsmithACPI_STATUS
28185754SmsmithAcpiExOpcode_1A_1T_1R (
28285754Smsmith    ACPI_WALK_STATE         *WalkState)
28385754Smsmith{
28485754Smsmith    ACPI_STATUS             Status = AE_OK;
28585754Smsmith    ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
28685754Smsmith    ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
28785754Smsmith    ACPI_OPERAND_OBJECT     *ReturnDesc2 = NULL;
28885754Smsmith    UINT32                  Temp32;
28985754Smsmith    UINT32                  i;
290202771Sjkim    UINT64                  PowerOfTen;
291202771Sjkim    UINT64                  Digit;
29285754Smsmith
29385754Smsmith
294167802Sjkim    ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_1R,
295151937Sjkim        AcpiPsGetOpcodeName (WalkState->Opcode));
29685754Smsmith
29785754Smsmith
29899679Siwasaki    /* Examine the AML opcode */
29999679Siwasaki
30085754Smsmith    switch (WalkState->Opcode)
30185754Smsmith    {
30285754Smsmith    case AML_BIT_NOT_OP:
30385754Smsmith    case AML_FIND_SET_LEFT_BIT_OP:
30485754Smsmith    case AML_FIND_SET_RIGHT_BIT_OP:
30585754Smsmith    case AML_FROM_BCD_OP:
30685754Smsmith    case AML_TO_BCD_OP:
30785754Smsmith    case AML_COND_REF_OF_OP:
30885754Smsmith
30999679Siwasaki        /* Create a return object of type Integer for these opcodes */
31099679Siwasaki
31185754Smsmith        ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
31285754Smsmith        if (!ReturnDesc)
31385754Smsmith        {
31485754Smsmith            Status = AE_NO_MEMORY;
31585754Smsmith            goto Cleanup;
31685754Smsmith        }
31785754Smsmith
31899679Siwasaki        switch (WalkState->Opcode)
31999679Siwasaki        {
32099679Siwasaki        case AML_BIT_NOT_OP:            /* Not (Operand, Result)  */
32185754Smsmith
32299679Siwasaki            ReturnDesc->Integer.Value = ~Operand[0]->Integer.Value;
32399679Siwasaki            break;
32485754Smsmith
32599679Siwasaki        case AML_FIND_SET_LEFT_BIT_OP:  /* FindSetLeftBit (Operand, Result) */
32685754Smsmith
32799679Siwasaki            ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
32885754Smsmith
32999679Siwasaki            /*
33099679Siwasaki             * Acpi specification describes Integer type as a little
33199679Siwasaki             * endian unsigned value, so this boundary condition is valid.
33299679Siwasaki             */
333138287Smarks            for (Temp32 = 0; ReturnDesc->Integer.Value &&
334306536Sjkim                    Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
33599679Siwasaki            {
33699679Siwasaki                ReturnDesc->Integer.Value >>= 1;
33799679Siwasaki            }
33885754Smsmith
33999679Siwasaki            ReturnDesc->Integer.Value = Temp32;
34099679Siwasaki            break;
34185754Smsmith
342151937Sjkim        case AML_FIND_SET_RIGHT_BIT_OP: /* FindSetRightBit (Operand, Result) */
34385754Smsmith
34499679Siwasaki            ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
34585754Smsmith
34699679Siwasaki            /*
34799679Siwasaki             * The Acpi specification describes Integer type as a little
34899679Siwasaki             * endian unsigned value, so this boundary condition is valid.
34999679Siwasaki             */
350138287Smarks            for (Temp32 = 0; ReturnDesc->Integer.Value &&
351306536Sjkim                     Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
35299679Siwasaki            {
35399679Siwasaki                ReturnDesc->Integer.Value <<= 1;
35499679Siwasaki            }
35585754Smsmith
35699679Siwasaki            /* Since the bit position is one-based, subtract from 33 (65) */
35785754Smsmith
358167802Sjkim            ReturnDesc->Integer.Value =
359167802Sjkim                Temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - Temp32;
36099679Siwasaki            break;
36185754Smsmith
36299679Siwasaki        case AML_FROM_BCD_OP:           /* FromBcd (BCDValue, Result)  */
36399679Siwasaki            /*
364117521Snjl             * The 64-bit ACPI integer can hold 16 4-bit BCD characters
365117521Snjl             * (if table is 32-bit, integer can hold 8 BCD characters)
366117521Snjl             * Convert each 4-bit BCD value
36799679Siwasaki             */
368117521Snjl            PowerOfTen = 1;
36999679Siwasaki            ReturnDesc->Integer.Value = 0;
370117521Snjl            Digit = Operand[0]->Integer.Value;
371117521Snjl
372117521Snjl            /* Convert each BCD digit (each is one nybble wide) */
373117521Snjl
374117521Snjl            for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
37599679Siwasaki            {
376117521Snjl                /* Get the least significant 4-bit BCD digit */
37785754Smsmith
378117521Snjl                Temp32 = ((UINT32) Digit) & 0xF;
37985754Smsmith
38099679Siwasaki                /* Check the range of the digit */
38185754Smsmith
382117521Snjl                if (Temp32 > 9)
38399679Siwasaki                {
384167802Sjkim                    ACPI_ERROR ((AE_INFO,
385167802Sjkim                        "BCD digit too large (not decimal): 0x%X",
386117521Snjl                        Temp32));
387117521Snjl
38899679Siwasaki                    Status = AE_AML_NUMERIC_OVERFLOW;
38999679Siwasaki                    goto Cleanup;
39099679Siwasaki                }
39185754Smsmith
392117521Snjl                /* Sum the digit into the result with the current power of 10 */
39385754Smsmith
394167802Sjkim                ReturnDesc->Integer.Value +=
395202771Sjkim                    (((UINT64) Temp32) * PowerOfTen);
39685754Smsmith
397117521Snjl                /* Shift to next BCD digit */
398117521Snjl
399117521Snjl                Digit >>= 4;
400117521Snjl
401117521Snjl                /* Next power of 10 */
402117521Snjl
403117521Snjl                PowerOfTen *= 10;
40499679Siwasaki            }
40599679Siwasaki            break;
40699679Siwasaki
40799679Siwasaki        case AML_TO_BCD_OP:             /* ToBcd (Operand, Result)  */
40899679Siwasaki
409117521Snjl            ReturnDesc->Integer.Value = 0;
410117521Snjl            Digit = Operand[0]->Integer.Value;
411117521Snjl
412117521Snjl            /* Each BCD digit is one nybble wide */
413117521Snjl
414117521Snjl            for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
41585754Smsmith            {
416138287Smarks                (void) AcpiUtShortDivide (Digit, 10, &Digit, &Temp32);
417117521Snjl
418151937Sjkim                /*
419151937Sjkim                 * Insert the BCD digit that resides in the
420151937Sjkim                 * remainder from above
421151937Sjkim                 */
422167802Sjkim                ReturnDesc->Integer.Value |=
423202771Sjkim                    (((UINT64) Temp32) << ACPI_MUL_4 (i));
424117521Snjl            }
425117521Snjl
426117521Snjl            /* Overflow if there is any data left in Digit */
427117521Snjl
428117521Snjl            if (Digit > 0)
429117521Snjl            {
430167802Sjkim                ACPI_ERROR ((AE_INFO,
431204773Sjkim                    "Integer too large to convert to BCD: 0x%8.8X%8.8X",
432138287Smarks                    ACPI_FORMAT_UINT64 (Operand[0]->Integer.Value)));
43385754Smsmith                Status = AE_AML_NUMERIC_OVERFLOW;
43485754Smsmith                goto Cleanup;
43585754Smsmith            }
43699679Siwasaki            break;
43785754Smsmith
43899679Siwasaki        case AML_COND_REF_OF_OP:        /* CondRefOf (SourceObject, Result)  */
43999679Siwasaki            /*
44099679Siwasaki             * This op is a little strange because the internal return value is
44199679Siwasaki             * different than the return value stored in the result descriptor
44299679Siwasaki             * (There are really two return values)
44399679Siwasaki             */
44499679Siwasaki            if ((ACPI_NAMESPACE_NODE *) Operand[0] == AcpiGbl_RootNode)
44599679Siwasaki            {
44699679Siwasaki                /*
44799679Siwasaki                 * This means that the object does not exist in the namespace,
44899679Siwasaki                 * return FALSE
44999679Siwasaki                 */
45099679Siwasaki                ReturnDesc->Integer.Value = 0;
45199679Siwasaki                goto Cleanup;
45285754Smsmith            }
45385754Smsmith
454100966Siwasaki            /* Get the object reference, store it, and remove our reference */
45585754Smsmith
456151937Sjkim            Status = AcpiExGetObjectReference (Operand[0],
457306536Sjkim                &ReturnDesc2, WalkState);
45899679Siwasaki            if (ACPI_FAILURE (Status))
45985754Smsmith            {
46099679Siwasaki                goto Cleanup;
46185754Smsmith            }
46285754Smsmith
46399679Siwasaki            Status = AcpiExStore (ReturnDesc2, Operand[1], WalkState);
464100966Siwasaki            AcpiUtRemoveReference (ReturnDesc2);
46585754Smsmith
46699679Siwasaki            /* The object exists in the namespace, return TRUE */
46785754Smsmith
468202771Sjkim            ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
46985754Smsmith            goto Cleanup;
47085754Smsmith
47185754Smsmith
47299679Siwasaki        default:
473250838Sjkim
47499679Siwasaki            /* No other opcodes get here */
475250838Sjkim
47699679Siwasaki            break;
47785754Smsmith        }
47899679Siwasaki        break;
47985754Smsmith
48085754Smsmith    case AML_STORE_OP:              /* Store (Source, Target) */
48185754Smsmith        /*
48285754Smsmith         * A store operand is typically a number, string, buffer or lvalue
48385754Smsmith         * Be careful about deleting the source object,
48485754Smsmith         * since the object itself may have been stored.
48585754Smsmith         */
48685754Smsmith        Status = AcpiExStore (Operand[0], Operand[1], WalkState);
48785754Smsmith        if (ACPI_FAILURE (Status))
48885754Smsmith        {
48985754Smsmith            return_ACPI_STATUS (Status);
49085754Smsmith        }
49185754Smsmith
492107325Siwasaki        /* It is possible that the Store already produced a return object */
493107325Siwasaki
494107325Siwasaki        if (!WalkState->ResultObj)
495107325Siwasaki        {
496107325Siwasaki            /*
497151937Sjkim             * Normally, we would remove a reference on the Operand[0]
498151937Sjkim             * parameter; But since it is being used as the internal return
499151937Sjkim             * object (meaning we would normally increment it), the two
500151937Sjkim             * cancel out, and we simply don't do anything.
501107325Siwasaki             */
502107325Siwasaki            WalkState->ResultObj = Operand[0];
503107325Siwasaki            WalkState->Operands[0] = NULL;  /* Prevent deletion */
504107325Siwasaki        }
50585754Smsmith        return_ACPI_STATUS (Status);
50685754Smsmith
50785754Smsmith    /*
50885754Smsmith     * ACPI 2.0 Opcodes
50985754Smsmith     */
51085754Smsmith    case AML_COPY_OP:               /* Copy (Source, Target) */
51185754Smsmith
512306536Sjkim        Status = AcpiUtCopyIobjectToIobject (
513306536Sjkim            Operand[0], &ReturnDesc, WalkState);
51485754Smsmith        break;
51585754Smsmith
51685754Smsmith    case AML_TO_DECSTRING_OP:       /* ToDecimalString (Data, Result) */
51785754Smsmith
518306536Sjkim        Status = AcpiExConvertToString (
519306536Sjkim            Operand[0], &ReturnDesc, ACPI_EXPLICIT_CONVERT_DECIMAL);
520151937Sjkim        if (ReturnDesc == Operand[0])
521151937Sjkim        {
522151937Sjkim            /* No conversion performed, add ref to handle return value */
523306536Sjkim
524151937Sjkim            AcpiUtAddReference (ReturnDesc);
525151937Sjkim        }
52685754Smsmith        break;
52785754Smsmith
52885754Smsmith    case AML_TO_HEXSTRING_OP:       /* ToHexString (Data, Result) */
52985754Smsmith
530306536Sjkim        Status = AcpiExConvertToString (
531306536Sjkim            Operand[0], &ReturnDesc, ACPI_EXPLICIT_CONVERT_HEX);
532151937Sjkim        if (ReturnDesc == Operand[0])
533151937Sjkim        {
534151937Sjkim            /* No conversion performed, add ref to handle return value */
535306536Sjkim
536151937Sjkim            AcpiUtAddReference (ReturnDesc);
537151937Sjkim        }
53885754Smsmith        break;
53985754Smsmith
54085754Smsmith    case AML_TO_BUFFER_OP:          /* ToBuffer (Data, Result) */
54185754Smsmith
542138287Smarks        Status = AcpiExConvertToBuffer (Operand[0], &ReturnDesc);
543151937Sjkim        if (ReturnDesc == Operand[0])
544151937Sjkim        {
545151937Sjkim            /* No conversion performed, add ref to handle return value */
546306536Sjkim
547151937Sjkim            AcpiUtAddReference (ReturnDesc);
548151937Sjkim        }
54985754Smsmith        break;
55085754Smsmith
55185754Smsmith    case AML_TO_INTEGER_OP:         /* ToInteger (Data, Result) */
55285754Smsmith
553306536Sjkim        Status = AcpiExConvertToInteger (
554306536Sjkim            Operand[0], &ReturnDesc, ACPI_ANY_BASE);
555151937Sjkim        if (ReturnDesc == Operand[0])
556151937Sjkim        {
557151937Sjkim            /* No conversion performed, add ref to handle return value */
558306536Sjkim
559151937Sjkim            AcpiUtAddReference (ReturnDesc);
560151937Sjkim        }
56185754Smsmith        break;
56285754Smsmith
563138287Smarks    case AML_SHIFT_LEFT_BIT_OP:     /* ShiftLeftBit (Source, BitNum)  */
564138287Smarks    case AML_SHIFT_RIGHT_BIT_OP:    /* ShiftRightBit (Source, BitNum) */
56585754Smsmith
566151937Sjkim        /* These are two obsolete opcodes */
567151937Sjkim
568167802Sjkim        ACPI_ERROR ((AE_INFO,
569167802Sjkim            "%s is obsolete and not implemented",
570138287Smarks            AcpiPsGetOpcodeName (WalkState->Opcode)));
57185754Smsmith        Status = AE_SUPPORT;
57285754Smsmith        goto Cleanup;
57385754Smsmith
57485754Smsmith    default:                        /* Unknown opcode */
57585754Smsmith
576204773Sjkim        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
57785754Smsmith            WalkState->Opcode));
57885754Smsmith        Status = AE_AML_BAD_OPCODE;
57985754Smsmith        goto Cleanup;
58085754Smsmith    }
58185754Smsmith
582151937Sjkim    if (ACPI_SUCCESS (Status))
583151937Sjkim    {
584151937Sjkim        /* Store the return value computed above into the target object */
58585754Smsmith
586151937Sjkim        Status = AcpiExStore (ReturnDesc, Operand[1], WalkState);
587151937Sjkim    }
58885754Smsmith
589151937Sjkim
59085754SmsmithCleanup:
59185754Smsmith
59285754Smsmith    /* Delete return object on error */
59385754Smsmith
59485754Smsmith    if (ACPI_FAILURE (Status))
59585754Smsmith    {
59685754Smsmith        AcpiUtRemoveReference (ReturnDesc);
59785754Smsmith    }
59885754Smsmith
599167802Sjkim    /* Save return object on success */
600167802Sjkim
601167802Sjkim    else if (!WalkState->ResultObj)
602167802Sjkim    {
603167802Sjkim        WalkState->ResultObj = ReturnDesc;
604167802Sjkim    }
605167802Sjkim
60685754Smsmith    return_ACPI_STATUS (Status);
60785754Smsmith}
60885754Smsmith
60985754Smsmith
61085754Smsmith/*******************************************************************************
61185754Smsmith *
61285754Smsmith * FUNCTION:    AcpiExOpcode_1A_0T_1R
61385754Smsmith *
61485754Smsmith * PARAMETERS:  WalkState           - Current state (contains AML opcode)
61585754Smsmith *
61685754Smsmith * RETURN:      Status
61785754Smsmith *
61885754Smsmith * DESCRIPTION: Execute opcode with one argument, no target, and a return value
61985754Smsmith *
62085754Smsmith ******************************************************************************/
62185754Smsmith
62285754SmsmithACPI_STATUS
62385754SmsmithAcpiExOpcode_1A_0T_1R (
62485754Smsmith    ACPI_WALK_STATE         *WalkState)
62585754Smsmith{
62685754Smsmith    ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
62785754Smsmith    ACPI_OPERAND_OBJECT     *TempDesc;
62885754Smsmith    ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
62985754Smsmith    ACPI_STATUS             Status = AE_OK;
63085754Smsmith    UINT32                  Type;
631202771Sjkim    UINT64                  Value;
63285754Smsmith
63385754Smsmith
634167802Sjkim    ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_1R,
635151937Sjkim        AcpiPsGetOpcodeName (WalkState->Opcode));
63685754Smsmith
63785754Smsmith
63887031Smsmith    /* Examine the AML opcode */
63985754Smsmith
64085754Smsmith    switch (WalkState->Opcode)
64185754Smsmith    {
64285754Smsmith    case AML_LNOT_OP:               /* LNot (Operand) */
64385754Smsmith
644199337Sjkim        ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) 0);
64585754Smsmith        if (!ReturnDesc)
64685754Smsmith        {
64785754Smsmith            Status = AE_NO_MEMORY;
64885754Smsmith            goto Cleanup;
64985754Smsmith        }
65085754Smsmith
651138287Smarks        /*
652241973Sjkim         * Set result to ONES (TRUE) if Value == 0. Note:
653138287Smarks         * ReturnDesc->Integer.Value is initially == 0 (FALSE) from above.
654138287Smarks         */
655138287Smarks        if (!Operand[0]->Integer.Value)
656138287Smarks        {
657202771Sjkim            ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
658138287Smarks        }
65985754Smsmith        break;
66085754Smsmith
66185754Smsmith    case AML_DECREMENT_OP:          /* Decrement (Operand)  */
66285754Smsmith    case AML_INCREMENT_OP:          /* Increment (Operand)  */
66385754Smsmith        /*
664241973Sjkim         * Create a new integer. Can't just get the base integer and
665138287Smarks         * increment it because it may be an Arg or Field.
66685754Smsmith         */
667138287Smarks        ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
668138287Smarks        if (!ReturnDesc)
66985754Smsmith        {
670138287Smarks            Status = AE_NO_MEMORY;
671138287Smarks            goto Cleanup;
672138287Smarks        }
673138287Smarks
674138287Smarks        /*
675138287Smarks         * Since we are expecting a Reference operand, it can be either a
676138287Smarks         * NS Node or an internal object.
677138287Smarks         */
678138287Smarks        TempDesc = Operand[0];
679138287Smarks        if (ACPI_GET_DESCRIPTOR_TYPE (TempDesc) == ACPI_DESC_TYPE_OPERAND)
680138287Smarks        {
68185754Smsmith            /* Internal reference object - prevent deletion */
68285754Smsmith
683138287Smarks            AcpiUtAddReference (TempDesc);
68485754Smsmith        }
68585754Smsmith
68685754Smsmith        /*
687138287Smarks         * Convert the Reference operand to an Integer (This removes a
688138287Smarks         * reference on the Operand[0] object)
689138287Smarks         *
690138287Smarks         * NOTE:  We use LNOT_OP here in order to force resolution of the
691138287Smarks         * reference operand to an actual integer.
69285754Smsmith         */
693138287Smarks        Status = AcpiExResolveOperands (AML_LNOT_OP, &TempDesc, WalkState);
69485754Smsmith        if (ACPI_FAILURE (Status))
69585754Smsmith        {
696167802Sjkim            ACPI_EXCEPTION ((AE_INFO, Status,
697167802Sjkim                "While resolving operands for [%s]",
698167802Sjkim                AcpiPsGetOpcodeName (WalkState->Opcode)));
69985754Smsmith
70085754Smsmith            goto Cleanup;
70185754Smsmith        }
70285754Smsmith
70387031Smsmith        /*
704138287Smarks         * TempDesc is now guaranteed to be an Integer object --
705138287Smarks         * Perform the actual increment or decrement
70685754Smsmith         */
707138287Smarks        if (WalkState->Opcode == AML_INCREMENT_OP)
70885754Smsmith        {
709306536Sjkim            ReturnDesc->Integer.Value = TempDesc->Integer.Value + 1;
71085754Smsmith        }
71185754Smsmith        else
71285754Smsmith        {
713306536Sjkim            ReturnDesc->Integer.Value = TempDesc->Integer.Value - 1;
71485754Smsmith        }
71585754Smsmith
716138287Smarks        /* Finished with this Integer object */
71785754Smsmith
718138287Smarks        AcpiUtRemoveReference (TempDesc);
719138287Smarks
720138287Smarks        /*
721138287Smarks         * Store the result back (indirectly) through the original
722138287Smarks         * Reference object
723138287Smarks         */
72485754Smsmith        Status = AcpiExStore (ReturnDesc, Operand[0], WalkState);
72585754Smsmith        break;
72685754Smsmith
727306536Sjkim    case AML_OBJECT_TYPE_OP:            /* ObjectType (SourceObject) */
728138287Smarks        /*
729138287Smarks         * Note: The operand is not resolved at this point because we want to
730241973Sjkim         * get the associated object, not its value. For example, we don't
731151937Sjkim         * want to resolve a FieldUnit to its value, we want the actual
732151937Sjkim         * FieldUnit object.
733138287Smarks         */
734138287Smarks
735104470Siwasaki        /* Get the type of the base object */
73685754Smsmith
737104470Siwasaki        Status = AcpiExResolveMultiple (WalkState, Operand[0], &Type, NULL);
738104470Siwasaki        if (ACPI_FAILURE (Status))
73985754Smsmith        {
740104470Siwasaki            goto Cleanup;
74185754Smsmith        }
742167802Sjkim
74385754Smsmith        /* Allocate a descriptor to hold the type. */
74485754Smsmith
745199337Sjkim        ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) Type);
74685754Smsmith        if (!ReturnDesc)
74785754Smsmith        {
74885754Smsmith            Status = AE_NO_MEMORY;
74985754Smsmith            goto Cleanup;
75085754Smsmith        }
75185754Smsmith        break;
75285754Smsmith
75385754Smsmith    case AML_SIZE_OF_OP:            /* SizeOf (SourceObject)  */
754138287Smarks        /*
755138287Smarks         * Note: The operand is not resolved at this point because we want to
756138287Smarks         * get the associated object, not its value.
757138287Smarks         */
758138287Smarks
759104470Siwasaki        /* Get the base object */
760104470Siwasaki
761306536Sjkim        Status = AcpiExResolveMultiple (
762306536Sjkim            WalkState, Operand[0], &Type, &TempDesc);
763104470Siwasaki        if (ACPI_FAILURE (Status))
76485754Smsmith        {
765104470Siwasaki            goto Cleanup;
76685754Smsmith        }
76785754Smsmith
768104470Siwasaki        /*
769138287Smarks         * The type of the base object must be integer, buffer, string, or
770241973Sjkim         * package. All others are not supported.
771138287Smarks         *
772138287Smarks         * NOTE: Integer is not specifically supported by the ACPI spec,
773138287Smarks         * but is supported implicitly via implicit operand conversion.
774138287Smarks         * rather than bother with conversion, we just use the byte width
775138287Smarks         * global (4 or 8 bytes).
776104470Siwasaki         */
777104470Siwasaki        switch (Type)
77885754Smsmith        {
779138287Smarks        case ACPI_TYPE_INTEGER:
780250838Sjkim
781138287Smarks            Value = AcpiGbl_IntegerByteWidth;
782138287Smarks            break;
783138287Smarks
784193267Sjkim        case ACPI_TYPE_STRING:
785250838Sjkim
786193267Sjkim            Value = TempDesc->String.Length;
787193267Sjkim            break;
788193267Sjkim
789104470Siwasaki        case ACPI_TYPE_BUFFER:
790193267Sjkim
791193267Sjkim            /* Buffer arguments may not be evaluated at this point */
792193267Sjkim
793193267Sjkim            Status = AcpiDsGetBufferArguments (TempDesc);
794104470Siwasaki            Value = TempDesc->Buffer.Length;
795104470Siwasaki            break;
79685754Smsmith
797193267Sjkim        case ACPI_TYPE_PACKAGE:
79885754Smsmith
799193267Sjkim            /* Package arguments may not be evaluated at this point */
800193267Sjkim
801193267Sjkim            Status = AcpiDsGetPackageArguments (TempDesc);
802104470Siwasaki            Value = TempDesc->Package.Count;
803104470Siwasaki            break;
80485754Smsmith
805104470Siwasaki        default:
806250838Sjkim
807167802Sjkim            ACPI_ERROR ((AE_INFO,
808306536Sjkim                "Operand must be Buffer/Integer/String/Package"
809306536Sjkim                " - found type %s",
810104470Siwasaki                AcpiUtGetTypeName (Type)));
811306536Sjkim
812104470Siwasaki            Status = AE_AML_OPERAND_TYPE;
813104470Siwasaki            goto Cleanup;
81485754Smsmith        }
81585754Smsmith
816193267Sjkim        if (ACPI_FAILURE (Status))
817193267Sjkim        {
818193267Sjkim            goto Cleanup;
819193267Sjkim        }
820193267Sjkim
82185754Smsmith        /*
82285754Smsmith         * Now that we have the size of the object, create a result
82385754Smsmith         * object to hold the value
82485754Smsmith         */
825199337Sjkim        ReturnDesc = AcpiUtCreateIntegerObject (Value);
82685754Smsmith        if (!ReturnDesc)
82785754Smsmith        {
82885754Smsmith            Status = AE_NO_MEMORY;
82985754Smsmith            goto Cleanup;
83085754Smsmith        }
83185754Smsmith        break;
83285754Smsmith
83385754Smsmith
83485754Smsmith    case AML_REF_OF_OP:             /* RefOf (SourceObject) */
83585754Smsmith
836306536Sjkim        Status = AcpiExGetObjectReference (
837306536Sjkim            Operand[0], &ReturnDesc, WalkState);
83885754Smsmith        if (ACPI_FAILURE (Status))
83985754Smsmith        {
84085754Smsmith            goto Cleanup;
84185754Smsmith        }
84285754Smsmith        break;
84385754Smsmith
84485754Smsmith
84591116Smsmith    case AML_DEREF_OF_OP:           /* DerefOf (ObjReference | String) */
84685754Smsmith
84791116Smsmith        /* Check for a method local or argument, or standalone String */
84885754Smsmith
849167802Sjkim        if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED)
85085754Smsmith        {
851167802Sjkim            TempDesc = AcpiNsGetAttachedObject (
852167802Sjkim                           (ACPI_NAMESPACE_NODE *) Operand[0]);
853167802Sjkim            if (TempDesc &&
854193267Sjkim                 ((TempDesc->Common.Type == ACPI_TYPE_STRING) ||
855193267Sjkim                  (TempDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)))
856167802Sjkim            {
857167802Sjkim                Operand[0] = TempDesc;
858167802Sjkim                AcpiUtAddReference (TempDesc);
859167802Sjkim            }
860167802Sjkim            else
861167802Sjkim            {
862167802Sjkim                Status = AE_AML_OPERAND_TYPE;
863167802Sjkim                goto Cleanup;
864167802Sjkim            }
865167802Sjkim        }
866167802Sjkim        else
867167802Sjkim        {
868193267Sjkim            switch ((Operand[0])->Common.Type)
86985754Smsmith            {
870107325Siwasaki            case ACPI_TYPE_LOCAL_REFERENCE:
87191116Smsmith                /*
87291116Smsmith                 * This is a DerefOf (LocalX | ArgX)
87391116Smsmith                 *
87491116Smsmith                 * Must resolve/dereference the local/arg reference first
87591116Smsmith                 */
876193267Sjkim                switch (Operand[0]->Reference.Class)
87791116Smsmith                {
878193267Sjkim                case ACPI_REFCLASS_LOCAL:
879193267Sjkim                case ACPI_REFCLASS_ARG:
88085754Smsmith
88191116Smsmith                    /* Set Operand[0] to the value of the local/arg */
88287031Smsmith
883151937Sjkim                    Status = AcpiDsMethodDataGetValue (
884306536Sjkim                        Operand[0]->Reference.Class,
885306536Sjkim                        Operand[0]->Reference.Value,
886306536Sjkim                        WalkState, &TempDesc);
88799679Siwasaki                    if (ACPI_FAILURE (Status))
88899679Siwasaki                    {
88999679Siwasaki                        goto Cleanup;
89099679Siwasaki                    }
89185754Smsmith
89291116Smsmith                    /*
89391116Smsmith                     * Delete our reference to the input object and
89491116Smsmith                     * point to the object just retrieved
89591116Smsmith                     */
89691116Smsmith                    AcpiUtRemoveReference (Operand[0]);
89791116Smsmith                    Operand[0] = TempDesc;
89891116Smsmith                    break;
89991116Smsmith
900193267Sjkim                case ACPI_REFCLASS_REFOF:
901100966Siwasaki
902100966Siwasaki                    /* Get the object to which the reference refers */
903100966Siwasaki
904100966Siwasaki                    TempDesc = Operand[0]->Reference.Object;
905100966Siwasaki                    AcpiUtRemoveReference (Operand[0]);
906100966Siwasaki                    Operand[0] = TempDesc;
907100966Siwasaki                    break;
908100966Siwasaki
90991116Smsmith                default:
91091116Smsmith
91191116Smsmith                    /* Must be an Index op - handled below */
91291116Smsmith                    break;
91391116Smsmith                }
91491116Smsmith                break;
91591116Smsmith
91691116Smsmith            case ACPI_TYPE_STRING:
917250838Sjkim
918167802Sjkim                break;
91991116Smsmith
920167802Sjkim            default:
921250838Sjkim
922167802Sjkim                Status = AE_AML_OPERAND_TYPE;
923167802Sjkim                goto Cleanup;
924167802Sjkim            }
925167802Sjkim        }
926167802Sjkim
927167802Sjkim        if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) != ACPI_DESC_TYPE_NAMED)
928167802Sjkim        {
929193267Sjkim            if ((Operand[0])->Common.Type == ACPI_TYPE_STRING)
930167802Sjkim            {
93185754Smsmith                /*
932167802Sjkim                 * This is a DerefOf (String). The string is a reference
933151937Sjkim                 * to a named ACPI object.
93491116Smsmith                 *
93591116Smsmith                 * 1) Find the owning Node
936167802Sjkim                 * 2) Dereference the node to an actual object. Could be a
937151937Sjkim                 *    Field, so we need to resolve the node to a value.
93885754Smsmith                 */
939167802Sjkim                Status = AcpiNsGetNode (WalkState->ScopeInfo->Scope.Node,
940306536Sjkim                    Operand[0]->String.Pointer,
941306536Sjkim                    ACPI_NS_SEARCH_PARENT,
942306536Sjkim                    ACPI_CAST_INDIRECT_PTR (
943306536Sjkim                        ACPI_NAMESPACE_NODE, &ReturnDesc));
94491116Smsmith                if (ACPI_FAILURE (Status))
94591116Smsmith                {
94691116Smsmith                    goto Cleanup;
94791116Smsmith                }
94885754Smsmith
94999679Siwasaki                Status = AcpiExResolveNodeToValue (
950306536Sjkim                    ACPI_CAST_INDIRECT_PTR (
951306536Sjkim                        ACPI_NAMESPACE_NODE, &ReturnDesc),
952306536Sjkim                    WalkState);
95391116Smsmith                goto Cleanup;
95485754Smsmith            }
95585754Smsmith        }
95685754Smsmith
95785754Smsmith        /* Operand[0] may have changed from the code above */
95885754Smsmith
95991116Smsmith        if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED)
96085754Smsmith        {
96191116Smsmith            /*
96291116Smsmith             * This is a DerefOf (ObjectReference)
96391116Smsmith             * Get the actual object from the Node (This is the dereference).
964151937Sjkim             * This case may only happen when a LocalX or ArgX is
965151937Sjkim             * dereferenced above.
96691116Smsmith             */
967151937Sjkim            ReturnDesc = AcpiNsGetAttachedObject (
968306536Sjkim                (ACPI_NAMESPACE_NODE *) Operand[0]);
969151937Sjkim            AcpiUtAddReference (ReturnDesc);
97085754Smsmith        }
97185754Smsmith        else
97285754Smsmith        {
97385754Smsmith            /*
974151937Sjkim             * This must be a reference object produced by either the
975151937Sjkim             * Index() or RefOf() operator
97685754Smsmith             */
977193267Sjkim            switch (Operand[0]->Reference.Class)
97885754Smsmith            {
979193267Sjkim            case ACPI_REFCLASS_INDEX:
98085754Smsmith                /*
98187031Smsmith                 * The target type for the Index operator must be
98287031Smsmith                 * either a Buffer or a Package
98385754Smsmith                 */
98487031Smsmith                switch (Operand[0]->Reference.TargetType)
98585754Smsmith                {
98687031Smsmith                case ACPI_TYPE_BUFFER_FIELD:
98799146Siwasaki
98899146Siwasaki                    TempDesc = Operand[0]->Reference.Object;
98999146Siwasaki
99085754Smsmith                    /*
991102550Siwasaki                     * Create a new object that contains one element of the
99299146Siwasaki                     * buffer -- the element pointed to by the index.
99385754Smsmith                     *
99485754Smsmith                     * NOTE: index into a buffer is NOT a pointer to a
99585754Smsmith                     * sub-buffer of the main buffer, it is only a pointer to a
99685754Smsmith                     * single element (byte) of the buffer!
997199337Sjkim                     *
998199337Sjkim                     * Since we are returning the value of the buffer at the
999199337Sjkim                     * indexed location, we don't need to add an additional
1000199337Sjkim                     * reference to the buffer itself.
100185754Smsmith                     */
1002199337Sjkim                    ReturnDesc = AcpiUtCreateIntegerObject ((UINT64)
1003199337Sjkim                        TempDesc->Buffer.Pointer[Operand[0]->Reference.Value]);
100485754Smsmith                    if (!ReturnDesc)
100585754Smsmith                    {
100685754Smsmith                        Status = AE_NO_MEMORY;
100785754Smsmith                        goto Cleanup;
100885754Smsmith                    }
100987031Smsmith                    break;
101085754Smsmith
101187031Smsmith                case ACPI_TYPE_PACKAGE:
101285754Smsmith                    /*
1013241973Sjkim                     * Return the referenced element of the package. We must
1014151937Sjkim                     * add another reference to the referenced object, however.
101585754Smsmith                     */
101685754Smsmith                    ReturnDesc = *(Operand[0]->Reference.Where);
1017253690Sjkim                    if (!ReturnDesc)
101885754Smsmith                    {
1019253690Sjkim                        /*
1020253690Sjkim                         * Element is NULL, do not allow the dereference.
1021253690Sjkim                         * This provides compatibility with other ACPI
1022253690Sjkim                         * implementations.
1023253690Sjkim                         */
1024253690Sjkim                        return_ACPI_STATUS (AE_AML_UNINITIALIZED_ELEMENT);
102585754Smsmith                    }
1026253690Sjkim
1027253690Sjkim                    AcpiUtAddReference (ReturnDesc);
102887031Smsmith                    break;
102985754Smsmith
103087031Smsmith                default:
103187031Smsmith
1032167802Sjkim                    ACPI_ERROR ((AE_INFO,
1033204773Sjkim                        "Unknown Index TargetType 0x%X in reference object %p",
103485754Smsmith                        Operand[0]->Reference.TargetType, Operand[0]));
1035306536Sjkim
103685754Smsmith                    Status = AE_AML_OPERAND_TYPE;
103785754Smsmith                    goto Cleanup;
103885754Smsmith                }
103985754Smsmith                break;
104085754Smsmith
1041193267Sjkim            case ACPI_REFCLASS_REFOF:
104285754Smsmith
104385754Smsmith                ReturnDesc = Operand[0]->Reference.Object;
104485754Smsmith
1045151937Sjkim                if (ACPI_GET_DESCRIPTOR_TYPE (ReturnDesc) ==
1046253690Sjkim                    ACPI_DESC_TYPE_NAMED)
1047100966Siwasaki                {
1048151937Sjkim                    ReturnDesc = AcpiNsGetAttachedObject (
1049253690Sjkim                        (ACPI_NAMESPACE_NODE *) ReturnDesc);
1050253690Sjkim                    if (!ReturnDesc)
1051253690Sjkim                    {
1052253690Sjkim                        break;
1053253690Sjkim                    }
1054100966Siwasaki
1055253690Sjkim                   /*
1056253690Sjkim                    * June 2013:
1057253690Sjkim                    * BufferFields/FieldUnits require additional resolution
1058253690Sjkim                    */
1059253690Sjkim                    switch (ReturnDesc->Common.Type)
1060253690Sjkim                    {
1061253690Sjkim                    case ACPI_TYPE_BUFFER_FIELD:
1062253690Sjkim                    case ACPI_TYPE_LOCAL_REGION_FIELD:
1063253690Sjkim                    case ACPI_TYPE_LOCAL_BANK_FIELD:
1064253690Sjkim                    case ACPI_TYPE_LOCAL_INDEX_FIELD:
106585754Smsmith
1066306536Sjkim                        Status = AcpiExReadDataFromField (
1067306536Sjkim                            WalkState, ReturnDesc, &TempDesc);
1068253690Sjkim                        if (ACPI_FAILURE (Status))
1069253690Sjkim                        {
1070253690Sjkim                            goto Cleanup;
1071253690Sjkim                        }
1072253690Sjkim
1073253690Sjkim                        ReturnDesc = TempDesc;
1074253690Sjkim                        break;
1075253690Sjkim
1076253690Sjkim                    default:
1077253690Sjkim
1078253690Sjkim                        /* Add another reference to the object */
1079253690Sjkim
1080253690Sjkim                        AcpiUtAddReference (ReturnDesc);
1081253690Sjkim                        break;
1082253690Sjkim                    }
1083253690Sjkim                }
108485754Smsmith                break;
108587031Smsmith
1086250838Sjkim            default:
108787031Smsmith
1088167802Sjkim                ACPI_ERROR ((AE_INFO,
1089204773Sjkim                    "Unknown class in reference(%p) - 0x%2.2X",
1090193267Sjkim                    Operand[0], Operand[0]->Reference.Class));
109187031Smsmith
109287031Smsmith                Status = AE_TYPE;
109387031Smsmith                goto Cleanup;
109485754Smsmith            }
109585754Smsmith        }
109685754Smsmith        break;
109785754Smsmith
109885754Smsmith    default:
109985754Smsmith
1100204773Sjkim        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
110185754Smsmith            WalkState->Opcode));
1102306536Sjkim
110385754Smsmith        Status = AE_AML_BAD_OPCODE;
110485754Smsmith        goto Cleanup;
110585754Smsmith    }
110685754Smsmith
110785754Smsmith
110885754SmsmithCleanup:
110985754Smsmith
111085754Smsmith    /* Delete return object on error */
111185754Smsmith
111285754Smsmith    if (ACPI_FAILURE (Status))
111385754Smsmith    {
111485754Smsmith        AcpiUtRemoveReference (ReturnDesc);
111585754Smsmith    }
111685754Smsmith
1117167802Sjkim    /* Save return object on success */
1118167802Sjkim
1119167802Sjkim    else
1120167802Sjkim    {
1121167802Sjkim        WalkState->ResultObj = ReturnDesc;
1122167802Sjkim    }
1123167802Sjkim
112485754Smsmith    return_ACPI_STATUS (Status);
112585754Smsmith}
1126