Print this page
update to acpica-unix2-20130927
acpica-unix2-20130823
PANKOVs restructure

@@ -3,11 +3,11 @@
  * Module Name: exstore - AML Interpreter object store support
  *
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2011, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:

@@ -60,18 +60,24 @@
 AcpiExStoreObjectToIndex (
     ACPI_OPERAND_OBJECT     *ValDesc,
     ACPI_OPERAND_OBJECT     *DestDesc,
     ACPI_WALK_STATE         *WalkState);
 
+static ACPI_STATUS
+AcpiExStoreDirectToNode (
+    ACPI_OPERAND_OBJECT     *SourceDesc,
+    ACPI_NAMESPACE_NODE     *Node,
+    ACPI_WALK_STATE         *WalkState);
 
+
 /*******************************************************************************
  *
  * FUNCTION:    AcpiExStore
  *
  * PARAMETERS:  *SourceDesc         - Value to be stored
  *              *DestDesc           - Where to store it.  Must be an NS node
- *                                    or an ACPI_OPERAND_OBJECT of type
+ *                                    or ACPI_OPERAND_OBJECT of type
  *                                    Reference;
  *              WalkState           - Current walk state
  *
  * RETURN:      Status
  *

@@ -122,10 +128,11 @@
     /* Destination object must be a Reference or a Constant object */
 
     switch (DestDesc->Common.Type)
     {
     case ACPI_TYPE_LOCAL_REFERENCE:
+
         break;
 
     case ACPI_TYPE_INTEGER:
 
         /* Allow stores to Constants -- a Noop as per ACPI spec */

@@ -165,31 +172,27 @@
         Status = AcpiExStoreObjectToNode (SourceDesc,
                     RefDesc->Reference.Object,
                     WalkState, ACPI_IMPLICIT_CONVERSION);
         break;
 
-
     case ACPI_REFCLASS_INDEX:
 
         /* Storing to an Index (pointer into a packager or buffer) */
 
         Status = AcpiExStoreObjectToIndex (SourceDesc, RefDesc, WalkState);
         break;
 
-
     case ACPI_REFCLASS_LOCAL:
     case ACPI_REFCLASS_ARG:
 
         /* Store to a method local/arg  */
 
         Status = AcpiDsStoreObjectToLocal (RefDesc->Reference.Class,
                     RefDesc->Reference.Value, SourceDesc, WalkState);
         break;
 
-
     case ACPI_REFCLASS_DEBUG:
-
         /*
          * Storing to the Debug object causes the value stored to be
          * displayed and otherwise has no effect -- see ACPI Specification
          */
         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,

@@ -197,11 +200,10 @@
             SourceDesc, AcpiUtGetObjectTypeName (SourceDesc)));
 
         ACPI_DEBUG_OBJECT (SourceDesc, 0, 0);
         break;
 
-
     default:
 
         ACPI_ERROR ((AE_INFO, "Unknown Reference Class 0x%2.2X",
             RefDesc->Reference.Class));
         ACPI_DUMP_ENTRY (RefDesc, ACPI_LV_INFO);

@@ -306,13 +308,11 @@
             AcpiUtAddReference (NewDesc);
         }
 
         break;
 
-
     case ACPI_TYPE_BUFFER_FIELD:
-
         /*
          * Store into a Buffer or String (not actually a real BufferField)
          * at a location defined by an Index.
          *
          * The first 8-bit element of the source object is written to the

@@ -366,11 +366,10 @@
         /* Store the source value into the target buffer byte */
 
         ObjDesc->Buffer.Pointer[IndexDesc->Reference.Value] = Value;
         break;
 
-
     default:
         ACPI_ERROR ((AE_INFO,
             "Target is not a Package or BufferField"));
         Status = AE_AML_OPERAND_TYPE;
         break;

@@ -398,12 +397,16 @@
  *              with the input value.
  *
  *              When storing into an object the data is converted to the
  *              target object type then stored in the object.  This means
  *              that the target object type (for an initialized target) will
- *              not be changed by a store operation.
+ *              not be changed by a store operation. A CopyObject can change
+ *              the target type, however.
  *
+ *              The ImplicitConversion flag is set to NO/FALSE only when
+ *              storing to an ArgX -- as per the rules of the ACPI spec.
+ *
  *              Assumes parameters are already validated.
  *
  ******************************************************************************/
 
 ACPI_STATUS

@@ -425,11 +428,11 @@
     /* Get current type of the node, and object attached to Node */
 
     TargetType = AcpiNsGetType (Node);
     TargetDesc = AcpiNsGetAttachedObject (Node);
 
