1 /******************************************************************************
2  *
3  * Module Name: dsfield - Dispatcher field routines
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2020, 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     }
205     else
206     {
207         /* Execute flag should always be set when this function is entered */
208 
209         if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
210         {
211             ACPI_ERROR ((AE_INFO,
212                 "Parse execute mode is not set"));
213             return_ACPI_STATUS (AE_AML_INTERNAL);
214         }
215 
216         /* Creating new namespace node, should not already exist */
217 
218         Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
219             ACPI_NS_ERROR_IF_FOUND;
220 
221         /*
222          * Mark node temporary if we are executing a normal control
223          * method. (Don't mark if this is a module-level code method)
224          */
225         if (WalkState->MethodNode &&
226             !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
227         {
228             Flags |= ACPI_NS_TEMPORARY;
229         }
230 
231         /* Enter the NameString into the namespace */
232 
233         Status = AcpiNsLookup (WalkState->ScopeInfo,
234             Arg->Common.Value.String, ACPI_TYPE_ANY,
235             ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
236         if (ACPI_FAILURE (Status))
237         {
238             ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
239                 Arg->Common.Value.String, Status);
240             return_ACPI_STATUS (Status);
241         }
242     }
243 
244     /*
245      * We could put the returned object (Node) on the object stack for later,
246      * but for now, we will put it in the "op" object that the parser uses,
247      * so we can get it again at the end of this scope.
248      */
249     Op->Common.Node = Node;
250 
251     /*
252      * If there is no object attached to the node, this node was just created
253      * and we need to create the field object. Otherwise, this was a lookup
254      * of an existing node and we don't want to create the field object again.
255      */
256     ObjDesc = AcpiNsGetAttachedObject (Node);
257     if (ObjDesc)
258     {
259         return_ACPI_STATUS (AE_OK);
260     }
261 
262     /*
263      * The Field definition is not fully parsed at this time.
264      * (We must save the address of the AML for the buffer and index operands)
265      */
266 
267     /* Create the buffer field object */
268 
269     ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD);
270     if (!ObjDesc)
271     {
272         Status = AE_NO_MEMORY;
273         goto Cleanup;
274     }
275 
276     /*
277      * Remember location in AML stream of the field unit opcode and operands
278      * -- since the buffer and index operands must be evaluated.
279      */
280     SecondDesc = ObjDesc->Common.NextObject;
281     SecondDesc->Extra.AmlStart = Op->Named.Data;
282     SecondDesc->Extra.AmlLength = Op->Named.Length;
283     ObjDesc->BufferField.Node = Node;
284 
285     /* Attach constructed field descriptors to parent node */
286 
287     Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD);
288     if (ACPI_FAILURE (Status))
289     {
290         goto Cleanup;
291     }
292 
293 
294 Cleanup:
295 
296     /* Remove local reference to the object */
297 
298     AcpiUtRemoveReference (ObjDesc);
299     return_ACPI_STATUS (Status);
300 }
301 
302 
303 /*******************************************************************************
304  *
305  * FUNCTION:    AcpiDsGetFieldNames
306  *
307  * PARAMETERS:  Info            - CreateField info structure
308  *              WalkState       - Current method state
309  *              Arg             - First parser arg for the field name list
310  *
311  * RETURN:      Status
312  *
313  * DESCRIPTION: Process all named fields in a field declaration. Names are
314  *              entered into the namespace.
315  *
316  ******************************************************************************/
317 
318 static ACPI_STATUS
319 AcpiDsGetFieldNames (
320     ACPI_CREATE_FIELD_INFO  *Info,
321     ACPI_WALK_STATE         *WalkState,
322     ACPI_PARSE_OBJECT       *Arg)
323 {
324     ACPI_STATUS             Status;
325     UINT64                  Position;
326     ACPI_PARSE_OBJECT       *Child;
327 
328 #ifdef ACPI_EXEC_APP
329     ACPI_OPERAND_OBJECT     *ResultDesc;
330     ACPI_OPERAND_OBJECT     *ObjDesc;
331     char                    *NamePath;
332 #endif
333 
334 
335     ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info);
336 
337 
338     /* First field starts at bit zero */
339 
340     Info->FieldBitPosition = 0;
341 
342     /* Process all elements in the field list (of parse nodes) */
343 
344     while (Arg)
345     {
346         /*
347          * Four types of field elements are handled:
348          * 1) Name - Enters a new named field into the namespace
349          * 2) Offset - specifies a bit offset
350          * 3) AccessAs - changes the access mode/attributes
351          * 4) Connection - Associate a resource template with the field
352          */
353         switch (Arg->Common.AmlOpcode)
354         {
355         case AML_INT_RESERVEDFIELD_OP:
356 
357             Position = (UINT64) Info->FieldBitPosition +
358                 (UINT64) Arg->Common.Value.Size;
359 
360             if (Position > ACPI_UINT32_MAX)
361             {
362                 ACPI_ERROR ((AE_INFO,
363                     "Bit offset within field too large (> 0xFFFFFFFF)"));
364                 return_ACPI_STATUS (AE_SUPPORT);
365             }
366 
367             Info->FieldBitPosition = (UINT32) Position;
368             break;
369 
370         case AML_INT_ACCESSFIELD_OP:
371         case AML_INT_EXTACCESSFIELD_OP:
372             /*
373              * Get new AccessType, AccessAttribute, and AccessLength fields
374              * -- to be used for all field units that follow, until the
375              * end-of-field or another AccessAs keyword is encountered.
376              * NOTE. These three bytes are encoded in the integer value
377              * of the parseop for convenience.
378              *
379              * In FieldFlags, preserve the flag bits other than the
380              * ACCESS_TYPE bits.
381              */
382 
383             /* AccessType (ByteAcc, WordAcc, etc.) */
384 
385             Info->FieldFlags = (UINT8)
386                 ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
387                 ((UINT8) ((UINT32) (Arg->Common.Value.Integer & 0x07))));
388 
389             /* AccessAttribute (AttribQuick, AttribByte, etc.) */
390 
391             Info->Attribute = (UINT8)
392                 ((Arg->Common.Value.Integer >> 8) & 0xFF);
393 
394             /* AccessLength (for serial/buffer protocols) */
395 
396             Info->AccessLength = (UINT8)
397                 ((Arg->Common.Value.Integer >> 16) & 0xFF);
398             break;
399 
400         case AML_INT_CONNECTION_OP:
401             /*
402              * Clear any previous connection. New connection is used for all
403              * fields that follow, similar to AccessAs
404              */
405             Info->ResourceBuffer = NULL;
406             Info->ConnectionNode = NULL;
407             Info->PinNumberIndex = 0;
408 
409             /*
410              * A Connection() is either an actual resource descriptor (buffer)
411              * or a named reference to a resource template
412              */
413             Child = Arg->Common.Value.Arg;
414             if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
415             {
416                 Info->ResourceBuffer = Child->Named.Data;
417                 Info->ResourceLength = (UINT16) Child->Named.Value.Integer;
418             }
419             else
420             {
421                 /* Lookup the Connection() namepath, it should already exist */
422 
423                 Status = AcpiNsLookup (WalkState->ScopeInfo,
424                     Child->Common.Value.Name, ACPI_TYPE_ANY,
425                     ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
426                     WalkState, &Info->ConnectionNode);
427                 if (ACPI_FAILURE (Status))
428                 {
429                     ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
430                         Child->Common.Value.Name, Status);
431                     return_ACPI_STATUS (Status);
432                 }
433             }
434             break;
435 
436         case AML_INT_NAMEDFIELD_OP:
437 
438             /* Lookup the name, it should already exist */
439 
440             Status = AcpiNsLookup (WalkState->ScopeInfo,
441                 (char *) &Arg->Named.Name, Info->FieldType,
442                 ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
443                 WalkState, &Info->FieldNode);
444             if (ACPI_FAILURE (Status))
445             {
446                 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
447                     (char *) &Arg->Named.Name, Status);
448                 return_ACPI_STATUS (Status);
449             }
450             else
451             {
452                 Arg->Common.Node = Info->FieldNode;
453                 Info->FieldBitLength = Arg->Common.Value.Size;
454 
455                 /*
456                  * If there is no object attached to the node, this node was
457                  * just created and we need to create the field object.
458                  * Otherwise, this was a lookup of an existing node and we
459                  * don't want to create the field object again.
460                  */
461                 if (!AcpiNsGetAttachedObject (Info->FieldNode))
462                 {
463                     Status = AcpiExPrepFieldValue (Info);
464                     if (ACPI_FAILURE (Status))
465                     {
466                         return_ACPI_STATUS (Status);
467                     }
468 #ifdef ACPI_EXEC_APP
469                     NamePath = AcpiNsGetExternalPathname (Info->FieldNode);
470                     if (ACPI_SUCCESS (AeLookupInitFileEntry (NamePath, &ObjDesc)))
471                     {
472                         AcpiExWriteDataToField (ObjDesc,
473                             AcpiNsGetAttachedObject (Info->FieldNode),
474                             &ResultDesc);
475                         AcpiUtRemoveReference (ObjDesc);
476                     }
477                     ACPI_FREE (NamePath);
478 #endif
479                 }
480             }
481 
482             /* Keep track of bit position for the next field */
483 
484             Position = (UINT64) Info->FieldBitPosition +
485                 (UINT64) Arg->Common.Value.Size;
486 
487             if (Position > ACPI_UINT32_MAX)
488             {
489                 ACPI_ERROR ((AE_INFO,
490                     "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
491                     ACPI_CAST_PTR (char, &Info->FieldNode->Name)));
492                 return_ACPI_STATUS (AE_SUPPORT);
493             }
494 
495             Info->FieldBitPosition += Info->FieldBitLength;
496             Info->PinNumberIndex++; /* Index relative to previous Connection() */
497             break;
498 
499         default:
500 
501             ACPI_ERROR ((AE_INFO,
502                 "Invalid opcode in field list: 0x%X",
503                 Arg->Common.AmlOpcode));
504             return_ACPI_STATUS (AE_AML_BAD_OPCODE);
505         }
506 
507         Arg = Arg->Common.Next;
508     }
509 
510     return_ACPI_STATUS (AE_OK);
511 }
512 
513 
514 /*******************************************************************************
515  *
516  * FUNCTION:    AcpiDsCreateField
517  *
518  * PARAMETERS:  Op              - Op containing the Field definition and args
519  *              RegionNode      - Object for the containing Operation Region
520  *  `           WalkState       - Current method state
521  *
522  * RETURN:      Status
523  *
524  * DESCRIPTION: Create a new field in the specified operation region
525  *
526  ******************************************************************************/
527 
528 ACPI_STATUS
529 AcpiDsCreateField (
530     ACPI_PARSE_OBJECT       *Op,
531     ACPI_NAMESPACE_NODE     *RegionNode,
532     ACPI_WALK_STATE         *WalkState)
533 {
534     ACPI_STATUS             Status;
535     ACPI_PARSE_OBJECT       *Arg;
536     ACPI_CREATE_FIELD_INFO  Info;
537 
538 
539     ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op);
540 
541 
542     /* First arg is the name of the parent OpRegion (must already exist) */
543 
544     Arg = Op->Common.Value.Arg;
545 
546     if (!RegionNode)
547     {
548         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
549             ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
550             ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
551 #ifdef ACPI_ASL_COMPILER
552         Status = AcpiDsCreateExternalRegion (Status, Arg,
553             Arg->Common.Value.Name, WalkState, &RegionNode);
554 #endif
555         if (ACPI_FAILURE (Status))
556         {
557             ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
558                 Arg->Common.Value.Name, Status);
559             return_ACPI_STATUS (Status);
560         }
561     }
562 
563     memset (&Info, 0, sizeof (ACPI_CREATE_FIELD_INFO));
564 
565     /* Second arg is the field flags */
566 
567     Arg = Arg->Common.Next;
568     Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
569     Info.Attribute = 0;
570 
571     /* Each remaining arg is a Named Field */
572 
573     Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD;
574     Info.RegionNode = RegionNode;
575 
576     Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
577     if (Info.RegionNode->Object->Region.SpaceId == ACPI_ADR_SPACE_PLATFORM_COMM &&
578         !(RegionNode->Object->Field.InternalPccBuffer
579         = ACPI_ALLOCATE_ZEROED(Info.RegionNode->Object->Region.Length)))
580     {
581         return_ACPI_STATUS (AE_NO_MEMORY);
582     }
583     return_ACPI_STATUS (Status);
584 }
585 
586 
587 /*******************************************************************************
588  *
589  * FUNCTION:    AcpiDsInitFieldObjects
590  *
591  * PARAMETERS:  Op              - Op containing the Field definition and args
592  *  `           WalkState       - Current method state
593  *
594  * RETURN:      Status
595  *
596  * DESCRIPTION: For each "Field Unit" name in the argument list that is
597  *              part of the field declaration, enter the name into the
598  *              namespace.
599  *
600  ******************************************************************************/
601 
602 ACPI_STATUS
603 AcpiDsInitFieldObjects (
604     ACPI_PARSE_OBJECT       *Op,
605     ACPI_WALK_STATE         *WalkState)
606 {
607     ACPI_STATUS             Status;
608     ACPI_PARSE_OBJECT       *Arg = NULL;
609     ACPI_NAMESPACE_NODE     *Node;
610     UINT8                   Type = 0;
611     UINT32                  Flags;
612 
613 
614     ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op);
615 
616 
617     /* Execute flag should always be set when this function is entered */
618 
619     if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
620     {
621         if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP)
622         {
623             /* BankField Op is deferred, just return OK */
624 
625             return_ACPI_STATUS (AE_OK);
626         }
627 
628         ACPI_ERROR ((AE_INFO,
629             "Parse deferred mode is not set"));
630         return_ACPI_STATUS (AE_AML_INTERNAL);
631     }
632 
633     /*
634      * Get the FieldList argument for this opcode. This is the start of the
635      * list of field elements.
636      */
637     switch (WalkState->Opcode)
638     {
639     case AML_FIELD_OP:
640 
641         Arg = AcpiPsGetArg (Op, 2);
642         Type = ACPI_TYPE_LOCAL_REGION_FIELD;
643         break;
644 
645     case AML_BANK_FIELD_OP:
646 
647         Arg = AcpiPsGetArg (Op, 4);
648         Type = ACPI_TYPE_LOCAL_BANK_FIELD;
649         break;
650 
651     case AML_INDEX_FIELD_OP:
652 
653         Arg = AcpiPsGetArg (Op, 3);
654         Type = ACPI_TYPE_LOCAL_INDEX_FIELD;
655         break;
656 
657     default:
658 
659         return_ACPI_STATUS (AE_BAD_PARAMETER);
660     }
661 
662     /* Creating new namespace node(s), should not already exist */
663 
664     Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
665         ACPI_NS_ERROR_IF_FOUND;
666 
667     /*
668      * Mark node(s) temporary if we are executing a normal control
669      * method. (Don't mark if this is a module-level code method)
670      */
671     if (WalkState->MethodNode &&
672         !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
673     {
674         Flags |= ACPI_NS_TEMPORARY;
675     }
676 
677 #ifdef ACPI_EXEC_APP
678         Flags |= ACPI_NS_OVERRIDE_IF_FOUND;
679 #endif
680     /*
681      * Walk the list of entries in the FieldList
682      * Note: FieldList can be of zero length. In this case, Arg will be NULL.
683      */
684     while (Arg)
685     {
686         /*
687          * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
688          * in the field names in order to enter them into the namespace.
689          */
690         if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
691         {
692             Status = AcpiNsLookup (WalkState->ScopeInfo,
693                 (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1,
694                 Flags, WalkState, &Node);
695             if (ACPI_FAILURE (Status))
696             {
697                 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
698                     (char *) &Arg->Named.Name, Status);
699                 if (Status != AE_ALREADY_EXISTS)
700                 {
701                     return_ACPI_STATUS (Status);
702                 }
703 
704                 /* Name already exists, just ignore this error */
705             }
706 
707             Arg->Common.Node = Node;
708         }
709 
710         /* Get the next field element in the list */
711 
712         Arg = Arg->Common.Next;
713     }
714 
715     return_ACPI_STATUS (AE_OK);
716 }
717 
718 
719 /*******************************************************************************
720  *
721  * FUNCTION:    AcpiDsCreateBankField
722  *
723  * PARAMETERS:  Op              - Op containing the Field definition and args
724  *              RegionNode      - Object for the containing Operation Region
725  *              WalkState       - Current method state
726  *
727  * RETURN:      Status
728  *
729  * DESCRIPTION: Create a new bank field in the specified operation region
730  *
731  ******************************************************************************/
732 
733 ACPI_STATUS
734 AcpiDsCreateBankField (
735     ACPI_PARSE_OBJECT       *Op,
736     ACPI_NAMESPACE_NODE     *RegionNode,
737     ACPI_WALK_STATE         *WalkState)
738 {
739     ACPI_STATUS             Status;
740     ACPI_PARSE_OBJECT       *Arg;
741     ACPI_CREATE_FIELD_INFO  Info;
742 
743 
744     ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op);
745 
746 
747     /* First arg is the name of the parent OpRegion (must already exist) */
748 
749     Arg = Op->Common.Value.Arg;
750     if (!RegionNode)
751     {
752         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
753             ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
754             ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
755 #ifdef ACPI_ASL_COMPILER
756         Status = AcpiDsCreateExternalRegion (Status, Arg,
757             Arg->Common.Value.Name, WalkState, &RegionNode);
758 #endif
759         if (ACPI_FAILURE (Status))
760         {
761             ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
762                 Arg->Common.Value.Name, Status);
763             return_ACPI_STATUS (Status);
764         }
765     }
766 
767     /* Second arg is the Bank Register (Field) (must already exist) */
768 
769     Arg = Arg->Common.Next;
770     Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
771         ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
772         ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
773     if (ACPI_FAILURE (Status))
774     {
775         ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
776             Arg->Common.Value.String, Status);
777         return_ACPI_STATUS (Status);
778     }
779 
780     /*
781      * Third arg is the BankValue
782      * This arg is a TermArg, not a constant
783      * It will be evaluated later, by AcpiDsEvalBankFieldOperands
784      */
785     Arg = Arg->Common.Next;
786 
787     /* Fourth arg is the field flags */
788 
789     Arg = Arg->Common.Next;
790     Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
791 
792     /* Each remaining arg is a Named Field */
793 
794     Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD;
795     Info.RegionNode = RegionNode;
796 
797     /*
798      * Use Info.DataRegisterNode to store BankField Op
799      * It's safe because DataRegisterNode will never be used when create
800      * bank field \we store AmlStart and AmlLength in the BankField Op for
801      * late evaluation. Used in AcpiExPrepFieldValue(Info)
802      *
803      * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like
804      * "void *ParentOp"?
805      */
806     Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op;
807 
808     Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
809     return_ACPI_STATUS (Status);
810 }
811 
812 
813 /*******************************************************************************
814  *
815  * FUNCTION:    AcpiDsCreateIndexField
816  *
817  * PARAMETERS:  Op              - Op containing the Field definition and args
818  *              RegionNode      - Object for the containing Operation Region
819  *  `           WalkState       - Current method state
820  *
821  * RETURN:      Status
822  *
823  * DESCRIPTION: Create a new index field in the specified operation region
824  *
825  ******************************************************************************/
826 
827 ACPI_STATUS
828 AcpiDsCreateIndexField (
829     ACPI_PARSE_OBJECT       *Op,
830     ACPI_NAMESPACE_NODE     *RegionNode,
831     ACPI_WALK_STATE         *WalkState)
832 {
833     ACPI_STATUS             Status;
834     ACPI_PARSE_OBJECT       *Arg;
835     ACPI_CREATE_FIELD_INFO  Info;
836 
837 
838     ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op);
839 
840 
841     /* First arg is the name of the Index register (must already exist) */
842 
843     Arg = Op->Common.Value.Arg;
844     Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
845         ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
846         ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
847     if (ACPI_FAILURE (Status))
848     {
849         ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
850             Arg->Common.Value.String, Status);
851         return_ACPI_STATUS (Status);
852     }
853 
854     /* Second arg is the data register (must already exist) */
855 
856     Arg = Arg->Common.Next;
857     Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
858         ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
859         ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode);
860     if (ACPI_FAILURE (Status))
861     {
862         ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
863             Arg->Common.Value.String, Status);
864         return_ACPI_STATUS (Status);
865     }
866 
867     /* Next arg is the field flags */
868 
869     Arg = Arg->Common.Next;
870     Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
871 
872     /* Each remaining arg is a Named Field */
873 
874     Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD;
875     Info.RegionNode = RegionNode;
876 
877     Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
878     return_ACPI_STATUS (Status);
879 }
880