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