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