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 - 2012, 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
135static ACPI_STATUS
136AcpiDsCreateExternalRegion (
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
144static ACPI_STATUS
145AcpiDsGetFieldNames (
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
169static ACPI_STATUS
170AcpiDsCreateExternalRegion (
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    AcpiDmAddToExternalList (Op, Path, ACPI_TYPE_REGION, 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
233ACPI_STATUS
234AcpiDsCreateBufferField (
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
361Cleanup:
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
385static ACPI_STATUS
386AcpiDsGetFieldNames (
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
571ACPI_STATUS
572AcpiDsCreateField (
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
638ACPI_STATUS
639AcpiDsInitFieldObjects (
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        Arg = AcpiPsGetArg (Op, 2);
675        Type = ACPI_TYPE_LOCAL_REGION_FIELD;
676        break;
677
678    case AML_BANK_FIELD_OP:
679        Arg = AcpiPsGetArg (Op, 4);
680        Type = ACPI_TYPE_LOCAL_BANK_FIELD;
681        break;
682
683    case AML_INDEX_FIELD_OP:
684        Arg = AcpiPsGetArg (Op, 3);
685        Type = ACPI_TYPE_LOCAL_INDEX_FIELD;
686        break;
687
688    default:
689        return_ACPI_STATUS (AE_BAD_PARAMETER);
690    }
691
692    /* Creating new namespace node(s), should not already exist */
693
694    Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
695            ACPI_NS_ERROR_IF_FOUND;
696
697    /*
698     * Mark node(s) temporary if we are executing a normal control
699     * method. (Don't mark if this is a module-level code method)
700     */
701    if (WalkState->MethodNode &&
702        !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
703    {
704        Flags |= ACPI_NS_TEMPORARY;
705    }
706
707    /*
708     * Walk the list of entries in the FieldList
709     * Note: FieldList can be of zero length. In this case, Arg will be NULL.
710     */
711    while (Arg)
712    {
713        /*
714         * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
715         * in the field names in order to enter them into the namespace.
716         */
717        if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
718        {
719            Status = AcpiNsLookup (WalkState->ScopeInfo,
720                        (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1,
721                        Flags, WalkState, &Node);
722            if (ACPI_FAILURE (Status))
723            {
724                ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
725                if (Status != AE_ALREADY_EXISTS)
726                {
727                    return_ACPI_STATUS (Status);
728                }
729
730                /* Name already exists, just ignore this error */
731
732                Status = AE_OK;
733            }
734
735            Arg->Common.Node = Node;
736        }
737
738        /* Get the next field element in the list */
739
740        Arg = Arg->Common.Next;
741    }
742
743    return_ACPI_STATUS (AE_OK);
744}
745
746
747/*******************************************************************************
748 *
749 * FUNCTION:    AcpiDsCreateBankField
750 *
751 * PARAMETERS:  Op              - Op containing the Field definition and args
752 *              RegionNode      - Object for the containing Operation Region
753 *              WalkState       - Current method state
754 *
755 * RETURN:      Status
756 *
757 * DESCRIPTION: Create a new bank field in the specified operation region
758 *
759 ******************************************************************************/
760
761ACPI_STATUS
762AcpiDsCreateBankField (
763    ACPI_PARSE_OBJECT       *Op,
764    ACPI_NAMESPACE_NODE     *RegionNode,
765    ACPI_WALK_STATE         *WalkState)
766{
767    ACPI_STATUS             Status;
768    ACPI_PARSE_OBJECT       *Arg;
769    ACPI_CREATE_FIELD_INFO  Info;
770
771
772    ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op);
773
774
775    /* First arg is the name of the parent OpRegion (must already exist) */
776
777    Arg = Op->Common.Value.Arg;
778    if (!RegionNode)
779    {
780        Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
781                        ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
782                        ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
783#ifdef ACPI_ASL_COMPILER
784        Status = AcpiDsCreateExternalRegion (Status, Arg,
785            Arg->Common.Value.Name, WalkState, &RegionNode);
786#endif
787        if (ACPI_FAILURE (Status))
788        {
789            ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
790            return_ACPI_STATUS (Status);
791        }
792    }
793
794    /* Second arg is the Bank Register (Field) (must already exist) */
795
796    Arg = Arg->Common.Next;
797    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
798                    ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
799                    ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
800    if (ACPI_FAILURE (Status))
801    {
802        ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
803        return_ACPI_STATUS (Status);
804    }
805
806    /*
807     * Third arg is the BankValue
808     * This arg is a TermArg, not a constant
809     * It will be evaluated later, by AcpiDsEvalBankFieldOperands
810     */
811    Arg = Arg->Common.Next;
812
813    /* Fourth arg is the field flags */
814
815    Arg = Arg->Common.Next;
816    Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
817
818    /* Each remaining arg is a Named Field */
819
820    Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD;
821    Info.RegionNode = RegionNode;
822
823    /*
824     * Use Info.DataRegisterNode to store BankField Op
825     * It's safe because DataRegisterNode will never be used when create bank field
826     * We store AmlStart and AmlLength in the BankField Op for late evaluation
827     * Used in AcpiExPrepFieldValue(Info)
828     *
829     * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like "void *ParentOp"?
830     */
831    Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op;
832
833    Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
834    return_ACPI_STATUS (Status);
835}
836
837
838/*******************************************************************************
839 *
840 * FUNCTION:    AcpiDsCreateIndexField
841 *
842 * PARAMETERS:  Op              - Op containing the Field definition and args
843 *              RegionNode      - Object for the containing Operation Region
844 *  `           WalkState       - Current method state
845 *
846 * RETURN:      Status
847 *
848 * DESCRIPTION: Create a new index field in the specified operation region
849 *
850 ******************************************************************************/
851
852ACPI_STATUS
853AcpiDsCreateIndexField (
854    ACPI_PARSE_OBJECT       *Op,
855    ACPI_NAMESPACE_NODE     *RegionNode,
856    ACPI_WALK_STATE         *WalkState)
857{
858    ACPI_STATUS             Status;
859    ACPI_PARSE_OBJECT       *Arg;
860    ACPI_CREATE_FIELD_INFO  Info;
861
862
863    ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op);
864
865
866    /* First arg is the name of the Index register (must already exist) */
867
868    Arg = Op->Common.Value.Arg;
869    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
870                    ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
871                    ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
872    if (ACPI_FAILURE (Status))
873    {
874        ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
875        return_ACPI_STATUS (Status);
876    }
877
878    /* Second arg is the data register (must already exist) */
879
880    Arg = Arg->Common.Next;
881    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
882                    ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
883                    ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode);
884    if (ACPI_FAILURE (Status))
885    {
886        ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
887        return_ACPI_STATUS (Status);
888    }
889
890    /* Next arg is the field flags */
891
892    Arg = Arg->Common.Next;
893    Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
894
895    /* Each remaining arg is a Named Field */
896
897    Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD;
898    Info.RegionNode = RegionNode;
899
900    Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
901    return_ACPI_STATUS (Status);
902}
903