167754Smsmith/******************************************************************************
267754Smsmith *
3249112Sjkim * Module Name: dsopcode - Dispatcher support for regions and fields
467754Smsmith *
567754Smsmith *****************************************************************************/
667754Smsmith
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, 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
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/amlcode.h>
48193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
49193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
50193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
51193341Sjkim#include <contrib/dev/acpica/include/acevents.h>
52193341Sjkim#include <contrib/dev/acpica/include/actables.h>
5367754Smsmith
5477424Smsmith#define _COMPONENT          ACPI_DISPATCHER
5591116Smsmith        ACPI_MODULE_NAME    ("dsopcode")
5667754Smsmith
57151937Sjkim/* Local prototypes */
5867754Smsmith
59151937Sjkimstatic ACPI_STATUS
60151937SjkimAcpiDsInitBufferField (
61151937Sjkim    UINT16                  AmlOpcode,
62151937Sjkim    ACPI_OPERAND_OBJECT     *ObjDesc,
63151937Sjkim    ACPI_OPERAND_OBJECT     *BufferDesc,
64151937Sjkim    ACPI_OPERAND_OBJECT     *OffsetDesc,
65151937Sjkim    ACPI_OPERAND_OBJECT     *LengthDesc,
66151937Sjkim    ACPI_OPERAND_OBJECT     *ResultDesc);
67151937Sjkim
68151937Sjkim
69151937Sjkim/*******************************************************************************
7067754Smsmith *
7167754Smsmith * FUNCTION:    AcpiDsInitializeRegion
7267754Smsmith *
73151937Sjkim * PARAMETERS:  ObjHandle       - Region namespace node
7467754Smsmith *
7567754Smsmith * RETURN:      Status
7667754Smsmith *
7799679Siwasaki * DESCRIPTION: Front end to EvInitializeRegion
7867754Smsmith *
79151937Sjkim ******************************************************************************/
8067754Smsmith
8167754SmsmithACPI_STATUS
8267754SmsmithAcpiDsInitializeRegion (
8367754Smsmith    ACPI_HANDLE             ObjHandle)
8467754Smsmith{
8567754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
8667754Smsmith    ACPI_STATUS             Status;
8767754Smsmith
8867754Smsmith
8967754Smsmith    ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
9067754Smsmith
9167754Smsmith    /* Namespace is NOT locked */
9267754Smsmith
9367754Smsmith    Status = AcpiEvInitializeRegion (ObjDesc, FALSE);
9467754Smsmith    return (Status);
9567754Smsmith}
9667754Smsmith
9767754Smsmith
98151937Sjkim/*******************************************************************************
9967754Smsmith *
10099679Siwasaki * FUNCTION:    AcpiDsInitBufferField
10167754Smsmith *
10299679Siwasaki * PARAMETERS:  AmlOpcode       - CreateXxxField
10399679Siwasaki *              ObjDesc         - BufferField object
10499679Siwasaki *              BufferDesc      - Host Buffer
10599679Siwasaki *              OffsetDesc      - Offset into buffer
106151937Sjkim *              LengthDesc      - Length of field (CREATE_FIELD_OP only)
107151937Sjkim *              ResultDesc      - Where to store the result
10867754Smsmith *
10967754Smsmith * RETURN:      Status
11067754Smsmith *
11199679Siwasaki * DESCRIPTION: Perform actual initialization of a buffer field
11267754Smsmith *
113151937Sjkim ******************************************************************************/
11467754Smsmith
115151937Sjkimstatic ACPI_STATUS
11699679SiwasakiAcpiDsInitBufferField (
11799679Siwasaki    UINT16                  AmlOpcode,
11899679Siwasaki    ACPI_OPERAND_OBJECT     *ObjDesc,
11999679Siwasaki    ACPI_OPERAND_OBJECT     *BufferDesc,
12099679Siwasaki    ACPI_OPERAND_OBJECT     *OffsetDesc,
12199679Siwasaki    ACPI_OPERAND_OBJECT     *LengthDesc,
12299679Siwasaki    ACPI_OPERAND_OBJECT     *ResultDesc)
12367754Smsmith{
12467754Smsmith    UINT32                  Offset;
12567754Smsmith    UINT32                  BitOffset;
12677424Smsmith    UINT32                  BitCount;
12777424Smsmith    UINT8                   FieldFlags;
12899679Siwasaki    ACPI_STATUS             Status;
12967754Smsmith
13067754Smsmith
131167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc);
13267754Smsmith
13367754Smsmith
13499679Siwasaki    /* Host object must be a Buffer */
13567754Smsmith
136193267Sjkim    if (BufferDesc->Common.Type != ACPI_TYPE_BUFFER)
13767754Smsmith    {
138167802Sjkim        ACPI_ERROR ((AE_INFO,
139167802Sjkim            "Target of Create Field is not a Buffer object - %s",
14099679Siwasaki            AcpiUtGetObjectTypeName (BufferDesc)));
14167754Smsmith
14299679Siwasaki        Status = AE_AML_OPERAND_TYPE;
14384491Smsmith        goto Cleanup;
14484491Smsmith    }
14584491Smsmith
14667754Smsmith    /*
14799679Siwasaki     * The last parameter to all of these opcodes (ResultDesc) started
14899679Siwasaki     * out as a NameString, and should therefore now be a NS node
149102550Siwasaki     * after resolution in AcpiExResolveOperands().
15067754Smsmith     */
15199679Siwasaki    if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
15267754Smsmith    {
153167802Sjkim        ACPI_ERROR ((AE_INFO,
154167802Sjkim            "(%s) destination not a NS Node [%s]",
155167802Sjkim            AcpiPsGetOpcodeName (AmlOpcode),
156167802Sjkim            AcpiUtGetDescriptorName (ResultDesc)));
15767754Smsmith
15867754Smsmith        Status = AE_AML_OPERAND_TYPE;
15967754Smsmith        goto Cleanup;
16067754Smsmith    }
16167754Smsmith
16299679Siwasaki    Offset = (UINT32) OffsetDesc->Integer.Value;
16399679Siwasaki
16467754Smsmith    /*
16567754Smsmith     * Setup the Bit offsets and counts, according to the opcode
16667754Smsmith     */
16799679Siwasaki    switch (AmlOpcode)
16867754Smsmith    {
16977424Smsmith    case AML_CREATE_FIELD_OP:
17077424Smsmith
17177424Smsmith        /* Offset is in bits, count is in bits */
17277424Smsmith
173151937Sjkim        FieldFlags = AML_FIELD_ACCESS_BYTE;
17499679Siwasaki        BitOffset  = Offset;
17599679Siwasaki        BitCount   = (UINT32) LengthDesc->Integer.Value;
176151937Sjkim
177151937Sjkim        /* Must have a valid (>0) bit count */
178151937Sjkim
179151937Sjkim        if (BitCount == 0)
180151937Sjkim        {
181167802Sjkim            ACPI_ERROR ((AE_INFO,
182167802Sjkim                "Attempt to CreateField of length zero"));
183151937Sjkim            Status = AE_AML_OPERAND_VALUE;
184151937Sjkim            goto Cleanup;
185151937Sjkim        }
18677424Smsmith        break;
18777424Smsmith
18877424Smsmith    case AML_CREATE_BIT_FIELD_OP:
18967754Smsmith
19077424Smsmith        /* Offset is in bits, Field is one bit */
19167754Smsmith
19299679Siwasaki        BitOffset  = Offset;
19399679Siwasaki        BitCount   = 1;
19499679Siwasaki        FieldFlags = AML_FIELD_ACCESS_BYTE;
19567754Smsmith        break;
19667754Smsmith
19777424Smsmith    case AML_CREATE_BYTE_FIELD_OP:
19867754Smsmith
19977424Smsmith        /* Offset is in bytes, field is one byte */
20067754Smsmith
20199679Siwasaki        BitOffset  = 8 * Offset;
20299679Siwasaki        BitCount   = 8;
20399679Siwasaki        FieldFlags = AML_FIELD_ACCESS_BYTE;
20467754Smsmith        break;
20567754Smsmith
20677424Smsmith    case AML_CREATE_WORD_FIELD_OP:
20767754Smsmith
20877424Smsmith        /* Offset is in bytes, field is one word */
20967754Smsmith
21099679Siwasaki        BitOffset  = 8 * Offset;
21199679Siwasaki        BitCount   = 16;
21299679Siwasaki        FieldFlags = AML_FIELD_ACCESS_WORD;
21367754Smsmith        break;
21467754Smsmith
21577424Smsmith    case AML_CREATE_DWORD_FIELD_OP:
21667754Smsmith
21777424Smsmith        /* Offset is in bytes, field is one dword */
21867754Smsmith
21999679Siwasaki        BitOffset  = 8 * Offset;
22099679Siwasaki        BitCount   = 32;
22199679Siwasaki        FieldFlags = AML_FIELD_ACCESS_DWORD;
22267754Smsmith        break;
22367754Smsmith
22477424Smsmith    case AML_CREATE_QWORD_FIELD_OP:
22567754Smsmith
22677424Smsmith        /* Offset is in bytes, field is one qword */
22767754Smsmith
22899679Siwasaki        BitOffset  = 8 * Offset;
22999679Siwasaki        BitCount   = 64;
23099679Siwasaki        FieldFlags = AML_FIELD_ACCESS_QWORD;
23167754Smsmith        break;
23267754Smsmith
23367754Smsmith    default:
23467754Smsmith
235167802Sjkim        ACPI_ERROR ((AE_INFO,
236204773Sjkim            "Unknown field creation opcode 0x%02X",
23799679Siwasaki            AmlOpcode));
23867754Smsmith        Status = AE_AML_BAD_OPCODE;
23967754Smsmith        goto Cleanup;
24067754Smsmith    }
24167754Smsmith
24299679Siwasaki    /* Entire field must fit within the current length of the buffer */
24399679Siwasaki
24499679Siwasaki    if ((BitOffset + BitCount) >
24599679Siwasaki        (8 * (UINT32) BufferDesc->Buffer.Length))
24699679Siwasaki    {
247167802Sjkim        ACPI_ERROR ((AE_INFO,
248204773Sjkim            "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
249167802Sjkim            AcpiUtGetNodeName (ResultDesc),
250167802Sjkim            BitOffset + BitCount,
251167802Sjkim            AcpiUtGetNodeName (BufferDesc->Buffer.Node),
252167802Sjkim            8 * (UINT32) BufferDesc->Buffer.Length));
25399679Siwasaki        Status = AE_AML_BUFFER_LIMIT;
25499679Siwasaki        goto Cleanup;
25599679Siwasaki    }
25699679Siwasaki
25767754Smsmith    /*
25899679Siwasaki     * Initialize areas of the field object that are common to all fields
259151937Sjkim     * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
260151937Sjkim     * UPDATE_RULE = 0 (UPDATE_PRESERVE)
26167754Smsmith     */
262306536Sjkim    Status = AcpiExPrepCommonFieldObject (
263306536Sjkim        ObjDesc, FieldFlags, 0, BitOffset, BitCount);
26499679Siwasaki    if (ACPI_FAILURE (Status))
26567754Smsmith    {
26699679Siwasaki        goto Cleanup;
26799679Siwasaki    }
26867754Smsmith
26999679Siwasaki    ObjDesc->BufferField.BufferObj = BufferDesc;
27067754Smsmith
27199679Siwasaki    /* Reference count for BufferDesc inherits ObjDesc count */
27267754Smsmith
273151937Sjkim    BufferDesc->Common.ReferenceCount = (UINT16)
274151937Sjkim        (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);
27567754Smsmith
27667754Smsmith
27799679SiwasakiCleanup:
27867754Smsmith
27999679Siwasaki    /* Always delete the operands */
28067754Smsmith
28199679Siwasaki    AcpiUtRemoveReference (OffsetDesc);
28299679Siwasaki    AcpiUtRemoveReference (BufferDesc);
28367754Smsmith
28499679Siwasaki    if (AmlOpcode == AML_CREATE_FIELD_OP)
28599679Siwasaki    {
28699679Siwasaki        AcpiUtRemoveReference (LengthDesc);
28799679Siwasaki    }
28867754Smsmith
28999679Siwasaki    /* On failure, delete the result descriptor */
29067754Smsmith
29199679Siwasaki    if (ACPI_FAILURE (Status))
29299679Siwasaki    {
29399679Siwasaki        AcpiUtRemoveReference (ResultDesc);     /* Result descriptor */
29499679Siwasaki    }
29599679Siwasaki    else
29699679Siwasaki    {
29799679Siwasaki        /* Now the address and length are valid for this BufferField */
29867754Smsmith
29999679Siwasaki        ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
30067754Smsmith    }
30167754Smsmith
30299679Siwasaki    return_ACPI_STATUS (Status);
30399679Siwasaki}
30467754Smsmith
30567754Smsmith
306151937Sjkim/*******************************************************************************
30799679Siwasaki *
30899679Siwasaki * FUNCTION:    AcpiDsEvalBufferFieldOperands
30999679Siwasaki *
31099679Siwasaki * PARAMETERS:  WalkState       - Current walk
31199679Siwasaki *              Op              - A valid BufferField Op object
31299679Siwasaki *
31399679Siwasaki * RETURN:      Status
31499679Siwasaki *
31599679Siwasaki * DESCRIPTION: Get BufferField Buffer and Index
31699679Siwasaki *              Called from AcpiDsExecEndOp during BufferField parse tree walk
31799679Siwasaki *
318151937Sjkim ******************************************************************************/
31967754Smsmith
32099679SiwasakiACPI_STATUS
32199679SiwasakiAcpiDsEvalBufferFieldOperands (
32299679Siwasaki    ACPI_WALK_STATE         *WalkState,
32399679Siwasaki    ACPI_PARSE_OBJECT       *Op)
32499679Siwasaki{
32599679Siwasaki    ACPI_STATUS             Status;
32699679Siwasaki    ACPI_OPERAND_OBJECT     *ObjDesc;
32799679Siwasaki    ACPI_NAMESPACE_NODE     *Node;
32899679Siwasaki    ACPI_PARSE_OBJECT       *NextOp;
32967754Smsmith
33067754Smsmith
331167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op);
33267754Smsmith
33367754Smsmith
33499679Siwasaki    /*
33599679Siwasaki     * This is where we evaluate the address and length fields of the
33699679Siwasaki     * CreateXxxField declaration
33799679Siwasaki     */
33899679Siwasaki    Node =  Op->Common.Node;
33999679Siwasaki
34099679Siwasaki    /* NextOp points to the op that holds the Buffer */
34199679Siwasaki
34299679Siwasaki    NextOp = Op->Common.Value.Arg;
34399679Siwasaki
34499679Siwasaki    /* Evaluate/create the address and length operands */
34599679Siwasaki
34699679Siwasaki    Status = AcpiDsCreateOperands (WalkState, NextOp);
34799679Siwasaki    if (ACPI_FAILURE (Status))
34867754Smsmith    {
34999679Siwasaki        return_ACPI_STATUS (Status);
35067754Smsmith    }
35167754Smsmith
35299679Siwasaki    ObjDesc = AcpiNsGetAttachedObject (Node);
35399679Siwasaki    if (!ObjDesc)
35499679Siwasaki    {
35599679Siwasaki        return_ACPI_STATUS (AE_NOT_EXIST);
35699679Siwasaki    }
35767754Smsmith
35899679Siwasaki    /* Resolve the operands */
35999679Siwasaki
360306536Sjkim    Status = AcpiExResolveOperands (
361306536Sjkim        Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
36267754Smsmith    if (ACPI_FAILURE (Status))
36367754Smsmith    {
364204773Sjkim        ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
36599679Siwasaki            AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
36699679Siwasaki
36799679Siwasaki        return_ACPI_STATUS (Status);
36867754Smsmith    }
36999679Siwasaki
37099679Siwasaki    /* Initialize the Buffer Field */
37199679Siwasaki
37299679Siwasaki    if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
37399679Siwasaki    {
37499679Siwasaki        /* NOTE: Slightly different operands for this opcode */
37599679Siwasaki
376102550Siwasaki        Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
377306536Sjkim            WalkState->Operands[0], WalkState->Operands[1],
378306536Sjkim            WalkState->Operands[2], WalkState->Operands[3]);
37999679Siwasaki    }
38067754Smsmith    else
38167754Smsmith    {
38299679Siwasaki        /* All other, CreateXxxField opcodes */
38367754Smsmith
384102550Siwasaki        Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
385306536Sjkim            WalkState->Operands[0], WalkState->Operands[1],
386306536Sjkim            NULL, WalkState->Operands[2]);
38767754Smsmith    }
38867754Smsmith
38967754Smsmith    return_ACPI_STATUS (Status);
39067754Smsmith}
39167754Smsmith
39267754Smsmith
393151937Sjkim/*******************************************************************************
39467754Smsmith *
39567754Smsmith * FUNCTION:    AcpiDsEvalRegionOperands
39667754Smsmith *
39799679Siwasaki * PARAMETERS:  WalkState       - Current walk
39899679Siwasaki *              Op              - A valid region Op object
39967754Smsmith *
40067754Smsmith * RETURN:      Status
40167754Smsmith *
40267754Smsmith * DESCRIPTION: Get region address and length
40367754Smsmith *              Called from AcpiDsExecEndOp during OpRegion parse tree walk
40467754Smsmith *
405151937Sjkim ******************************************************************************/
40667754Smsmith
40767754SmsmithACPI_STATUS
40867754SmsmithAcpiDsEvalRegionOperands (
40967754Smsmith    ACPI_WALK_STATE         *WalkState,
41067754Smsmith    ACPI_PARSE_OBJECT       *Op)
41167754Smsmith{
41267754Smsmith    ACPI_STATUS             Status;
41367754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
41467754Smsmith    ACPI_OPERAND_OBJECT     *OperandDesc;
41567754Smsmith    ACPI_NAMESPACE_NODE     *Node;
41667754Smsmith    ACPI_PARSE_OBJECT       *NextOp;
41767754Smsmith
41867754Smsmith
419167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op);
42067754Smsmith
42167754Smsmith
42267754Smsmith    /*
423151937Sjkim     * This is where we evaluate the address and length fields of the
424151937Sjkim     * OpRegion declaration
42567754Smsmith     */
42699679Siwasaki    Node =  Op->Common.Node;
42767754Smsmith
42867754Smsmith    /* NextOp points to the op that holds the SpaceID */
42983174Smsmith
43099679Siwasaki    NextOp = Op->Common.Value.Arg;
43167754Smsmith
43267754Smsmith    /* NextOp points to address op */
43383174Smsmith
43499679Siwasaki    NextOp = NextOp->Common.Next;
43567754Smsmith
43699146Siwasaki    /* Evaluate/create the address and length operands */
43767754Smsmith
43867754Smsmith    Status = AcpiDsCreateOperands (WalkState, NextOp);
43967754Smsmith    if (ACPI_FAILURE (Status))
44067754Smsmith    {
44167754Smsmith        return_ACPI_STATUS (Status);
44267754Smsmith    }
44367754Smsmith
44469450Smsmith    /* Resolve the length and address operands to numbers */
44569450Smsmith
446306536Sjkim    Status = AcpiExResolveOperands (
447306536Sjkim        Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
44869450Smsmith    if (ACPI_FAILURE (Status))
44969450Smsmith    {
45069450Smsmith        return_ACPI_STATUS (Status);
45169450Smsmith    }
45269450Smsmith
45367754Smsmith    ObjDesc = AcpiNsGetAttachedObject (Node);
45467754Smsmith    if (!ObjDesc)
45567754Smsmith    {
45667754Smsmith        return_ACPI_STATUS (AE_NOT_EXIST);
45767754Smsmith    }
45867754Smsmith
45969450Smsmith    /*
46069450Smsmith     * Get the length operand and save it
46169450Smsmith     * (at Top of stack)
46269450Smsmith     */
46367754Smsmith    OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
46467754Smsmith
46571867Smsmith    ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
46677424Smsmith    AcpiUtRemoveReference (OperandDesc);
46767754Smsmith
46869450Smsmith    /*
46969450Smsmith     * Get the address and save it
47069450Smsmith     * (at top of stack - 1)
47169450Smsmith     */
47267754Smsmith    OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
47367754Smsmith
474151937Sjkim    ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS)
475306536Sjkim        OperandDesc->Integer.Value;
47677424Smsmith    AcpiUtRemoveReference (OperandDesc);
47767754Smsmith
47885756Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
479306536Sjkim        ObjDesc, ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
48080062Smsmith        ObjDesc->Region.Length));
48167754Smsmith
48267754Smsmith    /* Now the address and length are valid for this opregion */
48367754Smsmith
48467754Smsmith    ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
48567754Smsmith    return_ACPI_STATUS (Status);
48667754Smsmith}
48767754Smsmith
48867754Smsmith
489151937Sjkim/*******************************************************************************
49099146Siwasaki *
491193267Sjkim * FUNCTION:    AcpiDsEvalTableRegionOperands
492193267Sjkim *
493193267Sjkim * PARAMETERS:  WalkState       - Current walk
494193267Sjkim *              Op              - A valid region Op object
495193267Sjkim *
496193267Sjkim * RETURN:      Status
497193267Sjkim *
498218590Sjkim * DESCRIPTION: Get region address and length.
499218590Sjkim *              Called from AcpiDsExecEndOp during DataTableRegion parse
500218590Sjkim *              tree walk.
501193267Sjkim *
502193267Sjkim ******************************************************************************/
503193267Sjkim
504193267SjkimACPI_STATUS
505193267SjkimAcpiDsEvalTableRegionOperands (
506193267Sjkim    ACPI_WALK_STATE         *WalkState,
507193267Sjkim    ACPI_PARSE_OBJECT       *Op)
508193267Sjkim{
509193267Sjkim    ACPI_STATUS             Status;
510193267Sjkim    ACPI_OPERAND_OBJECT     *ObjDesc;
511193267Sjkim    ACPI_OPERAND_OBJECT     **Operand;
512193267Sjkim    ACPI_NAMESPACE_NODE     *Node;
513193267Sjkim    ACPI_PARSE_OBJECT       *NextOp;
514306536Sjkim    ACPI_TABLE_HEADER       *Table;
515193267Sjkim    UINT32                  TableIndex;
516193267Sjkim
517193267Sjkim
518193267Sjkim    ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op);
519193267Sjkim
520193267Sjkim
521193267Sjkim    /*
522237412Sjkim     * This is where we evaluate the Signature string, OemId string,
523237412Sjkim     * and OemTableId string of the Data Table Region declaration
524193267Sjkim     */
525193267Sjkim    Node =  Op->Common.Node;
526193267Sjkim
527237412Sjkim    /* NextOp points to Signature string op */
528193267Sjkim
529193267Sjkim    NextOp = Op->Common.Value.Arg;
530193267Sjkim
531193267Sjkim    /*
532237412Sjkim     * Evaluate/create the Signature string, OemId string,
533237412Sjkim     * and OemTableId string operands
534193267Sjkim     */
535193267Sjkim    Status = AcpiDsCreateOperands (WalkState, NextOp);
536193267Sjkim    if (ACPI_FAILURE (Status))
537193267Sjkim    {
538193267Sjkim        return_ACPI_STATUS (Status);
539193267Sjkim    }
540193267Sjkim
541306536Sjkim    Operand = &WalkState->Operands[0];
542306536Sjkim
543193267Sjkim    /*
544237412Sjkim     * Resolve the Signature string, OemId string,
545237412Sjkim     * and OemTableId string operands
546193267Sjkim     */
547306536Sjkim    Status = AcpiExResolveOperands (
548306536Sjkim        Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
549193267Sjkim    if (ACPI_FAILURE (Status))
550193267Sjkim    {
551306536Sjkim        goto Cleanup;
552193267Sjkim    }
553193267Sjkim
554193267Sjkim    /* Find the ACPI table */
555193267Sjkim
556306536Sjkim    Status = AcpiTbFindTable (
557306536Sjkim        Operand[0]->String.Pointer,
558306536Sjkim        Operand[1]->String.Pointer,
559306536Sjkim        Operand[2]->String.Pointer, &TableIndex);
560193267Sjkim    if (ACPI_FAILURE (Status))
561193267Sjkim    {
562306536Sjkim        if (Status == AE_NOT_FOUND)
563306536Sjkim        {
564306536Sjkim            ACPI_ERROR ((AE_INFO,
565306536Sjkim                "ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT",
566306536Sjkim                Operand[0]->String.Pointer,
567306536Sjkim                Operand[1]->String.Pointer,
568306536Sjkim                Operand[2]->String.Pointer));
569306536Sjkim        }
570306536Sjkim        goto Cleanup;
571193267Sjkim    }
572193267Sjkim
573193267Sjkim    Status = AcpiGetTableByIndex (TableIndex, &Table);
574193267Sjkim    if (ACPI_FAILURE (Status))
575193267Sjkim    {
576306536Sjkim        goto Cleanup;
577193267Sjkim    }
578193267Sjkim
579193267Sjkim    ObjDesc = AcpiNsGetAttachedObject (Node);
580193267Sjkim    if (!ObjDesc)
581193267Sjkim    {
582306536Sjkim        Status = AE_NOT_EXIST;
583306536Sjkim        goto Cleanup;
584193267Sjkim    }
585193267Sjkim
586281687Sjkim    ObjDesc->Region.Address = ACPI_PTR_TO_PHYSADDR (Table);
587193267Sjkim    ObjDesc->Region.Length = Table->Length;
588193267Sjkim
589193267Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
590306536Sjkim        ObjDesc, ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
591193267Sjkim        ObjDesc->Region.Length));
592193267Sjkim
593193267Sjkim    /* Now the address and length are valid for this opregion */
594193267Sjkim
595193267Sjkim    ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
596193267Sjkim
597306536SjkimCleanup:
598306536Sjkim    AcpiUtRemoveReference (Operand[0]);
599306536Sjkim    AcpiUtRemoveReference (Operand[1]);
600306536Sjkim    AcpiUtRemoveReference (Operand[2]);
601306536Sjkim
602193267Sjkim    return_ACPI_STATUS (Status);
603193267Sjkim}
604193267Sjkim
605193267Sjkim
606193267Sjkim/*******************************************************************************
607193267Sjkim *
60899146Siwasaki * FUNCTION:    AcpiDsEvalDataObjectOperands
60999146Siwasaki *
61099679Siwasaki * PARAMETERS:  WalkState       - Current walk
61199679Siwasaki *              Op              - A valid DataObject Op object
61299679Siwasaki *              ObjDesc         - DataObject
61399146Siwasaki *
61499146Siwasaki * RETURN:      Status
61599146Siwasaki *
616151937Sjkim * DESCRIPTION: Get the operands and complete the following data object types:
617151937Sjkim *              Buffer, Package.
61899146Siwasaki *
619151937Sjkim ******************************************************************************/
62099146Siwasaki
62199146SiwasakiACPI_STATUS
62299146SiwasakiAcpiDsEvalDataObjectOperands (
62399146Siwasaki    ACPI_WALK_STATE         *WalkState,
62499146Siwasaki    ACPI_PARSE_OBJECT       *Op,
62599146Siwasaki    ACPI_OPERAND_OBJECT     *ObjDesc)
62699146Siwasaki{
62799146Siwasaki    ACPI_STATUS             Status;
62899146Siwasaki    ACPI_OPERAND_OBJECT     *ArgDesc;
62999146Siwasaki    UINT32                  Length;
63099146Siwasaki
63199146Siwasaki
632167802Sjkim    ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands);
63399146Siwasaki
63499146Siwasaki
63599146Siwasaki    /* The first operand (for all of these data objects) is the length */
63699146Siwasaki
637167802Sjkim    /*
638167802Sjkim     * Set proper index into operand stack for AcpiDsObjStackPush
639167802Sjkim     * invoked inside AcpiDsCreateOperand.
640167802Sjkim     */
641167802Sjkim    WalkState->OperandIndex = WalkState->NumOperands;
642167802Sjkim
64399679Siwasaki    Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
64499146Siwasaki    if (ACPI_FAILURE (Status))
64599146Siwasaki    {
64699146Siwasaki        return_ACPI_STATUS (Status);
64799146Siwasaki    }
64899146Siwasaki
64999146Siwasaki    Status = AcpiExResolveOperands (WalkState->Opcode,
650306536Sjkim        &(WalkState->Operands [WalkState->NumOperands -1]),
651306536Sjkim        WalkState);
65299146Siwasaki    if (ACPI_FAILURE (Status))
65399146Siwasaki    {
65499146Siwasaki        return_ACPI_STATUS (Status);
65599146Siwasaki    }
65699146Siwasaki
65799146Siwasaki    /* Extract length operand */
65899146Siwasaki
65999146Siwasaki    ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
66099146Siwasaki    Length = (UINT32) ArgDesc->Integer.Value;
66199146Siwasaki
66299146Siwasaki    /* Cleanup for length operand */
66399146Siwasaki
66499679Siwasaki    Status = AcpiDsObjStackPop (1, WalkState);
66599679Siwasaki    if (ACPI_FAILURE (Status))
66699679Siwasaki    {
66799679Siwasaki        return_ACPI_STATUS (Status);
66899679Siwasaki    }
66999679Siwasaki
67099146Siwasaki    AcpiUtRemoveReference (ArgDesc);
67199146Siwasaki
672102550Siwasaki    /*
67399146Siwasaki     * Create the actual data object
67499146Siwasaki     */
67599679Siwasaki    switch (Op->Common.AmlOpcode)
67699146Siwasaki    {
67799146Siwasaki    case AML_BUFFER_OP:
67899146Siwasaki
679306536Sjkim        Status = AcpiDsBuildInternalBufferObj (
680306536Sjkim            WalkState, Op, Length, &ObjDesc);
68199146Siwasaki        break;
68299146Siwasaki
68399146Siwasaki    case AML_PACKAGE_OP:
68499146Siwasaki    case AML_VAR_PACKAGE_OP:
68599146Siwasaki
686306536Sjkim        Status = AcpiDsBuildInternalPackageObj (
687306536Sjkim            WalkState, Op, Length, &ObjDesc);
68899146Siwasaki        break;
68999146Siwasaki
69099146Siwasaki    default:
691250838Sjkim
69299146Siwasaki        return_ACPI_STATUS (AE_AML_BAD_OPCODE);
69399146Siwasaki    }
69499146Siwasaki
69599146Siwasaki    if (ACPI_SUCCESS (Status))
69699146Siwasaki    {
69799146Siwasaki        /*
698151937Sjkim         * Return the object in the WalkState, unless the parent is a package -
69999146Siwasaki         * in this case, the return object will be stored in the parse tree
70099146Siwasaki         * for the package.
70199146Siwasaki         */
70299679Siwasaki        if ((!Op->Common.Parent) ||
70399679Siwasaki            ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
70499679Siwasaki             (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) &&
70599679Siwasaki             (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
70699146Siwasaki        {
70799146Siwasaki            WalkState->ResultObj = ObjDesc;
70899146Siwasaki        }
70999146Siwasaki    }
71099146Siwasaki
71199146Siwasaki    return_ACPI_STATUS (Status);
71299146Siwasaki}
71399146Siwasaki
71499146Siwasaki
71567754Smsmith/*******************************************************************************
71667754Smsmith *
717193267Sjkim * FUNCTION:    AcpiDsEvalBankFieldOperands
718193267Sjkim *
719193267Sjkim * PARAMETERS:  WalkState       - Current walk
720193267Sjkim *              Op              - A valid BankField Op object
721193267Sjkim *
722193267Sjkim * RETURN:      Status
723193267Sjkim *
724193267Sjkim * DESCRIPTION: Get BankField BankValue
725193267Sjkim *              Called from AcpiDsExecEndOp during BankField parse tree walk
726193267Sjkim *
727193267Sjkim ******************************************************************************/
728193267Sjkim
729193267SjkimACPI_STATUS
730193267SjkimAcpiDsEvalBankFieldOperands (
731193267Sjkim    ACPI_WALK_STATE         *WalkState,
732193267Sjkim    ACPI_PARSE_OBJECT       *Op)
733193267Sjkim{
734193267Sjkim    ACPI_STATUS             Status;
735193267Sjkim    ACPI_OPERAND_OBJECT     *ObjDesc;
736193267Sjkim    ACPI_OPERAND_OBJECT     *OperandDesc;
737193267Sjkim    ACPI_NAMESPACE_NODE     *Node;
738193267Sjkim    ACPI_PARSE_OBJECT       *NextOp;
739193267Sjkim    ACPI_PARSE_OBJECT       *Arg;
740193267Sjkim
741193267Sjkim
742193267Sjkim    ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands, Op);
743193267Sjkim
744193267Sjkim
745193267Sjkim    /*
746193267Sjkim     * This is where we evaluate the BankValue field of the
747193267Sjkim     * BankField declaration
748193267Sjkim     */
749193267Sjkim
750193267Sjkim    /* NextOp points to the op that holds the Region */
751193267Sjkim
752193267Sjkim    NextOp = Op->Common.Value.Arg;
753193267Sjkim
754193267Sjkim    /* NextOp points to the op that holds the Bank Register */
755193267Sjkim
756193267Sjkim    NextOp = NextOp->Common.Next;
757193267Sjkim
758193267Sjkim    /* NextOp points to the op that holds the Bank Value */
759193267Sjkim
760193267Sjkim    NextOp = NextOp->Common.Next;
761193267Sjkim
762193267Sjkim    /*
763193267Sjkim     * Set proper index into operand stack for AcpiDsObjStackPush
764193267Sjkim     * invoked inside AcpiDsCreateOperand.
765193267Sjkim     *
766193267Sjkim     * We use WalkState->Operands[0] to store the evaluated BankValue
767193267Sjkim     */
768193267Sjkim    WalkState->OperandIndex = 0;
769193267Sjkim
770193267Sjkim    Status = AcpiDsCreateOperand (WalkState, NextOp, 0);
771193267Sjkim    if (ACPI_FAILURE (Status))
772193267Sjkim    {
773193267Sjkim        return_ACPI_STATUS (Status);
774193267Sjkim    }
775193267Sjkim
776193267Sjkim    Status = AcpiExResolveToValue (&WalkState->Operands[0], WalkState);
777193267Sjkim    if (ACPI_FAILURE (Status))
778193267Sjkim    {
779193267Sjkim        return_ACPI_STATUS (Status);
780193267Sjkim    }
781193267Sjkim
782193267Sjkim    ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS,
783193267Sjkim        AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 1);
784193267Sjkim    /*
785193267Sjkim     * Get the BankValue operand and save it
786193267Sjkim     * (at Top of stack)
787193267Sjkim     */
788193267Sjkim    OperandDesc = WalkState->Operands[0];
789193267Sjkim
790193267Sjkim    /* Arg points to the start Bank Field */
791193267Sjkim
792193267Sjkim    Arg = AcpiPsGetArg (Op, 4);
793193267Sjkim    while (Arg)
794193267Sjkim    {
795193267Sjkim        /* Ignore OFFSET and ACCESSAS terms here */
796193267Sjkim
797193267Sjkim        if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
798193267Sjkim        {
799193267Sjkim            Node = Arg->Common.Node;
800193267Sjkim
801193267Sjkim            ObjDesc = AcpiNsGetAttachedObject (Node);
802193267Sjkim            if (!ObjDesc)
803193267Sjkim            {
804193267Sjkim                return_ACPI_STATUS (AE_NOT_EXIST);
805193267Sjkim            }
806193267Sjkim
807193267Sjkim            ObjDesc->BankField.Value = (UINT32) OperandDesc->Integer.Value;
808193267Sjkim        }
809193267Sjkim
810193267Sjkim        /* Move to next field in the list */
811193267Sjkim
812193267Sjkim        Arg = Arg->Common.Next;
813193267Sjkim    }
814193267Sjkim
815193267Sjkim    AcpiUtRemoveReference (OperandDesc);
816193267Sjkim    return_ACPI_STATUS (Status);
817193267Sjkim}
818