xref: /netbsd-src/sys/external/bsd/acpica/dist/dispatcher/dsopcode.c (revision 2c7d7e3ca2e4f0b675c6c58e614f6aede66c678e)
128c506b8Sjruoho /******************************************************************************
228c506b8Sjruoho  *
3a2c051a9Schristos  * Module Name: dsopcode - Dispatcher support for regions and fields
428c506b8Sjruoho  *
528c506b8Sjruoho  *****************************************************************************/
628c506b8Sjruoho 
7159c4e26Sjruoho /*
8*2c7d7e3cSchristos  * Copyright (C) 2000 - 2023, Intel Corp.
928c506b8Sjruoho  * All rights reserved.
1028c506b8Sjruoho  *
11159c4e26Sjruoho  * Redistribution and use in source and binary forms, with or without
12159c4e26Sjruoho  * modification, are permitted provided that the following conditions
13159c4e26Sjruoho  * are met:
14159c4e26Sjruoho  * 1. Redistributions of source code must retain the above copyright
15159c4e26Sjruoho  *    notice, this list of conditions, and the following disclaimer,
16159c4e26Sjruoho  *    without modification.
17159c4e26Sjruoho  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18159c4e26Sjruoho  *    substantially similar to the "NO WARRANTY" disclaimer below
19159c4e26Sjruoho  *    ("Disclaimer") and any redistribution must be conditioned upon
20159c4e26Sjruoho  *    including a substantially similar Disclaimer requirement for further
21159c4e26Sjruoho  *    binary redistribution.
22159c4e26Sjruoho  * 3. Neither the names of the above-listed copyright holders nor the names
23159c4e26Sjruoho  *    of any contributors may be used to endorse or promote products derived
24159c4e26Sjruoho  *    from this software without specific prior written permission.
2528c506b8Sjruoho  *
26159c4e26Sjruoho  * Alternatively, this software may be distributed under the terms of the
27159c4e26Sjruoho  * GNU General Public License ("GPL") version 2 as published by the Free
28159c4e26Sjruoho  * Software Foundation.
2928c506b8Sjruoho  *
30159c4e26Sjruoho  * NO WARRANTY
31159c4e26Sjruoho  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32159c4e26Sjruoho  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3398244dcfSchristos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34159c4e26Sjruoho  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35159c4e26Sjruoho  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36159c4e26Sjruoho  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37159c4e26Sjruoho  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38159c4e26Sjruoho  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39159c4e26Sjruoho  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40159c4e26Sjruoho  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41159c4e26Sjruoho  * POSSIBILITY OF SUCH DAMAGES.
42159c4e26Sjruoho  */
4328c506b8Sjruoho 
4428c506b8Sjruoho #include "acpi.h"
4528c506b8Sjruoho #include "accommon.h"
4628c506b8Sjruoho #include "acparser.h"
4728c506b8Sjruoho #include "amlcode.h"
4828c506b8Sjruoho #include "acdispat.h"
4928c506b8Sjruoho #include "acinterp.h"
5028c506b8Sjruoho #include "acnamesp.h"
5128c506b8Sjruoho #include "acevents.h"
5228c506b8Sjruoho #include "actables.h"
5328c506b8Sjruoho 
5428c506b8Sjruoho #define _COMPONENT          ACPI_DISPATCHER
5528c506b8Sjruoho         ACPI_MODULE_NAME    ("dsopcode")
5628c506b8Sjruoho 
5728c506b8Sjruoho /* Local prototypes */
5828c506b8Sjruoho 
5928c506b8Sjruoho static ACPI_STATUS
6028c506b8Sjruoho AcpiDsInitBufferField (
6128c506b8Sjruoho     UINT16                  AmlOpcode,
6228c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ObjDesc,
6328c506b8Sjruoho     ACPI_OPERAND_OBJECT     *BufferDesc,
6428c506b8Sjruoho     ACPI_OPERAND_OBJECT     *OffsetDesc,
6528c506b8Sjruoho     ACPI_OPERAND_OBJECT     *LengthDesc,
6628c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ResultDesc);
6728c506b8Sjruoho 
6828c506b8Sjruoho 
6928c506b8Sjruoho /*******************************************************************************
7028c506b8Sjruoho  *
7128c506b8Sjruoho  * FUNCTION:    AcpiDsInitializeRegion
7228c506b8Sjruoho  *
7328c506b8Sjruoho  * PARAMETERS:  ObjHandle       - Region namespace node
7428c506b8Sjruoho  *
7528c506b8Sjruoho  * RETURN:      Status
7628c506b8Sjruoho  *
7728c506b8Sjruoho  * DESCRIPTION: Front end to EvInitializeRegion
7828c506b8Sjruoho  *
7928c506b8Sjruoho  ******************************************************************************/
8028c506b8Sjruoho 
8128c506b8Sjruoho ACPI_STATUS
AcpiDsInitializeRegion(ACPI_HANDLE ObjHandle)8228c506b8Sjruoho AcpiDsInitializeRegion (
8328c506b8Sjruoho     ACPI_HANDLE             ObjHandle)
8428c506b8Sjruoho {
8528c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ObjDesc;
8628c506b8Sjruoho     ACPI_STATUS             Status;
8728c506b8Sjruoho 
8828c506b8Sjruoho 
8928c506b8Sjruoho     ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
9028c506b8Sjruoho 
9128c506b8Sjruoho     /* Namespace is NOT locked */
9228c506b8Sjruoho 
93660602a8Schristos     Status = AcpiEvInitializeRegion (ObjDesc);
9428c506b8Sjruoho     return (Status);
9528c506b8Sjruoho }
9628c506b8Sjruoho 
9728c506b8Sjruoho 
9828c506b8Sjruoho /*******************************************************************************
9928c506b8Sjruoho  *
10028c506b8Sjruoho  * FUNCTION:    AcpiDsInitBufferField
10128c506b8Sjruoho  *
10228c506b8Sjruoho  * PARAMETERS:  AmlOpcode       - CreateXxxField
10328c506b8Sjruoho  *              ObjDesc         - BufferField object
10428c506b8Sjruoho  *              BufferDesc      - Host Buffer
10528c506b8Sjruoho  *              OffsetDesc      - Offset into buffer
10628c506b8Sjruoho  *              LengthDesc      - Length of field (CREATE_FIELD_OP only)
10728c506b8Sjruoho  *              ResultDesc      - Where to store the result
10828c506b8Sjruoho  *
10928c506b8Sjruoho  * RETURN:      Status
11028c506b8Sjruoho  *
11128c506b8Sjruoho  * DESCRIPTION: Perform actual initialization of a buffer field
11228c506b8Sjruoho  *
11328c506b8Sjruoho  ******************************************************************************/
11428c506b8Sjruoho 
11528c506b8Sjruoho static ACPI_STATUS
AcpiDsInitBufferField(UINT16 AmlOpcode,ACPI_OPERAND_OBJECT * ObjDesc,ACPI_OPERAND_OBJECT * BufferDesc,ACPI_OPERAND_OBJECT * OffsetDesc,ACPI_OPERAND_OBJECT * LengthDesc,ACPI_OPERAND_OBJECT * ResultDesc)11628c506b8Sjruoho AcpiDsInitBufferField (
11728c506b8Sjruoho     UINT16                  AmlOpcode,
11828c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ObjDesc,
11928c506b8Sjruoho     ACPI_OPERAND_OBJECT     *BufferDesc,
12028c506b8Sjruoho     ACPI_OPERAND_OBJECT     *OffsetDesc,
12128c506b8Sjruoho     ACPI_OPERAND_OBJECT     *LengthDesc,
12228c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ResultDesc)
12328c506b8Sjruoho {
12428c506b8Sjruoho     UINT32                  Offset;
12528c506b8Sjruoho     UINT32                  BitOffset;
12628c506b8Sjruoho     UINT32                  BitCount;
12728c506b8Sjruoho     UINT8                   FieldFlags;
12828c506b8Sjruoho     ACPI_STATUS             Status;
12928c506b8Sjruoho 
13028c506b8Sjruoho 
13128c506b8Sjruoho     ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc);
13228c506b8Sjruoho 
13328c506b8Sjruoho 
13428c506b8Sjruoho     /* Host object must be a Buffer */
13528c506b8Sjruoho 
13628c506b8Sjruoho     if (BufferDesc->Common.Type != ACPI_TYPE_BUFFER)
13728c506b8Sjruoho     {
13828c506b8Sjruoho         ACPI_ERROR ((AE_INFO,
13928c506b8Sjruoho             "Target of Create Field is not a Buffer object - %s",
14028c506b8Sjruoho             AcpiUtGetObjectTypeName (BufferDesc)));
14128c506b8Sjruoho 
14228c506b8Sjruoho         Status = AE_AML_OPERAND_TYPE;
14328c506b8Sjruoho         goto Cleanup;
14428c506b8Sjruoho     }
14528c506b8Sjruoho 
14628c506b8Sjruoho     /*
14728c506b8Sjruoho      * The last parameter to all of these opcodes (ResultDesc) started
14828c506b8Sjruoho      * out as a NameString, and should therefore now be a NS node
14928c506b8Sjruoho      * after resolution in AcpiExResolveOperands().
15028c506b8Sjruoho      */
15128c506b8Sjruoho     if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
15228c506b8Sjruoho     {
15328c506b8Sjruoho         ACPI_ERROR ((AE_INFO,
15428c506b8Sjruoho             "(%s) destination not a NS Node [%s]",
15528c506b8Sjruoho             AcpiPsGetOpcodeName (AmlOpcode),
15628c506b8Sjruoho             AcpiUtGetDescriptorName (ResultDesc)));
15728c506b8Sjruoho 
15828c506b8Sjruoho         Status = AE_AML_OPERAND_TYPE;
15928c506b8Sjruoho         goto Cleanup;
16028c506b8Sjruoho     }
16128c506b8Sjruoho 
16228c506b8Sjruoho     Offset = (UINT32) OffsetDesc->Integer.Value;
16328c506b8Sjruoho 
16428c506b8Sjruoho     /*
16528c506b8Sjruoho      * Setup the Bit offsets and counts, according to the opcode
16628c506b8Sjruoho      */
16728c506b8Sjruoho     switch (AmlOpcode)
16828c506b8Sjruoho     {
16928c506b8Sjruoho     case AML_CREATE_FIELD_OP:
17028c506b8Sjruoho 
17128c506b8Sjruoho         /* Offset is in bits, count is in bits */
17228c506b8Sjruoho 
17328c506b8Sjruoho         FieldFlags = AML_FIELD_ACCESS_BYTE;
17428c506b8Sjruoho         BitOffset  = Offset;
17528c506b8Sjruoho         BitCount   = (UINT32) LengthDesc->Integer.Value;
17628c506b8Sjruoho 
17728c506b8Sjruoho         /* Must have a valid (>0) bit count */
17828c506b8Sjruoho 
17928c506b8Sjruoho         if (BitCount == 0)
18028c506b8Sjruoho         {
1815b948c02Schristos             ACPI_BIOS_ERROR ((AE_INFO,
18228c506b8Sjruoho                 "Attempt to CreateField of length zero"));
18328c506b8Sjruoho             Status = AE_AML_OPERAND_VALUE;
18428c506b8Sjruoho             goto Cleanup;
18528c506b8Sjruoho         }
18628c506b8Sjruoho         break;
18728c506b8Sjruoho 
18828c506b8Sjruoho     case AML_CREATE_BIT_FIELD_OP:
18928c506b8Sjruoho 
19028c506b8Sjruoho         /* Offset is in bits, Field is one bit */
19128c506b8Sjruoho 
19228c506b8Sjruoho         BitOffset  = Offset;
19328c506b8Sjruoho         BitCount   = 1;
19428c506b8Sjruoho         FieldFlags = AML_FIELD_ACCESS_BYTE;
19528c506b8Sjruoho         break;
19628c506b8Sjruoho 
19728c506b8Sjruoho     case AML_CREATE_BYTE_FIELD_OP:
19828c506b8Sjruoho 
19928c506b8Sjruoho         /* Offset is in bytes, field is one byte */
20028c506b8Sjruoho 
20128c506b8Sjruoho         BitOffset  = 8 * Offset;
20228c506b8Sjruoho         BitCount   = 8;
20328c506b8Sjruoho         FieldFlags = AML_FIELD_ACCESS_BYTE;
20428c506b8Sjruoho         break;
20528c506b8Sjruoho 
20628c506b8Sjruoho     case AML_CREATE_WORD_FIELD_OP:
20728c506b8Sjruoho 
20828c506b8Sjruoho         /* Offset is in bytes, field is one word */
20928c506b8Sjruoho 
21028c506b8Sjruoho         BitOffset  = 8 * Offset;
21128c506b8Sjruoho         BitCount   = 16;
21228c506b8Sjruoho         FieldFlags = AML_FIELD_ACCESS_WORD;
21328c506b8Sjruoho         break;
21428c506b8Sjruoho 
21528c506b8Sjruoho     case AML_CREATE_DWORD_FIELD_OP:
21628c506b8Sjruoho 
21728c506b8Sjruoho         /* Offset is in bytes, field is one dword */
21828c506b8Sjruoho 
21928c506b8Sjruoho         BitOffset  = 8 * Offset;
22028c506b8Sjruoho         BitCount   = 32;
22128c506b8Sjruoho         FieldFlags = AML_FIELD_ACCESS_DWORD;
22228c506b8Sjruoho         break;
22328c506b8Sjruoho 
22428c506b8Sjruoho     case AML_CREATE_QWORD_FIELD_OP:
22528c506b8Sjruoho 
22628c506b8Sjruoho         /* Offset is in bytes, field is one qword */
22728c506b8Sjruoho 
22828c506b8Sjruoho         BitOffset  = 8 * Offset;
22928c506b8Sjruoho         BitCount   = 64;
23028c506b8Sjruoho         FieldFlags = AML_FIELD_ACCESS_QWORD;
23128c506b8Sjruoho         break;
23228c506b8Sjruoho 
23328c506b8Sjruoho     default:
23428c506b8Sjruoho 
23528c506b8Sjruoho         ACPI_ERROR ((AE_INFO,
23628c506b8Sjruoho             "Unknown field creation opcode 0x%02X",
23728c506b8Sjruoho             AmlOpcode));
23828c506b8Sjruoho         Status = AE_AML_BAD_OPCODE;
23928c506b8Sjruoho         goto Cleanup;
24028c506b8Sjruoho     }
24128c506b8Sjruoho 
24228c506b8Sjruoho     /* Entire field must fit within the current length of the buffer */
24328c506b8Sjruoho 
24428c506b8Sjruoho     if ((BitOffset + BitCount) >
24528c506b8Sjruoho         (8 * (UINT32) BufferDesc->Buffer.Length))
24628c506b8Sjruoho     {
2475b948c02Schristos         Status = AE_AML_BUFFER_LIMIT;
2485b948c02Schristos         ACPI_BIOS_EXCEPTION ((AE_INFO, Status,
249ae01dbf5Schristos             "Field [%4.4s] at bit offset/length %u/%u "
250ae01dbf5Schristos             "exceeds size of target Buffer (%u bits)",
251ae01dbf5Schristos             AcpiUtGetNodeName (ResultDesc), BitOffset, BitCount,
25228c506b8Sjruoho             8 * (UINT32) BufferDesc->Buffer.Length));
25328c506b8Sjruoho         goto Cleanup;
25428c506b8Sjruoho     }
25528c506b8Sjruoho 
25628c506b8Sjruoho     /*
25728c506b8Sjruoho      * Initialize areas of the field object that are common to all fields
25828c506b8Sjruoho      * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
25928c506b8Sjruoho      * UPDATE_RULE = 0 (UPDATE_PRESERVE)
26028c506b8Sjruoho      */
26181bd9c9cSchristos     Status = AcpiExPrepCommonFieldObject (
26281bd9c9cSchristos         ObjDesc, FieldFlags, 0, BitOffset, BitCount);
26328c506b8Sjruoho     if (ACPI_FAILURE (Status))
26428c506b8Sjruoho     {
26528c506b8Sjruoho         goto Cleanup;
26628c506b8Sjruoho     }
26728c506b8Sjruoho 
26828c506b8Sjruoho     ObjDesc->BufferField.BufferObj = BufferDesc;
2691c663068Schristos     ObjDesc->BufferField.IsCreateField = AmlOpcode == AML_CREATE_FIELD_OP;
27028c506b8Sjruoho 
27128c506b8Sjruoho     /* Reference count for BufferDesc inherits ObjDesc count */
27228c506b8Sjruoho 
27328c506b8Sjruoho     BufferDesc->Common.ReferenceCount = (UINT16)
27428c506b8Sjruoho         (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);
27528c506b8Sjruoho 
27628c506b8Sjruoho 
27728c506b8Sjruoho Cleanup:
27828c506b8Sjruoho 
27928c506b8Sjruoho     /* Always delete the operands */
28028c506b8Sjruoho 
28128c506b8Sjruoho     AcpiUtRemoveReference (OffsetDesc);
28228c506b8Sjruoho     AcpiUtRemoveReference (BufferDesc);
28328c506b8Sjruoho 
28428c506b8Sjruoho     if (AmlOpcode == AML_CREATE_FIELD_OP)
28528c506b8Sjruoho     {
28628c506b8Sjruoho         AcpiUtRemoveReference (LengthDesc);
28728c506b8Sjruoho     }
28828c506b8Sjruoho 
28928c506b8Sjruoho     /* On failure, delete the result descriptor */
29028c506b8Sjruoho 
29128c506b8Sjruoho     if (ACPI_FAILURE (Status))
29228c506b8Sjruoho     {
29328c506b8Sjruoho         AcpiUtRemoveReference (ResultDesc);     /* Result descriptor */
29428c506b8Sjruoho     }
29528c506b8Sjruoho     else
29628c506b8Sjruoho     {
29728c506b8Sjruoho         /* Now the address and length are valid for this BufferField */
29828c506b8Sjruoho 
29928c506b8Sjruoho         ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
30028c506b8Sjruoho     }
30128c506b8Sjruoho 
30228c506b8Sjruoho     return_ACPI_STATUS (Status);
30328c506b8Sjruoho }
30428c506b8Sjruoho 
30528c506b8Sjruoho 
30628c506b8Sjruoho /*******************************************************************************
30728c506b8Sjruoho  *
30828c506b8Sjruoho  * FUNCTION:    AcpiDsEvalBufferFieldOperands
30928c506b8Sjruoho  *
31028c506b8Sjruoho  * PARAMETERS:  WalkState       - Current walk
31128c506b8Sjruoho  *              Op              - A valid BufferField Op object
31228c506b8Sjruoho  *
31328c506b8Sjruoho  * RETURN:      Status
31428c506b8Sjruoho  *
31528c506b8Sjruoho  * DESCRIPTION: Get BufferField Buffer and Index
31628c506b8Sjruoho  *              Called from AcpiDsExecEndOp during BufferField parse tree walk
31728c506b8Sjruoho  *
31828c506b8Sjruoho  ******************************************************************************/
31928c506b8Sjruoho 
32028c506b8Sjruoho ACPI_STATUS
AcpiDsEvalBufferFieldOperands(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * Op)32128c506b8Sjruoho AcpiDsEvalBufferFieldOperands (
32228c506b8Sjruoho     ACPI_WALK_STATE         *WalkState,
32328c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op)
32428c506b8Sjruoho {
32528c506b8Sjruoho     ACPI_STATUS             Status;
32628c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ObjDesc;
32728c506b8Sjruoho     ACPI_NAMESPACE_NODE     *Node;
32828c506b8Sjruoho     ACPI_PARSE_OBJECT       *NextOp;
32928c506b8Sjruoho 
33028c506b8Sjruoho 
33128c506b8Sjruoho     ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op);
33228c506b8Sjruoho 
33328c506b8Sjruoho 
33428c506b8Sjruoho     /*
33528c506b8Sjruoho      * This is where we evaluate the address and length fields of the
33628c506b8Sjruoho      * CreateXxxField declaration
33728c506b8Sjruoho      */
33828c506b8Sjruoho     Node =  Op->Common.Node;
33928c506b8Sjruoho 
34028c506b8Sjruoho     /* NextOp points to the op that holds the Buffer */
34128c506b8Sjruoho 
34228c506b8Sjruoho     NextOp = Op->Common.Value.Arg;
34328c506b8Sjruoho 
34428c506b8Sjruoho     /* Evaluate/create the address and length operands */
34528c506b8Sjruoho 
34628c506b8Sjruoho     Status = AcpiDsCreateOperands (WalkState, NextOp);
34728c506b8Sjruoho     if (ACPI_FAILURE (Status))
34828c506b8Sjruoho     {
34928c506b8Sjruoho         return_ACPI_STATUS (Status);
35028c506b8Sjruoho     }
35128c506b8Sjruoho 
35228c506b8Sjruoho     ObjDesc = AcpiNsGetAttachedObject (Node);
35328c506b8Sjruoho     if (!ObjDesc)
35428c506b8Sjruoho     {
35528c506b8Sjruoho         return_ACPI_STATUS (AE_NOT_EXIST);
35628c506b8Sjruoho     }
35728c506b8Sjruoho 
35828c506b8Sjruoho     /* Resolve the operands */
35928c506b8Sjruoho 
36081bd9c9cSchristos     Status = AcpiExResolveOperands (
36181bd9c9cSchristos         Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
36228c506b8Sjruoho     if (ACPI_FAILURE (Status))
36328c506b8Sjruoho     {
36428c506b8Sjruoho         ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
36528c506b8Sjruoho             AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
36628c506b8Sjruoho 
36728c506b8Sjruoho         return_ACPI_STATUS (Status);
36828c506b8Sjruoho     }
36928c506b8Sjruoho 
37028c506b8Sjruoho     /* Initialize the Buffer Field */
37128c506b8Sjruoho 
37228c506b8Sjruoho     if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
37328c506b8Sjruoho     {
37428c506b8Sjruoho         /* NOTE: Slightly different operands for this opcode */
37528c506b8Sjruoho 
37628c506b8Sjruoho         Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
37728c506b8Sjruoho             WalkState->Operands[0], WalkState->Operands[1],
37828c506b8Sjruoho             WalkState->Operands[2], WalkState->Operands[3]);
37928c506b8Sjruoho     }
38028c506b8Sjruoho     else
38128c506b8Sjruoho     {
38228c506b8Sjruoho         /* All other, CreateXxxField opcodes */
38328c506b8Sjruoho 
38428c506b8Sjruoho         Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
38528c506b8Sjruoho             WalkState->Operands[0], WalkState->Operands[1],
38628c506b8Sjruoho             NULL, WalkState->Operands[2]);
38728c506b8Sjruoho     }
38828c506b8Sjruoho 
38928c506b8Sjruoho     return_ACPI_STATUS (Status);
39028c506b8Sjruoho }
39128c506b8Sjruoho 
39228c506b8Sjruoho 
39328c506b8Sjruoho /*******************************************************************************
39428c506b8Sjruoho  *
39528c506b8Sjruoho  * FUNCTION:    AcpiDsEvalRegionOperands
39628c506b8Sjruoho  *
39728c506b8Sjruoho  * PARAMETERS:  WalkState       - Current walk
39828c506b8Sjruoho  *              Op              - A valid region Op object
39928c506b8Sjruoho  *
40028c506b8Sjruoho  * RETURN:      Status
40128c506b8Sjruoho  *
40228c506b8Sjruoho  * DESCRIPTION: Get region address and length
40328c506b8Sjruoho  *              Called from AcpiDsExecEndOp during OpRegion parse tree walk
40428c506b8Sjruoho  *
40528c506b8Sjruoho  ******************************************************************************/
40628c506b8Sjruoho 
40728c506b8Sjruoho ACPI_STATUS
AcpiDsEvalRegionOperands(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * Op)40828c506b8Sjruoho AcpiDsEvalRegionOperands (
40928c506b8Sjruoho     ACPI_WALK_STATE         *WalkState,
41028c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op)
41128c506b8Sjruoho {
41228c506b8Sjruoho     ACPI_STATUS             Status;
41328c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ObjDesc;
41428c506b8Sjruoho     ACPI_OPERAND_OBJECT     *OperandDesc;
41528c506b8Sjruoho     ACPI_NAMESPACE_NODE     *Node;
41628c506b8Sjruoho     ACPI_PARSE_OBJECT       *NextOp;
4175b948c02Schristos     ACPI_ADR_SPACE_TYPE     SpaceId;
41828c506b8Sjruoho 
41928c506b8Sjruoho 
42028c506b8Sjruoho     ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op);
42128c506b8Sjruoho 
42228c506b8Sjruoho 
42328c506b8Sjruoho     /*
42428c506b8Sjruoho      * This is where we evaluate the address and length fields of the
42528c506b8Sjruoho      * OpRegion declaration
42628c506b8Sjruoho      */
42728c506b8Sjruoho     Node = Op->Common.Node;
42828c506b8Sjruoho 
42928c506b8Sjruoho     /* NextOp points to the op that holds the SpaceID */
43028c506b8Sjruoho 
43128c506b8Sjruoho     NextOp = Op->Common.Value.Arg;
4325b948c02Schristos     SpaceId = (ACPI_ADR_SPACE_TYPE) NextOp->Common.Value.Integer;
43328c506b8Sjruoho 
43428c506b8Sjruoho     /* NextOp points to address op */
43528c506b8Sjruoho 
43628c506b8Sjruoho     NextOp = NextOp->Common.Next;
43728c506b8Sjruoho 
43828c506b8Sjruoho     /* Evaluate/create the address and length operands */
43928c506b8Sjruoho 
44028c506b8Sjruoho     Status = AcpiDsCreateOperands (WalkState, NextOp);
44128c506b8Sjruoho     if (ACPI_FAILURE (Status))
44228c506b8Sjruoho     {
44328c506b8Sjruoho         return_ACPI_STATUS (Status);
44428c506b8Sjruoho     }
44528c506b8Sjruoho 
44628c506b8Sjruoho     /* Resolve the length and address operands to numbers */
44728c506b8Sjruoho 
44881bd9c9cSchristos     Status = AcpiExResolveOperands (
44981bd9c9cSchristos         Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
45028c506b8Sjruoho     if (ACPI_FAILURE (Status))
45128c506b8Sjruoho     {
45228c506b8Sjruoho         return_ACPI_STATUS (Status);
45328c506b8Sjruoho     }
45428c506b8Sjruoho 
45528c506b8Sjruoho     ObjDesc = AcpiNsGetAttachedObject (Node);
45628c506b8Sjruoho     if (!ObjDesc)
45728c506b8Sjruoho     {
45828c506b8Sjruoho         return_ACPI_STATUS (AE_NOT_EXIST);
45928c506b8Sjruoho     }
46028c506b8Sjruoho 
46128c506b8Sjruoho     /*
46228c506b8Sjruoho      * Get the length operand and save it
46328c506b8Sjruoho      * (at Top of stack)
46428c506b8Sjruoho      */
46528c506b8Sjruoho     OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
46628c506b8Sjruoho 
46728c506b8Sjruoho     ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
46828c506b8Sjruoho     AcpiUtRemoveReference (OperandDesc);
46928c506b8Sjruoho 
4705b948c02Schristos     /* A zero-length operation region is unusable. Just warn */
4715b948c02Schristos 
4725b948c02Schristos     if (!ObjDesc->Region.Length && (SpaceId < ACPI_NUM_PREDEFINED_REGIONS))
4735b948c02Schristos     {
4745b948c02Schristos         ACPI_WARNING ((AE_INFO,
4755b948c02Schristos             "Operation Region [%4.4s] has zero length (SpaceId %X)",
4765b948c02Schristos             Node->Name.Ascii, SpaceId));
4775b948c02Schristos     }
4785b948c02Schristos 
47928c506b8Sjruoho     /*
48028c506b8Sjruoho      * Get the address and save it
48128c506b8Sjruoho      * (at top of stack - 1)
48228c506b8Sjruoho      */
48328c506b8Sjruoho     OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
48428c506b8Sjruoho 
48528c506b8Sjruoho     ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS)
48628c506b8Sjruoho         OperandDesc->Integer.Value;
48728c506b8Sjruoho     AcpiUtRemoveReference (OperandDesc);
48828c506b8Sjruoho 
48928c506b8Sjruoho     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
49081bd9c9cSchristos         ObjDesc, ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
49128c506b8Sjruoho         ObjDesc->Region.Length));
49228c506b8Sjruoho 
4937efa3256Schristos     Status = AcpiUtAddAddressRange (ObjDesc->Region.SpaceId,
4947efa3256Schristos         ObjDesc->Region.Address, ObjDesc->Region.Length, Node);
4957efa3256Schristos 
49628c506b8Sjruoho     /* Now the address and length are valid for this opregion */
49728c506b8Sjruoho 
49828c506b8Sjruoho     ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
49928c506b8Sjruoho     return_ACPI_STATUS (Status);
50028c506b8Sjruoho }
50128c506b8Sjruoho 
50228c506b8Sjruoho 
50328c506b8Sjruoho /*******************************************************************************
50428c506b8Sjruoho  *
50528c506b8Sjruoho  * FUNCTION:    AcpiDsEvalTableRegionOperands
50628c506b8Sjruoho  *
50728c506b8Sjruoho  * PARAMETERS:  WalkState       - Current walk
50828c506b8Sjruoho  *              Op              - A valid region Op object
50928c506b8Sjruoho  *
51028c506b8Sjruoho  * RETURN:      Status
51128c506b8Sjruoho  *
512159c4e26Sjruoho  * DESCRIPTION: Get region address and length.
513159c4e26Sjruoho  *              Called from AcpiDsExecEndOp during DataTableRegion parse
514159c4e26Sjruoho  *              tree walk.
51528c506b8Sjruoho  *
51628c506b8Sjruoho  ******************************************************************************/
51728c506b8Sjruoho 
51828c506b8Sjruoho ACPI_STATUS
AcpiDsEvalTableRegionOperands(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * Op)51928c506b8Sjruoho AcpiDsEvalTableRegionOperands (
52028c506b8Sjruoho     ACPI_WALK_STATE         *WalkState,
52128c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op)
52228c506b8Sjruoho {
52328c506b8Sjruoho     ACPI_STATUS             Status;
52428c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ObjDesc;
52528c506b8Sjruoho     ACPI_OPERAND_OBJECT     **Operand;
52628c506b8Sjruoho     ACPI_NAMESPACE_NODE     *Node;
52728c506b8Sjruoho     ACPI_PARSE_OBJECT       *NextOp;
52828c506b8Sjruoho     ACPI_TABLE_HEADER       *Table;
52981bd9c9cSchristos     UINT32                  TableIndex;
53028c506b8Sjruoho 
53128c506b8Sjruoho 
53228c506b8Sjruoho     ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op);
53328c506b8Sjruoho 
53428c506b8Sjruoho 
53528c506b8Sjruoho     /*
536a2c051a9Schristos      * This is where we evaluate the Signature string, OemId string,
537a2c051a9Schristos      * and OemTableId string of the Data Table Region declaration
53828c506b8Sjruoho      */
53928c506b8Sjruoho     Node =  Op->Common.Node;
54028c506b8Sjruoho 
541a2c051a9Schristos     /* NextOp points to Signature string op */
54228c506b8Sjruoho 
54328c506b8Sjruoho     NextOp = Op->Common.Value.Arg;
54428c506b8Sjruoho 
54528c506b8Sjruoho     /*
546a2c051a9Schristos      * Evaluate/create the Signature string, OemId string,
547a2c051a9Schristos      * and OemTableId string operands
54828c506b8Sjruoho      */
54928c506b8Sjruoho     Status = AcpiDsCreateOperands (WalkState, NextOp);
55028c506b8Sjruoho     if (ACPI_FAILURE (Status))
55128c506b8Sjruoho     {
55228c506b8Sjruoho         return_ACPI_STATUS (Status);
55328c506b8Sjruoho     }
55428c506b8Sjruoho 
55581bd9c9cSchristos     Operand = &WalkState->Operands[0];
55681bd9c9cSchristos 
55728c506b8Sjruoho     /*
558a2c051a9Schristos      * Resolve the Signature string, OemId string,
559a2c051a9Schristos      * and OemTableId string operands
56028c506b8Sjruoho      */
56181bd9c9cSchristos     Status = AcpiExResolveOperands (
56281bd9c9cSchristos         Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
56328c506b8Sjruoho     if (ACPI_FAILURE (Status))
56428c506b8Sjruoho     {
56581bd9c9cSchristos         goto Cleanup;
56628c506b8Sjruoho     }
56728c506b8Sjruoho 
56828c506b8Sjruoho     /* Find the ACPI table */
56928c506b8Sjruoho 
57081bd9c9cSchristos     Status = AcpiTbFindTable (
57181bd9c9cSchristos         Operand[0]->String.Pointer,
57281bd9c9cSchristos         Operand[1]->String.Pointer,
57381bd9c9cSchristos         Operand[2]->String.Pointer, &TableIndex);
57428c506b8Sjruoho     if (ACPI_FAILURE (Status))
57528c506b8Sjruoho     {
57681bd9c9cSchristos         if (Status == AE_NOT_FOUND)
57781bd9c9cSchristos         {
57881bd9c9cSchristos             ACPI_ERROR ((AE_INFO,
57981bd9c9cSchristos                 "ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT",
58081bd9c9cSchristos                 Operand[0]->String.Pointer,
58181bd9c9cSchristos                 Operand[1]->String.Pointer,
58281bd9c9cSchristos                 Operand[2]->String.Pointer));
58328c506b8Sjruoho         }
58481bd9c9cSchristos         goto Cleanup;
58581bd9c9cSchristos     }
58628c506b8Sjruoho 
58728c506b8Sjruoho     Status = AcpiGetTableByIndex (TableIndex, &Table);
58828c506b8Sjruoho     if (ACPI_FAILURE (Status))
58928c506b8Sjruoho     {
59081bd9c9cSchristos         goto Cleanup;
59128c506b8Sjruoho     }
59228c506b8Sjruoho 
59328c506b8Sjruoho     ObjDesc = AcpiNsGetAttachedObject (Node);
59428c506b8Sjruoho     if (!ObjDesc)
59528c506b8Sjruoho     {
59681bd9c9cSchristos         Status = AE_NOT_EXIST;
59781bd9c9cSchristos         goto Cleanup;
59828c506b8Sjruoho     }
59928c506b8Sjruoho 
600cb2bd8f0Schristos     ObjDesc->Region.Address = ACPI_PTR_TO_PHYSADDR (Table);
60128c506b8Sjruoho     ObjDesc->Region.Length = Table->Length;
602a43dcd2aSchristos     ObjDesc->Region.Pointer = Table;
60328c506b8Sjruoho 
60428c506b8Sjruoho     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
60581bd9c9cSchristos         ObjDesc, ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
60628c506b8Sjruoho         ObjDesc->Region.Length));
60728c506b8Sjruoho 
60828c506b8Sjruoho     /* Now the address and length are valid for this opregion */
60928c506b8Sjruoho 
61028c506b8Sjruoho     ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
61128c506b8Sjruoho 
61281bd9c9cSchristos Cleanup:
61381bd9c9cSchristos     AcpiUtRemoveReference (Operand[0]);
61481bd9c9cSchristos     AcpiUtRemoveReference (Operand[1]);
61581bd9c9cSchristos     AcpiUtRemoveReference (Operand[2]);
61681bd9c9cSchristos 
61728c506b8Sjruoho     return_ACPI_STATUS (Status);
61828c506b8Sjruoho }
61928c506b8Sjruoho 
62028c506b8Sjruoho 
62128c506b8Sjruoho /*******************************************************************************
62228c506b8Sjruoho  *
62328c506b8Sjruoho  * FUNCTION:    AcpiDsEvalDataObjectOperands
62428c506b8Sjruoho  *
62528c506b8Sjruoho  * PARAMETERS:  WalkState       - Current walk
62628c506b8Sjruoho  *              Op              - A valid DataObject Op object
62728c506b8Sjruoho  *              ObjDesc         - DataObject
62828c506b8Sjruoho  *
62928c506b8Sjruoho  * RETURN:      Status
63028c506b8Sjruoho  *
63128c506b8Sjruoho  * DESCRIPTION: Get the operands and complete the following data object types:
63228c506b8Sjruoho  *              Buffer, Package.
63328c506b8Sjruoho  *
63428c506b8Sjruoho  ******************************************************************************/
63528c506b8Sjruoho 
63628c506b8Sjruoho ACPI_STATUS
AcpiDsEvalDataObjectOperands(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * Op,ACPI_OPERAND_OBJECT * ObjDesc)63728c506b8Sjruoho AcpiDsEvalDataObjectOperands (
63828c506b8Sjruoho     ACPI_WALK_STATE         *WalkState,
63928c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
64028c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ObjDesc)
64128c506b8Sjruoho {
64228c506b8Sjruoho     ACPI_STATUS             Status;
64328c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ArgDesc;
64428c506b8Sjruoho     UINT32                  Length;
64528c506b8Sjruoho 
64628c506b8Sjruoho 
64728c506b8Sjruoho     ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands);
64828c506b8Sjruoho 
64928c506b8Sjruoho 
65028c506b8Sjruoho     /* The first operand (for all of these data objects) is the length */
65128c506b8Sjruoho 
65228c506b8Sjruoho     /*
65328c506b8Sjruoho      * Set proper index into operand stack for AcpiDsObjStackPush
65428c506b8Sjruoho      * invoked inside AcpiDsCreateOperand.
65528c506b8Sjruoho      */
65628c506b8Sjruoho     WalkState->OperandIndex = WalkState->NumOperands;
65728c506b8Sjruoho 
658ae01dbf5Schristos     /* Ignore if child is not valid */
659ae01dbf5Schristos 
660ae01dbf5Schristos     if (!Op->Common.Value.Arg)
661ae01dbf5Schristos     {
662ae01dbf5Schristos         ACPI_ERROR ((AE_INFO,
663f45f09e8Schristos             "Missing child while evaluating opcode %4.4X, Op %p",
664f45f09e8Schristos             Op->Common.AmlOpcode, Op));
665ae01dbf5Schristos         return_ACPI_STATUS (AE_OK);
666ae01dbf5Schristos     }
667ae01dbf5Schristos 
66828c506b8Sjruoho     Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
66928c506b8Sjruoho     if (ACPI_FAILURE (Status))
67028c506b8Sjruoho     {
67128c506b8Sjruoho         return_ACPI_STATUS (Status);
67228c506b8Sjruoho     }
67328c506b8Sjruoho 
67428c506b8Sjruoho     Status = AcpiExResolveOperands (WalkState->Opcode,
67528c506b8Sjruoho         &(WalkState->Operands [WalkState->NumOperands -1]),
67628c506b8Sjruoho         WalkState);
67728c506b8Sjruoho     if (ACPI_FAILURE (Status))
67828c506b8Sjruoho     {
67928c506b8Sjruoho         return_ACPI_STATUS (Status);
68028c506b8Sjruoho     }
68128c506b8Sjruoho 
68228c506b8Sjruoho     /* Extract length operand */
68328c506b8Sjruoho 
68428c506b8Sjruoho     ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
68528c506b8Sjruoho     Length = (UINT32) ArgDesc->Integer.Value;
68628c506b8Sjruoho 
68728c506b8Sjruoho     /* Cleanup for length operand */
68828c506b8Sjruoho 
68928c506b8Sjruoho     Status = AcpiDsObjStackPop (1, WalkState);
69028c506b8Sjruoho     if (ACPI_FAILURE (Status))
69128c506b8Sjruoho     {
69228c506b8Sjruoho         return_ACPI_STATUS (Status);
69328c506b8Sjruoho     }
69428c506b8Sjruoho 
69528c506b8Sjruoho     AcpiUtRemoveReference (ArgDesc);
69628c506b8Sjruoho 
69728c506b8Sjruoho     /*
69828c506b8Sjruoho      * Create the actual data object
69928c506b8Sjruoho      */
70028c506b8Sjruoho     switch (Op->Common.AmlOpcode)
70128c506b8Sjruoho     {
70228c506b8Sjruoho     case AML_BUFFER_OP:
70328c506b8Sjruoho 
70481bd9c9cSchristos         Status = AcpiDsBuildInternalBufferObj (
70581bd9c9cSchristos             WalkState, Op, Length, &ObjDesc);
70628c506b8Sjruoho         break;
70728c506b8Sjruoho 
70828c506b8Sjruoho     case AML_PACKAGE_OP:
7098f1e17bdSchristos     case AML_VARIABLE_PACKAGE_OP:
71028c506b8Sjruoho 
71181bd9c9cSchristos         Status = AcpiDsBuildInternalPackageObj (
71281bd9c9cSchristos             WalkState, Op, Length, &ObjDesc);
71328c506b8Sjruoho         break;
71428c506b8Sjruoho 
71528c506b8Sjruoho     default:
716a2c051a9Schristos 
71728c506b8Sjruoho         return_ACPI_STATUS (AE_AML_BAD_OPCODE);
71828c506b8Sjruoho     }
71928c506b8Sjruoho 
72028c506b8Sjruoho     if (ACPI_SUCCESS (Status))
72128c506b8Sjruoho     {
72228c506b8Sjruoho         /*
72328c506b8Sjruoho          * Return the object in the WalkState, unless the parent is a package -
72428c506b8Sjruoho          * in this case, the return object will be stored in the parse tree
72528c506b8Sjruoho          * for the package.
72628c506b8Sjruoho          */
72728c506b8Sjruoho         if ((!Op->Common.Parent) ||
72828c506b8Sjruoho             ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
7298f1e17bdSchristos              (Op->Common.Parent->Common.AmlOpcode != AML_VARIABLE_PACKAGE_OP) &&
73028c506b8Sjruoho              (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
73128c506b8Sjruoho         {
73228c506b8Sjruoho             WalkState->ResultObj = ObjDesc;
73328c506b8Sjruoho         }
73428c506b8Sjruoho     }
73528c506b8Sjruoho 
73628c506b8Sjruoho     return_ACPI_STATUS (Status);
73728c506b8Sjruoho }
73828c506b8Sjruoho 
73928c506b8Sjruoho 
74028c506b8Sjruoho /*******************************************************************************
74128c506b8Sjruoho  *
74228c506b8Sjruoho  * FUNCTION:    AcpiDsEvalBankFieldOperands
74328c506b8Sjruoho  *
74428c506b8Sjruoho  * PARAMETERS:  WalkState       - Current walk
74528c506b8Sjruoho  *              Op              - A valid BankField Op object
74628c506b8Sjruoho  *
74728c506b8Sjruoho  * RETURN:      Status
74828c506b8Sjruoho  *
74928c506b8Sjruoho  * DESCRIPTION: Get BankField BankValue
75028c506b8Sjruoho  *              Called from AcpiDsExecEndOp during BankField parse tree walk
75128c506b8Sjruoho  *
75228c506b8Sjruoho  ******************************************************************************/
75328c506b8Sjruoho 
75428c506b8Sjruoho ACPI_STATUS
AcpiDsEvalBankFieldOperands(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * Op)75528c506b8Sjruoho AcpiDsEvalBankFieldOperands (
75628c506b8Sjruoho     ACPI_WALK_STATE         *WalkState,
75728c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op)
75828c506b8Sjruoho {
75928c506b8Sjruoho     ACPI_STATUS             Status;
76028c506b8Sjruoho     ACPI_OPERAND_OBJECT     *ObjDesc;
76128c506b8Sjruoho     ACPI_OPERAND_OBJECT     *OperandDesc;
76228c506b8Sjruoho     ACPI_NAMESPACE_NODE     *Node;
76328c506b8Sjruoho     ACPI_PARSE_OBJECT       *NextOp;
76428c506b8Sjruoho     ACPI_PARSE_OBJECT       *Arg;
76528c506b8Sjruoho 
76628c506b8Sjruoho 
76728c506b8Sjruoho     ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands, Op);
76828c506b8Sjruoho 
76928c506b8Sjruoho 
77028c506b8Sjruoho     /*
77128c506b8Sjruoho      * This is where we evaluate the BankValue field of the
77228c506b8Sjruoho      * BankField declaration
77328c506b8Sjruoho      */
77428c506b8Sjruoho 
77528c506b8Sjruoho     /* NextOp points to the op that holds the Region */
77628c506b8Sjruoho 
77728c506b8Sjruoho     NextOp = Op->Common.Value.Arg;
77828c506b8Sjruoho 
77928c506b8Sjruoho     /* NextOp points to the op that holds the Bank Register */
78028c506b8Sjruoho 
78128c506b8Sjruoho     NextOp = NextOp->Common.Next;
78228c506b8Sjruoho 
78328c506b8Sjruoho     /* NextOp points to the op that holds the Bank Value */
78428c506b8Sjruoho 
78528c506b8Sjruoho     NextOp = NextOp->Common.Next;
78628c506b8Sjruoho 
78728c506b8Sjruoho     /*
78828c506b8Sjruoho      * Set proper index into operand stack for AcpiDsObjStackPush
78928c506b8Sjruoho      * invoked inside AcpiDsCreateOperand.
79028c506b8Sjruoho      *
79128c506b8Sjruoho      * We use WalkState->Operands[0] to store the evaluated BankValue
79228c506b8Sjruoho      */
79328c506b8Sjruoho     WalkState->OperandIndex = 0;
79428c506b8Sjruoho 
79528c506b8Sjruoho     Status = AcpiDsCreateOperand (WalkState, NextOp, 0);
79628c506b8Sjruoho     if (ACPI_FAILURE (Status))
79728c506b8Sjruoho     {
79828c506b8Sjruoho         return_ACPI_STATUS (Status);
79928c506b8Sjruoho     }
80028c506b8Sjruoho 
80128c506b8Sjruoho     Status = AcpiExResolveToValue (&WalkState->Operands[0], WalkState);
80228c506b8Sjruoho     if (ACPI_FAILURE (Status))
80328c506b8Sjruoho     {
80428c506b8Sjruoho         return_ACPI_STATUS (Status);
80528c506b8Sjruoho     }
80628c506b8Sjruoho 
80728c506b8Sjruoho     ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS,
80828c506b8Sjruoho         AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 1);
80928c506b8Sjruoho     /*
81028c506b8Sjruoho      * Get the BankValue operand and save it
81128c506b8Sjruoho      * (at Top of stack)
81228c506b8Sjruoho      */
81328c506b8Sjruoho     OperandDesc = WalkState->Operands[0];
81428c506b8Sjruoho 
81528c506b8Sjruoho     /* Arg points to the start Bank Field */
81628c506b8Sjruoho 
81728c506b8Sjruoho     Arg = AcpiPsGetArg (Op, 4);
81828c506b8Sjruoho     while (Arg)
81928c506b8Sjruoho     {
82028c506b8Sjruoho         /* Ignore OFFSET and ACCESSAS terms here */
82128c506b8Sjruoho 
82228c506b8Sjruoho         if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
82328c506b8Sjruoho         {
82428c506b8Sjruoho             Node = Arg->Common.Node;
82528c506b8Sjruoho 
82628c506b8Sjruoho             ObjDesc = AcpiNsGetAttachedObject (Node);
82728c506b8Sjruoho             if (!ObjDesc)
82828c506b8Sjruoho             {
82928c506b8Sjruoho                 return_ACPI_STATUS (AE_NOT_EXIST);
83028c506b8Sjruoho             }
83128c506b8Sjruoho 
83228c506b8Sjruoho             ObjDesc->BankField.Value = (UINT32) OperandDesc->Integer.Value;
83328c506b8Sjruoho         }
83428c506b8Sjruoho 
83528c506b8Sjruoho         /* Move to next field in the list */
83628c506b8Sjruoho 
83728c506b8Sjruoho         Arg = Arg->Common.Next;
83828c506b8Sjruoho     }
83928c506b8Sjruoho 
84028c506b8Sjruoho     AcpiUtRemoveReference (OperandDesc);
84128c506b8Sjruoho     return_ACPI_STATUS (Status);
84228c506b8Sjruoho }
843