167754Smsmith/******************************************************************************
267754Smsmith *
3218590Sjkim * Module Name: dsopcode - Dispatcher suport for regions and fields
467754Smsmith *
567754Smsmith *****************************************************************************/
667754Smsmith
7217365Sjkim/*
8217365Sjkim * Copyright (C) 2000 - 2011, Intel Corp.
970243Smsmith * All rights reserved.
1067754Smsmith *
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.
2567754Smsmith *
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.
2967754Smsmith *
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 */
4367754Smsmith
4467754Smsmith#define __DSOPCODE_C__
4567754Smsmith
46193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
47193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
48193341Sjkim#include <contrib/dev/acpica/include/acparser.h>
49193341Sjkim#include <contrib/dev/acpica/include/amlcode.h>
50193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
51193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
52193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
53193341Sjkim#include <contrib/dev/acpica/include/acevents.h>
54193341Sjkim#include <contrib/dev/acpica/include/actables.h>
5567754Smsmith
5677424Smsmith#define _COMPONENT          ACPI_DISPATCHER
5791116Smsmith        ACPI_MODULE_NAME    ("dsopcode")
5867754Smsmith
59151937Sjkim/* Local prototypes */
6067754Smsmith
61151937Sjkimstatic ACPI_STATUS
62151937SjkimAcpiDsInitBufferField (
63151937Sjkim    UINT16                  AmlOpcode,
64151937Sjkim    ACPI_OPERAND_OBJECT     *ObjDesc,
65151937Sjkim    ACPI_OPERAND_OBJECT     *BufferDesc,
66151937Sjkim    ACPI_OPERAND_OBJECT     *OffsetDesc,
67151937Sjkim    ACPI_OPERAND_OBJECT     *LengthDesc,
68151937Sjkim    ACPI_OPERAND_OBJECT     *ResultDesc);
69151937Sjkim
70151937Sjkim
71151937Sjkim/*******************************************************************************
7267754Smsmith *
7367754Smsmith * FUNCTION:    AcpiDsInitializeRegion
7467754Smsmith *
75151937Sjkim * PARAMETERS:  ObjHandle       - Region namespace node
7667754Smsmith *
7767754Smsmith * RETURN:      Status
7867754Smsmith *
7999679Siwasaki * DESCRIPTION: Front end to EvInitializeRegion
8067754Smsmith *
81151937Sjkim ******************************************************************************/
8267754Smsmith
8367754SmsmithACPI_STATUS
8467754SmsmithAcpiDsInitializeRegion (
8567754Smsmith    ACPI_HANDLE             ObjHandle)
8667754Smsmith{
8767754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
8867754Smsmith    ACPI_STATUS             Status;
8967754Smsmith
9067754Smsmith
9167754Smsmith    ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
9267754Smsmith
9367754Smsmith    /* Namespace is NOT locked */
9467754Smsmith
9567754Smsmith    Status = AcpiEvInitializeRegion (ObjDesc, FALSE);
9667754Smsmith    return (Status);
9767754Smsmith}
9867754Smsmith
9967754Smsmith
100151937Sjkim/*******************************************************************************
10167754Smsmith *
10299679Siwasaki * FUNCTION:    AcpiDsInitBufferField
10367754Smsmith *
10499679Siwasaki * PARAMETERS:  AmlOpcode       - CreateXxxField
10599679Siwasaki *              ObjDesc         - BufferField object
10699679Siwasaki *              BufferDesc      - Host Buffer
10799679Siwasaki *              OffsetDesc      - Offset into buffer
108151937Sjkim *              LengthDesc      - Length of field (CREATE_FIELD_OP only)
109151937Sjkim *              ResultDesc      - Where to store the result
11067754Smsmith *
11167754Smsmith * RETURN:      Status
11267754Smsmith *
11399679Siwasaki * DESCRIPTION: Perform actual initialization of a buffer field
11467754Smsmith *
115151937Sjkim ******************************************************************************/
11667754Smsmith
117151937Sjkimstatic ACPI_STATUS
11899679SiwasakiAcpiDsInitBufferField (
11999679Siwasaki    UINT16                  AmlOpcode,
12099679Siwasaki    ACPI_OPERAND_OBJECT     *ObjDesc,
12199679Siwasaki    ACPI_OPERAND_OBJECT     *BufferDesc,
12299679Siwasaki    ACPI_OPERAND_OBJECT     *OffsetDesc,
12399679Siwasaki    ACPI_OPERAND_OBJECT     *LengthDesc,
12499679Siwasaki    ACPI_OPERAND_OBJECT     *ResultDesc)
12567754Smsmith{
12667754Smsmith    UINT32                  Offset;
12767754Smsmith    UINT32                  BitOffset;
12877424Smsmith    UINT32                  BitCount;
12977424Smsmith    UINT8                   FieldFlags;
13099679Siwasaki    ACPI_STATUS             Status;
13167754Smsmith
13267754Smsmith
133167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc);
13467754Smsmith
13567754Smsmith
13699679Siwasaki    /* Host object must be a Buffer */
13767754Smsmith
138193267Sjkim    if (BufferDesc->Common.Type != ACPI_TYPE_BUFFER)
13967754Smsmith    {
140167802Sjkim        ACPI_ERROR ((AE_INFO,
141167802Sjkim            "Target of Create Field is not a Buffer object - %s",
14299679Siwasaki            AcpiUtGetObjectTypeName (BufferDesc)));
14367754Smsmith
14499679Siwasaki        Status = AE_AML_OPERAND_TYPE;
14584491Smsmith        goto Cleanup;
14684491Smsmith    }
14784491Smsmith
14867754Smsmith    /*
14999679Siwasaki     * The last parameter to all of these opcodes (ResultDesc) started
15099679Siwasaki     * out as a NameString, and should therefore now be a NS node
151102550Siwasaki     * after resolution in AcpiExResolveOperands().
15267754Smsmith     */
15399679Siwasaki    if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
15467754Smsmith    {
155167802Sjkim        ACPI_ERROR ((AE_INFO,
156167802Sjkim            "(%s) destination not a NS Node [%s]",
157167802Sjkim            AcpiPsGetOpcodeName (AmlOpcode),
158167802Sjkim            AcpiUtGetDescriptorName (ResultDesc)));
15967754Smsmith
16067754Smsmith        Status = AE_AML_OPERAND_TYPE;
16167754Smsmith        goto Cleanup;
16267754Smsmith    }
16367754Smsmith
16499679Siwasaki    Offset = (UINT32) OffsetDesc->Integer.Value;
16599679Siwasaki
16667754Smsmith    /*
16767754Smsmith     * Setup the Bit offsets and counts, according to the opcode
16867754Smsmith     */
16999679Siwasaki    switch (AmlOpcode)
17067754Smsmith    {
17177424Smsmith    case AML_CREATE_FIELD_OP:
17277424Smsmith
17377424Smsmith        /* Offset is in bits, count is in bits */
17477424Smsmith
175151937Sjkim        FieldFlags = AML_FIELD_ACCESS_BYTE;
17699679Siwasaki        BitOffset  = Offset;
17799679Siwasaki        BitCount   = (UINT32) LengthDesc->Integer.Value;
178151937Sjkim
179151937Sjkim        /* Must have a valid (>0) bit count */
180151937Sjkim
181151937Sjkim        if (BitCount == 0)
182151937Sjkim        {
183167802Sjkim            ACPI_ERROR ((AE_INFO,
184167802Sjkim                "Attempt to CreateField of length zero"));
185151937Sjkim            Status = AE_AML_OPERAND_VALUE;
186151937Sjkim            goto Cleanup;
187151937Sjkim        }
18877424Smsmith        break;
18977424Smsmith
19077424Smsmith    case AML_CREATE_BIT_FIELD_OP:
19167754Smsmith
19277424Smsmith        /* Offset is in bits, Field is one bit */
19367754Smsmith
19499679Siwasaki        BitOffset  = Offset;
19599679Siwasaki        BitCount   = 1;
19699679Siwasaki        FieldFlags = AML_FIELD_ACCESS_BYTE;
19767754Smsmith        break;
19867754Smsmith
19977424Smsmith    case AML_CREATE_BYTE_FIELD_OP:
20067754Smsmith
20177424Smsmith        /* Offset is in bytes, field is one byte */
20267754Smsmith
20399679Siwasaki        BitOffset  = 8 * Offset;
20499679Siwasaki        BitCount   = 8;
20599679Siwasaki        FieldFlags = AML_FIELD_ACCESS_BYTE;
20667754Smsmith        break;
20767754Smsmith
20877424Smsmith    case AML_CREATE_WORD_FIELD_OP:
20967754Smsmith
21077424Smsmith        /* Offset is in bytes, field is one word */
21167754Smsmith
21299679Siwasaki        BitOffset  = 8 * Offset;
21399679Siwasaki        BitCount   = 16;
21499679Siwasaki        FieldFlags = AML_FIELD_ACCESS_WORD;
21567754Smsmith        break;
21667754Smsmith
21777424Smsmith    case AML_CREATE_DWORD_FIELD_OP:
21867754Smsmith
21977424Smsmith        /* Offset is in bytes, field is one dword */
22067754Smsmith
22199679Siwasaki        BitOffset  = 8 * Offset;
22299679Siwasaki        BitCount   = 32;
22399679Siwasaki        FieldFlags = AML_FIELD_ACCESS_DWORD;
22467754Smsmith        break;
22567754Smsmith
22677424Smsmith    case AML_CREATE_QWORD_FIELD_OP:
22767754Smsmith
22877424Smsmith        /* Offset is in bytes, field is one qword */
22967754Smsmith
23099679Siwasaki        BitOffset  = 8 * Offset;
23199679Siwasaki        BitCount   = 64;
23299679Siwasaki        FieldFlags = AML_FIELD_ACCESS_QWORD;
23367754Smsmith        break;
23467754Smsmith
23567754Smsmith    default:
23667754Smsmith
237167802Sjkim        ACPI_ERROR ((AE_INFO,
238204773Sjkim            "Unknown field creation opcode 0x%02X",
23999679Siwasaki            AmlOpcode));
24067754Smsmith        Status = AE_AML_BAD_OPCODE;
24167754Smsmith        goto Cleanup;
24267754Smsmith    }
24367754Smsmith
24499679Siwasaki    /* Entire field must fit within the current length of the buffer */
24599679Siwasaki
24699679Siwasaki    if ((BitOffset + BitCount) >
24799679Siwasaki        (8 * (UINT32) BufferDesc->Buffer.Length))
24899679Siwasaki    {
249167802Sjkim        ACPI_ERROR ((AE_INFO,
250204773Sjkim            "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
251167802Sjkim            AcpiUtGetNodeName (ResultDesc),
252167802Sjkim            BitOffset + BitCount,
253167802Sjkim            AcpiUtGetNodeName (BufferDesc->Buffer.Node),
254167802Sjkim            8 * (UINT32) BufferDesc->Buffer.Length));
25599679Siwasaki        Status = AE_AML_BUFFER_LIMIT;
25699679Siwasaki        goto Cleanup;
25799679Siwasaki    }
25899679Siwasaki
25967754Smsmith    /*
26099679Siwasaki     * Initialize areas of the field object that are common to all fields
261151937Sjkim     * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
262151937Sjkim     * UPDATE_RULE = 0 (UPDATE_PRESERVE)
26367754Smsmith     */
26499679Siwasaki    Status = AcpiExPrepCommonFieldObject (ObjDesc, FieldFlags, 0,
26599679Siwasaki                                            BitOffset, BitCount);
26699679Siwasaki    if (ACPI_FAILURE (Status))
26767754Smsmith    {
26899679Siwasaki        goto Cleanup;
26999679Siwasaki    }
27067754Smsmith
27199679Siwasaki    ObjDesc->BufferField.BufferObj = BufferDesc;
27267754Smsmith
27399679Siwasaki    /* Reference count for BufferDesc inherits ObjDesc count */
27467754Smsmith
275151937Sjkim    BufferDesc->Common.ReferenceCount = (UINT16)
276151937Sjkim        (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);
27767754Smsmith
27867754Smsmith
27999679SiwasakiCleanup:
28067754Smsmith
28199679Siwasaki    /* Always delete the operands */
28267754Smsmith
28399679Siwasaki    AcpiUtRemoveReference (OffsetDesc);
28499679Siwasaki    AcpiUtRemoveReference (BufferDesc);
28567754Smsmith
28699679Siwasaki    if (AmlOpcode == AML_CREATE_FIELD_OP)
28799679Siwasaki    {
28899679Siwasaki        AcpiUtRemoveReference (LengthDesc);
28999679Siwasaki    }
29067754Smsmith
29199679Siwasaki    /* On failure, delete the result descriptor */
29267754Smsmith
29399679Siwasaki    if (ACPI_FAILURE (Status))
29499679Siwasaki    {
29599679Siwasaki        AcpiUtRemoveReference (ResultDesc);     /* Result descriptor */
29699679Siwasaki    }
29799679Siwasaki    else
29899679Siwasaki    {
29999679Siwasaki        /* Now the address and length are valid for this BufferField */
30067754Smsmith
30199679Siwasaki        ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
30267754Smsmith    }
30367754Smsmith
30499679Siwasaki    return_ACPI_STATUS (Status);
30599679Siwasaki}
30667754Smsmith
30767754Smsmith
308151937Sjkim/*******************************************************************************
30999679Siwasaki *
31099679Siwasaki * FUNCTION:    AcpiDsEvalBufferFieldOperands
31199679Siwasaki *
31299679Siwasaki * PARAMETERS:  WalkState       - Current walk
31399679Siwasaki *              Op              - A valid BufferField Op object
31499679Siwasaki *
31599679Siwasaki * RETURN:      Status
31699679Siwasaki *
31799679Siwasaki * DESCRIPTION: Get BufferField Buffer and Index
31899679Siwasaki *              Called from AcpiDsExecEndOp during BufferField parse tree walk
31999679Siwasaki *
320151937Sjkim ******************************************************************************/
32167754Smsmith
32299679SiwasakiACPI_STATUS
32399679SiwasakiAcpiDsEvalBufferFieldOperands (
32499679Siwasaki    ACPI_WALK_STATE         *WalkState,
32599679Siwasaki    ACPI_PARSE_OBJECT       *Op)
32699679Siwasaki{
32799679Siwasaki    ACPI_STATUS             Status;
32899679Siwasaki    ACPI_OPERAND_OBJECT     *ObjDesc;
32999679Siwasaki    ACPI_NAMESPACE_NODE     *Node;
33099679Siwasaki    ACPI_PARSE_OBJECT       *NextOp;
33167754Smsmith
33267754Smsmith
333167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op);
33467754Smsmith
33567754Smsmith
33699679Siwasaki    /*
33799679Siwasaki     * This is where we evaluate the address and length fields of the
33899679Siwasaki     * CreateXxxField declaration
33999679Siwasaki     */
34099679Siwasaki    Node =  Op->Common.Node;
34199679Siwasaki
34299679Siwasaki    /* NextOp points to the op that holds the Buffer */
34399679Siwasaki
34499679Siwasaki    NextOp = Op->Common.Value.Arg;
34599679Siwasaki
34699679Siwasaki    /* Evaluate/create the address and length operands */
34799679Siwasaki
34899679Siwasaki    Status = AcpiDsCreateOperands (WalkState, NextOp);
34999679Siwasaki    if (ACPI_FAILURE (Status))
35067754Smsmith    {
35199679Siwasaki        return_ACPI_STATUS (Status);
35267754Smsmith    }
35367754Smsmith
35499679Siwasaki    ObjDesc = AcpiNsGetAttachedObject (Node);
35599679Siwasaki    if (!ObjDesc)
35699679Siwasaki    {
35799679Siwasaki        return_ACPI_STATUS (AE_NOT_EXIST);
35899679Siwasaki    }
35967754Smsmith
36099679Siwasaki    /* Resolve the operands */
36199679Siwasaki
362102550Siwasaki    Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
36399679Siwasaki                    ACPI_WALK_OPERANDS, WalkState);
36467754Smsmith    if (ACPI_FAILURE (Status))
36567754Smsmith    {
366204773Sjkim        ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
36799679Siwasaki            AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
36899679Siwasaki
36999679Siwasaki        return_ACPI_STATUS (Status);
37067754Smsmith    }
37199679Siwasaki
37299679Siwasaki    /* Initialize the Buffer Field */
37399679Siwasaki
37499679Siwasaki    if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
37599679Siwasaki    {
37699679Siwasaki        /* NOTE: Slightly different operands for this opcode */
37799679Siwasaki
378102550Siwasaki        Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
379102550Siwasaki                    WalkState->Operands[0], WalkState->Operands[1],
38099679Siwasaki                    WalkState->Operands[2], WalkState->Operands[3]);
38199679Siwasaki    }
38267754Smsmith    else
38367754Smsmith    {
38499679Siwasaki        /* All other, CreateXxxField opcodes */
38567754Smsmith
386102550Siwasaki        Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
387102550Siwasaki                    WalkState->Operands[0], WalkState->Operands[1],
38899679Siwasaki                                      NULL, WalkState->Operands[2]);
38967754Smsmith    }
39067754Smsmith
39167754Smsmith    return_ACPI_STATUS (Status);
39267754Smsmith}
39367754Smsmith
39467754Smsmith
395151937Sjkim/*******************************************************************************
39667754Smsmith *
39767754Smsmith * FUNCTION:    AcpiDsEvalRegionOperands
39867754Smsmith *
39999679Siwasaki * PARAMETERS:  WalkState       - Current walk
40099679Siwasaki *              Op              - A valid region Op object
40167754Smsmith *
40267754Smsmith * RETURN:      Status
40367754Smsmith *
40467754Smsmith * DESCRIPTION: Get region address and length
40567754Smsmith *              Called from AcpiDsExecEndOp during OpRegion parse tree walk
40667754Smsmith *
407151937Sjkim ******************************************************************************/
40867754Smsmith
40967754SmsmithACPI_STATUS
41067754SmsmithAcpiDsEvalRegionOperands (
41167754Smsmith    ACPI_WALK_STATE         *WalkState,
41267754Smsmith    ACPI_PARSE_OBJECT       *Op)
41367754Smsmith{
41467754Smsmith    ACPI_STATUS             Status;
41567754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
41667754Smsmith    ACPI_OPERAND_OBJECT     *OperandDesc;
41767754Smsmith    ACPI_NAMESPACE_NODE     *Node;
41867754Smsmith    ACPI_PARSE_OBJECT       *NextOp;
41967754Smsmith
42067754Smsmith
421167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op);
42267754Smsmith
42367754Smsmith
42467754Smsmith    /*
425151937Sjkim     * This is where we evaluate the address and length fields of the
426151937Sjkim     * OpRegion declaration
42767754Smsmith     */
42899679Siwasaki    Node =  Op->Common.Node;
42967754Smsmith
43067754Smsmith    /* NextOp points to the op that holds the SpaceID */
43183174Smsmith
43299679Siwasaki    NextOp = Op->Common.Value.Arg;
43367754Smsmith
43467754Smsmith    /* NextOp points to address op */
43583174Smsmith
43699679Siwasaki    NextOp = NextOp->Common.Next;
43767754Smsmith
43899146Siwasaki    /* Evaluate/create the address and length operands */
43967754Smsmith
44067754Smsmith    Status = AcpiDsCreateOperands (WalkState, NextOp);
44167754Smsmith    if (ACPI_FAILURE (Status))
44267754Smsmith    {
44367754Smsmith        return_ACPI_STATUS (Status);
44467754Smsmith    }
44567754Smsmith
44669450Smsmith    /* Resolve the length and address operands to numbers */
44769450Smsmith
448151937Sjkim    Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
449151937Sjkim                ACPI_WALK_OPERANDS, WalkState);
45069450Smsmith    if (ACPI_FAILURE (Status))
45169450Smsmith    {
45269450Smsmith        return_ACPI_STATUS (Status);
45369450Smsmith    }
45469450Smsmith
45567754Smsmith    ObjDesc = AcpiNsGetAttachedObject (Node);
45667754Smsmith    if (!ObjDesc)
45767754Smsmith    {
45867754Smsmith        return_ACPI_STATUS (AE_NOT_EXIST);
45967754Smsmith    }
46067754Smsmith
46169450Smsmith    /*
46269450Smsmith     * Get the length operand and save it
46369450Smsmith     * (at Top of stack)
46469450Smsmith     */
46567754Smsmith    OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
46667754Smsmith
46771867Smsmith    ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
46877424Smsmith    AcpiUtRemoveReference (OperandDesc);
46967754Smsmith
47069450Smsmith    /*
47169450Smsmith     * Get the address and save it
47269450Smsmith     * (at top of stack - 1)
47369450Smsmith     */
47467754Smsmith    OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
47567754Smsmith
476151937Sjkim    ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS)
477151937Sjkim                                OperandDesc->Integer.Value;
47877424Smsmith    AcpiUtRemoveReference (OperandDesc);
47967754Smsmith
48085756Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
48191116Smsmith        ObjDesc,
482193267Sjkim        ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address),
48380062Smsmith        ObjDesc->Region.Length));
48467754Smsmith
48567754Smsmith    /* Now the address and length are valid for this opregion */
48667754Smsmith
48767754Smsmith    ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
48867754Smsmith
48967754Smsmith    return_ACPI_STATUS (Status);
49067754Smsmith}
49167754Smsmith
49267754Smsmith
493151937Sjkim/*******************************************************************************
49499146Siwasaki *
495193267Sjkim * FUNCTION:    AcpiDsEvalTableRegionOperands
496193267Sjkim *
497193267Sjkim * PARAMETERS:  WalkState       - Current walk
498193267Sjkim *              Op              - A valid region Op object
499193267Sjkim *
500193267Sjkim * RETURN:      Status
501193267Sjkim *
502218590Sjkim * DESCRIPTION: Get region address and length.
503218590Sjkim *              Called from AcpiDsExecEndOp during DataTableRegion parse
504218590Sjkim *              tree walk.
505193267Sjkim *
506193267Sjkim ******************************************************************************/
507193267Sjkim
508193267SjkimACPI_STATUS
509193267SjkimAcpiDsEvalTableRegionOperands (
510193267Sjkim    ACPI_WALK_STATE         *WalkState,
511193267Sjkim    ACPI_PARSE_OBJECT       *Op)
512193267Sjkim{
513193267Sjkim    ACPI_STATUS             Status;
514193267Sjkim    ACPI_OPERAND_OBJECT     *ObjDesc;
515193267Sjkim    ACPI_OPERAND_OBJECT     **Operand;
516193267Sjkim    ACPI_NAMESPACE_NODE     *Node;
517193267Sjkim    ACPI_PARSE_OBJECT       *NextOp;
518193267Sjkim    UINT32                  TableIndex;
519193267Sjkim    ACPI_TABLE_HEADER       *Table;
520193267Sjkim
521193267Sjkim
522193267Sjkim    ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op);
523193267Sjkim
524193267Sjkim
525193267Sjkim    /*
526193267Sjkim     * This is where we evaluate the SignatureString and OemIDString
527193267Sjkim     * and OemTableIDString of the DataTableRegion declaration
528193267Sjkim     */
529193267Sjkim    Node =  Op->Common.Node;
530193267Sjkim
531193267Sjkim    /* NextOp points to SignatureString op */
532193267Sjkim
533193267Sjkim    NextOp = Op->Common.Value.Arg;
534193267Sjkim
535193267Sjkim    /*
536193267Sjkim     * Evaluate/create the SignatureString and OemIDString
537193267Sjkim     * and OemTableIDString operands
538193267Sjkim     */
539193267Sjkim    Status = AcpiDsCreateOperands (WalkState, NextOp);
540193267Sjkim    if (ACPI_FAILURE (Status))
541193267Sjkim    {
542193267Sjkim        return_ACPI_STATUS (Status);
543193267Sjkim    }
544193267Sjkim
545193267Sjkim    /*
546193267Sjkim     * Resolve the SignatureString and OemIDString
547193267Sjkim     * and OemTableIDString operands
548193267Sjkim     */
549193267Sjkim    Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
550193267Sjkim                ACPI_WALK_OPERANDS, WalkState);
551193267Sjkim    if (ACPI_FAILURE (Status))
552193267Sjkim    {
553193267Sjkim        return_ACPI_STATUS (Status);
554193267Sjkim    }
555193267Sjkim
556193267Sjkim    Operand = &WalkState->Operands[0];
557193267Sjkim
558193267Sjkim    /* Find the ACPI table */
559193267Sjkim
560193267Sjkim    Status = AcpiTbFindTable (Operand[0]->String.Pointer,
561193267Sjkim                Operand[1]->String.Pointer, Operand[2]->String.Pointer,
562193267Sjkim                &TableIndex);
563193267Sjkim    if (ACPI_FAILURE (Status))
564193267Sjkim    {
565193267Sjkim        return_ACPI_STATUS (Status);
566193267Sjkim    }
567193267Sjkim
568193267Sjkim    AcpiUtRemoveReference (Operand[0]);
569193267Sjkim    AcpiUtRemoveReference (Operand[1]);
570193267Sjkim    AcpiUtRemoveReference (Operand[2]);
571193267Sjkim
572193267Sjkim    Status = AcpiGetTableByIndex (TableIndex, &Table);
573193267Sjkim    if (ACPI_FAILURE (Status))
574193267Sjkim    {
575193267Sjkim        return_ACPI_STATUS (Status);
576193267Sjkim    }
577193267Sjkim
578193267Sjkim    ObjDesc = AcpiNsGetAttachedObject (Node);
579193267Sjkim    if (!ObjDesc)
580193267Sjkim    {
581193267Sjkim        return_ACPI_STATUS (AE_NOT_EXIST);
582193267Sjkim    }
583193267Sjkim
584193267Sjkim    ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS) ACPI_TO_INTEGER (Table);
585193267Sjkim    ObjDesc->Region.Length = Table->Length;
586193267Sjkim
587193267Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
588193267Sjkim        ObjDesc,
589193267Sjkim        ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address),
590193267Sjkim        ObjDesc->Region.Length));
591193267Sjkim
592193267Sjkim    /* Now the address and length are valid for this opregion */
593193267Sjkim
594193267Sjkim    ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
595193267Sjkim
596193267Sjkim    return_ACPI_STATUS (Status);
597193267Sjkim}
598193267Sjkim
599193267Sjkim
600193267Sjkim/*******************************************************************************
601193267Sjkim *
60299146Siwasaki * FUNCTION:    AcpiDsEvalDataObjectOperands
60399146Siwasaki *
60499679Siwasaki * PARAMETERS:  WalkState       - Current walk
60599679Siwasaki *              Op              - A valid DataObject Op object
60699679Siwasaki *              ObjDesc         - DataObject
60799146Siwasaki *
60899146Siwasaki * RETURN:      Status
60999146Siwasaki *
610151937Sjkim * DESCRIPTION: Get the operands and complete the following data object types:
611151937Sjkim *              Buffer, Package.
61299146Siwasaki *
613151937Sjkim ******************************************************************************/
61499146Siwasaki
61599146SiwasakiACPI_STATUS
61699146SiwasakiAcpiDsEvalDataObjectOperands (
61799146Siwasaki    ACPI_WALK_STATE         *WalkState,
61899146Siwasaki    ACPI_PARSE_OBJECT       *Op,
61999146Siwasaki    ACPI_OPERAND_OBJECT     *ObjDesc)
62099146Siwasaki{
62199146Siwasaki    ACPI_STATUS             Status;
62299146Siwasaki    ACPI_OPERAND_OBJECT     *ArgDesc;
62399146Siwasaki    UINT32                  Length;
62499146Siwasaki
62599146Siwasaki
626167802Sjkim    ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands);
62799146Siwasaki
62899146Siwasaki
62999146Siwasaki    /* The first operand (for all of these data objects) is the length */
63099146Siwasaki
631167802Sjkim    /*
632167802Sjkim     * Set proper index into operand stack for AcpiDsObjStackPush
633167802Sjkim     * invoked inside AcpiDsCreateOperand.
634167802Sjkim     */
635167802Sjkim    WalkState->OperandIndex = WalkState->NumOperands;
636167802Sjkim
63799679Siwasaki    Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
63899146Siwasaki    if (ACPI_FAILURE (Status))
63999146Siwasaki    {
64099146Siwasaki        return_ACPI_STATUS (Status);
64199146Siwasaki    }
64299146Siwasaki
64399146Siwasaki    Status = AcpiExResolveOperands (WalkState->Opcode,
64499146Siwasaki                    &(WalkState->Operands [WalkState->NumOperands -1]),
64599146Siwasaki                    WalkState);
64699146Siwasaki    if (ACPI_FAILURE (Status))
64799146Siwasaki    {
64899146Siwasaki        return_ACPI_STATUS (Status);
64999146Siwasaki    }
65099146Siwasaki
65199146Siwasaki    /* Extract length operand */
65299146Siwasaki
65399146Siwasaki    ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
65499146Siwasaki    Length = (UINT32) ArgDesc->Integer.Value;
65599146Siwasaki
65699146Siwasaki    /* Cleanup for length operand */
65799146Siwasaki
65899679Siwasaki    Status = AcpiDsObjStackPop (1, WalkState);
65999679Siwasaki    if (ACPI_FAILURE (Status))
66099679Siwasaki    {
66199679Siwasaki        return_ACPI_STATUS (Status);
66299679Siwasaki    }
66399679Siwasaki
66499146Siwasaki    AcpiUtRemoveReference (ArgDesc);
66599146Siwasaki
666102550Siwasaki    /*
66799146Siwasaki     * Create the actual data object
66899146Siwasaki     */
66999679Siwasaki    switch (Op->Common.AmlOpcode)
67099146Siwasaki    {
67199146Siwasaki    case AML_BUFFER_OP:
67299146Siwasaki
67399146Siwasaki        Status = AcpiDsBuildInternalBufferObj (WalkState, Op, Length, &ObjDesc);
67499146Siwasaki        break;
67599146Siwasaki
67699146Siwasaki    case AML_PACKAGE_OP:
67799146Siwasaki    case AML_VAR_PACKAGE_OP:
67899146Siwasaki
67999146Siwasaki        Status = AcpiDsBuildInternalPackageObj (WalkState, Op, Length, &ObjDesc);
68099146Siwasaki        break;
68199146Siwasaki
68299146Siwasaki    default:
68399146Siwasaki        return_ACPI_STATUS (AE_AML_BAD_OPCODE);
68499146Siwasaki    }
68599146Siwasaki
68699146Siwasaki    if (ACPI_SUCCESS (Status))
68799146Siwasaki    {
68899146Siwasaki        /*
689151937Sjkim         * Return the object in the WalkState, unless the parent is a package -
69099146Siwasaki         * in this case, the return object will be stored in the parse tree
69199146Siwasaki         * for the package.
69299146Siwasaki         */
69399679Siwasaki        if ((!Op->Common.Parent) ||
69499679Siwasaki            ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
69599679Siwasaki             (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) &&
69699679Siwasaki             (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
69799146Siwasaki        {
69899146Siwasaki            WalkState->ResultObj = ObjDesc;
69999146Siwasaki        }
70099146Siwasaki    }
70199146Siwasaki
70299146Siwasaki    return_ACPI_STATUS (Status);
70399146Siwasaki}
70499146Siwasaki
70599146Siwasaki
70667754Smsmith/*******************************************************************************
70767754Smsmith *
708193267Sjkim * FUNCTION:    AcpiDsEvalBankFieldOperands
709193267Sjkim *
710193267Sjkim * PARAMETERS:  WalkState       - Current walk
711193267Sjkim *              Op              - A valid BankField Op object
712193267Sjkim *
713193267Sjkim * RETURN:      Status
714193267Sjkim *
715193267Sjkim * DESCRIPTION: Get BankField BankValue
716193267Sjkim *              Called from AcpiDsExecEndOp during BankField parse tree walk
717193267Sjkim *
718193267Sjkim ******************************************************************************/
719193267Sjkim
720193267SjkimACPI_STATUS
721193267SjkimAcpiDsEvalBankFieldOperands (
722193267Sjkim    ACPI_WALK_STATE         *WalkState,
723193267Sjkim    ACPI_PARSE_OBJECT       *Op)
724193267Sjkim{
725193267Sjkim    ACPI_STATUS             Status;
726193267Sjkim    ACPI_OPERAND_OBJECT     *ObjDesc;
727193267Sjkim    ACPI_OPERAND_OBJECT     *OperandDesc;
728193267Sjkim    ACPI_NAMESPACE_NODE     *Node;
729193267Sjkim    ACPI_PARSE_OBJECT       *NextOp;
730193267Sjkim    ACPI_PARSE_OBJECT       *Arg;
731193267Sjkim
732193267Sjkim
733193267Sjkim    ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands, Op);
734193267Sjkim
735193267Sjkim
736193267Sjkim    /*
737193267Sjkim     * This is where we evaluate the BankValue field of the
738193267Sjkim     * BankField declaration
739193267Sjkim     */
740193267Sjkim
741193267Sjkim    /* NextOp points to the op that holds the Region */
742193267Sjkim
743193267Sjkim    NextOp = Op->Common.Value.Arg;
744193267Sjkim
745193267Sjkim    /* NextOp points to the op that holds the Bank Register */
746193267Sjkim
747193267Sjkim    NextOp = NextOp->Common.Next;
748193267Sjkim
749193267Sjkim    /* NextOp points to the op that holds the Bank Value */
750193267Sjkim
751193267Sjkim    NextOp = NextOp->Common.Next;
752193267Sjkim
753193267Sjkim    /*
754193267Sjkim     * Set proper index into operand stack for AcpiDsObjStackPush
755193267Sjkim     * invoked inside AcpiDsCreateOperand.
756193267Sjkim     *
757193267Sjkim     * We use WalkState->Operands[0] to store the evaluated BankValue
758193267Sjkim     */
759193267Sjkim    WalkState->OperandIndex = 0;
760193267Sjkim
761193267Sjkim    Status = AcpiDsCreateOperand (WalkState, NextOp, 0);
762193267Sjkim    if (ACPI_FAILURE (Status))
763193267Sjkim    {
764193267Sjkim        return_ACPI_STATUS (Status);
765193267Sjkim    }
766193267Sjkim
767193267Sjkim    Status = AcpiExResolveToValue (&WalkState->Operands[0], WalkState);
768193267Sjkim    if (ACPI_FAILURE (Status))
769193267Sjkim    {
770193267Sjkim        return_ACPI_STATUS (Status);
771193267Sjkim    }
772193267Sjkim
773193267Sjkim    ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS,
774193267Sjkim        AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 1);
775193267Sjkim    /*
776193267Sjkim     * Get the BankValue operand and save it
777193267Sjkim     * (at Top of stack)
778193267Sjkim     */
779193267Sjkim    OperandDesc = WalkState->Operands[0];
780193267Sjkim
781193267Sjkim    /* Arg points to the start Bank Field */
782193267Sjkim
783193267Sjkim    Arg = AcpiPsGetArg (Op, 4);
784193267Sjkim    while (Arg)
785193267Sjkim    {
786193267Sjkim        /* Ignore OFFSET and ACCESSAS terms here */
787193267Sjkim
788193267Sjkim        if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
789193267Sjkim        {
790193267Sjkim            Node = Arg->Common.Node;
791193267Sjkim
792193267Sjkim            ObjDesc = AcpiNsGetAttachedObject (Node);
793193267Sjkim            if (!ObjDesc)
794193267Sjkim            {
795193267Sjkim                return_ACPI_STATUS (AE_NOT_EXIST);
796193267Sjkim            }
797193267Sjkim
798193267Sjkim            ObjDesc->BankField.Value = (UINT32) OperandDesc->Integer.Value;
799193267Sjkim        }
800193267Sjkim
801193267Sjkim        /* Move to next field in the list */
802193267Sjkim
803193267Sjkim        Arg = Arg->Common.Next;
804193267Sjkim    }
805193267Sjkim
806193267Sjkim    AcpiUtRemoveReference (OperandDesc);
807193267Sjkim    return_ACPI_STATUS (Status);
808193267Sjkim}
809193267Sjkim
810