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