167754Smsmith/******************************************************************************
267754Smsmith *
377424Smsmith * Module Name: utobject - ACPI object create/delete/size/cache 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/acnamesp.h>
4767754Smsmith
4867754Smsmith
4977424Smsmith#define _COMPONENT          ACPI_UTILITIES
5091116Smsmith        ACPI_MODULE_NAME    ("utobject")
5167754Smsmith
52151937Sjkim/* Local prototypes */
5367754Smsmith
54151937Sjkimstatic ACPI_STATUS
55151937SjkimAcpiUtGetSimpleObjectSize (
56151937Sjkim    ACPI_OPERAND_OBJECT     *Obj,
57151937Sjkim    ACPI_SIZE               *ObjLength);
58151937Sjkim
59151937Sjkimstatic ACPI_STATUS
60151937SjkimAcpiUtGetPackageObjectSize (
61151937Sjkim    ACPI_OPERAND_OBJECT     *Obj,
62151937Sjkim    ACPI_SIZE               *ObjLength);
63151937Sjkim
64151937Sjkimstatic ACPI_STATUS
65151937SjkimAcpiUtGetElementLength (
66151937Sjkim    UINT8                   ObjectType,
67151937Sjkim    ACPI_OPERAND_OBJECT     *SourceObject,
68151937Sjkim    ACPI_GENERIC_STATE      *State,
69151937Sjkim    void                    *Context);
70151937Sjkim
71151937Sjkim
7273561Smsmith/*******************************************************************************
7367754Smsmith *
7483174Smsmith * FUNCTION:    AcpiUtCreateInternalObjectDbg
7567754Smsmith *
7699679Siwasaki * PARAMETERS:  ModuleName          - Source file name of caller
7799679Siwasaki *              LineNumber          - Line number of caller
7899679Siwasaki *              ComponentId         - Component type of caller
7967754Smsmith *              Type                - ACPI Type of the new object
8067754Smsmith *
81151937Sjkim * RETURN:      A new internal object, null on failure
8267754Smsmith *
8367754Smsmith * DESCRIPTION: Create and initialize a new internal object.
8467754Smsmith *
8577424Smsmith * NOTE:        We always allocate the worst-case object descriptor because
8677424Smsmith *              these objects are cached, and we want them to be
87241973Sjkim *              one-size-satisifies-any-request. This in itself may not be
8877424Smsmith *              the most memory efficient, but the efficiency of the object
8973561Smsmith *              cache should more than make up for this!
9067754Smsmith *
9167754Smsmith ******************************************************************************/
9267754Smsmith
9367754SmsmithACPI_OPERAND_OBJECT  *
9483174SmsmithAcpiUtCreateInternalObjectDbg (
95193267Sjkim    const char              *ModuleName,
9667754Smsmith    UINT32                  LineNumber,
9767754Smsmith    UINT32                  ComponentId,
9891116Smsmith    ACPI_OBJECT_TYPE        Type)
9967754Smsmith{
10067754Smsmith    ACPI_OPERAND_OBJECT     *Object;
10187031Smsmith    ACPI_OPERAND_OBJECT     *SecondObject;
10267754Smsmith
10367754Smsmith
104167802Sjkim    ACPI_FUNCTION_TRACE_STR (UtCreateInternalObjectDbg,
105151937Sjkim        AcpiUtGetTypeName (Type));
10667754Smsmith
10767754Smsmith
10867754Smsmith    /* Allocate the raw object descriptor */
10967754Smsmith
110306536Sjkim    Object = AcpiUtAllocateObjectDescDbg (
111306536Sjkim        ModuleName, LineNumber, ComponentId);
11267754Smsmith    if (!Object)
11367754Smsmith    {
11477424Smsmith        return_PTR (NULL);
11567754Smsmith    }
11667754Smsmith
11787031Smsmith    switch (Type)
11887031Smsmith    {
11987031Smsmith    case ACPI_TYPE_REGION:
12087031Smsmith    case ACPI_TYPE_BUFFER_FIELD:
121193267Sjkim    case ACPI_TYPE_LOCAL_BANK_FIELD:
12291116Smsmith
12387031Smsmith        /* These types require a secondary object */
12487031Smsmith
125306536Sjkim        SecondObject = AcpiUtAllocateObjectDescDbg (
126306536Sjkim            ModuleName, LineNumber, ComponentId);
12787031Smsmith        if (!SecondObject)
12887031Smsmith        {
12987031Smsmith            AcpiUtDeleteObjectDesc (Object);
13087031Smsmith            return_PTR (NULL);
13187031Smsmith        }
13287031Smsmith
133107325Siwasaki        SecondObject->Common.Type = ACPI_TYPE_LOCAL_EXTRA;
13487031Smsmith        SecondObject->Common.ReferenceCount = 1;
13587031Smsmith
13687031Smsmith        /* Link the second object to the first */
13787031Smsmith
13887031Smsmith        Object->Common.NextObject = SecondObject;
13987031Smsmith        break;
14099679Siwasaki
14199679Siwasaki    default:
142250838Sjkim
14399679Siwasaki        /* All others have no secondary object */
14499679Siwasaki        break;
14587031Smsmith    }
14687031Smsmith
14767754Smsmith    /* Save the object type in the object descriptor */
14867754Smsmith
14991116Smsmith    Object->Common.Type = (UINT8) Type;
15067754Smsmith
15167754Smsmith    /* Init the reference count */
15267754Smsmith
15367754Smsmith    Object->Common.ReferenceCount = 1;
15467754Smsmith
15567754Smsmith    /* Any per-type initialization should go here */
15667754Smsmith
15767754Smsmith    return_PTR (Object);
15867754Smsmith}
15967754Smsmith
16067754Smsmith
16173561Smsmith/*******************************************************************************
16267754Smsmith *
163193267Sjkim * FUNCTION:    AcpiUtCreatePackageObject
164193267Sjkim *
165193267Sjkim * PARAMETERS:  Count               - Number of package elements
166193267Sjkim *
167193267Sjkim * RETURN:      Pointer to a new Package object, null on failure
168193267Sjkim *
169193267Sjkim * DESCRIPTION: Create a fully initialized package object
170193267Sjkim *
171193267Sjkim ******************************************************************************/
172193267Sjkim
173193267SjkimACPI_OPERAND_OBJECT *
174193267SjkimAcpiUtCreatePackageObject (
175193267Sjkim    UINT32                  Count)
176193267Sjkim{
177193267Sjkim    ACPI_OPERAND_OBJECT     *PackageDesc;
178193267Sjkim    ACPI_OPERAND_OBJECT     **PackageElements;
179193267Sjkim
180193267Sjkim
181193267Sjkim    ACPI_FUNCTION_TRACE_U32 (UtCreatePackageObject, Count);
182193267Sjkim
183193267Sjkim
184193267Sjkim    /* Create a new Package object */
185193267Sjkim
186193267Sjkim    PackageDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
187193267Sjkim    if (!PackageDesc)
188193267Sjkim    {
189193267Sjkim        return_PTR (NULL);
190193267Sjkim    }
191193267Sjkim
192193267Sjkim    /*
193193267Sjkim     * Create the element array. Count+1 allows the array to be null
194193267Sjkim     * terminated.
195193267Sjkim     */
196193267Sjkim    PackageElements = ACPI_ALLOCATE_ZEROED (
197306536Sjkim        ((ACPI_SIZE) Count + 1) * sizeof (void *));
198193267Sjkim    if (!PackageElements)
199193267Sjkim    {
200193267Sjkim        ACPI_FREE (PackageDesc);
201193267Sjkim        return_PTR (NULL);
202193267Sjkim    }
203193267Sjkim
204193267Sjkim    PackageDesc->Package.Count = Count;
205193267Sjkim    PackageDesc->Package.Elements = PackageElements;
206193267Sjkim    return_PTR (PackageDesc);
207193267Sjkim}
208193267Sjkim
209193267Sjkim
210193267Sjkim/*******************************************************************************
211193267Sjkim *
212199337Sjkim * FUNCTION:    AcpiUtCreateIntegerObject
213199337Sjkim *
214199337Sjkim * PARAMETERS:  InitialValue        - Initial value for the integer
215199337Sjkim *
216199337Sjkim * RETURN:      Pointer to a new Integer object, null on failure
217199337Sjkim *
218199337Sjkim * DESCRIPTION: Create an initialized integer object
219199337Sjkim *
220199337Sjkim ******************************************************************************/
221199337Sjkim
222199337SjkimACPI_OPERAND_OBJECT *
223199337SjkimAcpiUtCreateIntegerObject (
224199337Sjkim    UINT64                  InitialValue)
225199337Sjkim{
226199337Sjkim    ACPI_OPERAND_OBJECT     *IntegerDesc;
227199337Sjkim
228199337Sjkim
229199337Sjkim    ACPI_FUNCTION_TRACE (UtCreateIntegerObject);
230199337Sjkim
231199337Sjkim
232199337Sjkim    /* Create and initialize a new integer object */
233199337Sjkim
234199337Sjkim    IntegerDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
235199337Sjkim    if (!IntegerDesc)
236199337Sjkim    {
237199337Sjkim        return_PTR (NULL);
238199337Sjkim    }
239199337Sjkim
240199337Sjkim    IntegerDesc->Integer.Value = InitialValue;
241199337Sjkim    return_PTR (IntegerDesc);
242199337Sjkim}
243199337Sjkim
244199337Sjkim
245199337Sjkim/*******************************************************************************
246199337Sjkim *
247107325Siwasaki * FUNCTION:    AcpiUtCreateBufferObject
248107325Siwasaki *
249107325Siwasaki * PARAMETERS:  BufferSize             - Size of buffer to be created
250107325Siwasaki *
251151937Sjkim * RETURN:      Pointer to a new Buffer object, null on failure
252107325Siwasaki *
253107325Siwasaki * DESCRIPTION: Create a fully initialized buffer object
254107325Siwasaki *
255107325Siwasaki ******************************************************************************/
256107325Siwasaki
257107325SiwasakiACPI_OPERAND_OBJECT *
258107325SiwasakiAcpiUtCreateBufferObject (
259107325Siwasaki    ACPI_SIZE               BufferSize)
260107325Siwasaki{
261107325Siwasaki    ACPI_OPERAND_OBJECT     *BufferDesc;
262117521Snjl    UINT8                   *Buffer = NULL;
263107325Siwasaki
264107325Siwasaki
265167802Sjkim    ACPI_FUNCTION_TRACE_U32 (UtCreateBufferObject, BufferSize);
266107325Siwasaki
267107325Siwasaki
268138287Smarks    /* Create a new Buffer object */
269138287Smarks
270107325Siwasaki    BufferDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
271107325Siwasaki    if (!BufferDesc)
272107325Siwasaki    {
273107325Siwasaki        return_PTR (NULL);
274107325Siwasaki    }
275107325Siwasaki
276117521Snjl    /* Create an actual buffer only if size > 0 */
277107325Siwasaki
278117521Snjl    if (BufferSize > 0)
279107325Siwasaki    {
280117521Snjl        /* Allocate the actual buffer */
281117521Snjl
282167802Sjkim        Buffer = ACPI_ALLOCATE_ZEROED (BufferSize);
283117521Snjl        if (!Buffer)
284117521Snjl        {
285204773Sjkim            ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
286117521Snjl                (UINT32) BufferSize));
287306536Sjkim
288117521Snjl            AcpiUtRemoveReference (BufferDesc);
289117521Snjl            return_PTR (NULL);
290117521Snjl        }
291107325Siwasaki    }
292107325Siwasaki
293107325Siwasaki    /* Complete buffer object initialization */
294107325Siwasaki
295107325Siwasaki    BufferDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
296107325Siwasaki    BufferDesc->Buffer.Pointer = Buffer;
297107325Siwasaki    BufferDesc->Buffer.Length = (UINT32) BufferSize;
298107325Siwasaki
299107325Siwasaki    /* Return the new buffer descriptor */
300107325Siwasaki
301107325Siwasaki    return_PTR (BufferDesc);
302107325Siwasaki}
303107325Siwasaki
304107325Siwasaki
305107325Siwasaki/*******************************************************************************
306107325Siwasaki *
307138287Smarks * FUNCTION:    AcpiUtCreateStringObject
308138287Smarks *
309151937Sjkim * PARAMETERS:  StringSize          - Size of string to be created. Does not
310151937Sjkim *                                    include NULL terminator, this is added
311151937Sjkim *                                    automatically.
312138287Smarks *
313138287Smarks * RETURN:      Pointer to a new String object
314138287Smarks *
315138287Smarks * DESCRIPTION: Create a fully initialized string object
316138287Smarks *
317138287Smarks ******************************************************************************/
318138287Smarks
319138287SmarksACPI_OPERAND_OBJECT *
320138287SmarksAcpiUtCreateStringObject (
321138287Smarks    ACPI_SIZE               StringSize)
322138287Smarks{
323138287Smarks    ACPI_OPERAND_OBJECT     *StringDesc;
324138287Smarks    char                    *String;
325138287Smarks
326138287Smarks
327167802Sjkim    ACPI_FUNCTION_TRACE_U32 (UtCreateStringObject, StringSize);
328138287Smarks
329138287Smarks
330138287Smarks    /* Create a new String object */
331138287Smarks
332138287Smarks    StringDesc = AcpiUtCreateInternalObject (ACPI_TYPE_STRING);
333138287Smarks    if (!StringDesc)
334138287Smarks    {
335138287Smarks        return_PTR (NULL);
336138287Smarks    }
337138287Smarks
338138287Smarks    /*
339138287Smarks     * Allocate the actual string buffer -- (Size + 1) for NULL terminator.
340138287Smarks     * NOTE: Zero-length strings are NULL terminated
341138287Smarks     */
342167802Sjkim    String = ACPI_ALLOCATE_ZEROED (StringSize + 1);
343138287Smarks    if (!String)
344138287Smarks    {
345204773Sjkim        ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
346138287Smarks            (UINT32) StringSize));
347306536Sjkim
348138287Smarks        AcpiUtRemoveReference (StringDesc);
349138287Smarks        return_PTR (NULL);
350138287Smarks    }
351138287Smarks
352138287Smarks    /* Complete string object initialization */
353138287Smarks
354138287Smarks    StringDesc->String.Pointer = String;
355138287Smarks    StringDesc->String.Length = (UINT32) StringSize;
356138287Smarks
357138287Smarks    /* Return the new string descriptor */
358138287Smarks
359138287Smarks    return_PTR (StringDesc);
360138287Smarks}
361138287Smarks
362138287Smarks
363138287Smarks/*******************************************************************************
364138287Smarks *
36577424Smsmith * FUNCTION:    AcpiUtValidInternalObject
36667754Smsmith *
36799679Siwasaki * PARAMETERS:  Object              - Object to be validated
36867754Smsmith *
369151937Sjkim * RETURN:      TRUE if object is valid, FALSE otherwise
37067754Smsmith *
371238381Sjkim * DESCRIPTION: Validate a pointer to be of type ACPI_OPERAND_OBJECT
372151937Sjkim *
37373561Smsmith ******************************************************************************/
37467754Smsmith
37567754SmsmithBOOLEAN
37677424SmsmithAcpiUtValidInternalObject (
37767754Smsmith    void                    *Object)
37867754Smsmith{
37967754Smsmith
380167802Sjkim    ACPI_FUNCTION_NAME (UtValidInternalObject);
38177424Smsmith
38277424Smsmith
38367754Smsmith    /* Check for a null pointer */
38467754Smsmith
38567754Smsmith    if (!Object)
38667754Smsmith    {
387193267Sjkim        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "**** Null Object Ptr\n"));
38867754Smsmith        return (FALSE);
38967754Smsmith    }
39067754Smsmith
39167754Smsmith    /* Check the descriptor type field */
39267754Smsmith
39391116Smsmith    switch (ACPI_GET_DESCRIPTOR_TYPE (Object))
39467754Smsmith    {
39599679Siwasaki    case ACPI_DESC_TYPE_OPERAND:
39667754Smsmith
397238381Sjkim        /* The object appears to be a valid ACPI_OPERAND_OBJECT */
39867754Smsmith
39991116Smsmith        return (TRUE);
40067754Smsmith
401123315Snjl    default:
402250838Sjkim
403193267Sjkim        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
404306536Sjkim            "%p is not an ACPI operand obj [%s]\n",
405306536Sjkim            Object, AcpiUtGetDescriptorName (Object)));
40691116Smsmith        break;
40791116Smsmith    }
40891116Smsmith
40991116Smsmith    return (FALSE);
41067754Smsmith}
41167754Smsmith
41267754Smsmith
41373561Smsmith/*******************************************************************************
41467754Smsmith *
41583174Smsmith * FUNCTION:    AcpiUtAllocateObjectDescDbg
41667754Smsmith *
41767754Smsmith * PARAMETERS:  ModuleName          - Caller's module name (for error output)
41867754Smsmith *              LineNumber          - Caller's line number (for error output)
41967754Smsmith *              ComponentId         - Caller's component ID (for error output)
42067754Smsmith *
421241973Sjkim * RETURN:      Pointer to newly allocated object descriptor. Null on error
42267754Smsmith *
423241973Sjkim * DESCRIPTION: Allocate a new object descriptor. Gracefully handle
42467754Smsmith *              error conditions.
42567754Smsmith *
42673561Smsmith ******************************************************************************/
42767754Smsmith
42867754Smsmithvoid *
42983174SmsmithAcpiUtAllocateObjectDescDbg (
430193267Sjkim    const char              *ModuleName,
43167754Smsmith    UINT32                  LineNumber,
43267754Smsmith    UINT32                  ComponentId)
43367754Smsmith{
43467754Smsmith    ACPI_OPERAND_OBJECT     *Object;
43567754Smsmith
43667754Smsmith
437167802Sjkim    ACPI_FUNCTION_TRACE (UtAllocateObjectDescDbg);
43867754Smsmith
43967754Smsmith
440151937Sjkim    Object = AcpiOsAcquireObject (AcpiGbl_OperandCache);
44182367Smsmith    if (!Object)
44267754Smsmith    {
443167802Sjkim        ACPI_ERROR ((ModuleName, LineNumber,
444167802Sjkim            "Could not allocate an object descriptor"));
44567754Smsmith
44682367Smsmith        return_PTR (NULL);
44767754Smsmith    }
44867754Smsmith
44967754Smsmith    /* Mark the descriptor type */
45067754Smsmith
45199679Siwasaki    ACPI_SET_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_OPERAND);
45267754Smsmith
45382367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
454306536Sjkim        Object, (UINT32) sizeof (ACPI_OPERAND_OBJECT)));
45567754Smsmith
45667754Smsmith    return_PTR (Object);
45767754Smsmith}
45867754Smsmith
45967754Smsmith
46073561Smsmith/*******************************************************************************
46167754Smsmith *
46277424Smsmith * FUNCTION:    AcpiUtDeleteObjectDesc
46367754Smsmith *
46499679Siwasaki * PARAMETERS:  Object          - An Acpi internal object to be deleted
46567754Smsmith *
46667754Smsmith * RETURN:      None.
46767754Smsmith *
46867754Smsmith * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
46967754Smsmith *
47073561Smsmith ******************************************************************************/
47167754Smsmith
47267754Smsmithvoid
47377424SmsmithAcpiUtDeleteObjectDesc (
47467754Smsmith    ACPI_OPERAND_OBJECT     *Object)
47567754Smsmith{
476167802Sjkim    ACPI_FUNCTION_TRACE_PTR (UtDeleteObjectDesc, Object);
47767754Smsmith
47867754Smsmith
479238381Sjkim    /* Object must be of type ACPI_OPERAND_OBJECT */
48067754Smsmith
48199679Siwasaki    if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
48267754Smsmith    {
483167802Sjkim        ACPI_ERROR ((AE_INFO,
484167802Sjkim            "%p is not an ACPI Operand object [%s]", Object,
485167802Sjkim            AcpiUtGetDescriptorName (Object)));
48667754Smsmith        return_VOID;
48767754Smsmith    }
48867754Smsmith
489151937Sjkim    (void) AcpiOsReleaseObject (AcpiGbl_OperandCache, Object);
49067754Smsmith    return_VOID;
49167754Smsmith}
49267754Smsmith
49367754Smsmith
49473561Smsmith/*******************************************************************************
49567754Smsmith *
49677424Smsmith * FUNCTION:    AcpiUtGetSimpleObjectSize
49767754Smsmith *
498151937Sjkim * PARAMETERS:  InternalObject     - An ACPI operand object
499151937Sjkim *              ObjLength          - Where the length is returned
50067754Smsmith *
50173561Smsmith * RETURN:      Status
50267754Smsmith *
50367754Smsmith * DESCRIPTION: This function is called to determine the space required to
50499679Siwasaki *              contain a simple object for return to an external user.
50567754Smsmith *
50667754Smsmith *              The length includes the object structure plus any additional
50767754Smsmith *              needed space.
50867754Smsmith *
50967754Smsmith ******************************************************************************/
51067754Smsmith
511151937Sjkimstatic ACPI_STATUS
51277424SmsmithAcpiUtGetSimpleObjectSize (
51373561Smsmith    ACPI_OPERAND_OBJECT     *InternalObject,
51491116Smsmith    ACPI_SIZE               *ObjLength)
51567754Smsmith{
51691116Smsmith    ACPI_SIZE               Length;
517193267Sjkim    ACPI_SIZE               Size;
51867754Smsmith    ACPI_STATUS             Status = AE_OK;
51967754Smsmith
52067754Smsmith
521167802Sjkim    ACPI_FUNCTION_TRACE_PTR (UtGetSimpleObjectSize, InternalObject);
52267754Smsmith
52367754Smsmith
524193267Sjkim    /* Start with the length of the (external) Acpi object */
525193267Sjkim
526193267Sjkim    Length = sizeof (ACPI_OBJECT);
527193267Sjkim
528193267Sjkim    /* A NULL object is allowed, can be a legal uninitialized package element */
529193267Sjkim
53073561Smsmith    if (!InternalObject)
53167754Smsmith    {
532193267Sjkim        /*
533193267Sjkim         * Object is NULL, just return the length of ACPI_OBJECT
534193267Sjkim         * (A NULL ACPI_OBJECT is an object of all zeroes.)
535193267Sjkim         */
536193267Sjkim        *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length);
53767754Smsmith        return_ACPI_STATUS (AE_OK);
53867754Smsmith    }
53967754Smsmith
540193267Sjkim    /* A Namespace Node should never appear here */
54167754Smsmith
54291116Smsmith    if (ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_NAMED)
54367754Smsmith    {
544193267Sjkim        /* A namespace node should never get here */
54567754Smsmith
546193267Sjkim        return_ACPI_STATUS (AE_AML_INTERNAL);
54767754Smsmith    }
54867754Smsmith
54967754Smsmith    /*
55067754Smsmith     * The final length depends on the object type
55167754Smsmith     * Strings and Buffers are packed right up against the parent object and
55277424Smsmith     * must be accessed bytewise or there may be alignment problems on
55377424Smsmith     * certain processors
55467754Smsmith     */
555193267Sjkim    switch (InternalObject->Common.Type)
55667754Smsmith    {
55767754Smsmith    case ACPI_TYPE_STRING:
55867754Smsmith
55999679Siwasaki        Length += (ACPI_SIZE) InternalObject->String.Length + 1;
56067754Smsmith        break;
56167754Smsmith
56267754Smsmith    case ACPI_TYPE_BUFFER:
56367754Smsmith
56499679Siwasaki        Length += (ACPI_SIZE) InternalObject->Buffer.Length;
56567754Smsmith        break;
56667754Smsmith
56771867Smsmith    case ACPI_TYPE_INTEGER:
56867754Smsmith    case ACPI_TYPE_PROCESSOR:
56967754Smsmith    case ACPI_TYPE_POWER:
57067754Smsmith
571193267Sjkim        /* No extra data for these types */
572193267Sjkim
57367754Smsmith        break;
57467754Smsmith
575107325Siwasaki    case ACPI_TYPE_LOCAL_REFERENCE:
57667754Smsmith
577193267Sjkim        switch (InternalObject->Reference.Class)
57867754Smsmith        {
579193267Sjkim        case ACPI_REFCLASS_NAME:
58077424Smsmith            /*
58177424Smsmith             * Get the actual length of the full pathname to this object.
58277424Smsmith             * The reference will be converted to the pathname to the object
58377424Smsmith             */
584193267Sjkim            Size = AcpiNsGetPathnameLength (InternalObject->Reference.Node);
585193267Sjkim            if (!Size)
586193267Sjkim            {
587193267Sjkim                return_ACPI_STATUS (AE_BAD_PARAMETER);
588193267Sjkim            }
589193267Sjkim
590193267Sjkim            Length += ACPI_ROUND_UP_TO_NATIVE_WORD (Size);
59191116Smsmith            break;
59291116Smsmith
59391116Smsmith        default:
59491116Smsmith            /*
59591116Smsmith             * No other reference opcodes are supported.
59699679Siwasaki             * Notably, Locals and Args are not supported, but this may be
59791116Smsmith             * required eventually.
59891116Smsmith             */
599193267Sjkim            ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
600204773Sjkim                "unsupported Reference Class [%s] 0x%X in object %p",
601193267Sjkim                AcpiUtGetReferenceName (InternalObject),
602193267Sjkim                InternalObject->Reference.Class, InternalObject));
60391116Smsmith            Status = AE_TYPE;
60491116Smsmith            break;
60577424Smsmith        }
60667754Smsmith        break;
60767754Smsmith
60867754Smsmith    default:
60967754Smsmith
610193267Sjkim        ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
611204773Sjkim            "unsupported type [%s] 0x%X in object %p",
612193267Sjkim            AcpiUtGetObjectTypeName (InternalObject),
613193267Sjkim            InternalObject->Common.Type, InternalObject));
61467754Smsmith        Status = AE_TYPE;
61567754Smsmith        break;
61667754Smsmith    }
61767754Smsmith
61867754Smsmith    /*
61967754Smsmith     * Account for the space required by the object rounded up to the next
620241973Sjkim     * multiple of the machine word size. This keeps each object aligned
62167754Smsmith     * on a machine word boundary. (preventing alignment faults on some
62267754Smsmith     * machines.)
62367754Smsmith     */
62491116Smsmith    *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length);
62567754Smsmith    return_ACPI_STATUS (Status);
62667754Smsmith}
62767754Smsmith
62867754Smsmith
62973561Smsmith/*******************************************************************************
63067754Smsmith *
63177424Smsmith * FUNCTION:    AcpiUtGetElementLength
63267754Smsmith *
63373561Smsmith * PARAMETERS:  ACPI_PKG_CALLBACK
63467754Smsmith *
63599679Siwasaki * RETURN:      Status
63667754Smsmith *
63777424Smsmith * DESCRIPTION: Get the length of one package element.
63867754Smsmith *
63967754Smsmith ******************************************************************************/
64067754Smsmith
641151937Sjkimstatic ACPI_STATUS
64277424SmsmithAcpiUtGetElementLength (
64373561Smsmith    UINT8                   ObjectType,
64473561Smsmith    ACPI_OPERAND_OBJECT     *SourceObject,
64573561Smsmith    ACPI_GENERIC_STATE      *State,
64673561Smsmith    void                    *Context)
64767754Smsmith{
64873561Smsmith    ACPI_STATUS             Status = AE_OK;
64973561Smsmith    ACPI_PKG_INFO           *Info = (ACPI_PKG_INFO *) Context;
65091116Smsmith    ACPI_SIZE               ObjectSpace;
65167754Smsmith
65267754Smsmith
65373561Smsmith    switch (ObjectType)
65473561Smsmith    {
65591116Smsmith    case ACPI_COPY_TYPE_SIMPLE:
65673561Smsmith        /*
65773561Smsmith         * Simple object - just get the size (Null object/entry is handled
65873561Smsmith         * here also) and sum it into the running package length
65973561Smsmith         */
66077424Smsmith        Status = AcpiUtGetSimpleObjectSize (SourceObject, &ObjectSpace);
66173561Smsmith        if (ACPI_FAILURE (Status))
66273561Smsmith        {
66373561Smsmith            return (Status);
66473561Smsmith        }
66567754Smsmith
66673561Smsmith        Info->Length += ObjectSpace;
66773561Smsmith        break;
66869450Smsmith
66991116Smsmith    case ACPI_COPY_TYPE_PACKAGE:
67067754Smsmith
67191116Smsmith        /* Package object - nothing much to do here, let the walk handle it */
67291116Smsmith
67373561Smsmith        Info->NumPackages++;
67473561Smsmith        State->Pkg.ThisTargetObj = NULL;
67573561Smsmith        break;
67699679Siwasaki
67799679Siwasaki    default:
67899679Siwasaki
67999679Siwasaki        /* No other types allowed */
68099679Siwasaki
68199679Siwasaki        return (AE_BAD_PARAMETER);
68273561Smsmith    }
68367754Smsmith
68473561Smsmith    return (Status);
68573561Smsmith}
68667754Smsmith
68767754Smsmith
68873561Smsmith/*******************************************************************************
68973561Smsmith *
69077424Smsmith * FUNCTION:    AcpiUtGetPackageObjectSize
69173561Smsmith *
692151937Sjkim * PARAMETERS:  InternalObject      - An ACPI internal object
693151937Sjkim *              ObjLength           - Where the length is returned
69473561Smsmith *
69573561Smsmith * RETURN:      Status
69673561Smsmith *
69777424Smsmith * DESCRIPTION: This function is called to determine the space required to
69899679Siwasaki *              contain a package object for return to an external user.
69973561Smsmith *
70077424Smsmith *              This is moderately complex since a package contains other
70173561Smsmith *              objects including packages.
70273561Smsmith *
70373561Smsmith ******************************************************************************/
70467754Smsmith
705151937Sjkimstatic ACPI_STATUS
70677424SmsmithAcpiUtGetPackageObjectSize (
70773561Smsmith    ACPI_OPERAND_OBJECT     *InternalObject,
70891116Smsmith    ACPI_SIZE               *ObjLength)
70973561Smsmith{
71073561Smsmith    ACPI_STATUS             Status;
71173561Smsmith    ACPI_PKG_INFO           Info;
71267754Smsmith
71367754Smsmith
714167802Sjkim    ACPI_FUNCTION_TRACE_PTR (UtGetPackageObjectSize, InternalObject);
71567754Smsmith
71667754Smsmith
717306536Sjkim    Info.Length = 0;
71873561Smsmith    Info.ObjectSpace = 0;
71973561Smsmith    Info.NumPackages = 1;
72067754Smsmith
721306536Sjkim    Status = AcpiUtWalkPackageTree (
722306536Sjkim        InternalObject, NULL, AcpiUtGetElementLength, &Info);
72387031Smsmith    if (ACPI_FAILURE (Status))
72487031Smsmith    {
72587031Smsmith        return_ACPI_STATUS (Status);
72687031Smsmith    }
72767754Smsmith
72873561Smsmith    /*
72973561Smsmith     * We have handled all of the objects in all levels of the package.
73073561Smsmith     * just add the length of the package objects themselves.
73173561Smsmith     * Round up to the next machine word.
73273561Smsmith     */
733306536Sjkim    Info.Length += ACPI_ROUND_UP_TO_NATIVE_WORD (
734306536Sjkim        sizeof (ACPI_OBJECT)) * (ACPI_SIZE) Info.NumPackages;
73567754Smsmith
73673561Smsmith    /* Return the total package length */
73773561Smsmith
73873561Smsmith    *ObjLength = Info.Length;
73973561Smsmith    return_ACPI_STATUS (Status);
74067754Smsmith}
74167754Smsmith
74267754Smsmith
74373561Smsmith/*******************************************************************************
74467754Smsmith *
74577424Smsmith * FUNCTION:    AcpiUtGetObjectSize
74667754Smsmith *
747151937Sjkim * PARAMETERS:  InternalObject      - An ACPI internal object
748151937Sjkim *              ObjLength           - Where the length will be returned
74967754Smsmith *
75077424Smsmith * RETURN:      Status
75167754Smsmith *
75267754Smsmith * DESCRIPTION: This function is called to determine the space required to
75367754Smsmith *              contain an object for return to an API user.
75467754Smsmith *
75567754Smsmith ******************************************************************************/
75667754Smsmith
75767754SmsmithACPI_STATUS
758151937SjkimAcpiUtGetObjectSize (
75973561Smsmith    ACPI_OPERAND_OBJECT     *InternalObject,
76091116Smsmith    ACPI_SIZE               *ObjLength)
76167754Smsmith{
76267754Smsmith    ACPI_STATUS             Status;
76367754Smsmith
76467754Smsmith
76591116Smsmith    ACPI_FUNCTION_ENTRY ();
76683174Smsmith
76783174Smsmith
768306536Sjkim    if ((ACPI_GET_DESCRIPTOR_TYPE (InternalObject) ==
769306536Sjkim            ACPI_DESC_TYPE_OPERAND) &&
770193267Sjkim        (InternalObject->Common.Type == ACPI_TYPE_PACKAGE))
77167754Smsmith    {
77277424Smsmith        Status = AcpiUtGetPackageObjectSize (InternalObject, ObjLength);
77367754Smsmith    }
77467754Smsmith    else
77567754Smsmith    {
77677424Smsmith        Status = AcpiUtGetSimpleObjectSize (InternalObject, ObjLength);
77767754Smsmith    }
77867754Smsmith
77967754Smsmith    return (Status);
78067754Smsmith}
781