Merge branch 'vendor/FILE'
[dragonfly.git] / sys / contrib / dev / acpica / source / components / dispatcher / dsfield.c
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 - 2017, 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  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151
152 #include "acpi.h"
153 #include "accommon.h"
154 #include "amlcode.h"
155 #include "acdispat.h"
156 #include "acinterp.h"
157 #include "acnamesp.h"
158 #include "acparser.h"
159
160
161 #define _COMPONENT          ACPI_DISPATCHER
162         ACPI_MODULE_NAME    ("dsfield")
163
164 /* Local prototypes */
165
166 #ifdef ACPI_ASL_COMPILER
167 #include "acdisasm.h"
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 #endif
177
178 static ACPI_STATUS
179 AcpiDsGetFieldNames (
180     ACPI_CREATE_FIELD_INFO  *Info,
181     ACPI_WALK_STATE         *WalkState,
182     ACPI_PARSE_OBJECT       *Arg);
183
184
185 #ifdef ACPI_ASL_COMPILER
186 /*******************************************************************************
187  *
188  * FUNCTION:    AcpiDsCreateExternalRegion (iASL Disassembler only)
189  *
190  * PARAMETERS:  LookupStatus    - Status from NsLookup operation
191  *              Op              - Op containing the Field definition and args
192  *              Path            - Pathname of the region
193  *  `           WalkState       - Current method state
194  *              Node            - Where the new region node is returned
195  *
196  * RETURN:      Status
197  *
198  * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
199  *              region node/object.
200  *
201  ******************************************************************************/
202
203 static ACPI_STATUS
204 AcpiDsCreateExternalRegion (
205     ACPI_STATUS             LookupStatus,
206     ACPI_PARSE_OBJECT       *Op,
207     char                    *Path,
208     ACPI_WALK_STATE         *WalkState,
209     ACPI_NAMESPACE_NODE     **Node)
210 {
211     ACPI_STATUS             Status;
212     ACPI_OPERAND_OBJECT     *ObjDesc;
213
214
215     if (LookupStatus != AE_NOT_FOUND)
216     {
217         return (LookupStatus);
218     }
219
220     /*
221      * Table disassembly:
222      * OperationRegion not found. Generate an External for it, and
223      * insert the name into the namespace.
224      */
225     AcpiDmAddOpToExternalList (Op, Path, ACPI_TYPE_REGION, 0, 0);
226
227     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_REGION,
228        ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, WalkState, Node);
229     if (ACPI_FAILURE (Status))
230     {
231         return (Status);
232     }
233
234     /* Must create and install a region object for the new node */
235
236     ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
237     if (!ObjDesc)
238     {
239         return (AE_NO_MEMORY);
240     }
241
242     ObjDesc->Region.Node = *Node;
243     Status = AcpiNsAttachObject (*Node, ObjDesc, ACPI_TYPE_REGION);
244     return (Status);
245 }
246 #endif
247
248
249 /*******************************************************************************
250  *
251  * FUNCTION:    AcpiDsCreateBufferField
252  *
253  * PARAMETERS:  Op                  - Current parse op (CreateXXField)
254  *              WalkState           - Current state
255  *
256  * RETURN:      Status
257  *
258  * DESCRIPTION: Execute the CreateField operators:
259  *              CreateBitFieldOp,
260  *              CreateByteFieldOp,
261  *              CreateWordFieldOp,
262  *              CreateDwordFieldOp,
263  *              CreateQwordFieldOp,
264  *              CreateFieldOp       (all of which define a field in a buffer)
265  *
266  ******************************************************************************/
267
268 ACPI_STATUS
269 AcpiDsCreateBufferField (
270     ACPI_PARSE_OBJECT       *Op,
271     ACPI_WALK_STATE         *WalkState)
272 {
273     ACPI_PARSE_OBJECT       *Arg;
274     ACPI_NAMESPACE_NODE     *Node;
275     ACPI_STATUS             Status;
276     ACPI_OPERAND_OBJECT     *ObjDesc;
277     ACPI_OPERAND_OBJECT     *SecondDesc = NULL;
278     UINT32                  Flags;
279
280
281     ACPI_FUNCTION_TRACE (DsCreateBufferField);
282
283
284     /*
285      * Get the NameString argument (name of the new BufferField)
286      */
287     if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
288     {
289         /* For CreateField, name is the 4th argument */
290
291         Arg = AcpiPsGetArg (Op, 3);
292     }
293     else
294     {
295         /* For all other CreateXXXField operators, name is the 3rd argument */
296
297         Arg = AcpiPsGetArg (Op, 2);
298     }
299
300     if (!Arg)
301     {
302         return_ACPI_STATUS (AE_AML_NO_OPERAND);
303     }
304
305     if (WalkState->DeferredNode)
306     {
307         Node = WalkState->DeferredNode;
308         Status = AE_OK;
309     }
310     else
311     {
312         /* Execute flag should always be set when this function is entered */
313
314         if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
315         {
316             ACPI_ERROR ((AE_INFO,
317                 "Parse execute mode is not set"));
318             return_ACPI_STATUS (AE_AML_INTERNAL);
319         }
320
321         /* Creating new namespace node, should not already exist */
322
323         Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
324             ACPI_NS_ERROR_IF_FOUND;
325
326         /*
327          * Mark node temporary if we are executing a normal control
328          * method. (Don't mark if this is a module-level code method)
329          */
330         if (WalkState->MethodNode &&
331             !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
332         {
333             Flags |= ACPI_NS_TEMPORARY;
334         }
335
336         /* Enter the NameString into the namespace */
337
338         Status = AcpiNsLookup (WalkState->ScopeInfo,
339             Arg->Common.Value.String, ACPI_TYPE_ANY,
340             ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
341         if (ACPI_FAILURE (Status))
342         {
343             ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
344             return_ACPI_STATUS (Status);
345         }
346     }
347
348     /*
349      * We could put the returned object (Node) on the object stack for later,
350      * but for now, we will put it in the "op" object that the parser uses,
351      * so we can get it again at the end of this scope.
352      */
353     Op->Common.Node = Node;
354
355     /*
356      * If there is no object attached to the node, this node was just created
357      * and we need to create the field object. Otherwise, this was a lookup
358      * of an existing node and we don't want to create the field object again.
359      */
360     ObjDesc = AcpiNsGetAttachedObject (Node);
361     if (ObjDesc)
362     {
363         return_ACPI_STATUS (AE_OK);
364     }
365
366     /*
367      * The Field definition is not fully parsed at this time.
368      * (We must save the address of the AML for the buffer and index operands)
369      */
370
371     /* Create the buffer field object */
372
373     ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD);
374     if (!ObjDesc)
375     {
376         Status = AE_NO_MEMORY;
377         goto Cleanup;
378     }
379
380     /*
381      * Remember location in AML stream of the field unit opcode and operands
382      * -- since the buffer and index operands must be evaluated.
383      */
384     SecondDesc = ObjDesc->Common.NextObject;
385     SecondDesc->Extra.AmlStart = Op->Named.Data;
386     SecondDesc->Extra.AmlLength = Op->Named.Length;
387     ObjDesc->BufferField.Node = Node;
388
389     /* Attach constructed field descriptors to parent node */
390
391     Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD);
392     if (ACPI_FAILURE (Status))
393     {
394         goto Cleanup;
395     }
396
397
398 Cleanup:
399
400     /* Remove local reference to the object */
401
402     AcpiUtRemoveReference (ObjDesc);
403     return_ACPI_STATUS (Status);
404 }
405
406
407 /*******************************************************************************
408  *
409  * FUNCTION:    AcpiDsGetFieldNames
410  *
411  * PARAMETERS:  Info            - CreateField info structure
412  *  `           WalkState       - Current method state
413  *              Arg             - First parser arg for the field name list
414  *
415  * RETURN:      Status
416  *
417  * DESCRIPTION: Process all named fields in a field declaration. Names are
418  *              entered into the namespace.
419  *
420  ******************************************************************************/
421
422 static ACPI_STATUS
423 AcpiDsGetFieldNames (
424     ACPI_CREATE_FIELD_INFO  *Info,
425     ACPI_WALK_STATE         *WalkState,
426     ACPI_PARSE_OBJECT       *Arg)
427 {
428     ACPI_STATUS             Status;
429     UINT64                  Position;
430     ACPI_PARSE_OBJECT       *Child;
431
432
433     ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info);
434
435
436     /* First field starts at bit zero */
437
438     Info->FieldBitPosition = 0;
439
440     /* Process all elements in the field list (of parse nodes) */
441
442     while (Arg)
443     {
444         /*
445          * Four types of field elements are handled:
446          * 1) Name - Enters a new named field into the namespace
447          * 2) Offset - specifies a bit offset
448          * 3) AccessAs - changes the access mode/attributes
449          * 4) Connection - Associate a resource template with the field
450          */
451         switch (Arg->Common.AmlOpcode)
452         {
453         case AML_INT_RESERVEDFIELD_OP:
454
455             Position = (UINT64) Info->FieldBitPosition +
456                 (UINT64) Arg->Common.Value.Size;
457
458             if (Position > ACPI_UINT32_MAX)
459             {
460                 ACPI_ERROR ((AE_INFO,
461                     "Bit offset within field too large (> 0xFFFFFFFF)"));
462                 return_ACPI_STATUS (AE_SUPPORT);
463             }
464
465             Info->FieldBitPosition = (UINT32) Position;
466             break;
467
468         case AML_INT_ACCESSFIELD_OP:
469         case AML_INT_EXTACCESSFIELD_OP:
470             /*
471              * Get new AccessType, AccessAttribute, and AccessLength fields
472              * -- to be used for all field units that follow, until the
473              * end-of-field or another AccessAs keyword is encountered.
474              * NOTE. These three bytes are encoded in the integer value
475              * of the parseop for convenience.
476              *
477              * In FieldFlags, preserve the flag bits other than the
478              * ACCESS_TYPE bits.
479              */
480
481             /* AccessType (ByteAcc, WordAcc, etc.) */
482
483             Info->FieldFlags = (UINT8)
484                 ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
485                 ((UINT8) ((UINT32) (Arg->Common.Value.Integer & 0x07))));
486
487             /* AccessAttribute (AttribQuick, AttribByte, etc.) */
488
489             Info->Attribute = (UINT8)
490                 ((Arg->Common.Value.Integer >> 8) & 0xFF);
491
492             /* AccessLength (for serial/buffer protocols) */
493
494             Info->AccessLength = (UINT8)
495                 ((Arg->Common.Value.Integer >> 16) & 0xFF);
496             break;
497
498         case AML_INT_CONNECTION_OP:
499             /*
500              * Clear any previous connection. New connection is used for all
501              * fields that follow, similar to AccessAs
502              */
503             Info->ResourceBuffer = NULL;
504             Info->ConnectionNode = NULL;
505             Info->PinNumberIndex = 0;
506
507             /*
508              * A Connection() is either an actual resource descriptor (buffer)
509              * or a named reference to a resource template
510              */
511             Child = Arg->Common.Value.Arg;
512             if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
513             {
514                 Info->ResourceBuffer = Child->Named.Data;
515                 Info->ResourceLength = (UINT16) Child->Named.Value.Integer;
516             }
517             else
518             {
519                 /* Lookup the Connection() namepath, it should already exist */
520
521                 Status = AcpiNsLookup (WalkState->ScopeInfo,
522                     Child->Common.Value.Name, ACPI_TYPE_ANY,
523                     ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
524                     WalkState, &Info->ConnectionNode);
525                 if (ACPI_FAILURE (Status))
526                 {
527                     ACPI_ERROR_NAMESPACE (Child->Common.Value.Name, Status);
528                     return_ACPI_STATUS (Status);
529                 }
530             }
531             break;
532
533         case AML_INT_NAMEDFIELD_OP:
534
535             /* Lookup the name, it should already exist */
536
537             Status = AcpiNsLookup (WalkState->ScopeInfo,
538                 (char *) &Arg->Named.Name, Info->FieldType,
539                 ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
540                 WalkState, &Info->FieldNode);
541             if (ACPI_FAILURE (Status))
542             {
543                 ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
544                 return_ACPI_STATUS (Status);
545             }
546             else
547             {
548                 Arg->Common.Node = Info->FieldNode;
549                 Info->FieldBitLength = Arg->Common.Value.Size;
550
551                 /*
552                  * If there is no object attached to the node, this node was
553                  * just created and we need to create the field object.
554                  * Otherwise, this was a lookup of an existing node and we
555                  * don't want to create the field object again.
556                  */
557                 if (!AcpiNsGetAttachedObject (Info->FieldNode))
558                 {
559                     Status = AcpiExPrepFieldValue (Info);
560                     if (ACPI_FAILURE (Status))
561                     {
562                         return_ACPI_STATUS (Status);
563                     }
564                 }
565             }
566
567             /* Keep track of bit position for the next field */
568
569             Position = (UINT64) Info->FieldBitPosition +
570                 (UINT64) Arg->Common.Value.Size;
571
572             if (Position > ACPI_UINT32_MAX)
573             {
574                 ACPI_ERROR ((AE_INFO,
575                     "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
576                     ACPI_CAST_PTR (char, &Info->FieldNode->Name)));
577                 return_ACPI_STATUS (AE_SUPPORT);
578             }
579
580             Info->FieldBitPosition += Info->FieldBitLength;
581             Info->PinNumberIndex++; /* Index relative to previous Connection() */
582             break;
583
584         default:
585
586             ACPI_ERROR ((AE_INFO,
587                 "Invalid opcode in field list: 0x%X",
588                 Arg->Common.AmlOpcode));
589             return_ACPI_STATUS (AE_AML_BAD_OPCODE);
590         }
591
592         Arg = Arg->Common.Next;
593     }
594
595     return_ACPI_STATUS (AE_OK);
596 }
597
598
599 /*******************************************************************************
600  *
601  * FUNCTION:    AcpiDsCreateField
602  *
603  * PARAMETERS:  Op              - Op containing the Field definition and args
604  *              RegionNode      - Object for the containing Operation Region
605  *  `           WalkState       - Current method state
606  *
607  * RETURN:      Status
608  *
609  * DESCRIPTION: Create a new field in the specified operation region
610  *
611  ******************************************************************************/
612
613 ACPI_STATUS
614 AcpiDsCreateField (
615     ACPI_PARSE_OBJECT       *Op,
616     ACPI_NAMESPACE_NODE     *RegionNode,
617     ACPI_WALK_STATE         *WalkState)
618 {
619     ACPI_STATUS             Status;
620     ACPI_PARSE_OBJECT       *Arg;
621     ACPI_CREATE_FIELD_INFO  Info;
622
623
624     ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op);
625
626
627     /* First arg is the name of the parent OpRegion (must already exist) */
628
629     Arg = Op->Common.Value.Arg;
630
631     if (!RegionNode)
632     {
633         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
634             ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
635             ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
636 #ifdef ACPI_ASL_COMPILER
637         Status = AcpiDsCreateExternalRegion (Status, Arg,
638             Arg->Common.Value.Name, WalkState, &RegionNode);
639 #endif
640         if (ACPI_FAILURE (Status))
641         {
642             ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
643             return_ACPI_STATUS (Status);
644         }
645     }
646
647     memset (&Info, 0, sizeof (ACPI_CREATE_FIELD_INFO));
648
649     /* Second arg is the field flags */
650
651     Arg = Arg->Common.Next;
652     Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
653     Info.Attribute = 0;
654
655     /* Each remaining arg is a Named Field */
656
657     Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD;
658     Info.RegionNode = RegionNode;
659
660     Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
661     return_ACPI_STATUS (Status);
662 }
663
664
665 /*******************************************************************************
666  *
667  * FUNCTION:    AcpiDsInitFieldObjects
668  *
669  * PARAMETERS:  Op              - Op containing the Field definition and args
670  *  `           WalkState       - Current method state
671  *
672  * RETURN:      Status
673  *
674  * DESCRIPTION: For each "Field Unit" name in the argument list that is
675  *              part of the field declaration, enter the name into the
676  *              namespace.
677  *
678  ******************************************************************************/
679
680 ACPI_STATUS
681 AcpiDsInitFieldObjects (
682     ACPI_PARSE_OBJECT       *Op,
683     ACPI_WALK_STATE         *WalkState)
684 {
685     ACPI_STATUS             Status;
686     ACPI_PARSE_OBJECT       *Arg = NULL;
687     ACPI_NAMESPACE_NODE     *Node;
688     UINT8                   Type = 0;
689     UINT32                  Flags;
690
691
692     ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op);
693
694
695     /* Execute flag should always be set when this function is entered */
696
697     if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
698     {
699         if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP)
700         {
701             /* BankField Op is deferred, just return OK */
702
703             return_ACPI_STATUS (AE_OK);
704         }
705
706         ACPI_ERROR ((AE_INFO,
707             "Parse deferred mode is not set"));
708         return_ACPI_STATUS (AE_AML_INTERNAL);
709     }
710
711     /*
712      * Get the FieldList argument for this opcode. This is the start of the
713      * list of field elements.
714      */
715     switch (WalkState->Opcode)
716     {
717     case AML_FIELD_OP:
718
719         Arg = AcpiPsGetArg (Op, 2);
720         Type = ACPI_TYPE_LOCAL_REGION_FIELD;
721         break;
722
723     case AML_BANK_FIELD_OP:
724
725         Arg = AcpiPsGetArg (Op, 4);
726         Type = ACPI_TYPE_LOCAL_BANK_FIELD;
727         break;
728
729     case AML_INDEX_FIELD_OP:
730
731         Arg = AcpiPsGetArg (Op, 3);
732         Type = ACPI_TYPE_LOCAL_INDEX_FIELD;
733         break;
734
735     default:
736
737         return_ACPI_STATUS (AE_BAD_PARAMETER);
738     }
739
740     /* Creating new namespace node(s), should not already exist */
741
742     Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
743         ACPI_NS_ERROR_IF_FOUND;
744
745     /*
746      * Mark node(s) temporary if we are executing a normal control
747      * method. (Don't mark if this is a module-level code method)
748      */
749     if (WalkState->MethodNode &&
750         !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
751     {
752         Flags |= ACPI_NS_TEMPORARY;
753     }
754
755     /*
756      * Walk the list of entries in the FieldList
757      * Note: FieldList can be of zero length. In this case, Arg will be NULL.
758      */
759     while (Arg)
760     {
761         /*
762          * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
763          * in the field names in order to enter them into the namespace.
764          */
765         if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
766         {
767             Status = AcpiNsLookup (WalkState->ScopeInfo,
768                 (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1,
769                 Flags, WalkState, &Node);
770             if (ACPI_FAILURE (Status))
771             {
772                 ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
773                 if (Status != AE_ALREADY_EXISTS)
774                 {
775                     return_ACPI_STATUS (Status);
776                 }
777
778                 /* Name already exists, just ignore this error */
779
780                 Status = AE_OK;
781             }
782
783             Arg->Common.Node = Node;
784         }
785
786         /* Get the next field element in the list */
787
788         Arg = Arg->Common.Next;
789     }
790
791     return_ACPI_STATUS (AE_OK);
792 }
793
794
795 /*******************************************************************************
796  *
797  * FUNCTION:    AcpiDsCreateBankField
798  *
799  * PARAMETERS:  Op              - Op containing the Field definition and args
800  *              RegionNode      - Object for the containing Operation Region
801  *              WalkState       - Current method state
802  *
803  * RETURN:      Status
804  *
805  * DESCRIPTION: Create a new bank field in the specified operation region
806  *
807  ******************************************************************************/
808
809 ACPI_STATUS
810 AcpiDsCreateBankField (
811     ACPI_PARSE_OBJECT       *Op,
812     ACPI_NAMESPACE_NODE     *RegionNode,
813     ACPI_WALK_STATE         *WalkState)
814 {
815     ACPI_STATUS             Status;
816     ACPI_PARSE_OBJECT       *Arg;
817     ACPI_CREATE_FIELD_INFO  Info;
818
819
820     ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op);
821
822
823     /* First arg is the name of the parent OpRegion (must already exist) */
824
825     Arg = Op->Common.Value.Arg;
826     if (!RegionNode)
827     {
828         Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
829             ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
830             ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
831 #ifdef ACPI_ASL_COMPILER
832         Status = AcpiDsCreateExternalRegion (Status, Arg,
833             Arg->Common.Value.Name, WalkState, &RegionNode);
834 #endif
835         if (ACPI_FAILURE (Status))
836         {
837             ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
838             return_ACPI_STATUS (Status);
839         }
840     }
841
842     /* Second arg is the Bank Register (Field) (must already exist) */
843
844     Arg = Arg->Common.Next;
845     Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
846         ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
847         ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
848     if (ACPI_FAILURE (Status))
849     {
850         ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
851         return_ACPI_STATUS (Status);
852     }
853
854     /*
855      * Third arg is the BankValue
856      * This arg is a TermArg, not a constant
857      * It will be evaluated later, by AcpiDsEvalBankFieldOperands
858      */
859     Arg = Arg->Common.Next;
860
861     /* Fourth arg is the field flags */
862
863     Arg = Arg->Common.Next;
864     Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
865
866     /* Each remaining arg is a Named Field */
867
868     Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD;
869     Info.RegionNode = RegionNode;
870
871     /*
872      * Use Info.DataRegisterNode to store BankField Op
873      * It's safe because DataRegisterNode will never be used when create
874      * bank field \we store AmlStart and AmlLength in the BankField Op for
875      * late evaluation. Used in AcpiExPrepFieldValue(Info)
876      *
877      * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like
878      * "void *ParentOp"?
879      */
880     Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op;
881
882     Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
883     return_ACPI_STATUS (Status);
884 }
885
886
887 /*******************************************************************************
888  *
889  * FUNCTION:    AcpiDsCreateIndexField
890  *
891  * PARAMETERS:  Op              - Op containing the Field definition and args
892  *              RegionNode      - Object for the containing Operation Region
893  *  `           WalkState       - Current method state
894  *
895  * RETURN:      Status
896  *
897  * DESCRIPTION: Create a new index field in the specified operation region
898  *
899  ******************************************************************************/
900
901 ACPI_STATUS
902 AcpiDsCreateIndexField (
903     ACPI_PARSE_OBJECT       *Op,
904     ACPI_NAMESPACE_NODE     *RegionNode,
905     ACPI_WALK_STATE         *WalkState)
906 {
907     ACPI_STATUS             Status;
908     ACPI_PARSE_OBJECT       *Arg;
909     ACPI_CREATE_FIELD_INFO  Info;
910
911
912     ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op);
913
914
915     /* First arg is the name of the Index register (must already exist) */
916
917     Arg = Op->Common.Value.Arg;
918     Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
919         ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
920         ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
921     if (ACPI_FAILURE (Status))
922     {
923         ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
924         return_ACPI_STATUS (Status);
925     }
926
927     /* Second arg is the data register (must already exist) */
928
929     Arg = Arg->Common.Next;
930     Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
931         ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
932         ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode);
933     if (ACPI_FAILURE (Status))
934     {
935         ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
936         return_ACPI_STATUS (Status);
937     }
938
939     /* Next arg is the field flags */
940
941     Arg = Arg->Common.Next;
942     Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
943
944     /* Each remaining arg is a Named Field */
945
946     Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD;
947     Info.RegionNode = RegionNode;
948
949     Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
950     return_ACPI_STATUS (Status);
951 }