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