exstore.c revision 202771
182936Sdfr
282936Sdfr/******************************************************************************
382936Sdfr *
482936Sdfr * Module Name: exstore - AML Interpreter object store support
582936Sdfr *
682936Sdfr *****************************************************************************/
782936Sdfr
882936Sdfr/******************************************************************************
982936Sdfr *
1082936Sdfr * 1. Copyright Notice
1182936Sdfr *
1282936Sdfr * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
1382936Sdfr * All rights reserved.
1482936Sdfr *
1582936Sdfr * 2. License
1682936Sdfr *
1782936Sdfr * 2.1. This is your license from Intel Corp. under its intellectual property
1882936Sdfr * rights.  You may have additional license terms from the party that provided
1982936Sdfr * you this software, covering your right to use that party's intellectual
2082936Sdfr * property rights.
2182936Sdfr *
2282936Sdfr * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2382936Sdfr * copy of the source code appearing in this file ("Covered Code") an
2482936Sdfr * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2582936Sdfr * base code distributed originally by Intel ("Original Intel Code") to copy,
2682936Sdfr * make derivatives, distribute, use and display any portion of the Covered
2782936Sdfr * Code in any form, with the right to sublicense such rights; and
2882936Sdfr *
2982936Sdfr * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
3082936Sdfr * license (with the right to sublicense), under only those claims of Intel
3182936Sdfr * patents that are infringed by the Original Intel Code, to make, use, sell,
3282936Sdfr * offer to sell, and import the Covered Code and derivative works thereof
3382936Sdfr * solely to the minimum extent necessary to exercise the above copyright
3482936Sdfr * license, and in no event shall the patent license extend to any additions
3582936Sdfr * to or modifications of the Original Intel Code.  No other license or right
3682936Sdfr * is granted directly or by implication, estoppel or otherwise;
3782936Sdfr *
3882936Sdfr * The above copyright and patent license is granted only if the following
3982936Sdfr * conditions are met:
4067117Sdfr *
4182936Sdfr * 3. Conditions
4282936Sdfr *
4382936Sdfr * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4482936Sdfr * Redistribution of source code of any substantial portion of the Covered
4582936Sdfr * Code or modification with rights to further distribute source must include
4682936Sdfr * the above Copyright Notice, the above License, this list of Conditions,
4782936Sdfr * and the following Disclaimer and Export Compliance provision.  In addition,
4882936Sdfr * Licensee must cause all Covered Code to which Licensee contributes to
4982936Sdfr * contain a file documenting the changes Licensee made to create that Covered
5067117Sdfr * Code and the date of any change.  Licensee must include in that file the
5182936Sdfr * documentation of any changes made by any predecessor Licensee.  Licensee
5267117Sdfr * must include a prominent statement that the modification is derived,
53111777Sobrien * directly or indirectly, from Original Intel Code.
54111777Sobrien *
55111777Sobrien * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5682936Sdfr * Redistribution of source code of any substantial portion of the Covered
5782936Sdfr * Code or modification without rights to further distribute source must
5867117Sdfr * include the following Disclaimer and Export Compliance provision in the
5982936Sdfr * documentation and/or other materials provided with distribution.  In
6082936Sdfr * addition, Licensee may not authorize further sublicense of source of any
6182936Sdfr * portion of the Covered Code, and must include terms to the effect that the
6282936Sdfr * license from Licensee to its licensee is limited to the intellectual
6382936Sdfr * property embodied in the software Licensee provides to its licensee, and
6482936Sdfr * not to intellectual property embodied in modifications its licensee may
6582936Sdfr * make.
6682936Sdfr *
6782936Sdfr * 3.3. Redistribution of Executable. Redistribution in executable form of any
6882936Sdfr * substantial portion of the Covered Code or modification must reproduce the
6982936Sdfr * above Copyright Notice, and the following Disclaimer and Export Compliance
7082936Sdfr * provision in the documentation and/or other materials provided with the
7182936Sdfr * distribution.
7267117Sdfr *
7382936Sdfr * 3.4. Intel retains all right, title, and interest in and to the Original
7482936Sdfr * Intel Code.
7582936Sdfr *
7682936Sdfr * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7782936Sdfr * Intel shall be used in advertising or otherwise to promote the sale, use or
7882936Sdfr * other dealings in products derived from or relating to the Covered Code
7982936Sdfr * without prior written authorization from Intel.
8082936Sdfr *
8182936Sdfr * 4. Disclaimer and Export Compliance
8282936Sdfr *
8382936Sdfr * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8482936Sdfr * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8582936Sdfr * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8682936Sdfr * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8782936Sdfr * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8882936Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8982936Sdfr * PARTICULAR PURPOSE.
9082936Sdfr *
9182936Sdfr * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9282936Sdfr * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9382936Sdfr * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9482936Sdfr * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9582936Sdfr * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9682936Sdfr * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9782936Sdfr * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9882936Sdfr * LIMITED REMEDY.
99106904Smarcel *
10082936Sdfr * 4.3. Licensee shall not export, either directly or indirectly, any of this
101106904Smarcel * software or system incorporating such software without first obtaining any
102106904Smarcel * required license or other approval from the U. S. Department of Commerce or
10382936Sdfr * any other agency or department of the United States Government.  In the
104106904Smarcel * event Licensee exports any such software from the United States or
10582936Sdfr * re-exports any such software from a foreign destination, Licensee shall
106106904Smarcel * ensure that the distribution and export/re-export of the software is in
10782936Sdfr * compliance with all laws, regulations, orders, or other restrictions of the
10882936Sdfr * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10982936Sdfr * any of its subsidiaries will export/re-export any technical data, process,
110106904Smarcel * software, or service, directly or indirectly, to any country for which the
11182936Sdfr * United States government or any agency thereof requires an export license,
11282936Sdfr * other governmental approval, or letter of assurance, without first obtaining
11382936Sdfr * such license, approval or letter.
11482936Sdfr *
11582936Sdfr *****************************************************************************/
116106904Smarcel
11782936Sdfr#define __EXSTORE_C__
11882936Sdfr
119106904Smarcel#include <contrib/dev/acpica/include/acpi.h>
12082936Sdfr#include <contrib/dev/acpica/include/accommon.h>
121106904Smarcel#include <contrib/dev/acpica/include/acdispat.h>
122106904Smarcel#include <contrib/dev/acpica/include/acinterp.h>
12382936Sdfr#include <contrib/dev/acpica/include/amlcode.h>
12482936Sdfr#include <contrib/dev/acpica/include/acnamesp.h>
12582936Sdfr
12682936Sdfr
12782936Sdfr#define _COMPONENT          ACPI_EXECUTER
12882936Sdfr        ACPI_MODULE_NAME    ("exstore")
12982936Sdfr
13082936Sdfr/* Local prototypes */
13182936Sdfr
13282936Sdfrstatic void
13382936SdfrAcpiExDoDebugObject (
13482936Sdfr    ACPI_OPERAND_OBJECT     *SourceDesc,
13582936Sdfr    UINT32                  Level,
13682936Sdfr    UINT32                  Index);
13782936Sdfr
13882936Sdfrstatic ACPI_STATUS
13982936SdfrAcpiExStoreObjectToIndex (
14082936Sdfr    ACPI_OPERAND_OBJECT     *ValDesc,
14182936Sdfr    ACPI_OPERAND_OBJECT     *DestDesc,
14282936Sdfr    ACPI_WALK_STATE         *WalkState);
14382936Sdfr
14482936Sdfr
14582936Sdfr/*******************************************************************************
14682936Sdfr *
14782936Sdfr * FUNCTION:    AcpiExDoDebugObject
14882936Sdfr *
14982936Sdfr * PARAMETERS:  SourceDesc          - Value to be stored
15082936Sdfr *              Level               - Indentation level (used for packages)
15182936Sdfr *              Index               - Current package element, zero if not pkg
15282936Sdfr *
15382936Sdfr * RETURN:      None
15482936Sdfr *
155106904Smarcel * DESCRIPTION: Handles stores to the Debug Object.
156106904Smarcel *
15782936Sdfr ******************************************************************************/
15882936Sdfr
15982936Sdfrstatic void
16082936SdfrAcpiExDoDebugObject (
16182936Sdfr    ACPI_OPERAND_OBJECT     *SourceDesc,
16282936Sdfr    UINT32                  Level,
16382936Sdfr    UINT32                  Index)
16482936Sdfr{
16582936Sdfr    UINT32                  i;
16682936Sdfr
16782936Sdfr
16882936Sdfr    ACPI_FUNCTION_TRACE_PTR (ExDoDebugObject, SourceDesc);
16982936Sdfr
17082936Sdfr
17182936Sdfr    /* Print line header as long as we are not in the middle of an object display */
17282936Sdfr
17382936Sdfr    if (!((Level > 0) && Index == 0))
174111897Smarcel    {
17582936Sdfr        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s",
17682936Sdfr            Level, " "));
17782936Sdfr    }
178111897Smarcel
17982936Sdfr    /* Display index for package output only */
18082936Sdfr
18182936Sdfr    if (Index > 0)
18282936Sdfr    {
18382936Sdfr       ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
18482936Sdfr           "(%.2u) ", Index -1));
18582936Sdfr    }
18682936Sdfr
18767117Sdfr    if (!SourceDesc)
18867117Sdfr    {
18967117Sdfr        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[Null Object]\n"));
19082936Sdfr        return_VOID;
19182936Sdfr    }
19282936Sdfr
19382936Sdfr    if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND)
19482936Sdfr    {
19582936Sdfr        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s ",
19682936Sdfr            AcpiUtGetObjectTypeName (SourceDesc)));
19782936Sdfr
19882936Sdfr        if (!AcpiUtValidInternalObject (SourceDesc))
19982936Sdfr        {
20082936Sdfr           ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
20182936Sdfr               "%p, Invalid Internal Object!\n", SourceDesc));
20267117Sdfr           return_VOID;
20385229Sdfr        }
20485229Sdfr    }
205106904Smarcel    else if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
20682936Sdfr    {
20782936Sdfr        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s: %p\n",
208106904Smarcel            AcpiUtGetTypeName (((ACPI_NAMESPACE_NODE *) SourceDesc)->Type),
209106904Smarcel            SourceDesc));
21082936Sdfr        return_VOID;
211106904Smarcel    }
21282936Sdfr    else
21382936Sdfr    {
21482936Sdfr        return_VOID;
215106904Smarcel    }
21682936Sdfr
217106904Smarcel    /* SourceDesc is of type ACPI_DESC_TYPE_OPERAND */
21882936Sdfr
219106904Smarcel    switch (SourceDesc->Common.Type)
22082936Sdfr    {
22182936Sdfr    case ACPI_TYPE_INTEGER:
222106904Smarcel
22382936Sdfr        /* Output correct integer width */
22482936Sdfr
225106904Smarcel        if (AcpiGbl_IntegerByteWidth == 4)
226106904Smarcel        {
22782936Sdfr            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n",
228106904Smarcel                (UINT32) SourceDesc->Integer.Value));
22982936Sdfr        }
23082936Sdfr        else
23182936Sdfr        {
23282936Sdfr            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X%8.8X\n",
23382936Sdfr                ACPI_FORMAT_UINT64 (SourceDesc->Integer.Value)));
23482936Sdfr        }
23582936Sdfr        break;
23682936Sdfr
23782936Sdfr    case ACPI_TYPE_BUFFER:
23882936Sdfr
23982936Sdfr        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]\n",
24082936Sdfr            (UINT32) SourceDesc->Buffer.Length));
24182936Sdfr        ACPI_DUMP_BUFFER (SourceDesc->Buffer.Pointer,
24282936Sdfr            (SourceDesc->Buffer.Length < 256) ? SourceDesc->Buffer.Length : 256);
24382936Sdfr        break;
24482936Sdfr
24582936Sdfr    case ACPI_TYPE_STRING:
24682936Sdfr
24782936Sdfr        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n",
24882936Sdfr            SourceDesc->String.Length, SourceDesc->String.Pointer));
24982936Sdfr        break;
25082936Sdfr
25182936Sdfr    case ACPI_TYPE_PACKAGE:
25282936Sdfr
25382936Sdfr        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[Contains 0x%.2X Elements]\n",
25482936Sdfr            SourceDesc->Package.Count));
25582936Sdfr
25682936Sdfr        /* Output the entire contents of the package */
25782936Sdfr
25882936Sdfr        for (i = 0; i < SourceDesc->Package.Count; i++)
25982936Sdfr        {
26082936Sdfr            AcpiExDoDebugObject (SourceDesc->Package.Elements[i],
26182936Sdfr                Level+4, i+1);
26282936Sdfr        }
26382936Sdfr        break;
26482936Sdfr
26582936Sdfr    case ACPI_TYPE_LOCAL_REFERENCE:
26682936Sdfr
26782936Sdfr        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[%s] ",
26882936Sdfr            AcpiUtGetReferenceName (SourceDesc)));
26982936Sdfr
27082936Sdfr        /* Decode the reference */
27182936Sdfr
27282936Sdfr        switch (SourceDesc->Reference.Class)
27382936Sdfr        {
27482936Sdfr        case ACPI_REFCLASS_INDEX:
27582936Sdfr
27682936Sdfr            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%X\n",
27782936Sdfr                SourceDesc->Reference.Value));
27882936Sdfr            break;
27982936Sdfr
28082936Sdfr        case ACPI_REFCLASS_TABLE:
28182936Sdfr
28282936Sdfr            /* Case for DdbHandle */
28382936Sdfr
28482936Sdfr            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Table Index 0x%X\n",
28582936Sdfr                SourceDesc->Reference.Value));
28682936Sdfr            return;
28782936Sdfr
28882936Sdfr        default:
28982936Sdfr            break;
29082936Sdfr        }
29182936Sdfr
29282936Sdfr        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "  "));
29382936Sdfr
294111897Smarcel        /* Check for valid node first, then valid object */
29582936Sdfr
29682936Sdfr        if (SourceDesc->Reference.Node)
297111897Smarcel        {
29882936Sdfr            if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Node) !=
299111897Smarcel                    ACPI_DESC_TYPE_NAMED)
300106904Smarcel            {
30182936Sdfr                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
30282936Sdfr                    " %p - Not a valid namespace node\n",
30382936Sdfr                    SourceDesc->Reference.Node));
30482936Sdfr            }
30582936Sdfr            else
30682936Sdfr            {
30782936Sdfr                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Node %p [%4.4s] ",
30882936Sdfr                    SourceDesc->Reference.Node, (SourceDesc->Reference.Node)->Name.Ascii));
30982936Sdfr
31082936Sdfr                switch ((SourceDesc->Reference.Node)->Type)
31182936Sdfr                {
31285229Sdfr                /* These types have no attached object */
313
314                case ACPI_TYPE_DEVICE:
315                    AcpiOsPrintf ("Device\n");
316                    break;
317
318                case ACPI_TYPE_THERMAL:
319                    AcpiOsPrintf ("Thermal Zone\n");
320                    break;
321
322                default:
323                    AcpiExDoDebugObject ((SourceDesc->Reference.Node)->Object,
324                        Level+4, 0);
325                    break;
326                }
327            }
328        }
329        else if (SourceDesc->Reference.Object)
330        {
331            if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Object) ==
332                    ACPI_DESC_TYPE_NAMED)
333            {
334                AcpiExDoDebugObject (((ACPI_NAMESPACE_NODE *)
335                    SourceDesc->Reference.Object)->Object,
336                    Level+4, 0);
337            }
338            else
339            {
340                AcpiExDoDebugObject (SourceDesc->Reference.Object, Level+4, 0);
341            }
342        }
343        break;
344
345    default:
346
347        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%p\n",
348            SourceDesc));
349        break;
350    }
351
352    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
353    return_VOID;
354}
355
356
357/*******************************************************************************
358 *
359 * FUNCTION:    AcpiExStore
360 *
361 * PARAMETERS:  *SourceDesc         - Value to be stored
362 *              *DestDesc           - Where to store it.  Must be an NS node
363 *                                    or an ACPI_OPERAND_OBJECT of type
364 *                                    Reference;
365 *              WalkState           - Current walk state
366 *
367 * RETURN:      Status
368 *
369 * DESCRIPTION: Store the value described by SourceDesc into the location
370 *              described by DestDesc.  Called by various interpreter
371 *              functions to store the result of an operation into
372 *              the destination operand -- not just simply the actual "Store"
373 *              ASL operator.
374 *
375 ******************************************************************************/
376
377ACPI_STATUS
378AcpiExStore (
379    ACPI_OPERAND_OBJECT     *SourceDesc,
380    ACPI_OPERAND_OBJECT     *DestDesc,
381    ACPI_WALK_STATE         *WalkState)
382{
383    ACPI_STATUS             Status = AE_OK;
384    ACPI_OPERAND_OBJECT     *RefDesc = DestDesc;
385
386
387    ACPI_FUNCTION_TRACE_PTR (ExStore, DestDesc);
388
389
390    /* Validate parameters */
391
392    if (!SourceDesc || !DestDesc)
393    {
394        ACPI_ERROR ((AE_INFO, "Null parameter"));
395        return_ACPI_STATUS (AE_AML_NO_OPERAND);
396    }
397
398    /* DestDesc can be either a namespace node or an ACPI object */
399
400    if (ACPI_GET_DESCRIPTOR_TYPE (DestDesc) == ACPI_DESC_TYPE_NAMED)
401    {
402        /*
403         * Dest is a namespace node,
404         * Storing an object into a Named node.
405         */
406        Status = AcpiExStoreObjectToNode (SourceDesc,
407                    (ACPI_NAMESPACE_NODE *) DestDesc, WalkState,
408                    ACPI_IMPLICIT_CONVERSION);
409
410        return_ACPI_STATUS (Status);
411    }
412
413    /* Destination object must be a Reference or a Constant object */
414
415    switch (DestDesc->Common.Type)
416    {
417    case ACPI_TYPE_LOCAL_REFERENCE:
418        break;
419
420    case ACPI_TYPE_INTEGER:
421
422        /* Allow stores to Constants -- a Noop as per ACPI spec */
423
424        if (DestDesc->Common.Flags & AOPOBJ_AML_CONSTANT)
425        {
426            return_ACPI_STATUS (AE_OK);
427        }
428
429        /*lint -fallthrough */
430
431    default:
432
433        /* Destination is not a Reference object */
434
435        ACPI_ERROR ((AE_INFO,
436            "Target is not a Reference or Constant object - %s [%p]",
437            AcpiUtGetObjectTypeName (DestDesc), DestDesc));
438
439        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
440    }
441
442    /*
443     * Examine the Reference class. These cases are handled:
444     *
445     * 1) Store to Name (Change the object associated with a name)
446     * 2) Store to an indexed area of a Buffer or Package
447     * 3) Store to a Method Local or Arg
448     * 4) Store to the debug object
449     */
450    switch (RefDesc->Reference.Class)
451    {
452    case ACPI_REFCLASS_REFOF:
453
454        /* Storing an object into a Name "container" */
455
456        Status = AcpiExStoreObjectToNode (SourceDesc,
457                    RefDesc->Reference.Object,
458                    WalkState, ACPI_IMPLICIT_CONVERSION);
459        break;
460
461
462    case ACPI_REFCLASS_INDEX:
463
464        /* Storing to an Index (pointer into a packager or buffer) */
465
466        Status = AcpiExStoreObjectToIndex (SourceDesc, RefDesc, WalkState);
467        break;
468
469
470    case ACPI_REFCLASS_LOCAL:
471    case ACPI_REFCLASS_ARG:
472
473        /* Store to a method local/arg  */
474
475        Status = AcpiDsStoreObjectToLocal (RefDesc->Reference.Class,
476                    RefDesc->Reference.Value, SourceDesc, WalkState);
477        break;
478
479
480    case ACPI_REFCLASS_DEBUG:
481
482        /*
483         * Storing to the Debug object causes the value stored to be
484         * displayed and otherwise has no effect -- see ACPI Specification
485         */
486        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
487            "**** Write to Debug Object: Object %p %s ****:\n\n",
488            SourceDesc, AcpiUtGetObjectTypeName (SourceDesc)));
489
490        AcpiExDoDebugObject (SourceDesc, 0, 0);
491        break;
492
493
494    default:
495
496        ACPI_ERROR ((AE_INFO, "Unknown Reference Class %2.2X",
497            RefDesc->Reference.Class));
498        ACPI_DUMP_ENTRY (RefDesc, ACPI_LV_INFO);
499
500        Status = AE_AML_INTERNAL;
501        break;
502    }
503
504    return_ACPI_STATUS (Status);
505}
506
507
508/*******************************************************************************
509 *
510 * FUNCTION:    AcpiExStoreObjectToIndex
511 *
512 * PARAMETERS:  *SourceDesc             - Value to be stored
513 *              *DestDesc               - Named object to receive the value
514 *              WalkState               - Current walk state
515 *
516 * RETURN:      Status
517 *
518 * DESCRIPTION: Store the object to indexed Buffer or Package element
519 *
520 ******************************************************************************/
521
522static ACPI_STATUS
523AcpiExStoreObjectToIndex (
524    ACPI_OPERAND_OBJECT     *SourceDesc,
525    ACPI_OPERAND_OBJECT     *IndexDesc,
526    ACPI_WALK_STATE         *WalkState)
527{
528    ACPI_STATUS             Status = AE_OK;
529    ACPI_OPERAND_OBJECT     *ObjDesc;
530    ACPI_OPERAND_OBJECT     *NewDesc;
531    UINT8                   Value = 0;
532    UINT32                  i;
533
534
535    ACPI_FUNCTION_TRACE (ExStoreObjectToIndex);
536
537
538    /*
539     * Destination must be a reference pointer, and
540     * must point to either a buffer or a package
541     */
542    switch (IndexDesc->Reference.TargetType)
543    {
544    case ACPI_TYPE_PACKAGE:
545        /*
546         * Storing to a package element. Copy the object and replace
547         * any existing object with the new object. No implicit
548         * conversion is performed.
549         *
550         * The object at *(IndexDesc->Reference.Where) is the
551         * element within the package that is to be modified.
552         * The parent package object is at IndexDesc->Reference.Object
553         */
554        ObjDesc = *(IndexDesc->Reference.Where);
555
556        if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE &&
557            SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE)
558        {
559            /* This is a DDBHandle, just add a reference to it */
560
561            AcpiUtAddReference (SourceDesc);
562            NewDesc = SourceDesc;
563        }
564        else
565        {
566            /* Normal object, copy it */
567
568            Status = AcpiUtCopyIobjectToIobject (SourceDesc, &NewDesc, WalkState);
569            if (ACPI_FAILURE (Status))
570            {
571                return_ACPI_STATUS (Status);
572            }
573        }
574
575        if (ObjDesc)
576        {
577            /* Decrement reference count by the ref count of the parent package */
578
579            for (i = 0;
580                 i < ((ACPI_OPERAND_OBJECT *)
581                        IndexDesc->Reference.Object)->Common.ReferenceCount;
582                 i++)
583            {
584                AcpiUtRemoveReference (ObjDesc);
585            }
586        }
587
588        *(IndexDesc->Reference.Where) = NewDesc;
589
590        /* Increment ref count by the ref count of the parent package-1 */
591
592        for (i = 1;
593             i < ((ACPI_OPERAND_OBJECT *)
594                    IndexDesc->Reference.Object)->Common.ReferenceCount;
595             i++)
596        {
597            AcpiUtAddReference (NewDesc);
598        }
599
600        break;
601
602
603    case ACPI_TYPE_BUFFER_FIELD:
604
605        /*
606         * Store into a Buffer or String (not actually a real BufferField)
607         * at a location defined by an Index.
608         *
609         * The first 8-bit element of the source object is written to the
610         * 8-bit Buffer location defined by the Index destination object,
611         * according to the ACPI 2.0 specification.
612         */
613
614        /*
615         * Make sure the target is a Buffer or String. An error should
616         * not happen here, since the ReferenceObject was constructed
617         * by the INDEX_OP code.
618         */
619        ObjDesc = IndexDesc->Reference.Object;
620        if ((ObjDesc->Common.Type != ACPI_TYPE_BUFFER) &&
621            (ObjDesc->Common.Type != ACPI_TYPE_STRING))
622        {
623            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
624        }
625
626        /*
627         * The assignment of the individual elements will be slightly
628         * different for each source type.
629         */
630        switch (SourceDesc->Common.Type)
631        {
632        case ACPI_TYPE_INTEGER:
633
634            /* Use the least-significant byte of the integer */
635
636            Value = (UINT8) (SourceDesc->Integer.Value);
637            break;
638
639        case ACPI_TYPE_BUFFER:
640        case ACPI_TYPE_STRING:
641
642            /* Note: Takes advantage of common string/buffer fields */
643
644            Value = SourceDesc->Buffer.Pointer[0];
645            break;
646
647        default:
648
649            /* All other types are invalid */
650
651            ACPI_ERROR ((AE_INFO,
652                "Source must be Integer/Buffer/String type, not %s",
653                AcpiUtGetObjectTypeName (SourceDesc)));
654            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
655        }
656
657        /* Store the source value into the target buffer byte */
658
659        ObjDesc->Buffer.Pointer[IndexDesc->Reference.Value] = Value;
660        break;
661
662
663    default:
664        ACPI_ERROR ((AE_INFO,
665            "Target is not a Package or BufferField"));
666        Status = AE_AML_OPERAND_TYPE;
667        break;
668    }
669
670    return_ACPI_STATUS (Status);
671}
672
673
674/*******************************************************************************
675 *
676 * FUNCTION:    AcpiExStoreObjectToNode
677 *
678 * PARAMETERS:  SourceDesc              - Value to be stored
679 *              Node                    - Named object to receive the value
680 *              WalkState               - Current walk state
681 *              ImplicitConversion      - Perform implicit conversion (yes/no)
682 *
683 * RETURN:      Status
684 *
685 * DESCRIPTION: Store the object to the named object.
686 *
687 *              The Assignment of an object to a named object is handled here
688 *              The value passed in will replace the current value (if any)
689 *              with the input value.
690 *
691 *              When storing into an object the data is converted to the
692 *              target object type then stored in the object.  This means
693 *              that the target object type (for an initialized target) will
694 *              not be changed by a store operation.
695 *
696 *              Assumes parameters are already validated.
697 *
698 ******************************************************************************/
699
700ACPI_STATUS
701AcpiExStoreObjectToNode (
702    ACPI_OPERAND_OBJECT     *SourceDesc,
703    ACPI_NAMESPACE_NODE     *Node,
704    ACPI_WALK_STATE         *WalkState,
705    UINT8                   ImplicitConversion)
706{
707    ACPI_STATUS             Status = AE_OK;
708    ACPI_OPERAND_OBJECT     *TargetDesc;
709    ACPI_OPERAND_OBJECT     *NewDesc;
710    ACPI_OBJECT_TYPE        TargetType;
711
712
713    ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToNode, SourceDesc);
714
715
716    /* Get current type of the node, and object attached to Node */
717
718    TargetType = AcpiNsGetType (Node);
719    TargetDesc = AcpiNsGetAttachedObject (Node);
720
721    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n",
722        SourceDesc, AcpiUtGetObjectTypeName (SourceDesc),
723              Node, AcpiUtGetTypeName (TargetType)));
724
725    /*
726     * Resolve the source object to an actual value
727     * (If it is a reference object)
728     */
729    Status = AcpiExResolveObject (&SourceDesc, TargetType, WalkState);
730    if (ACPI_FAILURE (Status))
731    {
732        return_ACPI_STATUS (Status);
733    }
734
735    /* If no implicit conversion, drop into the default case below */
736
737    if ((!ImplicitConversion) ||
738          ((WalkState->Opcode == AML_COPY_OP) &&
739           (TargetType != ACPI_TYPE_LOCAL_REGION_FIELD) &&
740           (TargetType != ACPI_TYPE_LOCAL_BANK_FIELD) &&
741           (TargetType != ACPI_TYPE_LOCAL_INDEX_FIELD)))
742    {
743        /*
744         * Force execution of default (no implicit conversion). Note:
745         * CopyObject does not perform an implicit conversion, as per the ACPI
746         * spec -- except in case of region/bank/index fields -- because these
747         * objects must retain their original type permanently.
748         */
749        TargetType = ACPI_TYPE_ANY;
750    }
751
752    /* Do the actual store operation */
753
754    switch (TargetType)
755    {
756    case ACPI_TYPE_BUFFER_FIELD:
757    case ACPI_TYPE_LOCAL_REGION_FIELD:
758    case ACPI_TYPE_LOCAL_BANK_FIELD:
759    case ACPI_TYPE_LOCAL_INDEX_FIELD:
760
761        /* For fields, copy the source data to the target field. */
762
763        Status = AcpiExWriteDataToField (SourceDesc, TargetDesc,
764                    &WalkState->ResultObj);
765        break;
766
767
768    case ACPI_TYPE_INTEGER:
769    case ACPI_TYPE_STRING:
770    case ACPI_TYPE_BUFFER:
771
772        /*
773         * These target types are all of type Integer/String/Buffer, and
774         * therefore support implicit conversion before the store.
775         *
776         * Copy and/or convert the source object to a new target object
777         */
778        Status = AcpiExStoreObjectToObject (SourceDesc, TargetDesc,
779                    &NewDesc, WalkState);
780        if (ACPI_FAILURE (Status))
781        {
782            return_ACPI_STATUS (Status);
783        }
784
785        if (NewDesc != TargetDesc)
786        {
787            /*
788             * Store the new NewDesc as the new value of the Name, and set
789             * the Name's type to that of the value being stored in it.
790             * SourceDesc reference count is incremented by AttachObject.
791             *
792             * Note: This may change the type of the node if an explicit store
793             * has been performed such that the node/object type has been
794             * changed.
795             */
796            Status = AcpiNsAttachObject (Node, NewDesc, NewDesc->Common.Type);
797
798            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
799                "Store %s into %s via Convert/Attach\n",
800                AcpiUtGetObjectTypeName (SourceDesc),
801                AcpiUtGetObjectTypeName (NewDesc)));
802        }
803        break;
804
805
806    default:
807
808        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
809            "Storing %s (%p) directly into node (%p) with no implicit conversion\n",
810            AcpiUtGetObjectTypeName (SourceDesc), SourceDesc, Node));
811
812        /* No conversions for all other types.  Just attach the source object */
813
814        Status = AcpiNsAttachObject (Node, SourceDesc,
815                    SourceDesc->Common.Type);
816        break;
817    }
818
819    return_ACPI_STATUS (Status);
820}
821
822
823