1 /****************************************************************************** 2 * 3 * Module Name: dsfield - Dispatcher field routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2017, 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 "acpi.h" 45 #include "accommon.h" 46 #include "amlcode.h" 47 #include "acdispat.h" 48 #include "acinterp.h" 49 #include "acnamesp.h" 50 #include "acparser.h" 51 52 53 #define _COMPONENT ACPI_DISPATCHER 54 ACPI_MODULE_NAME ("dsfield") 55 56 /* Local prototypes */ 57 58 #ifdef ACPI_ASL_COMPILER 59 #include "acdisasm.h" 60 61 static ACPI_STATUS 62 AcpiDsCreateExternalRegion ( 63 ACPI_STATUS LookupStatus, 64 ACPI_PARSE_OBJECT *Op, 65 char *Path, 66 ACPI_WALK_STATE *WalkState, 67 ACPI_NAMESPACE_NODE **Node); 68 #endif 69 70 static ACPI_STATUS 71 AcpiDsGetFieldNames ( 72 ACPI_CREATE_FIELD_INFO *Info, 73 ACPI_WALK_STATE *WalkState, 74 ACPI_PARSE_OBJECT *Arg); 75 76 77 #ifdef ACPI_ASL_COMPILER 78 /******************************************************************************* 79 * 80 * FUNCTION: AcpiDsCreateExternalRegion (iASL Disassembler only) 81 * 82 * PARAMETERS: LookupStatus - Status from NsLookup operation 83 * Op - Op containing the Field definition and args 84 * Path - Pathname of the region 85 * ` WalkState - Current method state 86 * Node - Where the new region node is returned 87 * 88 * RETURN: Status 89 * 90 * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new 91 * region node/object. 92 * 93 ******************************************************************************/ 94 95 static ACPI_STATUS 96 AcpiDsCreateExternalRegion ( 97 ACPI_STATUS LookupStatus, 98 ACPI_PARSE_OBJECT *Op, 99 char *Path, 100 ACPI_WALK_STATE *WalkState, 101 ACPI_NAMESPACE_NODE **Node) 102 { 103 ACPI_STATUS Status; 104 ACPI_OPERAND_OBJECT *ObjDesc; 105 106 107 if (LookupStatus != AE_NOT_FOUND) 108 { 109 return (LookupStatus); 110 } 111 112 /* 113 * Table disassembly: 114 * OperationRegion not found. Generate an External for it, and 115 * insert the name into the namespace. 116 */ 117 AcpiDmAddOpToExternalList (Op, Path, ACPI_TYPE_REGION, 0, 0); 118 119 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_REGION, 120 ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, WalkState, Node); 121 if (ACPI_FAILURE (Status)) 122 { 123 return (Status); 124 } 125 126 /* Must create and install a region object for the new node */ 127 128 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION); 129 if (!ObjDesc) 130 { 131 return (AE_NO_MEMORY); 132 } 133 134 ObjDesc->Region.Node = *Node; 135 Status = AcpiNsAttachObject (*Node, ObjDesc, ACPI_TYPE_REGION); 136 return (Status); 137 } 138 #endif 139 140 141 /******************************************************************************* 142 * 143 * FUNCTION: AcpiDsCreateBufferField 144 * 145 * PARAMETERS: Op - Current parse op (CreateXXField) 146 * WalkState - Current state 147 * 148 * RETURN: Status 149 * 150 * DESCRIPTION: Execute the CreateField operators: 151 * CreateBitFieldOp, 152 * CreateByteFieldOp, 153 * CreateWordFieldOp, 154 * CreateDwordFieldOp, 155 * CreateQwordFieldOp, 156 * CreateFieldOp (all of which define a field in a buffer) 157 * 158 ******************************************************************************/ 159 160 ACPI_STATUS 161 AcpiDsCreateBufferField ( 162 ACPI_PARSE_OBJECT *Op, 163 ACPI_WALK_STATE *WalkState) 164 { 165 ACPI_PARSE_OBJECT *Arg; 166 ACPI_NAMESPACE_NODE *Node; 167 ACPI_STATUS Status; 168 ACPI_OPERAND_OBJECT *ObjDesc; 169 ACPI_OPERAND_OBJECT *SecondDesc = NULL; 170 UINT32 Flags; 171 172 173 ACPI_FUNCTION_TRACE (DsCreateBufferField); 174 175 176 /* 177 * Get the NameString argument (name of the new BufferField) 178 */ 179 if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP) 180 { 181 /* For CreateField, name is the 4th argument */ 182 183 Arg = AcpiPsGetArg (Op, 3); 184 } 185 else 186 { 187 /* For all other CreateXXXField operators, name is the 3rd argument */ 188 189 Arg = AcpiPsGetArg (Op, 2); 190 } 191 192 if (!Arg) 193 { 194 return_ACPI_STATUS (AE_AML_NO_OPERAND); 195 } 196 197 if (WalkState->DeferredNode) 198 { 199 Node = WalkState->DeferredNode; 200 Status = AE_OK; 201 } 202 else 203 { 204 /* Execute flag should always be set when this function is entered */ 205 206 if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE)) 207 { 208 ACPI_ERROR ((AE_INFO, 209 "Parse execute mode is not set")); 210 return_ACPI_STATUS (AE_AML_INTERNAL); 211 } 212 213 /* Creating new namespace node, should not already exist */ 214 215 Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 216 ACPI_NS_ERROR_IF_FOUND; 217 218 /* 219 * Mark node temporary if we are executing a normal control 220 * method. (Don't mark if this is a module-level code method) 221 */ 222 if (WalkState->MethodNode && 223 !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) 224 { 225 Flags |= ACPI_NS_TEMPORARY; 226 } 227 228 /* Enter the NameString into the namespace */ 229 230 Status = AcpiNsLookup (WalkState->ScopeInfo, 231 Arg->Common.Value.String, ACPI_TYPE_ANY, 232 ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); 233 if (ACPI_FAILURE (Status)) 234 { 235 ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 236 return_ACPI_STATUS (Status); 237 } 238 } 239 240 /* 241 * We could put the returned object (Node) on the object stack for later, 242 * but for now, we will put it in the "op" object that the parser uses, 243 * so we can get it again at the end of this scope. 244 */ 245 Op->Common.Node = Node; 246 247 /* 248 * If there is no object attached to the node, this node was just created 249 * and we need to create the field object. Otherwise, this was a lookup 250 * of an existing node and we don't want to create the field object again. 251 */ 252 ObjDesc = AcpiNsGetAttachedObject (Node); 253 if (ObjDesc) 254 { 255 return_ACPI_STATUS (AE_OK); 256 } 257 258 /* 259 * The Field definition is not fully parsed at this time. 260 * (We must save the address of the AML for the buffer and index operands) 261 */ 262 263 /* Create the buffer field object */ 264 265 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD); 266 if (!ObjDesc) 267 { 268 Status = AE_NO_MEMORY; 269 goto Cleanup; 270 } 271 272 /* 273 * Remember location in AML stream of the field unit opcode and operands 274 * -- since the buffer and index operands must be evaluated. 275 */ 276 SecondDesc = ObjDesc->Common.NextObject; 277 SecondDesc->Extra.AmlStart = Op->Named.Data; 278 SecondDesc->Extra.AmlLength = Op->Named.Length; 279 ObjDesc->BufferField.Node = Node; 280 281 /* Attach constructed field descriptors to parent node */ 282 283 Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD); 284 if (ACPI_FAILURE (Status)) 285 { 286 goto Cleanup; 287 } 288 289 290 Cleanup: 291 292 /* Remove local reference to the object */ 293 294 AcpiUtRemoveReference (ObjDesc); 295 return_ACPI_STATUS (Status); 296 } 297 298 299 /******************************************************************************* 300 * 301 * FUNCTION: AcpiDsGetFieldNames 302 * 303 * PARAMETERS: Info - CreateField info structure 304 * ` WalkState - Current method state 305 * Arg - First parser arg for the field name list 306 * 307 * RETURN: Status 308 * 309 * DESCRIPTION: Process all named fields in a field declaration. Names are 310 * entered into the namespace. 311 * 312 ******************************************************************************/ 313 314 static ACPI_STATUS 315 AcpiDsGetFieldNames ( 316 ACPI_CREATE_FIELD_INFO *Info, 317 ACPI_WALK_STATE *WalkState, 318 ACPI_PARSE_OBJECT *Arg) 319 { 320 ACPI_STATUS Status; 321 UINT64 Position; 322 ACPI_PARSE_OBJECT *Child; 323 324 325 ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info); 326 327 328 /* First field starts at bit zero */ 329 330 Info->FieldBitPosition = 0; 331 332 /* Process all elements in the field list (of parse nodes) */ 333 334 while (Arg) 335 { 336 /* 337 * Four types of field elements are handled: 338 * 1) Name - Enters a new named field into the namespace 339 * 2) Offset - specifies a bit offset 340 * 3) AccessAs - changes the access mode/attributes 341 * 4) Connection - Associate a resource template with the field 342 */ 343 switch (Arg->Common.AmlOpcode) 344 { 345 case AML_INT_RESERVEDFIELD_OP: 346 347 Position = (UINT64) Info->FieldBitPosition + 348 (UINT64) Arg->Common.Value.Size; 349 350 if (Position > ACPI_UINT32_MAX) 351 { 352 ACPI_ERROR ((AE_INFO, 353 "Bit offset within field too large (> 0xFFFFFFFF)")); 354 return_ACPI_STATUS (AE_SUPPORT); 355 } 356 357 Info->FieldBitPosition = (UINT32) Position; 358 break; 359 360 case AML_INT_ACCESSFIELD_OP: 361 case AML_INT_EXTACCESSFIELD_OP: 362 /* 363 * Get new AccessType, AccessAttribute, and AccessLength fields 364 * -- to be used for all field units that follow, until the 365 * end-of-field or another AccessAs keyword is encountered. 366 * NOTE. These three bytes are encoded in the integer value 367 * of the parseop for convenience. 368 * 369 * In FieldFlags, preserve the flag bits other than the 370 * ACCESS_TYPE bits. 371 */ 372 373 /* AccessType (ByteAcc, WordAcc, etc.) */ 374 375 Info->FieldFlags = (UINT8) 376 ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) | 377 ((UINT8) ((UINT32) (Arg->Common.Value.Integer & 0x07)))); 378 379 /* AccessAttribute (AttribQuick, AttribByte, etc.) */ 380 381 Info->Attribute = (UINT8) 382 ((Arg->Common.Value.Integer >> 8) & 0xFF); 383 384 /* AccessLength (for serial/buffer protocols) */ 385 386 Info->AccessLength = (UINT8) 387 ((Arg->Common.Value.Integer >> 16) & 0xFF); 388 break; 389 390 case AML_INT_CONNECTION_OP: 391 /* 392 * Clear any previous connection. New connection is used for all 393 * fields that follow, similar to AccessAs 394 */ 395 Info->ResourceBuffer = NULL; 396 Info->ConnectionNode = NULL; 397 Info->PinNumberIndex = 0; 398 399 /* 400 * A Connection() is either an actual resource descriptor (buffer) 401 * or a named reference to a resource template 402 */ 403 Child = Arg->Common.Value.Arg; 404 if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP) 405 { 406 Info->ResourceBuffer = Child->Named.Data; 407 Info->ResourceLength = (UINT16) Child->Named.Value.Integer; 408 } 409 else 410 { 411 /* Lookup the Connection() namepath, it should already exist */ 412 413 Status = AcpiNsLookup (WalkState->ScopeInfo, 414 Child->Common.Value.Name, ACPI_TYPE_ANY, 415 ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE, 416 WalkState, &Info->ConnectionNode); 417 if (ACPI_FAILURE (Status)) 418 { 419 ACPI_ERROR_NAMESPACE (Child->Common.Value.Name, Status); 420 return_ACPI_STATUS (Status); 421 } 422 } 423 break; 424 425 case AML_INT_NAMEDFIELD_OP: 426 427 /* Lookup the name, it should already exist */ 428 429 Status = AcpiNsLookup (WalkState->ScopeInfo, 430 (char *) &Arg->Named.Name, Info->FieldType, 431 ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE, 432 WalkState, &Info->FieldNode); 433 if (ACPI_FAILURE (Status)) 434 { 435 ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status); 436 return_ACPI_STATUS (Status); 437 } 438 else 439 { 440 Arg->Common.Node = Info->FieldNode; 441 Info->FieldBitLength = Arg->Common.Value.Size; 442 443 /* 444 * If there is no object attached to the node, this node was 445 * just created and we need to create the field object. 446 * Otherwise, this was a lookup of an existing node and we 447 * don't want to create the field object again. 448 */ 449 if (!AcpiNsGetAttachedObject (Info->FieldNode)) 450 { 451 Status = AcpiExPrepFieldValue (Info); 452 if (ACPI_FAILURE (Status)) 453 { 454 return_ACPI_STATUS (Status); 455 } 456 } 457 } 458 459 /* Keep track of bit position for the next field */ 460 461 Position = (UINT64) Info->FieldBitPosition + 462 (UINT64) Arg->Common.Value.Size; 463 464 if (Position > ACPI_UINT32_MAX) 465 { 466 ACPI_ERROR ((AE_INFO, 467 "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)", 468 ACPI_CAST_PTR (char, &Info->FieldNode->Name))); 469 return_ACPI_STATUS (AE_SUPPORT); 470 } 471 472 Info->FieldBitPosition += Info->FieldBitLength; 473 Info->PinNumberIndex++; /* Index relative to previous Connection() */ 474 break; 475 476 default: 477 478 ACPI_ERROR ((AE_INFO, 479 "Invalid opcode in field list: 0x%X", 480 Arg->Common.AmlOpcode)); 481 return_ACPI_STATUS (AE_AML_BAD_OPCODE); 482 } 483 484 Arg = Arg->Common.Next; 485 } 486 487 return_ACPI_STATUS (AE_OK); 488 } 489 490 491 /******************************************************************************* 492 * 493 * FUNCTION: AcpiDsCreateField 494 * 495 * PARAMETERS: Op - Op containing the Field definition and args 496 * RegionNode - Object for the containing Operation Region 497 * ` WalkState - Current method state 498 * 499 * RETURN: Status 500 * 501 * DESCRIPTION: Create a new field in the specified operation region 502 * 503 ******************************************************************************/ 504 505 ACPI_STATUS 506 AcpiDsCreateField ( 507 ACPI_PARSE_OBJECT *Op, 508 ACPI_NAMESPACE_NODE *RegionNode, 509 ACPI_WALK_STATE *WalkState) 510 { 511 ACPI_STATUS Status; 512 ACPI_PARSE_OBJECT *Arg; 513 ACPI_CREATE_FIELD_INFO Info; 514 515 516 ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op); 517 518 519 /* First arg is the name of the parent OpRegion (must already exist) */ 520 521 Arg = Op->Common.Value.Arg; 522 523 if (!RegionNode) 524 { 525 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name, 526 ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE, 527 ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode); 528 #ifdef ACPI_ASL_COMPILER 529 Status = AcpiDsCreateExternalRegion (Status, Arg, 530 Arg->Common.Value.Name, WalkState, &RegionNode); 531 #endif 532 if (ACPI_FAILURE (Status)) 533 { 534 ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status); 535 return_ACPI_STATUS (Status); 536 } 537 } 538 539 memset (&Info, 0, sizeof (ACPI_CREATE_FIELD_INFO)); 540 541 /* Second arg is the field flags */ 542 543 Arg = Arg->Common.Next; 544 Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 545 Info.Attribute = 0; 546 547 /* Each remaining arg is a Named Field */ 548 549 Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD; 550 Info.RegionNode = RegionNode; 551 552 Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 553 return_ACPI_STATUS (Status); 554 } 555 556 557 /******************************************************************************* 558 * 559 * FUNCTION: AcpiDsInitFieldObjects 560 * 561 * PARAMETERS: Op - Op containing the Field definition and args 562 * ` WalkState - Current method state 563 * 564 * RETURN: Status 565 * 566 * DESCRIPTION: For each "Field Unit" name in the argument list that is 567 * part of the field declaration, enter the name into the 568 * namespace. 569 * 570 ******************************************************************************/ 571 572 ACPI_STATUS 573 AcpiDsInitFieldObjects ( 574 ACPI_PARSE_OBJECT *Op, 575 ACPI_WALK_STATE *WalkState) 576 { 577 ACPI_STATUS Status; 578 ACPI_PARSE_OBJECT *Arg = NULL; 579 ACPI_NAMESPACE_NODE *Node; 580 UINT8 Type = 0; 581 UINT32 Flags; 582 583 584 ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op); 585 586 587 /* Execute flag should always be set when this function is entered */ 588 589 if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE)) 590 { 591 if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP) 592 { 593 /* BankField Op is deferred, just return OK */ 594 595 return_ACPI_STATUS (AE_OK); 596 } 597 598 ACPI_ERROR ((AE_INFO, 599 "Parse deferred mode is not set")); 600 return_ACPI_STATUS (AE_AML_INTERNAL); 601 } 602 603 /* 604 * Get the FieldList argument for this opcode. This is the start of the 605 * list of field elements. 606 */ 607 switch (WalkState->Opcode) 608 { 609 case AML_FIELD_OP: 610 611 Arg = AcpiPsGetArg (Op, 2); 612 Type = ACPI_TYPE_LOCAL_REGION_FIELD; 613 break; 614 615 case AML_BANK_FIELD_OP: 616 617 Arg = AcpiPsGetArg (Op, 4); 618 Type = ACPI_TYPE_LOCAL_BANK_FIELD; 619 break; 620 621 case AML_INDEX_FIELD_OP: 622 623 Arg = AcpiPsGetArg (Op, 3); 624 Type = ACPI_TYPE_LOCAL_INDEX_FIELD; 625 break; 626 627 default: 628 629 return_ACPI_STATUS (AE_BAD_PARAMETER); 630 } 631 632 /* Creating new namespace node(s), should not already exist */ 633 634 Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 635 ACPI_NS_ERROR_IF_FOUND; 636 637 /* 638 * Mark node(s) temporary if we are executing a normal control 639 * method. (Don't mark if this is a module-level code method) 640 */ 641 if (WalkState->MethodNode && 642 !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) 643 { 644 Flags |= ACPI_NS_TEMPORARY; 645 } 646 647 /* 648 * Walk the list of entries in the FieldList 649 * Note: FieldList can be of zero length. In this case, Arg will be NULL. 650 */ 651 while (Arg) 652 { 653 /* 654 * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested 655 * in the field names in order to enter them into the namespace. 656 */ 657 if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP) 658 { 659 Status = AcpiNsLookup (WalkState->ScopeInfo, 660 (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1, 661 Flags, WalkState, &Node); 662 if (ACPI_FAILURE (Status)) 663 { 664 ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status); 665 if (Status != AE_ALREADY_EXISTS) 666 { 667 return_ACPI_STATUS (Status); 668 } 669 670 /* Name already exists, just ignore this error */ 671 672 Status = AE_OK; 673 } 674 675 Arg->Common.Node = Node; 676 } 677 678 /* Get the next field element in the list */ 679 680 Arg = Arg->Common.Next; 681 } 682 683 return_ACPI_STATUS (AE_OK); 684 } 685 686 687 /******************************************************************************* 688 * 689 * FUNCTION: AcpiDsCreateBankField 690 * 691 * PARAMETERS: Op - Op containing the Field definition and args 692 * RegionNode - Object for the containing Operation Region 693 * WalkState - Current method state 694 * 695 * RETURN: Status 696 * 697 * DESCRIPTION: Create a new bank field in the specified operation region 698 * 699 ******************************************************************************/ 700 701 ACPI_STATUS 702 AcpiDsCreateBankField ( 703 ACPI_PARSE_OBJECT *Op, 704 ACPI_NAMESPACE_NODE *RegionNode, 705 ACPI_WALK_STATE *WalkState) 706 { 707 ACPI_STATUS Status; 708 ACPI_PARSE_OBJECT *Arg; 709 ACPI_CREATE_FIELD_INFO Info; 710 711 712 ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op); 713 714 715 /* First arg is the name of the parent OpRegion (must already exist) */ 716 717 Arg = Op->Common.Value.Arg; 718 if (!RegionNode) 719 { 720 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name, 721 ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE, 722 ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode); 723 #ifdef ACPI_ASL_COMPILER 724 Status = AcpiDsCreateExternalRegion (Status, Arg, 725 Arg->Common.Value.Name, WalkState, &RegionNode); 726 #endif 727 if (ACPI_FAILURE (Status)) 728 { 729 ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status); 730 return_ACPI_STATUS (Status); 731 } 732 } 733 734 /* Second arg is the Bank Register (Field) (must already exist) */ 735 736 Arg = Arg->Common.Next; 737 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 738 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 739 ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode); 740 if (ACPI_FAILURE (Status)) 741 { 742 ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 743 return_ACPI_STATUS (Status); 744 } 745 746 /* 747 * Third arg is the BankValue 748 * This arg is a TermArg, not a constant 749 * It will be evaluated later, by AcpiDsEvalBankFieldOperands 750 */ 751 Arg = Arg->Common.Next; 752 753 /* Fourth arg is the field flags */ 754 755 Arg = Arg->Common.Next; 756 Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 757 758 /* Each remaining arg is a Named Field */ 759 760 Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD; 761 Info.RegionNode = RegionNode; 762 763 /* 764 * Use Info.DataRegisterNode to store BankField Op 765 * It's safe because DataRegisterNode will never be used when create 766 * bank field \we store AmlStart and AmlLength in the BankField Op for 767 * late evaluation. Used in AcpiExPrepFieldValue(Info) 768 * 769 * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like 770 * "void *ParentOp"? 771 */ 772 Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op; 773 774 Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 775 return_ACPI_STATUS (Status); 776 } 777 778 779 /******************************************************************************* 780 * 781 * FUNCTION: AcpiDsCreateIndexField 782 * 783 * PARAMETERS: Op - Op containing the Field definition and args 784 * RegionNode - Object for the containing Operation Region 785 * ` WalkState - Current method state 786 * 787 * RETURN: Status 788 * 789 * DESCRIPTION: Create a new index field in the specified operation region 790 * 791 ******************************************************************************/ 792 793 ACPI_STATUS 794 AcpiDsCreateIndexField ( 795 ACPI_PARSE_OBJECT *Op, 796 ACPI_NAMESPACE_NODE *RegionNode, 797 ACPI_WALK_STATE *WalkState) 798 { 799 ACPI_STATUS Status; 800 ACPI_PARSE_OBJECT *Arg; 801 ACPI_CREATE_FIELD_INFO Info; 802 803 804 ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op); 805 806 807 /* First arg is the name of the Index register (must already exist) */ 808 809 Arg = Op->Common.Value.Arg; 810 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 811 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 812 ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode); 813 if (ACPI_FAILURE (Status)) 814 { 815 ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 816 return_ACPI_STATUS (Status); 817 } 818 819 /* Second arg is the data register (must already exist) */ 820 821 Arg = Arg->Common.Next; 822 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 823 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 824 ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode); 825 if (ACPI_FAILURE (Status)) 826 { 827 ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 828 return_ACPI_STATUS (Status); 829 } 830 831 /* Next arg is the field flags */ 832 833 Arg = Arg->Common.Next; 834 Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 835 836 /* Each remaining arg is a Named Field */ 837 838 Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD; 839 Info.RegionNode = RegionNode; 840 841 Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 842 return_ACPI_STATUS (Status); 843 } 844