1db2bae30SDana Myers /****************************************************************************** 2db2bae30SDana Myers * 3*385cc6b4SJerry Jelinek * Module Name: dsopcode - Dispatcher support for regions and fields 4db2bae30SDana Myers * 5db2bae30SDana Myers *****************************************************************************/ 6db2bae30SDana Myers 726f3cdf0SGordon Ross /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 9db2bae30SDana Myers * All rights reserved. 10db2bae30SDana Myers * 1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1326f3cdf0SGordon Ross * are met: 1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1626f3cdf0SGordon Ross * without modification. 1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2126f3cdf0SGordon Ross * binary redistribution. 2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2426f3cdf0SGordon Ross * from this software without specific prior written permission. 25db2bae30SDana Myers * 2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2826f3cdf0SGordon Ross * Software Foundation. 29db2bae30SDana Myers * 3026f3cdf0SGordon Ross * NO WARRANTY 3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4226f3cdf0SGordon Ross */ 43db2bae30SDana Myers 44db2bae30SDana Myers #include "acpi.h" 45aa2aa9a6SDana Myers #include "accommon.h" 46db2bae30SDana Myers #include "acparser.h" 47db2bae30SDana Myers #include "amlcode.h" 48db2bae30SDana Myers #include "acdispat.h" 49db2bae30SDana Myers #include "acinterp.h" 50db2bae30SDana Myers #include "acnamesp.h" 51db2bae30SDana Myers #include "acevents.h" 52db2bae30SDana Myers #include "actables.h" 53db2bae30SDana Myers 54db2bae30SDana Myers #define _COMPONENT ACPI_DISPATCHER 55db2bae30SDana Myers ACPI_MODULE_NAME ("dsopcode") 56db2bae30SDana Myers 57db2bae30SDana Myers /* Local prototypes */ 58db2bae30SDana Myers 59db2bae30SDana Myers static ACPI_STATUS 60db2bae30SDana Myers AcpiDsInitBufferField ( 61db2bae30SDana Myers UINT16 AmlOpcode, 62db2bae30SDana Myers ACPI_OPERAND_OBJECT *ObjDesc, 63db2bae30SDana Myers ACPI_OPERAND_OBJECT *BufferDesc, 64db2bae30SDana Myers ACPI_OPERAND_OBJECT *OffsetDesc, 65db2bae30SDana Myers ACPI_OPERAND_OBJECT *LengthDesc, 66db2bae30SDana Myers ACPI_OPERAND_OBJECT *ResultDesc); 67db2bae30SDana Myers 68db2bae30SDana Myers 69db2bae30SDana Myers /******************************************************************************* 70db2bae30SDana Myers * 71db2bae30SDana Myers * FUNCTION: AcpiDsInitializeRegion 72db2bae30SDana Myers * 73db2bae30SDana Myers * PARAMETERS: ObjHandle - Region namespace node 74db2bae30SDana Myers * 75db2bae30SDana Myers * RETURN: Status 76db2bae30SDana Myers * 77db2bae30SDana Myers * DESCRIPTION: Front end to EvInitializeRegion 78db2bae30SDana Myers * 79db2bae30SDana Myers ******************************************************************************/ 80db2bae30SDana Myers 81db2bae30SDana Myers ACPI_STATUS 82db2bae30SDana Myers AcpiDsInitializeRegion ( 83db2bae30SDana Myers ACPI_HANDLE ObjHandle) 84db2bae30SDana Myers { 85db2bae30SDana Myers ACPI_OPERAND_OBJECT *ObjDesc; 86db2bae30SDana Myers ACPI_STATUS Status; 87db2bae30SDana Myers 88db2bae30SDana Myers 89db2bae30SDana Myers ObjDesc = AcpiNsGetAttachedObject (ObjHandle); 90db2bae30SDana Myers 91db2bae30SDana Myers /* Namespace is NOT locked */ 92db2bae30SDana Myers 93db2bae30SDana Myers Status = AcpiEvInitializeRegion (ObjDesc, FALSE); 94db2bae30SDana Myers return (Status); 95db2bae30SDana Myers } 96db2bae30SDana Myers 97db2bae30SDana Myers 98db2bae30SDana Myers /******************************************************************************* 99db2bae30SDana Myers * 100db2bae30SDana Myers * FUNCTION: AcpiDsInitBufferField 101db2bae30SDana Myers * 102db2bae30SDana Myers * PARAMETERS: AmlOpcode - CreateXxxField 103db2bae30SDana Myers * ObjDesc - BufferField object 104db2bae30SDana Myers * BufferDesc - Host Buffer 105db2bae30SDana Myers * OffsetDesc - Offset into buffer 106db2bae30SDana Myers * LengthDesc - Length of field (CREATE_FIELD_OP only) 107db2bae30SDana Myers * ResultDesc - Where to store the result 108db2bae30SDana Myers * 109db2bae30SDana Myers * RETURN: Status 110db2bae30SDana Myers * 111db2bae30SDana Myers * DESCRIPTION: Perform actual initialization of a buffer field 112db2bae30SDana Myers * 113db2bae30SDana Myers ******************************************************************************/ 114db2bae30SDana Myers 115db2bae30SDana Myers static ACPI_STATUS 116db2bae30SDana Myers AcpiDsInitBufferField ( 117db2bae30SDana Myers UINT16 AmlOpcode, 118db2bae30SDana Myers ACPI_OPERAND_OBJECT *ObjDesc, 119db2bae30SDana Myers ACPI_OPERAND_OBJECT *BufferDesc, 120db2bae30SDana Myers ACPI_OPERAND_OBJECT *OffsetDesc, 121db2bae30SDana Myers ACPI_OPERAND_OBJECT *LengthDesc, 122db2bae30SDana Myers ACPI_OPERAND_OBJECT *ResultDesc) 123db2bae30SDana Myers { 124db2bae30SDana Myers UINT32 Offset; 125db2bae30SDana Myers UINT32 BitOffset; 126db2bae30SDana Myers UINT32 BitCount; 127db2bae30SDana Myers UINT8 FieldFlags; 128db2bae30SDana Myers ACPI_STATUS Status; 129db2bae30SDana Myers 130db2bae30SDana Myers 131db2bae30SDana Myers ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc); 132db2bae30SDana Myers 133db2bae30SDana Myers 134db2bae30SDana Myers /* Host object must be a Buffer */ 135db2bae30SDana Myers 136aa2aa9a6SDana Myers if (BufferDesc->Common.Type != ACPI_TYPE_BUFFER) 137db2bae30SDana Myers { 138db2bae30SDana Myers ACPI_ERROR ((AE_INFO, 139db2bae30SDana Myers "Target of Create Field is not a Buffer object - %s", 140db2bae30SDana Myers AcpiUtGetObjectTypeName (BufferDesc))); 141db2bae30SDana Myers 142db2bae30SDana Myers Status = AE_AML_OPERAND_TYPE; 143db2bae30SDana Myers goto Cleanup; 144db2bae30SDana Myers } 145db2bae30SDana Myers 146db2bae30SDana Myers /* 147db2bae30SDana Myers * The last parameter to all of these opcodes (ResultDesc) started 148db2bae30SDana Myers * out as a NameString, and should therefore now be a NS node 149db2bae30SDana Myers * after resolution in AcpiExResolveOperands(). 150db2bae30SDana Myers */ 151db2bae30SDana Myers if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED) 152db2bae30SDana Myers { 153db2bae30SDana Myers ACPI_ERROR ((AE_INFO, 154db2bae30SDana Myers "(%s) destination not a NS Node [%s]", 155db2bae30SDana Myers AcpiPsGetOpcodeName (AmlOpcode), 156db2bae30SDana Myers AcpiUtGetDescriptorName (ResultDesc))); 157db2bae30SDana Myers 158db2bae30SDana Myers Status = AE_AML_OPERAND_TYPE; 159db2bae30SDana Myers goto Cleanup; 160db2bae30SDana Myers } 161db2bae30SDana Myers 162db2bae30SDana Myers Offset = (UINT32) OffsetDesc->Integer.Value; 163db2bae30SDana Myers 164db2bae30SDana Myers /* 165db2bae30SDana Myers * Setup the Bit offsets and counts, according to the opcode 166db2bae30SDana Myers */ 167db2bae30SDana Myers switch (AmlOpcode) 168db2bae30SDana Myers { 169db2bae30SDana Myers case AML_CREATE_FIELD_OP: 170db2bae30SDana Myers 171db2bae30SDana Myers /* Offset is in bits, count is in bits */ 172db2bae30SDana Myers 173db2bae30SDana Myers FieldFlags = AML_FIELD_ACCESS_BYTE; 174db2bae30SDana Myers BitOffset = Offset; 175db2bae30SDana Myers BitCount = (UINT32) LengthDesc->Integer.Value; 176db2bae30SDana Myers 177db2bae30SDana Myers /* Must have a valid (>0) bit count */ 178db2bae30SDana Myers 179db2bae30SDana Myers if (BitCount == 0) 180db2bae30SDana Myers { 181db2bae30SDana Myers ACPI_ERROR ((AE_INFO, 182db2bae30SDana Myers "Attempt to CreateField of length zero")); 183db2bae30SDana Myers Status = AE_AML_OPERAND_VALUE; 184db2bae30SDana Myers goto Cleanup; 185db2bae30SDana Myers } 186db2bae30SDana Myers break; 187db2bae30SDana Myers 188db2bae30SDana Myers case AML_CREATE_BIT_FIELD_OP: 189db2bae30SDana Myers 190db2bae30SDana Myers /* Offset is in bits, Field is one bit */ 191db2bae30SDana Myers 192db2bae30SDana Myers BitOffset = Offset; 193db2bae30SDana Myers BitCount = 1; 194db2bae30SDana Myers FieldFlags = AML_FIELD_ACCESS_BYTE; 195db2bae30SDana Myers break; 196db2bae30SDana Myers 197db2bae30SDana Myers case AML_CREATE_BYTE_FIELD_OP: 198db2bae30SDana Myers 199db2bae30SDana Myers /* Offset is in bytes, field is one byte */ 200db2bae30SDana Myers 201db2bae30SDana Myers BitOffset = 8 * Offset; 202db2bae30SDana Myers BitCount = 8; 203db2bae30SDana Myers FieldFlags = AML_FIELD_ACCESS_BYTE; 204db2bae30SDana Myers break; 205db2bae30SDana Myers 206db2bae30SDana Myers case AML_CREATE_WORD_FIELD_OP: 207db2bae30SDana Myers 208db2bae30SDana Myers /* Offset is in bytes, field is one word */ 209db2bae30SDana Myers 210db2bae30SDana Myers BitOffset = 8 * Offset; 211db2bae30SDana Myers BitCount = 16; 212db2bae30SDana Myers FieldFlags = AML_FIELD_ACCESS_WORD; 213db2bae30SDana Myers break; 214db2bae30SDana Myers 215db2bae30SDana Myers case AML_CREATE_DWORD_FIELD_OP: 216db2bae30SDana Myers 217db2bae30SDana Myers /* Offset is in bytes, field is one dword */ 218db2bae30SDana Myers 219db2bae30SDana Myers BitOffset = 8 * Offset; 220db2bae30SDana Myers BitCount = 32; 221db2bae30SDana Myers FieldFlags = AML_FIELD_ACCESS_DWORD; 222db2bae30SDana Myers break; 223db2bae30SDana Myers 224db2bae30SDana Myers case AML_CREATE_QWORD_FIELD_OP: 225db2bae30SDana Myers 226db2bae30SDana Myers /* Offset is in bytes, field is one qword */ 227db2bae30SDana Myers 228db2bae30SDana Myers BitOffset = 8 * Offset; 229db2bae30SDana Myers BitCount = 64; 230db2bae30SDana Myers FieldFlags = AML_FIELD_ACCESS_QWORD; 231db2bae30SDana Myers break; 232db2bae30SDana Myers 233db2bae30SDana Myers default: 234db2bae30SDana Myers 235db2bae30SDana Myers ACPI_ERROR ((AE_INFO, 23626f3cdf0SGordon Ross "Unknown field creation opcode 0x%02X", 237db2bae30SDana Myers AmlOpcode)); 238db2bae30SDana Myers Status = AE_AML_BAD_OPCODE; 239db2bae30SDana Myers goto Cleanup; 240db2bae30SDana Myers } 241db2bae30SDana Myers 242db2bae30SDana Myers /* Entire field must fit within the current length of the buffer */ 243db2bae30SDana Myers 244db2bae30SDana Myers if ((BitOffset + BitCount) > 245db2bae30SDana Myers (8 * (UINT32) BufferDesc->Buffer.Length)) 246db2bae30SDana Myers { 247db2bae30SDana Myers ACPI_ERROR ((AE_INFO, 24826f3cdf0SGordon Ross "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)", 249db2bae30SDana Myers AcpiUtGetNodeName (ResultDesc), 250db2bae30SDana Myers BitOffset + BitCount, 251db2bae30SDana Myers AcpiUtGetNodeName (BufferDesc->Buffer.Node), 252db2bae30SDana Myers 8 * (UINT32) BufferDesc->Buffer.Length)); 253db2bae30SDana Myers Status = AE_AML_BUFFER_LIMIT; 254db2bae30SDana Myers goto Cleanup; 255db2bae30SDana Myers } 256db2bae30SDana Myers 257db2bae30SDana Myers /* 258db2bae30SDana Myers * Initialize areas of the field object that are common to all fields 259db2bae30SDana Myers * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK), 260db2bae30SDana Myers * UPDATE_RULE = 0 (UPDATE_PRESERVE) 261db2bae30SDana Myers */ 262*385cc6b4SJerry Jelinek Status = AcpiExPrepCommonFieldObject ( 263*385cc6b4SJerry Jelinek ObjDesc, FieldFlags, 0, BitOffset, BitCount); 264db2bae30SDana Myers if (ACPI_FAILURE (Status)) 265db2bae30SDana Myers { 266db2bae30SDana Myers goto Cleanup; 267db2bae30SDana Myers } 268db2bae30SDana Myers 269db2bae30SDana Myers ObjDesc->BufferField.BufferObj = BufferDesc; 270db2bae30SDana Myers 271db2bae30SDana Myers /* Reference count for BufferDesc inherits ObjDesc count */ 272db2bae30SDana Myers 273db2bae30SDana Myers BufferDesc->Common.ReferenceCount = (UINT16) 274db2bae30SDana Myers (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount); 275db2bae30SDana Myers 276db2bae30SDana Myers 277db2bae30SDana Myers Cleanup: 278db2bae30SDana Myers 279db2bae30SDana Myers /* Always delete the operands */ 280db2bae30SDana Myers 281db2bae30SDana Myers AcpiUtRemoveReference (OffsetDesc); 282db2bae30SDana Myers AcpiUtRemoveReference (BufferDesc); 283db2bae30SDana Myers 284db2bae30SDana Myers if (AmlOpcode == AML_CREATE_FIELD_OP) 285db2bae30SDana Myers { 286db2bae30SDana Myers AcpiUtRemoveReference (LengthDesc); 287db2bae30SDana Myers } 288db2bae30SDana Myers 289db2bae30SDana Myers /* On failure, delete the result descriptor */ 290db2bae30SDana Myers 291db2bae30SDana Myers if (ACPI_FAILURE (Status)) 292db2bae30SDana Myers { 293db2bae30SDana Myers AcpiUtRemoveReference (ResultDesc); /* Result descriptor */ 294db2bae30SDana Myers } 295db2bae30SDana Myers else 296db2bae30SDana Myers { 297db2bae30SDana Myers /* Now the address and length are valid for this BufferField */ 298db2bae30SDana Myers 299db2bae30SDana Myers ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID; 300db2bae30SDana Myers } 301db2bae30SDana Myers 302db2bae30SDana Myers return_ACPI_STATUS (Status); 303db2bae30SDana Myers } 304db2bae30SDana Myers 305db2bae30SDana Myers 306db2bae30SDana Myers /******************************************************************************* 307db2bae30SDana Myers * 308db2bae30SDana Myers * FUNCTION: AcpiDsEvalBufferFieldOperands 309db2bae30SDana Myers * 310db2bae30SDana Myers * PARAMETERS: WalkState - Current walk 311db2bae30SDana Myers * Op - A valid BufferField Op object 312db2bae30SDana Myers * 313db2bae30SDana Myers * RETURN: Status 314db2bae30SDana Myers * 315db2bae30SDana Myers * DESCRIPTION: Get BufferField Buffer and Index 316db2bae30SDana Myers * Called from AcpiDsExecEndOp during BufferField parse tree walk 317db2bae30SDana Myers * 318db2bae30SDana Myers ******************************************************************************/ 319db2bae30SDana Myers 320db2bae30SDana Myers ACPI_STATUS 321db2bae30SDana Myers AcpiDsEvalBufferFieldOperands ( 322db2bae30SDana Myers ACPI_WALK_STATE *WalkState, 323db2bae30SDana Myers ACPI_PARSE_OBJECT *Op) 324db2bae30SDana Myers { 325db2bae30SDana Myers ACPI_STATUS Status; 326db2bae30SDana Myers ACPI_OPERAND_OBJECT *ObjDesc; 327db2bae30SDana Myers ACPI_NAMESPACE_NODE *Node; 328db2bae30SDana Myers ACPI_PARSE_OBJECT *NextOp; 329db2bae30SDana Myers 330db2bae30SDana Myers 331db2bae30SDana Myers ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op); 332db2bae30SDana Myers 333db2bae30SDana Myers 334db2bae30SDana Myers /* 335db2bae30SDana Myers * This is where we evaluate the address and length fields of the 336db2bae30SDana Myers * CreateXxxField declaration 337db2bae30SDana Myers */ 338db2bae30SDana Myers Node = Op->Common.Node; 339db2bae30SDana Myers 340db2bae30SDana Myers /* NextOp points to the op that holds the Buffer */ 341db2bae30SDana Myers 342db2bae30SDana Myers NextOp = Op->Common.Value.Arg; 343db2bae30SDana Myers 344db2bae30SDana Myers /* Evaluate/create the address and length operands */ 345db2bae30SDana Myers 346db2bae30SDana Myers Status = AcpiDsCreateOperands (WalkState, NextOp); 347db2bae30SDana Myers if (ACPI_FAILURE (Status)) 348db2bae30SDana Myers { 349db2bae30SDana Myers return_ACPI_STATUS (Status); 350db2bae30SDana Myers } 351db2bae30SDana Myers 352db2bae30SDana Myers ObjDesc = AcpiNsGetAttachedObject (Node); 353db2bae30SDana Myers if (!ObjDesc) 354db2bae30SDana Myers { 355db2bae30SDana Myers return_ACPI_STATUS (AE_NOT_EXIST); 356db2bae30SDana Myers } 357db2bae30SDana Myers 358db2bae30SDana Myers /* Resolve the operands */ 359db2bae30SDana Myers 360*385cc6b4SJerry Jelinek Status = AcpiExResolveOperands ( 361*385cc6b4SJerry Jelinek Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState); 362db2bae30SDana Myers if (ACPI_FAILURE (Status)) 363db2bae30SDana Myers { 36426f3cdf0SGordon Ross ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X", 365db2bae30SDana Myers AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status)); 366db2bae30SDana Myers 367db2bae30SDana Myers return_ACPI_STATUS (Status); 368db2bae30SDana Myers } 369db2bae30SDana Myers 370db2bae30SDana Myers /* Initialize the Buffer Field */ 371db2bae30SDana Myers 372db2bae30SDana Myers if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP) 373db2bae30SDana Myers { 374db2bae30SDana Myers /* NOTE: Slightly different operands for this opcode */ 375db2bae30SDana Myers 376db2bae30SDana Myers Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc, 377db2bae30SDana Myers WalkState->Operands[0], WalkState->Operands[1], 378db2bae30SDana Myers WalkState->Operands[2], WalkState->Operands[3]); 379db2bae30SDana Myers } 380db2bae30SDana Myers else 381db2bae30SDana Myers { 382db2bae30SDana Myers /* All other, CreateXxxField opcodes */ 383db2bae30SDana Myers 384db2bae30SDana Myers Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc, 385db2bae30SDana Myers WalkState->Operands[0], WalkState->Operands[1], 386db2bae30SDana Myers NULL, WalkState->Operands[2]); 387db2bae30SDana Myers } 388db2bae30SDana Myers 389db2bae30SDana Myers return_ACPI_STATUS (Status); 390db2bae30SDana Myers } 391db2bae30SDana Myers 392db2bae30SDana Myers 393db2bae30SDana Myers /******************************************************************************* 394db2bae30SDana Myers * 395db2bae30SDana Myers * FUNCTION: AcpiDsEvalRegionOperands 396db2bae30SDana Myers * 397db2bae30SDana Myers * PARAMETERS: WalkState - Current walk 398db2bae30SDana Myers * Op - A valid region Op object 399db2bae30SDana Myers * 400db2bae30SDana Myers * RETURN: Status 401db2bae30SDana Myers * 402db2bae30SDana Myers * DESCRIPTION: Get region address and length 403db2bae30SDana Myers * Called from AcpiDsExecEndOp during OpRegion parse tree walk 404db2bae30SDana Myers * 405db2bae30SDana Myers ******************************************************************************/ 406db2bae30SDana Myers 407db2bae30SDana Myers ACPI_STATUS 408db2bae30SDana Myers AcpiDsEvalRegionOperands ( 409db2bae30SDana Myers ACPI_WALK_STATE *WalkState, 410db2bae30SDana Myers ACPI_PARSE_OBJECT *Op) 411db2bae30SDana Myers { 412db2bae30SDana Myers ACPI_STATUS Status; 413db2bae30SDana Myers ACPI_OPERAND_OBJECT *ObjDesc; 414db2bae30SDana Myers ACPI_OPERAND_OBJECT *OperandDesc; 415db2bae30SDana Myers ACPI_NAMESPACE_NODE *Node; 416db2bae30SDana Myers ACPI_PARSE_OBJECT *NextOp; 417db2bae30SDana Myers 418db2bae30SDana Myers 419db2bae30SDana Myers ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op); 420db2bae30SDana Myers 421db2bae30SDana Myers 422db2bae30SDana Myers /* 423db2bae30SDana Myers * This is where we evaluate the address and length fields of the 424db2bae30SDana Myers * OpRegion declaration 425db2bae30SDana Myers */ 426db2bae30SDana Myers Node = Op->Common.Node; 427db2bae30SDana Myers 428db2bae30SDana Myers /* NextOp points to the op that holds the SpaceID */ 429db2bae30SDana Myers 430db2bae30SDana Myers NextOp = Op->Common.Value.Arg; 431db2bae30SDana Myers 432db2bae30SDana Myers /* NextOp points to address op */ 433db2bae30SDana Myers 434db2bae30SDana Myers NextOp = NextOp->Common.Next; 435db2bae30SDana Myers 436db2bae30SDana Myers /* Evaluate/create the address and length operands */ 437db2bae30SDana Myers 438db2bae30SDana Myers Status = AcpiDsCreateOperands (WalkState, NextOp); 439db2bae30SDana Myers if (ACPI_FAILURE (Status)) 440db2bae30SDana Myers { 441db2bae30SDana Myers return_ACPI_STATUS (Status); 442db2bae30SDana Myers } 443db2bae30SDana Myers 444db2bae30SDana Myers /* Resolve the length and address operands to numbers */ 445db2bae30SDana Myers 446*385cc6b4SJerry Jelinek Status = AcpiExResolveOperands ( 447*385cc6b4SJerry Jelinek Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState); 448db2bae30SDana Myers if (ACPI_FAILURE (Status)) 449db2bae30SDana Myers { 450db2bae30SDana Myers return_ACPI_STATUS (Status); 451db2bae30SDana Myers } 452db2bae30SDana Myers 453db2bae30SDana Myers ObjDesc = AcpiNsGetAttachedObject (Node); 454db2bae30SDana Myers if (!ObjDesc) 455db2bae30SDana Myers { 456db2bae30SDana Myers return_ACPI_STATUS (AE_NOT_EXIST); 457db2bae30SDana Myers } 458db2bae30SDana Myers 459db2bae30SDana Myers /* 460db2bae30SDana Myers * Get the length operand and save it 461db2bae30SDana Myers * (at Top of stack) 462db2bae30SDana Myers */ 463db2bae30SDana Myers OperandDesc = WalkState->Operands[WalkState->NumOperands - 1]; 464db2bae30SDana Myers 465db2bae30SDana Myers ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value; 466db2bae30SDana Myers AcpiUtRemoveReference (OperandDesc); 467db2bae30SDana Myers 468db2bae30SDana Myers /* 469db2bae30SDana Myers * Get the address and save it 470db2bae30SDana Myers * (at top of stack - 1) 471db2bae30SDana Myers */ 472db2bae30SDana Myers OperandDesc = WalkState->Operands[WalkState->NumOperands - 2]; 473db2bae30SDana Myers 474db2bae30SDana Myers ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS) 475db2bae30SDana Myers OperandDesc->Integer.Value; 476db2bae30SDana Myers AcpiUtRemoveReference (OperandDesc); 477db2bae30SDana Myers 478db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", 479*385cc6b4SJerry Jelinek ObjDesc, ACPI_FORMAT_UINT64 (ObjDesc->Region.Address), 480db2bae30SDana Myers ObjDesc->Region.Length)); 481db2bae30SDana Myers 482db2bae30SDana Myers /* Now the address and length are valid for this opregion */ 483db2bae30SDana Myers 484db2bae30SDana Myers ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID; 485db2bae30SDana Myers return_ACPI_STATUS (Status); 486db2bae30SDana Myers } 487db2bae30SDana Myers 488db2bae30SDana Myers 489db2bae30SDana Myers /******************************************************************************* 490db2bae30SDana Myers * 491db2bae30SDana Myers * FUNCTION: AcpiDsEvalTableRegionOperands 492db2bae30SDana Myers * 493db2bae30SDana Myers * PARAMETERS: WalkState - Current walk 494db2bae30SDana Myers * Op - A valid region Op object 495db2bae30SDana Myers * 496db2bae30SDana Myers * RETURN: Status 497db2bae30SDana Myers * 49826f3cdf0SGordon Ross * DESCRIPTION: Get region address and length. 49926f3cdf0SGordon Ross * Called from AcpiDsExecEndOp during DataTableRegion parse 50026f3cdf0SGordon Ross * tree walk. 501db2bae30SDana Myers * 502db2bae30SDana Myers ******************************************************************************/ 503db2bae30SDana Myers 504db2bae30SDana Myers ACPI_STATUS 505db2bae30SDana Myers AcpiDsEvalTableRegionOperands ( 506db2bae30SDana Myers ACPI_WALK_STATE *WalkState, 507db2bae30SDana Myers ACPI_PARSE_OBJECT *Op) 508db2bae30SDana Myers { 509db2bae30SDana Myers ACPI_STATUS Status; 510db2bae30SDana Myers ACPI_OPERAND_OBJECT *ObjDesc; 511db2bae30SDana Myers ACPI_OPERAND_OBJECT **Operand; 512db2bae30SDana Myers ACPI_NAMESPACE_NODE *Node; 513db2bae30SDana Myers ACPI_PARSE_OBJECT *NextOp; 514db2bae30SDana Myers ACPI_TABLE_HEADER *Table; 515*385cc6b4SJerry Jelinek UINT32 TableIndex; 516db2bae30SDana Myers 517db2bae30SDana Myers 518db2bae30SDana Myers ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op); 519db2bae30SDana Myers 520db2bae30SDana Myers 521db2bae30SDana Myers /* 522*385cc6b4SJerry Jelinek * This is where we evaluate the Signature string, OemId string, 523*385cc6b4SJerry Jelinek * and OemTableId string of the Data Table Region declaration 524db2bae30SDana Myers */ 525db2bae30SDana Myers Node = Op->Common.Node; 526db2bae30SDana Myers 527*385cc6b4SJerry Jelinek /* NextOp points to Signature string op */ 528db2bae30SDana Myers 529db2bae30SDana Myers NextOp = Op->Common.Value.Arg; 530db2bae30SDana Myers 531db2bae30SDana Myers /* 532*385cc6b4SJerry Jelinek * Evaluate/create the Signature string, OemId string, 533*385cc6b4SJerry Jelinek * and OemTableId string operands 534db2bae30SDana Myers */ 535db2bae30SDana Myers Status = AcpiDsCreateOperands (WalkState, NextOp); 536db2bae30SDana Myers if (ACPI_FAILURE (Status)) 537db2bae30SDana Myers { 538db2bae30SDana Myers return_ACPI_STATUS (Status); 539db2bae30SDana Myers } 540db2bae30SDana Myers 541*385cc6b4SJerry Jelinek Operand = &WalkState->Operands[0]; 542*385cc6b4SJerry Jelinek 543db2bae30SDana Myers /* 544*385cc6b4SJerry Jelinek * Resolve the Signature string, OemId string, 545*385cc6b4SJerry Jelinek * and OemTableId string operands 546db2bae30SDana Myers */ 547*385cc6b4SJerry Jelinek Status = AcpiExResolveOperands ( 548*385cc6b4SJerry Jelinek Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState); 549db2bae30SDana Myers if (ACPI_FAILURE (Status)) 550db2bae30SDana Myers { 551*385cc6b4SJerry Jelinek goto Cleanup; 552db2bae30SDana Myers } 553db2bae30SDana Myers 554db2bae30SDana Myers /* Find the ACPI table */ 555db2bae30SDana Myers 556*385cc6b4SJerry Jelinek Status = AcpiTbFindTable ( 557*385cc6b4SJerry Jelinek Operand[0]->String.Pointer, 558*385cc6b4SJerry Jelinek Operand[1]->String.Pointer, 559*385cc6b4SJerry Jelinek Operand[2]->String.Pointer, &TableIndex); 560db2bae30SDana Myers if (ACPI_FAILURE (Status)) 561db2bae30SDana Myers { 562*385cc6b4SJerry Jelinek if (Status == AE_NOT_FOUND) 563*385cc6b4SJerry Jelinek { 564*385cc6b4SJerry Jelinek ACPI_ERROR ((AE_INFO, 565*385cc6b4SJerry Jelinek "ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT", 566*385cc6b4SJerry Jelinek Operand[0]->String.Pointer, 567*385cc6b4SJerry Jelinek Operand[1]->String.Pointer, 568*385cc6b4SJerry Jelinek Operand[2]->String.Pointer)); 569db2bae30SDana Myers } 570*385cc6b4SJerry Jelinek goto Cleanup; 571*385cc6b4SJerry Jelinek } 572db2bae30SDana Myers 573db2bae30SDana Myers Status = AcpiGetTableByIndex (TableIndex, &Table); 574db2bae30SDana Myers if (ACPI_FAILURE (Status)) 575db2bae30SDana Myers { 576*385cc6b4SJerry Jelinek goto Cleanup; 577db2bae30SDana Myers } 578db2bae30SDana Myers 579db2bae30SDana Myers ObjDesc = AcpiNsGetAttachedObject (Node); 580db2bae30SDana Myers if (!ObjDesc) 581db2bae30SDana Myers { 582*385cc6b4SJerry Jelinek Status = AE_NOT_EXIST; 583*385cc6b4SJerry Jelinek goto Cleanup; 584db2bae30SDana Myers } 585db2bae30SDana Myers 586*385cc6b4SJerry Jelinek ObjDesc->Region.Address = ACPI_PTR_TO_PHYSADDR (Table); 587db2bae30SDana Myers ObjDesc->Region.Length = Table->Length; 588db2bae30SDana Myers 589db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", 590*385cc6b4SJerry Jelinek ObjDesc, ACPI_FORMAT_UINT64 (ObjDesc->Region.Address), 591db2bae30SDana Myers ObjDesc->Region.Length)); 592db2bae30SDana Myers 593db2bae30SDana Myers /* Now the address and length are valid for this opregion */ 594db2bae30SDana Myers 595db2bae30SDana Myers ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID; 596db2bae30SDana Myers 597*385cc6b4SJerry Jelinek Cleanup: 598*385cc6b4SJerry Jelinek AcpiUtRemoveReference (Operand[0]); 599*385cc6b4SJerry Jelinek AcpiUtRemoveReference (Operand[1]); 600*385cc6b4SJerry Jelinek AcpiUtRemoveReference (Operand[2]); 601*385cc6b4SJerry Jelinek 602db2bae30SDana Myers return_ACPI_STATUS (Status); 603db2bae30SDana Myers } 604db2bae30SDana Myers 605db2bae30SDana Myers 606db2bae30SDana Myers /******************************************************************************* 607db2bae30SDana Myers * 608db2bae30SDana Myers * FUNCTION: AcpiDsEvalDataObjectOperands 609db2bae30SDana Myers * 610db2bae30SDana Myers * PARAMETERS: WalkState - Current walk 611db2bae30SDana Myers * Op - A valid DataObject Op object 612db2bae30SDana Myers * ObjDesc - DataObject 613db2bae30SDana Myers * 614db2bae30SDana Myers * RETURN: Status 615db2bae30SDana Myers * 616db2bae30SDana Myers * DESCRIPTION: Get the operands and complete the following data object types: 617db2bae30SDana Myers * Buffer, Package. 618db2bae30SDana Myers * 619db2bae30SDana Myers ******************************************************************************/ 620db2bae30SDana Myers 621db2bae30SDana Myers ACPI_STATUS 622db2bae30SDana Myers AcpiDsEvalDataObjectOperands ( 623db2bae30SDana Myers ACPI_WALK_STATE *WalkState, 624db2bae30SDana Myers ACPI_PARSE_OBJECT *Op, 625db2bae30SDana Myers ACPI_OPERAND_OBJECT *ObjDesc) 626db2bae30SDana Myers { 627db2bae30SDana Myers ACPI_STATUS Status; 628db2bae30SDana Myers ACPI_OPERAND_OBJECT *ArgDesc; 629db2bae30SDana Myers UINT32 Length; 630db2bae30SDana Myers 631db2bae30SDana Myers 632db2bae30SDana Myers ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands); 633db2bae30SDana Myers 634db2bae30SDana Myers 635db2bae30SDana Myers /* The first operand (for all of these data objects) is the length */ 636db2bae30SDana Myers 637db2bae30SDana Myers /* 638db2bae30SDana Myers * Set proper index into operand stack for AcpiDsObjStackPush 639db2bae30SDana Myers * invoked inside AcpiDsCreateOperand. 640db2bae30SDana Myers */ 641db2bae30SDana Myers WalkState->OperandIndex = WalkState->NumOperands; 642db2bae30SDana Myers 643db2bae30SDana Myers Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1); 644db2bae30SDana Myers if (ACPI_FAILURE (Status)) 645db2bae30SDana Myers { 646db2bae30SDana Myers return_ACPI_STATUS (Status); 647db2bae30SDana Myers } 648db2bae30SDana Myers 649db2bae30SDana Myers Status = AcpiExResolveOperands (WalkState->Opcode, 650db2bae30SDana Myers &(WalkState->Operands [WalkState->NumOperands -1]), 651db2bae30SDana Myers WalkState); 652db2bae30SDana Myers if (ACPI_FAILURE (Status)) 653db2bae30SDana Myers { 654db2bae30SDana Myers return_ACPI_STATUS (Status); 655db2bae30SDana Myers } 656db2bae30SDana Myers 657db2bae30SDana Myers /* Extract length operand */ 658db2bae30SDana Myers 659db2bae30SDana Myers ArgDesc = WalkState->Operands [WalkState->NumOperands - 1]; 660db2bae30SDana Myers Length = (UINT32) ArgDesc->Integer.Value; 661db2bae30SDana Myers 662db2bae30SDana Myers /* Cleanup for length operand */ 663db2bae30SDana Myers 664db2bae30SDana Myers Status = AcpiDsObjStackPop (1, WalkState); 665db2bae30SDana Myers if (ACPI_FAILURE (Status)) 666db2bae30SDana Myers { 667db2bae30SDana Myers return_ACPI_STATUS (Status); 668db2bae30SDana Myers } 669db2bae30SDana Myers 670db2bae30SDana Myers AcpiUtRemoveReference (ArgDesc); 671db2bae30SDana Myers 672db2bae30SDana Myers /* 673db2bae30SDana Myers * Create the actual data object 674db2bae30SDana Myers */ 675db2bae30SDana Myers switch (Op->Common.AmlOpcode) 676db2bae30SDana Myers { 677db2bae30SDana Myers case AML_BUFFER_OP: 678db2bae30SDana Myers 679*385cc6b4SJerry Jelinek Status = AcpiDsBuildInternalBufferObj ( 680*385cc6b4SJerry Jelinek WalkState, Op, Length, &ObjDesc); 681db2bae30SDana Myers break; 682db2bae30SDana Myers 683db2bae30SDana Myers case AML_PACKAGE_OP: 684db2bae30SDana Myers case AML_VAR_PACKAGE_OP: 685db2bae30SDana Myers 686*385cc6b4SJerry Jelinek Status = AcpiDsBuildInternalPackageObj ( 687*385cc6b4SJerry Jelinek WalkState, Op, Length, &ObjDesc); 688db2bae30SDana Myers break; 689db2bae30SDana Myers 690db2bae30SDana Myers default: 691*385cc6b4SJerry Jelinek 692db2bae30SDana Myers return_ACPI_STATUS (AE_AML_BAD_OPCODE); 693db2bae30SDana Myers } 694db2bae30SDana Myers 695db2bae30SDana Myers if (ACPI_SUCCESS (Status)) 696db2bae30SDana Myers { 697db2bae30SDana Myers /* 698db2bae30SDana Myers * Return the object in the WalkState, unless the parent is a package - 699db2bae30SDana Myers * in this case, the return object will be stored in the parse tree 700db2bae30SDana Myers * for the package. 701db2bae30SDana Myers */ 702db2bae30SDana Myers if ((!Op->Common.Parent) || 703db2bae30SDana Myers ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) && 704db2bae30SDana Myers (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) && 705db2bae30SDana Myers (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP))) 706db2bae30SDana Myers { 707db2bae30SDana Myers WalkState->ResultObj = ObjDesc; 708db2bae30SDana Myers } 709db2bae30SDana Myers } 710db2bae30SDana Myers 711db2bae30SDana Myers return_ACPI_STATUS (Status); 712db2bae30SDana Myers } 713db2bae30SDana Myers 714db2bae30SDana Myers 715db2bae30SDana Myers /******************************************************************************* 716db2bae30SDana Myers * 717db2bae30SDana Myers * FUNCTION: AcpiDsEvalBankFieldOperands 718db2bae30SDana Myers * 719db2bae30SDana Myers * PARAMETERS: WalkState - Current walk 720db2bae30SDana Myers * Op - A valid BankField Op object 721db2bae30SDana Myers * 722db2bae30SDana Myers * RETURN: Status 723db2bae30SDana Myers * 724db2bae30SDana Myers * DESCRIPTION: Get BankField BankValue 725db2bae30SDana Myers * Called from AcpiDsExecEndOp during BankField parse tree walk 726db2bae30SDana Myers * 727db2bae30SDana Myers ******************************************************************************/ 728db2bae30SDana Myers 729db2bae30SDana Myers ACPI_STATUS 730db2bae30SDana Myers AcpiDsEvalBankFieldOperands ( 731db2bae30SDana Myers ACPI_WALK_STATE *WalkState, 732db2bae30SDana Myers ACPI_PARSE_OBJECT *Op) 733db2bae30SDana Myers { 734db2bae30SDana Myers ACPI_STATUS Status; 735db2bae30SDana Myers ACPI_OPERAND_OBJECT *ObjDesc; 736db2bae30SDana Myers ACPI_OPERAND_OBJECT *OperandDesc; 737db2bae30SDana Myers ACPI_NAMESPACE_NODE *Node; 738db2bae30SDana Myers ACPI_PARSE_OBJECT *NextOp; 739db2bae30SDana Myers ACPI_PARSE_OBJECT *Arg; 740db2bae30SDana Myers 741db2bae30SDana Myers 742db2bae30SDana Myers ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands, Op); 743db2bae30SDana Myers 744db2bae30SDana Myers 745db2bae30SDana Myers /* 746db2bae30SDana Myers * This is where we evaluate the BankValue field of the 747db2bae30SDana Myers * BankField declaration 748db2bae30SDana Myers */ 749db2bae30SDana Myers 750db2bae30SDana Myers /* NextOp points to the op that holds the Region */ 751db2bae30SDana Myers 752db2bae30SDana Myers NextOp = Op->Common.Value.Arg; 753db2bae30SDana Myers 754db2bae30SDana Myers /* NextOp points to the op that holds the Bank Register */ 755db2bae30SDana Myers 756db2bae30SDana Myers NextOp = NextOp->Common.Next; 757db2bae30SDana Myers 758db2bae30SDana Myers /* NextOp points to the op that holds the Bank Value */ 759db2bae30SDana Myers 760db2bae30SDana Myers NextOp = NextOp->Common.Next; 761db2bae30SDana Myers 762db2bae30SDana Myers /* 763db2bae30SDana Myers * Set proper index into operand stack for AcpiDsObjStackPush 764db2bae30SDana Myers * invoked inside AcpiDsCreateOperand. 765db2bae30SDana Myers * 766db2bae30SDana Myers * We use WalkState->Operands[0] to store the evaluated BankValue 767db2bae30SDana Myers */ 768db2bae30SDana Myers WalkState->OperandIndex = 0; 769db2bae30SDana Myers 770db2bae30SDana Myers Status = AcpiDsCreateOperand (WalkState, NextOp, 0); 771db2bae30SDana Myers if (ACPI_FAILURE (Status)) 772db2bae30SDana Myers { 773db2bae30SDana Myers return_ACPI_STATUS (Status); 774db2bae30SDana Myers } 775db2bae30SDana Myers 776db2bae30SDana Myers Status = AcpiExResolveToValue (&WalkState->Operands[0], WalkState); 777db2bae30SDana Myers if (ACPI_FAILURE (Status)) 778db2bae30SDana Myers { 779db2bae30SDana Myers return_ACPI_STATUS (Status); 780db2bae30SDana Myers } 781db2bae30SDana Myers 782db2bae30SDana Myers ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, 783db2bae30SDana Myers AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 1); 784db2bae30SDana Myers /* 785db2bae30SDana Myers * Get the BankValue operand and save it 786db2bae30SDana Myers * (at Top of stack) 787db2bae30SDana Myers */ 788db2bae30SDana Myers OperandDesc = WalkState->Operands[0]; 789db2bae30SDana Myers 790db2bae30SDana Myers /* Arg points to the start Bank Field */ 791db2bae30SDana Myers 792db2bae30SDana Myers Arg = AcpiPsGetArg (Op, 4); 793db2bae30SDana Myers while (Arg) 794db2bae30SDana Myers { 795db2bae30SDana Myers /* Ignore OFFSET and ACCESSAS terms here */ 796db2bae30SDana Myers 797db2bae30SDana Myers if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP) 798db2bae30SDana Myers { 799db2bae30SDana Myers Node = Arg->Common.Node; 800db2bae30SDana Myers 801db2bae30SDana Myers ObjDesc = AcpiNsGetAttachedObject (Node); 802db2bae30SDana Myers if (!ObjDesc) 803db2bae30SDana Myers { 804db2bae30SDana Myers return_ACPI_STATUS (AE_NOT_EXIST); 805db2bae30SDana Myers } 806db2bae30SDana Myers 807db2bae30SDana Myers ObjDesc->BankField.Value = (UINT32) OperandDesc->Integer.Value; 808db2bae30SDana Myers } 809db2bae30SDana Myers 810db2bae30SDana Myers /* Move to next field in the list */ 811db2bae30SDana Myers 812db2bae30SDana Myers Arg = Arg->Common.Next; 813db2bae30SDana Myers } 814db2bae30SDana Myers 815db2bae30SDana Myers AcpiUtRemoveReference (OperandDesc); 816db2bae30SDana Myers return_ACPI_STATUS (Status); 817db2bae30SDana Myers } 818