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