167754Smsmith/******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: dsobject - Dispatcher object management routines
467754Smsmith *
567754Smsmith *****************************************************************************/
667754Smsmith
7217365Sjkim/*
8298714Sjkim * 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/acparser.h>
47193341Sjkim#include <contrib/dev/acpica/include/amlcode.h>
48193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
50193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
5167754Smsmith
5277424Smsmith#define _COMPONENT          ACPI_DISPATCHER
5391116Smsmith        ACPI_MODULE_NAME    ("dsobject")
5467754Smsmith
55167802Sjkim/* Local prototypes */
56167802Sjkim
57151937Sjkimstatic ACPI_STATUS
58151937SjkimAcpiDsBuildInternalObject (
59151937Sjkim    ACPI_WALK_STATE         *WalkState,
60151937Sjkim    ACPI_PARSE_OBJECT       *Op,
61151937Sjkim    ACPI_OPERAND_OBJECT     **ObjDescPtr);
6267754Smsmith
63151937Sjkim
64100966Siwasaki#ifndef ACPI_NO_METHOD_EXECUTION
65151937Sjkim/*******************************************************************************
6667754Smsmith *
6799146Siwasaki * FUNCTION:    AcpiDsBuildInternalObject
6867754Smsmith *
6999146Siwasaki * PARAMETERS:  WalkState       - Current walk state
7099146Siwasaki *              Op              - Parser object to be translated
7167754Smsmith *              ObjDescPtr      - Where the ACPI internal object is returned
7267754Smsmith *
7367754Smsmith * RETURN:      Status
7467754Smsmith *
7567754Smsmith * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
7667754Smsmith *              Simple objects are any objects other than a package object!
7767754Smsmith *
78151937Sjkim ******************************************************************************/
7967754Smsmith
80151937Sjkimstatic ACPI_STATUS
8199146SiwasakiAcpiDsBuildInternalObject (
8267754Smsmith    ACPI_WALK_STATE         *WalkState,
8367754Smsmith    ACPI_PARSE_OBJECT       *Op,
8467754Smsmith    ACPI_OPERAND_OBJECT     **ObjDescPtr)
8567754Smsmith{
8667754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
8767754Smsmith    ACPI_STATUS             Status;
88209746Sjkim    ACPI_OBJECT_TYPE        Type;
8967754Smsmith
9067754Smsmith
91167802Sjkim    ACPI_FUNCTION_TRACE (DsBuildInternalObject);
9267754Smsmith
9367754Smsmith
94104470Siwasaki    *ObjDescPtr = NULL;
9599679Siwasaki    if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
9667754Smsmith    {
9767754Smsmith        /*
98167802Sjkim         * This is a named object reference. If this name was
9987031Smsmith         * previously looked up in the namespace, it was stored in this op.
10067754Smsmith         * Otherwise, go ahead and look it up now
10167754Smsmith         */
10299679Siwasaki        if (!Op->Common.Node)
10367754Smsmith        {
104151937Sjkim            Status = AcpiNsLookup (WalkState->ScopeInfo,
105298714Sjkim                Op->Common.Value.String,
106298714Sjkim                ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
107298714Sjkim                ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL,
108298714Sjkim                ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &(Op->Common.Node)));
10967754Smsmith            if (ACPI_FAILURE (Status))
11067754Smsmith            {
111167802Sjkim                /* Check if we are resolving a named reference within a package */
112167802Sjkim
113167802Sjkim                if ((Status == AE_NOT_FOUND) && (AcpiGbl_EnableInterpreterSlack) &&
114167802Sjkim
115167802Sjkim                    ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
116167802Sjkim                     (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
117167802Sjkim                {
118167802Sjkim                    /*
119167802Sjkim                     * We didn't find the target and we are populating elements
120167802Sjkim                     * of a package - ignore if slack enabled. Some ASL code
121167802Sjkim                     * contains dangling invalid references in packages and
122167802Sjkim                     * expects that no exception will be issued. Leave the
123167802Sjkim                     * element as a null element. It cannot be used, but it
124167802Sjkim                     * can be overwritten by subsequent ASL code - this is
125167802Sjkim                     * typically the case.
126167802Sjkim                     */
127167802Sjkim                    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
128167802Sjkim                        "Ignoring unresolved reference in package [%4.4s]\n",
129167802Sjkim                        WalkState->ScopeInfo->Scope.Node->Name.Ascii));
130167802Sjkim
131167802Sjkim                    return_ACPI_STATUS (AE_OK);
132167802Sjkim                }
133167802Sjkim                else
134167802Sjkim                {
135167802Sjkim                    ACPI_ERROR_NAMESPACE (Op->Common.Value.String, Status);
136167802Sjkim                }
137167802Sjkim
138104470Siwasaki                return_ACPI_STATUS (Status);
13967754Smsmith            }
14067754Smsmith        }
141193267Sjkim
142193267Sjkim        /* Special object resolution for elements of a package */
143193267Sjkim
144193267Sjkim        if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
145193267Sjkim            (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
146193267Sjkim        {
147193267Sjkim            /*
148193267Sjkim             * Attempt to resolve the node to a value before we insert it into
149193267Sjkim             * the package. If this is a reference to a common data type,
150193267Sjkim             * resolve it immediately. According to the ACPI spec, package
151193267Sjkim             * elements can only be "data objects" or method references.
152193267Sjkim             * Attempt to resolve to an Integer, Buffer, String or Package.
153193267Sjkim             * If cannot, return the named reference (for things like Devices,
154193267Sjkim             * Methods, etc.) Buffer Fields and Fields will resolve to simple
155193267Sjkim             * objects (int/buf/str/pkg).
156193267Sjkim             *
157193267Sjkim             * NOTE: References to things like Devices, Methods, Mutexes, etc.
158193267Sjkim             * will remain as named references. This behavior is not described
159193267Sjkim             * in the ACPI spec, but it appears to be an oversight.
160193267Sjkim             */
161193267Sjkim            ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Op->Common.Node);
162193267Sjkim
163193267Sjkim            Status = AcpiExResolveNodeToValue (
164298714Sjkim                ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc),
165298714Sjkim                WalkState);
166193267Sjkim            if (ACPI_FAILURE (Status))
167193267Sjkim            {
168193267Sjkim                return_ACPI_STATUS (Status);
169193267Sjkim            }
170193267Sjkim
171209746Sjkim            /*
172209746Sjkim             * Special handling for Alias objects. We need to setup the type
173209746Sjkim             * and the Op->Common.Node to point to the Alias target. Note,
174209746Sjkim             * Alias has at most one level of indirection internally.
175209746Sjkim             */
176209746Sjkim            Type = Op->Common.Node->Type;
177209746Sjkim            if (Type == ACPI_TYPE_LOCAL_ALIAS)
178193267Sjkim            {
179209746Sjkim                Type = ObjDesc->Common.Type;
180209746Sjkim                Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
181209746Sjkim                    Op->Common.Node->Object);
182209746Sjkim            }
183209746Sjkim
184209746Sjkim            switch (Type)
185209746Sjkim            {
186193267Sjkim            /*
187193267Sjkim             * For these types, we need the actual node, not the subobject.
188193267Sjkim             * However, the subobject did not get an extra reference count above.
189193267Sjkim             *
190193267Sjkim             * TBD: should ExResolveNodeToValue be changed to fix this?
191193267Sjkim             */
192193267Sjkim            case ACPI_TYPE_DEVICE:
193193267Sjkim            case ACPI_TYPE_THERMAL:
194193267Sjkim
195193267Sjkim                AcpiUtAddReference (Op->Common.Node->Object);
196193267Sjkim
197193267Sjkim                /*lint -fallthrough */
198193267Sjkim            /*
199193267Sjkim             * For these types, we need the actual node, not the subobject.
200193267Sjkim             * The subobject got an extra reference count in ExResolveNodeToValue.
201193267Sjkim             */
202193267Sjkim            case ACPI_TYPE_MUTEX:
203193267Sjkim            case ACPI_TYPE_METHOD:
204193267Sjkim            case ACPI_TYPE_POWER:
205193267Sjkim            case ACPI_TYPE_PROCESSOR:
206193267Sjkim            case ACPI_TYPE_EVENT:
207193267Sjkim            case ACPI_TYPE_REGION:
208193267Sjkim
209193267Sjkim                /* We will create a reference object for these types below */
210193267Sjkim                break;
211193267Sjkim
212193267Sjkim            default:
213193267Sjkim                /*
214193267Sjkim                 * All other types - the node was resolved to an actual
215193267Sjkim                 * object, we are done.
216193267Sjkim                 */
217193267Sjkim                goto Exit;
218193267Sjkim            }
219193267Sjkim        }
22067754Smsmith    }
22167754Smsmith
222167802Sjkim    /* Create and init a new internal ACPI object */
22367754Smsmith
224151937Sjkim    ObjDesc = AcpiUtCreateInternalObject (
225298714Sjkim        (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType);
22667754Smsmith    if (!ObjDesc)
22767754Smsmith    {
22867754Smsmith        return_ACPI_STATUS (AE_NO_MEMORY);
22967754Smsmith    }
23067754Smsmith
231298714Sjkim    Status = AcpiDsInitObjectFromOp (
232298714Sjkim        WalkState, Op, Op->Common.AmlOpcode, &ObjDesc);
23367754Smsmith    if (ACPI_FAILURE (Status))
23467754Smsmith    {
23577424Smsmith        AcpiUtRemoveReference (ObjDesc);
23667754Smsmith        return_ACPI_STATUS (Status);
23767754Smsmith    }
23867754Smsmith
239193267SjkimExit:
24067754Smsmith    *ObjDescPtr = ObjDesc;
241193267Sjkim    return_ACPI_STATUS (Status);
24267754Smsmith}
24367754Smsmith
24467754Smsmith
245151937Sjkim/*******************************************************************************
24667754Smsmith *
24799146Siwasaki * FUNCTION:    AcpiDsBuildInternalBufferObj
24867754Smsmith *
24999679Siwasaki * PARAMETERS:  WalkState       - Current walk state
25099679Siwasaki *              Op              - Parser object to be translated
25199679Siwasaki *              BufferLength    - Length of the buffer
25267754Smsmith *              ObjDescPtr      - Where the ACPI internal object is returned
25367754Smsmith *
25467754Smsmith * RETURN:      Status
25567754Smsmith *
25667754Smsmith * DESCRIPTION: Translate a parser Op package object to the equivalent
25767754Smsmith *              namespace object
25867754Smsmith *
259151937Sjkim ******************************************************************************/
26067754Smsmith
26167754SmsmithACPI_STATUS
26299146SiwasakiAcpiDsBuildInternalBufferObj (
26367754Smsmith    ACPI_WALK_STATE         *WalkState,
26467754Smsmith    ACPI_PARSE_OBJECT       *Op,
26599146Siwasaki    UINT32                  BufferLength,
26667754Smsmith    ACPI_OPERAND_OBJECT     **ObjDescPtr)
26767754Smsmith{
26867754Smsmith    ACPI_PARSE_OBJECT       *Arg;
26967754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
27099679Siwasaki    ACPI_PARSE_OBJECT       *ByteList;
27199146Siwasaki    UINT32                  ByteListLength = 0;
27267754Smsmith
27367754Smsmith
274167802Sjkim    ACPI_FUNCTION_TRACE (DsBuildInternalBufferObj);
27567754Smsmith
27667754Smsmith
277167802Sjkim    /*
278167802Sjkim     * If we are evaluating a Named buffer object "Name (xxxx, Buffer)".
279167802Sjkim     * The buffer object already exists (from the NS node), otherwise it must
280167802Sjkim     * be created.
281167802Sjkim     */
28299146Siwasaki    ObjDesc = *ObjDescPtr;
283167802Sjkim    if (!ObjDesc)
28467754Smsmith    {
28599146Siwasaki        /* Create a new buffer object */
28667754Smsmith
28799146Siwasaki        ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
28899146Siwasaki        *ObjDescPtr = ObjDesc;
28999146Siwasaki        if (!ObjDesc)
29099146Siwasaki        {
29199146Siwasaki            return_ACPI_STATUS (AE_NO_MEMORY);
29299146Siwasaki        }
29399146Siwasaki    }
29467754Smsmith
29567754Smsmith    /*
29699146Siwasaki     * Second arg is the buffer data (optional) ByteList can be either
297241973Sjkim     * individual bytes or a string initializer. In either case, a
29899146Siwasaki     * ByteList appears in the AML.
29967754Smsmith     */
30099679Siwasaki    Arg = Op->Common.Value.Arg;         /* skip first arg */
30167754Smsmith
30299679Siwasaki    ByteList = Arg->Named.Next;
30399146Siwasaki    if (ByteList)
30467754Smsmith    {
30599679Siwasaki        if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP)
30699146Siwasaki        {
307167802Sjkim            ACPI_ERROR ((AE_INFO,
308204773Sjkim                "Expecting bytelist, found AML opcode 0x%X in op %p",
30999679Siwasaki                ByteList->Common.AmlOpcode, ByteList));
31099146Siwasaki
31199146Siwasaki            AcpiUtRemoveReference (ObjDesc);
31299146Siwasaki            return (AE_TYPE);
31399146Siwasaki        }
31499146Siwasaki
315117521Snjl        ByteListLength = (UINT32) ByteList->Common.Value.Integer;
31667754Smsmith    }
31767754Smsmith
31867754Smsmith    /*
31999146Siwasaki     * The buffer length (number of bytes) will be the larger of:
320102550Siwasaki     * 1) The specified buffer length and
32199146Siwasaki     * 2) The length of the initializer byte list
32267754Smsmith     */
32399146Siwasaki    ObjDesc->Buffer.Length = BufferLength;
32499146Siwasaki    if (ByteListLength > BufferLength)
32567754Smsmith    {
32699146Siwasaki        ObjDesc->Buffer.Length = ByteListLength;
32799146Siwasaki    }
32867754Smsmith
32999146Siwasaki    /* Allocate the buffer */
33067754Smsmith
33199146Siwasaki    if (ObjDesc->Buffer.Length == 0)
33299146Siwasaki    {
33399146Siwasaki        ObjDesc->Buffer.Pointer = NULL;
334117521Snjl        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
335117521Snjl            "Buffer defined with zero length in AML, creating\n"));
33667754Smsmith    }
337114237Snjl    else
33899146Siwasaki    {
339298714Sjkim        ObjDesc->Buffer.Pointer =
340298714Sjkim            ACPI_ALLOCATE_ZEROED (ObjDesc->Buffer.Length);
341114237Snjl        if (!ObjDesc->Buffer.Pointer)
342114237Snjl        {
343114237Snjl            AcpiUtDeleteObjectDesc (ObjDesc);
344114237Snjl            return_ACPI_STATUS (AE_NO_MEMORY);
345114237Snjl        }
34699146Siwasaki
347114237Snjl        /* Initialize buffer from the ByteList (if present) */
34899146Siwasaki
349114237Snjl        if (ByteList)
350114237Snjl        {
351284583Sjkim            memcpy (ObjDesc->Buffer.Pointer, ByteList->Named.Data,
352298714Sjkim                ByteListLength);
353114237Snjl        }
35499146Siwasaki    }
35599146Siwasaki
35699146Siwasaki    ObjDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
357167802Sjkim    Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
35899146Siwasaki    return_ACPI_STATUS (AE_OK);
35967754Smsmith}
36067754Smsmith
36167754Smsmith
362151937Sjkim/*******************************************************************************
36367754Smsmith *
36499146Siwasaki * FUNCTION:    AcpiDsBuildInternalPackageObj
36567754Smsmith *
36699679Siwasaki * PARAMETERS:  WalkState       - Current walk state
36799679Siwasaki *              Op              - Parser object to be translated
368167802Sjkim *              ElementCount    - Number of elements in the package - this is
369167802Sjkim *                                the NumElements argument to Package()
37067754Smsmith *              ObjDescPtr      - Where the ACPI internal object is returned
37167754Smsmith *
37267754Smsmith * RETURN:      Status
37367754Smsmith *
37499146Siwasaki * DESCRIPTION: Translate a parser Op package object to the equivalent
37599146Siwasaki *              namespace object
37667754Smsmith *
377167802Sjkim * NOTE: The number of elements in the package will be always be the NumElements
378167802Sjkim * count, regardless of the number of elements in the package list. If
379167802Sjkim * NumElements is smaller, only that many package list elements are used.
380167802Sjkim * if NumElements is larger, the Package object is padded out with
381167802Sjkim * objects of type Uninitialized (as per ACPI spec.)
382167802Sjkim *
383167802Sjkim * Even though the ASL compilers do not allow NumElements to be smaller
384167802Sjkim * than the Package list length (for the fixed length package opcode), some
385167802Sjkim * BIOS code modifies the AML on the fly to adjust the NumElements, and
386167802Sjkim * this code compensates for that. This also provides compatibility with
387167802Sjkim * other AML interpreters.
388167802Sjkim *
389151937Sjkim ******************************************************************************/
39067754Smsmith
39167754SmsmithACPI_STATUS
39299146SiwasakiAcpiDsBuildInternalPackageObj (
39367754Smsmith    ACPI_WALK_STATE         *WalkState,
39467754Smsmith    ACPI_PARSE_OBJECT       *Op,
395167802Sjkim    UINT32                  ElementCount,
39667754Smsmith    ACPI_OPERAND_OBJECT     **ObjDescPtr)
39767754Smsmith{
39899146Siwasaki    ACPI_PARSE_OBJECT       *Arg;
39999146Siwasaki    ACPI_PARSE_OBJECT       *Parent;
40099146Siwasaki    ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
40199146Siwasaki    ACPI_STATUS             Status = AE_OK;
402193267Sjkim    UINT32                  i;
403167802Sjkim    UINT16                  Index;
404167802Sjkim    UINT16                  ReferenceCount;
40567754Smsmith
40667754Smsmith
407167802Sjkim    ACPI_FUNCTION_TRACE (DsBuildInternalPackageObj);
40899146Siwasaki
40999146Siwasaki
41099146Siwasaki    /* Find the parent of a possibly nested package */
41199146Siwasaki
41299679Siwasaki    Parent = Op->Common.Parent;
413167802Sjkim    while ((Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
41499679Siwasaki           (Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
41567754Smsmith    {
41699679Siwasaki        Parent = Parent->Common.Parent;
41799146Siwasaki    }
41882367Smsmith
419167802Sjkim    /*
420167802Sjkim     * If we are evaluating a Named package object "Name (xxxx, Package)",
421167802Sjkim     * the package object already exists, otherwise it must be created.
422167802Sjkim     */
42399146Siwasaki    ObjDesc = *ObjDescPtr;
424167802Sjkim    if (!ObjDesc)
42599146Siwasaki    {
42699146Siwasaki        ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
42799146Siwasaki        *ObjDescPtr = ObjDesc;
42899146Siwasaki        if (!ObjDesc)
42999146Siwasaki        {
43099146Siwasaki            return_ACPI_STATUS (AE_NO_MEMORY);
43199146Siwasaki        }
43267754Smsmith
43399679Siwasaki        ObjDesc->Package.Node = Parent->Common.Node;
43499146Siwasaki    }
43582367Smsmith
43699146Siwasaki    /*
437167802Sjkim     * Allocate the element array (array of pointers to the individual
438167802Sjkim     * objects) based on the NumElements parameter. Add an extra pointer slot
439167802Sjkim     * so that the list is always null terminated.
44099146Siwasaki     */
441167802Sjkim    ObjDesc->Package.Elements = ACPI_ALLOCATE_ZEROED (
442167802Sjkim        ((ACPI_SIZE) ElementCount + 1) * sizeof (void *));
44399146Siwasaki
44499146Siwasaki    if (!ObjDesc->Package.Elements)
44599146Siwasaki    {
44699146Siwasaki        AcpiUtDeleteObjectDesc (ObjDesc);
44799146Siwasaki        return_ACPI_STATUS (AE_NO_MEMORY);
44899146Siwasaki    }
44999146Siwasaki
450167802Sjkim    ObjDesc->Package.Count = ElementCount;
451167802Sjkim
45299146Siwasaki    /*
453167802Sjkim     * Initialize the elements of the package, up to the NumElements count.
454167802Sjkim     * Package is automatically padded with uninitialized (NULL) elements
455167802Sjkim     * if NumElements is greater than the package list length. Likewise,
456167802Sjkim     * Package is truncated if NumElements is less than the list length.
45799146Siwasaki     */
45899679Siwasaki    Arg = Op->Common.Value.Arg;
45999679Siwasaki    Arg = Arg->Common.Next;
460167802Sjkim    for (i = 0; Arg && (i < ElementCount); i++)
46199146Siwasaki    {
46299679Siwasaki        if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP)
46399146Siwasaki        {
464193267Sjkim            if (Arg->Common.Node->Type == ACPI_TYPE_METHOD)
465193267Sjkim            {
466193267Sjkim                /*
467193267Sjkim                 * A method reference "looks" to the parser to be a method
468193267Sjkim                 * invocation, so we special case it here
469193267Sjkim                 */
470193267Sjkim                Arg->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
471298714Sjkim                Status = AcpiDsBuildInternalObject (
472298714Sjkim                    WalkState, Arg, &ObjDesc->Package.Elements[i]);
473193267Sjkim            }
474193267Sjkim            else
475193267Sjkim            {
476193267Sjkim                /* This package element is already built, just get it */
47799146Siwasaki
478193267Sjkim                ObjDesc->Package.Elements[i] =
479193267Sjkim                    ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node);
480193267Sjkim            }
48199146Siwasaki        }
48299146Siwasaki        else
48399146Siwasaki        {
484298714Sjkim            Status = AcpiDsBuildInternalObject (
485298714Sjkim                WalkState, Arg, &ObjDesc->Package.Elements[i]);
48699146Siwasaki        }
48799146Siwasaki
488167802Sjkim        if (*ObjDescPtr)
489167802Sjkim        {
490167802Sjkim            /* Existing package, get existing reference count */
491167802Sjkim
492167802Sjkim            ReferenceCount = (*ObjDescPtr)->Common.ReferenceCount;
493167802Sjkim            if (ReferenceCount > 1)
494167802Sjkim            {
495167802Sjkim                /* Make new element ref count match original ref count */
496167802Sjkim
497167802Sjkim                for (Index = 0; Index < (ReferenceCount - 1); Index++)
498167802Sjkim                {
499167802Sjkim                    AcpiUtAddReference ((ObjDesc->Package.Elements[i]));
500167802Sjkim                }
501167802Sjkim            }
502167802Sjkim        }
503167802Sjkim
50499679Siwasaki        Arg = Arg->Common.Next;
50599146Siwasaki    }
50699146Siwasaki
507193267Sjkim    /* Check for match between NumElements and actual length of PackageList */
508193267Sjkim
509193267Sjkim    if (Arg)
510167802Sjkim    {
511193267Sjkim        /*
512193267Sjkim         * NumElements was exhausted, but there are remaining elements in the
513197104Sjkim         * PackageList. Truncate the package to NumElements.
514193267Sjkim         *
515193267Sjkim         * Note: technically, this is an error, from ACPI spec: "It is an error
516193267Sjkim         * for NumElements to be less than the number of elements in the
517199337Sjkim         * PackageList". However, we just print a message and
518197104Sjkim         * no exception is returned. This provides Windows compatibility. Some
519197104Sjkim         * BIOSs will alter the NumElements on the fly, creating this type
520197104Sjkim         * of ill-formed package object.
521193267Sjkim         */
522193267Sjkim        while (Arg)
523193267Sjkim        {
524197104Sjkim            /*
525197104Sjkim             * We must delete any package elements that were created earlier
526197104Sjkim             * and are not going to be used because of the package truncation.
527197104Sjkim             */
528197104Sjkim            if (Arg->Common.Node)
529197104Sjkim            {
530197104Sjkim                AcpiUtRemoveReference (
531197104Sjkim                    ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node));
532197104Sjkim                Arg->Common.Node = NULL;
533197104Sjkim            }
534197104Sjkim
535193267Sjkim            /* Find out how many elements there really are */
536193267Sjkim
537193267Sjkim            i++;
538193267Sjkim            Arg = Arg->Common.Next;
539193267Sjkim        }
540193267Sjkim
541298714Sjkim        ACPI_INFO ((
542298714Sjkim            "Actual Package length (%u) is larger than "
543298714Sjkim            "NumElements field (%u), truncated",
544193267Sjkim            i, ElementCount));
545193267Sjkim    }
546193267Sjkim    else if (i < ElementCount)
547193267Sjkim    {
548193267Sjkim        /*
549193267Sjkim         * Arg list (elements) was exhausted, but we did not reach NumElements count.
550193267Sjkim         * Note: this is not an error, the package is padded out with NULLs.
551193267Sjkim         */
552167802Sjkim        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
553298714Sjkim            "Package List length (%u) smaller than NumElements "
554298714Sjkim            "count (%u), padded with null elements\n",
555193267Sjkim            i, ElementCount));
556167802Sjkim    }
557167802Sjkim
55899146Siwasaki    ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
559167802Sjkim    Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
56099146Siwasaki    return_ACPI_STATUS (Status);
56167754Smsmith}
56267754Smsmith
56367754Smsmith
564151937Sjkim/*******************************************************************************
56567754Smsmith *
56667754Smsmith * FUNCTION:    AcpiDsCreateNode
56767754Smsmith *
56899679Siwasaki * PARAMETERS:  WalkState       - Current walk state
56999679Siwasaki *              Node            - NS Node to be initialized
57099679Siwasaki *              Op              - Parser object to be translated
57167754Smsmith *
57267754Smsmith * RETURN:      Status
57367754Smsmith *
57499679Siwasaki * DESCRIPTION: Create the object to be associated with a namespace node
57567754Smsmith *
576151937Sjkim ******************************************************************************/
57767754Smsmith
57867754SmsmithACPI_STATUS
57967754SmsmithAcpiDsCreateNode (
58067754Smsmith    ACPI_WALK_STATE         *WalkState,
58167754Smsmith    ACPI_NAMESPACE_NODE     *Node,
58267754Smsmith    ACPI_PARSE_OBJECT       *Op)
58367754Smsmith{
58467754Smsmith    ACPI_STATUS             Status;
58567754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
58667754Smsmith
58767754Smsmith
588167802Sjkim    ACPI_FUNCTION_TRACE_PTR (DsCreateNode, Op);
58967754Smsmith
59067754Smsmith
59185756Smsmith    /*
59285756Smsmith     * Because of the execution pass through the non-control-method
593241973Sjkim     * parts of the table, we can arrive here twice. Only init
59485756Smsmith     * the named object node the first time through
59585756Smsmith     */
59687031Smsmith    if (AcpiNsGetAttachedObject (Node))
59785756Smsmith    {
59885756Smsmith        return_ACPI_STATUS (AE_OK);
59985756Smsmith    }
60085756Smsmith
60199679Siwasaki    if (!Op->Common.Value.Arg)
60267754Smsmith    {
60367754Smsmith        /* No arguments, there is nothing to do */
60467754Smsmith
60567754Smsmith        return_ACPI_STATUS (AE_OK);
60667754Smsmith    }
60767754Smsmith
60867754Smsmith    /* Build an internal object for the argument(s) */
60967754Smsmith
610298714Sjkim    Status = AcpiDsBuildInternalObject (
611298714Sjkim        WalkState, Op->Common.Value.Arg, &ObjDesc);
61267754Smsmith    if (ACPI_FAILURE (Status))
61367754Smsmith    {
61467754Smsmith        return_ACPI_STATUS (Status);
61567754Smsmith    }
61667754Smsmith
617114237Snjl    /* Re-type the object according to its argument */
61867754Smsmith
619193267Sjkim    Node->Type = ObjDesc->Common.Type;
62067754Smsmith
62199146Siwasaki    /* Attach obj to node */
62267754Smsmith
62391116Smsmith    Status = AcpiNsAttachObject (Node, ObjDesc, Node->Type);
62467754Smsmith
62585756Smsmith    /* Remove local reference to the object */
62667754Smsmith
62777424Smsmith    AcpiUtRemoveReference (ObjDesc);
62867754Smsmith    return_ACPI_STATUS (Status);
62967754Smsmith}
63067754Smsmith
631100966Siwasaki#endif /* ACPI_NO_METHOD_EXECUTION */
63267754Smsmith
633100966Siwasaki
634151937Sjkim/*******************************************************************************
635100966Siwasaki *
636100966Siwasaki * FUNCTION:    AcpiDsInitObjectFromOp
637100966Siwasaki *
638100966Siwasaki * PARAMETERS:  WalkState       - Current walk state
639100966Siwasaki *              Op              - Parser op used to init the internal object
640100966Siwasaki *              Opcode          - AML opcode associated with the object
641100966Siwasaki *              RetObjDesc      - Namespace object to be initialized
642100966Siwasaki *
643100966Siwasaki * RETURN:      Status
644100966Siwasaki *
645100966Siwasaki * DESCRIPTION: Initialize a namespace object from a parser Op and its
646241973Sjkim *              associated arguments. The namespace object is a more compact
647100966Siwasaki *              representation of the Op and its arguments.
648100966Siwasaki *
649151937Sjkim ******************************************************************************/
650100966Siwasaki
651100966SiwasakiACPI_STATUS
652100966SiwasakiAcpiDsInitObjectFromOp (
653100966Siwasaki    ACPI_WALK_STATE         *WalkState,
654100966Siwasaki    ACPI_PARSE_OBJECT       *Op,
655100966Siwasaki    UINT16                  Opcode,
656100966Siwasaki    ACPI_OPERAND_OBJECT     **RetObjDesc)
657100966Siwasaki{
658100966Siwasaki    const ACPI_OPCODE_INFO  *OpInfo;
659100966Siwasaki    ACPI_OPERAND_OBJECT     *ObjDesc;
660100966Siwasaki    ACPI_STATUS             Status = AE_OK;
661100966Siwasaki
662100966Siwasaki
663167802Sjkim    ACPI_FUNCTION_TRACE (DsInitObjectFromOp);
664100966Siwasaki
665100966Siwasaki
666100966Siwasaki    ObjDesc = *RetObjDesc;
667100966Siwasaki    OpInfo = AcpiPsGetOpcodeInfo (Opcode);
668100966Siwasaki    if (OpInfo->Class == AML_CLASS_UNKNOWN)
669100966Siwasaki    {
670100966Siwasaki        /* Unknown opcode */
671100966Siwasaki
672100966Siwasaki        return_ACPI_STATUS (AE_TYPE);
673100966Siwasaki    }
674100966Siwasaki
675100966Siwasaki    /* Perform per-object initialization */
676100966Siwasaki
677193267Sjkim    switch (ObjDesc->Common.Type)
678100966Siwasaki    {
679100966Siwasaki    case ACPI_TYPE_BUFFER:
680100966Siwasaki        /*
681100966Siwasaki         * Defer evaluation of Buffer TermArg operand
682100966Siwasaki         */
683298714Sjkim        ObjDesc->Buffer.Node = ACPI_CAST_PTR (
684298714Sjkim            ACPI_NAMESPACE_NODE, WalkState->Operands[0]);
685298714Sjkim        ObjDesc->Buffer.AmlStart = Op->Named.Data;
686100966Siwasaki        ObjDesc->Buffer.AmlLength = Op->Named.Length;
687100966Siwasaki        break;
688100966Siwasaki
689100966Siwasaki    case ACPI_TYPE_PACKAGE:
690100966Siwasaki        /*
691100966Siwasaki         * Defer evaluation of Package TermArg operand
692100966Siwasaki         */
693298714Sjkim        ObjDesc->Package.Node = ACPI_CAST_PTR (
694298714Sjkim            ACPI_NAMESPACE_NODE, WalkState->Operands[0]);
695298714Sjkim        ObjDesc->Package.AmlStart = Op->Named.Data;
696100966Siwasaki        ObjDesc->Package.AmlLength = Op->Named.Length;
697100966Siwasaki        break;
698100966Siwasaki
699102550Siwasaki    case ACPI_TYPE_INTEGER:
700100966Siwasaki
701100966Siwasaki        switch (OpInfo->Type)
702100966Siwasaki        {
703100966Siwasaki        case AML_TYPE_CONSTANT:
704100966Siwasaki            /*
705100966Siwasaki             * Resolve AML Constants here - AND ONLY HERE!
706100966Siwasaki             * All constants are integers.
707151937Sjkim             * We mark the integer with a flag that indicates that it started
708151937Sjkim             * life as a constant -- so that stores to constants will perform
709151937Sjkim             * as expected (noop). ZeroOp is used as a placeholder for optional
710151937Sjkim             * target operands.
711100966Siwasaki             */
712100966Siwasaki            ObjDesc->Common.Flags = AOPOBJ_AML_CONSTANT;
713100966Siwasaki
714100966Siwasaki            switch (Opcode)
715100966Siwasaki            {
716100966Siwasaki            case AML_ZERO_OP:
717100966Siwasaki
718100966Siwasaki                ObjDesc->Integer.Value = 0;
719100966Siwasaki                break;
720100966Siwasaki
721100966Siwasaki            case AML_ONE_OP:
722100966Siwasaki
723100966Siwasaki                ObjDesc->Integer.Value = 1;
724100966Siwasaki                break;
725100966Siwasaki
726100966Siwasaki            case AML_ONES_OP:
727100966Siwasaki
728202771Sjkim                ObjDesc->Integer.Value = ACPI_UINT64_MAX;
729100966Siwasaki
730100966Siwasaki                /* Truncate value if we are executing from a 32-bit ACPI table */
731100966Siwasaki
732100966Siwasaki#ifndef ACPI_NO_METHOD_EXECUTION
733245582Sjkim                (void) AcpiExTruncateFor32bitTable (ObjDesc);
734100966Siwasaki#endif
735100966Siwasaki                break;
736100966Siwasaki
737100966Siwasaki            case AML_REVISION_OP:
738100966Siwasaki
739151937Sjkim                ObjDesc->Integer.Value = ACPI_CA_VERSION;
740100966Siwasaki                break;
741100966Siwasaki
742100966Siwasaki            default:
743100966Siwasaki
744167802Sjkim                ACPI_ERROR ((AE_INFO,
745204773Sjkim                    "Unknown constant opcode 0x%X", Opcode));
746100966Siwasaki                Status = AE_AML_OPERAND_TYPE;
747100966Siwasaki                break;
748100966Siwasaki            }
749100966Siwasaki            break;
750100966Siwasaki
751100966Siwasaki        case AML_TYPE_LITERAL:
752100966Siwasaki
753100966Siwasaki            ObjDesc->Integer.Value = Op->Common.Value.Integer;
754245582Sjkim
755151937Sjkim#ifndef ACPI_NO_METHOD_EXECUTION
756245582Sjkim            if (AcpiExTruncateFor32bitTable (ObjDesc))
757245582Sjkim            {
758245582Sjkim                /* Warn if we found a 64-bit constant in a 32-bit table */
759245582Sjkim
760245582Sjkim                ACPI_WARNING ((AE_INFO,
761245582Sjkim                    "Truncated 64-bit constant found in 32-bit table: %8.8X%8.8X => %8.8X",
762245582Sjkim                    ACPI_FORMAT_UINT64 (Op->Common.Value.Integer),
763245582Sjkim                    (UINT32) ObjDesc->Integer.Value));
764245582Sjkim            }
765151937Sjkim#endif
766100966Siwasaki            break;
767100966Siwasaki
768250838Sjkim        default:
769100966Siwasaki
770204773Sjkim            ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X",
771151937Sjkim                OpInfo->Type));
772100966Siwasaki            Status = AE_AML_OPERAND_TYPE;
773100966Siwasaki            break;
774100966Siwasaki        }
775100966Siwasaki        break;
776100966Siwasaki
777100966Siwasaki    case ACPI_TYPE_STRING:
778100966Siwasaki
779100966Siwasaki        ObjDesc->String.Pointer = Op->Common.Value.String;
780284583Sjkim        ObjDesc->String.Length = (UINT32) strlen (Op->Common.Value.String);
781100966Siwasaki
782100966Siwasaki        /*
783100966Siwasaki         * The string is contained in the ACPI table, don't ever try
784100966Siwasaki         * to delete it
785100966Siwasaki         */
786100966Siwasaki        ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;
787100966Siwasaki        break;
788100966Siwasaki
789100966Siwasaki    case ACPI_TYPE_METHOD:
790100966Siwasaki        break;
791100966Siwasaki
792107325Siwasaki    case ACPI_TYPE_LOCAL_REFERENCE:
793100966Siwasaki
794100966Siwasaki        switch (OpInfo->Type)
795100966Siwasaki        {
796100966Siwasaki        case AML_TYPE_LOCAL_VARIABLE:
797100966Siwasaki
798193267Sjkim            /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */
799100966Siwasaki
800193267Sjkim            ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_LOCAL_OP;
801193267Sjkim            ObjDesc->Reference.Class = ACPI_REFCLASS_LOCAL;
802104470Siwasaki
803100966Siwasaki#ifndef ACPI_NO_METHOD_EXECUTION
804193267Sjkim            Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_LOCAL,
805298714Sjkim                ObjDesc->Reference.Value, WalkState,
806298714Sjkim                ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE,
807298714Sjkim                    &ObjDesc->Reference.Object));
808100966Siwasaki#endif
809100966Siwasaki            break;
810100966Siwasaki
811100966Siwasaki        case AML_TYPE_METHOD_ARGUMENT:
812100966Siwasaki
813193267Sjkim            /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */
814100966Siwasaki
815193267Sjkim            ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_ARG_OP;
816193267Sjkim            ObjDesc->Reference.Class = ACPI_REFCLASS_ARG;
817126372Snjl
818126372Snjl#ifndef ACPI_NO_METHOD_EXECUTION
819193267Sjkim            Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_ARG,
820298714Sjkim                ObjDesc->Reference.Value, WalkState,
821298714Sjkim                ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE,
822298714Sjkim                    &ObjDesc->Reference.Object));
823126372Snjl#endif
824100966Siwasaki            break;
825100966Siwasaki
826193267Sjkim        default: /* Object name or Debug object */
827100966Siwasaki
828193267Sjkim            switch (Op->Common.AmlOpcode)
829100966Siwasaki            {
830193267Sjkim            case AML_INT_NAMEPATH_OP:
831193267Sjkim
832100966Siwasaki                /* Node was saved in Op */
833100966Siwasaki
834100966Siwasaki                ObjDesc->Reference.Node = Op->Common.Node;
835193267Sjkim                ObjDesc->Reference.Object = Op->Common.Node->Object;
836193267Sjkim                ObjDesc->Reference.Class = ACPI_REFCLASS_NAME;
837193267Sjkim                break;
838193267Sjkim
839193267Sjkim            case AML_DEBUG_OP:
840193267Sjkim
841193267Sjkim                ObjDesc->Reference.Class = ACPI_REFCLASS_DEBUG;
842193267Sjkim                break;
843193267Sjkim
844193267Sjkim            default:
845193267Sjkim
846193267Sjkim                ACPI_ERROR ((AE_INFO,
847204773Sjkim                    "Unimplemented reference type for AML opcode: 0x%4.4X", Opcode));
848193267Sjkim                return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
849100966Siwasaki            }
850100966Siwasaki            break;
851100966Siwasaki        }
852100966Siwasaki        break;
853100966Siwasaki
854100966Siwasaki    default:
855100966Siwasaki
856204773Sjkim        ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X",
857193267Sjkim            ObjDesc->Common.Type));
858100966Siwasaki
859100966Siwasaki        Status = AE_AML_OPERAND_TYPE;
860100966Siwasaki        break;
861100966Siwasaki    }
862100966Siwasaki
863100966Siwasaki    return_ACPI_STATUS (Status);
864100966Siwasaki}
865