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