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