123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817 |
- /******************************************************************************
- *
- * Module Name: dsopcode - Dispatcher support for regions and fields
- *
- *****************************************************************************/
- /*
- * Copyright (C) 2000 - 2015, Intel Corp.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- * substantially similar to the "NO WARRANTY" disclaimer below
- * ("Disclaimer") and any redistribution must be conditioned upon
- * including a substantially similar Disclaimer requirement for further
- * binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- * of any contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGES.
- */
- #include "acpi.h"
- #include "accommon.h"
- #include "acparser.h"
- #include "amlcode.h"
- #include "acdispat.h"
- #include "acinterp.h"
- #include "acnamesp.h"
- #include "acevents.h"
- #include "actables.h"
- #define _COMPONENT ACPI_DISPATCHER
- ACPI_MODULE_NAME ("dsopcode")
- /* Local prototypes */
- 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);
- /*******************************************************************************
- *
- * FUNCTION: AcpiDsInitializeRegion
- *
- * PARAMETERS: ObjHandle - Region namespace node
- *
- * RETURN: Status
- *
- * DESCRIPTION: Front end to EvInitializeRegion
- *
- ******************************************************************************/
- ACPI_STATUS
- AcpiDsInitializeRegion (
- ACPI_HANDLE ObjHandle)
- {
- ACPI_OPERAND_OBJECT *ObjDesc;
- ACPI_STATUS Status;
- ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
- /* Namespace is NOT locked */
- Status = AcpiEvInitializeRegion (ObjDesc, FALSE);
- return (Status);
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDsInitBufferField
- *
- * PARAMETERS: AmlOpcode - CreateXxxField
- * ObjDesc - BufferField object
- * BufferDesc - Host Buffer
- * OffsetDesc - Offset into buffer
- * LengthDesc - Length of field (CREATE_FIELD_OP only)
- * ResultDesc - Where to store the result
- *
- * RETURN: Status
- *
- * DESCRIPTION: Perform actual initialization of a buffer field
- *
- ******************************************************************************/
- 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)
- {
- UINT32 Offset;
- UINT32 BitOffset;
- UINT32 BitCount;
- UINT8 FieldFlags;
- ACPI_STATUS Status;
- ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc);
- /* Host object must be a Buffer */
- if (BufferDesc->Common.Type != ACPI_TYPE_BUFFER)
- {
- ACPI_ERROR ((AE_INFO,
- "Target of Create Field is not a Buffer object - %s",
- AcpiUtGetObjectTypeName (BufferDesc)));
- Status = AE_AML_OPERAND_TYPE;
- goto Cleanup;
- }
- /*
- * The last parameter to all of these opcodes (ResultDesc) started
- * out as a NameString, and should therefore now be a NS node
- * after resolution in AcpiExResolveOperands().
- */
- if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
- {
- ACPI_ERROR ((AE_INFO,
- "(%s) destination not a NS Node [%s]",
- AcpiPsGetOpcodeName (AmlOpcode),
- AcpiUtGetDescriptorName (ResultDesc)));
- Status = AE_AML_OPERAND_TYPE;
- goto Cleanup;
- }
- Offset = (UINT32) OffsetDesc->Integer.Value;
- /*
- * Setup the Bit offsets and counts, according to the opcode
- */
- switch (AmlOpcode)
- {
- case AML_CREATE_FIELD_OP:
- /* Offset is in bits, count is in bits */
- FieldFlags = AML_FIELD_ACCESS_BYTE;
- BitOffset = Offset;
- BitCount = (UINT32) LengthDesc->Integer.Value;
- /* Must have a valid (>0) bit count */
- if (BitCount == 0)
- {
- ACPI_ERROR ((AE_INFO,
- "Attempt to CreateField of length zero"));
- Status = AE_AML_OPERAND_VALUE;
- goto Cleanup;
- }
- break;
- case AML_CREATE_BIT_FIELD_OP:
- /* Offset is in bits, Field is one bit */
- BitOffset = Offset;
- BitCount = 1;
- FieldFlags = AML_FIELD_ACCESS_BYTE;
- break;
- case AML_CREATE_BYTE_FIELD_OP:
- /* Offset is in bytes, field is one byte */
- BitOffset = 8 * Offset;
- BitCount = 8;
- FieldFlags = AML_FIELD_ACCESS_BYTE;
- break;
- case AML_CREATE_WORD_FIELD_OP:
- /* Offset is in bytes, field is one word */
- BitOffset = 8 * Offset;
- BitCount = 16;
- FieldFlags = AML_FIELD_ACCESS_WORD;
- break;
- case AML_CREATE_DWORD_FIELD_OP:
- /* Offset is in bytes, field is one dword */
- BitOffset = 8 * Offset;
- BitCount = 32;
- FieldFlags = AML_FIELD_ACCESS_DWORD;
- break;
- case AML_CREATE_QWORD_FIELD_OP:
- /* Offset is in bytes, field is one qword */
- BitOffset = 8 * Offset;
- BitCount = 64;
- FieldFlags = AML_FIELD_ACCESS_QWORD;
- break;
- default:
- ACPI_ERROR ((AE_INFO,
- "Unknown field creation opcode 0x%02X",
- AmlOpcode));
- Status = AE_AML_BAD_OPCODE;
- goto Cleanup;
- }
- /* Entire field must fit within the current length of the buffer */
- if ((BitOffset + BitCount) >
- (8 * (UINT32) BufferDesc->Buffer.Length))
- {
- ACPI_ERROR ((AE_INFO,
- "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
- AcpiUtGetNodeName (ResultDesc),
- BitOffset + BitCount,
- AcpiUtGetNodeName (BufferDesc->Buffer.Node),
- 8 * (UINT32) BufferDesc->Buffer.Length));
- Status = AE_AML_BUFFER_LIMIT;
- goto Cleanup;
- }
- /*
- * Initialize areas of the field object that are common to all fields
- * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
- * UPDATE_RULE = 0 (UPDATE_PRESERVE)
- */
- Status = AcpiExPrepCommonFieldObject (
- ObjDesc, FieldFlags, 0, BitOffset, BitCount);
- if (ACPI_FAILURE (Status))
- {
- goto Cleanup;
- }
- ObjDesc->BufferField.BufferObj = BufferDesc;
- /* Reference count for BufferDesc inherits ObjDesc count */
- BufferDesc->Common.ReferenceCount = (UINT16)
- (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);
- Cleanup:
- /* Always delete the operands */
- AcpiUtRemoveReference (OffsetDesc);
- AcpiUtRemoveReference (BufferDesc);
- if (AmlOpcode == AML_CREATE_FIELD_OP)
- {
- AcpiUtRemoveReference (LengthDesc);
- }
- /* On failure, delete the result descriptor */
- if (ACPI_FAILURE (Status))
- {
- AcpiUtRemoveReference (ResultDesc); /* Result descriptor */
- }
- else
- {
- /* Now the address and length are valid for this BufferField */
- ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
- }
- return_ACPI_STATUS (Status);
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDsEvalBufferFieldOperands
- *
- * PARAMETERS: WalkState - Current walk
- * Op - A valid BufferField Op object
- *
- * RETURN: Status
- *
- * DESCRIPTION: Get BufferField Buffer and Index
- * Called from AcpiDsExecEndOp during BufferField parse tree walk
- *
- ******************************************************************************/
- ACPI_STATUS
- AcpiDsEvalBufferFieldOperands (
- ACPI_WALK_STATE *WalkState,
- ACPI_PARSE_OBJECT *Op)
- {
- ACPI_STATUS Status;
- ACPI_OPERAND_OBJECT *ObjDesc;
- ACPI_NAMESPACE_NODE *Node;
- ACPI_PARSE_OBJECT *NextOp;
- ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op);
- /*
- * This is where we evaluate the address and length fields of the
- * CreateXxxField declaration
- */
- Node = Op->Common.Node;
- /* NextOp points to the op that holds the Buffer */
- NextOp = Op->Common.Value.Arg;
- /* Evaluate/create the address and length operands */
- Status = AcpiDsCreateOperands (WalkState, NextOp);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
- ObjDesc = AcpiNsGetAttachedObject (Node);
- if (!ObjDesc)
- {
- return_ACPI_STATUS (AE_NOT_EXIST);
- }
- /* Resolve the operands */
- Status = AcpiExResolveOperands (
- Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
- if (ACPI_FAILURE (Status))
- {
- ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
- AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
- return_ACPI_STATUS (Status);
- }
- /* Initialize the Buffer Field */
- if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
- {
- /* NOTE: Slightly different operands for this opcode */
- Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
- WalkState->Operands[0], WalkState->Operands[1],
- WalkState->Operands[2], WalkState->Operands[3]);
- }
- else
- {
- /* All other, CreateXxxField opcodes */
- Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
- WalkState->Operands[0], WalkState->Operands[1],
- NULL, WalkState->Operands[2]);
- }
- return_ACPI_STATUS (Status);
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDsEvalRegionOperands
- *
- * PARAMETERS: WalkState - Current walk
- * Op - A valid region Op object
- *
- * RETURN: Status
- *
- * DESCRIPTION: Get region address and length
- * Called from AcpiDsExecEndOp during OpRegion parse tree walk
- *
- ******************************************************************************/
- ACPI_STATUS
- AcpiDsEvalRegionOperands (
- ACPI_WALK_STATE *WalkState,
- ACPI_PARSE_OBJECT *Op)
- {
- ACPI_STATUS Status;
- ACPI_OPERAND_OBJECT *ObjDesc;
- ACPI_OPERAND_OBJECT *OperandDesc;
- ACPI_NAMESPACE_NODE *Node;
- ACPI_PARSE_OBJECT *NextOp;
- ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op);
- /*
- * This is where we evaluate the address and length fields of the
- * OpRegion declaration
- */
- Node = Op->Common.Node;
- /* NextOp points to the op that holds the SpaceID */
- NextOp = Op->Common.Value.Arg;
- /* NextOp points to address op */
- NextOp = NextOp->Common.Next;
- /* Evaluate/create the address and length operands */
- Status = AcpiDsCreateOperands (WalkState, NextOp);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
- /* Resolve the length and address operands to numbers */
- Status = AcpiExResolveOperands (
- Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
- ObjDesc = AcpiNsGetAttachedObject (Node);
- if (!ObjDesc)
- {
- return_ACPI_STATUS (AE_NOT_EXIST);
- }
- /*
- * Get the length operand and save it
- * (at Top of stack)
- */
- OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
- ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
- AcpiUtRemoveReference (OperandDesc);
- /*
- * Get the address and save it
- * (at top of stack - 1)
- */
- OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
- ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS)
- OperandDesc->Integer.Value;
- AcpiUtRemoveReference (OperandDesc);
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
- ObjDesc, ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
- ObjDesc->Region.Length));
- /* Now the address and length are valid for this opregion */
- ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
- return_ACPI_STATUS (Status);
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDsEvalTableRegionOperands
- *
- * PARAMETERS: WalkState - Current walk
- * Op - A valid region Op object
- *
- * RETURN: Status
- *
- * DESCRIPTION: Get region address and length.
- * Called from AcpiDsExecEndOp during DataTableRegion parse
- * tree walk.
- *
- ******************************************************************************/
- ACPI_STATUS
- AcpiDsEvalTableRegionOperands (
- ACPI_WALK_STATE *WalkState,
- ACPI_PARSE_OBJECT *Op)
- {
- ACPI_STATUS Status;
- ACPI_OPERAND_OBJECT *ObjDesc;
- ACPI_OPERAND_OBJECT **Operand;
- ACPI_NAMESPACE_NODE *Node;
- ACPI_PARSE_OBJECT *NextOp;
- ACPI_TABLE_HEADER *Table;
- UINT32 TableIndex;
- ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op);
- /*
- * This is where we evaluate the Signature string, OemId string,
- * and OemTableId string of the Data Table Region declaration
- */
- Node = Op->Common.Node;
- /* NextOp points to Signature string op */
- NextOp = Op->Common.Value.Arg;
- /*
- * Evaluate/create the Signature string, OemId string,
- * and OemTableId string operands
- */
- Status = AcpiDsCreateOperands (WalkState, NextOp);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
- Operand = &WalkState->Operands[0];
- /*
- * Resolve the Signature string, OemId string,
- * and OemTableId string operands
- */
- Status = AcpiExResolveOperands (
- Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
- if (ACPI_FAILURE (Status))
- {
- goto Cleanup;
- }
- /* Find the ACPI table */
- Status = AcpiTbFindTable (
- Operand[0]->String.Pointer,
- Operand[1]->String.Pointer,
- Operand[2]->String.Pointer, &TableIndex);
- if (ACPI_FAILURE (Status))
- {
- if (Status == AE_NOT_FOUND)
- {
- ACPI_ERROR ((AE_INFO,
- "ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT",
- Operand[0]->String.Pointer,
- Operand[1]->String.Pointer,
- Operand[2]->String.Pointer));
- }
- goto Cleanup;
- }
- Status = AcpiGetTableByIndex (TableIndex, &Table);
- if (ACPI_FAILURE (Status))
- {
- goto Cleanup;
- }
- ObjDesc = AcpiNsGetAttachedObject (Node);
- if (!ObjDesc)
- {
- Status = AE_NOT_EXIST;
- goto Cleanup;
- }
- ObjDesc->Region.Address = ACPI_PTR_TO_PHYSADDR (Table);
- ObjDesc->Region.Length = Table->Length;
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
- ObjDesc, ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
- ObjDesc->Region.Length));
- /* Now the address and length are valid for this opregion */
- ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
- Cleanup:
- AcpiUtRemoveReference (Operand[0]);
- AcpiUtRemoveReference (Operand[1]);
- AcpiUtRemoveReference (Operand[2]);
- return_ACPI_STATUS (Status);
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDsEvalDataObjectOperands
- *
- * PARAMETERS: WalkState - Current walk
- * Op - A valid DataObject Op object
- * ObjDesc - DataObject
- *
- * RETURN: Status
- *
- * DESCRIPTION: Get the operands and complete the following data object types:
- * Buffer, Package.
- *
- ******************************************************************************/
- ACPI_STATUS
- AcpiDsEvalDataObjectOperands (
- ACPI_WALK_STATE *WalkState,
- ACPI_PARSE_OBJECT *Op,
- ACPI_OPERAND_OBJECT *ObjDesc)
- {
- ACPI_STATUS Status;
- ACPI_OPERAND_OBJECT *ArgDesc;
- UINT32 Length;
- ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands);
- /* The first operand (for all of these data objects) is the length */
- /*
- * Set proper index into operand stack for AcpiDsObjStackPush
- * invoked inside AcpiDsCreateOperand.
- */
- WalkState->OperandIndex = WalkState->NumOperands;
- Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
- Status = AcpiExResolveOperands (WalkState->Opcode,
- &(WalkState->Operands [WalkState->NumOperands -1]),
- WalkState);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
- /* Extract length operand */
- ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
- Length = (UINT32) ArgDesc->Integer.Value;
- /* Cleanup for length operand */
- Status = AcpiDsObjStackPop (1, WalkState);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
- AcpiUtRemoveReference (ArgDesc);
- /*
- * Create the actual data object
- */
- switch (Op->Common.AmlOpcode)
- {
- case AML_BUFFER_OP:
- Status = AcpiDsBuildInternalBufferObj (
- WalkState, Op, Length, &ObjDesc);
- break;
- case AML_PACKAGE_OP:
- case AML_VAR_PACKAGE_OP:
- Status = AcpiDsBuildInternalPackageObj (
- WalkState, Op, Length, &ObjDesc);
- break;
- default:
- return_ACPI_STATUS (AE_AML_BAD_OPCODE);
- }
- if (ACPI_SUCCESS (Status))
- {
- /*
- * Return the object in the WalkState, unless the parent is a package -
- * in this case, the return object will be stored in the parse tree
- * for the package.
- */
- if ((!Op->Common.Parent) ||
- ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
- (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) &&
- (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
- {
- WalkState->ResultObj = ObjDesc;
- }
- }
- return_ACPI_STATUS (Status);
- }
- /*******************************************************************************
- *
- * FUNCTION: AcpiDsEvalBankFieldOperands
- *
- * PARAMETERS: WalkState - Current walk
- * Op - A valid BankField Op object
- *
- * RETURN: Status
- *
- * DESCRIPTION: Get BankField BankValue
- * Called from AcpiDsExecEndOp during BankField parse tree walk
- *
- ******************************************************************************/
- ACPI_STATUS
- AcpiDsEvalBankFieldOperands (
- ACPI_WALK_STATE *WalkState,
- ACPI_PARSE_OBJECT *Op)
- {
- ACPI_STATUS Status;
- ACPI_OPERAND_OBJECT *ObjDesc;
- ACPI_OPERAND_OBJECT *OperandDesc;
- ACPI_NAMESPACE_NODE *Node;
- ACPI_PARSE_OBJECT *NextOp;
- ACPI_PARSE_OBJECT *Arg;
- ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands, Op);
- /*
- * This is where we evaluate the BankValue field of the
- * BankField declaration
- */
- /* NextOp points to the op that holds the Region */
- NextOp = Op->Common.Value.Arg;
- /* NextOp points to the op that holds the Bank Register */
- NextOp = NextOp->Common.Next;
- /* NextOp points to the op that holds the Bank Value */
- NextOp = NextOp->Common.Next;
- /*
- * Set proper index into operand stack for AcpiDsObjStackPush
- * invoked inside AcpiDsCreateOperand.
- *
- * We use WalkState->Operands[0] to store the evaluated BankValue
- */
- WalkState->OperandIndex = 0;
- Status = AcpiDsCreateOperand (WalkState, NextOp, 0);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
- Status = AcpiExResolveToValue (&WalkState->Operands[0], WalkState);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
- ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS,
- AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 1);
- /*
- * Get the BankValue operand and save it
- * (at Top of stack)
- */
- OperandDesc = WalkState->Operands[0];
- /* Arg points to the start Bank Field */
- Arg = AcpiPsGetArg (Op, 4);
- while (Arg)
- {
- /* Ignore OFFSET and ACCESSAS terms here */
- if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
- {
- Node = Arg->Common.Node;
- ObjDesc = AcpiNsGetAttachedObject (Node);
- if (!ObjDesc)
- {
- return_ACPI_STATUS (AE_NOT_EXIST);
- }
- ObjDesc->BankField.Value = (UINT32) OperandDesc->Integer.Value;
- }
- /* Move to next field in the list */
- Arg = Arg->Common.Next;
- }
- AcpiUtRemoveReference (OperandDesc);
- return_ACPI_STATUS (Status);
- }
|