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