1 /******************************************************************************
   2  *
   3  * Module Name: dsfield - Dispatcher field routines
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, 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 "acpi.h"
  47 #include "accommon.h"
  48 #include "amlcode.h"
  49 #include "acdispat.h"
  50 #include "acinterp.h"
  51 #include "acnamesp.h"
  52 #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 
 247 
 248     ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info);
 249 
 250 
 251     /* First field starts at bit zero */
 252 
 253     Info->FieldBitPosition = 0;
 254 
 255     /* Process all elements in the field list (of parse nodes) */
 256 
 257     while (Arg)
 258     {
 259         /*
 260          * Three types of field elements are handled:
 261          * 1) Offset - specifies a bit offset
 262          * 2) AccessAs - changes the access mode
 263          * 3) Name - Enters a new named field into the namespace
 264          */
 265         switch (Arg->Common.AmlOpcode)
 266         {
 267         case AML_INT_RESERVEDFIELD_OP:
 268 
 269             Position = (UINT64) Info->FieldBitPosition
 270                         + (UINT64) Arg->Common.Value.Size;
 271 
 272             if (Position > ACPI_UINT32_MAX)
 273             {
 274                 ACPI_ERROR ((AE_INFO,
 275                     "Bit offset within field too large (> 0xFFFFFFFF)"));
 276                 return_ACPI_STATUS (AE_SUPPORT);
 277             }
 278 
 279             Info->FieldBitPosition = (UINT32) Position;
 280             break;
 281 
 282 
 283         case AML_INT_ACCESSFIELD_OP:
 284 
 285             /*
 286              * Get a new AccessType and AccessAttribute -- to be used for all
 287              * field units that follow, until field end or another AccessAs
 288              * keyword.
 289              *
 290              * In FieldFlags, preserve the flag bits other than the
 291              * ACCESS_TYPE bits
 292              */
 293             Info->FieldFlags = (UINT8)
 294                 ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
 295                 ((UINT8) ((UINT32) Arg->Common.Value.Integer >> 8)));
 296 
 297             Info->Attribute = (UINT8) (Arg->Common.Value.Integer);
 298             break;
 299 
 300 
 301         case AML_INT_NAMEDFIELD_OP:
 302 
 303             /* Lookup the name, it should already exist */
 304 
 305             Status = AcpiNsLookup (WalkState->ScopeInfo,
 306                         (char *) &Arg->Named.Name, Info->FieldType,
 307                         ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
 308                         WalkState, &Info->FieldNode);
 309             if (ACPI_FAILURE (Status))
 310             {
 311                 ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
 312                 return_ACPI_STATUS (Status);
 313             }
 314             else
 315             {
 316                 Arg->Common.Node = Info->FieldNode;
 317                 Info->FieldBitLength = Arg->Common.Value.Size;
 318 
 319                 /*
 320                  * If there is no object attached to the node, this node was
 321                  * just created and we need to create the field object.
 322                  * Otherwise, this was a lookup of an existing node and we
 323                  * don't want to create the field object again.
 324                  */
 325                 if (!AcpiNsGetAttachedObject (Info->FieldNode))
 326                 {
 327                     Status = AcpiExPrepFieldValue (Info);
 328                     if (ACPI_FAILURE (Status))
 329                     {
 330                         return_ACPI_STATUS (Status);
 331                     }
 332                 }
 333             }
 334 
 335             /* Keep track of bit position for the next field */
 336 
 337             Position = (UINT64) Info->FieldBitPosition
 338                         + (UINT64) Arg->Common.Value.Size;
 339 
 340             if (Position > ACPI_UINT32_MAX)
 341             {
 342                 ACPI_ERROR ((AE_INFO,
 343                     "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
 344                     ACPI_CAST_PTR (char, &Info->FieldNode->Name)));
 345                 return_ACPI_STATUS (AE_SUPPORT);
 346             }
 347 
 348             Info->FieldBitPosition += Info->FieldBitLength;
 349             break;
 350 
 351 
 352         default:
 353 
 354             ACPI_ERROR ((AE_INFO,
 355                 "Invalid opcode in field list: 0x%X", Arg->Common.AmlOpcode));
 356             return_ACPI_STATUS (AE_AML_BAD_OPCODE);
 357         }
 358 
 359         Arg = Arg->Common.Next;
 360     }
 361 
 362     return_ACPI_STATUS (AE_OK);
 363 }
 364 
 365 
 366 /*******************************************************************************
 367  *
 368  * FUNCTION:    AcpiDsCreateField
 369  *
 370  * PARAMETERS:  Op              - Op containing the Field definition and args
 371  *              RegionNode      - Object for the containing Operation Region
 372  *  `           WalkState       - Current method state
 373  *
 374  * RETURN:      Status
 375  *
 376  * DESCRIPTION: Create a new field in the specified operation region
 377  *
 378  ******************************************************************************/
 379 
 380 ACPI_STATUS
 381 AcpiDsCreateField (
 382     ACPI_PARSE_OBJECT       *Op,
 383     ACPI_NAMESPACE_NODE     *RegionNode,
 384     ACPI_WALK_STATE         *WalkState)
 385 {
 386     ACPI_STATUS             Status;
 387     ACPI_PARSE_OBJECT       *Arg;
 388     ACPI_CREATE_FIELD_INFO  Info;
 389 
 390 
 391     ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op);
 392 
 393 
 394     /* First arg is the name of the parent OpRegion (must already exist) */
 395 
 396     Arg = Op->Common.Value.Arg;
 397     if (!RegionNode)
 398     {
 399         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
 400                         ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
 401                         ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
 402         if (ACPI_FAILURE (Status))
 403         {
 404             ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
 405             return_ACPI_STATUS (Status);
 406         }
 407     }
 408 
 409     /* Second arg is the field flags */
 410 
 411     Arg = Arg->Common.Next;
 412     Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
 413     Info.Attribute = 0;
 414 
 415     /* Each remaining arg is a Named Field */
 416 
 417     Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD;
 418     Info.RegionNode = RegionNode;
 419 
 420     Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
 421 
 422     return_ACPI_STATUS (Status);
 423 }
 424 
 425 
 426 /*******************************************************************************
 427  *
 428  * FUNCTION:    AcpiDsInitFieldObjects
 429  *
 430  * PARAMETERS:  Op              - Op containing the Field definition and args
 431  *  `           WalkState       - Current method state
 432  *
 433  * RETURN:      Status
 434  *
 435  * DESCRIPTION: For each "Field Unit" name in the argument list that is
 436  *              part of the field declaration, enter the name into the
 437  *              namespace.
 438  *
 439  ******************************************************************************/
 440 
 441 ACPI_STATUS
 442 AcpiDsInitFieldObjects (
 443     ACPI_PARSE_OBJECT       *Op,
 444     ACPI_WALK_STATE         *WalkState)
 445 {
 446     ACPI_STATUS             Status;
 447     ACPI_PARSE_OBJECT       *Arg = NULL;
 448     ACPI_NAMESPACE_NODE     *Node;
 449     UINT8                   Type = 0;
 450     UINT32                  Flags;
 451 
 452 
 453     ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op);
 454 
 455 
 456     /* Execute flag should always be set when this function is entered */
 457 
 458     if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
 459     {
 460         if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP)
 461         {
 462             /* BankField Op is deferred, just return OK */
 463 
 464             return_ACPI_STATUS (AE_OK);
 465         }
 466 
 467         return_ACPI_STATUS (AE_AML_INTERNAL);
 468     }
 469 
 470     /*
 471      * Get the FieldList argument for this opcode. This is the start of the
 472      * list of field elements.
 473      */
 474     switch (WalkState->Opcode)
 475     {
 476     case AML_FIELD_OP:
 477         Arg = AcpiPsGetArg (Op, 2);
 478         Type = ACPI_TYPE_LOCAL_REGION_FIELD;
 479         break;
 480 
 481     case AML_BANK_FIELD_OP:
 482         Arg = AcpiPsGetArg (Op, 4);
 483         Type = ACPI_TYPE_LOCAL_BANK_FIELD;
 484         break;
 485 
 486     case AML_INDEX_FIELD_OP:
 487         Arg = AcpiPsGetArg (Op, 3);
 488         Type = ACPI_TYPE_LOCAL_INDEX_FIELD;
 489         break;
 490 
 491     default:
 492         return_ACPI_STATUS (AE_BAD_PARAMETER);
 493     }
 494 
 495     /* Creating new namespace node(s), should not already exist */
 496 
 497     Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
 498             ACPI_NS_ERROR_IF_FOUND;
 499 
 500     /*
 501      * Mark node(s) temporary if we are executing a normal control
 502      * method. (Don't mark if this is a module-level code method)
 503      */
 504     if (WalkState->MethodNode &&
 505         !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
 506     {
 507         Flags |= ACPI_NS_TEMPORARY;
 508     }
 509 
 510     /*
 511      * Walk the list of entries in the FieldList
 512      * Note: FieldList can be of zero length. In this case, Arg will be NULL.
 513      */
 514     while (Arg)
 515     {
 516         /*
 517          * Ignore OFFSET and ACCESSAS terms here; we are only interested in the
 518          * field names in order to enter them into the namespace.
 519          */
 520         if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
 521         {
 522             Status = AcpiNsLookup (WalkState->ScopeInfo,
 523                         (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1,
 524                         Flags, WalkState, &Node);
 525             if (ACPI_FAILURE (Status))
 526             {
 527                 ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
 528                 if (Status != AE_ALREADY_EXISTS)
 529                 {
 530                     return_ACPI_STATUS (Status);
 531                 }
 532 
 533                 /* Name already exists, just ignore this error */
 534 
 535                 Status = AE_OK;
 536             }
 537 
 538             Arg->Common.Node = Node;
 539         }
 540 
 541         /* Get the next field element in the list */
 542 
 543         Arg = Arg->Common.Next;
 544     }
 545 
 546     return_ACPI_STATUS (AE_OK);
 547 }
 548 
 549 
 550 /*******************************************************************************
 551  *
 552  * FUNCTION:    AcpiDsCreateBankField
 553  *
 554  * PARAMETERS:  Op              - Op containing the Field definition and args
 555  *              RegionNode      - Object for the containing Operation Region
 556  *              WalkState       - Current method state
 557  *
 558  * RETURN:      Status
 559  *
 560  * DESCRIPTION: Create a new bank field in the specified operation region
 561  *
 562  ******************************************************************************/
 563 
 564 ACPI_STATUS
 565 AcpiDsCreateBankField (
 566     ACPI_PARSE_OBJECT       *Op,
 567     ACPI_NAMESPACE_NODE     *RegionNode,
 568     ACPI_WALK_STATE         *WalkState)
 569 {
 570     ACPI_STATUS             Status;
 571     ACPI_PARSE_OBJECT       *Arg;
 572     ACPI_CREATE_FIELD_INFO  Info;
 573 
 574 
 575     ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op);
 576 
 577 
 578     /* First arg is the name of the parent OpRegion (must already exist) */
 579 
 580     Arg = Op->Common.Value.Arg;
 581     if (!RegionNode)
 582     {
 583         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
 584                         ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
 585                         ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
 586         if (ACPI_FAILURE (Status))
 587         {
 588             ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
 589             return_ACPI_STATUS (Status);
 590         }
 591     }
 592 
 593     /* Second arg is the Bank Register (Field) (must already exist) */
 594 
 595     Arg = Arg->Common.Next;
 596     Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
 597                     ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
 598                     ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
 599     if (ACPI_FAILURE (Status))
 600     {
 601         ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
 602         return_ACPI_STATUS (Status);
 603     }
 604 
 605     /*
 606      * Third arg is the BankValue
 607      * This arg is a TermArg, not a constant
 608      * It will be evaluated later, by AcpiDsEvalBankFieldOperands
 609      */
 610     Arg = Arg->Common.Next;
 611 
 612     /* Fourth arg is the field flags */
 613 
 614     Arg = Arg->Common.Next;
 615     Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
 616 
 617     /* Each remaining arg is a Named Field */
 618 
 619     Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD;
 620     Info.RegionNode = RegionNode;
 621 
 622     /*
 623      * Use Info.DataRegisterNode to store BankField Op
 624      * It's safe because DataRegisterNode will never be used when create bank field
 625      * We store AmlStart and AmlLength in the BankField Op for late evaluation
 626      * Used in AcpiExPrepFieldValue(Info)
 627      *
 628      * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like "void *ParentOp"?
 629      */
 630     Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op;
 631 
 632     Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
 633     return_ACPI_STATUS (Status);
 634 }
 635 
 636 
 637 /*******************************************************************************
 638  *
 639  * FUNCTION:    AcpiDsCreateIndexField
 640  *
 641  * PARAMETERS:  Op              - Op containing the Field definition and args
 642  *              RegionNode      - Object for the containing Operation Region
 643  *  `           WalkState       - Current method state
 644  *
 645  * RETURN:      Status
 646  *
 647  * DESCRIPTION: Create a new index field in the specified operation region
 648  *
 649  ******************************************************************************/
 650 
 651 ACPI_STATUS
 652 AcpiDsCreateIndexField (
 653     ACPI_PARSE_OBJECT       *Op,
 654     ACPI_NAMESPACE_NODE     *RegionNode,
 655     ACPI_WALK_STATE         *WalkState)
 656 {
 657     ACPI_STATUS             Status;
 658     ACPI_PARSE_OBJECT       *Arg;
 659     ACPI_CREATE_FIELD_INFO  Info;
 660 
 661 
 662     ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op);
 663 
 664 
 665     /* First arg is the name of the Index register (must already exist) */
 666 
 667     Arg = Op->Common.Value.Arg;
 668     Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
 669                     ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
 670                     ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
 671     if (ACPI_FAILURE (Status))
 672     {
 673         ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
 674         return_ACPI_STATUS (Status);
 675     }
 676 
 677     /* Second arg is the data register (must already exist) */
 678 
 679     Arg = Arg->Common.Next;
 680     Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
 681                     ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
 682                     ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode);
 683     if (ACPI_FAILURE (Status))
 684     {
 685         ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
 686         return_ACPI_STATUS (Status);
 687     }
 688 
 689     /* Next arg is the field flags */
 690 
 691     Arg = Arg->Common.Next;
 692     Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
 693 
 694     /* Each remaining arg is a Named Field */
 695 
 696     Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD;
 697     Info.RegionNode = RegionNode;
 698 
 699     Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
 700 
 701     return_ACPI_STATUS (Status);
 702 }
 703 
 704