-    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n",
+    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p (%s) to node %p (%s)\n",
         SourceDesc, AcpiUtGetObjectTypeName (SourceDesc),
               Node, AcpiUtGetTypeName (TargetType)));
 
     /*
      * Resolve the source object to an actual value

@@ -439,53 +442,37 @@
     if (ACPI_FAILURE (Status))
     {
         return_ACPI_STATUS (Status);
     }
 
-    /* If no implicit conversion, drop into the default case below */
-
-    if ((!ImplicitConversion) ||
-          ((WalkState->Opcode == AML_COPY_OP) &&
-           (TargetType != ACPI_TYPE_LOCAL_REGION_FIELD) &&
-           (TargetType != ACPI_TYPE_LOCAL_BANK_FIELD) &&
-           (TargetType != ACPI_TYPE_LOCAL_INDEX_FIELD)))
-    {
-        /*
-         * Force execution of default (no implicit conversion). Note:
-         * CopyObject does not perform an implicit conversion, as per the ACPI
-         * spec -- except in case of region/bank/index fields -- because these
-         * objects must retain their original type permanently.
-         */
-        TargetType = ACPI_TYPE_ANY;
-    }
-
     /* Do the actual store operation */
 
     switch (TargetType)
     {
-    case ACPI_TYPE_BUFFER_FIELD:
-    case ACPI_TYPE_LOCAL_REGION_FIELD:
-    case ACPI_TYPE_LOCAL_BANK_FIELD:
-    case ACPI_TYPE_LOCAL_INDEX_FIELD:
-
-        /* For fields, copy the source data to the target field. */
-
-        Status = AcpiExWriteDataToField (SourceDesc, TargetDesc,
-                    &WalkState->ResultObj);
-        break;
-
-
     case ACPI_TYPE_INTEGER:
     case ACPI_TYPE_STRING:
     case ACPI_TYPE_BUFFER:
+        /*
+         * The simple data types all support implicit source operand
+         * conversion before the store.
+         */
 
+        if ((WalkState->Opcode == AML_COPY_OP) ||
+            !ImplicitConversion)
+        {
         /*
-         * These target types are all of type Integer/String/Buffer, and
-         * therefore support implicit conversion before the store.
-         *
-         * Copy and/or convert the source object to a new target object
+             * However, CopyObject and Stores to ArgX do not perform
+             * an implicit conversion, as per the ACPI specification.
+             * A direct store is performed instead.
          */
+            Status = AcpiExStoreDirectToNode (SourceDesc, Node,
+                WalkState);
+            break;
+        }
+
+        /* Store with implicit source operand conversion support */
+
         Status = AcpiExStoreObjectToObject (SourceDesc, TargetDesc,
                     &NewDesc, WalkState);
         if (ACPI_FAILURE (Status))
         {
             return_ACPI_STATUS (Status);

@@ -496,36 +483,102 @@
             /*
              * Store the new NewDesc as the new value of the Name, and set
              * the Name's type to that of the value being stored in it.
              * SourceDesc reference count is incremented by AttachObject.
              *
-             * Note: This may change the type of the node if an explicit store
-             * has been performed such that the node/object type has been
-             * changed.
+             * Note: This may change the type of the node if an explicit
+             * store has been performed such that the node/object type
+             * has been changed.
              */
-            Status = AcpiNsAttachObject (Node, NewDesc, NewDesc->Common.Type);
+            Status = AcpiNsAttachObject (Node, NewDesc,
+                NewDesc->Common.Type);
 
             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
                 "Store %s into %s via Convert/Attach\n",
                 AcpiUtGetObjectTypeName (SourceDesc),
                 AcpiUtGetObjectTypeName (NewDesc)));
         }
         break;
 
+    case ACPI_TYPE_BUFFER_FIELD:
+    case ACPI_TYPE_LOCAL_REGION_FIELD:
+    case ACPI_TYPE_LOCAL_BANK_FIELD:
+    case ACPI_TYPE_LOCAL_INDEX_FIELD:
+        /*
+         * For all fields, always write the source data to the target
+         * field. Any required implicit source operand conversion is
+         * performed in the function below as necessary. Note, field
+         * objects must retain their original type permanently.
+         */
+        Status = AcpiExWriteDataToField (SourceDesc, TargetDesc,
+            &WalkState->ResultObj);
+        break;
 
     default:
+        /*
+         * No conversions for all other types. Directly store a copy of
+         * the source object. This is the ACPI spec-defined behavior for
+         * the CopyObject operator.
+         *
+         * NOTE: For the Store operator, this is a departure from the
+         * ACPI spec, which states "If conversion is impossible, abort
+         * the running control method". Instead, this code implements
+         * "If conversion is impossible, treat the Store operation as
+         * a CopyObject".
+         */
+        Status = AcpiExStoreDirectToNode (SourceDesc, Node,
+            WalkState);
+        break;
+    }
 
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiExStoreDirectToNode
+ *
+ * PARAMETERS:  SourceDesc              - Value to be stored
+ *              Node                    - Named object to receive the value
+ *              WalkState               - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: "Store" an object directly to a node. This involves a copy
+ *              and an attach.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiExStoreDirectToNode (
+    ACPI_OPERAND_OBJECT     *SourceDesc,
+    ACPI_NAMESPACE_NODE     *Node,
+    ACPI_WALK_STATE         *WalkState)
+{
+    ACPI_STATUS             Status;
+    ACPI_OPERAND_OBJECT     *NewDesc;
+
+
+    ACPI_FUNCTION_TRACE (ExStoreDirectToNode);
+
+
         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
-            "Storing %s (%p) directly into node (%p) with no implicit conversion\n",
-            AcpiUtGetObjectTypeName (SourceDesc), SourceDesc, Node));
+        "Storing [%s] (%p) directly into node [%s] (%p)"
+        " with no implicit conversion\n",
+        AcpiUtGetObjectTypeName (SourceDesc), SourceDesc,
+        AcpiUtGetTypeName (Node->Type), Node));
 
-        /* No conversions for all other types.  Just attach the source object */
+    /* Copy the source object to a new object */
 
-        Status = AcpiNsAttachObject (Node, SourceDesc,
-                    SourceDesc->Common.Type);
-        break;
+    Status = AcpiUtCopyIobjectToIobject (SourceDesc, &NewDesc, WalkState);
+    if (ACPI_FAILURE (Status))
+    {
+        return_ACPI_STATUS (Status);
     }
 
+    /* Attach the new object to the node */
+
+    Status = AcpiNsAttachObject (Node, NewDesc, NewDesc->Common.Type);
+    AcpiUtRemoveReference (NewDesc);
     return_ACPI_STATUS (Status);
 }
-
-