xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/dispatcher/dsfield.c (revision 529cd177b573aaba391c8adc9c9f5ad76a14bf81)
1 /******************************************************************************
2  *
3  * Module Name: dsfield - Dispatcher field routines
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2014, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115 
116 #define __DSFIELD_C__
117 
118 #include "acpi.h"
119 #include "accommon.h"
120 #include "amlcode.h"
121 #include "acdispat.h"
122 #include "acinterp.h"
123 #include "acnamesp.h"
124 #include "acparser.h"
125 
126 
127 #define _COMPONENT          ACPI_DISPATCHER
128         ACPI_MODULE_NAME    ("dsfield")
129 
130 /* Local prototypes */
131 
132 #ifdef ACPI_ASL_COMPILER
133 #include "acdisasm.h"
134 
135 static ACPI_STATUS
136 AcpiDsCreateExternalRegion (
137     ACPI_STATUS             LookupStatus,
138     ACPI_PARSE_OBJECT       *Op,
139     char                    *Path,
140     ACPI_WALK_STATE         *WalkState,
141     ACPI_NAMESPACE_NODE     **Node);
142 #endif
143 
144 static ACPI_STATUS
145 AcpiDsGetFieldNames (
146     ACPI_CREATE_FIELD_INFO  *Info,
147     ACPI_WALK_STATE         *WalkState,
148     ACPI_PARSE_OBJECT       *Arg);
149 
150 
151 #ifdef ACPI_ASL_COMPILER
152 /*******************************************************************************
153  *
154  * FUNCTION:    AcpiDsCreateExternalRegion (iASL Disassembler only)
155  *
156  * PARAMETERS:  LookupStatus    - Status from NsLookup operation
157  *              Op              - Op containing the Field definition and args
158  *              Path            - Pathname of the region
159  *  `           WalkState       - Current method state
160  *              Node            - Where the new region node is returned
161  *
162  * RETURN:      Status
163  *
164  * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
165  *              region node/object.
166  *
167  ******************************************************************************/
168 
169 static ACPI_STATUS
170 AcpiDsCreateExternalRegion (
171     ACPI_STATUS             LookupStatus,
172     ACPI_PARSE_OBJECT       *Op,
173     char                    *Path,
174     ACPI_WALK_STATE         *WalkState,
175     ACPI_NAMESPACE_NODE     **Node)
176 {
177     ACPI_STATUS             Status;
178     ACPI_OPERAND_OBJECT     *ObjDesc;
179 
180 
181     if (LookupStatus != AE_NOT_FOUND)
182     {
183         return (LookupStatus);
184     }
185 
186     /*
187      * Table disassembly:
188      * OperationRegion not found. Generate an External for it, and
189      * insert the name into the namespace.
190      */
191     AcpiDmAddOpToExternalList (Op, Path, ACPI_TYPE_REGION, 0, 0);
192     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_REGION,
193        ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, WalkState, Node);
194     if (ACPI_FAILURE (Status))
195     {
196         return (Status);
197     }
198 
199     /* Must create and install a region object for the new node */
200 
201     ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
202     if (!ObjDesc)
203     {
204         return (AE_NO_MEMORY);
205     }
206 
207     ObjDesc->Region.Node = *Node;
208     Status = AcpiNsAttachObject (*Node, ObjDesc, ACPI_TYPE_REGION);
209     return (Status);
210 }
211 #endif
212 
213 
214 /*******************************************************************************
215  *
216  * FUNCTION:    AcpiDsCreateBufferField
217  *
218  * PARAMETERS:  Op                  - Current parse op (CreateXXField)
219  *              WalkState           - Current state
220  *
221  * RETURN:      Status
222  *
223  * DESCRIPTION: Execute the CreateField operators:
224  *              CreateBitFieldOp,
225  *              CreateByteFieldOp,
226  *              CreateWordFieldOp,
227  *              CreateDwordFieldOp,
228  *              CreateQwordFieldOp,
229  *              CreateFieldOp       (all of which define a field in a buffer)
230  *
231  ******************************************************************************/
232 
233 ACPI_STATUS
234 AcpiDsCreateBufferField (
235     ACPI_PARSE_OBJECT       *Op,
236     ACPI_WALK_STATE         *WalkState)
237 {
238     ACPI_PARSE_OBJECT       *Arg;
239     ACPI_NAMESPACE_NODE     *Node;
240     ACPI_STATUS             Status;
241     ACPI_OPERAND_OBJECT     *ObjDesc;
242     ACPI_OPERAND_OBJECT     *SecondDesc = NULL;
243     UINT32                  Flags;
244 
245 
246     ACPI_FUNCTION_TRACE (DsCreateBufferField);
247 
248 
249     /*
250      * Get the NameString argument (name of the new BufferField)
251      */
252     if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
253     {
254         /* For CreateField, name is the 4th argument */
255 
256         Arg = AcpiPsGetArg (Op, 3);
257     }
258     else
259     {
260         /* For all other CreateXXXField operators, name is the 3rd argument */
261 
262         Arg = AcpiPsGetArg (Op, 2);
263     }
264 
265     if (!Arg)
266     {
267         return_ACPI_STATUS (AE_AML_NO_OPERAND);
268     }
269 
270     if (WalkState->DeferredNode)
271     {
272         Node = WalkState->DeferredNode;
273         Status = AE_OK;
274     }
275     else
276     {
277         /* Execute flag should always be set when this function is entered */
278 
279         if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
280         {
281             return_ACPI_STATUS (AE_AML_INTERNAL);
282         }
283 
284         /* Creating new namespace node, should not already exist */
285 
286         Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
287                 ACPI_NS_ERROR_IF_FOUND;
288 
289         /*
290          * Mark node temporary if we are executing a normal control
291          * method. (Don't mark if this is a module-level code method)
292          */
293         if (WalkState->MethodNode &&
294             !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
295         {
296             Flags |= ACPI_NS_TEMPORARY;
297         }
298 
299         /* Enter the NameString into the namespace */
300 
301         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
302                     ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
303                     Flags, WalkState, &Node);
304         if (ACPI_FAILURE (Status))
305         {
306             ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
307             return_ACPI_STATUS (Status);
308         }
309     }
310 
311     /*
312      * We could put the returned object (Node) on the object stack for later,
313      * but for now, we will put it in the "op" object that the parser uses,
314      * so we can get it again at the end of this scope.
315      */
316     Op->Common.Node = Node;
317 
318     /*
319      * If there is no object attached to the node, this node was just created
320      * and we need to create the field object. Otherwise, this was a lookup
321      * of an existing node and we don't want to create the field object again.
322      */
323     ObjDesc = AcpiNsGetAttachedObject (Node);
324     if (ObjDesc)
325     {
326         return_ACPI_STATUS (AE_OK);
327     }
328 
329     /*
330      * The Field definition is not fully parsed at this time.
331      * (We must save the address of the AML for the buffer and index operands)
332      */
333 
334     /* Create the buffer field object */
335 
336     ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD);
337     if (!ObjDesc)
338     {
339         Status = AE_NO_MEMORY;
340         goto Cleanup;
341     }
342 
343     /*
344      * Remember location in AML stream of the field unit opcode and operands --
345      * since the buffer and index operands must be evaluated.
346      */
347     SecondDesc                  = ObjDesc->Common.NextObject;
348     SecondDesc->Extra.AmlStart  = Op->Named.Data;
349     SecondDesc->Extra.AmlLength = Op->Named.Length;
350     ObjDesc->BufferField.Node   = Node;
351 
352     /* Attach constructed field descriptors to parent node */
353 
354     Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD);
355     if (ACPI_FAILURE (Status))
356     {
357         goto Cleanup;
358     }
359 
360 
361 Cleanup:
362 
363     /* Remove local reference to the object */
364 
365     AcpiUtRemoveReference (ObjDesc);
366     return_ACPI_STATUS (Status);
367 }
368 
369 
370 /*******************************************************************************
371  *
372  * FUNCTION:    AcpiDsGetFieldNames
373  *
374  * PARAMETERS:  Info            - CreateField info structure
375  *  `           WalkState       - Current method state
376  *              Arg             - First parser arg for the field name list
377  *
378  * RETURN:      Status
379  *
380  * DESCRIPTION: Process all named fields in a field declaration. Names are
381  *              entered into the namespace.
382  *
383  ******************************************************************************/
384 
385 static ACPI_STATUS
386 AcpiDsGetFieldNames (
387     ACPI_CREATE_FIELD_INFO  *Info,
388     ACPI_WALK_STATE         *WalkState,
389     ACPI_PARSE_OBJECT       *Arg)
390 {
391     ACPI_STATUS             Status;
392     UINT64                  Position;
393     ACPI_PARSE_OBJECT       *Child;
394 
395 
396     ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info);
397 
398 
399     /* First field starts at bit zero */
400 
401     Info->FieldBitPosition = 0;
402 
403     /* Process all elements in the field list (of parse nodes) */
404 
405     while (Arg)
406     {
407         /*
408          * Four types of field elements are handled:
409          * 1) Name - Enters a new named field into the namespace
410          * 2) Offset - specifies a bit offset
411          * 3) AccessAs - changes the access mode/attributes
412          * 4) Connection - Associate a resource template with the field
413          */
414         switch (Arg->Common.AmlOpcode)
415         {
416         case AML_INT_RESERVEDFIELD_OP:
417 
418             Position = (UINT64) Info->FieldBitPosition
419                         + (UINT64) Arg->Common.Value.Size;
420 
421             if (Position > ACPI_UINT32_MAX)
422             {
423                 ACPI_ERROR ((AE_INFO,
424                     "Bit offset within field too large (> 0xFFFFFFFF)"));
425                 return_ACPI_STATUS (AE_SUPPORT);
426             }
427 
428             Info->FieldBitPosition = (UINT32) Position;
429             break;
430 
431         case AML_INT_ACCESSFIELD_OP:
432         case AML_INT_EXTACCESSFIELD_OP:
433             /*
434              * Get new AccessType, AccessAttribute, and AccessLength fields
435              * -- to be used for all field units that follow, until the
436              * end-of-field or another AccessAs keyword is encountered.
437              * NOTE. These three bytes are encoded in the integer value
438              * of the parseop for convenience.
439              *
440              * In FieldFlags, preserve the flag bits other than the
441              * ACCESS_TYPE bits.
442              */
443 
444             /* AccessType (ByteAcc, WordAcc, etc.) */
445 
446             Info->FieldFlags = (UINT8)
447                 ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
448                 ((UINT8) ((UINT32) (Arg->Common.Value.Integer & 0x07))));
449 
450             /* AccessAttribute (AttribQuick, AttribByte, etc.) */
451 
452             Info->Attribute = (UINT8) ((Arg->Common.Value.Integer >> 8) & 0xFF);
453 
454             /* AccessLength (for serial/buffer protocols) */
455 
456             Info->AccessLength = (UINT8) ((Arg->Common.Value.Integer >> 16) & 0xFF);
457             break;
458 
459         case AML_INT_CONNECTION_OP:
460             /*
461              * Clear any previous connection. New connection is used for all
462              * fields that follow, similar to AccessAs
463              */
464             Info->ResourceBuffer = NULL;
465             Info->ConnectionNode = NULL;
466 
467             /*
468              * A Connection() is either an actual resource descriptor (buffer)
469              * or a named reference to a resource template
470              */
471             Child = Arg->Common.Value.Arg;
472             if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
473             {
474                 Info->ResourceBuffer = Child->Named.Data;
475                 Info->ResourceLength = (UINT16) Child->Named.Value.Integer;
476             }
477             else
478             {
479                 /* Lookup the Connection() namepath, it should already exist */
480 
481                 Status = AcpiNsLookup (WalkState->ScopeInfo,
482                             Child->Common.Value.Name, ACPI_TYPE_ANY,
483                             ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
484                             WalkState, &Info->ConnectionNode);
485                 if (ACPI_FAILURE (Status))
486                 {
487                     ACPI_ERROR_NAMESPACE (Child->Common.Value.Name, Status);
488                     return_ACPI_STATUS (Status);
489                 }
490             }
491             break;
492 
493         case AML_INT_NAMEDFIELD_OP:
494 
495             /* Lookup the name, it should already exist */
496 
497             Status = AcpiNsLookup (WalkState->ScopeInfo,
498                         (char *) &Arg->Named.Name, Info->FieldType,
499                         ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
500                         WalkState, &Info->FieldNode);
501             if (ACPI_FAILURE (Status))
502             {
503                 ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
504                 return_ACPI_STATUS (Status);
505             }
506             else
507             {
508                 Arg->Common.Node = Info->FieldNode;
509                 Info->FieldBitLength = Arg->Common.Value.Size;
510 
511                 /*
512                  * If there is no object attached to the node, this node was
513                  * just created and we need to create the field object.
514                  * Otherwise, this was a lookup of an existing node and we
515                  * don't want to create the field object again.
516                  */
517                 if (!AcpiNsGetAttachedObject (Info->FieldNode))
518                 {
519                     Status = AcpiExPrepFieldValue (Info);
520                     if (ACPI_FAILURE (Status))
521                     {
522                         return_ACPI_STATUS (Status);
523                     }
524                 }
525             }
526 
527             /* Keep track of bit position for the next field */
528 
529             Position = (UINT64) Info->FieldBitPosition
530                         + (UINT64) Arg->Common.Value.Size;
531 
532             if (Position > ACPI_UINT32_MAX)
533             {
534                 ACPI_ERROR ((AE_INFO,
535                     "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
536                     ACPI_CAST_PTR (char, &Info->FieldNode->Name)));
537                 return_ACPI_STATUS (AE_SUPPORT);
538             }
539 
540             Info->FieldBitPosition += Info->FieldBitLength;
541             break;
542 
543         default:
544 
545             ACPI_ERROR ((AE_INFO,
546                 "Invalid opcode in field list: 0x%X", Arg->Common.AmlOpcode));
547             return_ACPI_STATUS (AE_AML_BAD_OPCODE);
548         }
549 
550         Arg = Arg->Common.Next;
551     }
552 
553     return_ACPI_STATUS (AE_OK);
554 }
555 
556 
557 /*******************************************************************************
558  *
559  * FUNCTION:    AcpiDsCreateField
560  *
561  * PARAMETERS:  Op              - Op containing the Field definition and args
562  *              RegionNode      - Object for the containing Operation Region
563  *  `           WalkState       - Current method state
564  *
565  * RETURN:      Status
566  *
567  * DESCRIPTION: Create a new field in the specified operation region
568  *
569  ******************************************************************************/
570 
571 ACPI_STATUS
572 AcpiDsCreateField (
573     ACPI_PARSE_OBJECT       *Op,
574     ACPI_NAMESPACE_NODE     *RegionNode,
575     ACPI_WALK_STATE         *WalkState)
576 {
577     ACPI_STATUS             Status;
578     ACPI_PARSE_OBJECT       *Arg;
579     ACPI_CREATE_FIELD_INFO  Info;
580 
581 
582     ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op);
583 
584 
585     /* First arg is the name of the parent OpRegion (must already exist) */
586 
587     Arg = Op->Common.Value.Arg;
588 
589     if (!RegionNode)
590     {
591         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
592                         ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
593                         ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
594 #ifdef ACPI_ASL_COMPILER
595         Status = AcpiDsCreateExternalRegion (Status, Arg,
596             Arg->Common.Value.Name, WalkState, &RegionNode);
597 #endif
598         if (ACPI_FAILURE (Status))
599         {
600             ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
601             return_ACPI_STATUS (Status);
602         }
603     }
604 
605     ACPI_MEMSET (&Info, 0, sizeof (ACPI_CREATE_FIELD_INFO));
606 
607     /* Second arg is the field flags */
608 
609     Arg = Arg->Common.Next;
610     Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
611     Info.Attribute = 0;
612 
613     /* Each remaining arg is a Named Field */
614 
615     Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD;
616     Info.RegionNode = RegionNode;
617 
618     Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
619     return_ACPI_STATUS (Status);
620 }
621 
622 
623 /*******************************************************************************
624  *
625  * FUNCTION:    AcpiDsInitFieldObjects
626  *
627  * PARAMETERS:  Op              - Op containing the Field definition and args
628  *  `           WalkState       - Current method state
629  *
630  * RETURN:      Status
631  *
632  * DESCRIPTION: For each "Field Unit" name in the argument list that is
633  *              part of the field declaration, enter the name into the
634  *              namespace.
635  *
636  ******************************************************************************/
637 
638 ACPI_STATUS
639 AcpiDsInitFieldObjects (
640     ACPI_PARSE_OBJECT       *Op,
641     ACPI_WALK_STATE         *WalkState)
642 {
643     ACPI_STATUS             Status;
644     ACPI_PARSE_OBJECT       *Arg = NULL;
645     ACPI_NAMESPACE_NODE     *Node;
646     UINT8                   Type = 0;
647     UINT32                  Flags;
648 
649 
650     ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op);
651 
652 
653     /* Execute flag should always be set when this function is entered */
654 
655     if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
656     {
657         if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP)
658         {
659             /* BankField Op is deferred, just return OK */
660 
661             return_ACPI_STATUS (AE_OK);
662         }
663 
664         return_ACPI_STATUS (AE_AML_INTERNAL);
665     }
666 
667     /*
668      * Get the FieldList argument for this opcode. This is the start of the
669      * list of field elements.
670      */
671     switch (WalkState->Opcode)
672     {
673     case AML_FIELD_OP:
674 
675         Arg = AcpiPsGetArg (Op, 2);
676         Type = ACPI_TYPE_LOCAL_REGION_FIELD;
677         break;
678 
679     case AML_BANK_FIELD_OP:
680 
681         Arg = AcpiPsGetArg (Op, 4);
682         Type = ACPI_TYPE_LOCAL_BANK_FIELD;
683         break;
684 
685     case AML_INDEX_FIELD_OP:
686 
687         Arg = AcpiPsGetArg (Op, 3);
688         Type = ACPI_TYPE_LOCAL_INDEX_FIELD;
689         break;
690 
691     default:
692 
693         return_ACPI_STATUS (AE_BAD_PARAMETER);
694     }
695 
696     /* Creating new namespace node(s), should not already exist */
697 
698     Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
699             ACPI_NS_ERROR_IF_FOUND;
700 
701     /*
702      * Mark node(s) temporary if we are executing a normal control
703      * method. (Don't mark if this is a module-level code method)
704      */
705     if (WalkState->MethodNode &&
706         !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
707     {
708         Flags |= ACPI_NS_TEMPORARY;
709     }
710 
711     /*
712      * Walk the list of entries in the FieldList
713      * Note: FieldList can be of zero length. In this case, Arg will be NULL.
714      */
715     while (Arg)
716     {
717         /*
718          * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
719          * in the field names in order to enter them into the namespace.
720          */
721         if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
722         {
723             Status = AcpiNsLookup (WalkState->ScopeInfo,
724                         (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1,
725                         Flags, WalkState, &Node);
726             if (ACPI_FAILURE (Status))
727             {
728                 ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
729                 if (Status != AE_ALREADY_EXISTS)
730                 {
731                     return_ACPI_STATUS (Status);
732                 }
733 
734                 /* Name already exists, just ignore this error */
735 
736                 Status = AE_OK;
737             }
738 
739             Arg->Common.Node = Node;
740         }
741 
742         /* Get the next field element in the list */
743 
744         Arg = Arg->Common.Next;
745     }
746 
747     return_ACPI_STATUS (AE_OK);
748 }
749 
750 
751 /*******************************************************************************
752  *
753  * FUNCTION:    AcpiDsCreateBankField
754  *
755  * PARAMETERS:  Op              - Op containing the Field definition and args
756  *              RegionNode      - Object for the containing Operation Region
757  *              WalkState       - Current method state
758  *
759  * RETURN:      Status
760  *
761  * DESCRIPTION: Create a new bank field in the specified operation region
762  *
763  ******************************************************************************/
764 
765 ACPI_STATUS
766 AcpiDsCreateBankField (
767     ACPI_PARSE_OBJECT       *Op,
768     ACPI_NAMESPACE_NODE     *RegionNode,
769     ACPI_WALK_STATE         *WalkState)
770 {
771     ACPI_STATUS             Status;
772     ACPI_PARSE_OBJECT       *Arg;
773     ACPI_CREATE_FIELD_INFO  Info;
774 
775 
776     ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op);
777 
778 
779     /* First arg is the name of the parent OpRegion (must already exist) */
780 
781     Arg = Op->Common.Value.Arg;
782     if (!RegionNode)
783     {
784         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
785                         ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
786                         ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
787 #ifdef ACPI_ASL_COMPILER
788         Status = AcpiDsCreateExternalRegion (Status, Arg,
789             Arg->Common.Value.Name, WalkState, &RegionNode);
790 #endif
791         if (ACPI_FAILURE (Status))
792         {
793             ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
794             return_ACPI_STATUS (Status);
795         }
796     }
797 
798     /* Second arg is the Bank Register (Field) (must already exist) */
799 
800     Arg = Arg->Common.Next;
801     Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
802                     ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
803                     ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
804     if (ACPI_FAILURE (Status))
805     {
806         ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
807         return_ACPI_STATUS (Status);
808     }
809 
810     /*
811      * Third arg is the BankValue
812      * This arg is a TermArg, not a constant
813      * It will be evaluated later, by AcpiDsEvalBankFieldOperands
814      */
815     Arg = Arg->Common.Next;
816 
817     /* Fourth arg is the field flags */
818 
819     Arg = Arg->Common.Next;
820     Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
821 
822     /* Each remaining arg is a Named Field */
823 
824     Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD;
825     Info.RegionNode = RegionNode;
826 
827     /*
828      * Use Info.DataRegisterNode to store BankField Op
829      * It's safe because DataRegisterNode will never be used when create bank field
830      * We store AmlStart and AmlLength in the BankField Op for late evaluation
831      * Used in AcpiExPrepFieldValue(Info)
832      *
833      * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like "void *ParentOp"?
834      */
835     Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op;
836 
837     Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
838     return_ACPI_STATUS (Status);
839 }
840 
841 
842 /*******************************************************************************
843  *
844  * FUNCTION:    AcpiDsCreateIndexField
845  *
846  * PARAMETERS:  Op              - Op containing the Field definition and args
847  *              RegionNode      - Object for the containing Operation Region
848  *  `           WalkState       - Current method state
849  *
850  * RETURN:      Status
851  *
852  * DESCRIPTION: Create a new index field in the specified operation region
853  *
854  ******************************************************************************/
855 
856 ACPI_STATUS
857 AcpiDsCreateIndexField (
858     ACPI_PARSE_OBJECT       *Op,
859     ACPI_NAMESPACE_NODE     *RegionNode,
860     ACPI_WALK_STATE         *WalkState)
861 {
862     ACPI_STATUS             Status;
863     ACPI_PARSE_OBJECT       *Arg;
864     ACPI_CREATE_FIELD_INFO  Info;
865 
866 
867     ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op);
868 
869 
870     /* First arg is the name of the Index register (must already exist) */
871 
872     Arg = Op->Common.Value.Arg;
873     Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
874                     ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
875                     ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
876     if (ACPI_FAILURE (Status))
877     {
878         ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
879         return_ACPI_STATUS (Status);
880     }
881 
882     /* Second arg is the data register (must already exist) */
883 
884     Arg = Arg->Common.Next;
885     Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
886                     ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
887                     ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode);
888     if (ACPI_FAILURE (Status))
889     {
890         ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
891         return_ACPI_STATUS (Status);
892     }
893 
894     /* Next arg is the field flags */
895 
896     Arg = Arg->Common.Next;
897     Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
898 
899     /* Each remaining arg is a Named Field */
900 
901     Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD;
902     Info.RegionNode = RegionNode;
903 
904     Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
905     return_ACPI_STATUS (Status);
906 }
907