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