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