167754Smsmith/******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: dsfield - Dispatcher field routines
467754Smsmith *
567754Smsmith *****************************************************************************/
667754Smsmith
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
970243Smsmith * All rights reserved.
1067754Smsmith *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
2567754Smsmith *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
2967754Smsmith *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
4367754Smsmith
44193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
45193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
46193341Sjkim#include <contrib/dev/acpica/include/amlcode.h>
47193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
48193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
50193341Sjkim#include <contrib/dev/acpica/include/acparser.h>
5167754Smsmith
5267754Smsmith
5377424Smsmith#define _COMPONENT          ACPI_DISPATCHER
5491116Smsmith        ACPI_MODULE_NAME    ("dsfield")
5567754Smsmith
56151937Sjkim/* Local prototypes */
5767754Smsmith
58235945Sjkim#ifdef ACPI_ASL_COMPILER
59235945Sjkim#include <contrib/dev/acpica/include/acdisasm.h>
60235945Sjkim
61151937Sjkimstatic ACPI_STATUS
62235945SjkimAcpiDsCreateExternalRegion (
63235945Sjkim    ACPI_STATUS             LookupStatus,
64235945Sjkim    ACPI_PARSE_OBJECT       *Op,
65235945Sjkim    char                    *Path,
66235945Sjkim    ACPI_WALK_STATE         *WalkState,
67235945Sjkim    ACPI_NAMESPACE_NODE     **Node);
68235945Sjkim#endif
69235945Sjkim
70235945Sjkimstatic ACPI_STATUS
71151937SjkimAcpiDsGetFieldNames (
72151937Sjkim    ACPI_CREATE_FIELD_INFO  *Info,
73151937Sjkim    ACPI_WALK_STATE         *WalkState,
74151937Sjkim    ACPI_PARSE_OBJECT       *Arg);
75151937Sjkim
76151937Sjkim
77235945Sjkim#ifdef ACPI_ASL_COMPILER
7867754Smsmith/*******************************************************************************
7967754Smsmith *
80235945Sjkim * FUNCTION:    AcpiDsCreateExternalRegion (iASL Disassembler only)
81235945Sjkim *
82235945Sjkim * PARAMETERS:  LookupStatus    - Status from NsLookup operation
83235945Sjkim *              Op              - Op containing the Field definition and args
84235945Sjkim *              Path            - Pathname of the region
85235945Sjkim *  `           WalkState       - Current method state
86235945Sjkim *              Node            - Where the new region node is returned
87235945Sjkim *
88235945Sjkim * RETURN:      Status
89235945Sjkim *
90235945Sjkim * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
91235945Sjkim *              region node/object.
92235945Sjkim *
93235945Sjkim ******************************************************************************/
94235945Sjkim
95235945Sjkimstatic ACPI_STATUS
96235945SjkimAcpiDsCreateExternalRegion (
97235945Sjkim    ACPI_STATUS             LookupStatus,
98235945Sjkim    ACPI_PARSE_OBJECT       *Op,
99235945Sjkim    char                    *Path,
100235945Sjkim    ACPI_WALK_STATE         *WalkState,
101235945Sjkim    ACPI_NAMESPACE_NODE     **Node)
102235945Sjkim{
103235945Sjkim    ACPI_STATUS             Status;
104235945Sjkim    ACPI_OPERAND_OBJECT     *ObjDesc;
105235945Sjkim
106235945Sjkim
107235945Sjkim    if (LookupStatus != AE_NOT_FOUND)
108235945Sjkim    {
109235945Sjkim        return (LookupStatus);
110235945Sjkim    }
111235945Sjkim
112235945Sjkim    /*
113235945Sjkim     * Table disassembly:
114235945Sjkim     * OperationRegion not found. Generate an External for it, and
115235945Sjkim     * insert the name into the namespace.
116235945Sjkim     */
117281075Sdim    AcpiDmAddOpToExternalList (Op, Path, ACPI_TYPE_REGION, 0, 0);
118306536Sjkim
119235945Sjkim    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_REGION,
120235945Sjkim       ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, WalkState, Node);
121235945Sjkim    if (ACPI_FAILURE (Status))
122235945Sjkim    {
123235945Sjkim        return (Status);
124235945Sjkim    }
125235945Sjkim
126235945Sjkim    /* Must create and install a region object for the new node */
127235945Sjkim
128235945Sjkim    ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
129235945Sjkim    if (!ObjDesc)
130235945Sjkim    {
131235945Sjkim        return (AE_NO_MEMORY);
132235945Sjkim    }
133235945Sjkim
134235945Sjkim    ObjDesc->Region.Node = *Node;
135235945Sjkim    Status = AcpiNsAttachObject (*Node, ObjDesc, ACPI_TYPE_REGION);
136235945Sjkim    return (Status);
137235945Sjkim}
138235945Sjkim#endif
139235945Sjkim
140235945Sjkim
141235945Sjkim/*******************************************************************************
142235945Sjkim *
14385756Smsmith * FUNCTION:    AcpiDsCreateBufferField
14467754Smsmith *
145151937Sjkim * PARAMETERS:  Op                  - Current parse op (CreateXXField)
14685756Smsmith *              WalkState           - Current state
14767754Smsmith *
14867754Smsmith * RETURN:      Status
14967754Smsmith *
15087031Smsmith * DESCRIPTION: Execute the CreateField operators:
15185756Smsmith *              CreateBitFieldOp,
15287031Smsmith *              CreateByteFieldOp,
15387031Smsmith *              CreateWordFieldOp,
154237412Sjkim *              CreateDwordFieldOp,
155237412Sjkim *              CreateQwordFieldOp,
156151937Sjkim *              CreateFieldOp       (all of which define a field in a buffer)
15767754Smsmith *
15867754Smsmith ******************************************************************************/
15967754Smsmith
16067754SmsmithACPI_STATUS
16185756SmsmithAcpiDsCreateBufferField (
16267754Smsmith    ACPI_PARSE_OBJECT       *Op,
16367754Smsmith    ACPI_WALK_STATE         *WalkState)
16467754Smsmith{
16567754Smsmith    ACPI_PARSE_OBJECT       *Arg;
16667754Smsmith    ACPI_NAMESPACE_NODE     *Node;
16785756Smsmith    ACPI_STATUS             Status;
16885756Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
16987031Smsmith    ACPI_OPERAND_OBJECT     *SecondDesc = NULL;
17087031Smsmith    UINT32                  Flags;
17167754Smsmith
17267754Smsmith
173167802Sjkim    ACPI_FUNCTION_TRACE (DsCreateBufferField);
17467754Smsmith
17567754Smsmith
176193267Sjkim    /*
177193267Sjkim     * Get the NameString argument (name of the new BufferField)
178193267Sjkim     */
17999679Siwasaki    if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
18067754Smsmith    {
181193267Sjkim        /* For CreateField, name is the 4th argument */
182193267Sjkim
18385756Smsmith        Arg = AcpiPsGetArg (Op, 3);
18467754Smsmith    }
18585756Smsmith    else
18685756Smsmith    {
187193267Sjkim        /* For all other CreateXXXField operators, name is the 3rd argument */
18867754Smsmith
18985756Smsmith        Arg = AcpiPsGetArg (Op, 2);
19085756Smsmith    }
19167754Smsmith
19285756Smsmith    if (!Arg)
19385756Smsmith    {
19485756Smsmith        return_ACPI_STATUS (AE_AML_NO_OPERAND);
19585756Smsmith    }
19667754Smsmith
197123315Snjl    if (WalkState->DeferredNode)
19887031Smsmith    {
199123315Snjl        Node = WalkState->DeferredNode;
200123315Snjl        Status = AE_OK;
20187031Smsmith    }
20287031Smsmith    else
20387031Smsmith    {
204193267Sjkim        /* Execute flag should always be set when this function is entered */
205193267Sjkim
206193267Sjkim        if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
207123315Snjl        {
208193267Sjkim            return_ACPI_STATUS (AE_AML_INTERNAL);
209123315Snjl        }
210193267Sjkim
211193267Sjkim        /* Creating new namespace node, should not already exist */
212193267Sjkim
213193267Sjkim        Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
214306536Sjkim            ACPI_NS_ERROR_IF_FOUND;
215193267Sjkim
216197104Sjkim        /*
217197104Sjkim         * Mark node temporary if we are executing a normal control
218197104Sjkim         * method. (Don't mark if this is a module-level code method)
219197104Sjkim         */
220197104Sjkim        if (WalkState->MethodNode &&
221197104Sjkim            !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
222123315Snjl        {
223193267Sjkim            Flags |= ACPI_NS_TEMPORARY;
224123315Snjl        }
22587031Smsmith
226193267Sjkim        /* Enter the NameString into the namespace */
227193267Sjkim
228306536Sjkim        Status = AcpiNsLookup (WalkState->ScopeInfo,
229306536Sjkim            Arg->Common.Value.String, ACPI_TYPE_ANY,
230306536Sjkim            ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
231123315Snjl        if (ACPI_FAILURE (Status))
232123315Snjl        {
233167802Sjkim            ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
234123315Snjl            return_ACPI_STATUS (Status);
235123315Snjl        }
23685756Smsmith    }
23767754Smsmith
238167802Sjkim    /*
239167802Sjkim     * We could put the returned object (Node) on the object stack for later,
240151937Sjkim     * but for now, we will put it in the "op" object that the parser uses,
241193267Sjkim     * so we can get it again at the end of this scope.
24285756Smsmith     */
24399679Siwasaki    Op->Common.Node = Node;
24485756Smsmith
24585756Smsmith    /*
246151937Sjkim     * If there is no object attached to the node, this node was just created
247193267Sjkim     * and we need to create the field object. Otherwise, this was a lookup
248151937Sjkim     * of an existing node and we don't want to create the field object again.
24985756Smsmith     */
25087031Smsmith    ObjDesc = AcpiNsGetAttachedObject (Node);
25187031Smsmith    if (ObjDesc)
25285756Smsmith    {
25385756Smsmith        return_ACPI_STATUS (AE_OK);
25485756Smsmith    }
25585756Smsmith
25685756Smsmith    /*
25785756Smsmith     * The Field definition is not fully parsed at this time.
25885756Smsmith     * (We must save the address of the AML for the buffer and index operands)
25985756Smsmith     */
26085756Smsmith
26185756Smsmith    /* Create the buffer field object */
26285756Smsmith
26385756Smsmith    ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD);
26485756Smsmith    if (!ObjDesc)
26585756Smsmith    {
26685756Smsmith        Status = AE_NO_MEMORY;
26785756Smsmith        goto Cleanup;
26885756Smsmith    }
26985756Smsmith
27085756Smsmith    /*
271306536Sjkim     * Remember location in AML stream of the field unit opcode and operands
272306536Sjkim     * -- since the buffer and index operands must be evaluated.
27385756Smsmith     */
274306536Sjkim    SecondDesc = ObjDesc->Common.NextObject;
275306536Sjkim    SecondDesc->Extra.AmlStart = Op->Named.Data;
27699679Siwasaki    SecondDesc->Extra.AmlLength = Op->Named.Length;
277306536Sjkim    ObjDesc->BufferField.Node = Node;
27885756Smsmith
27987031Smsmith    /* Attach constructed field descriptors to parent node */
28085756Smsmith
28185756Smsmith    Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD);
28287031Smsmith    if (ACPI_FAILURE (Status))
28387031Smsmith    {
28487031Smsmith        goto Cleanup;
28587031Smsmith    }
28685756Smsmith
28785756Smsmith
28885756SmsmithCleanup:
28985756Smsmith
29085756Smsmith    /* Remove local reference to the object */
29185756Smsmith
29285756Smsmith    AcpiUtRemoveReference (ObjDesc);
29385756Smsmith    return_ACPI_STATUS (Status);
29485756Smsmith}
29585756Smsmith
29685756Smsmith
29785756Smsmith/*******************************************************************************
29885756Smsmith *
29985756Smsmith * FUNCTION:    AcpiDsGetFieldNames
30085756Smsmith *
30185756Smsmith * PARAMETERS:  Info            - CreateField info structure
30285756Smsmith *  `           WalkState       - Current method state
30385756Smsmith *              Arg             - First parser arg for the field name list
30485756Smsmith *
30585756Smsmith * RETURN:      Status
30685756Smsmith *
307241973Sjkim * DESCRIPTION: Process all named fields in a field declaration. Names are
30885756Smsmith *              entered into the namespace.
30985756Smsmith *
31085756Smsmith ******************************************************************************/
31185756Smsmith
312151937Sjkimstatic ACPI_STATUS
31385756SmsmithAcpiDsGetFieldNames (
31485756Smsmith    ACPI_CREATE_FIELD_INFO  *Info,
31585756Smsmith    ACPI_WALK_STATE         *WalkState,
31685756Smsmith    ACPI_PARSE_OBJECT       *Arg)
31785756Smsmith{
31885756Smsmith    ACPI_STATUS             Status;
319202771Sjkim    UINT64                  Position;
320228110Sjkim    ACPI_PARSE_OBJECT       *Child;
32185756Smsmith
32285756Smsmith
323167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info);
32485756Smsmith
32585756Smsmith
32685756Smsmith    /* First field starts at bit zero */
32785756Smsmith
32885756Smsmith    Info->FieldBitPosition = 0;
32985756Smsmith
33085756Smsmith    /* Process all elements in the field list (of parse nodes) */
33185756Smsmith
33267754Smsmith    while (Arg)
33367754Smsmith    {
33485756Smsmith        /*
335228110Sjkim         * Four types of field elements are handled:
336228110Sjkim         * 1) Name - Enters a new named field into the namespace
337228110Sjkim         * 2) Offset - specifies a bit offset
338228110Sjkim         * 3) AccessAs - changes the access mode/attributes
339228110Sjkim         * 4) Connection - Associate a resource template with the field
34085756Smsmith         */
34199679Siwasaki        switch (Arg->Common.AmlOpcode)
34267754Smsmith        {
34377424Smsmith        case AML_INT_RESERVEDFIELD_OP:
34467754Smsmith
345306536Sjkim            Position = (UINT64) Info->FieldBitPosition +
346306536Sjkim                (UINT64) Arg->Common.Value.Size;
34799679Siwasaki
34899679Siwasaki            if (Position > ACPI_UINT32_MAX)
34991116Smsmith            {
350167802Sjkim                ACPI_ERROR ((AE_INFO,
351167802Sjkim                    "Bit offset within field too large (> 0xFFFFFFFF)"));
35291116Smsmith                return_ACPI_STATUS (AE_SUPPORT);
35391116Smsmith            }
35491116Smsmith
35599679Siwasaki            Info->FieldBitPosition = (UINT32) Position;
35667754Smsmith            break;
35767754Smsmith
35877424Smsmith        case AML_INT_ACCESSFIELD_OP:
359228110Sjkim        case AML_INT_EXTACCESSFIELD_OP:
36067754Smsmith            /*
361228110Sjkim             * Get new AccessType, AccessAttribute, and AccessLength fields
362228110Sjkim             * -- to be used for all field units that follow, until the
363228110Sjkim             * end-of-field or another AccessAs keyword is encountered.
364228110Sjkim             * NOTE. These three bytes are encoded in the integer value
365228110Sjkim             * of the parseop for convenience.
36687031Smsmith             *
367151937Sjkim             * In FieldFlags, preserve the flag bits other than the
368228110Sjkim             * ACCESS_TYPE bits.
36967754Smsmith             */
370228110Sjkim
371228110Sjkim            /* AccessType (ByteAcc, WordAcc, etc.) */
372228110Sjkim
373151937Sjkim            Info->FieldFlags = (UINT8)
374151937Sjkim                ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
375228110Sjkim                ((UINT8) ((UINT32) (Arg->Common.Value.Integer & 0x07))));
37687031Smsmith
377228110Sjkim            /* AccessAttribute (AttribQuick, AttribByte, etc.) */
378228110Sjkim
379306536Sjkim            Info->Attribute = (UINT8)
380306536Sjkim                ((Arg->Common.Value.Integer >> 8) & 0xFF);
381228110Sjkim
382228110Sjkim            /* AccessLength (for serial/buffer protocols) */
383228110Sjkim
384306536Sjkim            Info->AccessLength = (UINT8)
385306536Sjkim                ((Arg->Common.Value.Integer >> 16) & 0xFF);
38667754Smsmith            break;
38767754Smsmith
388228110Sjkim        case AML_INT_CONNECTION_OP:
389228110Sjkim            /*
390228110Sjkim             * Clear any previous connection. New connection is used for all
391228110Sjkim             * fields that follow, similar to AccessAs
392228110Sjkim             */
393228110Sjkim            Info->ResourceBuffer = NULL;
394228110Sjkim            Info->ConnectionNode = NULL;
395281075Sdim            Info->PinNumberIndex = 0;
39667754Smsmith
397228110Sjkim            /*
398228110Sjkim             * A Connection() is either an actual resource descriptor (buffer)
399228110Sjkim             * or a named reference to a resource template
400228110Sjkim             */
401228110Sjkim            Child = Arg->Common.Value.Arg;
402228110Sjkim            if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
403228110Sjkim            {
404228110Sjkim                Info->ResourceBuffer = Child->Named.Data;
405228110Sjkim                Info->ResourceLength = (UINT16) Child->Named.Value.Integer;
406228110Sjkim            }
407228110Sjkim            else
408228110Sjkim            {
409228110Sjkim                /* Lookup the Connection() namepath, it should already exist */
410228110Sjkim
411228110Sjkim                Status = AcpiNsLookup (WalkState->ScopeInfo,
412306536Sjkim                    Child->Common.Value.Name, ACPI_TYPE_ANY,
413306536Sjkim                    ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
414306536Sjkim                    WalkState, &Info->ConnectionNode);
415228110Sjkim                if (ACPI_FAILURE (Status))
416228110Sjkim                {
417228110Sjkim                    ACPI_ERROR_NAMESPACE (Child->Common.Value.Name, Status);
418228110Sjkim                    return_ACPI_STATUS (Status);
419228110Sjkim                }
420228110Sjkim            }
421228110Sjkim            break;
422228110Sjkim
42377424Smsmith        case AML_INT_NAMEDFIELD_OP:
42467754Smsmith
425193267Sjkim            /* Lookup the name, it should already exist */
42685756Smsmith
42767754Smsmith            Status = AcpiNsLookup (WalkState->ScopeInfo,
428306536Sjkim                (char *) &Arg->Named.Name, Info->FieldType,
429306536Sjkim                ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
430306536Sjkim                WalkState, &Info->FieldNode);
43167754Smsmith            if (ACPI_FAILURE (Status))
43267754Smsmith            {
433167802Sjkim                ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
434193267Sjkim                return_ACPI_STATUS (Status);
43567754Smsmith            }
43687031Smsmith            else
43787031Smsmith            {
43899679Siwasaki                Arg->Common.Node = Info->FieldNode;
43999679Siwasaki                Info->FieldBitLength = Arg->Common.Value.Size;
44067754Smsmith
441193267Sjkim                /*
442193267Sjkim                 * If there is no object attached to the node, this node was
443193267Sjkim                 * just created and we need to create the field object.
444193267Sjkim                 * Otherwise, this was a lookup of an existing node and we
445193267Sjkim                 * don't want to create the field object again.
446193267Sjkim                 */
447193267Sjkim                if (!AcpiNsGetAttachedObject (Info->FieldNode))
44887031Smsmith                {
449193267Sjkim                    Status = AcpiExPrepFieldValue (Info);
450193267Sjkim                    if (ACPI_FAILURE (Status))
451193267Sjkim                    {
452193267Sjkim                        return_ACPI_STATUS (Status);
453193267Sjkim                    }
45487031Smsmith                }
45567754Smsmith            }
45667754Smsmith
45785756Smsmith            /* Keep track of bit position for the next field */
45867754Smsmith
459306536Sjkim            Position = (UINT64) Info->FieldBitPosition +
460306536Sjkim                (UINT64) Arg->Common.Value.Size;
46199679Siwasaki
46299679Siwasaki            if (Position > ACPI_UINT32_MAX)
46391116Smsmith            {
464167802Sjkim                ACPI_ERROR ((AE_INFO,
465167802Sjkim                    "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
466167802Sjkim                    ACPI_CAST_PTR (char, &Info->FieldNode->Name)));
46791116Smsmith                return_ACPI_STATUS (AE_SUPPORT);
46891116Smsmith            }
46991116Smsmith
47085756Smsmith            Info->FieldBitPosition += Info->FieldBitLength;
471281075Sdim            Info->PinNumberIndex++; /* Index relative to previous Connection() */
47267754Smsmith            break;
47385756Smsmith
47485756Smsmith        default:
47585756Smsmith
476167802Sjkim            ACPI_ERROR ((AE_INFO,
477306536Sjkim                "Invalid opcode in field list: 0x%X",
478306536Sjkim                Arg->Common.AmlOpcode));
47999679Siwasaki            return_ACPI_STATUS (AE_AML_BAD_OPCODE);
48067754Smsmith        }
48167754Smsmith
48299679Siwasaki        Arg = Arg->Common.Next;
48367754Smsmith    }
48467754Smsmith
48585756Smsmith    return_ACPI_STATUS (AE_OK);
48685756Smsmith}
48785756Smsmith
48885756Smsmith
48985756Smsmith/*******************************************************************************
49085756Smsmith *
49185756Smsmith * FUNCTION:    AcpiDsCreateField
49285756Smsmith *
49385756Smsmith * PARAMETERS:  Op              - Op containing the Field definition and args
49485756Smsmith *              RegionNode      - Object for the containing Operation Region
49585756Smsmith *  `           WalkState       - Current method state
49685756Smsmith *
49785756Smsmith * RETURN:      Status
49885756Smsmith *
49985756Smsmith * DESCRIPTION: Create a new field in the specified operation region
50085756Smsmith *
50185756Smsmith ******************************************************************************/
50285756Smsmith
50385756SmsmithACPI_STATUS
50485756SmsmithAcpiDsCreateField (
50585756Smsmith    ACPI_PARSE_OBJECT       *Op,
50685756Smsmith    ACPI_NAMESPACE_NODE     *RegionNode,
50785756Smsmith    ACPI_WALK_STATE         *WalkState)
50885756Smsmith{
50999679Siwasaki    ACPI_STATUS             Status;
51085756Smsmith    ACPI_PARSE_OBJECT       *Arg;
51185756Smsmith    ACPI_CREATE_FIELD_INFO  Info;
51285756Smsmith
51385756Smsmith
514167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op);
51585756Smsmith
51685756Smsmith
51785756Smsmith    /* First arg is the name of the parent OpRegion (must already exist) */
51885756Smsmith
51999679Siwasaki    Arg = Op->Common.Value.Arg;
520235945Sjkim
52185756Smsmith    if (!RegionNode)
52285756Smsmith    {
52399679Siwasaki        Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
524306536Sjkim            ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
525306536Sjkim            ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
526235945Sjkim#ifdef ACPI_ASL_COMPILER
527235945Sjkim        Status = AcpiDsCreateExternalRegion (Status, Arg,
528235945Sjkim            Arg->Common.Value.Name, WalkState, &RegionNode);
529235945Sjkim#endif
53085756Smsmith        if (ACPI_FAILURE (Status))
53185756Smsmith        {
532167802Sjkim            ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
53385756Smsmith            return_ACPI_STATUS (Status);
53485756Smsmith        }
53585756Smsmith    }
53685756Smsmith
537306536Sjkim    memset (&Info, 0, sizeof (ACPI_CREATE_FIELD_INFO));
538228110Sjkim
53985756Smsmith    /* Second arg is the field flags */
54085756Smsmith
54199679Siwasaki    Arg = Arg->Common.Next;
542117521Snjl    Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
54387031Smsmith    Info.Attribute = 0;
54485756Smsmith
54585756Smsmith    /* Each remaining arg is a Named Field */
54685756Smsmith
547107325Siwasaki    Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD;
54885756Smsmith    Info.RegionNode = RegionNode;
54985756Smsmith
55099679Siwasaki    Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
55167754Smsmith    return_ACPI_STATUS (Status);
55267754Smsmith}
55367754Smsmith
55467754Smsmith
55567754Smsmith/*******************************************************************************
55667754Smsmith *
55787031Smsmith * FUNCTION:    AcpiDsInitFieldObjects
55887031Smsmith *
55987031Smsmith * PARAMETERS:  Op              - Op containing the Field definition and args
56087031Smsmith *  `           WalkState       - Current method state
56187031Smsmith *
56287031Smsmith * RETURN:      Status
56387031Smsmith *
56487031Smsmith * DESCRIPTION: For each "Field Unit" name in the argument list that is
56587031Smsmith *              part of the field declaration, enter the name into the
56687031Smsmith *              namespace.
56787031Smsmith *
56887031Smsmith ******************************************************************************/
56987031Smsmith
57087031SmsmithACPI_STATUS
57187031SmsmithAcpiDsInitFieldObjects (
57287031Smsmith    ACPI_PARSE_OBJECT       *Op,
57387031Smsmith    ACPI_WALK_STATE         *WalkState)
57487031Smsmith{
57599679Siwasaki    ACPI_STATUS             Status;
57687031Smsmith    ACPI_PARSE_OBJECT       *Arg = NULL;
57787031Smsmith    ACPI_NAMESPACE_NODE     *Node;
57887031Smsmith    UINT8                   Type = 0;
579193267Sjkim    UINT32                  Flags;
58087031Smsmith
58187031Smsmith
582167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op);
58387031Smsmith
58487031Smsmith
585193267Sjkim    /* Execute flag should always be set when this function is entered */
586193267Sjkim
587193267Sjkim    if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
588193267Sjkim    {
589193267Sjkim        if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP)
590193267Sjkim        {
591193267Sjkim            /* BankField Op is deferred, just return OK */
592193267Sjkim
593193267Sjkim            return_ACPI_STATUS (AE_OK);
594193267Sjkim        }
595193267Sjkim
596193267Sjkim        return_ACPI_STATUS (AE_AML_INTERNAL);
597193267Sjkim    }
598193267Sjkim
599193267Sjkim    /*
600193267Sjkim     * Get the FieldList argument for this opcode. This is the start of the
601193267Sjkim     * list of field elements.
602193267Sjkim     */
60387031Smsmith    switch (WalkState->Opcode)
60487031Smsmith    {
60587031Smsmith    case AML_FIELD_OP:
606250838Sjkim
60787031Smsmith        Arg = AcpiPsGetArg (Op, 2);
608107325Siwasaki        Type = ACPI_TYPE_LOCAL_REGION_FIELD;
60987031Smsmith        break;
61087031Smsmith
61187031Smsmith    case AML_BANK_FIELD_OP:
612250838Sjkim
61387031Smsmith        Arg = AcpiPsGetArg (Op, 4);
614107325Siwasaki        Type = ACPI_TYPE_LOCAL_BANK_FIELD;
61587031Smsmith        break;
61687031Smsmith
61787031Smsmith    case AML_INDEX_FIELD_OP:
618250838Sjkim
61987031Smsmith        Arg = AcpiPsGetArg (Op, 3);
620107325Siwasaki        Type = ACPI_TYPE_LOCAL_INDEX_FIELD;
62187031Smsmith        break;
62299679Siwasaki
62399679Siwasaki    default:
624250838Sjkim
62599679Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
62687031Smsmith    }
62787031Smsmith
628193267Sjkim    /* Creating new namespace node(s), should not already exist */
629193267Sjkim
630193267Sjkim    Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
631306536Sjkim        ACPI_NS_ERROR_IF_FOUND;
632193267Sjkim
633197104Sjkim    /*
634197104Sjkim     * Mark node(s) temporary if we are executing a normal control
635197104Sjkim     * method. (Don't mark if this is a module-level code method)
636197104Sjkim     */
637197104Sjkim    if (WalkState->MethodNode &&
638197104Sjkim        !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
639193267Sjkim    {
640193267Sjkim        Flags |= ACPI_NS_TEMPORARY;
641193267Sjkim    }
642193267Sjkim
64387031Smsmith    /*
64487031Smsmith     * Walk the list of entries in the FieldList
645193267Sjkim     * Note: FieldList can be of zero length. In this case, Arg will be NULL.
64687031Smsmith     */
64787031Smsmith    while (Arg)
64887031Smsmith    {
649193267Sjkim        /*
650228110Sjkim         * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
651228110Sjkim         * in the field names in order to enter them into the namespace.
652193267Sjkim         */
65399679Siwasaki        if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
65487031Smsmith        {
65587031Smsmith            Status = AcpiNsLookup (WalkState->ScopeInfo,
656306536Sjkim                (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1,
657306536Sjkim                Flags, WalkState, &Node);
65887031Smsmith            if (ACPI_FAILURE (Status))
65987031Smsmith            {
660167802Sjkim                ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
66187031Smsmith                if (Status != AE_ALREADY_EXISTS)
66287031Smsmith                {
66387031Smsmith                    return_ACPI_STATUS (Status);
66487031Smsmith                }
66587031Smsmith
66699679Siwasaki                /* Name already exists, just ignore this error */
66799679Siwasaki
66899679Siwasaki                Status = AE_OK;
66987031Smsmith            }
67087031Smsmith
67199679Siwasaki            Arg->Common.Node = Node;
67287031Smsmith        }
67387031Smsmith
674193267Sjkim        /* Get the next field element in the list */
67587031Smsmith
67699679Siwasaki        Arg = Arg->Common.Next;
67787031Smsmith    }
67887031Smsmith
67999679Siwasaki    return_ACPI_STATUS (AE_OK);
68087031Smsmith}
68187031Smsmith
68287031Smsmith
68387031Smsmith/*******************************************************************************
68487031Smsmith *
68567754Smsmith * FUNCTION:    AcpiDsCreateBankField
68667754Smsmith *
68767754Smsmith * PARAMETERS:  Op              - Op containing the Field definition and args
68877424Smsmith *              RegionNode      - Object for the containing Operation Region
689193267Sjkim *              WalkState       - Current method state
69067754Smsmith *
69167754Smsmith * RETURN:      Status
69267754Smsmith *
69367754Smsmith * DESCRIPTION: Create a new bank field in the specified operation region
69467754Smsmith *
69567754Smsmith ******************************************************************************/
69667754Smsmith
69767754SmsmithACPI_STATUS
69867754SmsmithAcpiDsCreateBankField (
69967754Smsmith    ACPI_PARSE_OBJECT       *Op,
70067754Smsmith    ACPI_NAMESPACE_NODE     *RegionNode,
70167754Smsmith    ACPI_WALK_STATE         *WalkState)
70267754Smsmith{
70399679Siwasaki    ACPI_STATUS             Status;
70467754Smsmith    ACPI_PARSE_OBJECT       *Arg;
70585756Smsmith    ACPI_CREATE_FIELD_INFO  Info;
70667754Smsmith
70767754Smsmith
708167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op);
70967754Smsmith
71067754Smsmith
71185756Smsmith    /* First arg is the name of the parent OpRegion (must already exist) */
71267754Smsmith
71399679Siwasaki    Arg = Op->Common.Value.Arg;
71467754Smsmith    if (!RegionNode)
71567754Smsmith    {
71699679Siwasaki        Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
717306536Sjkim            ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
718306536Sjkim            ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
719235945Sjkim#ifdef ACPI_ASL_COMPILER
720235945Sjkim        Status = AcpiDsCreateExternalRegion (Status, Arg,
721235945Sjkim            Arg->Common.Value.Name, WalkState, &RegionNode);
722235945Sjkim#endif
72367754Smsmith        if (ACPI_FAILURE (Status))
72467754Smsmith        {
725167802Sjkim            ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
72667754Smsmith            return_ACPI_STATUS (Status);
72767754Smsmith        }
72867754Smsmith    }
72967754Smsmith
730107325Siwasaki    /* Second arg is the Bank Register (Field) (must already exist) */
73167754Smsmith
73299679Siwasaki    Arg = Arg->Common.Next;
73399679Siwasaki    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
734306536Sjkim        ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
735306536Sjkim        ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
73667754Smsmith    if (ACPI_FAILURE (Status))
73767754Smsmith    {
738167802Sjkim        ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
73967754Smsmith        return_ACPI_STATUS (Status);
74067754Smsmith    }
74167754Smsmith
742193267Sjkim    /*
743193267Sjkim     * Third arg is the BankValue
744193267Sjkim     * This arg is a TermArg, not a constant
745193267Sjkim     * It will be evaluated later, by AcpiDsEvalBankFieldOperands
746193267Sjkim     */
74799679Siwasaki    Arg = Arg->Common.Next;
74867754Smsmith
74985756Smsmith    /* Fourth arg is the field flags */
75067754Smsmith
75199679Siwasaki    Arg = Arg->Common.Next;
752117521Snjl    Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
75367754Smsmith
75467754Smsmith    /* Each remaining arg is a Named Field */
75567754Smsmith
756107325Siwasaki    Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD;
75785756Smsmith    Info.RegionNode = RegionNode;
75867754Smsmith
759193267Sjkim    /*
760193267Sjkim     * Use Info.DataRegisterNode to store BankField Op
761306536Sjkim     * It's safe because DataRegisterNode will never be used when create
762306536Sjkim     * bank field \we store AmlStart and AmlLength in the BankField Op for
763306536Sjkim     * late evaluation. Used in AcpiExPrepFieldValue(Info)
764193267Sjkim     *
765306536Sjkim     * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like
766306536Sjkim     * "void *ParentOp"?
767193267Sjkim     */
768193267Sjkim    Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op;
769193267Sjkim
77099679Siwasaki    Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
77167754Smsmith    return_ACPI_STATUS (Status);
77267754Smsmith}
77367754Smsmith
77467754Smsmith
77567754Smsmith/*******************************************************************************
77667754Smsmith *
77767754Smsmith * FUNCTION:    AcpiDsCreateIndexField
77867754Smsmith *
77967754Smsmith * PARAMETERS:  Op              - Op containing the Field definition and args
78077424Smsmith *              RegionNode      - Object for the containing Operation Region
78177424Smsmith *  `           WalkState       - Current method state
78267754Smsmith *
78367754Smsmith * RETURN:      Status
78467754Smsmith *
78567754Smsmith * DESCRIPTION: Create a new index field in the specified operation region
78667754Smsmith *
78767754Smsmith ******************************************************************************/
78867754Smsmith
78967754SmsmithACPI_STATUS
79067754SmsmithAcpiDsCreateIndexField (
79167754Smsmith    ACPI_PARSE_OBJECT       *Op,
79277424Smsmith    ACPI_NAMESPACE_NODE     *RegionNode,
79367754Smsmith    ACPI_WALK_STATE         *WalkState)
79467754Smsmith{
79567754Smsmith    ACPI_STATUS             Status;
79667754Smsmith    ACPI_PARSE_OBJECT       *Arg;
79785756Smsmith    ACPI_CREATE_FIELD_INFO  Info;
79867754Smsmith
79967754Smsmith
800167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op);
80167754Smsmith
80267754Smsmith
80385756Smsmith    /* First arg is the name of the Index register (must already exist) */
80485756Smsmith
80599679Siwasaki    Arg = Op->Common.Value.Arg;
80699679Siwasaki    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
807306536Sjkim        ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
808306536Sjkim        ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
80967754Smsmith    if (ACPI_FAILURE (Status))
81067754Smsmith    {
811167802Sjkim        ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
81267754Smsmith        return_ACPI_STATUS (Status);
81367754Smsmith    }
81467754Smsmith
81585756Smsmith    /* Second arg is the data register (must already exist) */
81667754Smsmith
81799679Siwasaki    Arg = Arg->Common.Next;
81899679Siwasaki    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
819306536Sjkim        ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
820306536Sjkim        ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode);
82167754Smsmith    if (ACPI_FAILURE (Status))
82267754Smsmith    {
823167802Sjkim        ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
82467754Smsmith        return_ACPI_STATUS (Status);
82567754Smsmith    }
82667754Smsmith
82767754Smsmith    /* Next arg is the field flags */
82867754Smsmith
82999679Siwasaki    Arg = Arg->Common.Next;
830117521Snjl    Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
83167754Smsmith
83267754Smsmith    /* Each remaining arg is a Named Field */
83367754Smsmith
834107325Siwasaki    Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD;
83585756Smsmith    Info.RegionNode = RegionNode;
83667754Smsmith
83799679Siwasaki    Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
83867754Smsmith    return_ACPI_STATUS (Status);
83967754Smsmith}
840