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