xref: /freebsd/sys/contrib/dev/acpica/components/dispatcher/dsfield.c (revision 94e3ee44c3581ff37c5e01b5ffe5eb16d30079a7)
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