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 if (Info.RegionNode->Object->Region.SpaceId == ACPI_ADR_SPACE_PLATFORM_COMM && 581 !(RegionNode->Object->Field.InternalPccBuffer 582 = ACPI_ALLOCATE_ZEROED(Info.RegionNode->Object->Region.Length))) 583 { 584 return_ACPI_STATUS (AE_NO_MEMORY); 585 } 586 return_ACPI_STATUS (Status); 587 } 588 589 590 /******************************************************************************* 591 * 592 * FUNCTION: AcpiDsInitFieldObjects 593 * 594 * PARAMETERS: Op - Op containing the Field definition and args 595 * ` WalkState - Current method state 596 * 597 * RETURN: Status 598 * 599 * DESCRIPTION: For each "Field Unit" name in the argument list that is 600 * part of the field declaration, enter the name into the 601 * namespace. 602 * 603 ******************************************************************************/ 604 605 ACPI_STATUS 606 AcpiDsInitFieldObjects ( 607 ACPI_PARSE_OBJECT *Op, 608 ACPI_WALK_STATE *WalkState) 609 { 610 ACPI_STATUS Status; 611 ACPI_PARSE_OBJECT *Arg = NULL; 612 ACPI_NAMESPACE_NODE *Node; 613 UINT8 Type = 0; 614 UINT32 Flags; 615 616 617 ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op); 618 619 620 /* Execute flag should always be set when this function is entered */ 621 622 if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE)) 623 { 624 if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP) 625 { 626 /* BankField Op is deferred, just return OK */ 627 628 return_ACPI_STATUS (AE_OK); 629 } 630 631 ACPI_ERROR ((AE_INFO, 632 "Parse deferred mode is not set")); 633 return_ACPI_STATUS (AE_AML_INTERNAL); 634 } 635 636 /* 637 * Get the FieldList argument for this opcode. This is the start of the 638 * list of field elements. 639 */ 640 switch (WalkState->Opcode) 641 { 642 case AML_FIELD_OP: 643 644 Arg = AcpiPsGetArg (Op, 2); 645 Type = ACPI_TYPE_LOCAL_REGION_FIELD; 646 break; 647 648 case AML_BANK_FIELD_OP: 649 650 Arg = AcpiPsGetArg (Op, 4); 651 Type = ACPI_TYPE_LOCAL_BANK_FIELD; 652 break; 653 654 case AML_INDEX_FIELD_OP: 655 656 Arg = AcpiPsGetArg (Op, 3); 657 Type = ACPI_TYPE_LOCAL_INDEX_FIELD; 658 break; 659 660 default: 661 662 return_ACPI_STATUS (AE_BAD_PARAMETER); 663 } 664 665 /* Creating new namespace node(s), should not already exist */ 666 667 Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 668 ACPI_NS_ERROR_IF_FOUND; 669 670 /* 671 * Mark node(s) temporary if we are executing a normal control 672 * method. (Don't mark if this is a module-level code method) 673 */ 674 if (WalkState->MethodNode && 675 !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) 676 { 677 Flags |= ACPI_NS_TEMPORARY; 678 } 679 680 #ifdef ACPI_EXEC_APP 681 Flags |= ACPI_NS_OVERRIDE_IF_FOUND; 682 #endif 683 /* 684 * Walk the list of entries in the FieldList 685 * Note: FieldList can be of zero length. In this case, Arg will be NULL. 686 */ 687 while (Arg) 688 { 689 /* 690 * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested 691 * in the field names in order to enter them into the namespace. 692 */ 693 if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP) 694 { 695 Status = AcpiNsLookup (WalkState->ScopeInfo, 696 (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1, 697 Flags, WalkState, &Node); 698 if (ACPI_FAILURE (Status)) 699 { 700 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, 701 (char *) &Arg->Named.Name, Status); 702 if (Status != AE_ALREADY_EXISTS) 703 { 704 return_ACPI_STATUS (Status); 705 } 706 707 /* Name already exists, just ignore this error */ 708 709 Status = AE_OK; 710 } 711 712 Arg->Common.Node = Node; 713 } 714 715 /* Get the next field element in the list */ 716 717 Arg = Arg->Common.Next; 718 } 719 720 return_ACPI_STATUS (AE_OK); 721 } 722 723 724 /******************************************************************************* 725 * 726 * FUNCTION: AcpiDsCreateBankField 727 * 728 * PARAMETERS: Op - Op containing the Field definition and args 729 * RegionNode - Object for the containing Operation Region 730 * WalkState - Current method state 731 * 732 * RETURN: Status 733 * 734 * DESCRIPTION: Create a new bank field in the specified operation region 735 * 736 ******************************************************************************/ 737 738 ACPI_STATUS 739 AcpiDsCreateBankField ( 740 ACPI_PARSE_OBJECT *Op, 741 ACPI_NAMESPACE_NODE *RegionNode, 742 ACPI_WALK_STATE *WalkState) 743 { 744 ACPI_STATUS Status; 745 ACPI_PARSE_OBJECT *Arg; 746 ACPI_CREATE_FIELD_INFO Info; 747 748 749 ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op); 750 751 752 /* First arg is the name of the parent OpRegion (must already exist) */ 753 754 Arg = Op->Common.Value.Arg; 755 if (!RegionNode) 756 { 757 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name, 758 ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE, 759 ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode); 760 #ifdef ACPI_ASL_COMPILER 761 Status = AcpiDsCreateExternalRegion (Status, Arg, 762 Arg->Common.Value.Name, WalkState, &RegionNode); 763 #endif 764 if (ACPI_FAILURE (Status)) 765 { 766 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, 767 Arg->Common.Value.Name, Status); 768 return_ACPI_STATUS (Status); 769 } 770 } 771 772 /* Second arg is the Bank Register (Field) (must already exist) */ 773 774 Arg = Arg->Common.Next; 775 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 776 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 777 ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode); 778 if (ACPI_FAILURE (Status)) 779 { 780 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, 781 Arg->Common.Value.String, Status); 782 return_ACPI_STATUS (Status); 783 } 784 785 /* 786 * Third arg is the BankValue 787 * This arg is a TermArg, not a constant 788 * It will be evaluated later, by AcpiDsEvalBankFieldOperands 789 */ 790 Arg = Arg->Common.Next; 791 792 /* Fourth arg is the field flags */ 793 794 Arg = Arg->Common.Next; 795 Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 796 797 /* Each remaining arg is a Named Field */ 798 799 Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD; 800 Info.RegionNode = RegionNode; 801 802 /* 803 * Use Info.DataRegisterNode to store BankField Op 804 * It's safe because DataRegisterNode will never be used when create 805 * bank field \we store AmlStart and AmlLength in the BankField Op for 806 * late evaluation. Used in AcpiExPrepFieldValue(Info) 807 * 808 * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like 809 * "void *ParentOp"? 810 */ 811 Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op; 812 813 Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 814 return_ACPI_STATUS (Status); 815 } 816 817 818 /******************************************************************************* 819 * 820 * FUNCTION: AcpiDsCreateIndexField 821 * 822 * PARAMETERS: Op - Op containing the Field definition and args 823 * RegionNode - Object for the containing Operation Region 824 * ` WalkState - Current method state 825 * 826 * RETURN: Status 827 * 828 * DESCRIPTION: Create a new index field in the specified operation region 829 * 830 ******************************************************************************/ 831 832 ACPI_STATUS 833 AcpiDsCreateIndexField ( 834 ACPI_PARSE_OBJECT *Op, 835 ACPI_NAMESPACE_NODE *RegionNode, 836 ACPI_WALK_STATE *WalkState) 837 { 838 ACPI_STATUS Status; 839 ACPI_PARSE_OBJECT *Arg; 840 ACPI_CREATE_FIELD_INFO Info; 841 842 843 ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op); 844 845 846 /* First arg is the name of the Index register (must already exist) */ 847 848 Arg = Op->Common.Value.Arg; 849 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 850 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 851 ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode); 852 if (ACPI_FAILURE (Status)) 853 { 854 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, 855 Arg->Common.Value.String, Status); 856 return_ACPI_STATUS (Status); 857 } 858 859 /* Second arg is the data register (must already exist) */ 860 861 Arg = Arg->Common.Next; 862 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 863 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 864 ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode); 865 if (ACPI_FAILURE (Status)) 866 { 867 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, 868 Arg->Common.Value.String, Status); 869 return_ACPI_STATUS (Status); 870 } 871 872 /* Next arg is the field flags */ 873 874 Arg = Arg->Common.Next; 875 Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 876 877 /* Each remaining arg is a Named Field */ 878 879 Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD; 880 Info.RegionNode = RegionNode; 881 882 Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 883 return_ACPI_STATUS (Status); 884 } 885