185754Smsmith/******************************************************************************
285754Smsmith *
385754Smsmith * Module Name: exoparg2 - AML execution - opcodes with 2 arguments
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/acinterp.h>
48193341Sjkim#include <contrib/dev/acpica/include/acevents.h>
49193341Sjkim#include <contrib/dev/acpica/include/amlcode.h>
5085754Smsmith
5185754Smsmith
5285754Smsmith#define _COMPONENT          ACPI_EXECUTER
5391116Smsmith        ACPI_MODULE_NAME    ("exoparg2")
5485754Smsmith
5585754Smsmith
5685754Smsmith/*!
5785754Smsmith * Naming convention for AML interpreter execution routines.
5885754Smsmith *
5985754Smsmith * The routines that begin execution of AML opcodes are named with a common
6085754Smsmith * convention based upon the number of arguments, the number of target operands,
6185754Smsmith * and whether or not a value is returned:
6285754Smsmith *
6385754Smsmith *      AcpiExOpcode_xA_yT_zR
6485754Smsmith *
6587031Smsmith * Where:
6685754Smsmith *
6787031Smsmith * xA - ARGUMENTS:    The number of arguments (input operands) that are
6885754Smsmith *                    required for this opcode type (1 through 6 args).
6987031Smsmith * yT - TARGETS:      The number of targets (output operands) that are required
7085754Smsmith *                    for this opcode type (0, 1, or 2 targets).
7187031Smsmith * zR - RETURN VALUE: Indicates whether this opcode type returns a value
7285754Smsmith *                    as the function return (0 or 1).
7385754Smsmith *
7487031Smsmith * The AcpiExOpcode* functions are called via the Dispatcher component with
7585754Smsmith * fully resolved operands.
7685754Smsmith!*/
7785754Smsmith
7885754Smsmith
7985754Smsmith/*******************************************************************************
8085754Smsmith *
8185754Smsmith * FUNCTION:    AcpiExOpcode_2A_0T_0R
8285754Smsmith *
8385754Smsmith * PARAMETERS:  WalkState           - Current walk state
8485754Smsmith *
8585754Smsmith * RETURN:      Status
8685754Smsmith *
8785754Smsmith * DESCRIPTION: Execute opcode with two arguments, no target, and no return
8885754Smsmith *              value.
8985754Smsmith *
9085754Smsmith * ALLOCATION:  Deletes both operands
9185754Smsmith *
9285754Smsmith ******************************************************************************/
9385754Smsmith
9485754SmsmithACPI_STATUS
9585754SmsmithAcpiExOpcode_2A_0T_0R (
9685754Smsmith    ACPI_WALK_STATE         *WalkState)
9785754Smsmith{
9885754Smsmith    ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
9985754Smsmith    ACPI_NAMESPACE_NODE     *Node;
100129684Snjl    UINT32                  Value;
10185754Smsmith    ACPI_STATUS             Status = AE_OK;
10285754Smsmith
10385754Smsmith
104167802Sjkim    ACPI_FUNCTION_TRACE_STR (ExOpcode_2A_0T_0R,
10599146Siwasaki            AcpiPsGetOpcodeName (WalkState->Opcode));
10685754Smsmith
10785754Smsmith
10885754Smsmith    /* Examine the opcode */
10985754Smsmith
11085754Smsmith    switch (WalkState->Opcode)
11185754Smsmith    {
11285754Smsmith    case AML_NOTIFY_OP:         /* Notify (NotifyObject, NotifyValue) */
11385754Smsmith
11485754Smsmith        /* The first operand is a namespace node */
11585754Smsmith
11685754Smsmith        Node = (ACPI_NAMESPACE_NODE *) Operand[0];
11785754Smsmith
118129684Snjl        /* Second value is the notify value */
119129684Snjl
120129684Snjl        Value = (UINT32) Operand[1]->Integer.Value;
121129684Snjl
122151937Sjkim        /* Are notifies allowed on this object? */
12385754Smsmith
12499146Siwasaki        if (!AcpiEvIsNotifyObject (Node))
12585754Smsmith        {
126167802Sjkim            ACPI_ERROR ((AE_INFO,
127167802Sjkim                "Unexpected notify object type [%s]",
128167802Sjkim                AcpiUtGetTypeName (Node->Type)));
12985754Smsmith
13091116Smsmith            Status = AE_AML_OPERAND_TYPE;
13191116Smsmith            break;
13285754Smsmith        }
13399146Siwasaki
13499146Siwasaki        /*
13599146Siwasaki         * Dispatch the notify to the appropriate handler
13699146Siwasaki         * NOTE: the request is queued for execution after this method
137241973Sjkim         * completes. The notify handlers are NOT invoked synchronously
13899146Siwasaki         * from this thread -- because handlers may in turn run other
13999146Siwasaki         * control methods.
14099146Siwasaki         */
141129684Snjl        Status = AcpiEvQueueNotifyRequest (Node, Value);
14285754Smsmith        break;
14385754Smsmith
14485754Smsmith    default:
14585754Smsmith
146204773Sjkim        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
147167802Sjkim            WalkState->Opcode));
14885754Smsmith        Status = AE_AML_BAD_OPCODE;
14985754Smsmith    }
15085754Smsmith
15185754Smsmith    return_ACPI_STATUS (Status);
15285754Smsmith}
15385754Smsmith
15485754Smsmith
15585754Smsmith/*******************************************************************************
15685754Smsmith *
15785754Smsmith * FUNCTION:    AcpiExOpcode_2A_2T_1R
15885754Smsmith *
15985754Smsmith * PARAMETERS:  WalkState           - Current walk state
16085754Smsmith *
16185754Smsmith * RETURN:      Status
16285754Smsmith *
16385754Smsmith * DESCRIPTION: Execute a dyadic operator (2 operands) with 2 output targets
16485754Smsmith *              and one implicit return value.
16585754Smsmith *
16685754Smsmith ******************************************************************************/
16785754Smsmith
16885754SmsmithACPI_STATUS
16985754SmsmithAcpiExOpcode_2A_2T_1R (
17085754Smsmith    ACPI_WALK_STATE         *WalkState)
17185754Smsmith{
17285754Smsmith    ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
17385754Smsmith    ACPI_OPERAND_OBJECT     *ReturnDesc1 = NULL;
17485754Smsmith    ACPI_OPERAND_OBJECT     *ReturnDesc2 = NULL;
17585754Smsmith    ACPI_STATUS             Status;
17685754Smsmith
17785754Smsmith
178167802Sjkim    ACPI_FUNCTION_TRACE_STR (ExOpcode_2A_2T_1R,
179138287Smarks        AcpiPsGetOpcodeName (WalkState->Opcode));
18085754Smsmith
18185754Smsmith
182151937Sjkim    /* Execute the opcode */
183151937Sjkim
18485754Smsmith    switch (WalkState->Opcode)
18585754Smsmith    {
186151937Sjkim    case AML_DIVIDE_OP:
18785754Smsmith
188151937Sjkim        /* Divide (Dividend, Divisor, RemainderResult QuotientResult) */
189151937Sjkim
19085754Smsmith        ReturnDesc1 = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
19185754Smsmith        if (!ReturnDesc1)
19285754Smsmith        {
19385754Smsmith            Status = AE_NO_MEMORY;
19485754Smsmith            goto Cleanup;
19585754Smsmith        }
19685754Smsmith
19785754Smsmith        ReturnDesc2 = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
19885754Smsmith        if (!ReturnDesc2)
19985754Smsmith        {
20085754Smsmith            Status = AE_NO_MEMORY;
20185754Smsmith            goto Cleanup;
20285754Smsmith        }
20385754Smsmith
20485754Smsmith        /* Quotient to ReturnDesc1, remainder to ReturnDesc2 */
20585754Smsmith
206306536Sjkim        Status = AcpiUtDivide (
207306536Sjkim            Operand[0]->Integer.Value,
208306536Sjkim            Operand[1]->Integer.Value,
209306536Sjkim            &ReturnDesc1->Integer.Value,
210306536Sjkim            &ReturnDesc2->Integer.Value);
21185754Smsmith        if (ACPI_FAILURE (Status))
21285754Smsmith        {
21385754Smsmith            goto Cleanup;
21485754Smsmith        }
21585754Smsmith        break;
21685754Smsmith
21785754Smsmith    default:
21885754Smsmith
219204773Sjkim        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
220167802Sjkim            WalkState->Opcode));
221306536Sjkim
22285754Smsmith        Status = AE_AML_BAD_OPCODE;
22385754Smsmith        goto Cleanup;
22485754Smsmith    }
22585754Smsmith
22685754Smsmith    /* Store the results to the target reference operands */
22785754Smsmith
22885754Smsmith    Status = AcpiExStore (ReturnDesc2, Operand[2], WalkState);
22985754Smsmith    if (ACPI_FAILURE (Status))
23085754Smsmith    {
23185754Smsmith        goto Cleanup;
23285754Smsmith    }
23385754Smsmith
23485754Smsmith    Status = AcpiExStore (ReturnDesc1, Operand[3], WalkState);
23585754Smsmith    if (ACPI_FAILURE (Status))
23685754Smsmith    {
23785754Smsmith        goto Cleanup;
23885754Smsmith    }
23985754Smsmith
24085754SmsmithCleanup:
24185754Smsmith    /*
24285754Smsmith     * Since the remainder is not returned indirectly, remove a reference to
24385754Smsmith     * it. Only the quotient is returned indirectly.
24485754Smsmith     */
24585754Smsmith    AcpiUtRemoveReference (ReturnDesc2);
24685754Smsmith
24785754Smsmith    if (ACPI_FAILURE (Status))
24885754Smsmith    {
24985754Smsmith        /* Delete the return object */
25085754Smsmith
25185754Smsmith        AcpiUtRemoveReference (ReturnDesc1);
25285754Smsmith    }
25385754Smsmith
254167802Sjkim    /* Save return object (the remainder) on success */
255167802Sjkim
256167802Sjkim    else
257167802Sjkim    {
258167802Sjkim        WalkState->ResultObj = ReturnDesc1;
259167802Sjkim    }
260167802Sjkim
26185754Smsmith    return_ACPI_STATUS (Status);
26285754Smsmith}
26385754Smsmith
26485754Smsmith
26585754Smsmith/*******************************************************************************
26685754Smsmith *
26785754Smsmith * FUNCTION:    AcpiExOpcode_2A_1T_1R
26885754Smsmith *
26985754Smsmith * PARAMETERS:  WalkState           - Current walk state
27085754Smsmith *
27185754Smsmith * RETURN:      Status
27285754Smsmith *
27385754Smsmith * DESCRIPTION: Execute opcode with two arguments, one target, and a return
27485754Smsmith *              value.
27585754Smsmith *
27685754Smsmith ******************************************************************************/
27785754Smsmith
27885754SmsmithACPI_STATUS
27985754SmsmithAcpiExOpcode_2A_1T_1R (
28085754Smsmith    ACPI_WALK_STATE         *WalkState)
28185754Smsmith{
282107325Siwasaki    ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
28385754Smsmith    ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
284202771Sjkim    UINT64                  Index;
285107325Siwasaki    ACPI_STATUS             Status = AE_OK;
286249112Sjkim    ACPI_SIZE               Length = 0;
28785754Smsmith
28885754Smsmith
289167802Sjkim    ACPI_FUNCTION_TRACE_STR (ExOpcode_2A_1T_1R,
290138287Smarks        AcpiPsGetOpcodeName (WalkState->Opcode));
29185754Smsmith
29285754Smsmith
293151937Sjkim    /* Execute the opcode */
294151937Sjkim
29585754Smsmith    if (WalkState->OpInfo->Flags & AML_MATH)
29685754Smsmith    {
29785754Smsmith        /* All simple math opcodes (add, etc.) */
29885754Smsmith
29985754Smsmith        ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
30085754Smsmith        if (!ReturnDesc)
30185754Smsmith        {
30285754Smsmith            Status = AE_NO_MEMORY;
30385754Smsmith            goto Cleanup;
30485754Smsmith        }
30585754Smsmith
306306536Sjkim        ReturnDesc->Integer.Value = AcpiExDoMathOp (
307306536Sjkim            WalkState->Opcode,
308306536Sjkim            Operand[0]->Integer.Value,
309306536Sjkim            Operand[1]->Integer.Value);
31085754Smsmith        goto StoreResultToTarget;
31185754Smsmith    }
31285754Smsmith
31385754Smsmith    switch (WalkState->Opcode)
31485754Smsmith    {
315151937Sjkim    case AML_MOD_OP: /* Mod (Dividend, Divisor, RemainderResult (ACPI 2.0) */
31685754Smsmith
31785754Smsmith        ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
31885754Smsmith        if (!ReturnDesc)
31985754Smsmith        {
32085754Smsmith            Status = AE_NO_MEMORY;
32185754Smsmith            goto Cleanup;
32285754Smsmith        }
32385754Smsmith
32485754Smsmith        /* ReturnDesc will contain the remainder */
32585754Smsmith
326306536Sjkim        Status = AcpiUtDivide (
327306536Sjkim            Operand[0]->Integer.Value,
328306536Sjkim            Operand[1]->Integer.Value,
329306536Sjkim            NULL,
330306536Sjkim            &ReturnDesc->Integer.Value);
33185754Smsmith        break;
33285754Smsmith
333151937Sjkim    case AML_CONCAT_OP: /* Concatenate (Data1, Data2, Result) */
33485754Smsmith
335306536Sjkim        Status = AcpiExDoConcatenate (
336306536Sjkim            Operand[0], Operand[1], &ReturnDesc, WalkState);
33785754Smsmith        break;
33885754Smsmith
339151937Sjkim    case AML_TO_STRING_OP: /* ToString (Buffer, Length, Result) (ACPI 2.0) */
340104470Siwasaki        /*
341104470Siwasaki         * Input object is guaranteed to be a buffer at this point (it may have
342151937Sjkim         * been converted.)  Copy the raw buffer data to a new object of
343151937Sjkim         * type String.
344104470Siwasaki         */
345104470Siwasaki
346138287Smarks        /*
347138287Smarks         * Get the length of the new string. It is the smallest of:
348138287Smarks         * 1) Length of the input buffer
349138287Smarks         * 2) Max length as specified in the ToString operator
350138287Smarks         * 3) Length of input buffer up to a zero byte (null terminator)
351138287Smarks         *
352138287Smarks         * NOTE: A length of zero is ok, and will create a zero-length, null
353138287Smarks         *       terminated string.
354138287Smarks         */
355104470Siwasaki        while ((Length < Operand[0]->Buffer.Length) &&
356104470Siwasaki               (Length < Operand[1]->Integer.Value) &&
357104470Siwasaki               (Operand[0]->Buffer.Pointer[Length]))
358104470Siwasaki        {
359104470Siwasaki            Length++;
360104470Siwasaki        }
361104470Siwasaki
362138287Smarks        /* Allocate a new string object */
363104470Siwasaki
364138287Smarks        ReturnDesc = AcpiUtCreateStringObject (Length);
365104470Siwasaki        if (!ReturnDesc)
366104470Siwasaki        {
367104470Siwasaki            Status = AE_NO_MEMORY;
368104470Siwasaki            goto Cleanup;
369104470Siwasaki        }
370114237Snjl
371167802Sjkim        /*
372167802Sjkim         * Copy the raw buffer data with no transform.
373167802Sjkim         * (NULL terminated already)
374167802Sjkim         */
375306536Sjkim        memcpy (ReturnDesc->String.Pointer,
376138287Smarks            Operand[0]->Buffer.Pointer, Length);
37785754Smsmith        break;
37885754Smsmith
379151937Sjkim    case AML_CONCAT_RES_OP:
38085754Smsmith
381151937Sjkim        /* ConcatenateResTemplate (Buffer, Buffer, Result) (ACPI 2.0) */
382151937Sjkim
383306536Sjkim        Status = AcpiExConcatTemplate (
384306536Sjkim            Operand[0], Operand[1], &ReturnDesc, WalkState);
38585754Smsmith        break;
38685754Smsmith
38785754Smsmith    case AML_INDEX_OP:              /* Index (Source Index Result) */
38885754Smsmith
38985754Smsmith        /* Create the internal return object */
39085754Smsmith
391107325Siwasaki        ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE);
39285754Smsmith        if (!ReturnDesc)
39385754Smsmith        {
39485754Smsmith            Status = AE_NO_MEMORY;
39585754Smsmith            goto Cleanup;
39685754Smsmith        }
39785754Smsmith
398167802Sjkim        /* Initialize the Index reference object */
399167802Sjkim
400151937Sjkim        Index = Operand[1]->Integer.Value;
401193267Sjkim        ReturnDesc->Reference.Value = (UINT32) Index;
402193267Sjkim        ReturnDesc->Reference.Class = ACPI_REFCLASS_INDEX;
40385754Smsmith
404167802Sjkim        /*
405167802Sjkim         * At this point, the Source operand is a String, Buffer, or Package.
406167802Sjkim         * Verify that the index is within range.
407167802Sjkim         */
408193267Sjkim        switch ((Operand[0])->Common.Type)
40985754Smsmith        {
410167802Sjkim        case ACPI_TYPE_STRING:
41185754Smsmith
412167802Sjkim            if (Index >= Operand[0]->String.Length)
41385754Smsmith            {
414249112Sjkim                Length = Operand[0]->String.Length;
415167802Sjkim                Status = AE_AML_STRING_LIMIT;
41685754Smsmith            }
41785754Smsmith
418167802Sjkim            ReturnDesc->Reference.TargetType = ACPI_TYPE_BUFFER_FIELD;
419306536Sjkim            ReturnDesc->Reference.IndexPointer =
420306536Sjkim                &(Operand[0]->Buffer.Pointer [Index]);
421167802Sjkim            break;
42285754Smsmith
423167802Sjkim        case ACPI_TYPE_BUFFER:
424167802Sjkim
42585754Smsmith            if (Index >= Operand[0]->Buffer.Length)
42685754Smsmith            {
427249112Sjkim                Length = Operand[0]->Buffer.Length;
42885754Smsmith                Status = AE_AML_BUFFER_LIMIT;
42985754Smsmith            }
43085754Smsmith
431107325Siwasaki            ReturnDesc->Reference.TargetType = ACPI_TYPE_BUFFER_FIELD;
432306536Sjkim            ReturnDesc->Reference.IndexPointer =
433306536Sjkim                &(Operand[0]->Buffer.Pointer [Index]);
434167802Sjkim            break;
435167802Sjkim
436167802Sjkim        case ACPI_TYPE_PACKAGE:
437167802Sjkim
438167802Sjkim            if (Index >= Operand[0]->Package.Count)
439167802Sjkim            {
440249112Sjkim                Length = Operand[0]->Package.Count;
441167802Sjkim                Status = AE_AML_PACKAGE_LIMIT;
442167802Sjkim            }
443167802Sjkim
444167802Sjkim            ReturnDesc->Reference.TargetType = ACPI_TYPE_PACKAGE;
445306536Sjkim            ReturnDesc->Reference.Where =
446306536Sjkim                &Operand[0]->Package.Elements [Index];
447167802Sjkim            break;
448167802Sjkim
449167802Sjkim        default:
450167802Sjkim
451167802Sjkim            Status = AE_AML_INTERNAL;
452167802Sjkim            goto Cleanup;
45385754Smsmith        }
45485754Smsmith
455167802Sjkim        /* Failure means that the Index was beyond the end of the object */
456167802Sjkim
457167802Sjkim        if (ACPI_FAILURE (Status))
458167802Sjkim        {
459167802Sjkim            ACPI_EXCEPTION ((AE_INFO, Status,
460249112Sjkim                "Index (0x%X%8.8X) is beyond end of object (length 0x%X)",
461249112Sjkim                ACPI_FORMAT_UINT64 (Index), (UINT32) Length));
462167802Sjkim            goto Cleanup;
463167802Sjkim        }
464167802Sjkim
465151937Sjkim        /*
466167802Sjkim         * Save the target object and add a reference to it for the life
467167802Sjkim         * of the index
468151937Sjkim         */
469167802Sjkim        ReturnDesc->Reference.Object = Operand[0];
470151937Sjkim        AcpiUtAddReference (Operand[0]);
471151937Sjkim
472107325Siwasaki        /* Store the reference to the Target */
473107325Siwasaki
474107325Siwasaki        Status = AcpiExStore (ReturnDesc, Operand[2], WalkState);
475107325Siwasaki
476107325Siwasaki        /* Return the reference */
477107325Siwasaki
47885754Smsmith        WalkState->ResultObj = ReturnDesc;
47985754Smsmith        goto Cleanup;
48085754Smsmith
48185754Smsmith    default:
48285754Smsmith
483204773Sjkim        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
484167802Sjkim            WalkState->Opcode));
48585754Smsmith        Status = AE_AML_BAD_OPCODE;
48685754Smsmith        break;
48785754Smsmith    }
48885754Smsmith
48985754Smsmith
49085754SmsmithStoreResultToTarget:
49185754Smsmith
49285754Smsmith    if (ACPI_SUCCESS (Status))
49385754Smsmith    {
49485754Smsmith        /*
49585754Smsmith         * Store the result of the operation (which is now in ReturnDesc) into
49685754Smsmith         * the Target descriptor.
49785754Smsmith         */
49885754Smsmith        Status = AcpiExStore (ReturnDesc, Operand[2], WalkState);
49985754Smsmith        if (ACPI_FAILURE (Status))
50085754Smsmith        {
50185754Smsmith            goto Cleanup;
50285754Smsmith        }
50385754Smsmith
504107325Siwasaki        if (!WalkState->ResultObj)
505107325Siwasaki        {
506107325Siwasaki            WalkState->ResultObj = ReturnDesc;
507107325Siwasaki        }
50885754Smsmith    }
50985754Smsmith
51085754Smsmith
51185754SmsmithCleanup:
51285754Smsmith
51385754Smsmith    /* Delete return object on error */
51485754Smsmith
51585754Smsmith    if (ACPI_FAILURE (Status))
51685754Smsmith    {
51785754Smsmith        AcpiUtRemoveReference (ReturnDesc);
518167802Sjkim        WalkState->ResultObj = NULL;
51985754Smsmith    }
52085754Smsmith
52185754Smsmith    return_ACPI_STATUS (Status);
52285754Smsmith}
52385754Smsmith
52485754Smsmith
52585754Smsmith/*******************************************************************************
52685754Smsmith *
52785754Smsmith * FUNCTION:    AcpiExOpcode_2A_0T_1R
52885754Smsmith *
52985754Smsmith * PARAMETERS:  WalkState           - Current walk state
53085754Smsmith *
53185754Smsmith * RETURN:      Status
53285754Smsmith *
53385754Smsmith * DESCRIPTION: Execute opcode with 2 arguments, no target, and a return value
53485754Smsmith *
53585754Smsmith ******************************************************************************/
53685754Smsmith
53785754SmsmithACPI_STATUS
53885754SmsmithAcpiExOpcode_2A_0T_1R (
53985754Smsmith    ACPI_WALK_STATE         *WalkState)
54085754Smsmith{
54185754Smsmith    ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
54285754Smsmith    ACPI_OPERAND_OBJECT     *ReturnDesc = NULL;
54385754Smsmith    ACPI_STATUS             Status = AE_OK;
54485754Smsmith    BOOLEAN                 LogicalResult = FALSE;
54585754Smsmith
54685754Smsmith
547167802Sjkim    ACPI_FUNCTION_TRACE_STR (ExOpcode_2A_0T_1R,
548138287Smarks        AcpiPsGetOpcodeName (WalkState->Opcode));
54985754Smsmith
55085754Smsmith
55185754Smsmith    /* Create the internal return object */
55285754Smsmith
55385754Smsmith    ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
55485754Smsmith    if (!ReturnDesc)
55585754Smsmith    {
55685754Smsmith        Status = AE_NO_MEMORY;
55785754Smsmith        goto Cleanup;
55885754Smsmith    }
55985754Smsmith
560151937Sjkim    /* Execute the Opcode */
561151937Sjkim
562151937Sjkim    if (WalkState->OpInfo->Flags & AML_LOGICAL_NUMERIC)
56385754Smsmith    {
564151937Sjkim        /* LogicalOp  (Operand0, Operand1) */
565151937Sjkim
566138287Smarks        Status = AcpiExDoLogicalNumericOp (WalkState->Opcode,
567306536Sjkim            Operand[0]->Integer.Value, Operand[1]->Integer.Value,
568306536Sjkim            &LogicalResult);
56985754Smsmith        goto StoreLogicalResult;
57085754Smsmith    }
571151937Sjkim    else if (WalkState->OpInfo->Flags & AML_LOGICAL)
572138287Smarks    {
573151937Sjkim        /* LogicalOp  (Operand0, Operand1) */
574151937Sjkim
575138287Smarks        Status = AcpiExDoLogicalOp (WalkState->Opcode, Operand[0],
576306536Sjkim            Operand[1], &LogicalResult);
577138287Smarks        goto StoreLogicalResult;
578138287Smarks    }
57985754Smsmith
58085754Smsmith    switch (WalkState->Opcode)
58185754Smsmith    {
58285754Smsmith    case AML_ACQUIRE_OP:            /* Acquire (MutexObject, Timeout) */
58385754Smsmith
58485754Smsmith        Status = AcpiExAcquireMutex (Operand[1], Operand[0], WalkState);
58585754Smsmith        if (Status == AE_TIME)
58685754Smsmith        {
58785754Smsmith            LogicalResult = TRUE;       /* TRUE = Acquire timed out */
58885754Smsmith            Status = AE_OK;
58985754Smsmith        }
59085754Smsmith        break;
59185754Smsmith
59285754Smsmith
59385754Smsmith    case AML_WAIT_OP:               /* Wait (EventObject, Timeout) */
59485754Smsmith
59585754Smsmith        Status = AcpiExSystemWaitEvent (Operand[1], Operand[0]);
59685754Smsmith        if (Status == AE_TIME)
59785754Smsmith        {
59885754Smsmith            LogicalResult = TRUE;       /* TRUE, Wait timed out */
59985754Smsmith            Status = AE_OK;
60085754Smsmith        }
60185754Smsmith        break;
60285754Smsmith
60385754Smsmith    default:
60485754Smsmith
605204773Sjkim        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
606100966Siwasaki            WalkState->Opcode));
607306536Sjkim
60885754Smsmith        Status = AE_AML_BAD_OPCODE;
60985754Smsmith        goto Cleanup;
61085754Smsmith    }
61185754Smsmith
61285754Smsmith
61385754SmsmithStoreLogicalResult:
61487031Smsmith    /*
61585754Smsmith     * Set return value to according to LogicalResult. logical TRUE (all ones)
61687031Smsmith     * Default is FALSE (zero)
61785754Smsmith     */
61885754Smsmith    if (LogicalResult)
61985754Smsmith    {
620202771Sjkim        ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
62185754Smsmith    }
62285754Smsmith
62385754SmsmithCleanup:
62485754Smsmith
62585754Smsmith    /* Delete return object on error */
62685754Smsmith
62785754Smsmith    if (ACPI_FAILURE (Status))
62885754Smsmith    {
62985754Smsmith        AcpiUtRemoveReference (ReturnDesc);
63085754Smsmith    }
63185754Smsmith
632167802Sjkim    /* Save return object on success */
633167802Sjkim
634167802Sjkim    else
635167802Sjkim    {
636167802Sjkim        WalkState->ResultObj = ReturnDesc;
637167802Sjkim    }
638167802Sjkim
63985754Smsmith    return_ACPI_STATUS (Status);
64085754Smsmith}
641