dsfield.c revision 193251
154359Sroberto/******************************************************************************
254359Sroberto *
354359Sroberto * Module Name: dsfield - Dispatcher field routines
4285612Sdelphij *              $Revision: 1.84 $
554359Sroberto *
6285612Sdelphij *****************************************************************************/
7182007Sroberto
8182007Sroberto/******************************************************************************
9182007Sroberto *
10285612Sdelphij * 1. Copyright Notice
11285612Sdelphij *
12285612Sdelphij * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp.
13285612Sdelphij * All rights reserved.
14285612Sdelphij *
15285612Sdelphij * 2. License
16285612Sdelphij *
17285612Sdelphij * 2.1. This is your license from Intel Corp. under its intellectual property
18285612Sdelphij * rights.  You may have additional license terms from the party that provided
19285612Sdelphij * you this software, covering your right to use that party's intellectual
20285612Sdelphij * property rights.
21182007Sroberto *
2282498Sroberto * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2382498Sroberto * copy of the source code appearing in this file ("Covered Code") an
2482498Sroberto * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25285612Sdelphij * base code distributed originally by Intel ("Original Intel Code") to copy,
26285612Sdelphij * make derivatives, distribute, use and display any portion of the Covered
27285612Sdelphij * Code in any form, with the right to sublicense such rights; and
28285612Sdelphij *
29285612Sdelphij * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30285612Sdelphij * license (with the right to sublicense), under only those claims of Intel
31285612Sdelphij * patents that are infringed by the Original Intel Code, to make, use, sell,
3282498Sroberto * offer to sell, and import the Covered Code and derivative works thereof
33285612Sdelphij * solely to the minimum extent necessary to exercise the above copyright
34182007Sroberto * license, and in no event shall the patent license extend to any additions
3554359Sroberto * to or modifications of the Original Intel Code.  No other license or right
3654359Sroberto * is granted directly or by implication, estoppel or otherwise;
37182007Sroberto *
38182007Sroberto * The above copyright and patent license is granted only if the following
39182007Sroberto * conditions are met:
4054359Sroberto *
4154359Sroberto * 3. Conditions
42182007Sroberto *
43182007Sroberto * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44182007Sroberto * Redistribution of source code of any substantial portion of the Covered
45182007Sroberto * Code or modification with rights to further distribute source must include
46182007Sroberto * the above Copyright Notice, the above License, this list of Conditions,
4754359Sroberto * and the following Disclaimer and Export Compliance provision.  In addition,
4854359Sroberto * Licensee must cause all Covered Code to which Licensee contributes to
4954359Sroberto * contain a file documenting the changes Licensee made to create that Covered
5054359Sroberto * Code and the date of any change.  Licensee must include in that file the
5154359Sroberto * documentation of any changes made by any predecessor Licensee.  Licensee
5254359Sroberto * must include a prominent statement that the modification is derived,
5354359Sroberto * directly or indirectly, from Original Intel Code.
5454359Sroberto *
5554359Sroberto * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5654359Sroberto * Redistribution of source code of any substantial portion of the Covered
5754359Sroberto * Code or modification without rights to further distribute source must
5854359Sroberto * include the following Disclaimer and Export Compliance provision in the
59182007Sroberto * documentation and/or other materials provided with distribution.  In
6054359Sroberto * addition, Licensee may not authorize further sublicense of source of any
61285612Sdelphij * portion of the Covered Code, and must include terms to the effect that the
62285612Sdelphij * license from Licensee to its licensee is limited to the intellectual
6354359Sroberto * property embodied in the software Licensee provides to its licensee, and
6454359Sroberto * not to intellectual property embodied in modifications its licensee may
65182007Sroberto * make.
66182007Sroberto *
67182007Sroberto * 3.3. Redistribution of Executable. Redistribution in executable form of any
68182007Sroberto * substantial portion of the Covered Code or modification must reproduce the
69182007Sroberto * above Copyright Notice, and the following Disclaimer and Export Compliance
70285612Sdelphij * provision in the documentation and/or other materials provided with the
7154359Sroberto * distribution.
7254359Sroberto *
7354359Sroberto * 3.4. Intel retains all right, title, and interest in and to the Original
74285612Sdelphij * Intel Code.
75285612Sdelphij *
76285612Sdelphij * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77285612Sdelphij * Intel shall be used in advertising or otherwise to promote the sale, use or
78285612Sdelphij * other dealings in products derived from or relating to the Covered Code
79285612Sdelphij * without prior written authorization from Intel.
80285612Sdelphij *
81285612Sdelphij * 4. Disclaimer and Export Compliance
82285612Sdelphij *
83285612Sdelphij * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84285612Sdelphij * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85285612Sdelphij * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86285612Sdelphij * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87285612Sdelphij * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88285612Sdelphij * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89285612Sdelphij * PARTICULAR PURPOSE.
90285612Sdelphij *
91285612Sdelphij * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92285612Sdelphij * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93285612Sdelphij * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94285612Sdelphij * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95285612Sdelphij * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96285612Sdelphij * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97285612Sdelphij * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98285612Sdelphij * LIMITED REMEDY.
99285612Sdelphij *
100285612Sdelphij * 4.3. Licensee shall not export, either directly or indirectly, any of this
101285612Sdelphij * software or system incorporating such software without first obtaining any
102285612Sdelphij * required license or other approval from the U. S. Department of Commerce or
103285612Sdelphij * any other agency or department of the United States Government.  In the
10454359Sroberto * event Licensee exports any such software from the United States or
10554359Sroberto * re-exports any such software from a foreign destination, Licensee shall
10654359Sroberto * ensure that the distribution and export/re-export of the software is in
10754359Sroberto * compliance with all laws, regulations, orders, or other restrictions of the
10854359Sroberto * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10954359Sroberto * any of its subsidiaries will export/re-export any technical data, process,
11054359Sroberto * software, or service, directly or indirectly, to any country for which the
11154359Sroberto * United States government or any agency thereof requires an export license,
11254359Sroberto * other governmental approval, or letter of assurance, without first obtaining
11354359Sroberto * such license, approval or letter.
11454359Sroberto *
11554359Sroberto *****************************************************************************/
11654359Sroberto
117182007Sroberto#define __DSFIELD_C__
11854359Sroberto
11954359Sroberto#include "acpi.h"
120182007Sroberto#include "amlcode.h"
12154359Sroberto#include "acdispat.h"
12254359Sroberto#include "acinterp.h"
123132451Sroberto#include "acnamesp.h"
124132451Sroberto#include "acparser.h"
12554359Sroberto
12654359Sroberto
12754359Sroberto#define _COMPONENT          ACPI_DISPATCHER
12854359Sroberto        ACPI_MODULE_NAME    ("dsfield")
12954359Sroberto
13054359Sroberto/* Local prototypes */
13154359Sroberto
13254359Srobertostatic ACPI_STATUS
13354359SrobertoAcpiDsGetFieldNames (
13454359Sroberto    ACPI_CREATE_FIELD_INFO  *Info,
13554359Sroberto    ACPI_WALK_STATE         *WalkState,
13654359Sroberto    ACPI_PARSE_OBJECT       *Arg);
13754359Sroberto
13854359Sroberto
13954359Sroberto/*******************************************************************************
14054359Sroberto *
141182007Sroberto * FUNCTION:    AcpiDsCreateBufferField
14254359Sroberto *
14354359Sroberto * PARAMETERS:  Op                  - Current parse op (CreateXXField)
14454359Sroberto *              WalkState           - Current state
14554359Sroberto *
14654359Sroberto * RETURN:      Status
14754359Sroberto *
14854359Sroberto * DESCRIPTION: Execute the CreateField operators:
14954359Sroberto *              CreateBitFieldOp,
15054359Sroberto *              CreateByteFieldOp,
15154359Sroberto *              CreateWordFieldOp,
15254359Sroberto *              CreateDWordFieldOp,
15354359Sroberto *              CreateQWordFieldOp,
15454359Sroberto *              CreateFieldOp       (all of which define a field in a buffer)
15554359Sroberto *
15654359Sroberto ******************************************************************************/
15754359Sroberto
158285612SdelphijACPI_STATUS
15954359SrobertoAcpiDsCreateBufferField (
16054359Sroberto    ACPI_PARSE_OBJECT       *Op,
16154359Sroberto    ACPI_WALK_STATE         *WalkState)
16254359Sroberto{
16354359Sroberto    ACPI_PARSE_OBJECT       *Arg;
16454359Sroberto    ACPI_NAMESPACE_NODE     *Node;
16554359Sroberto    ACPI_STATUS             Status;
166182007Sroberto    ACPI_OPERAND_OBJECT     *ObjDesc;
167182007Sroberto    ACPI_OPERAND_OBJECT     *SecondDesc = NULL;
16854359Sroberto    UINT32                  Flags;
16954359Sroberto
17054359Sroberto
17154359Sroberto    ACPI_FUNCTION_TRACE (DsCreateBufferField);
172285612Sdelphij
173285612Sdelphij
17454359Sroberto    /* Get the NameString argument */
17554359Sroberto
176132451Sroberto    if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
17754359Sroberto    {
178132451Sroberto        Arg = AcpiPsGetArg (Op, 3);
179132451Sroberto    }
180132451Sroberto    else
18154359Sroberto    {
182132451Sroberto        /* Create Bit/Byte/Word/Dword field */
18354359Sroberto
18454359Sroberto        Arg = AcpiPsGetArg (Op, 2);
18554359Sroberto    }
18654359Sroberto
18754359Sroberto    if (!Arg)
18854359Sroberto    {
18954359Sroberto        return_ACPI_STATUS (AE_AML_NO_OPERAND);
19054359Sroberto    }
19154359Sroberto
19254359Sroberto    if (WalkState->DeferredNode)
19354359Sroberto    {
19454359Sroberto        Node = WalkState->DeferredNode;
195106163Sroberto        Status = AE_OK;
196106163Sroberto    }
197132451Sroberto    else
198106163Sroberto    {
199106163Sroberto        /*
200106163Sroberto         * During the load phase, we want to enter the name of the field into
20154359Sroberto         * the namespace.  During the execute phase (when we evaluate the size
20254359Sroberto         * operand), we want to lookup the name
20354359Sroberto         */
20454359Sroberto        if (WalkState->ParseFlags & ACPI_PARSE_EXECUTE)
20554359Sroberto        {
20654359Sroberto            Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE;
20754359Sroberto        }
20854359Sroberto        else
20954359Sroberto        {
21054359Sroberto            Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
21154359Sroberto                    ACPI_NS_ERROR_IF_FOUND;
21254359Sroberto        }
21354359Sroberto
21454359Sroberto        /*
21554359Sroberto         * Enter the NameString into the namespace
21654359Sroberto         */
21754359Sroberto        Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
21854359Sroberto                                ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
21954359Sroberto                                Flags, WalkState, &(Node));
22054359Sroberto        if (ACPI_FAILURE (Status))
22154359Sroberto        {
22254359Sroberto            ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
22354359Sroberto            return_ACPI_STATUS (Status);
22454359Sroberto        }
22554359Sroberto    }
22654359Sroberto
22754359Sroberto    /*
22854359Sroberto     * We could put the returned object (Node) on the object stack for later,
22954359Sroberto     * but for now, we will put it in the "op" object that the parser uses,
23054359Sroberto     * so we can get it again at the end of this scope
23154359Sroberto     */
23254359Sroberto    Op->Common.Node = Node;
23354359Sroberto
23454359Sroberto    /*
23554359Sroberto     * If there is no object attached to the node, this node was just created
23654359Sroberto     * and we need to create the field object.  Otherwise, this was a lookup
23754359Sroberto     * of an existing node and we don't want to create the field object again.
23854359Sroberto     */
23954359Sroberto    ObjDesc = AcpiNsGetAttachedObject (Node);
24054359Sroberto    if (ObjDesc)
24154359Sroberto    {
24254359Sroberto        return_ACPI_STATUS (AE_OK);
243289997Sglebius    }
24454359Sroberto
24554359Sroberto    /*
24654359Sroberto     * The Field definition is not fully parsed at this time.
24754359Sroberto     * (We must save the address of the AML for the buffer and index operands)
24854359Sroberto     */
24954359Sroberto
25054359Sroberto    /* Create the buffer field object */
25154359Sroberto
25254359Sroberto    ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD);
25354359Sroberto    if (!ObjDesc)
25454359Sroberto    {
25554359Sroberto        Status = AE_NO_MEMORY;
25654359Sroberto        goto Cleanup;
25754359Sroberto    }
25854359Sroberto
25954359Sroberto    /*
26054359Sroberto     * Remember location in AML stream of the field unit
26154359Sroberto     * opcode and operands -- since the buffer and index
26254359Sroberto     * operands must be evaluated.
26354359Sroberto     */
26454359Sroberto    SecondDesc                  = ObjDesc->Common.NextObject;
26554359Sroberto    SecondDesc->Extra.AmlStart  = Op->Named.Data;
26654359Sroberto    SecondDesc->Extra.AmlLength = Op->Named.Length;
26754359Sroberto    ObjDesc->BufferField.Node   = Node;
26854359Sroberto
26954359Sroberto    /* Attach constructed field descriptors to parent node */
27054359Sroberto
27154359Sroberto    Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD);
27254359Sroberto    if (ACPI_FAILURE (Status))
27354359Sroberto    {
27454359Sroberto        goto Cleanup;
27554359Sroberto    }
27654359Sroberto
27754359Sroberto
27854359SrobertoCleanup:
27954359Sroberto
28054359Sroberto    /* Remove local reference to the object */
28154359Sroberto
28254359Sroberto    AcpiUtRemoveReference (ObjDesc);
28354359Sroberto    return_ACPI_STATUS (Status);
28454359Sroberto}
28554359Sroberto
286285612Sdelphij
287285612Sdelphij/*******************************************************************************
288285612Sdelphij *
289132451Sroberto * FUNCTION:    AcpiDsGetFieldNames
290285612Sdelphij *
291285612Sdelphij * PARAMETERS:  Info            - CreateField info structure
292132451Sroberto *  `           WalkState       - Current method state
293132451Sroberto *              Arg             - First parser arg for the field name list
29454359Sroberto *
295182007Sroberto * RETURN:      Status
296182007Sroberto *
297285612Sdelphij * DESCRIPTION: Process all named fields in a field declaration.  Names are
298182007Sroberto *              entered into the namespace.
299182007Sroberto *
300182007Sroberto ******************************************************************************/
301182007Sroberto
302285612Sdelphijstatic ACPI_STATUS
303182007SrobertoAcpiDsGetFieldNames (
304285612Sdelphij    ACPI_CREATE_FIELD_INFO  *Info,
305182007Sroberto    ACPI_WALK_STATE         *WalkState,
306285612Sdelphij    ACPI_PARSE_OBJECT       *Arg)
307182007Sroberto{
308182007Sroberto    ACPI_STATUS             Status;
309182007Sroberto    ACPI_INTEGER            Position;
310182007Sroberto
311182007Sroberto
312182007Sroberto    ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info);
313182007Sroberto
314182007Sroberto
315182007Sroberto    /* First field starts at bit zero */
316182007Sroberto
317182007Sroberto    Info->FieldBitPosition = 0;
318285612Sdelphij
319182007Sroberto    /* Process all elements in the field list (of parse nodes) */
320182007Sroberto
321182007Sroberto    while (Arg)
322182007Sroberto    {
323182007Sroberto        /*
324182007Sroberto         * Three types of field elements are handled:
325182007Sroberto         * 1) Offset - specifies a bit offset
326182007Sroberto         * 2) AccessAs - changes the access mode
327182007Sroberto         * 3) Name - Enters a new named field into the namespace
328182007Sroberto         */
329182007Sroberto        switch (Arg->Common.AmlOpcode)
330182007Sroberto        {
331182007Sroberto        case AML_INT_RESERVEDFIELD_OP:
332182007Sroberto
333182007Sroberto            Position = (ACPI_INTEGER) Info->FieldBitPosition
334182007Sroberto                        + (ACPI_INTEGER) Arg->Common.Value.Size;
335182007Sroberto
336182007Sroberto            if (Position > ACPI_UINT32_MAX)
337182007Sroberto            {
338182007Sroberto                ACPI_ERROR ((AE_INFO,
339182007Sroberto                    "Bit offset within field too large (> 0xFFFFFFFF)"));
340182007Sroberto                return_ACPI_STATUS (AE_SUPPORT);
341182007Sroberto            }
342182007Sroberto
343182007Sroberto            Info->FieldBitPosition = (UINT32) Position;
344182007Sroberto            break;
345182007Sroberto
346182007Sroberto
347182007Sroberto        case AML_INT_ACCESSFIELD_OP:
348182007Sroberto
349182007Sroberto            /*
350182007Sroberto             * Get a new AccessType and AccessAttribute -- to be used for all
351182007Sroberto             * field units that follow, until field end or another AccessAs
35254359Sroberto             * keyword.
35354359Sroberto             *
35454359Sroberto             * In FieldFlags, preserve the flag bits other than the
35554359Sroberto             * ACCESS_TYPE bits
35654359Sroberto             */
35754359Sroberto            Info->FieldFlags = (UINT8)
35854359Sroberto                ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
35954359Sroberto                ((UINT8) ((UINT32) Arg->Common.Value.Integer >> 8)));
36054359Sroberto
361285612Sdelphij            Info->Attribute = (UINT8) (Arg->Common.Value.Integer);
36254359Sroberto            break;
36354359Sroberto
36454359Sroberto
36554359Sroberto        case AML_INT_NAMEDFIELD_OP:
36654359Sroberto
36754359Sroberto            /* Lookup the name */
36854359Sroberto
36954359Sroberto            Status = AcpiNsLookup (WalkState->ScopeInfo,
37054359Sroberto                            (char *) &Arg->Named.Name,
37154359Sroberto                            Info->FieldType, ACPI_IMODE_EXECUTE,
37254359Sroberto                            ACPI_NS_DONT_OPEN_SCOPE,
37354359Sroberto                            WalkState, &Info->FieldNode);
37454359Sroberto            if (ACPI_FAILURE (Status))
37554359Sroberto            {
37654359Sroberto                ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
37754359Sroberto                if (Status != AE_ALREADY_EXISTS)
37854359Sroberto                {
37954359Sroberto                    return_ACPI_STATUS (Status);
38054359Sroberto                }
38154359Sroberto
38254359Sroberto                /* Already exists, ignore error */
38354359Sroberto            }
38454359Sroberto            else
38554359Sroberto            {
38654359Sroberto                Arg->Common.Node = Info->FieldNode;
38754359Sroberto                Info->FieldBitLength = Arg->Common.Value.Size;
38854359Sroberto
38954359Sroberto                /* Create and initialize an object for the new Field Node */
39054359Sroberto
39154359Sroberto                Status = AcpiExPrepFieldValue (Info);
39254359Sroberto                if (ACPI_FAILURE (Status))
39354359Sroberto                {
39454359Sroberto                    return_ACPI_STATUS (Status);
395132451Sroberto                }
396132451Sroberto            }
397285612Sdelphij
398285612Sdelphij            /* Keep track of bit position for the next field */
399132451Sroberto
400132451Sroberto            Position = (ACPI_INTEGER) Info->FieldBitPosition
401132451Sroberto                        + (ACPI_INTEGER) Arg->Common.Value.Size;
40254359Sroberto
403132451Sroberto            if (Position > ACPI_UINT32_MAX)
404132451Sroberto            {
405132451Sroberto                ACPI_ERROR ((AE_INFO,
406132451Sroberto                    "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
407132451Sroberto                    ACPI_CAST_PTR (char, &Info->FieldNode->Name)));
408132451Sroberto                return_ACPI_STATUS (AE_SUPPORT);
409132451Sroberto            }
410132451Sroberto
411285612Sdelphij            Info->FieldBitPosition += Info->FieldBitLength;
412285612Sdelphij            break;
413285612Sdelphij
414285612Sdelphij
415285612Sdelphij        default:
416285612Sdelphij
417285612Sdelphij            ACPI_ERROR ((AE_INFO,
418285612Sdelphij                "Invalid opcode in field list: %X",
419132451Sroberto                Arg->Common.AmlOpcode));
420132451Sroberto            return_ACPI_STATUS (AE_AML_BAD_OPCODE);
421132451Sroberto        }
422132451Sroberto
423132451Sroberto        Arg = Arg->Common.Next;
424132451Sroberto    }
425132451Sroberto
426132451Sroberto    return_ACPI_STATUS (AE_OK);
427132451Sroberto}
428285612Sdelphij
429285612Sdelphij
430132451Sroberto/*******************************************************************************
431132451Sroberto *
432132451Sroberto * FUNCTION:    AcpiDsCreateField
433285612Sdelphij *
434132451Sroberto * PARAMETERS:  Op              - Op containing the Field definition and args
435132451Sroberto *              RegionNode      - Object for the containing Operation Region
436182007Sroberto *  `           WalkState       - Current method state
437182007Sroberto *
438182007Sroberto * RETURN:      Status
439182007Sroberto *
440182007Sroberto * DESCRIPTION: Create a new field in the specified operation region
441132451Sroberto *
442132451Sroberto ******************************************************************************/
443132451Sroberto
444132451SrobertoACPI_STATUS
445132451SrobertoAcpiDsCreateField (
44654359Sroberto    ACPI_PARSE_OBJECT       *Op,
447132451Sroberto    ACPI_NAMESPACE_NODE     *RegionNode,
448132451Sroberto    ACPI_WALK_STATE         *WalkState)
449132451Sroberto{
450132451Sroberto    ACPI_STATUS             Status;
451132451Sroberto    ACPI_PARSE_OBJECT       *Arg;
452132451Sroberto    ACPI_CREATE_FIELD_INFO  Info;
453285612Sdelphij
454182007Sroberto
455182007Sroberto    ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op);
456132451Sroberto
457132451Sroberto
45854359Sroberto    /* First arg is the name of the parent OpRegion (must already exist) */
459285612Sdelphij
460285612Sdelphij    Arg = Op->Common.Value.Arg;
461285612Sdelphij    if (!RegionNode)
462285612Sdelphij    {
463285612Sdelphij        Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
464285612Sdelphij                        ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
465285612Sdelphij                        ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
466285612Sdelphij        if (ACPI_FAILURE (Status))
467132451Sroberto        {
468285612Sdelphij            ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
469285612Sdelphij            return_ACPI_STATUS (Status);
470285612Sdelphij        }
471285612Sdelphij    }
472285612Sdelphij
47354359Sroberto    /* Second arg is the field flags */
474285612Sdelphij
47554359Sroberto    Arg = Arg->Common.Next;
47654359Sroberto    Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
47754359Sroberto    Info.Attribute = 0;
478285612Sdelphij
479285612Sdelphij    /* Each remaining arg is a Named Field */
48054359Sroberto
48154359Sroberto    Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD;
482285612Sdelphij    Info.RegionNode = RegionNode;
483132451Sroberto
484132451Sroberto    Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
485285612Sdelphij
486132451Sroberto    return_ACPI_STATUS (Status);
487132451Sroberto}
488132451Sroberto
489132451Sroberto
490132451Sroberto/*******************************************************************************
491132451Sroberto *
492132451Sroberto * FUNCTION:    AcpiDsInitFieldObjects
493132451Sroberto *
494132451Sroberto * PARAMETERS:  Op              - Op containing the Field definition and args
49554359Sroberto *  `           WalkState       - Current method state
49654359Sroberto *
49754359Sroberto * RETURN:      Status
49854359Sroberto *
49954359Sroberto * DESCRIPTION: For each "Field Unit" name in the argument list that is
500182007Sroberto *              part of the field declaration, enter the name into the
50154359Sroberto *              namespace.
50254359Sroberto *
50354359Sroberto ******************************************************************************/
50454359Sroberto
50554359SrobertoACPI_STATUS
50654359SrobertoAcpiDsInitFieldObjects (
507285612Sdelphij    ACPI_PARSE_OBJECT       *Op,
508132451Sroberto    ACPI_WALK_STATE         *WalkState)
509132451Sroberto{
51054359Sroberto    ACPI_STATUS             Status;
511285612Sdelphij    ACPI_PARSE_OBJECT       *Arg = NULL;
51254359Sroberto    ACPI_NAMESPACE_NODE     *Node;
51354359Sroberto    UINT8                   Type = 0;
51454359Sroberto
51554359Sroberto
51654359Sroberto    ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op);
51754359Sroberto
51854359Sroberto
51954359Sroberto    switch (WalkState->Opcode)
52054359Sroberto    {
52154359Sroberto    case AML_FIELD_OP:
522285612Sdelphij        Arg = AcpiPsGetArg (Op, 2);
52354359Sroberto        Type = ACPI_TYPE_LOCAL_REGION_FIELD;
52454359Sroberto        break;
52554359Sroberto
52654359Sroberto    case AML_BANK_FIELD_OP:
527132451Sroberto        Arg = AcpiPsGetArg (Op, 4);
528132451Sroberto        Type = ACPI_TYPE_LOCAL_BANK_FIELD;
529285612Sdelphij        break;
530132451Sroberto
531285612Sdelphij    case AML_INDEX_FIELD_OP:
532132451Sroberto        Arg = AcpiPsGetArg (Op, 3);
533285612Sdelphij        Type = ACPI_TYPE_LOCAL_INDEX_FIELD;
534285612Sdelphij        break;
535285612Sdelphij
536285612Sdelphij    default:
537285612Sdelphij        return_ACPI_STATUS (AE_BAD_PARAMETER);
53854359Sroberto    }
539106163Sroberto
540132451Sroberto    /*
54154359Sroberto     * Walk the list of entries in the FieldList
54254359Sroberto     */
54354359Sroberto    while (Arg)
54454359Sroberto    {
54554359Sroberto        /* Ignore OFFSET and ACCESSAS terms here */
54654359Sroberto
54754359Sroberto        if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
54854359Sroberto        {
54954359Sroberto            Status = AcpiNsLookup (WalkState->ScopeInfo,
55054359Sroberto                            (char *) &Arg->Named.Name,
551285612Sdelphij                            Type, ACPI_IMODE_LOAD_PASS1,
552285612Sdelphij                            ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
55354359Sroberto                            ACPI_NS_ERROR_IF_FOUND,
55454359Sroberto                            WalkState, &Node);
555285612Sdelphij            if (ACPI_FAILURE (Status))
556285612Sdelphij            {
55754359Sroberto                ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
55854359Sroberto                if (Status != AE_ALREADY_EXISTS)
55954359Sroberto                {
56054359Sroberto                    return_ACPI_STATUS (Status);
56154359Sroberto                }
56254359Sroberto
56354359Sroberto                /* Name already exists, just ignore this error */
56454359Sroberto
56554359Sroberto                Status = AE_OK;
56654359Sroberto            }
56754359Sroberto
56854359Sroberto            Arg->Common.Node = Node;
56954359Sroberto        }
570285612Sdelphij
571285612Sdelphij        /* Move to next field in the list */
572285612Sdelphij
57354359Sroberto        Arg = Arg->Common.Next;
574285612Sdelphij    }
57554359Sroberto
57654359Sroberto    return_ACPI_STATUS (AE_OK);
57754359Sroberto}
57854359Sroberto
57954359Sroberto
58054359Sroberto/*******************************************************************************
58154359Sroberto *
58254359Sroberto * FUNCTION:    AcpiDsCreateBankField
58354359Sroberto *
58454359Sroberto * PARAMETERS:  Op              - Op containing the Field definition and args
58554359Sroberto *              RegionNode      - Object for the containing Operation Region
58654359Sroberto *  `           WalkState       - Current method state
587132451Sroberto *
588132451Sroberto * RETURN:      Status
58954359Sroberto *
59054359Sroberto * DESCRIPTION: Create a new bank field in the specified operation region
59154359Sroberto *
592285612Sdelphij ******************************************************************************/
59354359Sroberto
594132451SrobertoACPI_STATUS
59554359SrobertoAcpiDsCreateBankField (
59654359Sroberto    ACPI_PARSE_OBJECT       *Op,
59754359Sroberto    ACPI_NAMESPACE_NODE     *RegionNode,
598132451Sroberto    ACPI_WALK_STATE         *WalkState)
59954359Sroberto{
60054359Sroberto    ACPI_STATUS             Status;
60154359Sroberto    ACPI_PARSE_OBJECT       *Arg;
60254359Sroberto    ACPI_CREATE_FIELD_INFO  Info;
60354359Sroberto
60454359Sroberto
605285612Sdelphij    ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op);
606132451Sroberto
60754359Sroberto
60854359Sroberto    /* First arg is the name of the parent OpRegion (must already exist) */
60954359Sroberto
61054359Sroberto    Arg = Op->Common.Value.Arg;
61154359Sroberto    if (!RegionNode)
61254359Sroberto    {
61354359Sroberto        Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
61454359Sroberto                        ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
61554359Sroberto                        ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
61654359Sroberto        if (ACPI_FAILURE (Status))
61754359Sroberto        {
61854359Sroberto            ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
61954359Sroberto            return_ACPI_STATUS (Status);
62054359Sroberto        }
621285612Sdelphij    }
62254359Sroberto
62354359Sroberto    /* Second arg is the Bank Register (Field) (must already exist) */
62454359Sroberto
62554359Sroberto    Arg = Arg->Common.Next;
626285612Sdelphij    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
62754359Sroberto                    ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
628285612Sdelphij                    ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
62954359Sroberto    if (ACPI_FAILURE (Status))
63054359Sroberto    {
63154359Sroberto        ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
63254359Sroberto        return_ACPI_STATUS (Status);
63354359Sroberto    }
634285612Sdelphij
63554359Sroberto    /* Third arg is the BankValue */
63654359Sroberto
63754359Sroberto    /* TBD: This arg is a TermArg, not a constant, and must be evaluated */
63854359Sroberto
63954359Sroberto    Arg = Arg->Common.Next;
64054359Sroberto
64154359Sroberto    /* Currently, only the following constants are supported */
64254359Sroberto
64354359Sroberto    switch (Arg->Common.AmlOpcode)
64454359Sroberto    {
64554359Sroberto    case AML_ZERO_OP:
64654359Sroberto        Info.BankValue = 0;
64754359Sroberto        break;
64854359Sroberto
64954359Sroberto    case AML_ONE_OP:
65054359Sroberto        Info.BankValue = 1;
65154359Sroberto        break;
65254359Sroberto
653285612Sdelphij    case AML_BYTE_OP:
65454359Sroberto    case AML_WORD_OP:
65554359Sroberto    case AML_DWORD_OP:
65654359Sroberto    case AML_QWORD_OP:
65754359Sroberto        Info.BankValue = (UINT32) Arg->Common.Value.Integer;
65854359Sroberto        break;
65954359Sroberto
66054359Sroberto    default:
66154359Sroberto        Info.BankValue = 0;
66254359Sroberto        ACPI_ERROR ((AE_INFO, "Non-constant BankValue for BankField is not implemented"));
66354359Sroberto    }
66454359Sroberto
665285612Sdelphij    /* Fourth arg is the field flags */
66654359Sroberto
66754359Sroberto    Arg = Arg->Common.Next;
66854359Sroberto    Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
66954359Sroberto
67054359Sroberto    /* Each remaining arg is a Named Field */
67154359Sroberto
67254359Sroberto    Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD;
673285612Sdelphij    Info.RegionNode = RegionNode;
67454359Sroberto
675285612Sdelphij    Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
67654359Sroberto
67754359Sroberto    return_ACPI_STATUS (Status);
67854359Sroberto}
67954359Sroberto
68054359Sroberto
681285612Sdelphij/*******************************************************************************
682285612Sdelphij *
68354359Sroberto * FUNCTION:    AcpiDsCreateIndexField
68454359Sroberto *
68554359Sroberto * PARAMETERS:  Op              - Op containing the Field definition and args
68654359Sroberto *              RegionNode      - Object for the containing Operation Region
687285612Sdelphij *  `           WalkState       - Current method state
688285612Sdelphij *
68954359Sroberto * RETURN:      Status
69054359Sroberto *
69154359Sroberto * DESCRIPTION: Create a new index field in the specified operation region
69254359Sroberto *
693285612Sdelphij ******************************************************************************/
69454359Sroberto
69554359SrobertoACPI_STATUS
69654359SrobertoAcpiDsCreateIndexField (
69754359Sroberto    ACPI_PARSE_OBJECT       *Op,
698285612Sdelphij    ACPI_NAMESPACE_NODE     *RegionNode,
69954359Sroberto    ACPI_WALK_STATE         *WalkState)
70054359Sroberto{
70154359Sroberto    ACPI_STATUS             Status;
70254359Sroberto    ACPI_PARSE_OBJECT       *Arg;
703285612Sdelphij    ACPI_CREATE_FIELD_INFO  Info;
70454359Sroberto
70554359Sroberto
70654359Sroberto    ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op);
70754359Sroberto
70854359Sroberto
70954359Sroberto    /* First arg is the name of the Index register (must already exist) */
71054359Sroberto
71154359Sroberto    Arg = Op->Common.Value.Arg;
712285612Sdelphij    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
71354359Sroberto                    ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
71454359Sroberto                    ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
71554359Sroberto    if (ACPI_FAILURE (Status))
71654359Sroberto    {
71754359Sroberto        ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
71854359Sroberto        return_ACPI_STATUS (Status);
71954359Sroberto    }
72054359Sroberto
72154359Sroberto    /* Second arg is the data register (must already exist) */
72254359Sroberto
72354359Sroberto    Arg = Arg->Common.Next;
72454359Sroberto    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
72554359Sroberto                    ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
72654359Sroberto                    ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode);
72754359Sroberto    if (ACPI_FAILURE (Status))
72854359Sroberto    {
72954359Sroberto        ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
73054359Sroberto        return_ACPI_STATUS (Status);
73154359Sroberto    }
73254359Sroberto
73354359Sroberto    /* Next arg is the field flags */
73454359Sroberto
735132451Sroberto    Arg = Arg->Common.Next;
736132451Sroberto    Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
737132451Sroberto
738132451Sroberto    /* Each remaining arg is a Named Field */
739285612Sdelphij
740285612Sdelphij    Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD;
74154359Sroberto    Info.RegionNode = RegionNode;
74254359Sroberto
743285612Sdelphij    Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
74454359Sroberto
74554359Sroberto    return_ACPI_STATUS (Status);
74654359Sroberto}
74754359Sroberto
74854359Sroberto
74954359Sroberto